agentleFS
dawg-iodawg-io/claude-skills/code-development/SKILL.md

code-development

Skill0 starsChanged 2 months agoMITView on GitHub

Guides a feature, bugfix, or patch through three tasks in strict sequence: (1) scope and design — read the repo, research best practices, surface every open question and design choice, and stop for explicit sign-off on a written plan; (2) implement — feature branch, smallest change, security first, written to pass SonarQube/CodeQL/lint, no commit until local tests actually run and pass; (3) document — update or create README/docs with fresh Playwright screenshots from a local run or mocks, sweeping stale images even on a bugfix. Ends by pushing and opening a fully filled PR (stacked PRs for larger work), then hands CI to pipeline-monitor. `/code-development init` records validated test, lint and PR conventions in `.claude/code-development.yml`. Use on /code-development, "develop a feature", "fix a bug", or any ask to build, implement, fix, or patch code — even if coding already started. Not for CI failures (/pipeline-monitor), releases (/code-release), or reviewing others' PRs. Needs git and gh — Claude Code only.

  • Commits and pushes

1 other project uses a version of this.

Adopted by

Most recently taken up by

  • Other versions1 project uses a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 1

    1. RainLib/full-stack-skill★ 0same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository5 other files it gives its agents.

The file

Show its rules and text

We split this skill into the rules it gives an agent

25 rules. About 0 are common, 18 are distinctive, and 7 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈18

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 7

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  • could be automatic: a setting could enforce it
  1. Distinctive:

    No look-ahead, no "while I'm here."

    line 41
  2. Distinctive:

    No commit until local tests pass: Run them for real. If they can't run, there is no commit — say why and stop.

    line 42
  3. Very specific:

    All work lands on a feature/, fix/, or — in setup mode only — chore/ branch, via a PR.

    line 47
  4. Distinctive:

    Smallest change, explicit staging: No unrelated edits, no renames or refactors the task doesn't require, and never git add -A — stage each …

    line 49
  5. Very specific:

    If gh repo view errors, don't work around it — step 3 covers why it can fail.

    line 129
  6. Distinctive:

    If you fix an entry here, show the corrected config again before going further — the user confirmed the version you had in step 7, not the …

    line 198
  7. Distinctive:

    If the user declines to run them, the commands are unvalidated — say so in the report and in the PR body.

    line 201
  8. Distinctive:

    Never commit anything else in that commit, and never push to the default branch.

    line 221
  9. Very specific:

    2. Load the config: Read .claude/code-development.yml (accept .yaml too).

    line 311
  10. Distinctive:

    Don't fall back to defaults for a required field, and don't improvise a config to keep the run going.

    line 325
  11. Distinctive:

    Read before asking: the code in the affected area, related modules, existing tests, existing docs, and recent PRs touching the same files.

    line 360
  12. Distinctive:

    Write the plan: scope, out of scope, each design decision as resolved, files expected to change, test plan, doc and screenshot impact, PR …

    line 375
  13. Very specific:

    Write to scanner standards even where the scanner can't run locally.

    line 393
  14. Distinctive:

    No secrets in code, config, tests, or fixtures.

    line 399
  15. Distinctive:

    No duplicated blocks, no dead code, no TODO standing in for an implementation.

    line 401
  16. Distinctive:

    No new dependency and no version pin the plan didn't approve.

    line 405
  17. Very specific:

    Run the gate: every command in the config's commands block — test, lint, and any typecheck/format/build recorded — or, with no config, the …

    line 409
  18. Distinctive:

    Write or update: what the change does, how to use it, config or flags added, breaking or behavior changes.

    line 429
  19. Distinctive:

    If neither a local run nor a mock will render: capture nothing, claim nothing.

    line 443
  20. Very specific:

    Commit docs separately (docs: commits) on the same branch — or on the docs stage's branch when stacked.

    line 448
  21. Distinctive:

    No test command is detectable anywhere, so there is no gate to commit behind (Setup).

    line 526
  22. Distinctive:

    No CI workflows exist — offer to create them, then wait for the answer.

    line 539
  23. Distinctive:

    Every task ends with its own block.

    line 543
  24. Distinctive:

    Never fill Commands run with anything that did not execute.

    line 557
  25. Very specific:

    No repo, no gh, no discoverable way to run the tests, an application that won't start, a toolchain this skill can't identify — say exactly …

    line 570

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

