chore(sdlc): adopt the SDLC loop (verify receipt, gates, stage workflows on codex) — closes #349 - #350
Conversation
Spec-stage trial with codex (provider in
|
Review matrix: Security / (root) (codex:default)FAIL — Review blocked; no security verdict established. Review matrix: Security / (root)SecurityNo findings established. Both file-read attempts exited with code 1 before returning content: The Verification section, Files read: 0 / unknown total touched by the diff. Files read in this cell: none. |
Review matrix: Bugs / (root) (codex:default)FAIL — review blocked; no conclusion about the changes. Review matrix: Bugs / (root)BugsNo findings established. File reads failed before execution with exit code 1: Consequently, I could not read the Verification section, Files read: 0 / unknown total touched by the diff. Files in this cell read: none. |
Review matrix: Compliance / (root) (codex:default)FAIL — review blocked; no PR compliance verdict established. Review matrix: Compliance / (root)ComplianceNo findings established. Both attempts to read No alternative local Read tool was available. Consequently, I could not inspect This cell requires rerunning with working repository read access. Files read: 0 / unknown total files touched by the diff. Files in this cell read: none. |
Review matrix: Bugs / .claude (codex:default)FAIL Review matrix: Bugs / .claudeBugsReview blocked; no code findings established. Every file-read attempt exited with code 1: I could not read the diff, Verification section, Files read: 0 / unknown total files touched by the diff. Files in this cell read: none. |
Review matrix: Security / .claude (codex:default)FAIL — review blocked; no verdict on the request’s security. Review matrix: Security / .claudeSecurityNo findings established. Repository reads failed with exit code Consequently, I could not read the Verification section, Files read: 0 / unknown total touched by the diff. Files read in this cell: none. |
Review matrix: Compliance / .claude (codex:default)FAIL Review matrix: Compliance / .claudeComplianceReview blocked; no PR findings established. Both file-read attempts exited with code 1 before returning content: Consequently, I could not read Files read: 0 / unknown total touched by the diff. Files in this cell read: none. |
Review matrix: Bugs / .github (codex:default)FAIL — review blocked; no code verdict. Review matrix: Bugs / .githubBugsNo findings established. File reads failed before execution with exit code 1: Consequently, I could not read the request’s Verification section, Files read: 0 / unknown total files touched by the diff. Files in this cell read: none. |
Review matrix: Security / .github (codex:default)FAIL Review matrix: Security / .githubSecurityReview blocked; no source findings established. Repository reads failed with exit code 1: I could not read the request’s Verification section, Files read: 0 / unknown total touched by the diff. Files in this cell read: none. |
Review matrix: Compliance / .github (codex:default)FAIL — Review blocked; no verdict on the request’s compliance. Review matrix: Compliance / .githubComplianceNo findings could be established. Repository reads failed with exit code 1: The diff, Verification section, Files read: 0 / unknown total touched by the diff. Files in this cell read: none. |
Review matrix: Bugs / docs (codex:default)FAIL Review matrix: Bugs / docsBugsReview blocked; no findings established. Both attempts to read No available Read tool or repository resource provided an alternative. I could not inspect the Verification section, This status indicates an incomplete review, not a demonstrated defect. Rerun this cell with working repository read access. Files read: 0 / unknown total touched by the diff. Files in this cell read: none. |
Review matrix: Security / docs (codex:default)FAIL Review matrix: Security / docsSecurityReview blocked; no findings established. Both file-read attempts exited with code 1: The diff, Verification section, Files read: 0 / unknown total touched by the diff. Files in this cell read: none. |
Review matrix: Compliance / docs (codex:default)FAIL — Review blocked; no PR compliance verdict established. Review matrix: Compliance / docsComplianceNo findings established. Both attempts to read Consequently, I could not read the Verification section, Restore repository read access and rerun this cell. Files read: 0 / unknown total touched by the diff. Files in this cell read: none. |
Review matrix: Bugs / evals (codex:default)FAIL — review blocked; no verdict on the code. Review matrix: Bugs / evalsBugsNo findings established. Repository reads failed before execution with exit code 1: Consequently, Files read: 0 / unknown files touched by the diff. Files read in this cell: none. |
Review matrix: Security / evals (codex:default)FAIL — review blocked; no code verdict. Review matrix: Security / evalsSecurityNo findings could be established. Repository reads failed with exit code 1: Consequently, Files read: 0 / unknown total files touched by the diff. Files in this cell read: none. |
Review matrix: Compliance / evals (codex:default)FAIL Review matrix: Compliance / evalsComplianceReview blocked; no repository findings established. Both file-read attempts exited with code 1: I could not read Files read: 0 / unknown total touched by the diff. Files read in this cell: none. |
"Done" in this repository now comes from the toolchain, not from the agent's report. `npm run verify` runs build, verify:release, the isolated suite, the packaged smoke and the dashboard e2e in order and, on green, writes .verify/receipt.json bound to the git tree hash; any later edit makes it stale. Claude Code project hooks (.claude/settings.json, .claude/hooks/) refuse to end a session, commit or push without a fresh receipt for the exact tree, refuse 20+ source lines on a branch with no docs/plans/<slug>.md, and refuse any hand-written .verify/. ci.yml gains an "SDLC verify" job that reruns the same steps and logs the tree hash so a quoted receipt can be compared with what CI saw. The stage workflows chain the artifacts: merging an accepted intent/<slug>.md produces docs/specs/<slug>.md as a PR (sdlc-loop.yml), merging that produces docs/plans/<slug>.md, merging that runs the build stage on sdlc/<slug>; sdlc-review.yml reviews with a different model than the implementer; sdlc-release.yml files a receipt after a release; sdlc-monitor.yml bands the CI failure rate on main. All project values live in sdlc/config.json; the scripts, hooks and prompts come from the sdlc-loop skill pack and are generic. memesh-specific: .gitignore stops ignoring all of .claude/ (four loop paths are tracked, everything else stays local) and docs/plans/ (dated scratch plans and the archive stay ignored); no public origin, so the release receipt runs qa:post-release against the registry, which gains --skip-machine (the runner is not an owner machine; reported NOT RUN); nine verification-audit hits triaged in scripts/audit/baseline.json; .nvmrc for the workflows; the PR template gets the Coverage table REVIEW.md reads; intent/observation-forget-survives-stop.md is the first intent, left as a draft (issue #346). Not automated here: the model credential, SDLC_GITHUB_TOKEN, branch protection and labels (scripts/sdlc/bootstrap.sh, owner-run). Refs #349 [Verified-By: node scripts/verify.mjs exit=0, GREEN, receipt for tree 8e1d57c; npm run sdlc:test exit=0, 45 pass / 0 fail; node scripts/audit/verification-audit.mjs exit=0]
The model provider is now sdlc/config.json agent.provider (codex here; claude and gemini are the other choices), built by scripts/sdlc/agent.mjs: run-stage, review and the evals ask it for the command and read back text, usage and tool calls in one shape. Workflows install the configured CLI and check its credential by name; the review workflow runs scripts/sdlc/review.mjs on any provider (one job, or a directory x pass matrix) instead of a Claude-only action; bootstrap prompts for the matching secret (OPENAI_API_KEY or the ChatGPT login file). Fixes from the fresh-eyes review of the first commit: the evals step lost node's exit code to tee (pipefail); the build stage could merge its own request (allowlist narrowed, merged-request check after the run, bootstrap explains the 0-vs-1 approval choice and reads the required checks from sdlc/config.json ci.requiredChecks); actions pinned to commit SHAs; @claude never runs fork code and fork PRs get a notice instead of a red check; hooks fail closed on a malformed payload; the build step is marked `regenerates` so the tracked dist/ no longer makes every first receipt stale; another project's names removed from the templates; monitor hourly with its artifact only on a breach; review prompt treats diff text as data; stale doc paths corrected. Refs #349 [Verified-By: node scripts/verify.mjs exit=0, GREEN, receipt for tree e816642; npm run sdlc:test exit=0, 55 pass / 0 fail; node scripts/audit/verification-audit.mjs exit=0]
The organization allows only GitHub-owned or its own actions, pinned to a full commit SHA; CI and SDLC review failed at startup on the first push (unpinned upload-artifact in ci.yml, anthropics/claude-code-action in the review workflow). The @claude fix loop now lives in its own template file, which this repository does not carry (provider is codex); the review workflow uses GitHub-owned actions only. Refs #349 [Verified-By: node scripts/verify.mjs exit=0, GREEN, receipt for tree 6a80cc1; npm run sdlc:test exit=0, 55 pass / 0 fail; node scripts/audit/verification-audit.mjs exit=0]
…stale runs, codex sandbox on runners
From the first real bootstrap and review runs on this PR:
- bootstrap step 1 skipped when a person typed "ChatGPT subscription"
instead of the keyword; it now maps a number, the keyword or plain
words and re-asks otherwise. Step 3 only printed an existing branch
protection; it now diffs it against sdlc/config.json (required checks,
admins) and offers the update.
- sdlc-review.yml: a new push cancels the review in flight (each matrix
cell is a model run).
- agent.mjs: codex's Linux sandbox failed on the Ubuntu 24.04 runner
("bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted"), so
every review cell reported FAIL with 0 files read; the install step
now relaxes kernel.apparmor_restrict_unprivileged_userns on CI Linux
and logs the outcome either way.
- baseline.json re-keyed for the moved lines.
Refs #349
…eipt On a pull_request event GitHub checks out a merge commit; its tree differs from the head's whenever main moved since the branch was cut, and the receipt comparison REVIEW.md asks for then fails for no reason (first run of #350 logged 326d37d while the local receipt was 6a80cc1). Strict status checks still require the branch to be up to date before merging. Refs #349 [Verified-By: node scripts/verify.mjs exit=0, GREEN, receipt for tree 7d63d9a (and 0763054 for the rebased tree before this commit); npm run sdlc:test exit=0, 55 pass / 0 fail]
The receipt and plan gates lived only in the Claude Code hook, so codex or a person at a shell could commit and push without a receipt and be caught only by CI. The decisions now live in scripts/sdlc/lib.mjs (commitGate, pushGate), shared by the Claude Code hook and by scripts/sdlc/git-gate.mjs, which the git hooks in scripts/sdlc/git-hooks/ call. scripts/sdlc/install-git-hooks.mjs copies them into the clone (never over a hook it did not write, unless --force); package.json's `prepare` runs it on every install, guarded so an unpacked tarball or a machine without the file gets a skip line instead of a failure. On a CI runner the gate lets the loop's own commits through and says so; `git commit --no-verify` remains git's escape hatch, and the CI verify job plus branch protection remain the gate nothing skips. Refs #349 [Verified-By: node scripts/verify.mjs exit=0, GREEN, receipt for tree 89ee4ba; npm run sdlc:test exit=0, 59 pass / 0 fail (a real git commit refused without a receipt and allowed with one); node scripts/audit/verification-audit.mjs exit=0; npm run prepare in an unpacked package dir exit=0]
a0e4f2a to
8ef9818
Compare
Review matrix: Security / (root) (codex:default)FAIL Review matrix: Security / (root)Security
Read in full: 9/68 changed files, including 5/5 root-cell files. Additional files: Files read in this cell:
|
Review matrix: Bugs / (root) (codex:default)FAIL Review matrix: Bugs / (root)Bugs
Read 14 of 68 changed files, including 5 of 5 root files. Evidence is source inspection; runtime tests were not run in the read-only environment. Files read in this cell:
|
Review matrix: Compliance / (root) (codex:default)FAIL Review matrix: Compliance / (root)Compliance
Read in full: 13/68 changed files, including 5/5 root-cell files. Root-cell files read:
|
Review matrix: Bugs / .claude (codex:default)FAIL Review matrix: Bugs / .claudeBugs
Read in full: 20/68 changed files, including 14/14 files in this cell. Full test suites were not run in the read-only workspace. Files read in this cell:
|
Review matrix: Security / .claude (codex:default)FAIL Review matrix: Security / .claudeSecurity
Read in full: 19/68 changed files, including 14/14 files in this cell. Findings are limited to Security. Files read in this cell:
|
Review matrix: Compliance / .claude (codex:default)FAIL Review matrix: Compliance / .claudeCompliance
Plan/spec comparison was unavailable: tracked Read in full: 23/68 changed files, including 14/14 files in this cell. No passing runtime-test claim is made. Files read in this cell:
|
Review matrix: Security / docs (codex:default)FAIL Review matrix: Security / docsSecurity
Read in full: 5/5 files in this cell, out of 68 files touched by the diff.
|
The installed-hook test ran a real git commit under GITHUB_ACTIONS, where the gate lets the loop's own commits through by design, so the refusal it asserted never happened on CI (Harness evals and SDLC verify red on the previous push). Refs #349 [Verified-By: node scripts/verify.mjs exit=0, GREEN, receipt for tree e78349c; GITHUB_ACTIONS=true npm run sdlc:test exit=0, 59 pass / 0 fail]
Review matrix: Bugs / evals (codex:default)FAIL Review matrix: Bugs / evalsBugs
Read in full: 13/68 changed files, including 7/7 files in this cell. Model-backed evals and full verification were not run. Files read in this cell:
|
Review matrix: Security / (root) (codex:default)PASS Review matrix: Security / (root)SecurityNo Important or Nit findings in this cell. No dependencies changed. Inspected the new Verification claims were read, but CI results were not independently confirmed. Read in full: 5/5 cell files; 10/68 changed files overall, including supporting files. Cell files read:
|
Review matrix: Bugs / (root) (codex:default)FAIL Review matrix: Bugs / (root)Bugs
Read in full: 13/68 changed files, including 5/5 root-cell files. Supporting changed files: the installer, verifier, SDLC config, CI workflow, and four plan/spec README/template files. Files read in this cell:
|
Review matrix: Compliance / (root) (codex:default)FAIL Review matrix: Compliance / (root)Compliance
Coverage: all 68 changed files have Coverage-table rows. Read 12/68 changed files in full, including 5/5 root-cell files. Root-cell files read:
|
Review matrix: Bugs / .claude (codex:default)FAIL Review matrix: Bugs / .claudeBugs
Coverage: 14/14 files in this cell, from 68 files touched by the diff. Probes used mocked dependencies; the filesystem-writing test suite was not run in the read-only sandbox. Files read in this cell:
|
Review matrix: Compliance / .claude (codex:default)FAIL Review matrix: Compliance / .claudeCompliance
Coverage: read 14/14 changed files in this cell, within 68 total changed files. The request Coverage table includes all 68 paths. No tests were run in this read-only review. Files read in this cell:
|
Review matrix: Security / .claude (codex:default)FAIL Review matrix: Security / .claudeSecurityImportant — cat /dev/null
node -e "require('fs').writeFileSync('.verify/receipt.json','{}')"Read-only function probes returned: All three returned no git subcommands, so the bypasses reach Reject substitutions and additional commands in the read-only exception, and add regression tests for both shapes. Probes evaluated the guard functions only; no receipt was written. Fully read 21 of 68 changed files, including 14 of 14 files in this cell. Files read in this cell:
|
Review matrix: Security / .github (codex:default)FAIL Review matrix: Security / .githubSecurity
Static review findings; no credential extraction was attempted. Read 15 of 68 changed files in full, including 7 of 7 files in this cell. Files read in this cell:
|
Review matrix: Compliance / .github (codex:default)FAIL Review matrix: Compliance / .githubCompliance
Read in full: 15/68 changed files, including 7/7 files in this cell. Files read in this cell:
|
Review matrix: Bugs / .github (codex:default)FAIL Review matrix: Bugs / .githubBugs
Read in full: 16/68 changed files, including 7/7 files in this cell. Workflow findings are based on source inspection and the stated read-only probes; no Actions run was replayed. Files read in this cell:
|
Review matrix: Security / docs (codex:default)FAIL Review matrix: Security / docsSecurity
Cell coverage: 5/5 changed documentation files, within 68 files touched by the diff. Static review; no live merge attempted. Files read in this cell:
|
Review matrix: Bugs / docs (codex:default)FAIL Review matrix: Bugs / docsBugs
Runtime validation was limited: the smoke test exited 1, reporting Cell coverage: 5/5 changed docs files, out of 68 files touched by the complete diff. Files read in full in this cell:
|
Review matrix: Compliance / docs (codex:default)FAIL Review matrix: Compliance / docsCompliance
Read in full: 10/68 changed files overall; 5/5 files in this cell. Files read in this cell:
|
Review matrix: Security / evals (codex:default)PASS Review matrix: Security / evalsSecurityNo security findings in the seven changed Coverage: 7/7 files in this cell, out of 68 files touched by the diff. Files read in full:
|
Review matrix: Bugs / evals (codex:default)FAIL Review matrix: Bugs / evalsBugs
Read 12/68 changed files in full, including 7/7 files in this cell. Model-backed evals were not run. Files read in this cell:
|
Review matrix: Bugs / intent (codex:default)PASS Review matrix: Bugs / intentBugsNo findings. The read-only workflow probe exited 0: {"status":"draft","validSlug":true,"pending":[]}Coverage: 3/3 files in this cell read in full; 7/68 changed files read in full overall. Verdict covers only Bugs / intent. Files read in this cell:
|
Review matrix: Security / intent (codex:default)PASS Review matrix: Security / intentSecurityNo security findings in the three changed Coverage: 3/3 cell files, out of 68 files touched by the diff. Verdict covers only Security / intent. Files read in this cell:
|
Review matrix: Compliance / intent (codex:default)FAIL Review matrix: Compliance / intentCompliance
No additional compliance findings in Read in full: 10/68 changed files, including 3/3 files in this cell. Cell files read:
|
Review matrix: Compliance / evals (codex:default)FAIL Review matrix: Compliance / evalsCompliance
Read in full: 17/68 changed files, including 7/7 files in this cell. All 68 changed files have Coverage rows. Files read in this cell:
|
Review matrix: Bugs / scripts (codex:default)FAIL Review matrix: Bugs / scriptsBugs
Probes used in-memory filesystem/process doubles. Full verification was not run in the read-only environment. Read 35/68 changed files in full, including 26/26 files in this cell. Files read in this cell:
|
Review matrix: Security / scripts (codex:default)FAIL Review matrix: Security / scriptsSecurity
CI verification could not be independently checked: the GitHub API request failed with Read 32/68 changed files, including 26/26 files in this cell. Files read in this cell:
|
Review matrix: Compliance / scripts (codex:default)FAIL Review matrix: Compliance / scriptsCompliance
Read in full: 36/68 changed files, including 26/26 files in this cell. No nits reported. Files read in this cell:
|
Review matrix: Security / sdlc (codex:default)PASS Review matrix: Security / sdlcSecurityNo security findings in Static review only; CI receipt correspondence was not independently verified. Cell coverage: 1/1 files, out of 68 files touched by the diff. Files read in this cell:
|
Review matrix: Bugs / sdlc (codex:default)FAIL Review matrix: Bugs / sdlcBugs
Read in full: 10/68 changed files, including 1/1 files in this cell. Files read in this cell:
|
Review matrix: Compliance / sdlc (codex:default)FAIL Review matrix: Compliance / sdlcCompliance
Coverage table: all 68 changed files have rows. Changed files read in full: 15/68 overall; 1/1 in this cell. Files read in this cell:
|
Summary
Installs the SDLC loop from the
sdlc-loopskill pack: onenpm run verifywhose green result is a receipt bound to the git tree hash, Claude Code project hooks that refuse to end a session, commit or push without it, anSDLC verifyCI job that reruns the same steps, and the stage workflows (intent → spec → plan → build → review → release receipt → monitor) with the model provider set to codex (sdlc/config.json→agent.provider). Closes #349.Type of change
Docs synced (project doc-sync rule —
CLAUDE.md)[Unreleased]or current[X.Y.Z]section) — not a user-facing change; no entryCLAUDE.md: "Verifying your work" section, working-notes bullet;docs/sdlc/LOOP.md,REVIEW.md,intent/,docs/specs/,docs/plans/READMEs and templates addedmemesh doctorreportsOverall: PASS— run bynpm run verify(packaged smoke) on this treeVerification
Receipt:
.verify/receipt.jsonfor tree4d23980cf1eed23fc2a0b1fbeab612638b69dc36(compare with the[verify] treeline of theSDLC verifycheck on this PR).npm run typecheckclean (insideverify:release, step 2 of verify)npm run buildclean (step 1 of verify; regenerates the trackeddist/, tree re-baselined)node scripts/run-tests-isolated.mjspassing (step 3 of verify, exit 0)npm run sdlc:testexit 0 — 59 pass, 0 fail (receipt, hooks, git-native gates, state machine, provider layer, smoke command)docs/specs/observation-forget-survives-stop.mdpassingcheckArtifact, no other file changed (see the comment below)qa:post-release --version 4.9.4 --skip-machinePASS against the registry throughscripts/sdlc/smoke-public.mjs(exit 0)Test plan
npm run sdlc:test→ 55 passnpm run verify→ ends with[verify] GREEN. Receipt for tree <hash> written to .verify/receipt.json.;npm run verify:receipt→freshgit commit→ blocked untilnpm run verifyis greennode scripts/sdlc/next-stage.mjs --human→ nothing pending (the intent isstatus: draft)bash scripts/sdlc/bootstrap.sh(OPENAI_API_KEY or CODEX_AUTH_JSON, SDLC_GITHUB_TOKEN, branch protection incl.SDLC verify, labels), then flipintent/observation-forget-survives-stop.mdtostatus: acceptedKnown limitations / follow-ups
CODEX_AUTH_JSON,SDLC_GITHUB_TOKENand the labels; branch protection still lacksSDLC verifyand enforce_admins (rerunbash scripts/sdlc/bootstrap.sh, step 3 now offers the update).mainis red oncheck-version-coherence(4.10.0 declared, no tag); the monitor'sci_failure_rate_mainband will show it until the release is finished.npm install(prepare) after merge;git commit --no-verifyskips them, as it skips any git hook, and CI plus branch protection remain the gate that cannot be skipped.agent.mjssays so); codex and claude ran the spec stage end to end, and codex reviews this PR from CI.SDLC_GITHUB_TOKENowned by the maintainer, branch protection stays at 0 approvals (a person cannot approve their own PR); bootstrap prints the consequence. A separate machine account for the token enables 1 approval + code-owner review.docs/plans/stay ignored by the new rule and untouched.Coverage (one row per changed file —
REVIEW.md).claude/agents/journey-verifier.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in full.claude/hooks/hooks.test.mjs(added)npm run sdlc:testexit=0 (59 pass, 0 fail)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.claude/hooks/lib.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.claude/hooks/pre-bash-gate.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.claude/hooks/protect-verify-dir.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.claude/hooks/session-start.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.claude/hooks/stop-receipt.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.claude/sdlc/PR_TEMPLATE.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in full.claude/sdlc/prompts/build.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in full.claude/sdlc/prompts/diagnose.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in full.claude/sdlc/prompts/plan.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in full.claude/sdlc/prompts/review.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in full.claude/sdlc/prompts/spec.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in full.claude/settings.json(added)npm run sdlc:testexactly as Claude Code spawns them (59 pass).github/pull_request_template.md(modified)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in full.github/workflows/ci.yml(modified)SDLC verifyjob runs on this PR (see checks)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.github/workflows/sdlc-evals.yml(added)python3 -c 'yaml.safe_load'exit=0;node scripts/sdlc/agent.mjs --checkexit=1 without a secret (::error), exit=0 with one; not run on CI yet (needs the bootstrap secrets)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.github/workflows/sdlc-loop.yml(added)python3 -c 'yaml.safe_load'exit=0;node scripts/sdlc/agent.mjs --checkexit=1 without a secret (::error), exit=0 with one; not run on CI yet (needs the bootstrap secrets)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.github/workflows/sdlc-monitor.yml(added)python3 -c 'yaml.safe_load'exit=0;node scripts/sdlc/agent.mjs --checkexit=1 without a secret (::error), exit=0 with one; not run on CI yet (needs the bootstrap secrets)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.github/workflows/sdlc-release.yml(added)python3 -c 'yaml.safe_load'exit=0;node scripts/sdlc/agent.mjs --checkexit=1 without a secret (::error), exit=0 with one; not run on CI yet (needs the bootstrap secrets)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.github/workflows/sdlc-review.yml(added)python3 -c 'yaml.safe_load'exit=0;node scripts/sdlc/agent.mjs --checkexit=1 without a secret (::error), exit=0 with one; not run on CI yet (needs the bootstrap secrets)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.gitignore(modified)git check-ignoreon 13 paths: the four.claude/loop paths anddocs/plans/<slug>.mdtracked;settings.local.json, other agents, dated plans,_archive*,.verify/,.sdlc-run/ignoredagentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per project.nvmrc(added)node -v22 matches ci.yml legs; workflows use node-version-fileagentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectCLAUDE.md(modified)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fullREVIEW.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fulldocs/plans/README.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fulldocs/plans/TEMPLATE.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fulldocs/sdlc/LOOP.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fulldocs/specs/README.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fulldocs/specs/TEMPLATE.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fullevals/README.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fullevals/cases/no-plan-no-build.json(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fullevals/cases/verify-before-done.json(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fullevals/checks/consulted-receipt.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectevals/checks/mentions-plan-proof.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectevals/lib.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectevals/run.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectintent/README.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fullintent/TEMPLATE.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fullintent/observation-forget-survives-stop.md(added)npm run verify:releaseexit=0 (check-doc-claims: no dangling paths); read in fullpackage.json(modified)npm run sdlc:testexit=0;npm run verifyexit=0 (scripts resolve)scripts/audit/baseline.json(modified)node scripts/audit/verification-audit.mjsexit=0 (9 hits triaged, 5 re-keyed)scripts/qa/post-release.mjs(modified)node scripts/sdlc/smoke-public.mjs --sha ed091744 --version 4.9.4exit=0 (qa:post-release --skip-machine PASS against the registry)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/agent.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/agent.test.mjs(added)npm run sdlc:testexit=0 (59 pass, 0 fail)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/bootstrap.sh(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/cli.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/git-gate.mjs(added)npm run sdlc:testexit=0 (git-gate.test.mjs: a realgit commitrefused without a receipt and with a partial index, allowed with a matching receipt; foreign hook not overwritten);npm run preparein an unpacked package dir exit=0 with the skip lineagentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/git-gate.test.mjs(added)npm run sdlc:testexit=0 (59 pass, 0 fail)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/git-hooks/pre-commit(added)npm run sdlc:testexit=0 (git-gate.test.mjs: a realgit commitrefused without a receipt and with a partial index, allowed with a matching receipt; foreign hook not overwritten);npm run preparein an unpacked package dir exit=0 with the skip lineagentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/git-hooks/pre-push(added)npm run sdlc:testexit=0 (git-gate.test.mjs: a realgit commitrefused without a receipt and with a partial index, allowed with a matching receipt; foreign hook not overwritten);npm run preparein an unpacked package dir exit=0 with the skip lineagentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/host.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/install-git-hooks.mjs(added)npm run sdlc:testexit=0 (git-gate.test.mjs: a realgit commitrefused without a receipt and with a partial index, allowed with a matching receipt; foreign hook not overwritten);npm run preparein an unpacked package dir exit=0 with the skip lineagentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/lib.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/lib.test.mjs(added)npm run sdlc:testexit=0 (59 pass, 0 fail)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/monitor.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/monitor.test.mjs(added)npm run sdlc:testexit=0 (59 pass, 0 fail)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/next-stage.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/next-stage.test.mjs(added)npm run sdlc:testexit=0 (59 pass, 0 fail)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/review.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/run-stage.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/run-stage.test.mjs(added)npm run sdlc:testexit=0 (59 pass, 0 fail)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/smoke-public.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/sdlc/smoke-public.test.mjs(added)npm run sdlc:testexit=0 (59 pass, 0 fail)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/verify-receipt.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/verify.mjs(added)npm run sdlc:testexit=0 (59 pass);node scripts/verify.mjsexit=0agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectscripts/verify.test.mjs(added)npm run sdlc:testexit=0 (59 pass, 0 fail)agentEnv/claudeArgsremoved, duplicated Coverage section and gitignore block removed; templates are copies of~/Developer/Projects/sdlc-loopand are not edited per projectsdlc/config.json(added)node scripts/verify.mjsexit=0 used it;node scripts/sdlc/next-stage.mjs --humanexit=0;run-stage --dry-runexit=0 (codex exec, workspace-write)