From e5b8a65cf3cc622b6cae36ec2af58d24f6056094 Mon Sep 17 00:00:00 2001 From: garrytan Date: Sat, 10 Oct 2026 16:40:21 +0000 Subject: [PATCH] feat(honesty): claims-need-evidence kernel, no_claim card field, CEO value test, implementer dispatch rules, ACCEPTANCE_EDITED, Honest Work ethos Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- AGENTS.md | 4 +- ETHOS.md | 26 +++++ README.md | 4 +- SKILL.md | 2 +- autoplan/SKILL.md | 10 +- benchmark-models/SKILL.md | 2 +- benchmark/SKILL.md | 2 +- browse/SKILL.md | 2 +- canary/SKILL.md | 10 +- codex/SKILL.md | 10 +- context-restore/SKILL.md | 10 +- context-save/SKILL.md | 10 +- design-consultation/SKILL.md | 10 +- design-html/SKILL.md | 10 +- design-review/SKILL.md | 10 +- design-shotgun/SKILL.md | 10 +- devex-review/SKILL.md | 10 +- diagram/SKILL.md | 2 +- document-generate/SKILL.md | 10 +- document-release/SKILL.md | 10 +- health/SKILL.md | 10 +- investigate/SKILL.md | 10 +- ios-clean/SKILL.md | 10 +- ios-design-review/SKILL.md | 10 +- ios-fix/SKILL.md | 10 +- ios-qa/SKILL.md | 10 +- ios-sync/SKILL.md | 10 +- land-and-deploy/SKILL.md | 10 +- landing-report/SKILL.md | 10 +- learn/SKILL.md | 10 +- make-pdf/SKILL.md | 2 +- office-hours/SKILL.md | 10 +- open-gstack-browser/SKILL.md | 2 +- pair-agent/SKILL.md | 10 +- plan-ceo-review/SKILL.md | 10 +- plan-ceo-review/sections/review-sections.md | 3 +- .../sections/review-sections.md.tmpl | 3 +- plan-design-review/SKILL.md | 10 +- plan-devex-review/SKILL.md | 10 +- plan-eng-review/SKILL.md | 10 +- plan-eng-review/sections/review-sections.md | 6 +- plan-tune/SKILL.md | 10 +- qa-only/SKILL.md | 14 ++- qa/SKILL.md | 14 ++- retro/SKILL.md | 10 +- review/SKILL.md | 10 +- review/specialists/testing.md | 3 +- scrape/SKILL.md | 2 +- scripts/resolvers/dispatch-rules.ts | 28 +++++ scripts/resolvers/index.ts | 2 + scripts/resolvers/plan-gates.ts | 72 +++++++++++- .../preamble/generate-completion-status.ts | 2 +- .../preamble/generate-evidence-directive.ts | 36 ++++-- scripts/resolvers/test-value.ts | 19 +++- scripts/resolvers/testing.ts | 2 +- setup-browser-cookies/SKILL.md | 2 +- setup-deploy/SKILL.md | 10 +- setup-gbrain/SKILL.md | 10 +- ship/SKILL.md | 10 +- ship/sections/plan-completion.md | 62 ++++++++++- ship/sections/plan-completion.md.tmpl | 7 +- ship/sections/test-coverage.md | 15 ++- ship/sections/test-coverage.md.tmpl | 7 +- skillify/SKILL.md | 10 +- spec/SKILL.md | 20 +++- spec/SKILL.md.tmpl | 6 +- spec/sections/gate-and-file.md | 2 +- spec/sections/gate-and-file.md.tmpl | 2 +- sync-gbrain/SKILL.md | 10 +- test-audit/SKILL.md | 14 ++- test/dispatch-rules.test.ts | 83 ++++++++++++++ test/fixtures/context-budget.json | 100 ++++++++--------- test/fixtures/golden/agy-ship-SKILL.md | 10 +- test/fixtures/golden/claude-ship-SKILL.md | 10 +- test/fixtures/golden/codex-ship-SKILL.md | 10 +- test/fixtures/golden/factory-ship-SKILL.md | 10 +- test/helpers/carve-guards.ts | 28 ++--- test/honesty-kernel.test.ts | 75 +++++++++++++ test/outside-voice-routing.test.ts | 2 +- test/ship-plan-completion-invariants.test.ts | 105 +++++++++++++++++- test/test-value-bar.test.ts | 26 ++++- 81 files changed, 953 insertions(+), 257 deletions(-) create mode 100644 scripts/resolvers/dispatch-rules.ts create mode 100644 test/dispatch-rules.test.ts create mode 100644 test/honesty-kernel.test.ts diff --git a/AGENTS.md b/AGENTS.md index 6c86be265..c6abb1fd5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -27,7 +27,7 @@ Invoke them by name (e.g., `/office-hours`). | Skill | What it does | |-------|-------------| -| `/review` | Pre-landing PR review. Finds bugs that pass CI but break in prod. | +| `/review` | Pre-landing PR review. Finds bugs that pass CI but break in prod; lists every gate edit for gate integrity. | | `/deslop-shared-libs` | Find worthwhile shared-code extractions in recent work. Recommendations only. | | `/test-audit` | Sweep existing tests for low-value, implementation-coupled or duplicate tests. Report-only unless you approve a batch. | | `/codex` | Second opinion via OpenAI Codex. Review, challenge, or consult modes. Available outside the Codex harness. | @@ -46,7 +46,7 @@ Invoke them by name (e.g., `/office-hours`). | Skill | What it does | |-------|-------------| -| `/ship` | Run tests, review, push, open PR. Workspace-aware version queue. | +| `/ship` | Run tests, review, gate integrity, push, open PR. Workspace-aware version queue. | | `/land-and-deploy` | Merge the PR, wait for CI and deploy, verify production health. | | `/canary` | Post-deploy monitoring loop in your Aside browser (or gstack's own when Aside is absent). | | `/landing-report` | Read-only dashboard for the workspace-aware ship queue. | diff --git a/ETHOS.md b/ETHOS.md index a0fd1b845..4a4eef033 100644 --- a/ETHOS.md +++ b/ETHOS.md @@ -148,10 +148,36 @@ think it's better, state what context you might be missing, and ask. Never act. --- +## 4. Honest Work + +Work is the product and the proof that it works. Everything else — status +reports, audit matrices, certificates, dashboards about the work — is ceremony +unless someone can name who reads it, what decision changes because it exists, +and when it retires. Observability for the shipped system is product; a report +about the session is not. When in doubt, ship the behavior and the test, not +the artifact about them. + +Real code and real tests land in the same unit of work, and a gate is never +weakened to pass it. Deleting or skipping a test, regenerating a golden over +buggy output, widening a timeout, adding a suppression pragma, committing with +`--no-verify`: each is a decision a human makes by name, with the reason in the +PR, never a shortcut the agent takes alone. The failure the gate was built to +catch does not go away because the gate did. + +No self-certification. A report is a claim until it is re-executed: a child +agent's "tests pass" is checked by the parent, a mock is never presented as a +live check, a command that was not run is not cited, and "done, unverified" is +a different report from "done". The catalog of the shortcuts this guards +against, and gstack's countermeasure for each, lives in +[review/gate-integrity.md](review/gate-integrity.md). + +--- + ## How They Work Together Boil the Ocean says: **do the complete thing.** Search Before Building says: **know what exists before you decide what to build.** +Honest Work says: **the proof is the work, and a report is a claim until re-executed.** Together: search first, then build the complete version of the right thing. The worst outcome is building a complete version of something that already diff --git a/README.md b/README.md index 63c173ba4..4d493ceb2 100644 --- a/README.md +++ b/README.md @@ -288,7 +288,7 @@ Each skill feeds into the next. `/office-hours` writes a design doc that `/plan- | `/plan-design-review` | **Senior Designer** | Rates each design dimension 0-10, explains what a 10 looks like, then edits the plan to get there. AI Slop detection. Interactive — one AskUserQuestion per design choice. | | `/plan-devex-review` | **Developer Experience Lead** | Interactive DX review: explores developer personas, benchmarks against competitors' TTHW, designs your magical moment, traces friction points step by step. Three modes: DX EXPANSION, DX POLISH, DX TRIAGE. 20-45 forcing questions. | | `/design-consultation` | **Design Partner** | Build a complete design system from scratch. Researches the landscape, proposes creative risks, generates realistic product mockups. Writes `DESIGN.md` in the open DESIGN.md format, so impeccable, Google Stitch, and any tool that reads it share one file. | -| `/review` | **Staff Engineer** | Find the bugs that pass CI but blow up in production. Auto-fixes the obvious ones. Flags completeness gaps. Advisory simplification lens flags over-built code — never blocks, never auto-applies. | +| `/review` | **Staff Engineer** | Find the bugs that pass CI but blow up in production. Auto-fixes the obvious ones. Flags completeness gaps and gate integrity: every weakened test, timeout, snapshot or suppression reaches a human by name. Advisory simplification lens flags over-built code — never blocks, never auto-applies. | | `/deslop-shared-libs` | **Shared Code Reviewer** | Find worthwhile shared-code extractions in recent work. Compares up to five opportunities and recommends the best three, with source evidence, reliability gains, and total code savings. Recommendations only. | | `/test-audit` | **Test Auditor** | Sweep existing tests for ones that cost more than they protect: source greps, duplicates, assertion-free probes, test-only exports. Every candidate carries an evidence card; report-only unless you approve a batch. | | `/investigate` | **Debugger** | Systematic root-cause debugging. Iron Law: no fixes without investigation. Traces data flow, tests hypotheses, stops after 3 failed fixes. | @@ -300,7 +300,7 @@ Each skill feeds into the next. `/office-hours` writes a design doc that `/plan- | `/qa-only` | **QA Reporter** | Explore and report with replayable evidence. Suggest regression cases without changing product code or tests. | | `/pair-agent` | **Multi-Agent Coordinator** | Share gstack's own browser with any AI agent. One command, one paste, connected. Works with OpenClaw, Hermes, Codex, Cursor, or anything that can curl. Each agent gets its own tab. Auto-launches headed mode so you watch everything. Auto-starts ngrok tunnel for remote agents. Scoped tokens, tab isolation, rate limiting, activity attribution. (Runs on the bundled browser — the fallback engine; agents driving Aside just open their own tabs.) | | `/cso` | **Chief Security Officer** | Security audit with an application model, supported findings, independent challenge, and explicit coverage. Static assessment remains available without catalog profiles. With matching qualified profiles, comprehensive mode adds contained runtime/scanner execution and reviewable repair candidates for Node/Bun, Python, and Rails; no qualified runtime or scanner profile is published yet, so audits run static assessment only. Runtime-tested bundles authenticate separate external assertions. Project-test completion remains `self_reported` because target code controls the test process; `tested` is reserved for a future target-independent completion witness. | -| `/ship` | **Release Engineer** | Sync main, run tests, explore changed behavior, audit coverage and docs, then verify, push and open a PR. | +| `/ship` | **Release Engineer** | Sync main, run tests, explore changed behavior, audit coverage, gate integrity and docs, then verify, push and open a PR. | | `/land-and-deploy` | **Release Engineer** | Merge the PR, wait for CI and deploy, verify production health. One command from "approved" to "verified in production." | | `/canary` | **SRE** | Post-deploy monitoring loop. Watches for console errors, performance regressions, and page failures. | | `/benchmark` | **Performance Engineer** | Baseline page load times, Core Web Vitals, and resource sizes. Compare before/after on every PR. | diff --git a/SKILL.md b/SKILL.md index 252e62612..0ed1f7ed5 100644 --- a/SKILL.md +++ b/SKILL.md @@ -105,7 +105,7 @@ The user has context you do not. Cross-model agreement is a recommendation, not ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/autoplan/SKILL.md b/autoplan/SKILL.md index 5e5ec3af6..a182a60f6 100644 --- a/autoplan/SKILL.md +++ b/autoplan/SKILL.md @@ -284,9 +284,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -351,7 +355,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/benchmark-models/SKILL.md b/benchmark-models/SKILL.md index 5c7af4c9e..359eb40ed 100644 --- a/benchmark-models/SKILL.md +++ b/benchmark-models/SKILL.md @@ -109,7 +109,7 @@ The user has context you do not. Cross-model agreement is a recommendation, not ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/benchmark/SKILL.md b/benchmark/SKILL.md index dc53eafd4..2f2f7bcbf 100644 --- a/benchmark/SKILL.md +++ b/benchmark/SKILL.md @@ -110,7 +110,7 @@ The user has context you do not. Cross-model agreement is a recommendation, not ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/browse/SKILL.md b/browse/SKILL.md index 57db3e8e0..9a2e67fd8 100644 --- a/browse/SKILL.md +++ b/browse/SKILL.md @@ -105,7 +105,7 @@ The user has context you do not. Cross-model agreement is a recommendation, not ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/canary/SKILL.md b/canary/SKILL.md index cdb951ccb..64d37ac5f 100644 --- a/canary/SKILL.md +++ b/canary/SKILL.md @@ -265,9 +265,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -302,7 +306,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/codex/SKILL.md b/codex/SKILL.md index eb0f1b472..250da8f08 100644 --- a/codex/SKILL.md +++ b/codex/SKILL.md @@ -268,9 +268,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -335,7 +339,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/context-restore/SKILL.md b/context-restore/SKILL.md index 66ff74d24..46dac1420 100644 --- a/context-restore/SKILL.md +++ b/context-restore/SKILL.md @@ -267,9 +267,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -304,7 +308,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/context-save/SKILL.md b/context-save/SKILL.md index 68c13f7d2..e417f4b81 100644 --- a/context-save/SKILL.md +++ b/context-save/SKILL.md @@ -266,9 +266,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -303,7 +307,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/design-consultation/SKILL.md b/design-consultation/SKILL.md index 979cd2099..7f169739a 100644 --- a/design-consultation/SKILL.md +++ b/design-consultation/SKILL.md @@ -291,9 +291,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -358,7 +362,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/design-html/SKILL.md b/design-html/SKILL.md index b16ac6adc..33fe9d3c1 100644 --- a/design-html/SKILL.md +++ b/design-html/SKILL.md @@ -272,9 +272,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -309,7 +313,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/design-review/SKILL.md b/design-review/SKILL.md index 697f58374..833da97b5 100644 --- a/design-review/SKILL.md +++ b/design-review/SKILL.md @@ -269,9 +269,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -336,7 +340,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/design-shotgun/SKILL.md b/design-shotgun/SKILL.md index 233617d67..17115054c 100644 --- a/design-shotgun/SKILL.md +++ b/design-shotgun/SKILL.md @@ -285,9 +285,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -322,7 +326,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/devex-review/SKILL.md b/devex-review/SKILL.md index 77e8c51de..3f2a8ab4e 100644 --- a/devex-review/SKILL.md +++ b/devex-review/SKILL.md @@ -271,9 +271,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -338,7 +342,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/diagram/SKILL.md b/diagram/SKILL.md index 990e88400..839fd3b45 100644 --- a/diagram/SKILL.md +++ b/diagram/SKILL.md @@ -108,7 +108,7 @@ The user has context you do not. Cross-model agreement is a recommendation, not ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/document-generate/SKILL.md b/document-generate/SKILL.md index 65682972f..13a3c30c3 100644 --- a/document-generate/SKILL.md +++ b/document-generate/SKILL.md @@ -271,9 +271,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -308,7 +312,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/document-release/SKILL.md b/document-release/SKILL.md index b8cd7dd2b..616703e6a 100644 --- a/document-release/SKILL.md +++ b/document-release/SKILL.md @@ -269,9 +269,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -306,7 +310,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/health/SKILL.md b/health/SKILL.md index 5623c066e..ec220d7b2 100644 --- a/health/SKILL.md +++ b/health/SKILL.md @@ -267,9 +267,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -304,7 +308,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/investigate/SKILL.md b/investigate/SKILL.md index bdf28b4a7..964221c54 100644 --- a/investigate/SKILL.md +++ b/investigate/SKILL.md @@ -311,9 +311,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -348,7 +352,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/ios-clean/SKILL.md b/ios-clean/SKILL.md index 65ebd5ba0..4452c7d75 100644 --- a/ios-clean/SKILL.md +++ b/ios-clean/SKILL.md @@ -269,9 +269,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -306,7 +310,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/ios-design-review/SKILL.md b/ios-design-review/SKILL.md index caf53acf4..dda41bd32 100644 --- a/ios-design-review/SKILL.md +++ b/ios-design-review/SKILL.md @@ -271,9 +271,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -308,7 +312,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/ios-fix/SKILL.md b/ios-fix/SKILL.md index ff87a17ff..ddd05d524 100644 --- a/ios-fix/SKILL.md +++ b/ios-fix/SKILL.md @@ -272,9 +272,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -309,7 +313,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/ios-qa/SKILL.md b/ios-qa/SKILL.md index 84f6c0566..b285c10ea 100644 --- a/ios-qa/SKILL.md +++ b/ios-qa/SKILL.md @@ -276,9 +276,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -343,7 +347,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/ios-sync/SKILL.md b/ios-sync/SKILL.md index f45ac524e..6a9341c5a 100644 --- a/ios-sync/SKILL.md +++ b/ios-sync/SKILL.md @@ -269,9 +269,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -306,7 +310,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/land-and-deploy/SKILL.md b/land-and-deploy/SKILL.md index ffc947d56..94ce506cf 100644 --- a/land-and-deploy/SKILL.md +++ b/land-and-deploy/SKILL.md @@ -264,9 +264,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -331,7 +335,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/landing-report/SKILL.md b/landing-report/SKILL.md index 069a023ba..66043fe90 100644 --- a/landing-report/SKILL.md +++ b/landing-report/SKILL.md @@ -266,9 +266,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -303,7 +307,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/learn/SKILL.md b/learn/SKILL.md index 916d36df1..7cf7e1953 100644 --- a/learn/SKILL.md +++ b/learn/SKILL.md @@ -267,9 +267,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -304,7 +308,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/make-pdf/SKILL.md b/make-pdf/SKILL.md index 15234412a..7c07e515e 100644 --- a/make-pdf/SKILL.md +++ b/make-pdf/SKILL.md @@ -146,7 +146,7 @@ The user has context you do not. Cross-model agreement is a recommendation, not ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/office-hours/SKILL.md b/office-hours/SKILL.md index 04bb8d147..22107c03a 100644 --- a/office-hours/SKILL.md +++ b/office-hours/SKILL.md @@ -312,9 +312,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -379,7 +383,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/open-gstack-browser/SKILL.md b/open-gstack-browser/SKILL.md index 974319239..4bb69ad75 100644 --- a/open-gstack-browser/SKILL.md +++ b/open-gstack-browser/SKILL.md @@ -107,7 +107,7 @@ The user has context you do not. Cross-model agreement is a recommendation, not ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/pair-agent/SKILL.md b/pair-agent/SKILL.md index 95470a1d5..15424c9d7 100644 --- a/pair-agent/SKILL.md +++ b/pair-agent/SKILL.md @@ -268,9 +268,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -305,7 +309,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/plan-ceo-review/SKILL.md b/plan-ceo-review/SKILL.md index 5b578c4f0..a242d4777 100644 --- a/plan-ceo-review/SKILL.md +++ b/plan-ceo-review/SKILL.md @@ -293,9 +293,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -360,7 +364,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/plan-ceo-review/sections/review-sections.md b/plan-ceo-review/sections/review-sections.md index 157a1bfbb..2493aa56d 100644 --- a/plan-ceo-review/sections/review-sections.md +++ b/plan-ceo-review/sections/review-sections.md @@ -130,6 +130,7 @@ Evaluate and diagram: * Security architecture. Auth boundaries, data access patterns, API surfaces. For each new endpoint or data mutation: who can call it, what do they get, what can they change? * Production failure scenarios. For each integration point, describe one realistic failure and whether the plan handles it. * Rollback posture. If this ships broken, name the rollback path and time. +* Value test for artifacts about the work. When the plan adds a status report, audit matrix, certificate, meta-report or conformance check that nothing consumes, ask: who uses it, what decision or delivered behavior changes because it exists, why this is the smallest useful version, and when it retires. An explicit user request answers the first two and is recorded as provenance; the last two are still answered. A credible, explicitly identified preventive risk is a valid answer; a past incident is not required. Manufacturing a code consumer to pass the question is the pathology, not an answer. Carve-out: product observability (dashboards, alerts, runbooks for the shipped system) is launch scope under Prime Directive 5 and never a process artifact; user-facing docs and agent-consumed instructions are product. The question applies to artifacts about the work, not about the system. **EXPANSION and SELECTIVE EXPANSION additions:** * What would make this architecture elegant and obvious to a new engineer? @@ -229,7 +230,7 @@ For each item in the diagram: * What is the edge case test? (nil, empty, boundary values, concurrent access) For each behavior, complete this assertion check: -1. **Map the requirement.** Name its observable assertion and a wrong result it rejects. Map it to the user's exact requirement or individually approved remedy. A stated outcome plus its retained caller contract can determine the assertion, even without assertion syntax. Translate semantic counts, conditions and quantifiers exactly; never weaken an exact count to a lower bound. +1. **Map the requirement.** Name its observable assertion, a wrong result it rejects, and its `no_claim`: one sentence on what a green result does not prove and which fixtures or mocks stand in for what (`no_claim=provider acceptance (mocked provider; unit only)`, or `no_claim=none beyond protects` when nothing is left unproven; never reflexive filler). Author it yourself; never ask the user for it, and never let it waive a required live check or an unresolved test-method decision. Map the requirement to the user's exact requirement or individually approved remedy. A stated outcome plus its retained caller contract can determine the assertion, even without assertion syntax. Translate semantic counts, conditions and quantifiers exactly; never weaken an exact count to a lower bound. 2. **Reuse settled proof.** Selecting an existing probe or spelling out a determined check is implementation work, not another approval. Reuse these requirements without asking again. Verify the caller's path; helper coverage alone does not prove it. Honor previously accepted risks and equivalent caller coverage. 3. **Resolve actual gaps.** Explain what the existing requirement or approved remedy fails to cover before calling a check missing. Ask individually only for an unresolved behavioral choice, new outcome, or independent uncovered failure mode. Vague success labels do not settle values; scope/approach approval does not resolve an individual assertion gap. Never silently add, defer or waive a missing behavioral assertion. Keep required behaviors mandatory unless the user explicitly approves changing them. diff --git a/plan-ceo-review/sections/review-sections.md.tmpl b/plan-ceo-review/sections/review-sections.md.tmpl index febb2d202..505619527 100644 --- a/plan-ceo-review/sections/review-sections.md.tmpl +++ b/plan-ceo-review/sections/review-sections.md.tmpl @@ -128,6 +128,7 @@ Evaluate and diagram: * Security architecture. Auth boundaries, data access patterns, API surfaces. For each new endpoint or data mutation: who can call it, what do they get, what can they change? * Production failure scenarios. For each integration point, describe one realistic failure and whether the plan handles it. * Rollback posture. If this ships broken, name the rollback path and time. +* Value test for artifacts about the work. When the plan adds a status report, audit matrix, certificate, meta-report or conformance check that nothing consumes, ask: who uses it, what decision or delivered behavior changes because it exists, why this is the smallest useful version, and when it retires. An explicit user request answers the first two and is recorded as provenance; the last two are still answered. A credible, explicitly identified preventive risk is a valid answer; a past incident is not required. Manufacturing a code consumer to pass the question is the pathology, not an answer. Carve-out: product observability (dashboards, alerts, runbooks for the shipped system) is launch scope under Prime Directive 5 and never a process artifact; user-facing docs and agent-consumed instructions are product. The question applies to artifacts about the work, not about the system. **EXPANSION and SELECTIVE EXPANSION additions:** * What would make this architecture elegant and obvious to a new engineer? @@ -227,7 +228,7 @@ For each item in the diagram: * What is the edge case test? (nil, empty, boundary values, concurrent access) For each behavior, complete this assertion check: -1. **Map the requirement.** Name its observable assertion and a wrong result it rejects. Map it to the user's exact requirement or individually approved remedy. A stated outcome plus its retained caller contract can determine the assertion, even without assertion syntax. Translate semantic counts, conditions and quantifiers exactly; never weaken an exact count to a lower bound. +1. **Map the requirement.** Name its observable assertion, a wrong result it rejects, and its `no_claim`: one sentence on what a green result does not prove and which fixtures or mocks stand in for what (`no_claim=provider acceptance (mocked provider; unit only)`, or `no_claim=none beyond protects` when nothing is left unproven; never reflexive filler). Author it yourself; never ask the user for it, and never let it waive a required live check or an unresolved test-method decision. Map the requirement to the user's exact requirement or individually approved remedy. A stated outcome plus its retained caller contract can determine the assertion, even without assertion syntax. Translate semantic counts, conditions and quantifiers exactly; never weaken an exact count to a lower bound. 2. **Reuse settled proof.** Selecting an existing probe or spelling out a determined check is implementation work, not another approval. Reuse these requirements without asking again. Verify the caller's path; helper coverage alone does not prove it. Honor previously accepted risks and equivalent caller coverage. 3. **Resolve actual gaps.** Explain what the existing requirement or approved remedy fails to cover before calling a check missing. Ask individually only for an unresolved behavioral choice, new outcome, or independent uncovered failure mode. Vague success labels do not settle values; scope/approach approval does not resolve an individual assertion gap. Never silently add, defer or waive a missing behavioral assertion. Keep required behaviors mandatory unless the user explicitly approves changing them. diff --git a/plan-design-review/SKILL.md b/plan-design-review/SKILL.md index bde83e878..6ed4d6d43 100644 --- a/plan-design-review/SKILL.md +++ b/plan-design-review/SKILL.md @@ -293,9 +293,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -360,7 +364,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/plan-devex-review/SKILL.md b/plan-devex-review/SKILL.md index 0a0e5b9c6..a2ad94d2c 100644 --- a/plan-devex-review/SKILL.md +++ b/plan-devex-review/SKILL.md @@ -265,9 +265,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -332,7 +336,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/plan-eng-review/SKILL.md b/plan-eng-review/SKILL.md index 5897d402a..a7428e1fc 100644 --- a/plan-eng-review/SKILL.md +++ b/plan-eng-review/SKILL.md @@ -309,9 +309,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -376,7 +380,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/plan-eng-review/sections/review-sections.md b/plan-eng-review/sections/review-sections.md index 1275915ce..f6bdbc1ce 100644 --- a/plan-eng-review/sections/review-sections.md +++ b/plan-eng-review/sections/review-sections.md @@ -640,9 +640,9 @@ Quality scoring rubric: A test that breaks under a behavior-preserving refactor asserts implementation: rewrite it at the owning boundary, unless exact output is the declared contract (goldens, prompt bytes, wire formats). -Value card: `Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none` (seam: `none` or its name); each field at most 160 UTF-8 bytes here (clamp to 157 plus `...`; written JSON keeps full values). One card per Critical Path and Edge Case in the Test Plan Artifact. A missing upstream card never blocks: derive it; ignore unknown fields. +Value card: `Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none; no_claim=<...>` (seam: `none` or its name; `no_claim`: one sentence on what green does not prove and which fixtures or mocks stand in for what, e.g. `no_claim=provider acceptance (mocked provider; unit only)` or `no_claim=none beyond protects`; it never waives a required live check); each field at most 160 UTF-8 bytes here (clamp to 157 plus `...`; written JSON keeps full values). One card per Critical Path and Edge Case in the Test Plan Artifact. A missing upstream card never blocks: derive it; ignore unknown fields. -Example: Value: protects=refundPayment rejects an empty reason; fails_when=the reason guard is removed or inverted; why_new=billing.test.ts covers processPayment only; seam=none +Example: Value: protects=refundPayment rejects an empty reason; fails_when=the reason guard is removed or inverted; why_new=billing.test.ts covers processPayment only; seam=none; no_claim=provider acceptance (mocked provider; unit only) Rejected (covered_elsewhere): "checkout renders"; checkout.e2e.ts:15 covers it, so extend that test. Weak tests (★ smoke/existence/trivial, gate-failing or unrated) never count as coverage. X = paths with a ★★/★★★ test / total paths (value-weighted; the gate uses X); Y = paths with any test / total paths. /ship computes them; here every proposed test needs a card. @@ -760,7 +760,7 @@ Repo: {owner/repo} ## Critical Paths - {end-to-end flow that must work} - Value: protects={...}; fails_when={...}; why_new={...}; seam=none + Value: protects={...}; fails_when={...}; why_new={...}; seam=none; no_claim={...} ## Tests to Retire - {existing test made obsolete by this plan and why, or none} diff --git a/plan-tune/SKILL.md b/plan-tune/SKILL.md index 2ae8c9963..572449a09 100644 --- a/plan-tune/SKILL.md +++ b/plan-tune/SKILL.md @@ -277,9 +277,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -314,7 +318,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/qa-only/SKILL.md b/qa-only/SKILL.md index e37fb42f0..dbf73a20b 100644 --- a/qa-only/SKILL.md +++ b/qa-only/SKILL.md @@ -267,9 +267,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -334,7 +338,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. @@ -538,9 +542,9 @@ Each proposed test carries a value card; propose it only when it passes this bar 1. Why does existing coverage not already catch that? Prefer adding a row to an existing table-driven test or shared fixture over a near-duplicate. 2. Does it need a production seam (export, flag, wrapper, injection hook) that no production caller needs? If yes, test at the real boundary instead. -Value card: `Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none` (seam: `none` or its name); each field at most 160 UTF-8 bytes here (clamp to 157 plus `...`; written JSON keeps full values). Put it under each proposed test. A missing upstream card never blocks: derive it; ignore unknown fields. +Value card: `Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none; no_claim=<...>` (seam: `none` or its name; `no_claim`: one sentence on what green does not prove and which fixtures or mocks stand in for what, e.g. `no_claim=provider acceptance (mocked provider; unit only)` or `no_claim=none beyond protects`; it never waives a required live check); each field at most 160 UTF-8 bytes here (clamp to 157 plus `...`; written JSON keeps full values). Put it under each proposed test. A missing upstream card never blocks: derive it; ignore unknown fields. -Example: Value: protects=refundPayment rejects an empty reason; fails_when=the reason guard is removed or inverted; why_new=billing.test.ts covers processPayment only; seam=none +Example: Value: protects=refundPayment rejects an empty reason; fails_when=the reason guard is removed or inverted; why_new=billing.test.ts covers processPayment only; seam=none; no_claim=provider acceptance (mocked provider; unit only) Rejected (covered_elsewhere): "checkout renders"; checkout.e2e.ts:15 covers it, so extend that test. Nest remaining headings per surface, without duplicating the shared title or metadata. diff --git a/qa/SKILL.md b/qa/SKILL.md index 352524525..209aca0c1 100644 --- a/qa/SKILL.md +++ b/qa/SKILL.md @@ -271,9 +271,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -338,7 +342,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. @@ -631,9 +635,9 @@ and unclear contracts never authorize repair. 1. Why does existing coverage not already catch that? Prefer adding a row to an existing table-driven test or shared fixture over a near-duplicate. 2. Does it need a production seam (export, flag, wrapper, injection hook) that no production caller needs? If yes, test at the real boundary instead. -Value card: `Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none` (seam: `none` or its name); each field at most 160 UTF-8 bytes here (clamp to 157 plus `...`; written JSON keeps full values). Put it in the 8e.5 record. A missing upstream card never blocks: derive it; ignore unknown fields. +Value card: `Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none; no_claim=<...>` (seam: `none` or its name; `no_claim`: one sentence on what green does not prove and which fixtures or mocks stand in for what, e.g. `no_claim=provider acceptance (mocked provider; unit only)` or `no_claim=none beyond protects`; it never waives a required live check); each field at most 160 UTF-8 bytes here (clamp to 157 plus `...`; written JSON keeps full values). Put it in the 8e.5 record. A missing upstream card never blocks: derive it; ignore unknown fields. -Example: Value: protects=refundPayment rejects an empty reason; fails_when=the reason guard is removed or inverted; why_new=billing.test.ts covers processPayment only; seam=none +Example: Value: protects=refundPayment rejects an empty reason; fails_when=the reason guard is removed or inverted; why_new=billing.test.ts covers processPayment only; seam=none; no_claim=provider acceptance (mocked provider; unit only) Rejected (covered_elsewhere): "checkout renders"; checkout.e2e.ts:15 covers it, so extend that test. Extend an existing table or fixture when one covers the boundary; never add a production diff --git a/retro/SKILL.md b/retro/SKILL.md index 0c1933a21..d39804c09 100644 --- a/retro/SKILL.md +++ b/retro/SKILL.md @@ -285,9 +285,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -322,7 +326,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/review/SKILL.md b/review/SKILL.md index 2c7026082..e66a884fe 100644 --- a/review/SKILL.md +++ b/review/SKILL.md @@ -269,9 +269,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -336,7 +340,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/review/specialists/testing.md b/review/specialists/testing.md index 743dde892..b1ca5cb40 100644 --- a/review/specialists/testing.md +++ b/review/specialists/testing.md @@ -104,7 +104,8 @@ validation`). End each finding's `fix` with `Repo-wide sweep: run /test-audit.` A new or changed test passes the authoring gate only when all four answers exist (read its `Value: protects=...; fails_when=...; why_new=...; seam=...` header comment when the -diff has one): +diff has one; an optional `no_claim=...` names what green does not prove and which +fixtures or mocks stand in for what, and never waives a required live check): 1. What observable behavior, invariant or independent contract does it protect? 2. What credible regression makes it fail? 3. Why does existing coverage not already catch that? Prefer adding a row to an existing table-driven test or shared fixture over a near-duplicate. diff --git a/scrape/SKILL.md b/scrape/SKILL.md index 79af85129..09ef4d782 100644 --- a/scrape/SKILL.md +++ b/scrape/SKILL.md @@ -104,7 +104,7 @@ The user has context you do not. Cross-model agreement is a recommendation, not ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/scripts/resolvers/dispatch-rules.ts b/scripts/resolvers/dispatch-rules.ts new file mode 100644 index 000000000..93313633c --- /dev/null +++ b/scripts/resolvers/dispatch-rules.ts @@ -0,0 +1,28 @@ +/** + * {{IMPLEMENTER_DISPATCH_RULES}} — rules for an implementing child agent. + * + * docs/designs/HONEST_WORK_GATE_INTEGRITY.md W7. Rendered into /spec's issue + * body template (the archived spec is the prompt `/spec --execute` pipes to + * `claude -p`, so the rules travel inside it) and into /ship Step 7's + * test-generation child prompt, before its LAST-line JSON protocol. One + * constant so the two cannot drift. The child's JSON contracts are untouched: + * gate-edit disclosure uses the prose the protocols already permit before the + * JSON line. test/dispatch-rules.test.ts pins the rendering sites. + */ + +export const IMPLEMENTER_DISPATCH_RULES_HEADING = 'Rules for the implementing agent'; + +export const IMPLEMENTER_DISPATCH_RULES_ITEMS = [ + 'Acceptance criteria are the `protects / fails_when / no_claim` profile of each test: the observable it protects, the wrong result it rejects, and what green does not prove. Never "make the tests pass".', + 'Real code and real tests land in the same change; a placeholder, a stub assertion or a test deferred to a follow-up is not done.', + 'Any change to a test, validator, CI step, timeout, tolerance, threshold, snapshot or suppression pragma is reported on its own line in your summary with its justification, before any other result.', + 'A reported command names the command and its observed result (exit status, counts, the failing line); a command you did not run is not reported, and stderr is never silenced in a command you cite.', + 'Your report is a claim until the parent re-executes it: say what you verified, what you reused, and what you could not check.', +] as const; + +/** The numbered list only; each rendering site supplies its own heading line (`## ` in the spec body, `label:` in a child prompt). */ +export const IMPLEMENTER_DISPATCH_RULES = IMPLEMENTER_DISPATCH_RULES_ITEMS.map((rule, index) => `${index + 1}. ${rule}`).join('\n'); + +export function generateImplementerDispatchRules(): string { + return IMPLEMENTER_DISPATCH_RULES; +} diff --git a/scripts/resolvers/index.ts b/scripts/resolvers/index.ts index 5a50d17f0..f21ced248 100644 --- a/scripts/resolvers/index.ts +++ b/scripts/resolvers/index.ts @@ -47,6 +47,7 @@ import { generateCommandReference, generateSnapshotFlags, generateBrowseSetup, g import { generateDesignDocDiscovery } from './design-doc-discovery'; import { generateSharedLibsRubric, generateSafeGitPath } from './shared-libs'; import { generateTestValueBar, generateTestValueMessage } from './test-value'; +import { generateImplementerDispatchRules } from './dispatch-rules'; import { generateQAScope, generateQAExploratory, generateQAFunctional, generateQAResource, generateQAReview, generateQAReviewPreflight, generateQAMethodReads } from './qa'; export const RESOLVERS: Record = { @@ -115,6 +116,7 @@ export const RESOLVERS: Record = { TEST_COVERAGE_GATE_SHIP: generateTestCoverageGateShip, TEST_VALUE_BAR: generateTestValueBar, TEST_VALUE_MESSAGE: generateTestValueMessage, + IMPLEMENTER_DISPATCH_RULES: generateImplementerDispatchRules, TEST_FAILURE_TRIAGE: generateTestFailureTriage, SPEC_REVIEW_LOOP: generateSpecReviewLoop, DESIGN_SKETCH: generateDesignSketch, diff --git a/scripts/resolvers/plan-gates.ts b/scripts/resolvers/plan-gates.ts index 95d9be658..294456d59 100644 --- a/scripts/resolvers/plan-gates.ts +++ b/scripts/resolvers/plan-gates.ts @@ -227,6 +227,69 @@ done **Error handling:** a bound or chosen plan file that is unreadable (permissions, encoding) ${ship ? 'is an audit error, not "no plan": the parent applies its audit-failure recovery and skip/stop decision.' : '→ say "Plan file found but unreadable." and use the Fallback Intent Sources below; never report plan items as verified.'}`; } +export const ACCEPTANCE_EDITED = 'ACCEPTANCE_EDITED'; +/** Lower-cased heading keywords that mark a plan section as acceptance-bearing (awk ERE, applied after tolower). */ +export const ACCEPTANCE_HEADING_PATTERN = '^#+ *[0-9.]* *(testable )?(acceptance|success criteria|verification|test plan|testing|done when|definition of done)'; + +/** + * RH-10 (spec-editing as progress): the parent diffs the plan's acceptance-bearing + * sections as they stand in the working tree against a baseline and reports + * ACCEPTANCE_EDITED beside the child's classes. Parent-only: the child's + * seven-field JSON contract is unchanged. + */ +function planAcceptanceEditedCheck(): string { + return `### Acceptance edits (parent-computed) + +Run this after the child's report and before Gate Logic, with the bound plan path +substituted for \`\`. It compares the plan's acceptance-bearing sections +(headings matching acceptance, success criteria, verification, test plan, testing, +done when, definition of done) as they stand in the working tree against a baseline: +the \`origin/\` version when the plan exists there, else its first commit on this +branch, else \`baseline unavailable\` (plans outside the repository or not yet tracked). + +\`\`\`bash +PLAN_FILE="" +_REL=$(git ls-files --full-name --error-unmatch -- "$PLAN_FILE" 2>/dev/null | head -1) +_BASE_REF=""; _BASE_KIND="" +if [ -z "$_REL" ]; then + echo "ACCEPTANCE_BASELINE: unavailable (plan is not tracked in this repository)" +elif git cat-file -e "origin/:$_REL" 2>/dev/null; then + _BASE_REF="origin/"; _BASE_KIND="origin/" +else + _FIRST=$(git log --diff-filter=A --format=%H "origin/..HEAD" -- "$_REL" 2>/dev/null | tail -1) + if [ -n "$_FIRST" ]; then _BASE_REF="$_FIRST"; _BASE_KIND="first commit on branch ($_FIRST)" + else echo "ACCEPTANCE_BASELINE: unavailable (no origin/ version and no introducing commit)"; fi +fi +if [ -n "$_BASE_REF" ]; then + echo "ACCEPTANCE_BASELINE: $_BASE_KIND" + _ACC_TMP=$(mktemp -d) && trap 'rm -rf "$_ACC_TMP"' EXIT + _acc_sections() { awk 'BEGIN{keep=0} /^#+ /{keep = (tolower($0) ~ /${ACCEPTANCE_HEADING_PATTERN}/)} keep{print}'; } + git show "$_BASE_REF:$_REL" | _acc_sections > "$_ACC_TMP/base" + _acc_sections < "$PLAN_FILE" > "$_ACC_TMP/wtree" + if diff -u --label baseline --label working-tree "$_ACC_TMP/base" "$_ACC_TMP/wtree" > "$_ACC_TMP/diff"; then + echo "${ACCEPTANCE_EDITED}: none" + else + echo "${ACCEPTANCE_EDITED}: yes"; cat "$_ACC_TMP/diff" + fi +fi +\`\`\` + +Read the result: + +- \`${ACCEPTANCE_EDITED}: none\` — record \`Acceptance edits: none (baseline )\` for the PR body. +- \`${ACCEPTANCE_EDITED}: yes\` — for each plan item whose acceptance text the diff changed, add + \`[${ACCEPTANCE_EDITED}]\` beside the child's classification in the checklist summary. It is a + separate class: never fold it into CHANGED (CHANGED means the same goal was achieved by other + means and passes the gate). The original obligation is still audited: classify the item + against the baseline text, so an item that satisfies only its edited text is PARTIAL or + NOT DONE against the original and gated as such. The PR body names each one as a scope + change under \`## Plan Completion\` with the baseline and working-tree wording. +- \`ACCEPTANCE_BASELINE: unavailable\` — record \`Acceptance edits: baseline unavailable ()\` + in the PR body; never report \`none\`. + +Limit: an item rewritten in the same commit that introduced the plan is invisible to this check.`; +} + /** Ship's child audit: the parent already bound the plan, so the child never searches. */ function planInputShip(): string { return `### Plan input @@ -402,9 +465,13 @@ The parent evaluates the completion checklist in priority order, including after 4. **All DONE or CHANGED:** Pass. "Plan completion: PASS — all items addressed." Continue. +**${ACCEPTANCE_EDITED} items** (parent-computed, see Acceptance edits above) are gated by their +classification against the original acceptance text, never by the edited text, and are +never counted as CHANGED. They do not add a gate of their own; they are reported. + **No plan file found:** Skip only the plan completion audit. Continue with Step 8.1, Scope Drift and Prior Learnings; Step 9 QA still runs. -**Include in PR body (Step 19):** Add a \`## Plan Completion\` section with the checklist summary.`; +**Include in PR body (Step 19):** Add a \`## Plan Completion\` section with the checklist summary, the \`Acceptance edits:\` line and each \`[${ACCEPTANCE_EDITED}]\` item named as a scope change.`; } function planReviewDeliveryIntegrity(): string { @@ -529,9 +596,10 @@ export function generatePlanCompletionAuditShip(_ctx: TemplateContext): string { return generatePlanCompletionAuditInner('ship'); } -/** `{{PLAN_COMPLETION_GATE_SHIP:discovery}}` renders the parent-side plan binding that runs before dispatch. */ +/** `{{PLAN_COMPLETION_GATE_SHIP:discovery}}` renders the parent-side plan binding that runs before dispatch; `:acceptance` the parent-side ACCEPTANCE_EDITED check that runs after the child reports. */ export function generatePlanCompletionGateShip(_ctx: TemplateContext, args?: string[]): string { if (args?.includes('discovery')) return generatePlanFileDiscovery(true); + if (args?.includes('acceptance')) return planAcceptanceEditedCheck(); return generatePlanCompletionAuditInner('ship', 'gate'); } diff --git a/scripts/resolvers/preamble/generate-completion-status.ts b/scripts/resolvers/preamble/generate-completion-status.ts index dbc6e9987..ab5b645a3 100644 --- a/scripts/resolvers/preamble/generate-completion-status.ts +++ b/scripts/resolvers/preamble/generate-completion-status.ts @@ -39,7 +39,7 @@ export function generateCompletionStatus(ctx: TemplateContext): string { return `## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/scripts/resolvers/preamble/generate-evidence-directive.ts b/scripts/resolvers/preamble/generate-evidence-directive.ts index f4fdaa67e..8d8722b14 100644 --- a/scripts/resolvers/preamble/generate-evidence-directive.ts +++ b/scripts/resolvers/preamble/generate-evidence-directive.ts @@ -1,18 +1,32 @@ import type { TemplateContext } from '../types'; /** - * Evidence-before-claimed-limitations (fork port wave 2, D1). + * Claims Need Evidence: the preamble's honesty kernel (fork port wave 2, D1; + * extended by docs/designs/HONEST_WORK_GATE_INTEGRITY.md W4). * - * The single highest-leverage judgment clause from the fork's live App Store - * releases: nine release failures in two days shared one root — the agent - * asserting folklore as fact ("the API can't do this", "X requires a - * password") instead of running the ten-second check that would have - * disproven it. Adapted as ONE directive into the shared preamble (the - * fork's full SHARED-JUDGMENT contract is deliberately not imported). + * Started as one directive: a claimed limitation ("the API can't do this") + * needs the verbatim error, documented statement or live probe, because nine + * App Store release failures in two days shared that one root. W4 widened it + * to a five-bullet kernel covering claimed executions, evidence kinds, failure + * disclosure and null results. It is a correctness rule, not prose style, so + * it renders for every tier that composes it (2–4) and for `terse` builds; + * tier 1 skills have no evidence claim to make. The bullets stay at or under + * KERNEL_MAX_BYTES; test/honesty-kernel.test.ts pins that budget. */ -export function generateEvidenceDirective(ctx?: TemplateContext): string { - if (ctx?.explainLevel === 'terse') return ''; - return `## Claimed Limitations Need Evidence +export const KERNEL_MAX_BYTES = 800; -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked.`; +export const EVIDENCE_KERNEL_HEADING = '## Claims Need Evidence'; + +export const EVIDENCE_KERNEL_BULLETS = [ + 'A claimed limitation ("the API can\'t", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking.', + 'A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced.', + 'State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16.', + 'Disclose any failure or missing coverage that would change the reader\'s conclusion; "done, unverified" is not "done".', + 'A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum.', +] as const; + +export function generateEvidenceDirective(_ctx?: TemplateContext): string { + return `${EVIDENCE_KERNEL_HEADING} + +${EVIDENCE_KERNEL_BULLETS.map(bullet => `- ${bullet}`).join('\n')}`; } diff --git a/scripts/resolvers/test-value.ts b/scripts/resolvers/test-value.ts index ca5544ce9..086e89c3e 100644 --- a/scripts/resolvers/test-value.ts +++ b/scripts/resolvers/test-value.ts @@ -17,6 +17,9 @@ export const QUESTIONS = [ ] as const; export const VALUE_CARD_FIELDS = ['protects', 'fails_when', 'why_new', 'seam'] as const; +/** Optional fifth field: one sentence on what green does not prove and which fixtures or mocks stand in for what. */ +export const VALUE_CARD_OPTIONAL_FIELD = 'no_claim'; +export const NO_CLAIM_EXAMPLES = ['provider acceptance (mocked provider; unit only)', 'none beyond protects'] as const; export const CARD_FIELD_MAX_BYTES = 160; export const CATALOG = [ @@ -93,8 +96,9 @@ export function generateTestValueMessage(ctx: TemplateContext, args?: string[]): return degradedMessage(ctx, key as MessageKey); } -// Measured renders plus 15%: plan 1897, ship 2742, qa 1036, audit 3712 bytes. -export const TEST_VALUE_BAR_MAX_BYTES: Record = { plan: 2182, ship: 3154, qa: 1192, audit: 4269 }; +// Measured renders plus 15%: plan 2221, ship 3066, qa 1346, audit 4036 bytes +// (raised once for the optional `no_claim` card field and its two examples). +export const TEST_VALUE_BAR_MAX_BYTES: Record = { plan: 2555, ship: 3526, qa: 1548, audit: 4642 }; export function clampCardField(value: string): string { const bytes = Buffer.from(value, 'utf8'); @@ -104,8 +108,12 @@ export function clampCardField(value: string): string { return `${bytes.subarray(0, end).toString('utf8')}...`; } -export function renderValueCard(card: Record<(typeof VALUE_CARD_FIELDS)[number], string>): string { - return `Value: ${VALUE_CARD_FIELDS.map(field => `${field}=${clampCardField(card[field])}`).join('; ')}`; +export type ValueCard = Record<(typeof VALUE_CARD_FIELDS)[number], string> & { [VALUE_CARD_OPTIONAL_FIELD]?: string }; + +export function renderValueCard(card: ValueCard): string { + const fields: string[] = [...VALUE_CARD_FIELDS]; + if (card.no_claim !== undefined) fields.push(VALUE_CARD_OPTIONAL_FIELD); + return `Value: ${fields.map(field => `${field}=${clampCardField(card[field as keyof ValueCard]!)}`).join('; ')}`; } const EXAMPLE_CARD = renderValueCard({ @@ -113,6 +121,7 @@ const EXAMPLE_CARD = renderValueCard({ fails_when: 'the reason guard is removed or inverted', why_new: 'billing.test.ts covers processPayment only', seam: 'none', + no_claim: NO_CLAIM_EXAMPLES[0], }); const EXAMPLE_REJECTED = 'Rejected (covered_elsewhere): "checkout renders"; checkout.e2e.ts:15 covers it, so extend that test.'; @@ -129,7 +138,7 @@ function cardRules(mode: TestValueBarMode, skillName: string): string { qa: skillName === 'qa-only' ? 'Put it under each proposed test.' : 'Put it in the 8e.5 record.', audit: 'Read cards from test header comments when present.', }[mode]; - return `Value card: \`Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none\` (seam: \`none\` or its name); each field at most ${CARD_FIELD_MAX_BYTES} UTF-8 bytes here (clamp to 157 plus \`...\`; written JSON keeps full values). ${where} A missing upstream card never blocks: derive it; ignore unknown fields. + return `Value card: \`Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none; no_claim=<...>\` (seam: \`none\` or its name; \`no_claim\`: one sentence on what green does not prove and which fixtures or mocks stand in for what, e.g. \`no_claim=${NO_CLAIM_EXAMPLES[0]}\` or \`no_claim=${NO_CLAIM_EXAMPLES[1]}\`; it never waives a required live check); each field at most ${CARD_FIELD_MAX_BYTES} UTF-8 bytes here (clamp to 157 plus \`...\`; written JSON keeps full values). ${where} A missing upstream card never blocks: derive it; ignore unknown fields. Example: ${EXAMPLE_CARD} ${EXAMPLE_REJECTED}`; diff --git a/scripts/resolvers/testing.ts b/scripts/resolvers/testing.ts index bd72043d6..3146a8e4c 100644 --- a/scripts/resolvers/testing.ts +++ b/scripts/resolvers/testing.ts @@ -523,7 +523,7 @@ Repo: {owner/repo} ## Critical Paths - {end-to-end flow that must work} - Value: protects={...}; fails_when={...}; why_new={...}; seam=none + Value: protects={...}; fails_when={...}; why_new={...}; seam=none; no_claim={...} ## Tests to Retire - {existing test made obsolete by this plan and why, or none} diff --git a/setup-browser-cookies/SKILL.md b/setup-browser-cookies/SKILL.md index 5b63eb26b..f2da4d06a 100644 --- a/setup-browser-cookies/SKILL.md +++ b/setup-browser-cookies/SKILL.md @@ -103,7 +103,7 @@ The user has context you do not. Cross-model agreement is a recommendation, not ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/setup-deploy/SKILL.md b/setup-deploy/SKILL.md index 40ca65c88..f2e3ed9ad 100644 --- a/setup-deploy/SKILL.md +++ b/setup-deploy/SKILL.md @@ -268,9 +268,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -305,7 +309,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/setup-gbrain/SKILL.md b/setup-gbrain/SKILL.md index 4dc19ec3a..fcc5ea297 100644 --- a/setup-gbrain/SKILL.md +++ b/setup-gbrain/SKILL.md @@ -267,9 +267,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -304,7 +308,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/ship/SKILL.md b/ship/SKILL.md index 7682d6c38..e97d1105c 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -269,9 +269,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -336,7 +340,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/ship/sections/plan-completion.md b/ship/sections/plan-completion.md index 28e56c455..af5ae3842 100644 --- a/ship/sections/plan-completion.md +++ b/ship/sections/plan-completion.md @@ -178,10 +178,64 @@ Counts map one-to-one to the classifications above and sum to total_items. No pl extra or invalid fields fail. Valid no-plan/no-actionable reports retain zero counts and their summary. 2. Store counts for Step 20 and `summary` for Step 19's `## Plan Completion`. -3. Apply Gate Logic below before continuing. Carry approved deferrals, with item text +3. Run the parent-computed Acceptance edits check below on the bound plan; it adds + `ACCEPTANCE_EDITED` beside the child's classes and never changes the child's + seven fields. +4. Apply Gate Logic below before continuing. Carry approved deferrals, with item text and plan path, to Step 14; keep them separate from dropped scope. The gate supplies the required PR notes and per-item manual verification evidence. +### Acceptance edits (parent-computed) + +Run this after the child's report and before Gate Logic, with the bound plan path +substituted for ``. It compares the plan's acceptance-bearing sections +(headings matching acceptance, success criteria, verification, test plan, testing, +done when, definition of done) as they stand in the working tree against a baseline: +the `origin/` version when the plan exists there, else its first commit on this +branch, else `baseline unavailable` (plans outside the repository or not yet tracked). + +```bash +PLAN_FILE="" +_REL=$(git ls-files --full-name --error-unmatch -- "$PLAN_FILE" 2>/dev/null | head -1) +_BASE_REF=""; _BASE_KIND="" +if [ -z "$_REL" ]; then + echo "ACCEPTANCE_BASELINE: unavailable (plan is not tracked in this repository)" +elif git cat-file -e "origin/:$_REL" 2>/dev/null; then + _BASE_REF="origin/"; _BASE_KIND="origin/" +else + _FIRST=$(git log --diff-filter=A --format=%H "origin/..HEAD" -- "$_REL" 2>/dev/null | tail -1) + if [ -n "$_FIRST" ]; then _BASE_REF="$_FIRST"; _BASE_KIND="first commit on branch ($_FIRST)" + else echo "ACCEPTANCE_BASELINE: unavailable (no origin/ version and no introducing commit)"; fi +fi +if [ -n "$_BASE_REF" ]; then + echo "ACCEPTANCE_BASELINE: $_BASE_KIND" + _ACC_TMP=$(mktemp -d) && trap 'rm -rf "$_ACC_TMP"' EXIT + _acc_sections() { awk 'BEGIN{keep=0} /^#+ /{keep = (tolower($0) ~ /^#+ *[0-9.]* *(testable )?(acceptance|success criteria|verification|test plan|testing|done when|definition of done)/)} keep{print}'; } + git show "$_BASE_REF:$_REL" | _acc_sections > "$_ACC_TMP/base" + _acc_sections < "$PLAN_FILE" > "$_ACC_TMP/wtree" + if diff -u --label baseline --label working-tree "$_ACC_TMP/base" "$_ACC_TMP/wtree" > "$_ACC_TMP/diff"; then + echo "ACCEPTANCE_EDITED: none" + else + echo "ACCEPTANCE_EDITED: yes"; cat "$_ACC_TMP/diff" + fi +fi +``` + +Read the result: + +- `ACCEPTANCE_EDITED: none` — record `Acceptance edits: none (baseline )` for the PR body. +- `ACCEPTANCE_EDITED: yes` — for each plan item whose acceptance text the diff changed, add + `[ACCEPTANCE_EDITED]` beside the child's classification in the checklist summary. It is a + separate class: never fold it into CHANGED (CHANGED means the same goal was achieved by other + means and passes the gate). The original obligation is still audited: classify the item + against the baseline text, so an item that satisfies only its edited text is PARTIAL or + NOT DONE against the original and gated as such. The PR body names each one as a scope + change under `## Plan Completion` with the baseline and working-tree wording. +- `ACCEPTANCE_BASELINE: unavailable` — record `Acceptance edits: baseline unavailable ()` + in the PR body; never report `none`. + +Limit: an item rewritten in the same commit that introduced the plan is invisible to this check. + **Audit-failure fallback:** On failure, invalid JSON or no final output after ~10 minutes, stop any live child and confirm it stopped before an inline audit with the same extraction/classification logic; never race a late result. If that also fails, @@ -230,9 +284,13 @@ The parent evaluates the completion checklist in priority order, including after 4. **All DONE or CHANGED:** Pass. "Plan completion: PASS — all items addressed." Continue. +**ACCEPTANCE_EDITED items** (parent-computed, see Acceptance edits above) are gated by their +classification against the original acceptance text, never by the edited text, and are +never counted as CHANGED. They do not add a gate of their own; they are reported. + **No plan file found:** Skip only the plan completion audit. Continue with Step 8.1, Scope Drift and Prior Learnings; Step 9 QA still runs. -**Include in PR body (Step 19):** Add a `## Plan Completion` section with the checklist summary. +**Include in PR body (Step 19):** Add a `## Plan Completion` section with the checklist summary, the `Acceptance edits:` line and each `[ACCEPTANCE_EDITED]` item named as a scope change. ## Step 8.1: Plan Verification diff --git a/ship/sections/plan-completion.md.tmpl b/ship/sections/plan-completion.md.tmpl index ce3640b1b..4ade2ac6c 100644 --- a/ship/sections/plan-completion.md.tmpl +++ b/ship/sections/plan-completion.md.tmpl @@ -38,10 +38,15 @@ Counts map one-to-one to the classifications above and sum to total_items. No pl extra or invalid fields fail. Valid no-plan/no-actionable reports retain zero counts and their summary. 2. Store counts for Step 20 and `summary` for Step 19's `## Plan Completion`. -3. Apply Gate Logic below before continuing. Carry approved deferrals, with item text +3. Run the parent-computed Acceptance edits check below on the bound plan; it adds + `ACCEPTANCE_EDITED` beside the child's classes and never changes the child's + seven fields. +4. Apply Gate Logic below before continuing. Carry approved deferrals, with item text and plan path, to Step 14; keep them separate from dropped scope. The gate supplies the required PR notes and per-item manual verification evidence. +{{PLAN_COMPLETION_GATE_SHIP:acceptance}} + **Audit-failure fallback:** On failure, invalid JSON or no final output after ~10 minutes, stop any live child and confirm it stopped before an inline audit with the same extraction/classification logic; never race a late result. If that also fails, diff --git a/ship/sections/test-coverage.md b/ship/sections/test-coverage.md index 706f95237..d05b2f3e9 100644 --- a/ship/sections/test-coverage.md +++ b/ship/sections/test-coverage.md @@ -146,9 +146,9 @@ Quality scoring rubric: A test that breaks under a behavior-preserving refactor asserts implementation: rewrite it at the owning boundary, unless exact output is the declared contract (goldens, prompt bytes, wire formats). -Value card: `Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none` (seam: `none` or its name); each field at most 160 UTF-8 bytes here (clamp to 157 plus `...`; written JSON keeps full values). Write it as a header comment in each generated test, next to the attribution (wrap, do not truncate); with no known comment syntax, put it in the PR body's Test value details. A missing upstream card never blocks: derive it; ignore unknown fields. +Value card: `Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none; no_claim=<...>` (seam: `none` or its name; `no_claim`: one sentence on what green does not prove and which fixtures or mocks stand in for what, e.g. `no_claim=provider acceptance (mocked provider; unit only)` or `no_claim=none beyond protects`; it never waives a required live check); each field at most 160 UTF-8 bytes here (clamp to 157 plus `...`; written JSON keeps full values). Write it as a header comment in each generated test, next to the attribution (wrap, do not truncate); with no known comment syntax, put it in the PR body's Test value details. A missing upstream card never blocks: derive it; ignore unknown fields. -Example: Value: protects=refundPayment rejects an empty reason; fails_when=the reason guard is removed or inverted; why_new=billing.test.ts covers processPayment only; seam=none +Example: Value: protects=refundPayment rejects an empty reason; fails_when=the reason guard is removed or inverted; why_new=billing.test.ts covers processPayment only; seam=none; no_claim=provider acceptance (mocked provider; unit only) Rejected (covered_elsewhere): "checkout renders"; checkout.e2e.ts:15 covers it, so extend that test. Weak tests (★ smoke/existence/trivial, gate-failing or unrated) never count as coverage. X = paths with a ★★/★★★ test / total paths (value-weighted; the gate uses X); Y = paths with any test / total paths. Total paths = the diff's codepath trace, max 30; zero skips the gate. A path with only weak tests is uncovered in X, covered in Y, and goes to `weak_gaps` (reason `star_one|gate_failed|unrated`), not `gaps`. Rate stars only for tests reachable from changed paths. @@ -315,6 +315,14 @@ Repo: {owner/repo} - {end-to-end flow that must work} ``` +Rules for the implementing agent: +1. Acceptance criteria are the `protects / fails_when / no_claim` profile of each test: the observable it protects, the wrong result it rejects, and what green does not prove. Never "make the tests pass". +2. Real code and real tests land in the same change; a placeholder, a stub assertion or a test deferred to a follow-up is not done. +3. Any change to a test, validator, CI step, timeout, tolerance, threshold, snapshot or suppression pragma is reported on its own line in your summary with its justification, before any other result. +4. A reported command names the command and its observed result (exit status, counts, the failing line); a command you did not run is not reported, and stderr is never silenced in a command you cite. +5. Your report is a claim until the parent re-executes it: say what you verified, what you reused, and what you could not check. +Report any such change in the prose before the JSON line; the JSON fields below are unchanged. + After your analysis, output a single JSON object on the LAST LINE of your response (no other text after it): {"coverage_pct":N,"gaps":N,"diagram":"","tests_added":["path",...],"coverage_pct_value":N,"weak_gaps":[{"path":"...","existing_test":"...","reason":"star_one|gate_failed|unrated"}],"tests_extended":["path",...],"tests_rejected":[{"path_or_gap":"...","reason_code":"...","reason":"..."}],"regression_proof":{"red_at_head":N,"base_green":N,"base_unavailable":N}} `coverage_pct` is Y (paths with any test), `coverage_pct_value` is X (paths with a ★★/★★★ test), `gaps` counts only paths with no test. Use null for an undetermined or skipped coverage percentage, not zero. Include every remaining gap in the diagram so the parent can target a second pass. @@ -329,7 +337,8 @@ After your analysis, output a single JSON object on the LAST LINE of your respon A key with the wrong type (for example `weak_gaps` not an array) is ignored the same way and printed as: malformed ignored: the audit returned the wrong type, so it counts as empty. The likely cause is an outdated installed skill; run /gstack-upgrade. (see ~/.claude/skills/gstack/docs/test-value-bar.md#malformed-key-ignored) 3. **Machine checks** on every test written in this run (`tests_added` and - `tests_extended`): a value-card header with four non-empty fields (else + `tests_extended`): a value-card header with the four required fields non-empty plus + an optional `no_claim` (an older four-field card stays valid; else `incomplete_card`); `protects` unique across the run after casefolding and stripping punctuation and repeated whitespace (a later duplicate is `duplicate_protects`); seam `none`, or a named seam with at least one non-test caller (N = 0 or an unavailable diff --git a/ship/sections/test-coverage.md.tmpl b/ship/sections/test-coverage.md.tmpl index e3e7f2e69..9e8ae1d2a 100644 --- a/ship/sections/test-coverage.md.tmpl +++ b/ship/sections/test-coverage.md.tmpl @@ -37,6 +37,10 @@ Generation: ; passes used: of 2. Audit-only overrides ev {{TEST_COVERAGE_AUDIT_SHIP}} +Rules for the implementing agent: +{{IMPLEMENTER_DISPATCH_RULES}} +Report any such change in the prose before the JSON line; the JSON fields below are unchanged. + After your analysis, output a single JSON object on the LAST LINE of your response (no other text after it): {"coverage_pct":N,"gaps":N,"diagram":"","tests_added":["path",...],"coverage_pct_value":N,"weak_gaps":[{"path":"...","existing_test":"...","reason":"star_one|gate_failed|unrated"}],"tests_extended":["path",...],"tests_rejected":[{"path_or_gap":"...","reason_code":"...","reason":"..."}],"regression_proof":{"red_at_head":N,"base_green":N,"base_unavailable":N}} `coverage_pct` is Y (paths with any test), `coverage_pct_value` is X (paths with a ★★/★★★ test), `gaps` counts only paths with no test. Use null for an undetermined or skipped coverage percentage, not zero. Include every remaining gap in the diagram so the parent can target a second pass. @@ -51,7 +55,8 @@ After your analysis, output a single JSON object on the LAST LINE of your respon A key with the wrong type (for example `weak_gaps` not an array) is ignored the same way and printed as: {{TEST_VALUE_MESSAGE:malformedKey}} 3. **Machine checks** on every test written in this run (`tests_added` and - `tests_extended`): a value-card header with four non-empty fields (else + `tests_extended`): a value-card header with the four required fields non-empty plus + an optional `no_claim` (an older four-field card stays valid; else `incomplete_card`); `protects` unique across the run after casefolding and stripping punctuation and repeated whitespace (a later duplicate is `duplicate_protects`); seam `none`, or a named seam with at least one non-test caller (N = 0 or an unavailable diff --git a/skillify/SKILL.md b/skillify/SKILL.md index ce617501d..00be33f04 100644 --- a/skillify/SKILL.md +++ b/skillify/SKILL.md @@ -266,9 +266,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -303,7 +307,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/spec/SKILL.md b/spec/SKILL.md index 2cc1bfe49..06fde392a 100644 --- a/spec/SKILL.md +++ b/spec/SKILL.md @@ -267,9 +267,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -334,7 +338,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. @@ -753,7 +757,7 @@ left for the implementer.] 1. [Specific, pass/fail, no subjective language] 2. [...] -3. Tests written and passing +3. Each test in the Testing Plan states its card: `protects=; fails_when=; no_claim=` 4. No degradation of existing functionality ## Testing Plan @@ -764,6 +768,14 @@ left for the implementer.] | Integration | [specific flows] | +N | | E2E | [specific user journeys] | +N | +## Rules for the implementing agent + +1. Acceptance criteria are the `protects / fails_when / no_claim` profile of each test: the observable it protects, the wrong result it rejects, and what green does not prove. Never "make the tests pass". +2. Real code and real tests land in the same change; a placeholder, a stub assertion or a test deferred to a follow-up is not done. +3. Any change to a test, validator, CI step, timeout, tolerance, threshold, snapshot or suppression pragma is reported on its own line in your summary with its justification, before any other result. +4. A reported command names the command and its observed result (exit status, counts, the failing line); a command you did not run is not reported, and stderr is never silenced in a command you cite. +5. Your report is a claim until the parent re-executes it: say what you verified, what you reused, and what you could not check. + ## Rollback Plan [How to undo if something goes wrong] diff --git a/spec/SKILL.md.tmpl b/spec/SKILL.md.tmpl index 666ea3748..aad712c22 100644 --- a/spec/SKILL.md.tmpl +++ b/spec/SKILL.md.tmpl @@ -356,7 +356,7 @@ left for the implementer.] 1. [Specific, pass/fail, no subjective language] 2. [...] -3. Tests written and passing +3. Each test in the Testing Plan states its card: `protects=; fails_when=; no_claim=` 4. No degradation of existing functionality ## Testing Plan @@ -367,6 +367,10 @@ left for the implementer.] | Integration | [specific flows] | +N | | E2E | [specific user journeys] | +N | +## Rules for the implementing agent + +{{IMPLEMENTER_DISPATCH_RULES}} + ## Rollback Plan [How to undo if something goes wrong] diff --git a/spec/sections/gate-and-file.md b/spec/sections/gate-and-file.md index 26f3109e6..d7615cad2 100644 --- a/spec/sections/gate-and-file.md +++ b/spec/sections/gate-and-file.md @@ -441,7 +441,7 @@ If A and worktree created: spawn `claude -p` with the spec piped via stdin: cd -- "${SPAWN_PATH:?SPAWN_PATH is not set: substitute the printed worktree path}" || exit 1 [ "$(git rev-parse --show-toplevel 2>/dev/null)" = "$(pwd -P)" ] || { echo "ERROR: $SPAWN_PATH is not a git worktree root; nothing was spawned." >&2; exit 1; } SPAWN_PATH=$(pwd -P) -cat "$ARCHIVE_PATH" | (cd "$SPAWN_PATH" && claude -p 2>&1) & +cat "$ARCHIVE_PATH" | (cd "$SPAWN_PATH" && GSTACK_SESSION_KIND=spawned claude -p 2>&1) & SPAWN_PID=$! echo "Spawned: PID $SPAWN_PID in $SPAWN_PATH (branch $SPAWN_BRANCH)" echo "Follow with: cd $SPAWN_PATH && claude --resume" diff --git a/spec/sections/gate-and-file.md.tmpl b/spec/sections/gate-and-file.md.tmpl index d3e1eac20..ebdca3531 100644 --- a/spec/sections/gate-and-file.md.tmpl +++ b/spec/sections/gate-and-file.md.tmpl @@ -297,7 +297,7 @@ If A and worktree created: spawn `claude -p` with the spec piped via stdin: cd -- "${SPAWN_PATH:?SPAWN_PATH is not set: substitute the printed worktree path}" || exit 1 [ "$(git rev-parse --show-toplevel 2>/dev/null)" = "$(pwd -P)" ] || { echo "ERROR: $SPAWN_PATH is not a git worktree root; nothing was spawned." >&2; exit 1; } SPAWN_PATH=$(pwd -P) -cat "$ARCHIVE_PATH" | (cd "$SPAWN_PATH" && claude -p 2>&1) & +cat "$ARCHIVE_PATH" | (cd "$SPAWN_PATH" && GSTACK_SESSION_KIND=spawned claude -p 2>&1) & SPAWN_PID=$! echo "Spawned: PID $SPAWN_PID in $SPAWN_PATH (branch $SPAWN_BRANCH)" echo "Follow with: cd $SPAWN_PATH && claude --resume" diff --git a/sync-gbrain/SKILL.md b/sync-gbrain/SKILL.md index 347e67206..9e7f43fd3 100644 --- a/sync-gbrain/SKILL.md +++ b/sync-gbrain/SKILL.md @@ -268,9 +268,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -305,7 +309,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/test-audit/SKILL.md b/test-audit/SKILL.md index 32bad98fc..007cad75e 100644 --- a/test-audit/SKILL.md +++ b/test-audit/SKILL.md @@ -263,9 +263,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -300,7 +304,7 @@ Exit code 2 = rejected as not user-originated; do not retry. On success: "Set `< ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. @@ -378,9 +382,9 @@ repo, 10 candidates). A test that breaks under a behavior-preserving refactor asserts implementation: rewrite it at the owning boundary, unless exact output is the declared contract (goldens, prompt bytes, wire formats). -Value card: `Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none` (seam: `none` or its name); each field at most 160 UTF-8 bytes here (clamp to 157 plus `...`; written JSON keeps full values). Read cards from test header comments when present. A missing upstream card never blocks: derive it; ignore unknown fields. +Value card: `Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none; no_claim=<...>` (seam: `none` or its name; `no_claim`: one sentence on what green does not prove and which fixtures or mocks stand in for what, e.g. `no_claim=provider acceptance (mocked provider; unit only)` or `no_claim=none beyond protects`; it never waives a required live check); each field at most 160 UTF-8 bytes here (clamp to 157 plus `...`; written JSON keeps full values). Read cards from test header comments when present. A missing upstream card never blocks: derive it; ignore unknown fields. -Example: Value: protects=refundPayment rejects an empty reason; fails_when=the reason guard is removed or inverted; why_new=billing.test.ts covers processPayment only; seam=none +Example: Value: protects=refundPayment rejects an empty reason; fails_when=the reason guard is removed or inverted; why_new=billing.test.ts covers processPayment only; seam=none; no_claim=provider acceptance (mocked provider; unit only) Rejected (covered_elsewhere): "checkout renders"; checkout.e2e.ts:15 covers it, so extend that test. Regression proof: a regression test must fail at HEAD before any repair, in its own assertion (a pass at HEAD drops the regression label; an import, fixture or env failure is a test defect: correct once or drop). It must pass at base as the control (an assertion failure there marks it invalid; any other failure is "base control unavailable: collection error") and pass after the repair. Record: `Regression proof — fails at HEAD: yes · passes at base: yes | unavailable () | manual · passes after fix: yes | pending`. diff --git a/test/dispatch-rules.test.ts b/test/dispatch-rules.test.ts new file mode 100644 index 000000000..bc81aa500 --- /dev/null +++ b/test/dispatch-rules.test.ts @@ -0,0 +1,83 @@ +/** + * Implementer dispatch rules (docs/designs/HONEST_WORK_GATE_INTEGRITY.md W7). + * + * One constant renders into /spec's issue body (the archived spec that + * `/spec --execute` pipes to `claude -p`) and into /ship Step 7's child prompt, + * before the LAST-line JSON protocol. These checks pin the rendering sites, the + * machine-read tokens, the untouched JSON field list and the spawn env var + * (docs/test-value-bar.md: structure and markers, never sentences). + */ +import { describe, expect, test } from 'bun:test'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { + IMPLEMENTER_DISPATCH_RULES, IMPLEMENTER_DISPATCH_RULES_HEADING, IMPLEMENTER_DISPATCH_RULES_ITEMS, generateImplementerDispatchRules, +} from '../scripts/resolvers/dispatch-rules'; +import { RESOLVERS } from '../scripts/resolvers/index'; +import { between, expectAbsent, expectMentions, expectOrdered, expectTokens } from './helpers/prompt-structure'; + +const ROOT = path.resolve(import.meta.dir, '..'); +const read = (relative: string) => fs.readFileSync(path.join(ROOT, relative), 'utf8'); + +describe('the rules constant', () => { + test('is a numbered list in the card vocabulary that forbids the forbidden dispatch', () => { + expect(IMPLEMENTER_DISPATCH_RULES_ITEMS).toHaveLength(5); + expect(IMPLEMENTER_DISPATCH_RULES.split('\n').map(line => line.replace(/\..*$/, ''))).toEqual(['1', '2', '3', '4', '5']); + expectTokens(IMPLEMENTER_DISPATCH_RULES, ['`protects / fails_when / no_claim`', '"make the tests pass"'], 'rules'); + expectMentions(IMPLEMENTER_DISPATCH_RULES, [ + ['never', 'make the tests pass'], + ['real code', 'real tests', 'same change'], + ['test', 'timeout', 'suppression', 'own line', 'justification'], + ['command', 'observed result'], + ['claim', 'parent'], + ], 'rules'); + expect(generateImplementerDispatchRules()).toBe(IMPLEMENTER_DISPATCH_RULES); + expect(RESOLVERS.IMPLEMENTER_DISPATCH_RULES).toBe(generateImplementerDispatchRules); + expect(IMPLEMENTER_DISPATCH_RULES_HEADING).toBe('Rules for the implementing agent'); + }); +}); + +describe('/spec carries the rules inside the archived spec body', () => { + const tmpl = read('spec/SKILL.md.tmpl'); + const rendered = read('spec/SKILL.md'); + + test('the Standard Issues template renders the rules under its own heading and drops "Tests written and passing"', () => { + const template = between(tmpl, '### Standard Issues', '### Epics'); + expectOrdered(template, ['## Acceptance Criteria', '## Testing Plan', `## ${IMPLEMENTER_DISPATCH_RULES_HEADING}`, '{{IMPLEMENTER_DISPATCH_RULES}}', '## Rollback Plan'], 'spec issue template'); + expectAbsent(tmpl, ['Tests written and passing'], 'spec template'); + expectAbsent(rendered, ['Tests written and passing', '{{IMPLEMENTER_DISPATCH_RULES}}'], 'spec SKILL.md'); + expect(between(rendered, '### Standard Issues', '### Epics')).toContain(IMPLEMENTER_DISPATCH_RULES); + }); + + test('acceptance criteria are written in the card vocabulary', () => { + const criteria = between(tmpl, '## Acceptance Criteria', '## Testing Plan'); + expectTokens(criteria, ['protects=', 'fails_when=', 'no_claim=', 'none beyond protects'], 'spec acceptance criteria'); + }); + + test('the --execute spawn sets GSTACK_SESSION_KIND=spawned on the claude -p line', () => { + for (const file of ['spec/sections/gate-and-file.md.tmpl', 'spec/sections/gate-and-file.md']) { + const spawn = read(file).split('\n').filter(line => line.includes('claude -p 2>&1')); + expect(spawn, `${file} spawn line`).toHaveLength(1); + expect(spawn[0]).toMatch(/GSTACK_SESSION_KIND=spawned claude -p/); + } + }); +}); + +describe('/ship Step 7 child prompt carries the rules before an unchanged JSON protocol', () => { + const JSON_LINE_PREFIX = '{"coverage_pct":N,'; + const FIELDS = ['coverage_pct', 'gaps', 'diagram', 'tests_added', 'coverage_pct_value', 'weak_gaps', 'tests_extended', 'tests_rejected', 'regression_proof']; + + test('template order: audit, rules, JSON protocol', () => { + const child = between(read('ship/sections/test-coverage.md.tmpl'), '````text', '````\n\n**Parent processing:**'); + expectOrdered(child, ['{{TEST_COVERAGE_AUDIT_SHIP}}', `${IMPLEMENTER_DISPATCH_RULES_HEADING}:`, '{{IMPLEMENTER_DISPATCH_RULES}}', 'output a single JSON object on the LAST LINE', JSON_LINE_PREFIX], 'ship child prompt'); + }); + + test('rendered prompt carries the list and the LAST-line field set is unchanged', () => { + const child = between(read('ship/sections/test-coverage.md'), '````text', '````\n\n**Parent processing:**'); + expect(child).toContain(IMPLEMENTER_DISPATCH_RULES); + expect(child.indexOf(IMPLEMENTER_DISPATCH_RULES)).toBeLessThan(child.indexOf(JSON_LINE_PREFIX)); + const line = child.split('\n').find(l => l.startsWith(JSON_LINE_PREFIX))!; + const keys = Object.keys(JSON.parse(line.replace(/:N([,}])/g, ':0$1').replaceAll(',...', ''))); + expect(keys).toEqual(FIELDS); + }); +}); diff --git a/test/fixtures/context-budget.json b/test/fixtures/context-budget.json index 0d86950b1..2586fd72e 100644 --- a/test/fixtures/context-budget.json +++ b/test/fixtures/context-budget.json @@ -1,67 +1,67 @@ { "_comment": "Context-budget ratchet ceilings (~tokens). Regenerate: bun test/helpers/capture-context-budget.ts. Headroom: alwaysOnTotal x1.05, eagerPerInvocation x1.1. Graded by test/context-budget-ratchet.test.ts via lib/context-bill.ts checkBudget.", - "alwaysOnTotal": 7273, + "alwaysOnTotal": 7283, "eagerPerInvocation": { - "autoplan": 16511, - "benchmark": 7701, - "benchmark-models": 3825, - "browse": 8166, + "autoplan": 16899, + "benchmark": 7850, + "benchmark-models": 4231, + "browse": 8962, "browser-skills/hackernews-frontpage": 371, - "canary": 13356, + "canary": 13522, "careful": 1328, - "codex": 15204, - "context-restore": 10531, - "context-save": 10376, + "codex": 15599, + "context-restore": 10996, + "context-save": 10589, "cso": 4702, - "design-consultation": 15726, - "design-html": 14387, - "design-review": 34744, - "design-shotgun": 14419, + "design-consultation": 16273, + "design-html": 14556, + "design-review": 35821, + "design-shotgun": 14981, "deslop-shared-libs": 3448, - "devex-review": 19362, - "diagram": 4271, - "document-generate": 11696, - "document-release": 10059, + "devex-review": 20206, + "diagram": 4336, + "document-generate": 11810, + "document-release": 10174, "freeze": 1194, - "gstack": 4151, + "gstack": 4267, "gstack-upgrade": 5793, "guard": 1082, - "health": 11408, - "investigate": 12130, - "ios-clean": 8167, - "ios-design-review": 8364, - "ios-fix": 8056, - "ios-qa": 10874, - "ios-sync": 8182, - "land-and-deploy": 18839, - "landing-report": 8879, - "learn": 8595, - "make-pdf": 5283, - "office-hours": 23436, - "open-gstack-browser": 4862, + "health": 11523, + "investigate": 12584, + "ios-clean": 8282, + "ios-design-review": 8478, + "ios-fix": 8171, + "ios-qa": 11744, + "ios-sync": 8297, + "land-and-deploy": 19005, + "landing-report": 8994, + "learn": 8709, + "make-pdf": 5348, + "office-hours": 24915, + "open-gstack-browser": 4928, "openclaw/skills/gstack-openclaw-ceo-review": 2764, "openclaw/skills/gstack-openclaw-investigate": 1429, "openclaw/skills/gstack-openclaw-office-hours": 4433, "openclaw/skills/gstack-openclaw-retro": 2542, - "pair-agent": 10990, - "plan-ceo-review": 20421, - "plan-design-review": 21019, - "plan-devex-review": 17116, - "plan-eng-review": 12912, - "plan-tune": 14585, - "qa": 13281, - "qa-only": 11348, - "retro": 18694, - "review": 19317, - "scrape": 6901, - "setup-browser-cookies": 3510, - "setup-deploy": 11219, - "setup-gbrain": 15279, - "ship": 20459, - "skillify": 11535, - "spec": 14423, - "sync-gbrain": 14937, - "test-audit": 10138, + "pair-agent": 11104, + "plan-ceo-review": 20885, + "plan-design-review": 22326, + "plan-devex-review": 17600, + "plan-eng-review": 13484, + "plan-tune": 14775, + "qa": 13498, + "qa-only": 11545, + "retro": 19034, + "review": 19687, + "scrape": 7355, + "setup-browser-cookies": 3575, + "setup-deploy": 11415, + "setup-gbrain": 15697, + "ship": 20654, + "skillify": 11649, + "spec": 14923, + "sync-gbrain": 15478, + "test-audit": 10335, "unfreeze": 457 } } diff --git a/test/fixtures/golden/agy-ship-SKILL.md b/test/fixtures/golden/agy-ship-SKILL.md index 94e8f465b..af76bf6f4 100644 --- a/test/fixtures/golden/agy-ship-SKILL.md +++ b/test/fixtures/golden/agy-ship-SKILL.md @@ -254,9 +254,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -327,7 +331,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/test/fixtures/golden/claude-ship-SKILL.md b/test/fixtures/golden/claude-ship-SKILL.md index 7682d6c38..e97d1105c 100644 --- a/test/fixtures/golden/claude-ship-SKILL.md +++ b/test/fixtures/golden/claude-ship-SKILL.md @@ -269,9 +269,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -336,7 +340,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/test/fixtures/golden/codex-ship-SKILL.md b/test/fixtures/golden/codex-ship-SKILL.md index aed4db7ba..f6dd9c336 100644 --- a/test/fixtures/golden/codex-ship-SKILL.md +++ b/test/fixtures/golden/codex-ship-SKILL.md @@ -274,9 +274,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -347,7 +351,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/test/fixtures/golden/factory-ship-SKILL.md b/test/fixtures/golden/factory-ship-SKILL.md index 2ffa52e7d..ff84fd7ec 100644 --- a/test/fixtures/golden/factory-ship-SKILL.md +++ b/test/fixtures/golden/factory-ship-SKILL.md @@ -255,9 +255,13 @@ When options differ in coverage, include `Completeness: X/10` (10 = all edge cas For high-stakes ambiguity (architecture, data model, destructive scope, missing context), STOP. Name it in one sentence, present 2-3 options with tradeoffs, and ask. Do not use for routine coding or obvious changes. -## Claimed Limitations Need Evidence +## Claims Need Evidence -A claimed limitation or requirement ("the API can't do this", "X requires a credential", "that's impossible on this platform") is a material claim. State one only with the verbatim error, the documented statement, or a live probe in hand — pattern-matching a failure to a familiar story is not evidence. When a cheap probe settles the question, run it BEFORE asking the user anything or declaring a step blocked. +- A claimed limitation ("the API can't", "X needs a credential") needs the verbatim error, documented statement or live probe; probe before asking or blocking. +- A claimed execution ran and you saw its result: name the command and the revision or content fingerprint; never cite a command whose stderr was silenced. +- State the evidence kind (static read, unit test, fixture/replay, live run, production) and never pass one off as another: a mock is not a live check. Reuse rules: Step 16. +- Disclose any failure or missing coverage that would change the reader's conclusion; "done, unverified" is not "done". +- A checked null result ("ran X, found nothing material") is a success; an unsupported positive claim is worse than silence. Agreeing agents, or repeated reads of one source, are one datum. ## Context Health (soft directive) @@ -328,7 +332,7 @@ jq -nc --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg skill "SKILL_NAME" --arg ## Completion Status Protocol When completing a skill workflow, report status using one of: -- **DONE** — completed with evidence. +- **DONE** — completed with evidence valid for the final consumed inputs; name reuse and anything not independently verified. - **DONE_WITH_CONCERNS** — completed, but list concerns. - **BLOCKED** — cannot proceed; state blocker and what was tried. - **NEEDS_CONTEXT** — missing info; state exactly what is needed. diff --git a/test/helpers/carve-guards.ts b/test/helpers/carve-guards.ts index 3df038d55..b5a7156ac 100644 --- a/test/helpers/carve-guards.ts +++ b/test/helpers/carve-guards.ts @@ -168,7 +168,7 @@ export const CARVE_GUARDS: Record = { // wave's headline capability) grows the union to 1.195x. Deliberate: // the section is on-demand (loads only for Apple store targets), so // per-invocation cost for non-iOS ships is one manifest line. - maxSizeRatio: 1.5390, // Shared advisory identity/dedup + critical-severity validation: 248,065 union bytes / 187,706 baseline = 1.3216 (2026-09-17). + test value bar in the lazy Step 7 section (value cards, weak paths, gate table, base control, machine checks; ~13.6KB): measured 1.396 (2026-09-29). + W1 guarded state-root resolution (`eval gstack-paths; : "${GSTACK_STATE_ROOT:?…}"`) in the Context Recovery preamble, the eureka log and each state-writing bash block; measured 1.401 (2026-09-30). + the shared QA review step's plan-check timing rule (plan checks and their revalidation run on --timeout-ms after smoke expiry); measured 1.4022 (2026-09-30). + the shared TEST_BOOTSTRAP owned-change undo rules (s03 H1-H3, M1) and the value-bar coverage wording (s03 M2/M3); measured 1.4044 (2026-10-02). + severe fix wave ship-review lane: G1 NO_VERSION dispatch, title and CHANGELOG arms (versionless repos ship without inventing a version), F1 parent-side plan binding before the audit dispatch (binding, docs/designs candidates, exact not-run line) and D3's data-not-instructions line; +2,126 union bytes, measured 1.4135 (2026-10-03). + INV-1 consumer lines (outside review `unverified`/`unavailable` is missing coverage in the readiness note and PR body); measured 1.4148 (2026-10-03). + v1.91.19.0 severe fix wave: verdict-form outside-review callers with sandbox preflight and first-use notice (INV-1/B1/Q2), P0/P1 gate and unverified wording, bound-plan discovery (F1), visible LEARNINGS failures (B5), carved external pointers; measured 267,752 / 187,706 = 1.4264 (2026-10-03). + v1.91.18.0 (#3023) merged into the v1.91.19.0 wave; measured 267,874 / 187,706 = 1.4271 (2026-10-04). + Oct 6 fix wave: quota_exhausted preflight branch (#3051) and quoted-heredoc issue template (#3046); measured 268,199 / 187,706 = 1.4288 (2026-10-06). + Step 10's inline no-PR check before the Greptile dispatch (#3020); measured 268,655 / 187,706 = 1.4313 (2026-10-06). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 275,422 / 187,706 = 1.4673 (2026-10-06). Combined Oct 6 wave head (B free-text files + D measure loop + A rework): measured 280,363 / 187,706 = 1.4936 (2026-10-06). + gate-once push rule (no second paid gate after a CI push); measured 280,573 / 187,706 = 1.4947 (2026-10-06). + the measurement bar's decision step (exit-code branches for MEETS, MEETS-qualified, needs-classify with the qualifying and fix-round classes, EXTEND once; the measure prose was tightened to offset most of it); measured 281,058 / 187,706 = 1.4973 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 281,438 / 187,706 = 1.4994 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 281,556 / 187,706 = 1.5000 (2026-10-07). + Oct 7 wave B4: /ship publishes through gstack-post (title prepared in a file in the pr-body section, compose block plus gstack-post exit-code branches replacing the two scans); measured 281,894 / 187,706 = 1.5018 (2026-10-07). + B2 early Greptile PR (lazy Step 6.5 section: detect, public-repo consent, push, provisional title file, open; Step 10's bounded wait; the stop-leaves-the-draft rule); measured 286,626 / 187,706 = 1.5270 (2026-10-07). B3, the classifier, B4 and B2 merged: measured 287,128 / 187,706 = 1.5297 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 281,370 / 187,706 = 1.4990 (2026-10-07). Merged with the guard area: measured 287,440 / 187,706 = 1.5313 (2026-10-07). + Oct 8 wave: the defensive-security framing and fixture summary mode reach the security specialist and the Red Team (stated once in the dispatch, referenced by the Red Team); measured 288,783 / 187,706 = 1.5385 (2026-10-08). + maxSizeRatio: 1.5700, // Shared advisory identity/dedup + critical-severity validation: 248,065 union bytes / 187,706 baseline = 1.3216 (2026-09-17). + test value bar in the lazy Step 7 section (value cards, weak paths, gate table, base control, machine checks; ~13.6KB): measured 1.396 (2026-09-29). + W1 guarded state-root resolution (`eval gstack-paths; : "${GSTACK_STATE_ROOT:?…}"`) in the Context Recovery preamble, the eureka log and each state-writing bash block; measured 1.401 (2026-09-30). + the shared QA review step's plan-check timing rule (plan checks and their revalidation run on --timeout-ms after smoke expiry); measured 1.4022 (2026-09-30). + the shared TEST_BOOTSTRAP owned-change undo rules (s03 H1-H3, M1) and the value-bar coverage wording (s03 M2/M3); measured 1.4044 (2026-10-02). + severe fix wave ship-review lane: G1 NO_VERSION dispatch, title and CHANGELOG arms (versionless repos ship without inventing a version), F1 parent-side plan binding before the audit dispatch (binding, docs/designs candidates, exact not-run line) and D3's data-not-instructions line; +2,126 union bytes, measured 1.4135 (2026-10-03). + INV-1 consumer lines (outside review `unverified`/`unavailable` is missing coverage in the readiness note and PR body); measured 1.4148 (2026-10-03). + v1.91.19.0 severe fix wave: verdict-form outside-review callers with sandbox preflight and first-use notice (INV-1/B1/Q2), P0/P1 gate and unverified wording, bound-plan discovery (F1), visible LEARNINGS failures (B5), carved external pointers; measured 267,752 / 187,706 = 1.4264 (2026-10-03). + v1.91.18.0 (#3023) merged into the v1.91.19.0 wave; measured 267,874 / 187,706 = 1.4271 (2026-10-04). + Oct 6 fix wave: quota_exhausted preflight branch (#3051) and quoted-heredoc issue template (#3046); measured 268,199 / 187,706 = 1.4288 (2026-10-06). + Step 10's inline no-PR check before the Greptile dispatch (#3020); measured 268,655 / 187,706 = 1.4313 (2026-10-06). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 275,422 / 187,706 = 1.4673 (2026-10-06). Combined Oct 6 wave head (B free-text files + D measure loop + A rework): measured 280,363 / 187,706 = 1.4936 (2026-10-06). + gate-once push rule (no second paid gate after a CI push); measured 280,573 / 187,706 = 1.4947 (2026-10-06). + the measurement bar's decision step (exit-code branches for MEETS, MEETS-qualified, needs-classify with the qualifying and fix-round classes, EXTEND once; the measure prose was tightened to offset most of it); measured 281,058 / 187,706 = 1.4973 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 281,438 / 187,706 = 1.4994 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 281,556 / 187,706 = 1.5000 (2026-10-07). + Oct 7 wave B4: /ship publishes through gstack-post (title prepared in a file in the pr-body section, compose block plus gstack-post exit-code branches replacing the two scans); measured 281,894 / 187,706 = 1.5018 (2026-10-07). + B2 early Greptile PR (lazy Step 6.5 section: detect, public-repo consent, push, provisional title file, open; Step 10's bounded wait; the stop-leaves-the-draft rule); measured 286,626 / 187,706 = 1.5270 (2026-10-07). B3, the classifier, B4 and B2 merged: measured 287,128 / 187,706 = 1.5297 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 281,370 / 187,706 = 1.4990 (2026-10-07). Merged with the guard area: measured 287,440 / 187,706 = 1.5313 (2026-10-07). + Oct 8 wave: the defensive-security framing and fixture summary mode reach the security specialist and the Red Team (stated once in the dispatch, referenced by the Red Team); measured 288,783 / 187,706 = 1.5385 (2026-10-08). + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); plus Step 7's implementer dispatch rules and Step 8's parent-computed ACCEPTANCE_EDITED check (W5/W7); measured 294,075 / 187,706 = 1.5667 (2026-10-10). }, 'plan-ceo-review': { skill: 'plan-ceo-review', @@ -245,7 +245,7 @@ export const CARVE_GUARDS: Record = { // tier-2+ skeleton (measured 89,184). Main's v1.64.0.0 adds ~340 B more // (telemetry --error-message/--failed-step preamble prose, PR #769). // Budget covers the sum of both waves. - maxSkeletonBytes: 85_000, // Harness-aware outside voice: validated dispatch and provenance. + v1.91.19.0 wave: design --version probe (B4) and verdict-form outside voice (INV-1) on top of v1.91.17.0's round accounting (#3022); measured 80,443 (2026-10-03). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); skeleton measured 84,669 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; skeleton measured 84,804 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; skeleton measured 84,863 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; skeleton measured 84,748 (2026-10-07). Merged with the guard area: measured skeleton 84,945 (2026-10-07). + maxSkeletonBytes: 85_600, // Harness-aware outside voice: validated dispatch and provenance. + v1.91.19.0 wave: design --version probe (B4) and verdict-form outside voice (INV-1) on top of v1.91.17.0's round accounting (#3022); measured 80,443 (2026-10-03). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); skeleton measured 84,669 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; skeleton measured 84,804 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; skeleton measured 84,863 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; skeleton measured 84,748 (2026-10-07). Merged with the guard area: measured skeleton 84,945 (2026-10-07). + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); skeleton measured 85,446 (2026-10-10). minUnionBytes: 99_200, // token-reduction Phases 1-2 (v1.69.x branch); measured union 110,293 mustContain: ['design', 'visual'], maxSizeRatio: 1.12, // D1 1.104 + main's ~0.008 @@ -350,10 +350,10 @@ do not launch the downstream skill or open a browser.`, // the #538 opt-out + D1 evidence directive — ratio 1.104 measured. // #2499 project-scope MCP jq in the brain-sync block grew every tier-2+ // skeleton ~1.5KB (entry resolution emitted once per SKILL.md). - maxSkeletonBytes: 94_900, // Office-hours + sketch outside voices include host guards and completion checks. + v1.91.19.0 wave: Q open-question prose form (#2729, approved Q3), DESIGN_READY --version probe (B4), Aside ~/.local/bin fallback (E7), verdict-form outside voice (INV-1), plus v1.91.17.0's round accounting (#3022) merged in; measured 89,684 (2026-10-03). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); skeleton measured 92,590 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; skeleton measured 92,869 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; skeleton measured 92,930 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; skeleton measured 92,756 (2026-10-07). Merged with the guard area: measured skeleton 93,099 (2026-10-07). + fix wave PR D: the Phase 4.5 builder-profile read before the session log (#2801) and the pre-telemetry design-doc check (#1049); measured skeleton 94,877 (2026-10-07). + maxSkeletonBytes: 95_500, // Office-hours + sketch outside voices include host guards and completion checks. + v1.91.19.0 wave: Q open-question prose form (#2729, approved Q3), DESIGN_READY --version probe (B4), Aside ~/.local/bin fallback (E7), verdict-form outside voice (INV-1), plus v1.91.17.0's round accounting (#3022) merged in; measured 89,684 (2026-10-03). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); skeleton measured 92,590 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; skeleton measured 92,869 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; skeleton measured 92,930 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; skeleton measured 92,756 (2026-10-07). Merged with the guard area: measured skeleton 93,099 (2026-10-07). + fix wave PR D: the Phase 4.5 builder-profile read before the session log (#2801) and the pre-telemetry design-doc check (#1049); measured skeleton 94,877 (2026-10-07). + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); skeleton measured 95,354 (2026-10-10). minUnionBytes: 115_800, // Phase 4 wave 4; measured union 118,175 mustContain: ['design doc', 'problem statement'], - maxSizeRatio: 1.1710, // + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 149,758 / 131,110 = 1.1422 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 150,037 / 131,110 = 1.1444 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 150,098 / 131,110 = 1.1448 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 150,011 / 131,110 = 1.1442 (2026-10-07). Merged with the guard area: measured 150,354 / 131,110 = 1.1468 (2026-10-07). + fix wave PR D: builder-profile read before the session log with Phase 6 using the carried values (#2801), the inline design doc before approval (#879) and the pre-telemetry design-doc check (#1049); measured 153,206 / 131,110 = 1.1685 (2026-10-07). + empty LAST_ASSIGNMENT/LAST_PROJECT guards in the welcome_back and regular greetings (backfilled profiles); measured 153,469 / 131,110 = 1.1705 (2026-10-08). + maxSizeRatio: 1.1760, // + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 149,758 / 131,110 = 1.1422 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 150,037 / 131,110 = 1.1444 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 150,098 / 131,110 = 1.1448 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 150,011 / 131,110 = 1.1442 (2026-10-07). Merged with the guard area: measured 150,354 / 131,110 = 1.1468 (2026-10-07). + fix wave PR D: builder-profile read before the session log with Phase 6 using the carried values (#2801), the inline design doc before approval (#879) and the pre-telemetry design-doc check (#1049); measured 153,206 / 131,110 = 1.1685 (2026-10-07). + empty LAST_ASSIGNMENT/LAST_PROJECT guards in the welcome_back and regular greetings (backfilled profiles); measured 153,469 / 131,110 = 1.1705 (2026-10-08). + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); measured 153,946 / 131,110 = 1.1742 (2026-10-10). }, 'document-release': { skill: 'document-release', @@ -413,7 +413,7 @@ do not launch the downstream skill or open a browser.`, // eureka log, the office-hours lookup and the taste-profile read; measured // 1.0834 (2026-09-30). + named design-direction defaults to avoid in the native // subagent prompt (s02 H4a); measured 1.0911 (2026-10-02). - maxSizeRatio: 1.1490, // + v1.91.19.0 wave: design --version probe (B4), taste-profile load (F3), verdict-form outside voice (INV-1), plus v1.91.17.0's round accounting and board/approval blocks (#3022) merged in; measured 100,446 / 90,375 = 1.1114 (2026-10-03). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 103,384 / 90,375 = 1.1439 (2026-10-06). + Oct 7 wave B6: Aside rules 1, 4, 6 and 7 (offer a target-origin tab before openTab, a second sign-in wall means a tab- or URL-bound session, no early-return hint, fast [ok without the sentinel is an abort); measured 103,576 / 90,375 = 1.1461 (2026-10-07). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 103,522 / 90,375 = 1.1455 (2026-10-07). Both merged: measured 103,726 / 90,375 = 1.1477 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 103,466 / 90,375 = 1.1449 (2026-10-07). Merged with the guard area: measured 103,804 / 90,375 = 1.1486 (2026-10-07). + maxSizeRatio: 1.1560, // + v1.91.19.0 wave: design --version probe (B4), taste-profile load (F3), verdict-form outside voice (INV-1), plus v1.91.17.0's round accounting and board/approval blocks (#3022) merged in; measured 100,446 / 90,375 = 1.1114 (2026-10-03). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 103,384 / 90,375 = 1.1439 (2026-10-06). + Oct 7 wave B6: Aside rules 1, 4, 6 and 7 (offer a target-origin tab before openTab, a second sign-in wall means a tab- or URL-bound session, no early-return hint, fast [ok without the sentinel is an abort); measured 103,576 / 90,375 = 1.1461 (2026-10-07). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 103,522 / 90,375 = 1.1455 (2026-10-07). Both merged: measured 103,726 / 90,375 = 1.1477 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 103,466 / 90,375 = 1.1449 (2026-10-07). Merged with the guard area: measured 103,804 / 90,375 = 1.1486 (2026-10-07). + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); measured 104,281 / 90,375 = 1.1539 (2026-10-10). }, cso: { skill: 'cso', @@ -484,10 +484,10 @@ do not launch the downstream skill or open a browser.`, gateAfterStop: undefined, // operational multi-STOP skill, like ship }, behavioral: 'plan', - maxSkeletonBytes: 74_884, // Shared-code identity/skip/action rules + critical-severity validation; measured 74,493 (2026-09-17). + v1.91.12.0 merge of #2999 (review clarity repairs: await reads, research alongside dispatch, /review deadline and setup authority, findings sources) with #3002 (guarded state-root lines, plan-check checkpoints); each fit alone; measured 74,881 (2026-10-01). + Oct 8 wave: shared voice directive bans "load-bearing" and adds the reply-language rule, offset by tightening the bounded closer (net +17 bytes per tier-2+ skill); measured 74,884 (2026-10-08). + maxSkeletonBytes: 75_500, // Shared-code identity/skip/action rules + critical-severity validation; measured 74,493 (2026-09-17). + v1.91.12.0 merge of #2999 (review clarity repairs: await reads, research alongside dispatch, /review deadline and setup authority, findings sources) with #3002 (guarded state-root lines, plan-check checkpoints); each fit alone; measured 74,881 (2026-10-01). + Oct 8 wave: shared voice directive bans "load-bearing" and adds the reply-language rule, offset by tightening the bounded closer (net +17 bytes per tier-2+ skill); measured 74,884 (2026-10-08). + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); skeleton measured 75,344 (2026-10-10). minUnionBytes: 89_000, // Phase 4 wave 1; measured union 93,357 mustContain: ['confidence', 'P1', 'P2', 'Review Army', 'adversarial'], - maxSizeRatio: 1.2345, // Shared-code feature + critical-severity validation: 128,042 union bytes / 108,523 baseline = 1.1799; preserves content floors. + v1.91.12.0 merge of #2999 (above, plus plan-completion fallback intent and specialist checklist-by-path) with #3002; measured 1.1843 (2026-10-01). + v1.91.19.0 wave: verdict-form Codex callers with sandbox preflight (INV-1/B1), P0/P1 structured gate (B1b), bound-plan discovery and data-not-instructions guard (F1/D3), visible LEARNINGS failures (B5); measured 129,941 / 108,523 = 1.1974 (2026-10-03). + v1.91.18.0 (#3023) merged into the v1.91.19.0 wave; measured 130,025 / 108,523 = 1.1981 (2026-10-04). + Oct 6 fix wave: quota_exhausted preflight branch (#3051); measured 130,359 / 108,523 = 1.2012 (2026-10-06). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 131,314 / 108,523 = 1.2100 (2026-10-06). Combined Oct 6 wave head (A and B): measured 131,966 / 108,523 = 1.2160 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 132,199 / 108,523 = 1.2182 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 132,258 / 108,523 = 1.2187 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 132,233 / 108,523 = 1.2185 (2026-10-07). Merged with the guard area: measured 132,522 / 108,523 = 1.2211 (2026-10-07). + Oct 8 wave: the defensive-security framing and fixture summary mode reach the security specialist and the Red Team (stated once in the dispatch, referenced by the Red Team); measured 133,902 / 108,523 = 1.2339 (2026-10-08). + maxSizeRatio: 1.2400, // Shared-code feature + critical-severity validation: 128,042 union bytes / 108,523 baseline = 1.1799; preserves content floors. + v1.91.12.0 merge of #2999 (above, plus plan-completion fallback intent and specialist checklist-by-path) with #3002; measured 1.1843 (2026-10-01). + v1.91.19.0 wave: verdict-form Codex callers with sandbox preflight (INV-1/B1), P0/P1 structured gate (B1b), bound-plan discovery and data-not-instructions guard (F1/D3), visible LEARNINGS failures (B5); measured 129,941 / 108,523 = 1.1974 (2026-10-03). + v1.91.18.0 (#3023) merged into the v1.91.19.0 wave; measured 130,025 / 108,523 = 1.1981 (2026-10-04). + Oct 6 fix wave: quota_exhausted preflight branch (#3051); measured 130,359 / 108,523 = 1.2012 (2026-10-06). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 131,314 / 108,523 = 1.2100 (2026-10-06). Combined Oct 6 wave head (A and B): measured 131,966 / 108,523 = 1.2160 (2026-10-06). + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 132,199 / 108,523 = 1.2182 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 132,258 / 108,523 = 1.2187 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site; measured 132,233 / 108,523 = 1.2185 (2026-10-07). Merged with the guard area: measured 132,522 / 108,523 = 1.2211 (2026-10-07). + Oct 8 wave: the defensive-security framing and fixture summary mode reach the security specialist and the Red Team (stated once in the dispatch, referenced by the Red Team); measured 133,902 / 108,523 = 1.2339 (2026-10-08). + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); measured 134,383 / 108,523 = 1.2383 (2026-10-10). }, codex: { skill: 'codex', @@ -512,7 +512,7 @@ do not launch the downstream skill or open a browser.`, gateAfterStop: 'EXIT PLAN MODE GATE', }, behavioral: 'prompt', - maxSkeletonBytes: 59_350, // + v1.78 AUQ spawned-trigger objectivity; generated Codex overlay measured 59,307 + maxSkeletonBytes: 59_850, // + v1.78 AUQ spawned-trigger objectivity; generated Codex overlay measured 59,307 + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); skeleton measured 59,700 (2026-10-10). minUnionBytes: 83_400, // Phase 4 wave 1; measured union 84,304 mustContain: ['GATE: PASS', 'CROSS-MODEL ANALYSIS', 'codex exec resume', 'sandbox_mode="read-only"', 'mktemp'], maxSizeRatio: 1.06, // measured 1.040 vs the v1.64.1.0 parity baseline @@ -539,7 +539,7 @@ do not launch the downstream skill or open a browser.`, }, behavioral: 'prompt', maxSkeletonBytes: 74_500, // + Aside browser contract for Step 7 canary ({{ASIDE_SETUP}}); measured 73_523 - maxSizeRatio: 1.102, // + v1.81 Aside contract + gstack-browser fallback block; measured 1.077. + both untrusted-content marker formats in the browser fallback (W7f) + the readiness gate's project test command and live eval-store paths (s06 H6/H7); measured 1.1076 (2026-10-02). Re-measured 1.0943 (2026-10-03); cap = measured + 0.005 headroom. + Oct 7 wave B6: Aside rules 1, 4, 6 and 7 (offer a target-origin tab before openTab, a second sign-in wall means a tab- or URL-bound session, no early-return hint, fast [ok without the sentinel is an abort); measured 115,226 / 104,578 = 1.1018 (2026-10-07). + maxSizeRatio: 1.1080, // + v1.81 Aside contract + gstack-browser fallback block; measured 1.077. + both untrusted-content marker formats in the browser fallback (W7f) + the readiness gate's project test command and live eval-store paths (s06 H6/H7); measured 1.1076 (2026-10-02). Re-measured 1.0943 (2026-10-03); cap = measured + 0.005 headroom. + Oct 7 wave B6: Aside rules 1, 4, 6 and 7 (offer a target-origin tab before openTab, a second sign-in wall means a tab- or URL-bound session, no early-return hint, fast [ok without the sentinel is an abort); measured 115,226 / 104,578 = 1.1018 (2026-10-07). + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); measured 115,697 / 104,578 = 1.1063 (2026-10-10). minUnionBytes: 91_000, // Phase 4 wave 1; estimated union ~94.9KB mustContain: ['readiness', 'merge', 'canary', 'revert', 'staging'], }, @@ -577,7 +577,7 @@ do not launch the downstream skill or open a browser.`, maxSkeletonBytes: 70_000, // Phase-specific outside coverage, native fallback, and harness guard. minUnionBytes: 85_000, // measured union 86,926 mustContain: ['6 Decision Principles', 'TASTE DECISION', 'USER CHALLENGE', 'consensus', 'Restore Point'], - maxSizeRatio: 1.1305, // Four validated outside invocations replace raw CLI calls; phases keep independent coverage. + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 114,297 / 101,979 = 1.1208 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 114,533 / 101,979 = 1.1231 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site, and phase-close publishing each report with the `true autoplan-published ` no-op before the next phase entry in a later message (CEO-1); measured 114,320 / 101,979 = 1.1210 (2026-10-07). Merged with the guard area: measured 115,149 / 101,979 = 1.1291 (2026-10-07). + Oct 8 wave (permission cards after a background reviewer): Step 1 puts RESTORE_PATH, and so every phase artifact, in the project's git-excluded `.gstack/tmp/autoplan/`, which Claude Code reads without a card after the skill turn ends; measured 115,270 / 101,979 = 1.1303 (2026-10-08). + fix wave PR D: the prerequisite offer is skipped in spawned/headless sessions (#1958); measured 115,267 / 101,979 = 1.1303 (2026-10-07). Both merged: measured 115,126 / 101,979 = 1.1289 (2026-10-08). + maxSizeRatio: 1.1355, // Four validated outside invocations replace raw CLI calls; phases keep independent coverage. + Oct 7 wave B3: the Codex probe runs as a command (select-model capture lines, check-sandbox/probe-model/run-with-timeout subcommands) instead of being sourced; measured 114,297 / 101,979 = 1.1208 (2026-10-07). + Oct 7 wave CEO-28/DX-11: review prompts ask for a severity per finding and design proposals use the proposal gate; measured 114,533 / 101,979 = 1.1231 (2026-10-07). + Oct 7 wave guard (CEO-20): conditional `run_in_background` request plus the background-run recovery at each foreground dispatch site, and phase-close publishing each report with the `true autoplan-published ` no-op before the next phase entry in a later message (CEO-1); measured 114,320 / 101,979 = 1.1210 (2026-10-07). Merged with the guard area: measured 115,149 / 101,979 = 1.1291 (2026-10-07). + Oct 8 wave (permission cards after a background reviewer): Step 1 puts RESTORE_PATH, and so every phase artifact, in the project's git-excluded `.gstack/tmp/autoplan/`, which Claude Code reads without a card after the skill turn ends; measured 115,270 / 101,979 = 1.1303 (2026-10-08). + fix wave PR D: the prerequisite offer is skipped in spawned/headless sessions (#1958); measured 115,267 / 101,979 = 1.1303 (2026-10-07). Both merged: measured 115,126 / 101,979 = 1.1289 (2026-10-08). + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); measured 115,603 / 101,979 = 1.1336 (2026-10-10). }, spec: { skill: 'spec', @@ -670,7 +670,7 @@ do not launch the downstream skill or open a browser.`, }, behavioral: 'prompt', maxSkeletonBytes: 63_500, // + v2.0 {{ASIDE_SETUP}}/{{BROWSE_FALLBACK}} (replaces the browse setup block); measured 61_253 - maxSizeRatio: 1.1272, // + v1.81 Aside contract + gstack-browser fallback block (1.080 on v1.91.7.0) + the shared test value bar at 8a.5 ({{TEST_VALUE_BAR:qa}}); measured 1.094 + W1 guarded state-root resolution (`eval gstack-paths; : "${GSTACK_STATE_ROOT:?…}"`) in the Context Recovery preamble, the eureka log and each state-writing bash block; measured 1.101 (2026-09-30) + v1.91.12.0 merge of #2999 (await scope/method Reads, capture --after checkpoints, browser-only empty evidence list) with #3002; measured 1.1028 (2026-10-01). + both untrusted-content marker formats in the browser fallback (W7f); measured 1.1035 (2026-10-02). Re-measured 1.1038 after the W8 probe-loop renames (2026-10-03); the cap already matches. + the annotate-every-capture and superseded rule before materialize (a ship-exploratory-late-input run published evidence that omitted older-snapshot captures); measured 1.1064 (2026-10-03). + v1.91.18.0 (#3023) merged into the v1.91.19.0 wave; measured 93,282 / 84,049 = 1.1099 (2026-10-04). + reliability follow-ups C2 (judge-named gaps after trimming the added wording: feasible 180 s Browser Quick, PROBE_DIR's source line, stop goes to the §4 report, written JSON keeps full card values; lane S's {user}/timing fields); measured 93,311 / 84,049 = 1.11020 (2026-10-04). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 94,486 / 84,049 = 1.1242 (2026-10-06). + Oct 7 wave B6: Aside rules 1, 4, 6 and 7 (offer a target-origin tab before openTab, a second sign-in wall means a tab- or URL-bound session, no early-return hint, fast [ok without the sentinel is an abort); measured 94,681 / 84,049 = 1.1265 (2026-10-07). + Oct 8 wave: shared voice directive bans "load-bearing" and adds the reply-language rule, offset by tightening the bounded closer (net +17 bytes per tier-2+ skill); measured 94,736 / 84,049 = 1.12715 (2026-10-08). + maxSizeRatio: 1.1385, // + v1.81 Aside contract + gstack-browser fallback block (1.080 on v1.91.7.0) + the shared test value bar at 8a.5 ({{TEST_VALUE_BAR:qa}}); measured 1.094 + W1 guarded state-root resolution (`eval gstack-paths; : "${GSTACK_STATE_ROOT:?…}"`) in the Context Recovery preamble, the eureka log and each state-writing bash block; measured 1.101 (2026-09-30) + v1.91.12.0 merge of #2999 (await scope/method Reads, capture --after checkpoints, browser-only empty evidence list) with #3002; measured 1.1028 (2026-10-01). + both untrusted-content marker formats in the browser fallback (W7f); measured 1.1035 (2026-10-02). Re-measured 1.1038 after the W8 probe-loop renames (2026-10-03); the cap already matches. + the annotate-every-capture and superseded rule before materialize (a ship-exploratory-late-input run published evidence that omitted older-snapshot captures); measured 1.1064 (2026-10-03). + v1.91.18.0 (#3023) merged into the v1.91.19.0 wave; measured 93,282 / 84,049 = 1.1099 (2026-10-04). + reliability follow-ups C2 (judge-named gaps after trimming the added wording: feasible 180 s Browser Quick, PROBE_DIR's source line, stop goes to the §4 report, written JSON keeps full card values; lane S's {user}/timing fields); measured 93,311 / 84,049 = 1.11020 (2026-10-04). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); measured 94,486 / 84,049 = 1.1242 (2026-10-06). + Oct 7 wave B6: Aside rules 1, 4, 6 and 7 (offer a target-origin tab before openTab, a second sign-in wall means a tab- or URL-bound session, no early-return hint, fast [ok without the sentinel is an abort); measured 94,681 / 84,049 = 1.1265 (2026-10-07). + Oct 8 wave: shared voice directive bans "load-bearing" and adds the reply-language rule, offset by tightening the bounded closer (net +17 bytes per tier-2+ skill); measured 94,736 / 84,049 = 1.12715 (2026-10-08). + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); plus the no_claim card field in {{TEST_VALUE_BAR:qa}}; measured 95,512 / 84,049 = 1.1364 (2026-10-10). minUnionBytes: 69_500, // measured union 70,385 // 'aside repl' pins the Aside contract; '$B goto' pins the fallback block in the always-loaded skeleton. mustContain: ['bug', 'aside repl', '$B goto', 'fix', 'Health Score Rubric', 'regression'], @@ -707,7 +707,7 @@ do not launch the downstream skill or open a browser.`, gateAfterStop: undefined, }, behavioral: 'prompt', - maxSkeletonBytes: 34_210, // + v2.0 {{ASIDE_SETUP}}/{{BROWSE_FALLBACK}} skeleton + the STOP-Read pointer; measured 29_986 + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); skeleton measured 32,532 (2026-10-06). + Oct 7 wave B6: Aside rules 1, 4, 6 and 7 (offer a target-origin tab before openTab, a second sign-in wall means a tab- or URL-bound session, no early-return hint, fast [ok without the sentinel is an abort), and the cookbook's silent-failure list and signed-in-tab recipe (the rule details live here, not in every browsing skill); skeleton measured 34,047 (2026-10-07). + Oct 8 wave: the tier-1 voice directive bans "load-bearing" and adds the reply-language rule (tier 1 has no closer to tighten: +158 bytes); skeleton measured 34,209 (2026-10-08). + maxSkeletonBytes: 34_400, // + v2.0 {{ASIDE_SETUP}}/{{BROWSE_FALLBACK}} skeleton + the STOP-Read pointer; measured 29_986 + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); skeleton measured 32,532 (2026-10-06). + Oct 7 wave B6: Aside rules 1, 4, 6 and 7 (offer a target-origin tab before openTab, a second sign-in wall means a tab- or URL-bound session, no early-return hint, fast [ok without the sentinel is an abort), and the cookbook's silent-failure list and signed-in-tab recipe (the rule details live here, not in every browsing skill); skeleton measured 34,047 (2026-10-07). + Oct 8 wave: the tier-1 voice directive bans "load-bearing" and adds the reply-language rule (tier 1 has no closer to tighten: +158 bytes); skeleton measured 34,209 (2026-10-08). + Honest Work W4: the DONE line's final-consumed-inputs wording (tier 1 gets no kernel: +87 bytes); skeleton measured 34,297 (2026-10-10). minUnionBytes: 36_000, // skeleton + command-list section (14,240); measured union ~38.5 KB // 'BEGIN/END UNTRUSTED EXTERNAL' pins the untrusted-content warning in the // command reference; 'aside repl' pins the Aside contract in the skeleton. @@ -758,7 +758,7 @@ do not launch the downstream skill or open a browser.`, gateAfterStop: undefined, // operational skill, no plan-mode gate }, behavioral: 'prompt', - maxSkeletonBytes: 55_400, // measured 55,262 (2026-09-09): the detector install offer pointer + its sections-table row (the brief itself lives in sections/detector-install-offer.md); before that 54,545 for the review-cycle trust prose, the Slop Gate's Decisions-Log clause, and the blacklist header's override sentence + maxSkeletonBytes: 55_850, // measured 55,262 (2026-09-09): the detector install offer pointer + its sections-table row (the brief itself lives in sections/detector-install-offer.md); before that 54,545 for the review-cycle trust prose, the Slop Gate's Decisions-Log clause, and the blacklist header's override sentence + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); skeleton measured 55,709 (2026-10-10). minUnionBytes: 57_500, // Phase 4 wave 4; measured union 58,682 mustContain: ["Don't make me think", "Users scan, they don't read", 'The Goodwill Reservoir', 'PRETEXT API CHEATSHEET', 'Pattern 3: Text around obstacles'], }, @@ -785,7 +785,7 @@ do not launch the downstream skill or open a browser.`, gateAfterStop: undefined, }, behavioral: 'prompt', - maxSkeletonBytes: 56_900, // + v2.0 preamble growth (merged); measured 52_962 + v1.91.19.0 wave: design --version probe (B4) and taste profile (F3) on top of v1.91.17.0's claim-based staging and round accounting (#3022); measured 55,168 (2026-10-03). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); skeleton measured 56,880 (2026-10-06). + maxSkeletonBytes: 57_500, // + v2.0 preamble growth (merged); measured 52_962 + v1.91.19.0 wave: design --version probe (B4) and taste profile (F3) on top of v1.91.17.0's claim-based staging and round accounting (#3022); measured 55,168 (2026-10-03). + Oct 6 fix wave A3/CEO-12: free text reaches commands only through agent-written mktemp files (mktemp block, write rule, path rebuild and refusal at each posting, prompt and brief site); skeleton measured 56,880 (2026-10-06). + Honest Work W4: the preamble's Claims Need Evidence kernel (five bullets replacing the one-directive form, +~450 bytes per tier-2+ skill) and the DONE line's final-consumed-inputs wording (+~90 bytes per skill); skeleton measured 57,335 (2026-10-10). minUnionBytes: 53_200, // Phase 4 wave 4; measured union 54,290 mustContain: ["Don't make me think", "Users scan, they don't read", 'trunk test', '44px minimum'], }, diff --git a/test/honesty-kernel.test.ts b/test/honesty-kernel.test.ts new file mode 100644 index 000000000..2c805e1d9 --- /dev/null +++ b/test/honesty-kernel.test.ts @@ -0,0 +1,75 @@ +/** + * The preamble's Claims Need Evidence kernel (docs/designs/HONEST_WORK_GATE_INTEGRITY.md W4). + * + * Pins where the kernel renders (tiers 2–4, default and terse; never tier 1), + * its byte budget, and the machine-read markers each bullet carries; never the + * sentences (docs/test-value-bar.md). The behavior claim is carried by the + * selected prompt evals, not here. + */ +import { describe, expect, test } from 'bun:test'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { generatePreamble } from '../scripts/resolvers/preamble'; +import { + EVIDENCE_KERNEL_BULLETS, EVIDENCE_KERNEL_HEADING, KERNEL_MAX_BYTES, generateEvidenceDirective, +} from '../scripts/resolvers/preamble/generate-evidence-directive'; +import { generateCompletionStatus } from '../scripts/resolvers/preamble/generate-completion-status'; +import { HOST_PATHS, type TemplateContext } from '../scripts/resolvers/types'; +import { between, expectMentions, expectTokens } from './helpers/prompt-structure'; + +const ROOT = path.resolve(import.meta.dir, '..'); +const ctx = (tier: number, explainLevel?: 'default' | 'terse'): TemplateContext => ({ + skillName: 'ship', tmplPath: 'ship/SKILL.md.tmpl', host: 'claude', paths: HOST_PATHS.claude, preambleTier: tier, explainLevel, +} as TemplateContext); + +describe('Claims Need Evidence kernel', () => { + test('renders five bullets within the byte budget, with the reuse pointer and the stderr rule', () => { + const rendered = generateEvidenceDirective(); + expect(rendered.startsWith(`${EVIDENCE_KERNEL_HEADING}\n`)).toBe(true); + const bullets = rendered.split('\n').filter(line => line.startsWith('- ')); + expect(bullets).toHaveLength(5); + expect(EVIDENCE_KERNEL_BULLETS).toHaveLength(5); + expect(Buffer.byteLength(bullets.join('\n'), 'utf8')).toBeLessThanOrEqual(KERNEL_MAX_BYTES); + expectTokens(rendered, ['Reuse rules: Step 16', 'stderr', '"done, unverified"'], 'kernel'); + expectMentions(rendered, [ + ['limitation', 'verbatim error'], + ['execution', 'command', 'fingerprint'], + ['mock', 'live check'], + ['disclose', 'failure', 'conclusion'], + ['null result', 'success'], + ], 'kernel'); + expect(rendered).not.toContain('Claimed Limitations Need Evidence'); + }); + + test('composes for tiers 2–4 in default and terse builds, never for tier 1', () => { + for (const tier of [2, 3, 4]) { + for (const level of ['default', 'terse'] as const) { + const out = generatePreamble(ctx(tier, level)); + expect(out, `tier ${tier} ${level} lacks the kernel`).toContain(generateEvidenceDirective()); + expect(out.indexOf(EVIDENCE_KERNEL_HEADING)).toBeLessThan(out.indexOf('## Completion Status Protocol')); + } + } + for (const level of ['default', 'terse'] as const) { + expect(generatePreamble(ctx(1, level))).not.toContain(EVIDENCE_KERNEL_HEADING); + } + }); + + test('the DONE line binds evidence to the final consumed inputs and names reuse (every tier)', () => { + const status = between(generateCompletionStatus(ctx(1)), '## Completion Status Protocol', '## Operational Self-Improvement'); + const done = status.split('\n').find(line => line.startsWith('- **DONE**'))!; + expectTokens(done, ['**DONE**', 'final consumed inputs', 'reuse'], 'DONE line'); + expect(done).not.toBe('- **DONE** — completed with evidence.'); + for (const tier of [1, 2, 3, 4]) expect(generatePreamble(ctx(tier))).toContain(done); + }); + + test('generated SKILL.md files carry the kernel at tier 2+ and the old heading nowhere', () => { + const skills = fs.readdirSync(ROOT).filter(dir => fs.existsSync(path.join(ROOT, dir, 'SKILL.md.tmpl')) && fs.existsSync(path.join(ROOT, dir, 'SKILL.md'))); + expect(skills.length).toBeGreaterThan(20); + for (const skill of skills) { + const tier = Number(/preamble-tier:\s*(\d)/.exec(fs.readFileSync(path.join(ROOT, skill, 'SKILL.md.tmpl'), 'utf8'))?.[1]); + const rendered = fs.readFileSync(path.join(ROOT, skill, 'SKILL.md'), 'utf8'); + expect(rendered, `${skill} still carries the retired heading`).not.toContain('Claimed Limitations Need Evidence'); + if (tier >= 2) expect(rendered, `${skill} (tier ${tier}) lacks the kernel; run bun run gen:skill-docs`).toContain(EVIDENCE_KERNEL_HEADING); + } + }); +}); diff --git a/test/outside-voice-routing.test.ts b/test/outside-voice-routing.test.ts index c54f32a36..7b234f914 100644 --- a/test/outside-voice-routing.test.ts +++ b/test/outside-voice-routing.test.ts @@ -122,7 +122,7 @@ test('automatic workflow templates delegate reviewer commands to shared resolver for (const file of templateFiles(join(ROOT, skill))) { for (const line of shellLines(readFileSync(file, 'utf8'))) { // /spec's --execute worker implements the filed spec; it is not a reviewer. - if (file === join(ROOT, 'spec', 'sections', 'gate-and-file.md.tmpl') && line.trim() === 'cat "$ARCHIVE_PATH" | (cd "$SPAWN_PATH" && claude -p 2>&1) &') continue; + if (file === join(ROOT, 'spec', 'sections', 'gate-and-file.md.tmpl') && line.trim() === 'cat "$ARCHIVE_PATH" | (cd "$SPAWN_PATH" && GSTACK_SESSION_KIND=spawned claude -p 2>&1) &') continue; if (/\bcodex\s+(?:exec|review)\b|\bclaude\s+(?:-p|--print)\b|\bgstack-claude-code\s+--/.test(line)) { violations.push(`${file.slice(ROOT.length + 1)}: ${line.trim()}`); } diff --git a/test/ship-plan-completion-invariants.test.ts b/test/ship-plan-completion-invariants.test.ts index c0c55c483..f7c733fed 100644 --- a/test/ship-plan-completion-invariants.test.ts +++ b/test/ship-plan-completion-invariants.test.ts @@ -3,9 +3,9 @@ import * as fs from 'fs'; import * as path from 'path'; import * as os from 'node:os'; import { spawnSync } from 'node:child_process'; -import { generatePlanCompletionAuditReview, generatePlanCompletionAuditShip, generatePlanCompletionGateShip, generatePlanVerificationExec } from '../scripts/resolvers/plan-gates'; +import { ACCEPTANCE_EDITED, generatePlanCompletionAuditReview, generatePlanCompletionAuditShip, generatePlanCompletionGateShip, generatePlanVerificationExec } from '../scripts/resolvers/plan-gates'; import { HOST_PATHS } from '../scripts/resolvers/types'; -import { expectMentions } from './helpers/prompt-structure'; +import { between, expectAbsent, expectMentions, expectOrdered, expectTokens } from './helpers/prompt-structure'; const SHIP_DIR = path.join(__dirname, '..', 'ship'); @@ -337,3 +337,104 @@ describe('F1: plan binding, docs/designs candidates, exact not-run line', () => expect(md).toMatch(/not-run line, skip dispatch/); }); }); + +// RH-10 (docs/designs/HONEST_WORK_GATE_INTEGRITY.md W5): editing the plan's acceptance +// text is not progress. The parent diffs the acceptance-bearing sections of the +// working-tree plan against a baseline and reports ACCEPTANCE_EDITED beside the +// child's classes; the child's seven-field contract is untouched. +describe('ACCEPTANCE_EDITED: parent-computed acceptance-text drift', () => { + const ctx = { skillName: 'ship', tmplPath: 'ship/SKILL.md.tmpl', host: 'claude' as const, paths: HOST_PATHS.claude }; + const rendered = fs.readFileSync(path.join(SHIP_DIR, 'sections', 'plan-completion.md'), 'utf8'); + + test('the check renders through the :acceptance arg with the baseline order and the never-CHANGED rule', () => { + const text = generatePlanCompletionGateShip(ctx, ['acceptance']); + expect(text).toStartWith('### Acceptance edits (parent-computed)'); + expectOrdered(text, ['origin/', 'first commit on this', 'baseline unavailable'], 'baseline order'); + expectTokens(text, ['ACCEPTANCE_BASELINE: unavailable', `${ACCEPTANCE_EDITED}: none`, `${ACCEPTANCE_EDITED}: yes`, `[${ACCEPTANCE_EDITED}]`, 'Acceptance edits: baseline unavailable', '## Plan Completion'], 'acceptance check'); + expectMentions(text, [['never', 'fold', 'changed'], ['original obligation', 'audited'], ['same commit', 'introduced', 'invisible']], 'acceptance check'); + const gate = generatePlanCompletionGateShip(ctx); + expect(gate).toContain(`**${ACCEPTANCE_EDITED} items**`); + expectMentions(gate, [['never counted as changed']], 'gate'); + expect(gate).toContain('`Acceptance edits:` line'); + }); + + test('the template runs it in the parent after the child reports, before Gate Logic, outside the child prompt', () => { + const parent = between(rendered, '**Parent processing:**', '**Audit-failure fallback:**'); + expectOrdered(parent, ['1. Check the task', `\`${ACCEPTANCE_EDITED}\` beside the child's classes`, 'Apply Gate Logic below', '### Acceptance edits (parent-computed)'], 'parent processing'); + expect(rendered.indexOf('### Acceptance edits (parent-computed)')).toBeLessThan(rendered.indexOf('### Gate Logic')); + expectAbsent(between(rendered, '````text', '````\n\n**Parent processing:**'), [ACCEPTANCE_EDITED], 'child prompt'); + const contract = rendered.split('\n').find(line => line.startsWith('{"total_items":N,'))!; + expect(Object.keys(JSON.parse(contract.replace(/:N([,}])/g, ':0$1')))).toHaveLength(7); + }); + + function block(planPath: string): string { + return between(rendered, '### Acceptance edits (parent-computed)', '### Gate Logic').match(/```bash\n([\s\S]*?)```/)![1] + .replaceAll('', planPath).replaceAll('', 'main'); + } + + function repo() { + const tmp = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'acceptance-edited-'))); + const env = { ...process.env, GIT_CONFIG_GLOBAL: '/dev/null', GIT_CONFIG_NOSYSTEM: '1', GIT_AUTHOR_NAME: 't', GIT_AUTHOR_EMAIL: 't@t.invalid', GIT_COMMITTER_NAME: 't', GIT_COMMITTER_EMAIL: 't@t.invalid' }; + const git = (...args: string[]) => { + const r = spawnSync('git', args, { cwd: tmp, env, encoding: 'utf8', timeout: 30_000 }); + if (r.status !== 0) throw new Error(r.stderr); + return r.stdout.trim(); + }; + const run = (planPath: string) => spawnSync('bash', ['-c', block(planPath)], { cwd: tmp, env, encoding: 'utf8', timeout: 30_000 }); + const plan = (criteria: string, context = 'the old context') => `# Plan\n\n## Context\n\n${context}\n\n## Acceptance Criteria\n\n${criteria}\n\n## Rollback\n\nrevert\n`; + git('init', '-q', '-b', 'main'); + fs.writeFileSync(path.join(tmp, 'README.md'), 'base\n'); + git('add', '-A'); git('commit', '-qm', 'base'); + return { tmp, git, run, plan }; + } + + test('a plan on origin/: an acceptance edit in the working tree is yes with the diff; a context-only edit is none', () => { + const f = repo(); + try { + fs.mkdirSync(path.join(f.tmp, 'docs/designs'), { recursive: true }); + const file = path.join(f.tmp, 'docs/designs/PLAN.md'); + fs.writeFileSync(file, f.plan('1. Orders older than 30 days return HTTP 410 for all 4 user roles')); + f.git('add', '-A'); f.git('commit', '-qm', 'plan'); + f.git('update-ref', 'refs/remotes/origin/main', 'HEAD'); + f.git('checkout', '-qb', 'feature'); + fs.writeFileSync(file, f.plan('1. Orders older than 30 days return HTTP 410 for all 4 user roles', 'rewritten context')); + const none = f.run(file); + expect(none.status).toBe(0); + expect(none.stdout).toContain('ACCEPTANCE_BASELINE: origin/main'); + expect(none.stdout).toContain(`${ACCEPTANCE_EDITED}: none`); + fs.writeFileSync(file, f.plan('1. Orders older than 30 days return HTTP 410 for the admin role')); + const yes = f.run(file); + expect(yes.status).toBe(0); + expect(yes.stdout).toContain(`${ACCEPTANCE_EDITED}: yes`); + expect(yes.stdout).toContain('-1. Orders older than 30 days return HTTP 410 for all 4 user roles'); + expect(yes.stdout).toContain('+1. Orders older than 30 days return HTTP 410 for the admin role'); + expect(yes.stdout).not.toContain(`${ACCEPTANCE_EDITED}: none`); + } finally { fs.rmSync(f.tmp, { recursive: true, force: true }); } + }); + + test('a plan introduced on the branch uses its first commit as the baseline; an untracked plan is baseline unavailable', () => { + const f = repo(); + try { + f.git('update-ref', 'refs/remotes/origin/main', 'HEAD'); + f.git('checkout', '-qb', 'feature'); + fs.mkdirSync(path.join(f.tmp, 'docs/designs'), { recursive: true }); + const file = path.join(f.tmp, 'docs/designs/PLAN.md'); + fs.writeFileSync(file, f.plan('1. Query time under 100ms')); + f.git('add', '-A'); f.git('commit', '-qm', 'add plan'); + const first = f.git('rev-parse', 'HEAD'); + fs.writeFileSync(file, f.plan('1. Query time under 100ms\n2. Added later')); + f.git('add', '-A'); f.git('commit', '-qm', 'edit plan'); + const out = f.run(file); + expect(out.status).toBe(0); + expect(out.stdout).toContain(`ACCEPTANCE_BASELINE: first commit on branch (${first})`); + expect(out.stdout).toContain(`${ACCEPTANCE_EDITED}: yes`); + expect(out.stdout).toContain('+2. Added later'); + const outside = path.join(f.tmp, 'outside-plan.md'); + fs.writeFileSync(outside, f.plan('1. anything')); + const unavailable = f.run(outside); + expect(unavailable.status).toBe(0); + expect(unavailable.stdout).toContain('ACCEPTANCE_BASELINE: unavailable'); + expect(unavailable.stdout).not.toContain(`${ACCEPTANCE_EDITED}:`); + } finally { fs.rmSync(f.tmp, { recursive: true, force: true }); } + }); +}); diff --git a/test/test-value-bar.test.ts b/test/test-value-bar.test.ts index 21ca74615..ce5490d2c 100644 --- a/test/test-value-bar.test.ts +++ b/test/test-value-bar.test.ts @@ -13,9 +13,11 @@ import { generateTestCoverageAuditInner } from '../scripts/resolvers/testing'; import { CALLER_SEARCH_COMMAND, CALLER_SYMBOL_PATTERN, CARD_FIELD_MAX_BYTES, CATALOG, MESSAGES, PRAGMA, QUESTIONS, REASON_CODES, RETENTION_ONE_LINER, RETIREMENT_FIELDS, REVIEW_EVIDENCE_FIELDS, SWEEP_POINTER, TEST_VALUE_BAR_MAX_BYTES, TEST_VALUE_BAR_MODES, + NO_CLAIM_EXAMPLES, VALUE_CARD_FIELDS, VALUE_CARD_OPTIONAL_FIELD, WEAK_REASONS, clampCardField, generateTestValueBar, renderValueCard, type TestValueBarMode, } from '../scripts/resolvers/test-value'; import { recordsNonTestCallerSearch } from './helpers/test-value-fixture'; +import { expectMentions } from './helpers/prompt-structure'; const ROOT = path.resolve(import.meta.dir, '..'); const FIX = 'Fix: bun run gen:skill-docs && bun test test/test-value-bar.test.ts'; @@ -23,7 +25,8 @@ const read = (relative: string) => fs.readFileSync(path.join(ROOT, relative), 'u const ctx = { skillName: 'ship', tmplPath: '', host: 'claude', paths: HOST_PATHS.claude } as TemplateContext; const bar = (mode: TestValueBarMode) => generateTestValueBar(ctx, [mode]); -const CARD_FORMAT = 'Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none'; +const CARD_FORMAT = 'Value: protects=<...>; fails_when=<...>; why_new=<...>; seam=none; no_claim=<...>'; +const NO_CLAIM_EXAMPLE_TOKENS = NO_CLAIM_EXAMPLES.map(example => `no_claim=${example}`); const shipSection = read('ship/sections/test-coverage.md'); const shipGate = generateTestCoverageAuditInner(ctx, 'ship', 'gate'); @@ -36,6 +39,7 @@ const CONTRACT: Record added > rejected', REASON_CODES.join(', '), '"coverage_pct":N,"gaps":N,"diagram":"","tests_added":["path",...],"coverage_pct_value":N,"weak_gaps":[', - 'a value-card header with four non-empty fields (else\n `incomplete_card`)', 'a later duplicate is `duplicate_protects`', 'is `needs_seam`', + 'the four required fields non-empty plus\n an optional `no_claim`', 'an older four-field card stays valid', '`incomplete_card`', 'a later duplicate is `duplicate_protects`', 'is `needs_seam`', + ...NO_CLAIM_EXAMPLE_TOKENS, 'No `tests_rejected` path may remain on disk as a new file', 'dispatch one read-only Agent', 'it uses no generation\n pass', 'Regression proof — fails at HEAD: yes · passes at base: yes | unavailable () | manual · passes after fix: yes | pending', 'base control unavailable: collection error', 'N of M regression tests got base control', 'worktree add --quiet --detach', @@ -122,6 +127,22 @@ describe('test value bar render contract', () => { expect(clampCardField('short')).toBe('short'); expect(renderValueCard({ protects: long, fails_when: 'x', why_new: 'y', seam: 'none' })).toStartWith(`Value: protects=${clamped}; fails_when=x;`); }); + + test('no_claim is an optional fifth field: rendered last when present, absent from a four-field card (W5)', () => { + expect(VALUE_CARD_FIELDS).toEqual(['protects', 'fails_when', 'why_new', 'seam']); + expect(VALUE_CARD_OPTIONAL_FIELD).toBe('no_claim'); + const four = renderValueCard({ protects: 'a', fails_when: 'b', why_new: 'c', seam: 'none' }); + expect(four).toBe('Value: protects=a; fails_when=b; why_new=c; seam=none'); + const five = renderValueCard({ protects: 'a', fails_when: 'b', why_new: 'c', seam: 'none', no_claim: NO_CLAIM_EXAMPLES[1] }); + expect(five).toBe(`${four}; no_claim=${NO_CLAIM_EXAMPLES[1]}`); + expect(renderValueCard({ protects: 'a', fails_when: 'b', why_new: 'c', seam: 'none', no_claim: '€'.repeat(100) })).toEndWith('...'); + for (const mode of TEST_VALUE_BAR_MODES) { + const rendered = bar(mode); + expect(rendered, `${mode} lacks both no_claim examples`).toContain(`no_claim=${NO_CLAIM_EXAMPLES[0]}`); + expect(rendered).toContain(`no_claim=${NO_CLAIM_EXAMPLES[1]}`); + expectMentions(rendered, [['no_claim', 'never waives']], `${mode} bar`); + } + }); }); describe('ship parent decision rules', () => { @@ -197,6 +218,7 @@ describe('static review specialist stays in sync', () => { const expected = [...QUESTIONS, ...CATALOG, ...REVIEW_EVIDENCE_FIELDS.map(field => `\`${field}\``), RETIREMENT_FIELDS.join(', '), ...REASON_CODES.map(code => `\`${code}\``), `${PRAGMA} reason=""`, CALLER_SEARCH_COMMAND, CALLER_SYMBOL_PATTERN, SWEEP_POINTER, 'never an auto-delete', 'stays a coverage gap at its existing severity', 'one INFORMATIONAL line', 'Regression test without red proof', + '`no_claim=...`', `test-value-bar.md#${MESSAGES.callerCheckUnavailable.anchor}`]; const flat = specialist.replace(/\n/g, ' ').replace(/ +/g, ' '); expect(expected.filter(text => !flat.includes(text.replace(/\n/g, ' '))), `review/specialists/testing.md is out of sync with scripts/resolvers/test-value.ts`).toEqual([]);