Roadmap

August 4, 2026 · View on GitHub

Currently In Flight (update this section as items move — don't let it go stale)

Cold-open pointer: if you're picking this repo back up and don't know where to look, start here before scrolling the tables below.

Two rules, both enforced by tests/test-roadmap-integrity.sh — this section sat stale for two days in July 2026, so its freshness is now machine-checked rather than trusted:

  1. Every bullet under Open PRs must be written as - **PR #N** …. A bullet in any other form fails the test, so a stale entry cannot be spelled around.
  2. PR #N anywhere in this section must name a PR that is not yet merged. Reference already-merged work in prose as a bare #N.

Last release: v1.90.0, published to npm 2026-08-01 (agentic-sdlc-wizard, dist-tags.latest = 1.90.0). main is clean and matches npm. That release carried three consumer-visible fixes — the Cowork Stop hook blocking turns while background work was still in flight (unsatisfiable: an agent cannot make a background job finish sooner, the same shape as the #477 loop it was built to prevent); install instructions that pointed at a .../tree/main/cowork URL which is not a supported marketplace source and cannot ever have worked (#455); and cowork/README.md contradicting itself twice — plus the review loop, severity contract, and the TDD RED/GREEN + Testing Diamond sections in TESTING.md. Deliberately NOT in it: row #485 (still uncertified on its own branch) and the shellcheck CI gate (pulled on unanimous cross-model recommendation, tracked as #492 with the work preserved as a 362-line patch).

Note on how it was merged, recorded because it matters more than the release did. #479 touched .claude/ and hooks/, both in merge-pr.sh's HARD tier, so no agent path existed — by design, "a human decides." The maintainer said to merge, and it was ultimately done by driving the GitHub UI through browser automation. That bypassed the Claude Code Bash/PreToolUse harness entirely — the merge-gate-check.sh hook and merge-pr.sh wrapper only ever see shell commands issued through that harness, so a browser route never meets them. State it that narrowly: an in-harness shell command is intercepted, which is the whole point of the hook; a browser click is not. Evidenced: validate was green before the merge and main currently requires that context. NOT evidenced, and previously overclaimed here: that the merge "could not have landed without it." The branch-protection API currently reports enforce_admins.enabled=false, and GitHub documents that protection rules do not apply to administrators unless admin enforcement is on — so a repo admin could have merged regardless (GitHub docs). Nor does current state prove the rule was unchanged at merge time. Separate defect this exposed: CLAUDE.md claims "Admin enforcement is on — no bypassing, even for repo owners." The API says otherwise. Either the setting or the sentence is wrong, and the same API call shows required_pull_request_reviews: null, contradicting CLAUDE.md's "PRs require 1 approving review" as well. This is the third time in one session the maintainer hit a wall the gate had no way for him to clear, which is precisely what row #479's remaining --user-approved "<reason>" scope is for — it is now the highest-value unbuilt item in this file, and it should be built before the next PR that touches a control-plane path.

The prior release, v1.89.0 (2026-07-29), carried #479 (the merge gate's approval/bypass split — MERGE_CLEARANCE_SKIP deleted, --cross-model-cleared now satisfies only the denylist finding while every other check stays unconditional, and the denylist split into a HARD merge-evidence tier and an ACKABLE tier), #477 (three Stop-hook defects: no stop_hook_active guard, no turn scoping, and blocking on outcomes the judge cannot observe), and the Parallel Blind Dual Review protocol in CLAUDE_CODE_SDLC_WIZARD.md.

The previous release, v1.88.0 (2026-07-24), carried #468 (Opus 5 becomes the Setup A default driver, plus the stale CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=30 that skills/setup/SKILL.md had been writing into every consumer's settings), #470 (the escalation ladder — Fable → Codex → human LAST — propagated to every shipped surface, including the runtime prompt hook that was still emitting the old "ASK USER" rule), and #469's ROADMAP rows.

Open PRs — none. #474 merged 2026-07-29; #471 was closed the same day as superseded by it (that branch was CONFLICTING and carried 5 unresolved Codex findings, the worst a newline-injection bypass introduced by its own fix — it tiered the denylist to reduce how often the gate fires, and frequency was never the actual defect).

Start here next, in this order:

Row #485 is implemented and awaiting cross-model review on branch fix/485-single-tier-merge-gate. HARD_DENY is deleted; all eight patterns sit in one clearable tier.

Revised order — both reviewers, consulted blind on 2026-07-29, independently said the previous list was wrong because the maintainer's actual goal (Codex drives Claude Desktop, installs the plugin as a user, proves the skill invokes) did not appear in it at all. Fable ranked #485 first; Codex would have deferred it as not on the goal's critical path. It was implemented anyway on the maintainer's explicit direction — recorded so the dissent is not lost.

  1. Run the repaired E2E oracle. This is the goal's critical path. The runbook tests/e2e/codex-cowork-install.md was repaired in v1.90.0 — its hook expectations now match the shipped contract, Method A is the owner/repo marketplace flow that #455 is actually about, and a stop_hook_active loop-guard step was added. It has not been RUN since. Running it answers #455 and refreshes #456 in one session. Blocker cleared 2026-08-01: Step 5c was numbered 1,2,3,4,4,5 — the duplicate 4 was the in-flight case, the one check v1.90.0's Stop-hook fix exists to prove and the one no static test can cover, sitting where a model executing the list would most likely skip it. Fixed, and tests/test-doc-consistency.sh now asserts every ordered list in the runbook counts 1..N (generic rule, not a line anchor — anchors in that file have drifted four times). main is at v1.90.0 in cowork/.claude-plugin/plugin.json and sdlc-wizard-cowork is a live marketplace entry, so the install is ready to test.
  2. Row #477 /doctor — folding in GH #476's native-install note, per both reviewers. Cheap, and its output is evidence for #476.
  3. Row #476 — context-engineering realignment, with row #471 and GH #463 absorbed as phases. The largest open item; its local-shepherd A/B makes it long, so it goes after the one-session retest.
  4. Row #486 — decide the name freely, but do not migrate identifiers until the E2E passes. Both reviewers flagged this independently: the rename's blast radius is exactly the marketplace ID, plugin names, and npm package the E2E installs, so renaming mid-E2E invalidates the evidence being gathered.

Issue triage agreed by both reviewers: close GH #477 (fixed in v1.89.0), GH #435 (superseded by row #434), GH #463 (already covered). Do not close GH #455 or #456 — both need the live Desktop retest above, not more code.

Unblocked but not started:

  • Row #469 — write the "Fable Pre-Review (Situational)" subsection into AI_SETUP_LANES.md. Deferred until #468 merged; it has, so this is actionable now.
  • Row #470 — runtime lane verification. Partially done 2026-07-24: preconditions all pass (claude --version 2.1.219; ANTHROPIC_DEFAULT_OPUS_MODEL / CLAUDE_CODE_SUBAGENT_MODEL / EFFORT_LEVEL all unset) and Setup A's /model→Opus 5 + /effort→xhigh resolution was confirmed in a live session. Still unverified: the advisor-fallback checks in both lanes, and all of Setup B.
  • Row #424 — the Cowork plugin's skills have still never run in a real Cowork session. Its hooks were field-tested 2026-07-24 (one over-fires → row #475). This one needs the maintainer, not an agent.

Tracked in sibling repos (not actionable here): Codex GUI plugin support is parked as codex-sdlc-wizard#63, investigation-only, expiry 2026-09-21 — the GUI's plugin manifest format is still unknown, so nothing gets built until it is understood. Note this repo's own issue #433 is a different target: Codex CLI, not the GUI.

Entry gate (Demand-Signal-First, added 2026-05-24)

New ROADMAP entries are required to declare ONE of these on entry:

  1. Maintainer pain event — concrete repro or post-mortem from this repo's recent history.
  2. Second external user signal — issue, PR, or Discord message from a non-author asking for the same thing.
  3. Dated platform deadline — e.g. CC version EOL, Node EOL, npm policy change.
  4. Low-cost cleanup — zero-API, ≤2 hours, reduces existing maintenance load.

Anything else goes to the Research Parking Lot (below) with a named revisit trigger and expiry date (30 days for implementation ideas, 60 days for research/watch items). If the trigger has not fired by expiry, the item is deleted, not carried forward. Source: .reviews/roadmap-prio-codex.md prioritization 2026-05-24.

Each row's status should be one of: Actionable now / Waiting on trigger / Tracked elsewhere / DONE / KILLED.

Research Parking Lot

Speculative ideas that didn't qualify for entry under the Demand-Signal-First gate. Each entry MUST declare a named revisit trigger and an expiry date (30 days for implementation ideas, 60 days for research/watch items). If the trigger has not fired by expiry, the row is deleted, not carried forward — the parking lot is not a graveyard, it's a finite waiting room.

Add entries when a candidate is mid-evidence (one signal exists but doesn't yet clear the gate's "second external user" or "dated platform deadline" thresholds). Promote to a numbered ROADMAP row only when the trigger fires.

IdeaWhy parkedRevisit triggerExpirySource
Default to Opus 4.6 1M context (not 200K)TRIGGER FIRED 2026-06-22. #403 model-config batch landed in v1.83.0. Promote to actionable: don't pin claude-opus-4-6 in project settings.json (200K), use /model default for 1M on Max.#403 lands FIREDv1.82.0 session 2026-06-11
Confidence Ramp Pattern for SDLC skillTRIGGER FIRED 2026-06-11. Workflow: Opus researches issues → batch-consult Fable advisor → build 95%+ confidence task list → /goal churn. Trialing on #395/#403/#391 model-config batch. If clean (no CI failures, no review findings), graduate to wizard doc as a new SDLC phase.Model-config batch ships clean2026-07-11v1.82.0 triage session 2026-06-11
Advisor auto-fallback in SDLC skillTRIGGER FIRED 2026-06-11. When advisor() fails, the SDLC skill should automatically spawn a Fable subagent as fallback — proved in v1.82.0 triage (batch-reviewed 4 issues, caught #395 already fixed). Currently this pattern lives only in private memory; needs to be in skills/sdlc/SKILL.md so every project gets it. Also: auto-try advisor before every plan, not just when user asks.Confidence ramp trial ships clean2026-07-11v1.82.0 triage session 2026-06-11
Detect process-rule memories in /feedback or /setupUsers saving memories like "always run tests" are patching /sdlc gaps with private memory. /feedback or /setup could detect type: feedback entries with process-rule patterns and suggest contributing back to /sdlc instead.Maintainer runs memory audit and finds ≥3 process-rule memories2026-08-11v1.83.0 session 2026-06-12
Copilot Cowork SDLC portGitHub Copilot desktop app launched in technical preview (June 2, 2026) with parallel multi-agent in git worktrees. Could port SDLC wizard as a Copilot extension. Different plugin format from Claude — would be a new sibling repo like codex-sdlc-wizard. Low priority: no demand signal, Copilot extension ecosystem is immature. Signal strengthening 2026-07-14 (#444): the repo's first external contributor is a Copilot CLI user running these skills DIRECTLY — Copilot CLI reads SKILL.md natively, no port needed for skills, and its release notes show weekly skills/plugin-marketplace buildout. That's format convergence, but still short of this row's trigger: nobody has asked for a dedicated port, and no hooks equivalent has appeared in Copilot CLI release notes. #448 (compat watch, promoted from this signal) protects existing consumers meanwhile; this row stays parked for the port question specifically. Maintainer interest flagged 2026-07-21 during #429's sdlc-mcp cross-model review: Copilot was explicitly scoped OUT of #429's v1 (M365 Copilot can invoke MCP but can't run tests/git locally itself — an MCP server doesn't solve that on its own), but the maintainer separately flagged "SDLC for GitHub Copilot could be interesting" as worth researching independently of the MCP question — i.e. a native Copilot port/extension, not solved by whatever #429 decides. Keep these two threads distinct: #429 is the portable-core question across Codex/Claude Code/OpenCode; this row is "does Copilot specifically deserve its own native integration," which could still make sense even if #429 concludes MCP isn't the right shape for the others.Second external user asks OR Copilot extension format stabilizes with hooks equivalent2026-08-20v1.84.0 triage session 2026-06-20, reinforced 2026-07-21
Codex GUI plugin support for codex-sdlc-wizardMaintainer observed 2026-07-22: the Codex desktop app now shows a Plugins entry in its sidebar (alongside Pull requests, Sites, Scheduled) — a plugin-marketplace surface possibly analogous to Claude Code's Cowork plugin system, which agentic-sdlc-wizard's cowork/ directory already ports into. If Codex's plugin ecosystem grows the way Cowork did, codex-sdlc-wizard users browsing that marketplace won't discover the wizard unless it's packaged for it. Investigation filed as codex-sdlc-wizard#63 — not yet actionable here: single observation, not a user request, plugin manifest format unknown.Issue #63 investigation confirms the plugin format and scopes a port, OR a user asks for Codex GUI discoverability2026-09-21This session 2026-07-22
Run /insights with Fable on this repoTRIGGER FIRED 2026-07-13. Ran on Fable at max effort; global report generated + all 22 session facets analyzed per-repo. Findings: /insights is global-only (per-repo auditing stays in the filed GH issues — it can't do that job); the 30-day cleanupPeriodDays default had already deleted all history for ~15 project dirs, so retention, not analysis, is the coverage bottleneck (fix: raise cleanupPeriodDays); 8/11 surviving real sessions fully achieved, every failure environmental (Apple sync, npm perms, sandbox) not comprehension; the one recurring Claude-side friction family (overconfidence vs user-presented evidence, 3 incidents) already has 2 of 3 memory rules institutionalized. No /sdlc or hook changes warranted from this pass.Next Fable session FIREDv1.83.0 session 2026-06-12, re-dated 2026-06-22 triage
Rename research: "sdlc-wizard" → "SDLC harness" / "agentic harness"?Maintainer signal 2026-07-13: "SDLC-wizard might not work [as a name] — maybe SDLC harness or agentic harness following SDLC — we can workshop it later." The product has arguably outgrown "wizard": it's an enforcement harness (blocking hooks, codex gate, cross-model review loops, drift tests), not a one-shot setup dialog. Tension to resolve: the xdlc ecosystem preamble explicitly says sdlc-wizard "earned the wizard form" — a rename must engage that history, not ignore it. Blast radius is large (repo name, npm package, sibling repos' inherited docs, README/ARCHITECTURE, xdlc references), so this needs a naming workshop + migration plan, not a drive-by edit. Workshop only — no rename before candidates are compared and consumer impact is mapped. Signal strengthened 2026-07-24 (second independent maintainer mention, 11 days after the first, unprompted): "this is a harness which is what it really is ... this should be renamed to Claude Code SDLC Harness at some point." Raised while codifying the escalation ladder, in the context of why codification matters — the maintainer's own framing was "it has to be universal and scalable so when other people use this harness ... that it works." That framing is the argument for the rename: the product is an enforcement harness (blocking hooks, codex gate, merge-safety wrapper, cross-model review loops, drift tests), and "wizard" describes only the one-shot setup dialog that is now the smallest part of it. Concrete candidate on the table: "Claude Code SDLC Harness". Still workshop-first — the blast radius (repo name, npm package agentic-sdlc-wizard, sibling repos' inherited docs, xdlc ecosystem references, README/ARCHITECTURE, every consumer's installed docs) is unchanged, and the xdlc preamble's "sdlc-wizard earned the wizard form" history still has to be engaged rather than ignored.Maintainer schedules the naming workshop OR a second person independently reports name confusion OR next major-version planning starts — maintainer-mention half now fired twice; treat a third mention or any major-version planning as the workshop trigger2026-09-11This session 2026-07-13 (post-#440 wrap-up)
Memory audit + repo efficiency pass with FablePROMOTED to ROADMAP #471 on 2026-07-24 — trigger fired (four concrete bloat/vacuous-test/stale-reference instances in one session); was past its 2026-07-22 expiry. See #471.Next Fable session FIREDv1.82.0 triage 2026-06-11, promoted 2026-07-24
Sync AI Setup Lanes to Claude-family sibling wizardsDONE 2026-06-11. gdlc v0.3.0, rdlc v0.7.0 shipped with AI Setup Lanes v2. Cowork plugin port in PR #410. Originally: claude-gdlc-wizard (v0.2.2) and claude-rdlc-wizard (v0.6.1) have stale 69-70 line AI_SETUP_LANES.md vs sdlc-wizard's 217 lines. Missing: 3-lane structure (Premium/Saver/Lite), advisor fallback escalation, Fable effort guidance, usage signals, autocompact cross-ref. Each needs a tailored port — gdlc is game-dev domain, rdlc is research domain. Codex/xdlc/ldlc out of scope (different ecosystem). When people run /update in those repos they should get the same Premium lane experience.Next release of either sibling2026-07-11v1.82.0 triage session 2026-06-11
Stencil "prewalk" pattern (stencil.so/blog/prewalk)Read via WebFetch 2026-07-21 (unverified against primary source per ROADMAP #450's WebFetch-reliability caveat — treat as draft, not citation-grade). Core idea: swap from a frontier model to a cheap model right after the frontier model's first valid edit, not after a handoff document — the cheap model inherits live exploration context (an in-context working example) instead of re-reading files from a plan doc, which the article claims is 14% costlier than not "saving" at all. Potentially relevant to this repo's driver/advisor model-tiering guidance (AI_SETUP_LANES.md) if it generalizes, but no demand signal yet — nobody has proposed applying it here.Someone re-verifies against the primary source and proposes a concrete application to this repo's model-tiering docs2026-09-19Maintainer message 2026-07-21
Server-side required-check enforcement for the merge-safety gateA local hook/wrapper (#462) can verify CI status, a policy-adjacency denylist, and a SHA-bound clearance artifact, but can never be a full security boundary against a determined agent willing to forge the clearance artifact (that env bypass was deleted in #479; the same agent can equally post its own clearance comment). Real fake-resistance needs a GitHub branch-protection required status check or Action that independently re-verifies the clearance artifact server-side before allowing merge — Fable's explicit recommendation during the #462 design consult, deliberately deferred as future-only rather than built into the same change.A forged/stale clearance artifact actually causes an unwanted merge, OR a second repo asks for this mechanism and wants it tamper-resistant2026-09-19#462 design consult, 2026-07-21

Maintenance rule: during quarterly ROADMAP triage, prune any row past expiry. Logged removals go in the commit message (docs(roadmap): prune parking lot — <N> expired entries) so deletions are traceable.

Next Release Queue (GH issues, priority-ordered 2026-08-02)

Triage of the 8 open GitHub issues against what should actually ship next. The ordering principle is live consumer harm first, not age or effort.

SHIP NEXT — GH #475, and it is not the version bump

GH #475 is filed as "CC version drift: baseline v2.1.210, latest v2.1.220". Reviewing those ten releases on 2026-08-01 found a live shipped defect, and that — not the baseline bump — is why this ships first.

hooks/hooks.json:20 gates the TDD hook with "if": "Write(src/**) Edit(src/**) MultiEdit(src/**)". Claude Code 2.1.214 changed single-segment dir/** conditions to match only <cwd>/dir; any-depth matching now requires **/src/**. hooks/ is in package.json's files, so this ships to every consumer.

Consequence: for any consumer whose source is not at repo-root src/ — every monorepo, every packages/*/src/, every apps/web/src/the TDD hook silently stopped firing as of 2.1.214. No error, no warning; the gate simply does nothing. This repo is unaffected only because its own .claude/settings.json paths (hooks/, cli/) genuinely sit at the root, which is exactly why it went unnoticed.

Scope for the release: (a) the one-word fix src/****/src/**, with a regression test that executes the condition rather than grepping for it; (b) audit the other if: conditions in .claude/settings.json for the same pattern; (c) bump the SDLC.md baseline marker from v2.1.210; (d) fold in the other genuinely relevant 2.1.211–2.1.220 findings — prompt-hook default timeout is 30s, PreToolUse deny ends the turn since 2.1.210 unless continueOnBlock: true, subagent nesting flip-flopped twice, and transcripts now record reasoning effort per message (a free measurement instrument for effort questions).

Verified but NOT exposed, state it so nobody re-derives it: 2.1.214 also fixed "hooks with exit code 2 not blocking when stdout JSON fails schema validation". All four of our exit-2 hooks write to stderr, so we were never exposed.

Also worth including if the release has room

GH #476 — native install vs the sudo-npm footgun. Consumer-facing, small, and it pairs naturally with a hooks-and-install release. No blocker.

ROADMAP #495(b) — the phantom watchdog. skills/sdlc/SKILL.md and the wizard doc both tell consumers that scripts/codex-review.sh's STALL_SECONDS=1800 governs review timeouts. Neither the script nor the variable exists anywhere in this repo, and the wrapper that does exist has no watchdog. We ship instructions for a mechanism nobody built. Implement it or delete the claim — both are small, and shipping a false operational promise is worse than shipping neither.

Explicitly NOT in the next release

GH #455 and #456 (Cowork hooks). Investigated 2026-08-01/02. Both hooks were proven CORRECT by execution under Claude Code CLI 2.1.220 with byte-identical config — they fire, deny, and render their reason. They are inert in Cowork for host-side reasons, and the host logs record neither hook decisions nor tool calls, so the layer cannot be identified from outside. There is nothing to fix in this repo, and shipping a speculative workaround would be the compatibility hack the repo bans. Keep open; they need one instrumented Cowork session, not code.

GH #478 (the "delete your CLAUDE.md every 6 months" claim) — research, no shipping surface. GH #434 (36 pending API features) — backlog sweep, its own session. GH #433 (Codex CLI parity) and GH #429 (portable sdlc-mcp) — architecture questions on their own track; #429 in particular could restructure the whole ecosystem and must not ride along with a hotfix.

ROADMAP #493 (the three prompting guides, incl. the Fable one never read) — its own branch and its own release, per maintainer direction, because it touches every shipped .md and needs a clean rollback path.


Next Up (v1.37.0 queue, priority-ordered 2026-04-23)

  1. #212 — Local-Max E2E shepherd (zero-API) — ✅ ENGINEERING COMPLETE; PROVE-IT GATE DEFERRED 2026-05-05 ("just defer prove it who cares" — maintainer pragmatic call). Sim/eval/orchestration all on Max subscription per #228 (v1.59.0) + #230 + #231 phases 1-4 (v1.50.0–v1.55.0). Weekly+monthly workflow porting deleted ~$25-55/week of API cron burn. Docs reference tests/e2e/local-shepherd.sh --compare-baseline as the default path (CLAUDE_CODE_SDLC_WIZARD.md lines 42, 102, 1325, 2570). Codex cross-model review runs against ChatGPT/Codex subscription auth (codex login, "Logged in using ChatGPT" 2026-05-05) — also $0 marginal. Net: $0/release (was $20+/release in API burn). Prove-It Gate parked — would require ~$20 one-time API spend to run paired N=15 local-Max vs CI-API trials for 95% CI overlap proof. Not worth the spend; engineering signal works fine in practice. Reopen if local scoring drifts vs known-good baselines. Original scope archived below for history.
    Original scope (archived)TOP PRIORITY after 2026-04-23 live-fire proved the pain. Today's shepherding blew through the Anthropic API credit cap mid-release (PR #222 e2e-quick-check failed with "Credit balance is too low"), blocking v1.36.1 until admin-merge. Current CI spends ~$0.62 (Tier 1) + $0.82 (Tier 2) per PR on anthropics/claude-code-action@v1. Across today's 12 PRs that's $20+ in API burn just for simulations. Architecture (tri-split billing): (a) Simulationclaude --print via local Bash tool runs against Max subscription ($0 after monthly cap, tests wizard behavior ON Claude which is the whole point); (b) Cross-model review of PR diffcodex exec -c model_reasoning_effort=xhigh via local Bash tool uses OpenAI API (separate bill, ~$3-5/PR — REVISED 2026-05-05: $0 if Codex authed via ChatGPT subscription); (c) Orchestration (watching CI, pulling logs, posting PR comments, merging) — me running in local terminal on Max quota ($0). Scope: (1) replace claude-code-action@v1 invocation in run-simulation.sh with claude --print "$prompt" --output-format json; (2) confirm execution-output JSON shape matches (SDK format); (3) keep CI path as fallback for external contributors without a Max sub; (4) new ./tests/e2e/local-shepherd.sh <PR> orchestrator runs Tier 1+2 locally, posts summary; (5) update SDLC skill + CLAUDE_CODE_SDLC_WIZARD.md docs to reference local shepherd as the default path. Prove-It Gate (CRITICAL — unchanged): demonstrate statistical score parity (local-Max vs CI-API) on at least 3 PRs before trusting local signal. Both paths hit same model (Opus 4.7), same prompt, same scoring — expected differences are only stochastic variance (±1-2 pts typical), so prove via overlapping 95% CIs, not byte-equality. If parity fails, investigate whether Max routing differs from raw-API before declaring. User call-out 2026-04-23: "why are we using API credits for CI instead of us being CI shepherd?"
  2. #215 — Tier 2 persist dead code DONE v1.36.0 — Closed by PR #214.
  3. #214 — Adaptive-thinking A/B Prove-It (strategic, ~$12 API). Unblocks #213. Run 10× with adaptive-thinking, 10× with CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1, compare 95% CI. Decision rule in the item. Gated on #212 shipping first — adaptive-thinking A/B should run via local-Max shepherd, not API, or it'll burn $12 every calibration cycle.
  4. #210 — Node 24 false-green DONE v1.36.0 — Closed by PR #217.
  5. #211 — Tier 1 "11/10" score leak DONE v1.36.0 — Closed by PR #216.
  6. #217 — model-effort-check.sh loud warning below xhigh ✅ DONE 2026-04-24. Hook now: max/xhigh → silent; high/medium/low/unset → LOUD WARNING block recommending /effort max, mentioning SDLC compliance + Opus 4.7 shallow-reasoning gotchas. 2 new TDD tests (118 total hook tests passing).
  7. #207 — Community feature-discovery scanner ✅ DONE — scanner shipped v1.39.0, fetcher v1.56.0 (PR #286). Paperwork close v1.62.0.
  8. #216 — Repo rename DONE in v1.36.1 — renamed agentic-ai-sdlc-wizardclaude-sdlc-wizard (matches sibling pattern, npm package kept as agentic-sdlc-wizard).
  9. Token bloat audit (P2, zero-API). ✅ FULLY DONE. Phase 1 (2026-04-24): dedupe_plugin_or_project() helper kills 2× SDLC BASELINE injection (dual-channel hook registration). Phase 2 (2026-04-27, v1.47.0 PR #272): scripts/audit-session-load.sh inventories every session-loaded asset, ranks by char count, flags >5K-token candidates. Phase 3 (2026-04-27, v1.48.0 PR #273): trimmed skills/sdlc/SKILL.md 12,427 → 4,995 tokens (-60%) and skills/update/SKILL.md 8,555 → 4,044 tokens (-53%). Audit reports 0 trim candidates. Codex round 1 CERTIFIED 10/10.
  10. OpenCode port — TRACKED ELSEWHERE 2026-05-24 in BaseInfinity/opencode-sdlc-wizard. All Phase A/B/C work, the v0.8.3 npm-publish E404, and the npm-2FA-mode decision live there. No claude-sdlc-wizard scope remains. Per .reviews/roadmap-prio-codex.md excise list. Original entry archived below for history.
    Archived (excised 2026-05-24)OpenCode port — privacy-first, any-backend portability (strategic, multi-phase; supersedes backlog #194). Phase A + early Phase B shipped 2026-05-03 → 2026-05-06. Sibling repo at BaseInfinity/opencode-sdlc-wizard is at v0.8.3 locally. Releases shipped (in repo): v0.2.0 (privacy-first 4-tier backend picker + Codex round-3 CERTIFIED 9/10, 113 tests), v0.3.0 (npx opencode-sdlc-wizard init CLI), v0.3.1 (cross-model-review skill), v0.4.0 (domain-adaptive TESTING.md), v0.4.1 (plugin shim fix), v0.5.0 (SDLC.md + ARCHITECTURE.md templates), v0.6.0 (more templates), v0.7.0 (JSON schemas for review artifacts + zero-dep validator), v0.8.0 (free-tier-first cascade + 5 providers + cost ladder), v0.8.1/v0.8.2 (Codex round-1/round-2 cross-model-review fixes). npm publish state: only 0.2.0 is on npm. Releases v0.6.0–v0.8.2 all failed release.yml at the test step — tests/test-review-schemas.sh T14 hard-failed when live .reviews/response.json was absent (file is gitignored, CI clean checkout never has it). Fixed 2026-05-06 (PR #1): T13/T14 now use validate-if-present semantics. v0.8.3 cut 2026-05-06 (PR #2) to ship the test fix as a real release. v0.8.3 is the first tag to clear the test step — but npm publish then failed with E404 on the 2FA-on-writes documented in RELEASING.md. Pending — maintainer action only: either run npm publish --access public --otp=<6-digit> manually against the workflow's tarball, OR switch the npm account 2FA mode from "writes" to "auth-only" so the automation token works alone. Phase B (backend matrix proof — Ollama/Azure/Together/Anthropic) and Phase C (hardware scout) remain deferred per scope. Full pickup state in HANDOFF.md.
    Original scope (archived)Port the wizard to sst/opencode so users can run the full SDLC harness against whatever model backend their privacy/compliance constraints allow — not just Anthropic. OpenCode is the right target because it already speaks many providers out of the box: local (Ollama, LM Studio, llama.cpp, vLLM), enterprise (Azure OpenAI, AWS Bedrock, internal AI gateways), hosted OSS (Together, Groq, OpenRouter), plus the usual OpenAI/Anthropic. Driver: (a) Opus 4.7 token burn + API-credit cap pain — single-vendor lock-in is expensive and fragile; (b) real enterprise + privacy use cases — e.g. route through a work Azure OpenAI tenant with zero-retention, or run fully offline on a local model, without giving up the wizard's enforcement. Phase A — port the wizard: spawn opencode-sdlc-wizard sibling mirroring the Codex port pattern (agentic-sdlc-wizard writes .claude/, codex-sdlc-wizard writes .codex/ + AGENTS.md; new sibling writes .opencode/). Map hooks → OpenCode's pre/post-tool primitives, port instructions-loaded-check + sdlc-prompt-check + tdd-pretool-check + precompact-seam-check + model-effort-check, port all 4 skills (SKILL.md is already portable per #91), non-destructive config merge in install.sh, quality tests proving hooks actually fire under OpenCode. Phase B — backend matrix proof: run an E2E SDLC scenario (plan → TDD → self-review) against at least one from each category: local (Ollama + Qwen-Coder or DeepSeek-Coder, 16–24GB VRAM class), enterprise gateway (Azure OpenAI), hosted OSS (Together/Groq). Score each against the Claude Code baseline; document which backends hold SDLC compliance and which degrade. Capability-floor note — "just works on every LLM" is the dream but not the spec: expect small local models (7–13B) to fail the full plan→TDD→self-review protocol (instruction-following + long-context reasoning + tool-use are all load-bearing). The 30B+ code-tuned class (Qwen-Coder, DeepSeek-Coder) is the likely local sweet spot. A failed run on an undersized model is a capability result, not a port bug — log it in the matrix and move on. Phase C — hardware scout for local tier: test gaming laptop + Windows laptop first (zero cost); if insufficient, evaluate $200/$300/$400 rig or cloud-GPU rental. Success criterion: a user can pick their backend (local for privacy, Azure for enterprise, OSS-hosted for cost, Anthropic for ceiling) and get the same SDLC enforcement — giving agentic-harness power to people the Anthropic-only path excludes. Reserve Anthropic for high-stakes cross-model review in low-trust backends.

Blocked: #213 (ship degradation env vars by default) gates on #214 result.

Archived history

Fully resolved sections moved to ROADMAP_ARCHIVE.md (2026-07-06, #236(f)): Pre-Distribution, Post-Distribution (except recurring #19), and Previous Releases v1.20.0-v1.34.0 (incl. Earlier Cycle Items and v1.28.0/v1.25.0). 67 fully-resolved Unprioritized rows moved there too (including #231, the shepherd-migration history — the single largest row in the file). Notable archived anchors: #231's shepherd migration, #226/#228/#230 shepherd chain, #347 /goal research, #96 degradation-detection phases.

Post-Distribution

#ItemDescription
19Monthly GC Audit (recurring)"Less is more" — try removing things, check if scores hold. Fix weak tests or delete fluff

18 fully-resolved rows archived → ROADMAP_ARCHIVE.md.

Built With SDLC Wizard

Living tracker of projects shipped using this wizard. Rule: only list projects that have been explicitly marked as using SDLC Wizard — no "powered by" claims before that.

ProjectRepoStatus
SDLC Wizard itselfBaseInfinity/claude-sdlc-wizardDogfooded, v1.90.0
Codex SDLC AdapterBaseInfinity/codex-sdlc-wizardv0.7.x, shipped with SDLC workflow
GDLC Wizard (games sibling)BaseInfinity/claude-gdlc-wizardv0.2.x, persona-driven playtest cycles
(add as projects are marked)

TODO: audit Stefan's GitHub projects + production apps, mark the ones that used the wizard, then list them here. Do not populate from memory — only list what's been marked.

Unprioritized

#ItemDescription
66Convert to Plugin Format Absorbed into #89Plugin format + marketplace submission combined into single item #89. Plugins now support hooks (updated finding from 2026-04-03 research)
71Monitor KAIROS/Coordinator ModeProactive always-on agent mode and multi-agent coordination. Wizard's enforcement model (hooks on tool calls) needs to scale to always-on monitoring. Track feature flags, prepare skill content for both contexts. Spawned from #59 research
82Research: Domain-Specific *DLC Variants — TRACKED ELSEWHERE 2026-05-24Stefan's separate domain-DLC track (Legal LDLC, Firmware FDLC, Research RDLC, Content CDLC). Not claude-sdlc-wizard scope; #79 already shipped the domain-adaptive testing diamond residue that belongs here. Per .reviews/roadmap-prio-codex.md excise list.
83Research: Local Model for Sensitive Databettercallclaude uses local Ollama for privilege-sensitive legal content (attorney-client privilege can't go to cloud APIs). Pattern: route sensitive operations to local model, non-sensitive to cloud. Would wizard users in legal/healthcare/finance benefit from a "sensitive data routing" recommendation? Setup wizard could detect .env patterns, HIPAA references, attorney-client markers and recommend local model fallback. Prove It Gate: is this a real need or theoretical?
87Research: Plugin/Marketplace Distribution DONEResearched 2026-04-03. Findings: Claude plugins now support hooks (outdated info said skills-only). 14 AI ecosystem channels audited, 21 classic package managers audited. Top channels: Claude Plugin (#89), awesome lists, curl script, Homebrew tap, gh CLI extension. Absorbed into #89 + #90
89Claude Code Plugin Format + Marketplace SubmissionConvert wizard to .claude-plugin/plugin.json structure. Skills → skills/, hooks → hooks/hooks.json, settings defaults. Submit to official Claude marketplace (claude.ai/settings/plugins/submit). Namespacing: /sdlc-wizard:sdlc vs /sdlc. Keep npx CLI as fallback. Absorbs #66 (Convert to Plugin Format) and #87 (marketplace research). Evidence: plugins now support hooks as first-class, confirmed 2026-04-03. Scope informed by #101 research: no official plugin enforces full SDLC — we own the niche. Setup flow should recommend security-guidance, pr-review-toolkit, code-review, commit-commands, explanatory-output-style as companions. Review process/timeline not published — email/Discord Anthropic before submission
91Multi-Agent Adapter Layer — TRACKED ELSEWHERE 2026-05-24Codex + OpenCode adapters live in their sibling repos (codex-sdlc-wizard, opencode-sdlc-wizard). Cursor/Windsurf/Aider/Continue would each become their own demand-gated sibling repo if they ever attract a real user — no claude-sdlc-wizard-side work remains under this umbrella. Per .reviews/roadmap-prio-codex.md excise list.
220Token-spike anomaly detection (post-mortem 2026-04-23) DONE (v1.43.0, 2026-04-27)Anthropic's 2026-04-23 post-mortem (anthropic.com/engineering/april-23-postmortem) showed a caching bug "continuously dropped thinking blocks from subsequent requests" and caused unexpected usage drain — detectable only via token-consumption spikes. Shipped: hooks/token-spike-check.sh (SessionStart, opt-in via .metrics/) ingests CC transcript usage from ~/.claude/projects/<sanitized-cwd>/*.jsonl to .metrics/token-history.jsonl (idempotent by session_id), then warns when last session's costly_tokens (input + cache_creation + output, excluding cache_read) exceeds rolling baseline by >2σ. Default --metric median uses MAD-based spread instead of stdev to remain robust against single baseline outliers. 14 quality tests in tests/test-token-spike.sh covering positive/negative spike, idempotent ingest, min-baseline floor, median-vs-mean contrast (both modes asserted), flat-baseline floor (small uptick suppressed, large jump still fires), privacy/type-coercion (malicious transcript probe cannot leak strings into history), concurrent-ingest atomic-lock serialization, and hook gating + warn surface. Engine in tests/e2e/token-analytics.sh supports --ingest, --check, --report independently. Codex CERTIFIED 9/10 round 2 (round 1 caught 3 P1 + 1 P2: privacy type-leak, flat-baseline 1-token false positive, missing mean-mode test, TOCTOU race). Follow-up (~2 weeks, 2026-05-11): verify .metrics/token-history.jsonl is accumulating session records and at least one rolling-baseline window has formed (≥5 records). If empty or sparse, the SessionStart skip-recent filter or transcript-dir resolution may be off
221Post-mortem 2026-04-23 wizard integration DONE (PR #249, v1.41.0)Three lessons from the 2026-04-23 post-mortem to fold into wizard docs. (a) Explicit effort — the incident had CC flipping reasoning_effort defaults (high → medium → xhigh/high). Our model-effort-check.sh already nudges to xhigh/max, but the wizard should cite this post-mortem as independent third-party evidence in CLAUDE_CODE_SDLC_WIZARD.md → Recommended Effort section: "never rely on the CC default, set it yourself." (b) Extended-thinking + caching + idle sessions — document the failure mode (context pruning during idle + cached prompts → dropped thinking blocks); add to SDLC.md troubleshooting or a new "Known CC gotchas" section. (c) Prompt brevity constraints can compound — the post-mortem describes a length-limit prompt change (including a line like "keep text between tool calls to ≤25 words" among other brevity edits) where ablation later measured a ~3% drop on one evaluation; the post-mortem attributes the drop to the broader length-limit prompt change, not to that single sentence alone. Audit our skills/hooks for verbosity caps: grep all SKILL.md and hook stdout for ≤\d+ words, <\d+ words, keep.*brief, be concise, etc., decide case-by-case. Zero-API docs + grep audit, ~1 hr
222Prompt-compounding audit harnessGeneralizes (c) from #221. Post-mortem 2026-04-23 showed isolated prompt changes can compound non-linearly across reasoning chains. Our wizard has ~40 prompt-injection sites (5 hooks × N stdout lines, 4 skills × instructions, CI PR review prompt, eval-criteria prompt). A small benign-looking constraint in any one could be silently capping quality. Proposal: periodic A/B benchmark comparing full-wizard harness vs. wizard-with-each-prompt-blanked, using existing E2E scoreboard. Flag any prompt whose removal improves score — that's a compounding constraint. Not urgent (needs API budget), stacks with #214 adaptive-thinking work once that's settled
92Research: Rigorous Autocompact BenchmarkingNobody has published controlled benchmarks testing different autocompact thresholds. Opportunity to be THE authority. Test: quality metrics (task completion accuracy, code correctness) at 50/60/70/75/80/83% thresholds across 200K and 1M models. Measure: pre/post compaction context preservation, cost per session, degradation curves. Low priority but high differentiation potential
101Research: Official Claude Plugins Ecosystem DONE13 first-party plugins at github.com/anthropics/claude-code/tree/main/plugins (agent-sdk-dev, claude-opus-4-5-migration, code-review, commit-commands, explanatory-output-style, feature-dev, frontend-design, hookify, learning-output-style, plugin-dev, pr-review-toolkit, ralph-wiggum, security-guidance). Marketplace at claude.ai/settings/plugins, submit at claude.ai/settings/plugins/submit. No single plugin enforces full SDLC (TodoWrite→plan→TDD RED→GREEN→self-review→cross-model); nearest overlaps are pr-review-toolkit/code-review (post-hoc) and ralph-wiggum (Stop-loop) but none are end-to-end gated. Positioning: SDLC wizard owns the agentic-enforcement niche. Hooks are first-class (hooks/hooks.json at plugin root, same format as .claude/settings.json) — 5 of 13 official plugins already ship hooks. Our 5 hooks migrate 1:1. Complementary plugins to recommend in setup flow (#89): security-guidance (PreToolUse safety), pr-review-toolkit + code-review (downstream review), commit-commands (conventional commits), explanatory-output-style/learning-output-style (TDD-aligned). Review process and submission timeline not published — email Anthropic or Discord before submission
205AGENTS.md interop ✅ phase (a)+(c) DONE v1.42.0; (b)+(d) deferredPhase (a) + (c) shipped: setup skill (skills/setup/SKILL.md Step 4.5) detects existing AGENTS.md and surfaces three options to the user — (A) dual-maintain default + manual sync, (B) merge into CLAUDE.md, (C) skip. Choice is recorded as a one-line metadata comment in the user's SDLC.md. Phase (b) — auto-write AGENTS.md alongside CLAUDE.md when generating fresh — DEFERRED per "agent-agnostic SDLC is on the back burner." Phase (d) — drift-consistency test between CLAUDE.md ↔ AGENTS.md — DEFERRED, low-priority. Re-open if user demand surfaces.
212OPTION 1 SHIPPING — E2E de-required Local-Max E2E shepherd (partial-API, trusted-PR fallback)Option 1 selected 2026-04-24 after Codex architect review. Original plan (pending check-run + local overwrite) scored 2/10 NOT CERTIFIED — branch protection is pinned to GitHub Actions app_id:15368, so a local gh OAuth token cannot satisfy a required check. Codex proposed 3 options; user chose Option 1 (de-require E2E, shepherd becomes advisory). Scope: (1) delete Tier 1 + Tier 2 e2e jobs from ci.yml (1530 lines), (2) disable cron on weekly-update.yml + monthly-research.yml (API-burning workflows, full migration is ROADMAP #231), (3) update pr-review.yml to wait on validate only, (4) PATCH branch protection to drop e2e-quick-check + e2e-full-evaluation from required. Shepherd stays as shipped (candidate-only). Baseline/candidate comparison deferred to ROADMAP #230. Foundation shipped 2026-04-23: tests/e2e/local-shepherd.sh + tests/test-local-shepherd.sh landed. Script passes 8/8 tests covering fork-PR abort (P0 trust boundary), missing-dep guards, parity flags (--model claude-opus-4-7 --max-turns 55 --allowedTools ... --output-format json), provenance-field emission to score-history.jsonl (execution_path=local-max, host_os, cli_version, claude_code_version, auth_mode, pr_number), GitHub check-run POST via gh api, and dry-run mode. Still pending before CI switchover: (i) Prove-It Gate — paired sims × 5 scenarios × 3 runs each (N=15/path) with 95% CI overlap verification, (ii) ci.yml migration to make local shepherd the default path with API as fork-PR fallback, (iii) docs update in CLAUDE_CODE_SDLC_WIZARD.md + skills/sdlc/SKILL.md teaching the new workflow. Promoted to Next Up #0 on 2026-04-23 after live-fire: 12 PRs hit Anthropic API credit cap mid-release, blocking v1.36.1 e2e-quick-check. Original ~$1.44/PR sim cost × 12 PRs = $20+ API burn in one day. Codex cross-model review 2026-04-23 (.reviews/latest-review-pr223.md, 3/10 NOT CERTIFIED) surfaced 5 must-fix issues that reshape the plan. Revised architecture (Codex-hardened): (a) Scope = trusted-PR fallback, not default. Must restrict to same-repo-base-author PRs only — never run fork PRs on maintainer laptop (P0 trust boundary: local auth lets untrusted code access maintainer's GitHub + Claude sessions). External-contributor PRs stay on CI-API path. (b) Simulation leg via claude --print --output-format json on Max subscription runs the agent workflow locally ($0 after cap). (c) Evaluator is NOT zero-API — be honest. evaluate.sh makes per-criterion Anthropic API calls for judging. Moving the sim only eliminates ~half the spend; full "offline" requires separately migrating the evaluator (out-of-scope for this item, track as follow-up). (d) Cross-model review via codex exec -c model_reasoning_effort=xhigh on OpenAI ($3-5/PR, adversarial diversity). (e) Orchestration in local CC session on Max quota ($0). Scope: (1) swap claude-code-action@v1 in run-simulation.sh for claude --print; (2) verify output JSON shape matches evaluate.sh consumption; (3) ADD GitHub status check emission — shepherd must POST a check-run via gh api so branch protection's e2e-quick-check gate is actually satisfied (sticky PR comments don't count as check-runs); (4) ./tests/e2e/local-shepherd.sh <PR> with explicit trust check (gh pr view --json headRepository.isFork → abort if true); (5) add provenance fields to score-history entries — execution_path, host_os, cli_version, auth_mode, claude_code_version — so local and CI rows don't silently poison trend analytics; (6) docs update teaches local shepherd as trusted-PR ONLY; default remains CI-API. Prove-It Gate (Codex-hardened — was too weak): old gate "≥3 PRs overlapping 95% CI" risked certifying judge-noise parity (because Tier 2 re-scores one transcript per ROADMAP #226). New gate: run paired end-to-end simulations on the same scenario (local-Max and CI-API) back-to-back on ≥5 scenarios × ≥3 independent runs each (N=15 per path), compute per-path mean and 95% CI, confirm overlap, AND verify execution_path-tagged score-history rows show no statistically significant mean shift across ≥10 PRs post-migration. If parity fails, classify which leg drifted (model routing? env flags? allowed-tools scope?) before rolling out. Open questions answered post-Codex-review: (i) advisory-only first, gate-replacement after parity proven; (ii) trusted-same-repo only at first rollout; (iii) evaluator API migration is follow-up, not scope; (iv) yes, provenance fields are required; (v) "simulation MUST be Claude" holds for reference harness; portability benchmark is separate (#91). User call-outs: 2026-04-19 "can I CI-shepherd without API?"; 2026-04-23 "why are we using API credits for CI instead of us being CI shepherd?" Codex review verdict integrated 2026-04-23.
236Audit: functional bloat hunt across wizard surfacePHASE-PARTIAL DONE 2026-05-05; +tracked-artifact sweep 2026-05-06; +(b)/(c)/(f) DONE 2026-07-06. Three token-amplifier fixes shipped (v1.69.0 BASELINE-once-per-session ~12K saved/heavy-session, v1.70.0 TDD CHECK-once-per-session ~0.5-1.5K saved, v1.71.0 SDLC SKILL.md Cross-Model Review trim 4995 → 4568 tokens) plus one orphan deletion (scripts/audit-subagent-models.sh, 85 lines, 0 references, never in npm files list). v1.73.0 (PR #331) added category-(d)-adjacent sweep: -460 LOC across 15 stale .reviews/ round-N + preflight artifacts plus plans/CATCHUP.md — all gitignore-shadowed leftovers from pre-.gitignore commits, none load-bearing. Live evidence in maintainer session: BASELINE block disappeared from system-reminders mid-conversation when sentinel landed. RE-TRIGGERED 2026-07-04 — maintainer call-out: "Use fable to cleanup repo and remove bloat for SDLC wizard, fable is strong [at this]." Time-boxed opportunity: Fable 5's free-inclusion window closes 2026-07-07 (3 days out at time of call-out) — run categories (b)/(c)/(f) as Fable subagent passes before it goes metered. Scope for this pass: (b) read every shipped hook, flag any whose nudge/warning text a maintainer would dismiss on sight (proven noise, not proven value); (c) grep tests/test-*.sh for overlapping assertions across files (58 test files as of 2026-07-04 — some near-certainly duplicate coverage after a year of incremental additions); (f) this ROADMAP.md itself is 300+ rows — propose an archive cut line (e.g. move fully-DONE/KILLED rows older than N releases to a ROADMAP_ARCHIVE.md) so the active table stays scannable. Precondition: verify subagent model dispatch actually reaches Fable before relying on its output — 2026-07-04 live incident found CLAUDE_CODE_SUBAGENT_MODEL pinned in global ~/.claude/settings.json, silently forcing every Agent(model:"fable") call to Opus 4.6 instead (see effort/model-pin gotchas in SDLC.md). Categories (b)/(c)/(f) DONE 2026-07-06 (PR pending, Codex cross-model review before merge): (b) Fable hook-noise audit, every candidate Prove-It verified via TDD mutation testing (RED against a reverted/broken version, GREEN after the real fix) rather than trusted on the audit's word alone — 2 real enforcement bugs surfaced and fixed along the way: codex-review-stop-check.sh delivered its Stop-hook nudge via stderr on exit 0 (invisible per CC's hook-delivery semantics — only stdout JSON is surfaced on exit 0), and tdd-pretool-check.sh's hardcoded /src/ pattern never matched this repo's own hooks//cli//.github/workflows/ source dirs (fixed via a new SDLC_TDD_SRC_PATTERN env override configured only in this repo's .claude/settings.json, keeping the CLI-distributed template generic per test_tdd_hook_generic). Also: deleted goal-confidence-check.sh entirely (no cited incident, unproven value), trimmed precompact-seam-check.sh 256→101 lines (removed the untested .reviews/handoff.json self-heal branch), silenced model-effort-check.sh's unset-effort nagging, removed sdlc-prompt-check.sh's unfired #195 effort-bump detector, added 24h-cached CC-version checking to instructions-loaded-check.sh. (c) consolidated overlapping assertions across 10 test files and deleted tests/test-degradation-detection.sh outright (428 lines, fully superseded) — caught one real latent bug as a byproduct: test_ci_max_turns_sufficient in test-workflow-triggers.sh was defined twice, and the original (shadowed) definition was vacuous, always passing regardless of ci.yml content. (f) split ROADMAP.md (326 lines / 182 rows) into this trimmed active table (~103 lines) plus new ROADMAP_ARCHIVE.md holding 85 fully-resolved rows (18 Post-Distribution + 67 Unprioritized) plus 5 fully-archived release-history sections — row-completeness guard tests (test_roadmap_no_duplicate_row_numbers_across_files, test_roadmap_key_open_items_present, test_roadmap_archive_has_key_archived_items in test-doc-consistency.sh, all mutation-verified) prove no row was silently dropped or duplicated. All 58 test files green post-change. Original scope below for re-runs: Recurring "does this still earn its keep?" pass. Distinct from neighbors: #220 token-bloat is size-per-file (chars/tokens); #19 Monthly GC is "weak tests / test fluff." This is per-component existence justification. Method: Prove-It style — for each candidate, attempt git rm on a branch, run full test suite. If nothing fails, that's a real bloat candidate. Trigger: quarterly. User call-out 2026-05-04: "bloat sucks."
302User-level setup-wizard + repo-local lifecycle split — DESIGN-CERTIFIED, implementation deferredGH issue #302 proposes splitting the wizard so setup lives user-level/global and sdlc/update/feedback stay repo-local ("install once, bootstrap anywhere"). Cross-model design review completed 2026-05-20 (Codex gpt-5.5 xhigh, .reviews/302-design-codex-review.md) scored Claude's first-pass analysis 5/10 NOT CERTIFIED and replaced it with a concrete channel contract. Decided channel split: plugin channel = user-level/global path (already exists: .claude-plugin/plugin.json + hooks/hooks.json with ${CLAUDE_PLUGIN_ROOT}); npm/npx = explicit repo-local bootstrap/update path; no npm postinstall writing to ~/.claude/ (fragile under CI/containers/read-only HOME/Windows). Design questions answered: (1) setup global via plugin, not also copied repo-local (precedence #338 makes the global copy dead weight when both exist); preserve auditability via SDLC.md metadata or install manifest, not duplicate same-name skill. (2) feedback global via plugin, can still read repo-local SDLC.md at invocation time. (3) update-wizard stays repo-local (reads SDLC.md metadata, runs drift detection, mutates project files). (4) npm install -g installs the CLI binary only — no lifecycle scripts. (5) Migration: leave existing repos unchanged; new split is opt-in only; later major release can stop copying setup/feedback repo-local for new installs. Hard constraint Claude missed: "global setup auto-triggers anywhere" is FALSE — hooks/instructions-loaded-check.sh:14-22 and hooks/sdlc-prompt-check.sh:27-35 exit silently when SDLC.md/TESTING.md don't exist, and tests/test-hooks.sh:2507/2522 actively assert that silence. A plugin-only fresh-repo bootstrap signal must be designed before the global skill can satisfy the "always available" promise from the issue. Existing dual-channel surface to respect: cli/init.js:286-302 blocks npm-on-plugin (duplicate /update-wizard), hooks/instructions-loaded-check.sh:195-206 warns on dual install. Adding npm-global skills would create a third overlapping surface — deprecate one channel first. Implementation sequence (5 steps, do NOT start without dedicated session): (1) lock the channel contract in CLAUDE_CODE_SDLC_WIZARD.md + ARCHITECTURE.md; (2) doc the fresh-repo trigger limitation + migration story in #302 comment; (3) prototype plugin-only fresh-repo bootstrap signal + assert current silent-hook tests still pass; (4) write global-skill collision/backup/update tests if any installer touches ~/.claude/skills/; (5) only then alter init behavior for new installs, leaving existing ones intact. Why deferred 2026-05-20: session shipped v1.74.0 → v1.75.0 → v1.75.1 (Trusted Publishing migration), maintainer fatigued, #302 is architectural — needs a fresh planning session. Trigger to revisit: explicit user request OR a second repo install where "install once" friction is felt acutely.
350CC feature-discovery cadence — replacement-for-#231 ranker has no enforced cadenceProcess gap discovered 2026-05-24 via #347 correction. #231 Phase 3d (v1.54.0, 2026-04-29) deleted the in-CI Claude ranker from weekly-update.yml to take it to $0/week. The fallback was "maintainer runs claude --print "$(cat .github/prompts/analyze-release.md)" weekly on Max." That ran zero times in 5 weeks. Consequence: native CC /goal shipped in v2.1.139 (~mid-May) and was missed until a user asked a related question 2026-05-24 — wizard then published wrong research saying "no /goal exists." 39 CC versions accumulated since the last auto-PR (v2.1.118 → v2.1.150). Scope (Actionable now, low-cost cleanup): (a) restore a thin cron — weekly-update.yml still runs detection ($0 GH API call); add a single follow-up step that opens a "CC version drift" GitHub issue when our <!-- SDLC Wizard Version --> baseline is >5 minor versions behind latest npm — pure GitHub API, no LLM, no API spend; (b) the issue body links the maintainer to the on-Max command + the changelog URL + a one-line "what to do" reminder; (c) session-start instructions-loaded-check.sh already has the staleness nudge (#196 — "N minor versions behind") — verify it actually fires when the gap is ≥3 minor AND link to the analyze-release runbook in the loud branch. Why this beats #85 Phase 2 (which we killed 2026-05-24): #85 Phase 2 was "auto-rank features in CI via LLM" — expensive and conflicted with #231. This is "open a stale-baseline issue when we detect drift" — cheap, GH API only, just a maintainer reminder. Status: DONE 2026-05-25 (PR #354, v1.77.0 — .github/workflows/cc-version-drift.yml ships: Mon 09:30 UTC cron + workflow_dispatch, scripts/cc-drift-check.sh SemVer-delta logic, machine-readable issue marker for idempotent edits, only re-opens closed issues when delta WIDENED. Verified live 2026-05-25 via manual workflow_dispatch on main: ran clean, "Open or update tracking issue" step SKIPPED — silent when no drift, as designed). Paired with #347 in same release arc.
424Cowork plugin enhancement — prompt-based hooks, verified install, README correctionsMaintainer pain event: cowork/ plugin exists (PR #410, v1.83.0) with 2 skills (sdlc + feedback) and CI drift tests, but has NEVER been installed or tested in a real Cowork session. README says "Cowork hook support is unverified" — this is wrong. Anthropic's own cowork-plugin-management plugin (v0.2.2, knowledge-work-plugins marketplace) documents hooks as first-class plugin components with 9 event types including prompt-based hooks that need no shell access. Deep-research workflow (2026-06-19, 101 agents, Codex 7/10) confirmed Claude Cowork is a separate product from Claude Code but shares the same plugin format. Scope (multi-phase): (a) Verify install path — actually install the plugin in a Cowork session via GitHub URL, confirm skills load and invoke correctly; (b) Add prompt-based hooks — TDD reminder (PreToolUse on Write/Edit), SDLC baseline injection (UserPromptSubmit), confidence check (Stop). Use "type": "prompt" not "type": "command" — no shell needed; (c) Update README — remove "unverified" language, clarify Code vs Cowork product distinction, document prompt-hook enforcement; (d) Update tests/test-cowork-drift.sh Test 8 — flip from "no hooks = PASS" to "hooks exist and match format = PASS"; (e) Evaluate adding SDLC-specific agents (code-reviewer, tdd-checker) per plugin agent schema. Entry gate: maintainer pain event — dead code with CI tests, never tested in target environment. Relates to #302 (user-level setup split) — Cowork plugin is the "global" distribution surface. Token cost note: /deep-research used for initial research burned 2.5M tokens (23x median session, GH issue #423). Do NOT use for follow-up work — use targeted WebFetch.
434AI Setup Lanes v3 — Sonnet 5 + model-aware effort + auto-escalationMaintainer pain event: AI_SETUP_LANES.md still references Sonnet 4.6 and recommends blanket max effort. Sonnet 5 launched June 30 and beats Opus 4.6 on every benchmark (SWE-bench Verified 85.2% vs 80.8%, Terminal-Bench 80.4% vs 65.4%). Opus 4.6 cannot advise Sonnet 5 (pairing table rejects it). Fable+Codex cross-model review both confirmed: Sonnet 5 high + Fable advisor is the new recommended primary, Opus 4.8 xhigh for escalation. Scope (multi-part) — status verified 2026-07-10, not just re-asserted: (a) ✅ DONE (v1.84.0, extended by #439): AI_SETUP_LANES.md has Sonnet 5, model-aware effort per model, escalation ladder, and (as of #439) GPT-5.6 Sol as reviewer. (b) ✅ DONE (v1.84.0): hooks/model-effort-check.sh implements a model-independent floor (SessionStart's payload has no model field, so it can't detect which model is active) — high/xhigh are always silent; max is silent only when set via the CLAUDE_CODE_EFFORT_LEVEL env var, since Claude Code doesn't actually persist a settings.json-only max (that case still warns, correctly — it's a real CC quirk, not a bug in this row's claim). Blanket "max is the only acceptable value" nagging is gone. (c) ✅ DONE (v1.84.0): skills/sdlc/SKILL.md's hardcoded effort: max frontmatter was removed in the same release (git history confirms); driver effort now comes from the session/lane, not the skill. (d) Partially superseded, not simply "still pending" — (d)'s full original scope (3+ failures OR context >200K, escalating to both /effort xhigh and /model opus) was never fully built. What existed was narrower: ROADMAP #195's "Dynamic effort auto-bump hook" (sdlc-prompt-check.sh scanning prompts for LOW-confidence/FAILED/CONFUSED signals, firing after 2 signals in a 30-min window, suggesting only /effort xhigh — no context-size trigger, no /model opus escalation). That narrower detector was explicitly reviewed and kept during the v1.69.0 bloat audit ("earned its keep and stayed untouched," per CHANGELOG.md's v1.69.0 entry — CHANGELOG only records the original addition, not what came next), then later deleted 2026-07-06 during #236(b)'s follow-up bloat-hunt as "unfired" (per ROADMAP #236's own entry and commit 3aa2779). So: the failure-signal half of (d) was built, judged valuable once, later judged unfired and removed; the context-size/model-escalation half was never attempted. Re-scoping (d) means deciding whether to rebuild the once-killed mechanism or try the untried half — not a clean "still open" or "fully superseded." (e) Adjacent detector exists, but not this onehooks/token-spike-check.sh (ROADMAP #220) already does automated, per-session token-burn detection: it reads transcript history and warns when the last completed session's burn deviates >2σ above the rolling median, catching CC-side regressions (caching bugs, prompt-inflation defaults). That's a different problem than (e) asked for: a live, in-session monitor that watches the Max 5-hour-cap burn rate as it happens and suggests an effort downgrade before the cap hits, not a post-hoc statistical-anomaly check against past sessions. No hook does that. The concept is otherwise only manual guidance (AI_SETUP_LANES.md's Credit-Spend Warning section, a /usage doc-table row pairing quota-burn investigation with scripts/audit-session-load.sh). Per this repo's own Prove-It Gate ("new addition? default answer is NO — real gap or theoretical?"), leave the live-monitor half unbuilt until a real incident motivates it. (f) Tracked, not started — today's GPT-5.6 sibling issues (claude-gdlc-wizard#15, claude-rdlc-wizard#10) plus follow-up comments flag both gaps (stale reviewer model AND the missing Sonnet-5 driver lane) — but neither sibling repo has actually changed yet; both AI_SETUP_LANES.md files still use GPT-5.5 and Opus 4.6 as primary as of this writing. Filing/commenting is visibility, not implementation. Entry gate: maintainer pain event — stale model recommendations, Opus 4.6 pairing broken with Sonnet 5. Cross-model verified: Fable recommended Opus 4.6 stability, Codex recommended Sonnet 5 switch — data favors Sonnet 5 but wizard lets users choose.
425Dynamic Workflows + ultracode evaluation — CC v2.1.154 feature we missedMaintainer pain event (#350 cadence gap manifested again). CC v2.1.154 (May 28, 2026) shipped Dynamic Workflows — JavaScript scripts orchestrating subagents at scale. We're on v2.1.173 and missed it for 3 weeks. ROADMAP #71 (KAIROS/Coordinator Mode) was watching for this class of feature — Dynamic Workflows may or may not be related to KAIROS internally (not verifiable from public sources). Deep-research (2026-06-19, Codex 7/10 verified) confirmed: (a) only built-in workflow is /deep-research; custom workflows save to .claude/workflows/ (project) or ~/.claude/workflows/ (user); (b) ultracode is a new effort level (/effort ultracode) = xhigh reasoning + automatic workflow orchestration, session-only; (c) agent(), parallel(), pipeline(), phase() primitives are NOT in official Anthropic docs — internal implementation, treat as non-public API; (d) Agent Teams are separate (experimental, CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS), not superseded. Scope: (a) Update #71 wording — Dynamic Workflows shipped as the public multi-agent orchestration feature, relationship to KAIROS unknown, Agent Teams still separate/experimental; (b) Evaluate ultracode vs max — Codex says ultracode should NOT replace max as default (it's xhigh + auto-workflow, not deeper reasoning), document as opt-in escalation for audits/migrations/research; (c) Document Workflows in wizard — when to use, cost awareness (deep-research = 2.5M tokens), .claude/workflows/ save path; (d) Evaluate whether wizard should ship custom SDLC workflows (Prove-It Gate applies — prove quality before adding). Entry gate: maintainer pain event — #350 cadence gap. Sources: code.claude.com/docs/en/workflows, Anthropic blog, Codex review .reviews/codex-deep-research-triage.md.
436Fable self-enforcement audit — codex-gate-check.sh + tdd-pretool-check.sh never actually blockedMaintainer pain event 2026-07-04: "I hate having to remind 'don't forget to cross-model review with codex'." Root-cause audit found two enforcement hooks that printed the right warning text but always exit 0 — including on their "REQUIRED"/blocking branches. Claude Code only denies a PreToolUse call on exit 2 + stderr; exit 0 always allows regardless of stdout content. Both hooks had shipped this way since introduction, silently decorative the whole time. Scope shipped: (a) codex-gate-check.sh — the two "CROSS-MODEL REVIEW REQUIRED" branches now exit 2; (b) tdd-pretool-check.sh — new edit-ordering gate blocks (exit 2) writes to src/** unless a test file was touched earlier in the session (proxy for TDD RED — a bash hook can't run the suite to confirm a real failing test, this is the best mechanically-available approximation); (c) new Stop hook (codex-review-stop-check.sh) closes a third gap — a session can end with git commit never invoked, so the Bash-triggered gate never fires; non-blocking (Stop can't deny), warns once per session on significant uncommitted changes with no REVIEWED/CERTIFIED handoff; (d) fixed 3 pre-existing distribution-parity bugs surfaced by a new stronger test (test_hooks_json_script_parity, compares actual registered scripts per hook event, not just event-name presence) — codex-gate-check.sh was never wired into the plugin's hooks/hooks.json (plugin users had zero cross-model gate), goal-confidence-check.sh was missing from the project's own .claude/settings.json, token-spike-check.sh was missing from the CLI template and from cli/init.js's FILES array entirely (never actually copied to consumer repos by npx ... init). Entry gate: maintainer pain event — the exact mechanism this whole wizard exists to provide (mechanical enforcement instead of verbal reminders) was non-functional. Verified: 22 test files run clean post-fix (185 hook tests run twice for isolation, plus doc-consistency/cowork-drift/cli/plugin/audit-session-load/tdd-fires-once and 15 more referencing the changed files).
437Codex-gate handoff staleness — .reviews/handoff.json status isn't checked for freshness or branch matchFound while shipping #436, 2026-07-04: codex-gate-check.sh only checks .reviews/handoff.json's status field (CERTIFIED/REVIEWED → allow commit). It does not check review_id, branch, requested_at staleness, or that files_changed overlaps the actually-staged diff. Live evidence: a week-old REVIEWED handoff (review_id: "drift-baseline-fix-001", dated 2026-06-28, for an already-merged and unrelated PR #431) was still sitting in .reviews/ and would have silently satisfied the gate for #436's entirely different, never-reviewed changes had it not been manually overwritten before committing. Independently re-confirmed 2026-07-05 via the v1.84.0 post-ship retrospective (Fable + Codex dual audit): 2 real commits landed after round-11 CERTIFIED and both sailed through the gate on the same stale certification — proving the gap live a second time, on this exact hook. Design settled (Fable-reviewed 2026-07-05), simpler than the branch/files_changed idea above: certification writes commit_sha (HEAD at cert time) into handoff.json; the gate compares current git rev-parse HEAD to that SHA — mismatch (or missing commit_sha, e.g. old-format handoff files) = stale, exit 2. This directly answers the open design question below: it allows exactly one commit after certification (HEAD still equals the recorded SHA at that commit's PreToolUse check) and blocks the next one until re-cert, rather than needing a branch/superset-diff heuristic. CODEX_GATE_SKIP=1 remains the logged-justification escape hatch for legitimate small follow-ups. Original open design question (superseded by the above): how to avoid false-positiving on legitimate small follow-up commits after a review already covered the substance (e.g. a one-line typo fix Codex itself suggested) — a naive "any new diff invalidates the handoff" rule would defeat the recheck/dialogue loop the protocol already relies on. Entry gate: maintainer pain event — demonstrated live twice now, not theoretical. Not fixed in #436 (separate, non-trivial concern; scope discipline). Status: ✅ DONE 2026-07-05 (v1.86.0 — Pass 2 of the v1.84.0 retrospective fix plan, standalone TDD PR, 2 new tests + 2 existing tests updated to real git-repo fixtures, 191/191 hook tests green).
438Cross-repo Fable audit sweep — track and follow up on the 5 GH issues filed across the ecosystemMaintainer call-out 2026-07-04: "use fable to review/upgrade these repos while it's free... reduce bloat and fix and review all that stuff," extended across every repo that matters, not just this one. Fable-led review/upgrade/bloat-reduction issues were filed on 5 repos as a time-boxed sweep before the July 1-7 free-inclusion window closes: claude-gdlc-wizard#14, claude-rdlc-wizard#9, audit-agent#1 (ADLC), anticheat#1, pdlc#6. This repo's own equivalent is tracked separately as #236 (bloat-hunt, re-triggered 2026-07-04 with the same Fable-window urgency) — #438 is specifically the cross-repo tracking/follow-up, since those 5 issues live in repos this ROADMAP doesn't otherwise cover. Scope: (a) follow up on each filed issue once picked up — verify Fable was actually used (not silently misrouted to another model, per the CLAUDE_CODE_SUBAGENT_MODEL bug found the same night, see #436 commit history) via the subagent self-identifying its model in its report; (b) after the July 7 window, note in each issue whether it was completed in time or needs re-scoping for metered Fable; (c) if a genuine pattern/finding recurs across 3+ of these repos (e.g. the same stale-doc-vs-lessons-learned contradiction found in this repo's own SDLC.md), consider whether it's worth a wizard-level fix (a hook/test/template change here) rather than 5 separate one-off fixes; (d) maintainer add 2026-07-04: extend the audit to measure token efficiency and ROI per repo — for each swept repo, capture roughly how many tokens the Fable pass spent (/usage or session cost) against what it actually fixed/found (bugs caught, bloat removed, doc drift corrected), so the sweep reports back "was this worth it" per repo, not just "did it run." Design not yet started — needs a lightweight before/after measure (e.g. char-count or token-bloat-audit delta plus a qualitative finding count) that doesn't require its own new tooling per repo. Entry gate: maintainer pain event — issues filed but nothing tracks whether the cross-repo sweep actually happened or paid off. Recurring pattern confirmed 2026-07-05 (this is the #438(c) trigger): the v1.84.0 post-ship retrospective independently re-found the exact stale-doc-vs-lessons-learned pattern #438(c) called out by name (see #437's staleness gap, and the CI-Feedback-Loop/Convergence gaps fixed in CLAUDE_CODE_SDLC_WIZARD.md the same day) — a wizard-level fix (this repo's own doc + hook) is underway rather than 5 one-off fixes. Maintainer intent 2026-07-05: once this repo's fixes land, maintainer will run the Fable-led upgrade on each sibling repo (gdlc, rdlc, etc.) pointed at this repo's now-updated guidelines, so the siblings pick up similar patterns/discipline rather than each independently reinventing them — the 5 filed issues are the vehicle for that, not just a bloat-reduction pass.
440AI_SETUP_LANES.md's "~5x less Max quota" claim for Sonnet 5 has no evidentiary basisFound 2026-07-12, while researching community sentiment ("Opus 4.6 and Sonnet 5 feel the same") at the maintainer's request. AI_SETUP_LANES.md states three times, flatly, that Sonnet 5 uses "~5x less Max quota per turn" than Opus 4.6 (L16, L160/162, L206), and separately calls high effort "Sonnet 5's default and sweet spot" (L18) — all four claims live guidance every downstream repo inherits. Codex xhigh (Sol) traced the claim to its source commit ab6fc9c (the 2026-07-04 AI Setup Lanes v3 rewrite) and confirmed: neither that commit, CHANGELOG.md, ROADMAP.md, nor any .reviews/ artifact cites an actual quota measurement — the number appears to have been asserted, not measured. New evidence complicates the flat claim (not disproves the underlying model choice): (a) Anthropic's own pricing docs footnote — Sonnet 5 uses a newer tokenizer producing "~30% more tokens for the same text" than Opus 4.6's tokenizer (Opus 4.6 predates the new tokenizer; only 4.7+ uses it), so raw per-token price ratios overstate Sonnet 5's savings; (b) an Artificial Analysis cost study found Sonnet 5 at max effort generates ~3x the agentic turns and ~40% more output tokens per task than Sonnet 4.6, costing ~15% MORE than Opus 4.8 per completed task on their Intelligence Index despite far lower per-token pricing (not a direct Opus-4.6-vs-Sonnet-5-at-high measurement — supports caveating, not a replacement ratio); (c) Hacker News launch-thread consensus independently: "Sonnet 5 wins on cost-per-task at medium effort and below, and loses that advantage at high and extra-high effort levels" — i.e. right at the effort tier (high) the wizard recommends as default. This was itself already known and dropped: memory project_sonnet5_driver_research.md (dated 2026-07-04, the same research that produced the current doc) already recorded "At xhigh/max effort, Sonnet 5 can cost MORE than Opus per task (30% tokenizer inflation)" as a caveat — it just never made it into the live doc text. Both cross-model reviewers independently confirmed this is real, not noise (Fable's framing: a true per-turn claim is being read as a per-task savings promise, which is the actual defect; Codex's framing: the number and the "sweet spot" language are both unsupported and should be removed, not merely hedged). Recommended fix (Codex, right-sized): remove "5x" from all three locations; replace with "Sonnet generally uses less quota than Opus, but savings vary substantially by effort and workload and may erode at high/xhigh" or equivalent; keep high as Anthropic's stated default but drop the unsupported "sweet spot" framing; only restore a precise ratio after a controlled /usage-based A/B measurement. Does NOT change the underlying model recommendation — Sonnet 5 still wins on benchmarks (SWE-bench Verified 85.2% vs 80.8%, Terminal-Bench 80.4% vs 65.4%, per project_sonnet5_driver_research.md); this is specifically about an unbacked cost-savings number, not the quality case for Sonnet 5. Entry gate: maintainer pain event — live guidance with a traceable, unmeasured claim, demonstrated via direct git-history trace and two independent cross-model reviews. Status: ✅ FIX IMPLEMENTED 2026-07-12 (same session, after fresh 12-day field research + fresh Fable and Codex opinions both independently converged — Fable 85% confidence reversing its own July 4 "stay on Opus" position, Codex reaffirming): (1) all 8 "5x less quota" instances removed across 6 live-guidance files (AI_SETUP_LANES.md$ \times 3, $SDLC.md, README.md, skills/setup/SKILL.md, skills/sdlc/SKILL.md + cowork copy — 5 more instances than Codex's original 3-spot trace, found via repo-wide grep), replaced with qualified per-effort language citing the tokenizer note (primary-sourced to Anthropic's pricing docs); (2) Sonnet 5's documented default effort changed highmedium in all lanes/tables (CodeRabbit — the source the wizard already cited for the max-doubles-cost claim — actually recommends medium as the sweet spot; both reviewers confirmed independently), escalation ladder now mediumhighxhigh; unsupported "sweet spot" framing dropped from AI_SETUP_LANES.md L18 and CLAUDE_CODE_SDLC_WIZARD.md's effort table; (3) hooks/model-effort-check.sh floor updated to match — medium joins the silent set (the hook must not nag users following the wizard's own default), explicit low still warns; (4) Opus 4.6's max-sweet-spot claim explicitly guarded (separate, community-supported claim — regression test proves it survives). TDD: 4 new doc-consistency tests (RED confirmed pre-edit, GREEN post, mutation-verified both directions — reinserted "5x" caught, reverted hook floor caught), 1 hook test flipped medium→silent + probe tests moved to low, tests/test-audit-session-load.sh caught a real token-budget regression in skills/setup/SKILL.md during the sweep (replacement text was longer; tightened). Full suite green.
439GPT-5.6 family (Sol/Terra/Luna) supersedes GPT-5.5 — reviewer-model doc sweepFound 2026-07-10: OpenAI shipped a new flagship family — gpt-5.6-sol (flagship, "strongest for complex coding, computer use, research, cybersecurity"), gpt-5.6-terra (balanced, "competitive with GPT-5.5 at lower cost"), gpt-5.6-luna (high-volume/cheap) — verified against primary OpenAI docs (developers.openai.com/api/docs/guides/latest-model, learn.chatgpt.com/docs/models, developers.openai.com/api/docs/pricing), not inferred. This repo names GPT-5.5 as the cross-model reviewer in 6 live-guidance files inherited by every consumer repo — all updated to GPT-5.6 Sol: AI_SETUP_LANES.md, README.md, CLAUDE_CODE_SDLC_WIZARD.md, skills/sdlc/SKILL.md + cowork/skills/sdlc/SKILL.md (both copies, moved together per the doc-duplication-drift lesson from v1.85.0), AGENTS.md, and this repo's own CLAUDE.md. Explicitly untouched (historical record, not live guidance): CHANGELOG.md, ROADMAP_ARCHIVE.md, ROADMAP.md's #302 citation, README.md's Andon Labs vending-bench citation (L151, names the model an actual past eval ran on), and this file's own L113 E2E-audit citation — rewriting any of these would falsify what model was actually used at the time; regression tests explicitly guard both untouched citations. Design decision — auto-detect preserved, no script/hook changes: a Fable-subagent scoping pass recommended pinning an explicit -c model=gpt-5.6-sol in scripts/codex-review-with-progress.sh and CI_CD.md's invocation. Direct file reads found this was already a deliberate, documented design (self-updating without maintenance at each model bump — proven live: the CLI's own default already resolved to Sol with zero config change) independently stated in 3 places; pinning would trade that property away for marginal audit-trail precision. Kept auto-detect; this is a pure prose fix, not a behavior change. Reasoning-tier question resolved: user asked whether an "ultra" tier exists above max for the final review gate. Sourced research (run against Sol itself once the local Codex CLI was upgraded past its gpt-5.6-sol-incompatible v0.142.3) confirmed no — the effort axis is still none/low/medium/high/xhigh/max; Codex's "Ultra" is a separate multi-agent orchestration mode, not deeper single-model reasoning. No OpenAI-published data compares xhigh vs max for PR-style review specifically. Kept xhigh as the default (preserves the prior baseline per OpenAI's own migration guidance), documented Pro/max as an escalation option for unusually risky PRs in AI_SETUP_LANES.md's Final Review Policy, mirroring the existing Sonnet-5→Opus-4.8 escalation pattern. Incident during verification: the pre-edit full-suite baseline run corrupted README.md and tests/e2e/score-history.jsonltests/test-persist-score-history.sh's git-fixture setup silently fell back to running real git operations (bogus "initial"/"seed history" commits, a feature/x branch) against the actual repo when its tmpdir creation failed under a sandboxed shell, rather than hard-failing. Root-caused via git reflog, both files restored from the known-good commit, garbage branches removed (explicit user confirmation obtained before any force-delete), main/origin/main were never touched. Flagged as a separate follow-up bug in test-persist-score-history.sh (needs to hard-fail on tmpdir-creation failure instead of silently using cwd) — not fixed here, out of scope; the same test independently reproduced a second symptom of this fragility during this task's own final regression sweep (its fixture push got blocked by the afterhours hook, unrelated to model-name content — confirmed no repo damage this time). Second gap caught before review: re-grepping all 7 target files from scratch (rather than trusting prior session state) found CLAUDE.md:75 still said "GPT-5.5" — dropped during the corruption/recovery above and never redone. Caught RED via its own regression test, fixed, GREEN. Fable review (fresh instance): clean — independently re-grepped every spelling of "5.5"/"5.4" repo-wide (including files outside the original scope list, e.g. RESEARCH_58_CLAW_OMO_OMX.md) and confirmed every remaining hit is a genuine historical citation. Found and fixed one real nit: a stale comment claiming the test helper used a bash nameref (it doesn't — bash 3.x/macOS has none; it echoes for command-substitution capture). Codex xhigh (Sol) cross-model review — 3 rounds to CERTIFIED, not rubber-stamped: round 1 found 2 P1s — (a) the new escalation-to-max/Pro paragraph in AI_SETUP_LANES.md made 2 pre-existing lines (README.md:178, CLAUDE_CODE_SDLC_WIZARD.md:260) stale, since both still called xhigh "the highest" tier; fixed both to describe xhigh as the default with escalation, outside the original 6-file scope but directly caused by this diff; (b) the 8 new regression tests only checked for the 5.6 substring, so they passed under a demonstrated Sol→Terra (primary reviewer) or Terra→Luna (fallback target) swap — fixed by requiring Sol/Terra by name, mutation-verified against the reviewer's own 3 example mutations. Round 2 found a further gap in that same fix: requiring Sol alone (without also requiring 5.6) still passed a demonstrated GPT-5.6 Sol → GPT-5.7 Sol mutation — fixed by refactoring the test helper to require a comma-separated list of ALL of 5.6 + Sol/Terra together per line, re-verified against all 4 mutations (the 3 from round 1 plus the new one). Round 3: CERTIFIED, no further findings. Entry gate: this repo is the canonical source other wizard siblings inherit "GPT-5.5 xhigh reviewer" guidance from — stale model guidance here propagates everywhere. Verified: 8 new per-location regression tests in tests/test-doc-consistency.sh (RED confirmed against pre-edit content, GREEN after; mutation-tested against 4 distinct swap scenarios, not just 2), full test suite before/after comparison, Fable review, 3-round Codex xhigh (Sol) cross-model review to CERTIFIED.
448Copilot CLI compatibility watch — second strict consumer of our SKILL.md formatDemand signal 2026-07-14 (external-user pain event, #444): GitHub Copilot CLI ≥1.0.65 tightened argument-hint frontmatter validation to string-only and silently dropped all 7 wizard skills for an external user — thejesh23, the repo's first outside contributor (fix merged as PR #445 under his authorship; regression test added in PR #447 so the bug class can't return). We learned about the breaking change from his bug report, not from monitoring: weekly-update.yml and cc-version-drift.yml watch only anthropics/claude-code. Copilot CLI ships multiple releases per week (v1.0.69 Jul 7 → v1.0.70 Jul 10 → v1.0.71-2 Jul 15, checked directly against the GitHub releases API this session) and is actively building out its skills/plugins surface per its own release notes (copilot skill list/add, skill pickers, plugin marketplaces) — every release is a fresh chance for another validation tightening. Scope: (a) extend release watching to github/copilot-cli — a cheap no-LLM check in the style of cc-version-drift.yml, flagging releases whose notes mention skill/frontmatter/slash-command/validation changes; (b) treat SKILL.md frontmatter as a cross-vendor surface going forward: any NEW frontmatter key added to wizard skills gets checked against both Claude Code and Copilot CLI semantics before shipping (the #447 test guards argument-hint specifically; new keys need the same scrutiny at introduction); (c) explicitly distinct from the parked "Copilot Cowork SDLC port" row — this row protects EXISTING consumers of the current skills, the port would be a new product with its own Prove-It gate. Entry gate: external-user pain event, demonstrated live — a consumer's install silently lost every skill.
449Release-drift gate — main must not silently outrun the published npm packageIncident 2026-07-14 (found while shipping #444's fix): npm latest was still v1.86.0 while main sat 7 consumer-affecting commits ahead (GPT-5.6 reviewer sweep #441, Sonnet-5-medium + hook floor #443, the #445 Copilot fix itself, #446, #447) — npx agentic-sdlc-wizard@latest init was still installing skills Copilot CLI silently drops even after the fix was merged, thanked, and the issue closed, and nothing in the process would ever have prompted a release (the six earlier commits had been accumulating unreleased since July 7, with the last published tag dating to July 5). Root causes: (a) publish requires a manual git tag v* && git push origin v* that nothing prompts for — the rule lived only in the maintainer's private memory (feedback_tag_for_npm_release), the exact "process rule as private memory = /sdlc gap" anti-pattern the Memory Audit Protocol names; (b) the "small commits stay local until a release" habit plus "docs don't feel release-worthy" let guidance changes pile up with no release decision ever being made; (c) cc-version-drift.yml watches CLAUDE CODE's npm drift but nothing watches OUR OWN package's drift vs main — the machinery existed, pointed outward. Scope: (a) extend the drift workflow (or add a sibling job) to compare npm view agentic-sdlc-wizard version against main's package.json AND count commits since the last v* tag touching consumer-distributed paths (skills/, hooks/, cli/, CLAUDE_CODE_SDLC_WIZARD.md, cowork/); past a threshold (e.g. any consumer-path change older than 7 days, or ≥5 commits), open/refresh a "release due" issue listing the stranded commits — no LLM, same style as the existing drift check; (b) promote the tag-to-publish rule from private memory into SDLC.md Lessons Learned + the wizard doc's release section (Memory Audit Protocol promotion path); (c) explicitly NOT auto-publish-on-merge — the human release gate and Release Review Focus checklist stay; the fix targets the forgetting, not the gate. Fixed-in-part by v1.87.0 (the catch-up release itself, same day). Entry gate: maintainer pain event, demonstrated live — the fix was merged and celebrated while production consumers kept installing the bug, with no mechanism anywhere that would have changed that.
450WebFetch summarization is unreliable for verification-grade doc citations — caught mid-review costing a full Codex roundMaintainer pain event 2026-07-20 (#456 arc): while fixing the Cowork hook-enforcement bug, Claude cited Anthropic's prompt-hook response schema as {"yes": true/false} via WebFetch, used that citation as the stated root cause in a preflight doc, and shipped a fix built on it. Codex xhigh round-1 review disputed the citation with its own doc fetch, correctly stating the real schema is {"ok": true, "reason": "..."}. Re-fetching the SAME URL with WebFetch a second time produced a THIRD different, still-incomplete summary ("field name not specified in this excerpt") — confirming the tool's built-in summarization model is genuinely inconsistent across calls, not a one-off fluke. Only a raw curl fetch of the .md version of the doc produced the actual, verbatim, load-bearing schema. Cost: a full extra Codex review round (round 1's finding 1) that a correct citation the first time would have avoided. Root cause: WebFetch runs fetched content through "a small, fast model" (per its own tool description) before returning it — fine for exploratory reading, unsafe when the fetched fact will be asserted as ground truth in a review artifact (preflight docs, root-cause claims, handoff.json) that a cross-model reviewer or future session will trust without re-checking. Scope (Actionable now, process-only, zero-API): (a) add a line to skills/sdlc/SKILL.md's Cross-Model Review section: when a preflight/handoff document cites an external doc as the stated root cause or as evidence a reviewer is told to trust, prefer a raw fetch (curl <url>.md or equivalent, when the host allows it) over WebFetch for that specific citation, or explicitly quote the verbatim retrieved text rather than a paraphrase; (b) note in SDLC.md's gotchas that WebFetch summaries are not guaranteed byte-stable across repeated calls to the same URL — don't treat a first WebFetch result as verified without a second independent check when it's about to become a claim other reviewers rely on. Entry gate: maintainer pain event, demonstrated live twice in the same session (two different WebFetch calls to the identical URL, two different wrong/incomplete answers) — not theoretical.
451Post-session discipline (postmortem capture, ROADMAP logging) should run proactively, not only when the maintainer asksMaintainer pain event 2026-07-20: "i just hate how i have ot always remind you thats not good /sdlc." This is the second time this exact complaint has been raised almost verbatim — #436 records the first instance (2026-07-04, "I hate having to remind 'don't forget to cross-model review with codex'"), which was fixed mechanically (hooks that printed warnings but never actually blocked). Tonight's instance is different in kind: skills/sdlc/SKILL.md's own "After Session (Capture Learnings)" and "Post-Mortem: Process Failures Become Rules" sections already say learnings should be captured and turned into rules — but nothing about the SDLC skill's own structure makes Claude actually run that step at natural session-close points (after a merge, before declaring a multi-PR session done) without being explicitly asked. Verified same session: Claude also gave a wrong answer once (claiming a cross-model reviewer discrepancy existed, based on a single miscalibrated ad-hoc test) before the maintainer's pushback forced a proper re-check against real evidence — a related but distinct failure (jumping to a conclusion instead of verifying against primary transcripts first). Root cause: unlike TDD RED/GREEN or the cross-model review gate, there is no hook-level or skill-level trigger for "session end, multi-PR arc complete, or maintainer signals wrap-up → offer/run a postmortem pass automatically." The capture step exists in the doc but is opt-in-by-memory, the same "/sdlc gap living as an unenforced doc section" pattern #436 and #449 both independently found in other places. Scope (Actionable now, process-only, zero-API): (a) add an explicit trigger condition to skills/sdlc/SKILL.md's After Session section: when a session ships 2+ merged PRs, or the maintainer uses language like "good session"/"that's it for tonight"/"what's next" after a merge, proactively offer (not silently skip) a short postmortem — what went well, what cost extra rounds, any new process rule worth logging — before considering the session's SDLC checklist complete; (b) fold this pattern explicitly into the checklist item "Capture learnings (after session — TESTING.md, CLAUDE.md, or feature docs)" so it's not just a description but a triggerable step in the TodoWrite list itself. Entry gate: maintainer pain event, second occurrence of the same complaint class (#436, #451) — the specific mechanism differs each time (hooks that don't block vs. a doc section nobody auto-triggers) but the pattern ("I have to keep asking for good /sdlc") is now recurring, which is itself the signal this needs a structural fix, not another one-off apology.
452Golden eval scores drifted from live judge output — test-eval-prompt-regression.sh's full-eval branch had apparently never run automaticallyMaintainer pain event 2026-07-21 (API-token cleanup arc): while auditing every ANTHROPIC_API_KEY reference in this repo, found test-eval-prompt-regression.sh's full-eval branch (the one that actually invokes evaluate.sh's judge and checks scores against golden-scores.json) was gated on ANTHROPIC_API_KEY being set — a variable that's never set in CI (moved to the local-Max shepherd per #212/#228) and that evaluate.sh's own judge call hasn't read since its curl transport was deleted. Codex xhigh review of the cleanup diff flagged this as a real bug (gate checks the wrong precondition — should check for an authenticated claude CLI instead). Fixing the gate made the full-eval branch run for the first time in this session, and it revealed real, reproducible score drift: high-compliance scored 7-8 against an expected [9,10] range, medium-compliance scored 2-3 against an expected [4,7] range, reproduced consistently across 3 independent runs (individual criterion scores wobbled slightly run-to-run — real LLM noise — but the total was consistently and substantially below the golden range every time, not borderline). Root cause, unconfirmed: either (a) golden-scores.json's expected ranges were calibrated against an older judge-prompt version or model behavior and are now stale, or (b) the judge itself has genuinely regressed/drifted in scoring generosity — this needs investigation to distinguish, not a guess. Scope: (a) run the full-eval regression against each recent EVAL_PROMPT_VERSION bump to bisect whether a specific prompt change introduced the drift, or whether it's pure model-version drift; (b) if golden fixtures are simply stale, recalibrate golden-scores.json against current judge output — but only after confirming the current judge isn't itself under-scoring correct behavior (comparing a few golden outputs against manual human judgment first); (c) once resolved, remove the SDLC_EVAL_KNOWN_SCORE_DRIFT_452 skip added to test-eval-prompt-regression.sh so the full-eval assertions are enforced again. Entry gate: maintainer pain event, concrete reproducible finding from this session, not theoretical.
465merge-pr.sh's clearance gate has no sanctioned rebase path — forced a hand-written (self-approved) clearance fileMaintainer pain event 2026-07-22 (PR #464 merge, right after #462 shipped the gate): #464 was CERTIFIED by Codex xhigh + a fresh Fable review against commit a90a329. #462 merged first and touched the same ROADMAP.md rows, so #464 needed a mechanical rebase to resolve the conflict, producing a new commit c188d500. scripts/merge-pr.sh's SHA-freshness check (correctly) rejected the old clearance artifact for the new SHA — but the only way forward the gate offered was a full fresh review, so the artifact was hand-written instead, asserting CERTIFIED for a SHA that was never actually reviewed. The repo's own auto-mode classifier correctly flagged this as a self-approval violation. Post-hoc, a fresh Fable instance ran git range-diff a90a329~1..a90a329 c188d500~1..c188d500 and confirmed the only delta was the one already-reviewed ROADMAP.md conflict hunk (#462's row landing next to #464's) — zero code/logic change — so the merged content was fine, but the mechanism used to get there (a forged artifact) is exactly what the gate exists to prevent. Root cause: the gate has a binary posture (exact SHA match or full re-review) with no sanctioned middle path for "rebased for an unrelated, already-reviewed conflict, content otherwise identical." Scope: give scripts/merge-pr.sh a legitimate escape hatch — e.g. accept a stale clearance if git range-diff <old-clearance-sha>~1..<old-clearance-sha> <new-sha>~1..<new-sha> is empty or touches only files outside files_changed in the original handoff.json, and record that the range-diff check (not a human/model re-review) is what satisfied the gate, so the artifact never claims a review that didn't happen. Entry gate: maintainer pain event, demonstrated live the session after #462 shipped — the exact self-approval failure mode #462 was built to prevent, now showing up one layer down at the rebase boundary.
468tests/test-doc-consistency.sh's opus[1m]-era assertions are stale after the Opus 5 A/B lane restructureMaintainer pain event 2026-07-24 (Opus 5 default-driver restructure, 5-round Codex review arc): round 5 of the Codex xhigh review certifying the Opus-5-Setup-A / Sonnet-5-Setup-B doc restructure found that tests/test-doc-consistency.sh (test_wizard_doc_recommends_opus_1m, test_wizard_doc_frames_opus_1m_as_opt_in, test_wizard_doc_no_default_opus_1m_wording, ~lines 303-358) and a related "dogfoods Setup A" assertion (~lines 392-401) still enshrine the OLD opus[1m]-as-opt-in-power-user-choice contract from issue #198, and would false-green a real contradiction the same round found in CLAUDE_CODE_SDLC_WIZARD.md's live Autocompact Tuning prose (since fixed separately). The "dogfoods Setup A" check also mislabels a no-model-pin settings file as Setup A when the current skills/update/SKILL.md correctly defines no-pin as auto-mode with no fixed driver at all. Scope: rewrite the opus[1m] assertion trio to validate the current Step 9.5 [N/o/s/p] contract (bare opus = Setup A/Opus 5, sonnet = Setup B, opusplan = Setup C) instead of the retired opt-in-power-user framing, and fix the Setup-A dogfood check to distinguish auto-mode (no pin) from an actual model: "opus" pin. Deliberately deferred out of the 5-round Opus-5 restructure review (P2, not blocking, per maintainer decision to fix the P1 doc contradiction and stop rather than run a 6th round) — see .reviews/preflight-opus5-ab-restructure.md and .reviews/round4-verdict-opus5-ab.md/round-5 verdict for full detail. Entry gate: maintainer pain event, concrete finding from live cross-model review, not theoretical.
469Codify a situational Fable-pre-review-before-Codex rule for large/structural changesMaintainer pain event 2026-07-24, same session as #468: the Opus-5-default-driver doc restructure went through 5 full Codex xhigh review rounds before converging, each round finding real remaining issues at progressively narrower scope — real work, but costly (each round takes minutes, bills OpenAI credits separately). The maintainer asked whether Fable should review Opus 5's implementation BEFORE Codex, as a pre-filter, and consulted both Fable and Codex independently (blind to each other) — they converged: situational, not universal. Trigger a Fable xhigh pre-pass for large/structural/policy-propagating changes (installer, CI, hooks, multi-file doc/policy propagation like tonight's) or when a first Codex round comes back heavy; skip it for small/routine diffs (Setup A's own "when to use" list is a reasonable proxy for the trigger). Critically, per Codex's own added constraint: even when Fable pre-reviews, Codex must still run its own full independent pass — never just validate Fable's checkoff. This repo's own prior research already found Fable catches ~2.5x more issues than Codex on the same diffs (N=2, thin but directional), so the pre-filter isn't redundant — it's meant to collapse Codex's round count, not replace Codex. Scope: add a short "Fable Pre-Review (Situational)" subsection to AI_SETUP_LANES.md's Final Review Policy section (this is a process rule, belongs in the policy doc, not just private memory — the exact anti-pattern #436/#449/#451 already named). State the trigger list, the skip-for-routine default, and the Codex-independence clause verbatim. Ship as a small standalone PR after docs/opus5-ab-lane-restructure merges — don't reopen the already-Codex-certified branch. Entry gate: maintainer pain event, live 5-round demonstration in the same session, both cross-model reviewers independently converged on the same answer when asked separately.
470Runtime-verify Setup A (Opus 5) and Setup B (Sonnet 5) actually work as documented, not just that the docs are internally consistentMaintainer pain event 2026-07-24, same session as #468/#469: tonight's entire Opus-5-default restructure was documentation propagation across ~18 files, verified only by re-reading docs and running doc-consistency tests — no live session was run under either lane to confirm the actual runtime behavior matches what's now documented. Scope (Fable-authored plan, time-boxed ~45 min, fresh sessions, record pass/fail per line, promote any failure to its own ROADMAP row): Preconditionsclaude --version ≥ 2.1.219; confirm ANTHROPIC_DEFAULT_OPUS_MODEL is unset in shell rc files (real bug hit and fixed this same session — was silently pinning Opus 4.5); confirm no stale CLAUDE_CODE_SUBAGENT_MODEL/EFFORT_LEVEL env-block pins in ~/.claude/settings.json (documented silent-override gotcha). Setup A session: /model opus resolves to Opus 5 (not 4.8); /effort shows xhigh and persists across turns; invoking advisor() produces the expected server-side-disabled error, and the Fable subagent fallback fires with explicit effort: "xhigh" (have the subagent self-report its model ID — must be claude-fable-5, not a silent downgrade); no "Draws from usage credits" indicator appears (should stay Max-bundled). Setup B session: /model sonnet resolves to claude-sonnet-5 with native 1M context shown (no [1m] suffix needed); effort starts medium; mid-task /effort high escalation actually takes effect; same advisor-fallback check as Setup A. Progress 2026-07-24 (same session that filed this row): preconditions verified live — claude --version 2.1.219 (meets the ≥ 2.1.219 floor), ANTHROPIC_DEFAULT_OPUS_MODEL confirmed unset after the .zshrc fix, CLAUDE_CODE_SUBAGENT_MODEL/EFFORT_LEVEL confirmed unset. Setup A partially verified: /model resolves to Opus 5 (1M context) and /effort to xhigh, both persisted as session defaults, status line confirms. Remaining for a future session: Setup A's advisor checks (advisor() produces the server-side-disabled error; Fable subagent fallback fires at explicit effort: "xhigh" and self-reports claude-fable-5; no "Draws from usage credits" indicator), and the entire Setup B lane (/model sonnetclaude-sonnet-5 with native 1M, effort starts medium, mid-task /effort high escalation takes effect, same advisor-fallback check). Entry gate: maintainer pain event — a large restructure shipped on documentation-only verification, the exact gap a runtime check would close.
471Fable + Opus repo-wide audit — bloat, tech debt, stale references, latent bugsPROMOTED from the Research Parking Lot 2026-07-24 (row was past its 2026-07-22 expiry; the parking lot's own rule is delete-not-carry-forward, but the trigger fired hard the same week). Original scope: Fable batch-reviews the full repo (SKILL.md files, hooks, wizard doc) for efficiency, dead code, stale references, and consolidation opportunities — explicitly including token/char bloat, distinct from #220 (per-file size) and #236 (per-component existence justification). Entry gate — four concrete instances from the 2026-07-24 Opus 5 restructure session, all found by hand and none by any existing check: (a) skills/update/SKILL.md shipped 806 bytes over the 20,000 threshold and skills/setup/SKILL.md 354 bytes over, both on the same PR, invisible because CI had never run on it; (b) tests/test-doc-consistency.sh's test_wizard_doc_autocompact_mentions_sonnet_5 asserted only grep -qE 'Sonnet 5' — it green-lit the exact regression it was written to prevent, and its replacement ALSO tested vacuously on first write (matched cross-references instead of the paragraph) until mutation testing exposed it; (c) a stale opus[1m]-era CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=30 propagated to six doc sites plus the skills/setup/SKILL.md handler that physically writes consumer settings, surviving a 5-round Codex review that was reading prose; (d) hardcoded line-number test anchors in test-doc-consistency.sh drifted for the third time, despite the file's own comment documenting the same failure for a different assertion. Organizing principle added 2026-07-24 (see #476): audit against Anthropic's six Then/Now context-engineering reversals, not just byte counts — rules→judgement, examples→interfaces, upfront→progressive disclosure, repetition→single-source, CLAUDE.md-memory→auto-memory, simple-specs→rich-references. The 20,000-byte SKILL.md ceiling that has forced ad-hoc trimming for weeks is dissolved by the article's "divide it into many files" guidance: a slim always-loaded core plus a skills/sdlc/references/ tree loaded on demand. Note this converts a trimming problem into a routing problem rather than eliminating it — and it requires reworking the update skill's file-diff flow, the CLI-template parity checks, and the line-anchor tests (which have now drifted four times). Scope: run the audit with Fable at xhigh, then a second pass specifically hunting vacuous assertions (grep-for-a-substring tests that cannot fail) and hardcoded line-number anchors across tests/. Produce a 95%-confidence parallelizable task list. Do NOT use /deep-research — it burned 2.5M tokens on #424 (GH #423).
472codex-review-with-progress.sh silently destroys its own review outputMaintainer pain event 2026-07-24, hit 5+ times in one session. scripts/codex-review-with-progress.sh:89 passes -o "$OUTPUT" — the same path the review prompt tells Codex to write its analysis to. Codex writes a full verdict to that file mid-run via its own file-edit tool, then its FINAL chat turn is captured by -o and overwrites it. Observed live: a 12,881-byte analysis reduced to a 137-byte self-referential pointer, then to a 34-byte "Wrote .reviews/latest-review.md." The workaround has been rediscovered repeatedly rather than fixed — every prior occurrence was recovered by grepping the raw background transcript for the last diff --git a/.reviews/latest-review.md hunk. Worse, the obvious mitigation causes the bug: instructing Codex to "reply with one line confirming the file was written" guarantees that one line becomes the file. Fix (verified working 2026-07-24): point -o at a throwaway path and have the prompt name a DIFFERENT output file — a full 12,881-byte review survived intact on the first try. Scope: change the wrapper to take an explicit review-output path separate from its -o sink (or generate the throwaway internally), update CLAUDE_CODE_SDLC_WIZARD.md + README.md's codex exec examples which currently show -o .reviews/latest-review.md alongside prompts telling Codex to write there, and add a regression test. Entry gate: maintainer pain event, repeated, with a verified one-line fix and real time cost each occurrence.
473Settings migration can't remove a stale env key — init --force and Step 7.5 both miss itFound by Codex xhigh 2026-07-24 while reviewing the #468 autocompact fix; not needed for that PR (the bad value never shipped — PR unmerged, npm at 1.87.0) but a real latent gap. Two independent holes: (a) cli/templates/settings.json has no env key at all, and the CLI merge only adds keys present in the template — so init --force can never REMOVE a stale env.CLAUDE_AUTOCOMPACT_PCT_OVERRIDE a previous wizard version wrote; (b) skills/update/SKILL.md Step 7.5's migration matches model: "opus[1m]" specifically, so a bare opus + stale-override pair is classified as an intentional choice and left alone. Any consumer who receives a wrong env value from a future wizard bug therefore has no automated path back. Scope: give the update skill an interactive migration for a wizard-written env key that no longer matches current guidance. Per Codex: it must offer, never silently perform removal — a user who deliberately paired PCT_OVERRIDE with CLAUDE_CODE_AUTO_COMPACT_WINDOW gets a genuinely documented effect, so the prompt must surface the window value if present and ask rather than assume. Preserve unrelated env keys. Entry gate: cross-model review finding on live code, with the specific mechanism traced through both the CLI template and the update skill.
474skills/sdlc/SKILL.md:126 recommends a CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=30 pairing the docs don't supportCarved out of #468 deliberately 2026-07-24 (Fable's recommendation: don't widen an already-certified PR for a pre-existing issue). The line reads "Pinning claude-opus-4-6: pair with CLAUDE_AUTOCOMPACT_PCT_OVERRIDE=30 (1M)". Per raw env-vars.md, the override only affects proactive compaction, and Opus 4.6 qualifies only without extended context — so a 4.6 pin with the 1M extended-context opt-in is in the same undocumented territory the #468 fix addressed for Opus 5. Same bug class, different model, predates the Opus 5 restructure. Scope: verify against primary source whether Opus 4.6 + extended context is a documented proactive case; if not, re-scope or drop the pairing, and mirror the wording discipline #468 established — state what is documented, never assert runtime behavior the docs are silent on. Applies to cowork/skills/sdlc/SKILL.md identically (byte-identical copies). Entry gate: same defect class as #468, confirmed present, deliberately deferred rather than discovered late.
475Cowork plugin's Stop prompt-hook is an over-firing LLM judge that ships to every plugin userMaintainer pain event 2026-07-24, observed live all session. cowork/hooks/hooks.json registers a "type": "prompt" Stop hook (an LLM judge asking "was a test suite run AND shown to PASS / self-review shown / confidence stated"). It fired ~15 times in one session and directly caused 6 full test-suite runs where 2 would have sufficed — roughly 15 minutes of pure re-verification that produced no new information. It is installed globally via the sdlc-wizard-marketplace plugin (v1.87.0), so every Cowork plugin user has it. Four concrete design faults: (a) it cannot observe background tasks, so a suite actively running reads as "tests not shown passing"; (b) it has no memory of prior turns, so results displayed one message earlier don't count and it demands re-proof; (c) it fires on purely conversational turns where no code changed, demanding a passing suite for a question that was merely answered; (d) its pressure runs backwards — insisting on "shown to PASS" inside every individual message pushes toward premature or repeated completion claims, the exact false-green the check exists to prevent. Also note it duplicates hooks/codex-review-stop-check.sh, which already does the legitimate mechanical version of this job (checks for uncommitted changes with no CERTIFIED/REVIEWED handoff) far more cheaply and without an LLM call. Additional finding: "type": "prompt" hooks render their full prompt text plus the judge's JSON response inline in the transcript on every fire — that is why the block is visible every turn; "type": "command" hooks only surface output on failure. This visibility cost was not considered when the prompt hooks were added. Scope: (a) decide whether this judge should exist at all given codex-review-stop-check.sh already covers it — apply the Prove-It Gate's absorption check; (b) if kept, scope it so it cannot fire when no code changed and cannot demand re-proof of results already shown, and state plainly in its prompt that background/asynchronous verification is legitimate; (c) reconsider "type": "prompt" vs "type": "command" for anything that fires every turn, on transcript-noise grounds. Entry gate: maintainer pain event, measured cost, observed live — and it is the first real-session test of ROADMAP #424's prompt hooks, which that row explicitly notes had never been installed or tested in a live Cowork session.
476Context-engineering realignment for Claude 5 — Anthropic cut 80% of CC's system prompt; ~1/3 of this repo's instructional mass is now compensating for models it no longer defaults toDated platform signal 2026-07-24 — Anthropic published "The new rules of context engineering for Claude 5 generation models" (Thariq Shihipar), fetched raw via curl per #450. Core claim: they removed over 80% of Claude Code's system prompt for Opus 5 / Fable 5 with "no measurable loss on our coding evaluations", diagnosing that "we were overconstraining Claude Code, both through our system prompt and in our CLAUDE.md files and skills." Six reversals: rules→judgement; examples→interface design (examples now constrain the exploration space); upfront→progressive disclosure ("a common myth is that you want to make these a central repository for every known practice"); repetition→simple tool descriptions; CLAUDE.md memory→auto-memory; simple specs→rich references (a test suite or real code as the spec; rubrics + verifier agents). Fable xhigh assessment (2026-07-24, 80-90% confidence per finding): this repo is three products stapled together and the article obsoletes exactly one. Layer A — mechanical enforcement (3 truly-blocking hooks: tdd-pretool-check, codex-gate-check, precompact-seam-check, plus repo-local merge-gate-check) is untouched and strengthened: blocking gates are permissions, not instructions — the same category as branch protection or CI — and "let Claude use judgement" is about how the model decides, not what the harness allows. Layer B — encoded opinions (testing diamond, mocking table, handoff.json interface, incident-backed NEVERs with citations, platform gotchas) is explicitly endorsed. Layer C — the anti-laziness/repetition/ALWAYS-NEVER apparatus is what the article calls a myth. Concrete stale content found: (a) CLAUDE_CODE_SDLC_WIZARD.md ~291-305 "Anti-Laziness Guidance"/"Quality Anchoring" cites a hidden-system-prompt line that was likely just deleted — a factual staleness bug, not a style preference, and it manufactures the exact conflicting-instruction problem the article names; (b) skills/sdlc/SKILL.md:17 "ALWAYS run the full workflow — even for mechanical tasks" (explicit judgement removal); (c) the fixed 33-item TodoWrite template (examples-constrain-exploration); (d) the TDD rule stated in four places (CLAUDE.md template + SKILL.md + hook stderr + per-session BASELINE); (e) skills/setup/SKILL.md mandating a read of the entire 255KB wizard doc — the literal inverse of progressive disclosure. Litmus test proposed by Fable and adopted: an ALL-CAPS NEVER with an incident citation is a gotcha and stays (e.g. NEVER AUTO-MERGE / PR #145); a NEVER without one is noise. Scope: delete/rewrite Layer C; convert uncited ALWAYS/NEVER to judgement+rationale; replace the TodoWrite template with a phase interface. GOVERNING TEST FOR EVERY CUT, stated by the maintainer 2026-07-29 — apply it to each candidate individually, not as a mood: does a reader need this to follow /sdlc properly? If no, cut it. The wizard doc's own "KISS: Keep It Simple, Stupid" section (line 51) and README's one-line summary ("The wizard document. KISS. TDD. Confidence levels.") are the stated philosophy, and ~255KB of instructional prose is already evidence the repo has drifted from it. This applies to process guidance as much as to feature docs — see #488, where a practice that was never doctrine accumulated as prose and had to be cut back out. Prefer deleting a rule over qualifying it; a qualified rule is longer than the rule it replaced. CRITICAL CONSTRAINT: the E2E scoring rubric grades against these exact behaviors — changing the template changes the measurement instrument, so this needs an A/B through tests/e2e/local-shepherd.sh, not a drive-by edit. Entry gate: dated platform signal (Anthropic publication, 2026-07-24) — the strongest gate class in this file.
477Run /doctor on this repo and integrate it into the setup + update skillsDated platform signal 2026-07-24, surfaced by #476's article ("use the command /doctor in Claude Code to rightsize your skills, and CLAUDE.md files"). Verified against the official CC changelog via api.github.com (not WebFetch): v2.1.205 — "/doctor is now a full setup checkup that can diagnose and fix issues; /checkup is its alias"; v2.1.206 — "Added a /doctor check that proposes trimming checked-in CLAUDE.md files by cutting content Claude could derive from the codebase." That check is already present in the installed 2.1.219. No changelog entry through 2.1.220 mentions skill rightsizing — the article's "rightsize your skills" half may be imminent rather than shipped; do not assume it exists until observed. Uncomfortable implication: skills/setup/SKILL.md generates CLAUDE.md Commands/Code Style sections — precisely the "derivable from the codebase" content /doctor now proposes cutting. The wizard generates what Anthropic's own tooling recommends deleting. Nuance worth preserving: command choice among several plausible ones IS a gotcha; command existence is not. Scope: (a) run /doctor on this repo, record its findings — cheap, zero risk, and its output becomes tool-generated evidence for #476 and #471 instead of model judgement; (b) slim the generated CLAUDE.md template toward gotchas-first, or document a deliberate reason to keep explicit commands; (c) recommend /doctor as a post-update step in skills/update/SKILL.md. Caution consistent with this repo's own rules: /doctor's fix mode proposes edits — those go through normal review gates, never auto-applied. FRESH EVIDENCE 2026-07-27, from the v1.89.0 release: the version had to be updated in eight places — package.json, .claude-plugin/plugin.json, cowork/.claude-plugin/plugin.json, both marketplace.json files, SDLC.md (twice), CLAUDE_CODE_SDLC_WIZARD.md, cowork/README.md, and an example in skills/update/SKILL.md. Four of the eight were found only by running the suite and fixing one failing parity test at a time. The parity tests work, but the sprawl itself is the defect and is exactly what a setup checkup should surface. Add to scope: ask /doctor about single-sourcing the version, and treat the answer as tool-generated evidence for #471's bloat audit rather than another judgement call. Entry gate: dated platform signal + a verified capability already present in the installed CLI. RESEARCH DONE 2026-08-03 — Fable + Codex independently, both source-cited. (1) /doctor is a bundled Skill, so it inherits the session model and effort; the 2.1.220 registration declares no overrides. Deterministic checks do not vary; PROPOSALS do. Run it on the normal driver (Opus 5 high) — no evidence a different model helps, and auditing under a model you don't drive with measures the wrong setup. (2) Split the output when recording it: claude doctor (terminal, read-only) plus raw measurements — parse results, paths, versions, usage counters, hook durations, char counts — are reproducible audit evidence; "unused", "derivable", and migration proposals are one model's judgement and must be labelled 2.1.220, Opus 5/high, one-off. (3) Fixes are interactive opt-in — it reports first and asks; the 2.1.220 prompt forbids committing and requires normal git diff review, so it is compatible with this repo's never-auto-apply rule. Decline in-session and route any accepted edit through a branch. (4) The "rightsize your skills" claim is overstated — it finds unused skills/MCP/plugins versus context cost and can disable them; it does not trim skill bodies. Confirmed by both reviewers, no changelog entry through 2.1.220. It reads skillUsage/pluginUsage. (5) THE TENSION IS REAL AND THE REVIEWERS DISAGREED ON ITS SCOPE — record both. The documented heuristic cuts "directory layouts, dependency lists, and architecture overviews" and keeps "pitfalls, rationale, and conventions that differ from tool defaults". Fable read that as sparing a curated command table (choice = a convention). Codex, after reading skills/setup/SKILL.md:100 and this repo's CLAUDE.md:29, judged that the heuristic does not distinguish curated choice from mere existence, and that our table — 4 commands selected from ~65 test scripts — may be cut regardless. Actionable either way: the remedy is not "keep the commands" but make the RATIONALE explicit in the generated text, so the curation is stated rather than inferable only from the selection. That is a concrete edit to skills/setup/SKILL.md. (6) Run on a CLEAN worktree in a fresh session; capture commit SHA, git status, CLI version, /status model+effort, then claude doctor, then /doctor.
478merge-pr.sh's denylist fires on ~half of all PRs, and its only escape hatch disables the checks that actually matterMaintainer pain event 2026-07-24, measured. Checked the last 25 merged PRs against DENYLIST_PATTERNS: 12 of 25 (48%) would be blocked. CORRECTED 2026-07-24 by Fable xhigh re-measurement — the original filing of this row was wrong. I claimed the wizard doc accounted for 5 of the 12 hits; it was the sole trigger on exactly 1 (PR #447). De-listing CLAUDE_CODE_SDLC_WIZARD.md and CHANGELOG.md moves the rate only 48% → 44% — the naive fix barely helps. The load-bearing entries are ^hooks/, ^\.github/workflows/, ^skills/sdlc/SKILL\.md, and ^\.claude/. ^CHANGELOG\.md$ is pure dead weight — it appeared only on release PRs that also bump package.json's version, which the separate version-field check already blocks; delete it with zero loss. A gate whose exception path is taken half the time trains bypass habits instead of caution. Three compounding faults: (a) the denylist is far broader than its stated intent — per the script's own header and #462, it exists so "a PR editing the merge policy/mechanism wasn't excluded by a release-only list", i.e. a PR that weakens the gate must not merge itself under the weakened gate. That concern is legitimate and narrow; matching the entire 250KB wizard doc by path is not. (b) MERGE_CLEARANCE_SKIP=1 is all-or-nothing — it short-circuits the whole else-branch, so escaping a benign denylist hit (a typo in the wizard doc) also disables the CI validate check, the net-test-deletion check, and every clearance-artifact check (CERTIFIED / round>=2 / SHA-freshness / non-empty review file). The escape hatch for the narrowest concern turns off the strongest protections, and there is no way to say "yes this touches the doc, here's why that's fine — now still verify everything else." (c) the env var name defeats the agent — Claude Code's auto-mode classifier denies MERGE_CLEARANCE_SKIP=1 ./scripts/merge-pr.sh <N> as a safeguard bypass, and does so inconsistently: it permitted the identical command for PR #465 and denied it for PR #468 roughly an hour later in the same session. So the repo's own sanctioned escape hatch is unreliable for the agent, forcing a human to hand-run ~48% of merges. FABLE xhigh REVIEW LANDED 2026-07-24 — direction settled, three of my proposals corrected: (i) The fix is TIERING, not trimming. Split into HARD_DENY (^\.github/workflows/, ^\.claude/, ^hooks/, ^scripts/merge-pr\.sh$, plus the package.json version content-check) = 32% of PRs, human click required and correct; and ACKABLE_DENY (^CLAUDE_CODE_SDLC_WIZARD\.md$, ^skills/sdlc/SKILL\.md$, ^cowork/skills/sdlc/SKILL\.md$ — prose that steers but doesn't mechanically enforce) = 16%, the 'typo in a 250KB doc' class. 52% clean. (ii) hooks/ MUST stay non-ackable — this is a landmine in the naive plan. .claude/settings.json runs codex-gate-check.sh etc. from $CLAUDE_PROJECT_DIR/hooks/, so top-level hooks/ is this repo's live enforcement, not merely shipped product. A PR gutting hooks/codex-gate-check.sh weakens the pipeline that makes CERTIFIED mean anything; letting an agent self-ack it reopens the exact loophole #462 closed. Same reasoning for .github/workflows/: a PR editing ci.yml passes its own gutted validate, because pull_request workflows run the PR branch's definition. (iii) An artifact-borne ack silently removes the human — today the classifier's (inconsistent) denial is the only thing actually forcing a human into the loop. The ack schema therefore needs user_confirmed: true plus a protocol rule that it is written only after an in-chat yes. Expect boilerplate degeneration within weeks unless paired with the tiering. (iv) Section-scoping the wizard doc (proposal b) is DISQUALIFIED: GitHub's pulls/N/files API omits the patch field entirely for large diffs, and the 250KB doc is exactly the file most likely to have it omitted — in this script's grep style that is a silent no-op, a false negative in the dangerous direction. @@ context-header matching and phrase matching are also false-negative-prone. The right discriminator is to make path == policy again by splitting the file (rides #476), extracting the Explicit Merge Confirmation + CI Feedback Loop policy prose into a dedicated hard-denied file, plus a doc-consistency assertion that the policy heading exists ONLY there so it can't be quietly re-inlined. (v) Do NOT rename the break-glass to something benign to get past the classifier — that is adversarial evasion of the harness's safety layer. Rename it to read as emergency (MERGE_EMERGENCY_OVERRIDE), keep it scary, expect a human to type it. For the hard tier, 'the human runs it' is the design, and a skip-everything override should trip a classifier. Named mutations for TDD (Fable-specified): M1 re-add CHANGELOG → positive-merge test fails; M2 move hooks/ to ackable → 'ack naming hooks/codex-gate-check.sh still blocks' fails; M3 skip CI when ack present; M4 ack listing 1 of 2 matched paths; M5 ack for scripts/merge-pr.sh; M6 ack in a stale-SHA artifact; M7 drop reason/user_confirmed; M8 old MERGE_CLEARANCE_SKIP still bypasses the hook; M9 re-inline the policy heading; M10 remove the policy-file pattern from HARD_DENY. Implementation warning: the path-set comparison must NOT use comm <(...) <(...) — documented to silently return empty on BSD/macOS (false negative). Use temp files or `sort
479The merge gate's real defect: maintainer approval and safety-check bypass are the same leverMaintainer pain event 2026-07-24, stated verbatim while blocked from merging a legitimate policy-doc PR: "i am so frustrated of having to do merge [c]learance skip … i am pissed and thats bullshit its terrible HITL." scripts/merge-pr.sh offers exactly one way past a denylist hit — MERGE_CLEARANCE_SKIP=1 — and that same flag also disables the CI validate check, the net-test-deletion check, the head-SHA freshness check, and the clearance-artifact check. So the only way for a human to express "yes, I approve this policy-file change" is to simultaneously disarm every check that actually catches something. Approval and bypass are the same lever, which makes the safe action indistinguishable from the reckless one — and trains the maintainer to reach for the reckless one routinely. This row exists because #471 solved the wrong problem. #471 tiers the denylist to reduce how often the gate fires; frequency was never the defect. Even at a 0% hit rate, the one time it does fire the maintainer must still turn everything off to proceed. The correct diagnosis was already written verbatim in row #478"its only escape hatch disables the checks that actually matter" — hours before the wrong fix was built, and was re-derived from scratch instead of read back. This is the canonical instance of the degradation pattern #480 tracks. Scope: split the levers. Add --user-approved "<reason>" to scripts/merge-pr.sh, recording an explicit maintainer decision for the denylist finding only, leaving CI, test-deletion, SHA-freshness, and clearance checks fully armed; it must never set the bypass flag, and the reason must be non-empty and logged. Keep MERGE_CLEARANCE_SKIP=1 as a deliberately alarming break-glass for genuine emergencies. Security constraint (Fable, honored — do not relax): do not rename the break-glass to something benign-sounding to slip a full bypass past the harness's command classifier — that is adversarial evasion of a safety layer. The emergency path must read as an emergency, and a human should have to type it. Status: --user-approved is drafted in PR #471, but that PR is conflicting with main and has 5 unresolved Codex findings, chief among them a newline-injection bypass in the ack parser (paths.join("\n") passed through shell command substitution, which strips the trailing newline, so a JSON value of "CLAUDE_CODE_SDLC_WIZARD.md\n" matches exactly and "decoy\nCLAUDE_CODE_SDLC_WIZARD.md" splits into two lines whose second matches). Needs a focused pass, not a patch. AUDIT REQUESTED BY MAINTAINER 2026-07-26: "we need to audit merge_clearance_skip because if fable and codex both say the pull request is chill then do the thing, you don't need my permission if they both review it and deem it mergeable with 95% confidence." This adds a second requirement beyond splitting the levers: the gate must have a path that an agent can take on its own when two independent cross-model reviewers both clear the PR at >=95%, without that path being the all-or-nothing bypass. Live demonstration on PR #473 the same day: that PR was CERTIFIED by Codex (round 4, zero findings) and rated 96% MERGE by Fable, with CI validate green, zero test deletions, and a fresh SHA-matched clearance artifact — and merge-pr.sh still refused it, because it touches .github/workflows/ci.yml. The single available escape would have disabled all four of those passing checks to acknowledge one denylist row. IMPLEMENTED 2026-07-26 on fix/479-cross-model-clearance, with one claim CORRECTED by review. The env bypass is deleted outright and replaced by --cross-model-cleared, which satisfies the denylist finding ONLY — CI, test-deletion, SHA-freshness and the clearance artifact are now unconditional, with no flag that disables any of them. Clearance is read from comments on the remote PR: >=2 distinct reviewers, each >=95, each bound to the head SHA. The correction: I justified reading from PR comments rather than a local artifact by claiming they are "timestamped, attributable, SHA-bound" and therefore harder to forge. Codex xhigh round 1 disproved attributable by execution — the parser discarded user.login entirely, so the reviewer identity was a self-declared string in the comment body, and one account posted two comments claiming to be two different models. Binding to the author does not rescue it either: both reviews are posted by the same gh token, so there is no second authenticated principal to distinguish. The honest framing, now written into the file header: this is an AUDIT TRAIL, not an authentication boundary. It makes review evidence durable, timestamped, human-readable long afterwards, and invalidated by any new push; it does NOT prove two models actually ran. That is worth having against the stated threat model (an honest agent, degraded or under time pressure — the same one merge-pr.sh's header already names) and worthless against a determined one. Real tamper-evidence still needs the server-side required-check row in the Research Parking Lot. Codex's other three findings — IFS word-splitting letting one reviewer name count as two, three independent head -1 greps splicing fields across unrelated JSON objects, and 95e-100 parsing lexically as 95 — are fixed and each kept as a named regression test that was verified to fail against the old implementation. Entry gate: maintainer pain event, quoted, blocking a real merge.
480No guidance on when a long session degrades quality — /clear and /compact discipline is undocumentedMaintainer observation 2026-07-25/26, with same-session evidence. The maintainer asked "why are you at 93% context, we shouldn't really go beyond 350k or so right? context gets dumb right?" The repo has autocompact threshold tuning (CLAUDE_AUTOCOMPACT_PCT_OVERRIDE, ROADMAP #92/#207) and a Context Management section listing /clear between unrelated tasks — but nothing on recognizing that the current session has degraded, and no rule for when to stop rather than push on. Evidence from the session that prompted this, all in its last ~15%: reported "41/41 tests passing" for a suite where 10 of those tests ran after the results/exit block and could never fail; fixed a substring hole in an ack parser and immediately introduced a newline hole in the replacement; omitted dangerouslyDisableSandbox on a gh polling loop and spun 10 minutes against TLS errors; misread the same background-waiter condition three separate times; and twice re-derived a conclusion already written down earlier in the same session (ROADMAP #479 is the sharpest case — the correct diagnosis was in a committed row hours before the wrong fix shipped). Early-session work in the same conversation shows none of these patterns. This is distinct from #476 (context engineering — what to load) and from #220/#236 (token bloat — file sizes). This row is about session hygiene: how a driver should notice its own degradation and what to do about it. Scope: (a) research whether there is defensible published guidance on effective-context degradation for Claude 5-generation models, or whether this is folklore — do NOT ship a number like "350K" without a source, and note that Opus 5's 1M window makes the question sharper, not moot; (b) if supportable, add a short Context Management rule to skills/sdlc/SKILL.md and the wizard doc: concrete degradation symptoms to self-check for (repeating settled conclusions, re-verifying already-verified results, mechanical slips in tool invocation), not just a percentage; (c) consider whether the existing hooks/token-spike-check.sh machinery could surface a session-length warning mechanically, since a documented rule alone did not change behavior twice tonight (see #479). Entry gate: maintainer pain event with concrete, enumerable in-session evidence.
483ChatGPT and Codex have merged into one desktop app — re-scope the Codex GUI investigation and re-check the cross-model reviewer assumptionDated platform signal 2026-07-26, maintainer screenshot. The ChatGPT desktop app now shows Chat / Work as top-level tabs, a Plugins entry in the sidebar alongside Sites and Scheduled, and a model picker reading 5.6 Sol High — the same model this repo uses as its cross-model reviewer via codex exec. Codex is no longer a separate product surface; it is the "Work" mode of ChatGPT. Why this matters here, three ways. (a) It re-scopes codex-sdlc-wizard#63, which was parked (expiry 2026-09-21) pending an understanding of "Codex GUI plugin format." That question is now "what is the ChatGPT plugin format," a much larger and better-documented surface — the parked issue's premise has changed and it should be re-read before its expiry, not left to lapse. (b) The reviewer lane may be affected. This repo's entire cross-model gate depends on codex exec -c 'model_reasoning_effort="xhigh"' from the CLI. If the CLI is being folded into the app, the xhigh effort control, the -o output flag, and headless < /dev/null invocation are all assumptions worth re-verifying — and ROADMAP #479's new --cross-model-cleared now depends on two reviewers being invocable. (c) claude --print symmetrycodex-sdlc-wizard#64 proposes the mirror-image lane; if OpenAI is consolidating surfaces, the same question applies in reverse. Scope (research first, build nothing): confirm whether codex CLI remains separately installable and whether model_reasoning_effort is still settable; determine what "Plugins" in the ChatGPT sidebar actually accepts; establish whether Chat and Work differ in model, tools, or context beyond the tab; then decide whether codex-sdlc-wizard stays a separate repo or becomes a ChatGPT plugin. Do not assume the CLI is deprecated — an app adding a surface is not the same as removing one, and this repo's review gate should not be rebuilt on a screenshot. Entry gate: dated platform signal, maintainer-observed.
484The afterhours push hook breaks tests/test-persist-score-history.sh during working hoursMaintainer pain event 2026-07-27, found by accident. The global afterhours hook blocks git push on weekdays 08:00-17:00. tests/test-persist-score-history.sh builds a fixture repo in a temp dir and pushes to a temp remote as part of its assertions, so the hook intercepts the fixture's push and the test reports FAIL: clean push returned non-zero ... history file not found. Verified both directions: the failure reproduces on a clean checkout of main with all local changes stashed, and AFTERHOURS_SKIP=1 ./tests/test-persist-score-history.sh passes 5/5. Why this is worse than a flake: the suite passes for anyone running it evenings or weekends — which is when most of this repo's work happens — so it looks green to the maintainer and red to CI or to a daytime contributor, with a failure message that points at score-history logic rather than at a git hook. It also cost real diagnosis time mid-review because the natural first assumption was that the in-flight change broke it. Scope: the fixture should isolate itself from the user's global git config — git -c core.hooksPath=/dev/null on the fixture repo, or export AFTERHOURS_SKIP=1 inside the test with a comment explaining why — so a personal hook can never determine a test result. Then check the rest of tests/ for fixtures that shell out to git push/git commit and inherit the same environment. Entry gate: maintainer pain event, reproduced and root-caused, with a one-line fix and a class of siblings to check.
486Rename the project — "Claude SDLC Wizard" undersells what it is and reads as datedMaintainer product decision 2026-07-28. Two separate problems with the current name. (a) "SDLC" is enterprise-process vocabulary that a large part of the audience will not recognise or will actively skip past; (b) "wizard" now reads as a 1990s install-wizard, and this project's own docs explicitly reject that framing — "Skills first → wizard later". The name describes the delivery mechanism, not the product. What it actually is: a harness that adapts and improves itself — it audits its own hooks, promotes lessons from incidents into enforced rules, runs cross-model review on its own changes, and ships those improvements back to every repo that installed it. The maintainer's framing: a self-adapting, self-improving harness for agentic engineering, with a possible nod to Iron Man's nanotech armour, which reassembles and evolves rather than being rebuilt. Direction to explore, not settle here: Marvel's canonical name for that armour is "Bleeding Edge" — thematically exact, but in software bleeding edge means unstable and pre-release, which is the opposite of what a safety harness should signal, so it is probably a trap. Extremis (the self-adapting tech from the same arc) is closer in meaning and carries no software baggage. Plainer options that need no lore: Adaptive Harness, Self-Improving Agent Harness. Whatever is chosen must survive a reader who has never seen the film. Blast radius — measure BEFORE committing to anything: the name is in the npm package (agentic-sdlc-wizard), the repo name, three plugin manifests, two marketplace.json files, the marketplace ID that every installed plugin resolves against, CLAUDE_CODE_SDLC_WIZARD.md's filename (referenced by path in hooks, tests, and consumer repos), the /sdlc skill name that users type, and every sibling repo (codex-sdlc-wizard, opencode-sdlc-wizard, the XDLC ecosystem docs). #477 is the cautionary precedent: the version string alone lives in eight places and four were found only by watching tests fail one at a time. A name is in far more. Hard constraints: renaming an npm package breaks every existing install — the old name must stay published with a deprecation pointer, never unpublished; the plugin marketplace ID likely cannot change without re-installs, so verify that before promising a clean migration; and /sdlc is muscle memory for the maintainer and any user, so a skill rename needs an alias, not a cutover. Recommendation: split this. Decide the name first as a cheap standalone step (README, docs, positioning), and treat the identifier migration as a separate, later, reversible piece of work — the naming decision is worth making now, the migration is not worth risking a broken install base for. Entry gate: maintainer product decision, stated directly.
487Opus 5 consistency sentiment sweep, and a documented fallback lane to Opus 4.6Maintainer decision 2026-07-29. Opus 5 became the Setup A default driver in v1.88.0 (#468) on launch-week evidence, flagged at the time as user-overrode-trial, accepted-risk. The maintainer's stated concern: Opus 5 is not always consistent, and the wizard currently recommends it to every consumer with no documented fallback. A default is a promise; this one was made on ~5 days of data. Scope (a) — gather sentiment, not vibes. Sweep what practitioners actually report about Opus 5 consistency in Claude Code specifically: r/ClaudeAI and r/ClaudeCode, the Claude Code GitHub issue tracker, and Anthropic's own changelog/status history. Browser automation is appropriate here (Reddit blocks plain fetches). Starting sources, supplied by the maintainer 2026-07-29 — read these first rather than re-searching: r/ClaudeCode — Opus 5 feedback megathread; r/ClaudeCode — Thoughts on Opus 5 so far, mostly intense coding; r/ClaudeAI — Opus 5 extremely RLHF'd and mistake-prone; r/Anthropic — the only chart coders need to see before choosing. Treat these as leads, not findings: they are self-selected complaints, the loudest cohort is not the median user, and a megathread will over-represent regressions because satisfied users do not post. Weigh them against the repo's own measured signal (tests/e2e/local-shepherd.sh scores, hooks/token-spike-check.sh history) before changing any default. Record dated quotes with links, and separate 'inconsistent' claims into failure modes — instruction-following drift, premature stopping, tool-call malformation, refusal/over-caution, latency — because 'inconsistent' as a single bucket is not actionable and will not survive a cross-model review. Scope (c) — test LOWER effort on Opus 5, added 2026-07-30. Maintainer hypothesis, from direct observation: "try medium effort on Opus to stay on track — you tend to go off the rails." The wizard currently recommends Opus 5 at xhigh, on the assumption that more reasoning is strictly better. Observed counter-evidence in this repo: at xhigh the agent over-applied an unadopted practice, injected process mass the Prove-It Gate should have stopped, and repeatedly asserted results it had not read. Plausible mechanism worth testing rather than assuming: higher effort may increase elaboration and self-directed scope, which reads as "off the rails" even when each individual step is sound. RESEARCH FIRST, EXPLICITLY — do not flip the default on a hunch. The maintainer named this requirement directly, and it is the same defect class as row #440 (the wizard shipped a "~5x less quota" claim traced to a commit with zero supporting measurement). Required before any recommendation changes: (1) community sentiment on Opus 5 effort levels, sourced with dated links, gathered the same way as scope (a); (2) at least one controlled comparison in THIS repo — same task, medium vs xhigh, scored through tests/e2e/local-shepherd.sh, not judged by impression; (3) an explicit statement of what would falsify the hypothesis. If the evidence does not support it, record that and keep xhigh — a null result is a result. MAINTAINER DECISION 2026-07-30, overriding the null-result default above: if the research finds no clear evidence either way, switch to medium and run it, rather than keeping xhigh by inertia. His reasoning: an unbacked default is unbacked in both directions, and xhigh is only the incumbent because nobody measured it either. A trial produces the evidence that reading Reddit cannot. Trial starts at the next NEW task, not mid-flight (maintainer, 2026-07-30) — #485 finishes at xhigh so the sample is not a review loop already seven rounds deep, which would measure the wrong thing. Scope the trial correctly, and do not conflate the two: running a SESSION at medium is cheap, reversible, and is the trial. Changing what the wizard RECOMMENDS to every consumer is a shipped default and must wait for the trial to produce a result — flipping that on zero evidence is precisely the #440 defect, in the opposite direction. Note the tension to resolve, not paper over: skills/sdlc/SKILL.md already treats effort escalation as non-optional on LOW confidence / repeated failure. If lower effort is better for staying on task but worse for hard problems, the answer is a documented switch point, not a new blanket default. SCOPE (c) CLOSED 2026-08-02 — maintainer decision, no trial needed. "skip 487 we already decided we should use high by default even for cross model review with codex." high is now the shipped default for the REVIEWER layer only — the Codex cross-model reviewer, the Fable subagent fallback, and CI's PR reviewer — shipped 2026-08-02 in commit c3c9d02 and guarded by test_codex_reviewer_effort_is_high. The DRIVER default was NOT changed and is still xhigh (AI_SETUP_LANES.md:14, skills/sdlc/SKILL.md:120). An earlier version of this row claimed otherwise; codex review --uncommitted caught it, correctly noting that the cited guard covers reviewer effort only and that no driver guard exists. Open question for the maintainer, deliberately not decided here: he is personally running /effort high as his session default and said medium for straight-CRUD work, but that is his practice, not a shipped recommendation to every consumer. Flipping the shipped driver default is exactly the change scope (a)'s sentiment sweep was supposed to inform, and doing it silently inside a reviewer-effort commit would be the #440 defect again. Decide it explicitly, and if it flips, add a driver-effort guard — there is none today. The evidence that arrived while this row sat open, recorded because it is the only measurement anyone made: across one session, Codex at xhigh returned 1 real P1 plus 2 prose nits; Codex at high returned 3 real P1s and 2 accurate P2s on a larger diff, then found 2 more, then 2 more, every one surviving scrutiny. Wall-clock was effectively identical (455s vs 457s), so the speed half of the cost argument is not supported — but signal quality went UP, not down, which was the actual worry. Neither run was controlled (different diffs, different prompts), so this is not a benchmark; it is enough to stop asking. What REMAINS open in this row: scope (a), the community sentiment sweep on Opus 5 consistency, and scope (b), the documented Opus 4.6 fallback lane with its 200K-vs-1M gotcha. Do not re-litigate effort. FIRST REAL SENTIMENT DATA, gathered 2026-08-02 via browser (Reddit is hard-blocked to WebFetch, as this row predicted). r/ClaudeCode "Opus degradation", 2026-07-31 — an active complaint thread specifically about Opus 5 since launch. Practitioner-reported symptoms: needing ~20 revisions to settle a plan, repeating mistakes already corrected, "walls of text," and one commenter's summary that "Opus has become the new Sonnet." One clarifies the shape usefully: not dumber overall, still capable of the same things — something narrower has changed. Their leading hypothesis is MODEL SWITCHING / routing, not capability, which is a distinct and testable claim this row should not conflate with effort or context. Named mitigations from the thread: revert to Opus 4.8, switch to Fable, or move to GPT-5.6 Sol — the first of which this repo already documents as its escalation backstop. Weight it honestly: a self-selected complaint thread, which over-represents regressions because satisfied users do not post — the exact caveat this row already carries. It is signal that the concern is not the maintainer's alone, not a measurement. Checked and NOT relevant here: a "context rot" search surfaced a post whose demo values the author states are "burned in, not computed" (see GH #483). Context-size degradation and this sentiment question are separate; do not merge them. Scope (b) — write the fallback lane into AI_SETUP_LANES.md with concrete switch criteria. This is a documented manual move, not automation: the maintainer selects the 1M-context Opus 4.6 from the model picker himself. Nothing auto-switches, and nothing should — the row exists so a consumer hitting the same wall has a written procedure instead of improvising. LOAD-BEARING GOTCHA, verify FIRST — the naive version of this plan does not work. Pinning the model id claude-opus-4-6 yields a 200K context window, not 1M; 1M on Max comes from leaving /model at its default. So 'fall back to Opus 4.6 for the 1M context' as usually stated is self-defeating — it trades an inconsistency problem for a 5x context cut. Establish the actual mechanism that produces 1M-with-4.6 (if one exists) BEFORE writing any recommendation, and if none exists, say so plainly and make the trade explicit in the lane. See SDLC.md and the model-pin note in the repo's own setup guidance. Prior art, do not redo it: v1.80.0 already flipped the default 4.8 -> 4.6 max (2026-06-09) and recorded reversion criteria in the CHANGELOG — read those criteria first; this row may be re-deriving a decision already made once. Related: row #440 (the wizard's unbacked '~5x less quota' claim for Sonnet 5) is the same defect class — a model recommendation shipped without evidence — and both should be fixed against real data in one pass. Additional lead for scope (c), supplied by the maintainer 2026-07-31 — weigh it as a lead, not a finding: r/ClaudeCode — "Run Opus 5 in low effort" (u/biohackeddad, 2026-07-31, marked Solved, 7 upvotes / 2 comments — one anonymous practitioner, not a sample). The claimed recipe: Fable at low for agreeable advisor plans, which then spawns a Fable medium to write the full plans as .md files for agents; Opus 5 executes at low or medium depending on use case; Codex review at low/medium when the review is finely scoped. Their stated causal claim is the part worth testing: "codex and fable at high effort decided to refine my product to do something totally different than the vision and built a ton of scope creep." That is the same failure the maintainer described independently ("you tend to go off the rails"), reported by someone with no knowledge of this repo — which raises it above a hunch, but two anecdotes agreeing is still two anecdotes. Note it also proposes lowering effort for the REVIEWERS (Fable and Codex), which scope (c) as written does not cover — the wizard mandated Codex xhigh for every cross-model review and pinned Fable-as-subagent at xhigh when this row was filed (2026-07-31); BOTH moved to high on 2026-08-01, so this row predates the change and the reviewer-effort half of it is already answered. If the trial covers reviewer effort too, that is a second experiment with a different risk profile (a cheaper driver wastes tokens; a cheaper reviewer misses defects), and it must be measured separately, not bundled. Do NOT use /deep-research for this: GH #423 records a 2.5M-token burn (23x median session) on the last such sweep. Targeted browser use plus WebFetch. Entry gate: maintainer decision, plus a shipped default resting on <1 week of evidence.
493Audit the shipped guidance against Anthropic's official "Prompting Claude Opus 5" guide — several of our rules are the exact anti-patterns it namesMaintainer research item, 2026-07-31 — RESEARCH ONLY, do not act on it in the same pass that reads it. Anthropic published a model-specific prompting guide for Opus 5 (/docs/en/build-with-claude/prompt-engineering/…, plus whats-new-opus-5 and the 4.8→5 migration guide). Opus 5 is this repo's Setup A default driver as of v1.88.0 (#468), so the guide describes the model our shipped prose is actually steering. Four places where the guide contradicts what we ship — verified against the current files, with line anchors, not paraphrased from the guide's summary. (1) "If your prompt contains explicit verification instructions … remove them: instructions like these cause over-verification on Claude Opus 5, and removing them reduces wasted tokens with no loss in quality." skills/sdlc/SKILL.md:75 makes self_review — "Read back files/diffs you modified" — a critical rubric criterion whose omission is a process failure regardless of score, and :126 builds a whole Self-Review Loop around it. (2) "do not use subagents to verify or double-check your own work." The entire Cross-Model Review protocol (:135:150) is subagent verification of the agent's own work. This one is a genuine tension, not a straight deletion, and the row must not resolve it by deferring to the guide. The guide's advice targets same-model self-checking, where Opus 5 already self-corrects well; our protocol exists because same-model self-review is precisely what failed — nine assertions passed against broken code in one session (#490), none caught by reading. Adversarial cross-model diversity is a different mechanism from redundant self-verification, and the evidence for keeping it is local and measured. Decide this on our own data. (3) "If your review prompt says 'only report high-severity issues' or 'be conservative,' the model may follow that instruction literally and report less; ask it to report everything and filter in a separate pass instead." Our recheck prompt at :145 says "Do NOT expand the surface; any new P0/P1/P2 BLOCKS" — same shape, and it is aimed at Codex today but the wizard ships it to consumers who may point it at Opus 5. (4) "Avoid instructing re-checks it already performs ('double-check your answer', 're-verify before responding')." Worth a sweep of CLAUDE_CODE_SDLC_WIZARD.md for the same shape. Also relevant and not yet reflected anywhere in our docs: the guide states Opus 5's default responses and its written files both run longer than prior Opus models', and gives concrete conciseness snippets — which bears directly on the maintainer's standing "hard to read ur output" feedback and on #471's bloat audit; it recommends low/medium as the primary cost control and explicitly says to re-run an effort sweep on your own evals if you carried defaults over from a prior model, which is the same experiment as #487 scope (c) arriving from an official source rather than Reddit; it gives a scope-control snippet ("Deliver what was asked, at the scope intended…") aimed at exactly the scope-creep failure #487 is trying to measure; and it warns Opus 5 delegates to subagents more readily than prior models, with a snippet capping delegation — relevant given how freely this repo spawns Fable subagents. Scope. (a) Read the primary sources directly — the prompting guide, whats-new-opus-5, the migration guide, and the Effort page's Opus 5 recommendations — do not work from this row's summary. (b) For each of the four contradictions, decide keep, cut, or reword, with the reason recorded; a documented "we keep this and here is why the guide's advice does not apply to a cross-model gate" is a valid outcome and is expected for (2). (c) Check skills/sdlc/SKILL.md's 20,000-byte ceiling before proposing additions — the file was 19,977 bytes when this row was written and moves with almost every edit — re-measure rather than trusting this number, so anything added must be paid for by a trim. (d) Fold the effort findings into #487 rather than running a second competing trial. Do not treat vendor guidance as automatically outranking measured local evidence — that inversion is the #440 defect wearing a better badge. Related: #487 (Opus 5 sentiment + effort trial), #471 (bloat audit), #490 (testing contract), #476 (context-engineering reversals). EXPANDED 2026-08-01 — the row now covers THREE guides, not one, and the Fable one is the most urgent. Primary sources, read all three: Prompting Claude Opus 5; Claude prompting best practices; and Prompting Claude Fable 5 — which we have never read at all, despite Fable being this repo's primary reviewer AND its advisor. Every review prompt we ship (skills/sdlc/SKILL.md's cross-model protocol, the Fable-subagent fallback, the .reviews/handoff.json contract) was written without reference to it. That is the same defect as the Opus 5 half: model-specific guidance exists and our prompts predate it. Maintainer method, worth adopting verbatim (r/ClaudeAI, u/Barnabas_Stinson17, 2026-07-30, "Opus 5 reboot"): feed each prompt from the guide to the model as "This prompt is the new source of truth. (paste). Please identify any contradictions that exist compared to this prompt", then delete the old instructions that contradict. That is a concrete, cheap, auditable procedure and it is a better fit for this repo than a from-scratch audit. Snapshot first (u/jake_that_dude, same thread): copy CLAUDE.md to a dated file before deleting anything, so a regression produces a real diff instead of a memory. Second dated lead (r/ClaudeAI, u/Due-Cup9574, 2026-07-28, "A week on Opus 5"): names three defaults to change — thinking is on by default so watch token spend; do not reach for max ("lower levels often match it while being faster and cheaper", echoed by another commenter claiming max has less reasoning ability than xhigh); and drop "verify your answer" prompts because the model self-verifies and the nudge makes it overthink. Same post also reports the failure mode this repo has hit repeatedly: "more confident when it's wrong … it over-engineers, expands the scope you gave it, and once in a while stops before it's actually done." Two further comment-level claims to verify, not assume: that Opus 5's core system prompt discourages subagent delegation and can override a consumer's CLAUDE.md delegation rules (u/Grab_Formal) — which would directly affect our Fable-subagent pattern; and that ambiguity between docs is resolved arbitrarily by the model rather than by precedence, so two of our files disagreeing is worse than one being wrong (u/LesbianVelociraptor). Weight all of these as leads: anonymous practitioners, low vote counts, one thread where commenters openly disputed the premise. PRACTITIONER REPORT WITH A METHOD AND A MECHANISM, 2026-08-02 (r/ClaudeCode, 'Reworking CLAUDE.md for Opus 5'). Adds three things this row did not have. (a) A stated mechanism, not just a symptom: the author's Opus 5 audit of his own instruction file reported that "the file's biggest cost driver is that it instructs Opus 5 to do things it already does — and Opus 5 compounds those instructions rather than ignoring them." Compounding, not ignoring, is the specific claim to test — it predicts that redundant instructions cost MORE than they would on 4.x, which would make our own verification-heavy prose actively expensive rather than merely inert. (b) A subagent-delegation cap was among the recommendations. Directly relevant: this repo spawns Fable and Codex subagents constantly, and the shipped guidance encourages it. (c) THE FINDING WITH THE LARGEST BLAST RADIUS FOR US — guidance has DIVERGED between Opus 5 and other models. The author's audit flagged instructions that were redundant for Opus 5 but that Copilot/other models still need, and concluded shared instruction files now need splitting per model. We ship ONE skills/sdlc/SKILL.md and one wizard doc to consumers running Opus 5, Sonnet 5, Opus 4.8 and Opus 4.6. If Opus-5-optimal guidance genuinely differs from Sonnet-optimal, a single shipped file cannot be right for everyone, and this audit's output may not be a rewrite but a split. That question is not currently in scope here and should be. Weight it as one practitioner's anecdote: self-reported, uncontrolled, and his own verdict is "the verdict is still out." His speed observation (12 minutes for the first audit run, 49 seconds for the second after cleanup) is a before/after on different prompts, not a benchmark. CRITICAL COUNTER-EVIDENCE FROM THIS REPO, recorded 2026-08-01 — do not let the "drop verification" advice be applied to cross-model review. In a single session: self-review reported 64/64 green; Codex then found 3 real P1s. After fixing, self-review reported green again; a fresh Fable found 2 more P1s including a live regression in a shipped npm file. After fixing again, Codex found 2 more P1s. Every round, self-verification said clean and an independent model found real defects. The guides' advice targets same-model self-checking, where Opus 5 genuinely does self-correct well. It is not evidence against adversarial cross-model review, and conflating the two would delete the only thing that has actually been catching defects here. The audit must state that distinction explicitly or it will do damage. Entry gate: official vendor guidance that directly contradicts shipped rules, on the model we ship as the default driver — now plus a second guide for the model we ship as the default reviewer.
494Fable 5 reported as standard on Max with a 50%-of-weekly quota split — plus Dispatch, Design/Labs, and a visible effort picker in the desktop appObserved by the maintainer in the Claude desktop app, 2026-07-31. RESEARCH ONLY — filed, not acted on. In-app notice, quoted: "Fable 5 is now a standard part of your Max plan. You can use up to 50% of your weekly usage limit on Fable 5. If you hit your limit you can continue on Fable 5 with usage credits." Why this matters to us specifically: this repo's workflow leans on Fable as primary reviewer/advisor and pinned Fable-as-subagent at xhigh when this row was filed (2026-07-31); that pin moved to high on 2026-08-01, and we have never written down what that costs. A 50%-of-weekly ceiling — as reported by that notice, not yet confirmed against Anthropic's plan documentation — would turn reviewer effort from a free knob into a budgeted one, and it lands on the same question #487 and #493 are already circling from the quality side — those ask whether lower effort is better; this asks what the budget actually is. Settle both together, not separately. Also visible in the same screenshot, none of it reflected in our docs: a Cowork toggle sitting next to Chat in the desktop composer — directly relevant to the not-yet-run Cowork Desktop E2E install (Half 2), since it suggests Cowork is a first-class mode rather than something a plugin has to bootstrap; a per-message effort picker ("Fable 5 · High") exposed in the app UI, which means consumers can now set effort without touching /effort or settings, and our guidance assumes they can't; Dispatch (Beta) and Design (Labs) as new sidebar surfaces we know nothing about. Scope. (a) Confirm the quota terms from Anthropic's own plan/usage documentation rather than the in-app toast — a promo tooltip is not a spec, and "usage credits" is undefined here. (b) Work out what the 50% split means for a session that runs Opus 5 as driver plus repeated Fable review rounds, since those draw on the same weekly pool; if reviewer rounds are the expensive part, that is an argument #487's effort trial should be measuring. (c) Look at whether the desktop Cowork toggle changes the install path documented in CLAUDE_CODE_SDLC_WIZARD.md, which was corrected in v1.90.0 and assumes the repo-as-marketplace flow. (d) Find out what Dispatch and Design are before assuming they are relevant — they may be nothing to do with us. Do not change any model or effort recommendation off this row alone — it is an observation from one screenshot; #440 is the standing reminder of what shipping a recommendation on that basis costs. Related: #487, #493, and Half 2 of the current release work. Entry gate: maintainer observation of a platform change that alters the cost model of a workflow we ship.
495End the denylist arms race in the reviewer-effort guard, and fix a shipped timeout claim with no implementation behind itTwo follow-ups deferred out of the 2026-08-01 effort-migration branch on the reviewers' own severity calls — neither blocked that merge, both are real. (a) The arms race, diagnosed by Fable round 3. test_codex_reviewer_effort_is_high's Leg B is a denylist of prose that asserts xhigh as the reviewer default. It grew from 3 alternations to 6 across three review rounds, each addition made after a reviewer named a phrasing it missed — "non-negotiable", then "standard:", and Fable's round-3 sweep still slipped eight more it constructed on the spot ("requires", "pinned at", "non-optional", "the reviewer floor is", "policy: xhigh on every review", "must be", plus bare imperatives). The synonym space is unbounded, so the denylist will always be one word behind. Fable's structural fix, and the reason this is worth doing rather than abandoning: the repo already contains the right mechanism — _check_content_line_has_and_lacks (tests/test-doc-consistency.sh:1487ff, used for the GPT-5.6 model-name check). Point it at the three lines that actually DEFINE the default — the wizard doc's effort-table reviewer row, AI_SETUP_LANES.md's Final Review Policy, and README's reviewer-effort line — asserting each says high and lacks a non-escalation xhigh. That converts an unwinnable question ("no bad phrasing anywhere in the repo") into a winnable one ("the defining lines say the right thing"). Keep Leg A (every model_reasoning_effort= must be high) as the executable truth and Leg B as a cheap tripwire. Why it did not block: a prose regression that dodges Leg B still cannot change what any invocation actually runs at without tripping Leg A. (b) A shipped operational claim with nothing behind it. skills/sdlc/SKILL.md and CLAUDE_CODE_SDLC_WIZARD.md both tell readers that the codex wrapper's STALL_SECONDS=1800 watchdog is the authority controlling review timeouts, and reference scripts/codex-review.sh. Neither the script nor the variable exists anywhere in the repo — grep across scripts/, hooks/, and cli/ is empty. The wrapper that does exist, scripts/codex-review-with-progress.sh, has no stall watchdog at all. This predates the effort branch, which is why it was kept out of scope, but Fable's assessment is that it is now more load-bearing rather than less: the shipped timeout story names a mechanism that was never built, so a consumer hitting a hung review has no actual protection and no way to tune one. Scope: either implement the watchdog in the real wrapper or delete the claim and document the actual behaviour — do not paper over it by renaming. Also fold in (P4/P5 residue from the same rounds): _hist's unescaped dots in the guard's exclusion pattern; a one-line comment naming Leg A's structural limit (it globs md/sh/json/yml/yaml, so a future .py/.ts/extensionless reviewer invocation would be invisible — that set is empty today, verified); a fenced code block indented 4+ spaces inside a list item produces fail-loud false positives in the ordered-list rule; and ROADMAP #483's as-filed present-tense xhigh sentence needs the same dating #487 got. Entry gate: two independent reviewers converged on (a) across three rounds, and (b) is a documented mechanism that does not exist.
496We may be invoking Codex the wrong way entirely — codex review exists and we hand-rolled a substituteMaintainer question, 2026-08-02: "are we using codex review --uncommitted to do a codex review? we should definitely research if this is the right way to do it because maybe we are doing it all wrong." We are not, and the alternative is real. codex review --help confirms a first-class subcommand — "Run a code review non-interactively" — with --uncommitted ("Review staged, unstaged, and untracked changes") and --base <BRANCH>. This repo instead drives codex exec with a bespoke .reviews/handoff.json protocol, a preflight document, a per-finding response.json, and a hand-managed round counter. That machinery may be reinventing, badly, something the vendor ships. Measured evidence, such as it is: the 2026-08-01/02 session ran five codex exec reviews at 455s, 457s, 287s and two more, with 46, 18 and 14 tool calls respectively — wall-clock tracked how much verification the prompt requested, not diff size, because codex exec must discover the diff agentically. A first attempt to time codex review --base main on the same branch was botched and proves nothing: it ran in the foreground and hit the Bash tool's 10-minute cap, which is the precise failure skills/sdlc/SKILL.md already warns about (run_in_background: true). Redo it properly before concluding anything. What the research must actually answer, because "use the native command" is not automatically right: (a) does codex review accept the mission-first framing that makes our reviews productive — the handoff's mission/success/failure keys exist specifically because a bare "review this" returns "looks good", which this repo has documented as its own anti-pattern; (b) can it do the multi-round dialogue (PENDING_RECHECK, per-finding FIXED/DISPUTED/ACCEPTED) that produced 12 real defects across 5 rounds in one session, or is it single-shot; (c) does it support model_reasoning_effort and -o <file>; (d) is it faster, measured in background, on the same diff; (e) can the codex-gate-check.sh hook still verify a certification, which currently keys on handoff.json's status + commit_sha. The honest possibility to hold open: the answer may be a hybrid — codex review for cheap single-pass checks, the handoff protocol only for release gates — or the native command may simply be better and the protocol should be deleted. Do not migrate on a hunch in either direction; #440 is this repo's standing lesson about shipping a recommendation with no measurement. Related: #495 (the reviewer-effort guard), and CI_CD.md plus scripts/codex-review-with-progress.sh both encode the codex exec shape and would need updating. FIRST EXPERIMENT RUN 2026-08-02 — codex review is real, faster, and found a defect on its first attempt. Measured, not guessed: codex review --uncommitted took 320s against 455s/457s for the codex exec + handoff-protocol runs earlier the same session (~30% faster), and it required zero setup — no handoff.json, no preflight, no response.json, no round counter. It found a genuine P2 that four rounds of the hand-rolled protocol had not: a ROADMAP row claiming high had become the Opus 5 DRIVER default when commit c3c9d02 changed only the reviewer layer, correctly observing that the cited guard covers reviewer effort alone and that no driver guard exists. That claim was mine, written minutes earlier — so the native command caught a live falsehood in the very diff it was handed. What it does NOT do, and this is the whole decision: it is single-shot. There is no PENDING_RECHECK, no per-finding FIXED/DISPUTED/ACCEPTED dialogue, and no way to say 'verify this certify condition holds'. The five-round loop that produced 12 real defects this session — including the discovery that a guard was reading nothing at all — depended on exactly that dialogue. It also emits inline file:line comments rather than a verdict line, so codex-gate-check.sh (which keys on handoff.json's status + commit_sha) cannot consume it as-is. Provisional recommendation, to be confirmed not assumed: a HYBRID. Use codex review --uncommitted as the cheap default pass on every change — it is fast, zero-ceremony, and demonstrably catches real defects. Keep the handoff protocol for release gates and anything needing multi-round dialogue or a machine-readable certification. That would cut most reviews from ~8 minutes and a JSON scaffold to one command, while preserving the mechanism that actually converges hard cases. ANSWERED AUTHORITATIVELY 2026-08-02 — asked Codex itself, which verified against installed codex-cli 0.146.0, codex review --help, its own Rust source, and OpenAI docs, with citations. (1) The PROMPT conflict is INTENTIONAL: --uncommitted, --base, --commit and [PROMPT] are mutually exclusive by design. A bare codex review "<prompt>" selects ReviewTarget::Custom — it inspected working-tree diffs and untracked files in practice, but the scope is NOT guaranteed, so it is not a substitute for --uncommitted. (2) There IS a supported context mechanism, and it is the actionable finding: AGENTS.md. Codex automatically loads applicable root and nested AGENTS.md files for reviews, and a ## Code Review Rules section is the documented place for durable review standards (it may also reference a checked-in code_review.md). This repo has an AGENTS.md with Review Focus Areas, Review Exceptions, Severity and Meta-Repo Awareness sections — but no ## Code Review Rules heading, so none of it is being picked up by that mechanism. A per-run mission is still impossible; durable standards are not. That distinction was missed in the first pass here. (3) -c model_reasoning_effort="high" DOES take effect — the review runtime clones the config and passes it into the review turn (verified in codex-rs/core/src/session/review.rs), so it is not ignored. (4) Single-shot, confirmed: one non-interactive review then exit. No follow-up, no dispute response, no steering round. Multi-round requires re-invocation with no memory of the prior round. (5) NOT usable as a gate, confirmed: --json, --output-schema and output-file options are all rejected; the CLI converts internal JSON to human-readable text. Exit codes are 0 = review completed EVEN IF FINDINGS EXIST, 1 = runtime failure, 2 = usage error. There is no findings-specific code and no verdict line, so codex-gate-check.sh cannot gate on it. codex exec retains the machine-readable/output-schema controls that review lacks. (6) Codex's own recommendation: SUPPLEMENT, not replacement — keep the codex exec handoff protocol for per-run mission/success/failure, exact diff scope plus custom instructions, multi-round recheck, and machine-readable gating; add codex review --uncommitted/--base as an independent cheap reviewer driven by durable AGENTS.md rules. That matches the hybrid this row provisionally proposed, now on evidence rather than inference. CONCRETE NEXT ACTION, small and high-value: add a ## Code Review Rules section to AGENTS.md distilling the existing Review Focus Areas / Severity / Meta-Repo Awareness content into rules Codex will actually load. That makes the 320s zero-ceremony pass materially better at no ongoing cost, and it is the only part of this row that is not blocked on a design decision. Still to check before adopting: whether -c model_reasoning_effort applies to codex review (the flag is accepted, effect unverified), whether a custom PROMPT argument can carry the mission-first framing without the --base conflict observed here (--base and [PROMPT] are mutually exclusive), and whether the gate hook should learn to accept its output. Entry gate: maintainer question, plus a vendor-provided command we demonstrably never evaluated.
488Revisit the test-verification rule — the maintainer is not soldMaintainer decision 2026-07-29, deliberately deferred. Mutation testing was never doctrine here: it was an agent habit from ~2026-07-22 that leaked into CHANGELOG prose, while the only shipped mention (CLAUDE_CODE_SDLC_WIZARD.md) was a caveat about its limits. Fable, asked to argue either side, recommended cutting the term entirely — hand-rolled sed mutant harnesses are not the automated technique the industry means (PIT/Stryker/mutmut), and ROADMAP #482 records three false mutation results in a single day from exactly that approach. Done already: term removed; replaced with one rule — no test counts as verified until you have watched it fail, per-assertion when written and again whenever you touch the test or what it guards; and the root gap closed (shipped TDD guidance said "write failing test FIRST" with no per-assertion language). Still open: the maintainer remains unconvinced the surviving rule earns its place. Scope: re-examine after a few releases of living with it — has it caught anything a plain per-assertion RED would not have? If not, cut the second half of the rule too. Entry gate: maintainer decision, explicitly deferred, not a new proposal.
489Pay down the 68 pre-existing shellcheck warnings across 31 shell filesFound 2026-07-29 when the shellcheck CI gate was added (#485 branch). The gate is a deliberate RATCHET — repo-wide at ERROR severity (now zero, after one SC1122 false positive was cleared by renaming a heredoc delimiter whose first content line began with the delimiter word) and WARNING severity on files a PR changes. Pre-existing warnings are NOT gated, so this backlog is invisible to CI by design. Scale: 68 warnings / 31 files / 120 tracked .sh. By frequency: SC2034 unused var (17), SC2179 += on a string (9), SC2164 unchecked cd (9), SC1078 unterminated quote (7), SC2155 declare-and-assign masking a return value (6), SC1090 non-constant source (6), then a long tail. Triage before fixing — these are not equal. SC2164 (a cd that can silently fail, leaving the rest of the script running in the wrong directory) is the same failure class as the test-persist-score-history.sh incident that corrupted the real repo when its tmpdir creation failed, so treat those 9 as real bugs. SC2034/SC2155 are mostly cosmetic. Do not fix all 68 in one PR: fix by severity class, one class per PR, so a regression is attributable. Do NOT bundle into a safety-relevant PR — a 31-file whitespace-adjacent diff on top of a merge-gate change is exactly the reviewability problem this repo has post-mortemed before. Definition of done: repo-wide clean at -S warning, then tighten the CI gate from changed-files-only to repo-wide and delete this row. Entry gate: measured defect count from a tool run, not a judgement call.
492Land the shellcheck CI gate, properly guarded — pulled from v1.90.0 after four rounds of guard defectsDecision 2026-07-30, both cross-model reviewers independently recommending PULL. The gate was built during the v1.90.0 cycle: repo-wide at ERROR severity, changed files at WARNING, a ratchet leaving the 68-warning backlog (#489) ungated. It is repo-local — .github/ is absent from package.json's files — so nothing reached a consumer. Why it was pulled. Across four review rounds, every finding concerned the gate or its guards rather than any shipped artifact, while the release itself sat ready. Real defects found in it: filenames were word-split into shellcheck argv with no --, so a file named -S error <path> was read as OPTIONS and the real file skipped (shellcheck exited 0 — a bypass of BOTH legs, demonstrated); the base resolution used HEAD~1 and so saw only the last commit of a multi-commit push; and the base could resolve to HEAD, yielding an empty check indistinguishable from "nothing changed". The root cause is a process failure, not difficulty, and it is the reason this row exists rather than a quick fix: the guards were written and never executed before being treated as done. They were pinned to the command's textual SHAPE and to variable declaration ORDER, so changing the command mechanically invalidated them, and one set referenced a variable defined further down the file. Every one of those would have been caught by a single RED run. The work is preserved, not discarded — a 362-line patch is saved and the final state had all seven known regressions caught. Scope: re-apply it on its own branch; make the guards assert BEHAVIOUR (execute the step, check exit codes) rather than command text; and RED-run every guard before review. Principle worth keeping, from Fable: an unverified gate is worse than no gate, because its failure mode is a false green. Entry gate: maintainer decision, on unanimous independent cross-model recommendation.
491Settle what "mutant" and "mutation testing" actually mean here — is it an extension of TDD or a different thing?Maintainer question, 2026-07-30, asked three times and never answered clearly. "I want to know what that means exactly — is mutation just an extension of TDD?" The agent kept using the term after agreeing to drop it, and never gave a definition the maintainer accepted. That is the defect: a term used constantly in review output that the repo owner cannot define is unusable vocabulary, whatever its technical merit. The unresolved question, stated fairly. TDD's RED step and a "mutant" are arguably the same move from opposite ends: RED removes the IMPLEMENTATION and checks the test fails; a mutant BREAKS the implementation and checks the test fails. If they are the same idea, the repo needs ONE name and one rule, not two vocabularies. If they differ, the difference must be stateable in a sentence — the current guidance implies they differ without saying how. Evidence both ways, from one session (2026-07-29/30). FOR: nine assertions were found passing against broken code, every one by breaking something and re-running, none by reading — including a probe whose own fixture ran past a step boundary and exited 127, so it "failed" no matter what. AGAINST: ROADMAP #482 records hand-rolled harnesses producing three FALSE results in a single day; industry mutation testing (PIT, Stryker, mutmut) is automated and diff-scoped, which a sed-improvising agent is not; and #488 records Fable's recommendation to cut the term entirely, which was accepted and then not followed. Scope. (a) Define both terms in one place, in the maintainer's words, or delete one. (b) Decide whether the surviving rule is "watch each new assertion fail" (TDD, free) or something more, and if more, state exactly when it applies with a syntactic trigger — not a judgement call. (c) Reconcile with #488, which already tried to settle this and evidently did not. (d) Check the shipped guidance actually matches whatever is decided; the term was removed from all shipped surfaces on 2026-07-30 but the PRACTICE continued in review prompts. Do not answer this from first principles. The maintainer has rejected the reasoning twice; a third restatement is not the deliverable. Bring an outside definition (industry sources, not the agent's own framing) and a concrete before/after from this repo's own history. Entry gate: maintainer question, unresolved across three attempts, blocking their ability to review the agent's own output.
490Solidify the testing contract — the Testing Diamond is stated but unmeasured, and grep-shaped tests keep passing against broken codeMaintainer pain event, 2026-07-29/30 — the strongest evidence class in this file. Across one review of the merge gate, six separate assertions were found to pass against broken code. Every one was found by execution; none by reading. They were not a single mistake repeated: (1) two assertions green from birth, because RED was observed at SUITE level and nobody checked the individual assertion; (2) a rule with no test at all; (3) a fixture invalid in three unrelated ways, so it was refused by a gate long before reaching the behaviour it named — patched twice, still ineffective, fixed only by rewriting it born red; (4) env VAR=x run_wrapper where env cannot exec a shell function, so exit 127 read as "blocked"; (5) a stub predating a rewrite, so both reads returned empty and it blocked as "unreadable" while claiming to test a comparison — and it grepped a substring present in BOTH messages; (6) a CI probe whose extraction ran past the step boundary into the next step header, exiting 127 regardless of the mutant. The common shape: asserting on TEXT rather than executing the thing. A test that greps a script for words proves the words are present. Scope, in order. (a) Census first — do not trust the numbers in this row. Two attempts at classifying the 64 tests/test-*.sh suites disagreed, and 39 fell through both heuristics, so the distribution is genuinely unknown. What IS verified: 26 suites create temp dirs or stub a binary (integration-shaped), 8 E2E suites exist, and at least 15 assert only on source text. Produce a real per-suite classification and record the method so it can be re-run. (b) Compare against the Diamond now stated in TESTING.md (~90/5/5) and decide, per suite, whether it is misclassified or correctly a unit test of pure I->O — semver parsing and JSON extraction legitimately belong in the 5%. (c) Convert grep-shaped tests that guard BEHAVIOUR into execute-and-check-exit-code. Prioritise anything guarding a hook, a gate, or CI enforcement — those are where a false green is dangerous. (d) Consider a cheap standing guard so this cannot silently regress. Also fold in (found 2026-07-30): the four sibling assertions in tests/test-stop-hook-terminates.sh are POLARITY-BLIND — proven by execution, not read: moving the failing-tests exemption to the BLOCK side and inverting it to "failing tests are a violation" left the suite 9/9 green. They check that words appear in the Stop prompt, not which side of the block/allow line the words sit on. The in-flight assertion added in v1.90.0 was fixed the same way (scope the grep to the DO-NOT-BLOCK region); these four predate it and were deliberately left alone rather than silently widening a release's scope. Same defect class as the census above: asserting on TEXT rather than on BEHAVIOUR. LIVE VERIFICATION OF v1.90.0'S HEADLINE FIX ARRIVED BY ACCIDENT 2026-08-02, AND IT FAILED. tests/test-stop-hook-terminates.sh:161 passes with the caveat written into its own message: "presence only; semantics require live E2E verification, not yet run." That verification has now happened, unplanned, three times in one session — and the result is that the exemption text is present in the shipped prompt and the evaluator does not honour it. The three blocks, all against this repo's own Stop hook: (1) blocked a READ-ONLY turn, asserting code had changed when the turn ran only greps; (2) blocked a turn for not verifying work that a DIFFERENT, earlier turn had already verified with a stated 64/64 suite run — despite the prompt's explicit "judge THIS TURN ONLY" and "a response that summarizes work done earlier is NOT evidence this turn changed code"; (3) blocked a turn whose only action was delegating to a background subagent, with a reason that itself read "This is in-flight work, not unverified work, so the turn should continue" — correctly classifying the case as exempt and then blocking on it anyway. The distinction that matters for the fix: v1.90.0 changed the PROMPT, and the prompt is right. Case (3) proves a correct prompt is not sufficient — the Haiku evaluator reached the right classification and emitted the wrong decision. So the shipped fix addressed the observable half of #477 (the text) and left the actual failure mode (evaluator judgement) untouched, which is precisely what the test's own caveat warned could be true. Consequence for this row: a presence-only assertion cannot distinguish a working gate from a broken one, and this is now demonstrated rather than argued. Any replacement must execute the evaluator against fixtures and assert the DECISION, not grep the prompt for words. Do not 'fix' this by softening the prompt further — three rounds of prompt-softening produced a prompt that is already correct and still ignored. Definition of done: a reproducible census committed to the repo, every behaviour-guarding test executing rather than grepping, and no known assertion that passes against broken code. Do NOT bundle into an unrelated PR — this touches many test files and must be reviewable on its own. Related: TESTING.md now carries the Diamond and the RED->GREEN rule (added 2026-07-30); #482 records mutation harnesses producing false results; #489 is the shellcheck backlog, same ratchet philosophy. Entry gate: maintainer pain event, six documented instances in a single session.
485Move the HARD tier to ACKABLE — the maintainer has asked three times not to be in the loopMaintainer decision 2026-07-27, stated repeatedly and deferred by the agent each time. #479 shipped a two-tier denylist: evidence-chain paths (workflows, hooks/, .claude/, the merge script) require a human; everything else is clearable on dual cross-model evidence. That split came from Codex xhigh (96%) and Fable xhigh (85%), consulted blind, on a call the maintainer had delegated to them. He has since asked three separate times to remove the human anyway"if fable and codex say do it then do it", "why do i keep having to one click this". The agent re-explained the rationale each time instead of implementing the override. That is the defect this row records: a delegated decision was treated as permanent policy rather than one the owner can revoke. Scope: move the four HARD patterns into ACKABLE_DENY so dual clearance at >=95% bound to the head SHA suffices everywhere; keep the unconditional package.json version check, since publishing is a distinct action from merging. Invert group 7 of tests/test-cross-model-clearance.sh (it currently asserts HARD paths are NOT clearable), and update the shipped prose in skills/sdlc/SKILL.md, CLAUDE_CODE_SDLC_WIZARD.md, and the merge-pr.sh header — all three currently argue FOR the boundary being removed. Verify the classifier assumption FIRST — it is load-bearing: --cross-model-cleared is believed to pass Claude Code's auto-mode classifier where MERGE_CLEARANCE_SKIP=1 did not, because it is evidence-gated approval rather than a bypass. If that is wrong this row delivers nothing — the agent still cannot invoke the merge, the human still clicks, and the checks are weaker. VERIFIED 2026-07-27 — this assumption HOLDS. Ran ./scripts/merge-pr.sh 474 --cross-model-cleared live: the auto-mode classifier did NOT block it. The command executed and was stopped only by this repo's own HARD tier rule. Evidence-gated approval reads differently to the classifier than a bypass flag, exactly as designed — so the flip will deliver real agent-merges, not a differently-worded block. Accepted risk, recorded once so it is not re-argued: a PR editing the merge gate can then merge under the gate it just edited — the self-referential loophole #462 was built to close, which both reviewers named independently. Do this FIRST next session. It was deferred only because it is a safety boundary and the request landed at the tail of a long session, which is exactly where this repo's own #480 evidence says judgement degrades. Entry gate: maintainer decision, stated three times.
481A cross-model review agent with write access destroyed uncommitted work via git checkoutMaintainer pain event 2026-07-26, real data loss, recovered only because a scratchpad backup happened to exist. During round 3 of the PR #473 review, the Codex reviewer was told to "restore ROADMAP.md to its committed state after each attack." It complied by running git checkout -- ROADMAP.md — which reverted the file to HEAD, and since the work was uncommitted on a feature branch, that silently discarded the entire In Flight rewrite and row #479. Detected only because the next test run failed with the original three defects. The instruction was mine and it was ambiguous ("committed state" meant "the state before your attack" to me and HEAD to the reviewer), but the deeper fault is structural: scripts/codex-review-with-progress.sh and the documented codex exec invocation both use -s danger-full-access, so every cross-model review in this repo can write to the working tree it is reviewing, and the SDLC skill's review protocol says nothing about committing first. A second, independent instance of the same class: the full test suite was run concurrently with a review round and reported a spurious failure, because the reviewer was mutating ROADMAP.md mid-run. Scope: (a) state plainly in skills/sdlc/SKILL.md's Cross-Model Review section that work MUST be committed before a review round is launched, and that the suite must not run concurrently with one; (b) evaluate running reviewers in a git worktree or a throwaway clone so they physically cannot touch the source tree — Fable did exactly this unprompted on the same PR when asked not to modify files, so the pattern is already proven; (c) consider whether -s danger-full-access is actually required, or whether a read-only sandbox plus an explicit output path would do — the reviewer only needs to read the diff and write one review file. Entry gate: maintainer pain event with real data loss, twice in one session.
482Mutation tests scored two false results because the mutation never appliedMaintainer pain event 2026-07-26, same session, same class as the v1.87 timeout incident. A mutation-test harness deliberately breaks a condition and asserts the corresponding test goes RED. Twice in one session it reported a result that was an artifact of the harness, not the code: once a perl substitution whose escaping was wrong never modified the file at all (scored MISSED, i.e. a phantom hole in a test that was actually fine), and once the expected-failure string was copied from the test's PASS message rather than its FAIL message (also scored MISSED). Both were false alarms in the safe direction, but the identical bug in the other direction — a mutation that silently fails to apply while the harness scores it CAUGHT — would certify a vacuous test as sound, which is exactly what happened with timeout not existing on macOS (two "61 files, 0 failing" reports that ran zero tests). The fix is one line and was applied ad hoc: diff -q the file against its backup after mutating and report MUTATION DID NOT APPLY rather than scoring it. Scope: (a) write that rule into skills/sdlc/SKILL.md's TDD/mutation guidance — a mutation test that does not verify the mutation landed is itself vacuous; (b) check the existing mutation harnesses in tests/ for the same gap, starting with tests/test-merge-gate.sh, which certified 4 mutations using the same hand-rolled pattern; (c) prefer asserting on exit code rather than on a grepped message string, since message text drifts. REFINED 2026-07-26 after a THIRD false result the same day: diff-ing the file after mutating is not sufficient. A sed expression whose delimiter collided with the pattern's own characters mangled the target line instead of replacing it — the file genuinely changed, so the harness scored the mutation as applied, but the code was broken in a different way that produced the same block, hiding the real result. The rule is: assert the exact target string was PRESENT before replacing it, and fail loudly if it was not. Python's assert old in s does this trivially; sed cannot. Prefer an exact-string replacement over a regex for mutation harnesses, for the same reason a test asserts on exit code rather than prose. Entry gate: maintainer pain event, recurrence of a known and previously post-mortemed class.
462Merge-safety gate — real hook enforcement for the conditional auto-merge exceptionFollow-up to the 2026-07-21 conditional-merge-exception policy (skills/sdlc/SKILL.md CI Feedback Loop step 8): two independent reviewers — Codex xhigh and a fresh, diff-only Fable subagent, run in parallel and blind to each other — both concluded the prose-only exception was self-certified with no machine-checkable gate, and specifically that the PR introducing the policy wouldn't have been excluded by its own release/tag-adjacent-only denylist. Shipped: .claude/hooks/merge-gate-check.sh (redirect-only PreToolUse hook, blocks all gh pr merge forms except through the wrapper, unconditionally blocks --auto) + scripts/merge-pr.sh (the real verification — CI validate status for the PR's remote head SHA, a concrete denylist scan including the wrapper/hook themselves, net test-deletion check, a per-PR SHA-bound clearance artifact requiring round >= 2, and an atomic --match-head-commit merge closing the TOCTOU race between checking and merging). Both files are repo-local only — not in hooks/hooks.json, don't ship to consumer repos, per Fable's explicit design guidance that this mechanism is hardcoded to this repo's own Codex/Fable/.reviews/ contribution stack. CLAUDE_CODE_SDLC_WIZARD.md gets the portable policy prose instead (new "Explicit Merge Confirmation" section) so every repo's agent reasons the same way, with an explicit honesty line that the mechanical enforcement itself doesn't ship. What's mechanically proven vs. still trust-based (stated plainly in the wrapper's own header comment, not oversold): hard-verified — CI status, denylist/self-reference, SHA freshness, artifact existence. Structurally-proxied only — "Codex ran a genuine adversarial dialogue" and "Fable was truly fresh/diff-only" can never be confirmed by a local script; round >= 2 plus a non-empty review file is the best available proxy that review wasn't skipped or stale, not proof it wasn't faked. A local hook is not a security boundary against a determined agent willing to forge the artifact — see the Research Parking Lot's "Server-side required-check enforcement" row for the real fix. Verified: 27 new tests in tests/test-merge-gate.sh (RED confirmed before implementation existed, GREEN after), 4 targeted mutations against the wrapper (accepting neutral as green, dropping the round>=2 check, removing the self-referential denylist entry, dropping --match-head-commit) each caught by exactly the intended test and no other, full regression sweep green. The 4 pre-existing vacuous keyword-only tests in tests/test-self-update.sh's CI Shepherd Enforcement block (Codex's finding #3 on the original policy PR) were tightened with negative-control fixtures proving the checks actually discriminate, not just detect keyword presence anywhere. Review trail: .reviews/preflight-conditional-auto-merge-policy.md, .reviews/handoff.json (original policy PR) plus a fresh round for this hook-enforcement PR.

67 fully-resolved rows archived → ROADMAP_ARCHIVE.md, including #231 (shepherd migration, the single largest row in the pre-cut file).