claude-code-sdlc
CLAUDE.md52 starsChanged 20 days agoMITView on GitHub
The harness itself. It dogfoods its own pipeline, so everything the agents enforce applies here too. This repository has no package.json, no build step and no runtime dependencies — it ships markdown and zero-dependency Node scripts. Its equivalent of a typecheck is: Use that, not a bare validator loop. This is not a style preference — it is the difference between evidence and none: That loop invokes each validator bare, skipping the ~40 seeded-fixture assertions (--root <fixture> --expect-failure … --expect-problems…
- Commits and pushes
In this repository10 other files it gives its agents.
- src/claude.mdCLAUDE.md
- templates/CLAUDE.mdCLAUDE.md
- bootstrap-featureSkill
- context-refreshSkill
- design-foundationSkill
- develop-featureSkill
- implement-sliceSkill
- merge-readySkill
- sdlc-fastSkill
- sdlc-quickSkill
The file
Files
claude-code-sdlc
The harness itself. It dogfoods its own pipeline, so everything the agents enforce applies here too.
Commands
This repository has no package.json, no build step and no runtime dependencies — it ships markdown
and zero-dependency Node scripts. Its equivalent of a typecheck is:
node scripts/ci/ci-parity.js # runs exactly what CI runs, read from ci.ymlUse that, not a bare validator loop. This is not a style preference — it is the difference between evidence and none:
for v in scripts/ci/validate-*.js; do node "$v" || exit 1; done # NOT sufficientThat loop invokes each validator bare, skipping the ~40 seeded-fixture assertions
(--root <fixture> --expect-failure … --expect-problems N) that CI also runs — the very checks that
make a validator evidence rather than decoration. It passes while CI fails. Measured: main sat red
for 16 consecutive runs across five releases (4.5.0–4.9.0) while that loop stayed green the whole
time, because three fixtures had silently stopped isolating and one validator was wired into nothing.
ci-parity.js --check-coverage now fails if any validate-*.js is missing from ci.yml.
Those check structure and hook logic. They do not check that the instructions this harness ships actually steer a real session — that is what the behavioural eval is for:
node scripts/eval/run-evals.js --dry-run # free: show the plan
node scripts/eval/run-evals.js # COSTS MONEY: real headless sessions, gradedIt sits outside the sweep because it spends real tokens; its grading logic is unit-tested for free
inside the sweep (tests/hooks/test-eval-graders.js, 30 checks, 8 seeded-broken). Read
evals/README.md before believing a failure — two separate instrument bugs produced confident
false results the first two times it ran, both pointing at the product while the eval itself was
broken.
Release
Read this before publishing anything. The ordering below is the whole point.
What ships to an installed user is the version advertised in .claude-plugin/marketplace.json.
claude plugin update compares that number against the installed one and never looks at the
commit. A merge that does not move it delivers nothing while reporting success — measured on
Claude Code 2.1.9, ten commits sat undelivered behind an unmoved 4.0.0.
Two consequences that are easy to get backwards:
- A git tag does not ship anything. The marketplace tracks
main, not tags. Tagging a stale version produces a repository that looks released and an install base that receives nothing. - Scopes update independently. A user-scope update leaves every project-scope install on the old
version until each one runs
--scope project.
Procedure
- Bump the version in all four sources — they must agree. Derive the next number from
origin/main's currently advertised version at release time — fetch, then read
plugins[0].versionfrom origin/main's.claude-plugin/marketplace.json(git fetch origin main && git show origin/main:.claude-plugin/marketplace.json) — never from a number remembered earlier in a branch or session: with parallel feature sessions, two branches that each memorized "current is X" both compute X+1 and collide..claude-plugin/marketplace.json→plugins[0].version← this is the one that ships.claude-plugin/plugin.json→versioninstall.sh→VERSION="..."README.md→ the version badge
- Verify the bump:
node scripts/ci/validate-version-consistency.js node scripts/ci/validate-release-readiness.js - Commit and push to
main. This is the step that actually delivers, because the marketplace tracksmain. The push that runs carries the guards:- Push the feature branch first, so CI runs on the exact SHA, and wait for CI green on it.
ci-parity.jsskips multi-linerun: |steps; CI does not. - Confirm the push with the user at push time.
- Publish the verified SHA with
SDLC_ALLOW_GIT_GUARD=1 git push origin "<sha>":refs/heads/main: fast-forward only, never--force, never a+refspec.
- Push the feature branch first, so CI runs on the exact SHA, and wait for CI green on it.
- Cut the GitHub release — documentation and discovery, using notes derived from the
CHANGELOG.mdentry:gh release create v<version> --target main --title "v<version> — <headline>" --notes-file <file> - Sync the outward-facing surfaces that live outside the repository:
GitHub's About panel, topics and homepage are not files, so no grep, validator or review can see them drift — the description sat at "13 AI agents" through two major versions for exactly that reason. The script derives them from./scripts/release/sync-repo-metadata.sh.claude-plugin/plugin.jsonso there is no second copy to fall out of date. It is idempotent; run it every release. - Confirm delivery rather than assuming it:
claude plugin marketplace update claude-code-sdlc claude plugin update claude-code-sdlc@claude-code-sdlc claude plugin list # expect the new version
Version choice
Patch for a fix, minor for new capability, major for a change to how consumers install, invoke or configure the harness. Never reuse a published number.
Working Rules
- Budgets are hard caps. ≤16 agents, ≤10 skills, ≤12 hook ids. Current: 16 / 8 / 12 —
agents AND hooks are both AT their ceilings now (the 16th slot went to
design-reviewer, deliberately — a seventeenth agent requires retiring one), and for hooks — hooks are AT the ceiling with no slot left, so a thirteenth requires retiring one. Ids, not registrations:pre:edit:read-guardlistens on two events and is one hook. - Instruction text has a budget too, and it is the one actually charged per session:
node scripts/ci/validate-context-budget.js --report. Ceilings are in bytes becauseclaude plugin detailsscores the installed cache, not the working tree — it cannot tell you whether a cut worked until after you have shipped it. Conversion is measured, not assumed (tokens ≈ bytes / 2.78,docs/findings/context-cost-calibration.md). Weight before you cut:implement-sliceis paid once per slice, so a byte there costs ~8× a byte inmerge-ready. The memory layer is scored too, since it loads every session:src/claude.md23500 andsrc/rules/topic-closure.md5000 (the rule itself is held to 4,950 byvalidate-topic-closure.js). - Every validator must fail on a seeded broken fixture, pinned to an exact problem count. A check that only ever passes is not evidence.
- Measure Claude Code's behaviour; do not read it off the docs. Several documented claims have
turned out false here. Findings from real measurement live in
docs/findings/. - Hooks fail open. A hook may block only by deciding to; a malfunctioning one exits 0.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
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.