code-development

Takes a feature, bugfix, or patch from "I want X" to an open pull request, in three tasks that run strictly in sequence — scope, implement, document — so no task steps on another.

This skill has real side effects: it creates branches, commits, pushes, and opens PRs. It never touches the default branch directly and never commits code whose tests haven't actually passed.

Everything repo-specific — how to run the tests, what CI enforces, which branch to cut from, whether PRs open ready or draft, whether screenshots are expected — comes from .claude/code-development.yml in the repo being worked on, written by /code-development init. Without that file the skill rediscovers the same facts on every single run and has no record of the answers you gave last time.

Hard rules, restated up front because they're the ones that erode mid-task:

  1. Never guess on direction. Any design decision with more than one viable approach is a stop-and-ask: present the options with tradeoffs and wait. Research first — the repo's own conventions, then current best practice — before proposing anything.
  2. Task gates are hard. Task 2 does not start until the Task 1 plan has the user's explicit sign-off. Task 3 does not start until Task 2's tests are green and committed. No look-ahead, no "while I'm here."
  3. No commit until local tests pass. Run them for real. If they can't run, there is no commit — say why and stop. Never claim a command ran that didn't. This governs commits that change code; setup mode's single config commit is the one exemption, and it reports a pre-existing red suite rather than committing on top of a green one it invented.
  4. Never push directly to the default branch, or to whatever branch.default names. All work lands on a feature/, fix/, or — in setup mode only — chore/ branch, via a PR.
  5. Smallest change, explicit staging. No unrelated edits, no renames or refactors the task doesn't require, and never git add -A — stage each file by name.
  6. Setup mode commits exactly one path, .claude/code-development.yml, and authors nothing else — no code, no tests, no docs, no workflow. It runs the repo's own commands to validate them; it never stages what those runs leave behind. A development run commits only what the signed-off plan named.
  7. The config is the contract; the repo is the truth. Where they disagree — a recorded command that no longer exists, a default branch that was renamed — stop and say which key is stale. Never improvise a substitute command to keep the run moving.

The two modes

Pick the mode before doing anything else, and say which one you're in.

InvocationModeWrites anything?
/code-development init, "set up code-development", "configure code-development"Setup — discover the toolchain, validate it by running it, write .claude/code-development.yml, open a PR for itOne file, on a branch, after confirmation
/code-development, "develop a feature", "fix a bug", "implement X"Development run — Phase 0, then Tasks 1–3, then the PRA branch, commits, a push, a PR

Plain /code-development in a repo with no config offers Setup first. Say that's what you're offering rather than silently interviewing. If the user declines, run the Phase 0 discovery inline for this run only and say plainly that nothing is being recorded — the next run will rediscover all of it.

Environment and tooling

  • Needs git, gh, and a checked-out repo — Claude Code only. Prefer a connected GitHub MCP server if one is in this session's tools; otherwise gh. Check the tools actually available in this session, not a registry of installable ones.
  • Push access is required in both modes. Both end in a pushed branch and a PR. If neither path is authenticated with write access, stop and say so before Task 1 rather than after the code is written.
  • The repo is whatever repo is checked out. Discover it; never assume a name.
  • Task 3 captures screenshots with Playwright, which needs its browsers installed (npx playwright install chromium or the repo's own equivalent). A repo whose config records screenshots.mode: none never needs it.

This skill is repo-agnostic, so the quality toolchain is discovered, not assumed. When .claude/code-development.yml exists, that discovery already happened and its result is in the file. When it doesn't, read, in this order, whatever exists:

  • .github/workflows/*.yml — what CI actually enforces: linters, test commands, scanners, matrices. This is the ground truth for what the code must pass.
  • Makefile, package.json scripts, pyproject.toml, tox.ini, go.mod, Cargo.toml — how to run those same checks locally.
  • Linter and scanner configs: .eslintrc*, ruff.toml, .golangci.yml, sonar-project.properties, .pre-commit-config.yaml, codeql config.

If no CI workflows exist, that is a finding, not a free pass: in a development run, offer to add a basic lint + test workflow (its own commit, or its own stacked PR if non-trivial). Offer — never silently create it, and never skip local checks just because CI wouldn't have caught the gap. Setup mode makes no such offer; it records the absence in the config's ci block and points at a development run.

SonarQube and CodeQL generally cannot run locally. Handle that honestly: run everything that can run (linters, the test suite, any local scanner the repo configures), write the code to the standards those scanners enforce (Task 2 lists them), and let pipeline-monitor catch the remainder after the push. Never report a scan as passed locally when it did not run locally.

Setup mode — /code-development init

Takes a repo from nothing to a committed, validated config, so every later run starts from recorded fact instead of rediscovery. Build it from what the repo actually has rather than by interrogating the user about things you can read.

1. Ground it. Confirm push access, then discover the repo, the current branch, the default branch, and whether the tree is clean:

git rev-parse --show-toplevel && git branch --show-current
git remote -v
git status --porcelain          # must be empty — see below
gh repo view --json nameWithOwner,defaultBranchRef

Stop now if the tree is dirty. Setup's commit has to contain the config and nothing else, and you cannot guarantee that starting from someone else's uncommitted work. Checking this here rather than at commit time matters, because step 7 writes a file and from then on "dirty" no longer distinguishes your change from theirs.

If gh repo view errors, don't work around it — step 3 covers why it can fail.

2. Check for an existing config at .claude/code-development.yml (or .yaml). If one exists, show it and ask whether to update it or keep it — never overwrite a config the user hasn't seen.

3. Check the prerequisites that actually block people, in this order, and stop helpfully on each:

  • Not a git repo → nothing here works. Say so and stop.
  • No remote (git remote -v is empty) → the skill ends in a push and a PR, so there is nothing to push to. Say so, name git remote add origin <url> as the fix, and stop.
  • No gh/MCP write access → same reason. Stop rather than discovering it after the code is written.
  • No detectable way to run tests — no test target in a Makefile, no test script in package.json, no pytest/tox/go test/cargo test reachable, nothing in CI that runs one. Stop here. Say plainly that /code-development refuses to commit without a real passing test run (hard rule 3), so a repo with no runnable test command has no usable gate. List exactly what you looked for and didn't find. Do not write a test harness, a CI workflow, or a placeholder command to get past this — building those is a development run's job, under the Task 1 gate, not setup's.

4. Read CI first — it's the ground truth. List the workflows and read what they actually run:

ls .github/workflows/
gh workflow list --repo <owner/repo> --all

Take the concrete step commands out of the YAML — npm run lint, pytest -q, make check — rather than inferring them from the language. Those are what the code must pass.

5. Derive the local equivalents from Makefile, package.json, pyproject.toml, tox.ini, go.mod, Cargo.toml, and the linter/scanner configs. Note every check CI runs that has no local equivalent — SonarQube, CodeQL, a hosted scanner, a matrix leg that only exists on CI. That gap goes in the config verbatim so it's visible on every run instead of being rediscovered or forgotten.

6. Ask only what genuinely can't be read, offering the derived answer for each so the user is correcting rather than composing:

  • which command is the test command, when the repo offers several (test, test:unit, test:ci) — offer the one CI uses
  • whether PRs open ready for review or as drafts
  • whether this repo has a UI worth screenshotting at all — offer none for a library, a CLI, or a backend service with no rendered surface
  • how the app comes up for a screenshot run, and at what URL
  • which paths count as docs, and where images live — offer what the repo actually has

7. Write .claude/code-development.yml, show it back in full, and ask for confirmation.

8. Validate it by actually running the recorded commands, before committing anything. A config claiming npm test works when it doesn't is worse than no config at all — it turns Task 2's gate into a lie that only surfaces mid-implementation.

Say which commands you're about to run and get a go-ahead first: these are the repo's own scripts, and a test target can have side effects. Then run each of commands.test, commands.lint, and any typecheck/format/build you recorded, and read the result carefully, because the two failure modes mean opposite things:

  • The command doesn't exist, isn't executable, or errors on invocation (command not found, an unknown npm script, a missing module) → the config is wrong. Fix the entry and re-run. Never commit a config in this state.
  • The command ran and the repo's own tests or lint failed → the config is right and the repo is red. That's not a setup problem. Record the config as-is, say clearly which command failed and that it's pre-existing, and note that /code-development will refuse to commit until it's green.

If you fix an entry here, show the corrected config again before going further — the user confirmed the version you had in step 7, not the one you changed.

If the user declines to run them, the commands are unvalidated — say so in the report and in the PR body. Never describe them as verified.

9. Commit it on a branch and open a PR. This is the only write setup mode makes, and it stays narrow. Step 1 established the tree was clean, so the config from step 7 should be the only tracked change — but a validation run can leave untracked artifacts (coverage/, .pytest_cache/, a dist/). Never stage those. If any of them aren't gitignored, say so; that's a finding for a development run, not something to sweep into this commit:

git fetch origin <default branch>
git checkout -b chore/code-development-config origin/<default branch>   # branch off the
                                                                       # default, not
                                                                       # whatever is checked out
git add .claude/code-development.yml         # explicit path, never -A
git commit -m "Add code-development config for the /code-development skill"
git push -u origin chore/code-development-config
gh pr create --fill --base <default branch>

Never commit anything else in that commit, and never push to the default branch.

10. Ask whether to merge it. Merge only on an explicit yes, and only after the PR's own checks are in a state the user accepts. If they'd rather review it themselves, leave the PR open and say that the next /code-development run won't see the config until it lands on the branch being worked from.

11. Say which branch they're on now, and switch back to where they started unless they're continuing straight into a development run from here.

12. Offer to continue into a development run. The Task 1 sign-off gate still stands between that point and any code being written, so continuing is safe — but say so rather than assuming.

Setup mode never edits code, adds a test, adds a CI workflow, or starts Task 1. It discovers, validates, records, and stops.

The config

.claude/code-development.yml, in the repo being worked on:

version: 1

branch:
  default: main                   # what feature branches are cut from
  prefixes:
    feature: feature/
    fix: fix/

commands:                         # the local gate — all of these must pass before a commit
  test: "npm test"
  lint: "npm run lint"
  typecheck: "npm run typecheck"  # omit if the repo has none
  format: "npm run format -- --check"
  build: "npm run build"          # omit if a build isn't part of the local gate

ci:
  workflows: [".github/workflows/ci.yml"]
  enforces: ["lint", "test", "typecheck", "codeql"]
  local_gap: "CodeQL runs only in CI — nothing local reproduces it"

pr:
  base: main                      # a stacked PR targets the stage below instead
  ready: true                     # false → open as a draft
  conventional_commits: true
  template: ".github/pull_request_template.md"   # omit if the repo has none

docs:
  paths: ["README.md", "docs/**"]
  images: "docs/images"

screenshots:
  mode: playwright-local          # playwright-local | playwright-mock | none
  start: "npm run dev"            # omit when mode is none
  url: "http://localhost:5173"
  viewport: "1280x800"

Required: version, branch.default, and a commands block containing at least test. Everything else is optional, and every omission has exactly one defined behavior — never improvise a different one:

OmittedBehavior
branch.prefixesfeature/ and fix/
commands.lintNo lint step in the Task 2 gate — say so, don't invent one
commands.typecheck / format / buildNot part of the gate
ciNothing is claimed about what CI enforces; the CI-vs-local gap goes unstated
pr.basebranch.default
pr.readyReady for review, not draft
pr.templateThe Finish template below
pr.conventional_commitsTrue
docs.pathsDiscover docs/, README.md, a wiki dir — whatever the repo has
docs.imagesdocs/images
screenshots.viewport1280x800
screenshots entirelyTreat as mode: playwright-local, discovering the app's start command in Task 3 exactly as an unconfigured repo would

Phase 0 — Orient

Three steps, in order. Verify with real commands; assume nothing.

1. Ground it.

git rev-parse --show-toplevel && git branch --show-current
gh repo view --json nameWithOwner,defaultBranchRef
git status --porcelain      # dirty tree → stop and ask; never sweep stray work into a feature

2. Load the config. Read .claude/code-development.yml (accept .yaml too). Three outcomes — say which one you're in before doing anything else, and never silently degrade:

  • Found — echo the resolved config back in one short block: the test and lint commands that will gate the commit, the branch it'll cut from, whether the PR opens ready or draft, the screenshot mode, and the recorded CI-vs-local gap. The user should be able to catch a wrong value here, before any of it matters. Skip toolchain rediscovery — the file is the answer. Skipping it isn't the same as trusting it blindly: rule 7 still holds, and a recorded command that turns out not to exist gets caught at the point of use in Task 2, where it's a stop rather than a substitution.
  • Absent — say so and offer /code-development init. If they take it, run Setup, then come back here. If they decline, run the toolchain discovery inline for this run only and say plainly that nothing is being recorded.
  • Present but unparseable, or missing a required key — stop. Name the offending key. Don't fall back to defaults for a required field, and don't improvise a config to keep the run going.

branch.default is the branch feature work is cut from, which is usually — but not always — the repo's GitHub default. A project that develops off develop records that, and rule 4 still forbids pushing directly to either. If the two differ, say so in the echo rather than letting it surprise someone at PR time.

3. Check the branch you'll actually cut from is current, now that you know which one it is:

git fetch origin
git rev-list --count <branch.default>..origin/<branch.default>   # >0 → local is behind:
                                                                 # say so and ask whether to
                                                                 # pull before branching

Classify the request — feature, bugfix, or patch. All three run all three tasks. A bugfix can change how something looks, and stale screenshots left in the docs after a fix are a defect; Task 3 may conclude "no doc changes needed," but only after actually checking, never by category ("it's just a bugfix").

Then state the toolchain: the CI checks, the local equivalents, and any gap between them — read from the config, or discovered inline if there isn't one.

Task 1 — Scope and design

Goal: a written plan with zero open questions, signed off by the user.

Open by reminding the user this task is best run in plan mode (Shift+Tab twice in Claude Code), so nothing gets edited while the design is still open.

  1. Restate the request in your own words — what the change is for, not just what it says. A fix that clears the symptom but contradicts the intent is the wrong fix.
  2. Read before asking: the code in the affected area, related modules, existing tests, existing docs, and recent PRs touching the same files. Repo conventions win over generic best practice when they conflict.
  3. Research best practices for anything unfamiliar — web search the library, pattern, or security guidance involved. Cite what was found; "best practice says" with no source is a guess wearing a suit.
  4. Enumerate every open question and every design decision with more than one viable approach. For each decision: the options, their tradeoffs, which you'd pick and why. Ask them together in one message where possible, not as a drip-feed.
  5. Size it. A standard task is one PR a reviewer can hold in their head — one concern, a handful of files. Bigger than that → propose a stacked-PR breakdown: stage 1 branches off branch.default, each later stage branches off the previous, each PR targets the branch below it, landed bottom-up. Docs get their own stacked PR on top of the implementation stage(s) when the change is large; on a standard-size task they ride the same PR as separate commits. Name every branch in the plan.
  6. Write the plan: scope, out of scope, each design decision as resolved, files expected to change, test plan, doc and screenshot impact, PR structure (single or stacked, with branch names and bases).

Gate: post the plan and stop. Task 2 starts only on explicit sign-off — "approved", "go", or an edit followed by a go. Silence is not sign-off. If implementation later reveals the plan was wrong, this gate reopens; the plan is amended and re-approved, not quietly outgrown.

Task 2 — Implement

Goal: the planned change, at quality, committed on a branch with green local tests.

  1. Branch: <branch.prefixes.feature><slug> or <branch.prefixes.fix><slug> — feature/ and fix/ by default — cut from an up-to-date branch.default, or from the previous stage's branch when stacked.
  2. Implement exactly the plan — the smallest change that fully delivers it. Anything that turns out to need more than the plan said is a stop: reopen the Task 1 gate.
  3. Write to scanner standards even where the scanner can't run locally. The recurring Sonar/CodeQL/lint findings to design out rather than patch up afterward:
    • Validate and bound every external input. Parameterize queries. Never build shell commands, SQL, or file paths by concatenating user input.
    • Handle every error path explicitly — no swallowed exceptions, no bare except/empty catch, no ignored return values.
    • No secrets in code, config, tests, or fixtures. Ever. Not even placeholders that look real.
    • No duplicated blocks, no dead code, no TODO standing in for an implementation. Keep cognitive complexity down by extracting functions, not by nesting deeper.
    • Release everything acquired — files, connections, locks. Prefer context managers, defer, try-with-resources.
    • No new dependency and no version pin the plan didn't approve.
  4. Tests: targeted tests for the changed area, per the plan's test plan. A bugfix's test must fail on the pre-fix code — verify that by actually running it against the unfixed code, don't assume it.
  5. Run the gate: every command in the config's commands block — test, lint, and any typecheck/format/build recorded — or, with no config, the equivalents discovered in Phase 0. All green → commit. Anything red → fix it or stop and report. Committing red is never in bounds, and neither is narrowing the test run until it passes. If a recorded command isn't found, the config is stale: stop, name the key, and say what the repo has instead. Don't substitute a command of your own choosing.
  6. Commits: Conventional Commits when pr.conventional_commits is true (feat:, fix:, test:, refactor: only when the plan called for one), one concern per commit, implementation only — docs come in Task 3's own docs: commits. Stage files by name.

Gate: tests green, work committed, tree clean. Report the exact commands run and their real output before moving on.

Task 3 — Document

Goal: the docs match the code that was just written, images included.

  1. Find the docs: docs.paths from the config, else docs/, README.md, a wiki directory — whatever the repo actually has. No docs at all → create or extend README.md. That is the floor, not an option to skip.
  2. Write or update: what the change does, how to use it, config or flags added, breaking or behavior changes. For a bugfix: check whether existing docs describe the old, broken behavior, and correct them.
  3. Screenshots, whenever the change is user-visible and screenshots.mode isn't none:
    • Get the application running locally with screenshots.start at screenshots.url — or, with no config, discover how from the README, scripts, and compose files, the same way the toolchain was discovered. If a real run isn't possible in this environment, fall back to mocked data or component-level rendering under Playwright — and say plainly which of the two produced each image.
    • Capture with Playwright at screenshots.viewport (1280×800 by default, unless the repo's existing images establish otherwise), saved to docs.images (else where existing images live, else docs/images/), named for the feature, not the date.
    • Stale-image sweep, every run, bugfixes included: list the existing doc images that touch the changed area and re-capture any the change visibly altered.
    • If neither a local run nor a mock will render: capture nothing, claim nothing. List the exact captures still needed in the PR body as follow-up. A fabricated or misattributed screenshot is worse than a missing one.
    • screenshots.mode: none means this repo has nothing to screenshot. Say that's why there are no images; don't treat it as a skipped step.
  4. Commit docs separately (docs: commits) on the same branch — or on the docs stage's branch when stacked.

Finish — push and open the PR

  1. Push the branch. For stacked work, push each stage's branch.
  2. Open the PR with an explicit base — pr.base (defaulting to branch.default), or the previous stage's branch for a stacked PR. gh pr create without --base targets the repo's default branch, which silently flattens a stack into one enormous PR:

    gh pr create --base <pr.base or the stage below> --title "<title>" --body-file <file>

    Ready for review unless pr.ready is false or the user said otherwise; add --draft when it is.

  3. PR body, fully filled. Use pr.template if the repo has one; otherwise this template:

    ## What
    <the change in plain terms — what it does and why>
    
    ## Changes
    - <path> — <what changed and why>
    
    ## Tests
    <exact commands run and their real results — or "not run — <reason>">
    
    ## Docs
    <what was updated; screenshots added or replaced and how they were captured
    (real run vs. mock); stale images swept — or why no doc change was needed>
    
    ## Risks / follow-up
    <noticed but not handled; screenshot captures still needed; etc.>
  4. Hand off. The push triggers CI, and pipeline-monitor loads automatically from here — watching runs, diagnosing failures, fixing or escalating is its job, not this skill's. Say the handoff happened; do not duplicate it.

Scope boundaries

Always in bounds

  • Reading anything in the repo; web research during Task 1.
  • The planned change, its tests, its docs, its screenshots.
  • Offering (never silently adding) a basic CI workflow when none exists — in a development run, under the Task 1 gate.
  • Writing .claude/code-development.yml in setup mode, after showing it and getting confirmation — committing that one path on a branch, pushing, opening a PR, and merging that PR on an explicit yes.
  • Running the repo's own recorded commands to validate the config in setup mode, after saying which ones and getting a go-ahead.

Never in bounds, even when it would be faster

  • Starting Task 2 without sign-off, or Task 3 with red tests.
  • Committing or pushing code whose local tests didn't run or didn't pass.
  • Pushing directly to the default branch or to branch.default, force-pushing, or git add -A.
  • Weakening any check to get green — skipping tests, loosening lint rules, lowering coverage, continue-on-error, excluding files from a scanner.
  • Expanding scope beyond the signed-off plan without reopening the gate.
  • A new dependency, schema change, or workflow edit the plan didn't approve.
  • Fabricating a screenshot, or presenting a mock as the real application.
  • Writing, committing, or authoring any file other than .claude/code-development.yml while in setup mode — no code, no tests, no docs, no CI workflow. Setup records; it doesn't build.
  • Recording a command in the config without running it, or describing an unvalidated command as verified.
  • Substituting a different command when a recorded one is missing, instead of stopping.
  • Merging the config PR without an explicit yes.
  • Watching, re-running, or diagnosing CI — that's pipeline-monitor's job.

Stop and ask when

  • The repo has no remote, or gh/MCP has no write access to it (Phase 0 and Setup) — both modes end in a push and a PR.
  • No test command is detectable anywhere, so there is no gate to commit behind (Setup).
  • A config already exists and Setup was asked to write one (Setup).
  • The config is missing a required key, won't parse, or names a command the repo doesn't have (Phase 0 and Task 2).
  • Any design decision has more than one viable approach — Task 1 exists to surface these, not to smooth past them.
  • The working tree is dirty (Phase 0 and Setup), or the branch you'd cut from is behind origin (Phase 0).
  • Implementation reveals the plan was wrong or incomplete.
  • The correct fix and the fast fix disagree — surface the tradeoff, pick nothing.
  • A schema change, new dependency, or workflow change turns out to be needed.
  • Local tests can't run in this environment.
  • The app won't run and mocks won't render, so a needed screenshot can't be captured.
  • No CI workflows exist — offer to create them, then wait for the answer.

Reporting

Every task ends with its own block; the run ends with the PR link. Fixed format:

## code-development — <setup | scope | implement | document | finish> — <slug>

**Target:** <repo> @ <branch> (default: <trunk>)
**Config:** `.claude/code-development.yml` <loaded | written this run, PR <link> |
absent — discovered inline, nothing recorded>
**Status:** <config written, commands validated | config written, commands UNVALIDATED |
plan awaiting sign-off | committed, tests green | docs committed | PR open: <link>>

**Done:** <what this task actually produced>
**Commands run:** <exact commands and their real results, or "not run — <reason>">
**Open questions:** <anything blocking the next task, or "none">

Never fill Commands run with anything that did not execute. "Not run — <reason>" is a correct answer; a fabricated pass is the one failure mode that makes this skill worse than developing by hand. In setup mode the same rule covers validation: a command that wasn't run is reported as unvalidated, never as working.

If something doesn't match reality

The config describes what the repo was when someone wrote it. The repo is what is true now. When they disagree — the test script was renamed, the default branch moved, the docs directory changed — trust the repo, say exactly what you found, and stop rather than forcing the run to match the config. Tell the user which key is stale so they can fix .claude/code-development.yml in the same breath.

No repo, no gh, no discoverable way to run the tests, an application that won't start, a toolchain this skill can't identify — say exactly which, report what was and wasn't done, and stop. Don't reconstruct test results from reading the code, don't infer what CI enforces from the language alone, and don't present a mocked render as the live app. A plan built on an unverified assumption gets signed off and then implemented — which is exactly how a wrong guess becomes permanent.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.