diff --git a/CHANGELOG.md b/CHANGELOG.md index a8bc051ed..eeecf5921 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ - **Unattended /ship may update an existing PR's body.** `gstack-skill-start`'s unattended block and `UNATTENDED_SHIP:` line, the ship skill's Step 18 and `docs/unattended.md` now say: when an open PR for the branch exists and HEAD is its pushed head, Step 18 takes the pr-body section's existing-PR path (body with the receipt first, and title); it never runs `pr-create` and never pushes a commit; anything else takes the handoff section. Before this the block said the receipt lived only in `.gstack/tmp/ship-receipt.md` while rule 22 and `ready` read it from the PR body. - **`INSTALL_UNVERIFIED` with no verdict names the directory to install from.** An installer run from the skill's own folder records a verdict for no project, so /ship launched from the project found none and the fix said only "run the installer on this machine" (GSTA-85). Both twins (`lib/install-verdict.ts`, `bin/gstack-install-verdict.sh`) now say `run … scripts/install.sh --for ship from : the verdict is keyed by the project directory the installer runs in`. - **Docs:** `docs/ship-policy.md#ship-before-ready` (the lane runs /ship before every READY and after every push; the stamp keeps the pin's receipt), the two codes in `docs/troubleshooting.md`, `docs/unattended.md` (/ship now prints the result line), and the ship skill's pr-body section says what refuses without a receipt. -- **Gate edit (size budgets):** `test/helpers/carve-guards.ts` raises ship's `maxSkeletonBytes` 81,000 → 82,000 and `maxSizeRatio` 1.6690 → 1.6760 for Step 22 and the Step 18 routing, both written as tight as they go (measured skeleton 81,711, union 314,204; the 2026-10-14 tightening had left 2 bytes of headroom). No threshold, trial count or case kind changed. +- **Gate edit (size budgets):** `test/helpers/carve-guards.ts` raises ship's `maxSkeletonBytes` 81,000 → 81,600 and `maxSizeRatio` 1.6690 → 1.6740 for Step 22 and the Step 18 routing, offset in part by tightening Steps 14, 16, 18 and 20 prose (measured skeleton 81,535, union 314,027; the 2026-10-14 tightening had left 2 bytes of headroom). No threshold, trial count or case kind changed. ### Tests - `test/ship-queue-train.test.ts`: READY, train build (dry run and live) and verify --train refuse a missing, invalid, other-head and other-PR receipt and admit the current one; the pinned-head receipt admits a stamp commit. `test/gstack-ship-queue.test.ts` covers the per-PR READY block. `test/gstack-ship-receipt.test.ts` covers `result` from a PR and from the handoff file. The train fixture's `openPr` now writes a receipt for the head it opens (`shipped: false` leaves the body empty). `test/install-verdict.test.ts` pins the GSTA-85 fix in both twins; `test/gstack-skill-start.test.ts` pins the new unattended /ship block. diff --git a/ship/SKILL.md b/ship/SKILL.md index 2a7f04a63..1ac44ff24 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -1154,9 +1154,9 @@ Lookup failure or ambiguous matches **STOP** for resolution, never mean no PR. Save the result for Step 19's recheck. The pr-body section prepares the title from that result, then publishes; -`--no-pr` or an automation lane takes the handoff section. Unattended -(`UNATTENDED_SHIP:` echoed): an open PR at HEAD takes the pr-body section's -existing-PR path (body and title only, never `pr-create` or a push); else handoff. +`--no-pr` or an automation lane takes the handoff section. Unattended (`UNATTENDED_SHIP:` +echoed): an open PR at HEAD takes pr-body's existing-PR path (body and title only, no +`pr-create`, no push); else handoff. > **STOP.** Before preparing the title and creating or updating the PR/MR with the verified documentation outcome (Steps 18-19), Read `~/.claude/skills/gstack/ship/sections/pr-body.md` and execute it > in full. Do not work from memory — that section is the source of truth for this step. @@ -1174,13 +1174,12 @@ JSON validation, storage and sync and takes **no path argument**. ``` Substitute from earlier steps: -- **COVERAGE_PCT**: Step 7 diagram's integer percentage; encode null/undetermined as -1 -- **COVERAGE_PCT_VALUE**: Step 7's `coverage_pct_value` (the gate's X) as an integer, or `null` when missing or ignored -- **WEAK_GAPS**, **TESTS_EXTENDED**, **TESTS_REJECTED**: counts of Step 7's `weak_gaps`, `tests_extended` and `tests_rejected` (0 when the key is missing or ignored) -- **REGRESSION_PROOF**: `{"red_at_head":N,"base_green":N,"base_unavailable":N}` from Step 7, or `null` when missing -- **PLAN_TOTAL**: total plan items extracted in Step 8 (0 if no plan file) -- **PLAN_DONE**: count of DONE + CHANGED items from Step 8 (0 if no plan file) -- **VERIFY_RESULT**: "pass", "fail", or "skipped", set after Step 9 executes Step 8.1's verification list +- **COVERAGE_PCT**: Step 7's integer percentage; -1 when null or undetermined +- **COVERAGE_PCT_VALUE**: Step 7's `coverage_pct_value` (the gate's X) as an integer; `null` when missing or ignored +- **WEAK_GAPS**, **TESTS_EXTENDED**, **TESTS_REJECTED**: counts of Step 7's `weak_gaps`, `tests_extended`, `tests_rejected` (0 when missing or ignored) +- **REGRESSION_PROOF**: Step 7's `{"red_at_head":N,"base_green":N,"base_unavailable":N}`; `null` when missing +- **PLAN_TOTAL** / **PLAN_DONE**: Step 8's plan items, total and DONE + CHANGED (0 with no plan file) +- **VERIFY_RESULT**: "pass", "fail" or "skipped", set when Step 9 runs Step 8.1's verification list - **VERSION**: `NEW_VERSION` from Step 12; `null` (unquoted) under NO_VERSION The shell supplies the branch. Run it without confirmation. @@ -1196,10 +1195,7 @@ GSTACK_STATE_ROOT=$(~/.claude/skills/gstack/bin/gstack-paths --get GSTACK_STATE_ _NUDGE_MARKER="$GSTACK_STATE_ROOT/.plan-tune-nudge-shown" _QT=$(~/.claude/skills/gstack/bin/gstack-config get question_tuning 2>/dev/null || echo "false") if [ ! -f "$_NUDGE_MARKER" ] && [ "$_QT" = "false" ]; then - echo "" - echo "gstack can learn from your AskUserQuestion answers. Run /plan-tune to opt in" - echo "— it captures which prompts you find valuable vs noisy and (with hooks installed)" - echo "auto-decides your never-ask preferences." + printf '\ngstack can learn from your AskUserQuestion answers. Run /plan-tune to opt in: it captures which prompts you find valuable vs noisy and (with hooks installed) auto-decides your never-ask preferences.\n' mkdir -p "$GSTACK_STATE_ROOT" && touch "$_NUDGE_MARKER" fi ``` @@ -1216,10 +1212,9 @@ The last line printed is the result line a parent greps (docs/unattended.md): ~/.claude/skills/gstack/bin/gstack-ship-receipt result --pr # handoff: --body .gstack/tmp/ship-receipt.md ``` -It binds the receipt to HEAD, writes `/ship/runs/-/` and prints -`GSTACK_RESULT: skill=ship status=complete run=`. `QUEUE_RECEIPT_STALE`: HEAD moved after -the receipt; rewrite, repost, rerun. A run that STOPs earlier ends with the literal -`GSTACK_RESULT: skill=ship status=refused run=-` after its reason. +It binds the receipt to HEAD, writes the run record and prints `GSTACK_RESULT: skill=ship +status=complete run=`; `QUEUE_RECEIPT_STALE` means HEAD moved after the receipt (rewrite, +repost, rerun). A run that STOPs earlier ends with `GSTACK_RESULT: skill=ship status=refused run=-`. --- diff --git a/ship/SKILL.md.tmpl b/ship/SKILL.md.tmpl index 833cba84e..c4c21022f 100644 --- a/ship/SKILL.md.tmpl +++ b/ship/SKILL.md.tmpl @@ -624,9 +624,9 @@ Lookup failure or ambiguous matches **STOP** for resolution, never mean no PR. Save the result for Step 19's recheck. The pr-body section prepares the title from that result, then publishes; -`--no-pr` or an automation lane takes the handoff section. Unattended -(`UNATTENDED_SHIP:` echoed): an open PR at HEAD takes the pr-body section's -existing-PR path (body and title only, never `pr-create` or a push); else handoff. +`--no-pr` or an automation lane takes the handoff section. Unattended (`UNATTENDED_SHIP:` +echoed): an open PR at HEAD takes pr-body's existing-PR path (body and title only, no +`pr-create`, no push); else handoff. {{SECTION:pr-body}} @@ -642,13 +642,12 @@ JSON validation, storage and sync and takes **no path argument**. ``` Substitute from earlier steps: -- **COVERAGE_PCT**: Step 7 diagram's integer percentage; encode null/undetermined as -1 -- **COVERAGE_PCT_VALUE**: Step 7's `coverage_pct_value` (the gate's X) as an integer, or `null` when missing or ignored -- **WEAK_GAPS**, **TESTS_EXTENDED**, **TESTS_REJECTED**: counts of Step 7's `weak_gaps`, `tests_extended` and `tests_rejected` (0 when the key is missing or ignored) -- **REGRESSION_PROOF**: `{"red_at_head":N,"base_green":N,"base_unavailable":N}` from Step 7, or `null` when missing -- **PLAN_TOTAL**: total plan items extracted in Step 8 (0 if no plan file) -- **PLAN_DONE**: count of DONE + CHANGED items from Step 8 (0 if no plan file) -- **VERIFY_RESULT**: "pass", "fail", or "skipped", set after Step 9 executes Step 8.1's verification list +- **COVERAGE_PCT**: Step 7's integer percentage; -1 when null or undetermined +- **COVERAGE_PCT_VALUE**: Step 7's `coverage_pct_value` (the gate's X) as an integer; `null` when missing or ignored +- **WEAK_GAPS**, **TESTS_EXTENDED**, **TESTS_REJECTED**: counts of Step 7's `weak_gaps`, `tests_extended`, `tests_rejected` (0 when missing or ignored) +- **REGRESSION_PROOF**: Step 7's `{"red_at_head":N,"base_green":N,"base_unavailable":N}`; `null` when missing +- **PLAN_TOTAL** / **PLAN_DONE**: Step 8's plan items, total and DONE + CHANGED (0 with no plan file) +- **VERIFY_RESULT**: "pass", "fail" or "skipped", set when Step 9 runs Step 8.1's verification list - **VERSION**: `NEW_VERSION` from Step 12; `null` (unquoted) under NO_VERSION The shell supplies the branch. Run it without confirmation. @@ -664,10 +663,7 @@ GSTACK_STATE_ROOT=$(~/.claude/skills/gstack/bin/gstack-paths --get GSTACK_STATE_ _NUDGE_MARKER="$GSTACK_STATE_ROOT/.plan-tune-nudge-shown" _QT=$(~/.claude/skills/gstack/bin/gstack-config get question_tuning 2>/dev/null || echo "false") if [ ! -f "$_NUDGE_MARKER" ] && [ "$_QT" = "false" ]; then - echo "" - echo "gstack can learn from your AskUserQuestion answers. Run /plan-tune to opt in" - echo "— it captures which prompts you find valuable vs noisy and (with hooks installed)" - echo "auto-decides your never-ask preferences." + printf '\ngstack can learn from your AskUserQuestion answers. Run /plan-tune to opt in: it captures which prompts you find valuable vs noisy and (with hooks installed) auto-decides your never-ask preferences.\n' mkdir -p "$GSTACK_STATE_ROOT" && touch "$_NUDGE_MARKER" fi ``` @@ -684,10 +680,9 @@ The last line printed is the result line a parent greps (docs/unattended.md): ~/.claude/skills/gstack/bin/gstack-ship-receipt result --pr # handoff: --body .gstack/tmp/ship-receipt.md ``` -It binds the receipt to HEAD, writes `/ship/runs/-/` and prints -`GSTACK_RESULT: skill=ship status=complete run=`. `QUEUE_RECEIPT_STALE`: HEAD moved after -the receipt; rewrite, repost, rerun. A run that STOPs earlier ends with the literal -`GSTACK_RESULT: skill=ship status=refused run=-` after its reason. +It binds the receipt to HEAD, writes the run record and prints `GSTACK_RESULT: skill=ship +status=complete run=`; `QUEUE_RECEIPT_STALE` means HEAD moved after the receipt (rewrite, +repost, rerun). A run that STOPs earlier ends with `GSTACK_RESULT: skill=ship status=refused run=-`. --- diff --git a/ship/sections/pr-body.md b/ship/sections/pr-body.md index 17fbc0c40..d9041c6e0 100644 --- a/ship/sections/pr-body.md +++ b/ship/sections/pr-body.md @@ -207,9 +207,9 @@ per-lane counts (`{"":{"pass":N,"fail":N,"skip":N}}`) to Add `--receipt .gstack/tmp/tree-receipt.json` only when Step 16 wrote it (gate-ahead). New PR/MR: omit `--pr`, then rerun with the number after creation and repost the body. Its `SHIP_RECEIPT:` line opens the completion message. The posted receipt is what -`gstack-ship-queue ready`, `train build` and `verify --train` check (`QUEUE_RECEIPT_MISSING`, -`QUEUE_RECEIPT_STALE`, no flag around them): /ship runs before every READY and after any -later push. `RECEIPT_INVALID` names the bad +`gstack-ship-queue ready`, `train build` and `verify --train` require (`QUEUE_RECEIPT_MISSING`, +`QUEUE_RECEIPT_STALE`, no flag around them), so /ship runs before every READY and after any +push. `RECEIPT_INVALID` names the bad field: fix that input file and rerun; nothing was written. `ISSUE_LINKS_MISSING`: add the named line under `## Issues` and rerun. `PREGATE_STALE` means rerun `gstack-pregate` on the stamped tree; `PREGATE_REMOTE_UNCLEARED` needs diff --git a/ship/sections/pr-body.md.tmpl b/ship/sections/pr-body.md.tmpl index 83dfc7c11..441624b01 100644 --- a/ship/sections/pr-body.md.tmpl +++ b/ship/sections/pr-body.md.tmpl @@ -190,9 +190,9 @@ per-lane counts (`{"":{"pass":N,"fail":N,"skip":N}}`) to Add `--receipt .gstack/tmp/tree-receipt.json` only when Step 16 wrote it (gate-ahead). New PR/MR: omit `--pr`, then rerun with the number after creation and repost the body. Its `SHIP_RECEIPT:` line opens the completion message. The posted receipt is what -`gstack-ship-queue ready`, `train build` and `verify --train` check (`QUEUE_RECEIPT_MISSING`, -`QUEUE_RECEIPT_STALE`, no flag around them): /ship runs before every READY and after any -later push. `RECEIPT_INVALID` names the bad +`gstack-ship-queue ready`, `train build` and `verify --train` require (`QUEUE_RECEIPT_MISSING`, +`QUEUE_RECEIPT_STALE`, no flag around them), so /ship runs before every READY and after any +push. `RECEIPT_INVALID` names the bad field: fix that input file and rerun; nothing was written. `ISSUE_LINKS_MISSING`: add the named line under `## Issues` and rerun. `PREGATE_STALE` means rerun `gstack-pregate` on the stamped tree; `PREGATE_REMOTE_UNCLEARED` needs diff --git a/test/fixtures/golden/agy-ship-SKILL.md b/test/fixtures/golden/agy-ship-SKILL.md index 75c9c3983..00847ded6 100644 --- a/test/fixtures/golden/agy-ship-SKILL.md +++ b/test/fixtures/golden/agy-ship-SKILL.md @@ -1149,9 +1149,9 @@ Lookup failure or ambiguous matches **STOP** for resolution, never mean no PR. Save the result for Step 19's recheck. The pr-body section prepares the title from that result, then publishes; -`--no-pr` or an automation lane takes the handoff section. Unattended -(`UNATTENDED_SHIP:` echoed): an open PR at HEAD takes the pr-body section's -existing-PR path (body and title only, never `pr-create` or a push); else handoff. +`--no-pr` or an automation lane takes the handoff section. Unattended (`UNATTENDED_SHIP:` +echoed): an open PR at HEAD takes pr-body's existing-PR path (body and title only, no +`pr-create`, no push); else handoff. > **STOP.** Before preparing the title and creating or updating the PR/MR with the verified documentation outcome (Steps 18-19), Read `sections/pr-body.md` relative to the installed `gstack-ship` SKILL.md directory and execute it > in full. Do not work from memory — that section is the source of truth for this step. @@ -1169,13 +1169,12 @@ JSON validation, storage and sync and takes **no path argument**. ``` Substitute from earlier steps: -- **COVERAGE_PCT**: Step 7 diagram's integer percentage; encode null/undetermined as -1 -- **COVERAGE_PCT_VALUE**: Step 7's `coverage_pct_value` (the gate's X) as an integer, or `null` when missing or ignored -- **WEAK_GAPS**, **TESTS_EXTENDED**, **TESTS_REJECTED**: counts of Step 7's `weak_gaps`, `tests_extended` and `tests_rejected` (0 when the key is missing or ignored) -- **REGRESSION_PROOF**: `{"red_at_head":N,"base_green":N,"base_unavailable":N}` from Step 7, or `null` when missing -- **PLAN_TOTAL**: total plan items extracted in Step 8 (0 if no plan file) -- **PLAN_DONE**: count of DONE + CHANGED items from Step 8 (0 if no plan file) -- **VERIFY_RESULT**: "pass", "fail", or "skipped", set after Step 9 executes Step 8.1's verification list +- **COVERAGE_PCT**: Step 7's integer percentage; -1 when null or undetermined +- **COVERAGE_PCT_VALUE**: Step 7's `coverage_pct_value` (the gate's X) as an integer; `null` when missing or ignored +- **WEAK_GAPS**, **TESTS_EXTENDED**, **TESTS_REJECTED**: counts of Step 7's `weak_gaps`, `tests_extended`, `tests_rejected` (0 when missing or ignored) +- **REGRESSION_PROOF**: Step 7's `{"red_at_head":N,"base_green":N,"base_unavailable":N}`; `null` when missing +- **PLAN_TOTAL** / **PLAN_DONE**: Step 8's plan items, total and DONE + CHANGED (0 with no plan file) +- **VERIFY_RESULT**: "pass", "fail" or "skipped", set when Step 9 runs Step 8.1's verification list - **VERSION**: `NEW_VERSION` from Step 12; `null` (unquoted) under NO_VERSION The shell supplies the branch. Run it without confirmation. @@ -1191,10 +1190,7 @@ GSTACK_STATE_ROOT=$(~/.gemini/antigravity-cli/skills/gstack/bin/gstack-paths --g _NUDGE_MARKER="$GSTACK_STATE_ROOT/.plan-tune-nudge-shown" _QT=$(~/.gemini/antigravity-cli/skills/gstack/bin/gstack-config get question_tuning 2>/dev/null || echo "false") if [ ! -f "$_NUDGE_MARKER" ] && [ "$_QT" = "false" ]; then - echo "" - echo "gstack can learn from your AskUserQuestion answers. Run /plan-tune to opt in" - echo "— it captures which prompts you find valuable vs noisy and (with hooks installed)" - echo "auto-decides your never-ask preferences." + printf '\ngstack can learn from your AskUserQuestion answers. Run /plan-tune to opt in: it captures which prompts you find valuable vs noisy and (with hooks installed) auto-decides your never-ask preferences.\n' mkdir -p "$GSTACK_STATE_ROOT" && touch "$_NUDGE_MARKER" fi ``` @@ -1211,10 +1207,9 @@ The last line printed is the result line a parent greps (docs/unattended.md): ~/.gemini/antigravity-cli/skills/gstack/bin/gstack-ship-receipt result --pr # handoff: --body .gstack/tmp/ship-receipt.md ``` -It binds the receipt to HEAD, writes `/ship/runs/-/` and prints -`GSTACK_RESULT: skill=ship status=complete run=`. `QUEUE_RECEIPT_STALE`: HEAD moved after -the receipt; rewrite, repost, rerun. A run that STOPs earlier ends with the literal -`GSTACK_RESULT: skill=ship status=refused run=-` after its reason. +It binds the receipt to HEAD, writes the run record and prints `GSTACK_RESULT: skill=ship +status=complete run=`; `QUEUE_RECEIPT_STALE` means HEAD moved after the receipt (rewrite, +repost, rerun). A run that STOPs earlier ends with `GSTACK_RESULT: skill=ship status=refused run=-`. --- diff --git a/test/fixtures/golden/claude-ship-SKILL.md b/test/fixtures/golden/claude-ship-SKILL.md index 2a7f04a63..1ac44ff24 100644 --- a/test/fixtures/golden/claude-ship-SKILL.md +++ b/test/fixtures/golden/claude-ship-SKILL.md @@ -1154,9 +1154,9 @@ Lookup failure or ambiguous matches **STOP** for resolution, never mean no PR. Save the result for Step 19's recheck. The pr-body section prepares the title from that result, then publishes; -`--no-pr` or an automation lane takes the handoff section. Unattended -(`UNATTENDED_SHIP:` echoed): an open PR at HEAD takes the pr-body section's -existing-PR path (body and title only, never `pr-create` or a push); else handoff. +`--no-pr` or an automation lane takes the handoff section. Unattended (`UNATTENDED_SHIP:` +echoed): an open PR at HEAD takes pr-body's existing-PR path (body and title only, no +`pr-create`, no push); else handoff. > **STOP.** Before preparing the title and creating or updating the PR/MR with the verified documentation outcome (Steps 18-19), Read `~/.claude/skills/gstack/ship/sections/pr-body.md` and execute it > in full. Do not work from memory — that section is the source of truth for this step. @@ -1174,13 +1174,12 @@ JSON validation, storage and sync and takes **no path argument**. ``` Substitute from earlier steps: -- **COVERAGE_PCT**: Step 7 diagram's integer percentage; encode null/undetermined as -1 -- **COVERAGE_PCT_VALUE**: Step 7's `coverage_pct_value` (the gate's X) as an integer, or `null` when missing or ignored -- **WEAK_GAPS**, **TESTS_EXTENDED**, **TESTS_REJECTED**: counts of Step 7's `weak_gaps`, `tests_extended` and `tests_rejected` (0 when the key is missing or ignored) -- **REGRESSION_PROOF**: `{"red_at_head":N,"base_green":N,"base_unavailable":N}` from Step 7, or `null` when missing -- **PLAN_TOTAL**: total plan items extracted in Step 8 (0 if no plan file) -- **PLAN_DONE**: count of DONE + CHANGED items from Step 8 (0 if no plan file) -- **VERIFY_RESULT**: "pass", "fail", or "skipped", set after Step 9 executes Step 8.1's verification list +- **COVERAGE_PCT**: Step 7's integer percentage; -1 when null or undetermined +- **COVERAGE_PCT_VALUE**: Step 7's `coverage_pct_value` (the gate's X) as an integer; `null` when missing or ignored +- **WEAK_GAPS**, **TESTS_EXTENDED**, **TESTS_REJECTED**: counts of Step 7's `weak_gaps`, `tests_extended`, `tests_rejected` (0 when missing or ignored) +- **REGRESSION_PROOF**: Step 7's `{"red_at_head":N,"base_green":N,"base_unavailable":N}`; `null` when missing +- **PLAN_TOTAL** / **PLAN_DONE**: Step 8's plan items, total and DONE + CHANGED (0 with no plan file) +- **VERIFY_RESULT**: "pass", "fail" or "skipped", set when Step 9 runs Step 8.1's verification list - **VERSION**: `NEW_VERSION` from Step 12; `null` (unquoted) under NO_VERSION The shell supplies the branch. Run it without confirmation. @@ -1196,10 +1195,7 @@ GSTACK_STATE_ROOT=$(~/.claude/skills/gstack/bin/gstack-paths --get GSTACK_STATE_ _NUDGE_MARKER="$GSTACK_STATE_ROOT/.plan-tune-nudge-shown" _QT=$(~/.claude/skills/gstack/bin/gstack-config get question_tuning 2>/dev/null || echo "false") if [ ! -f "$_NUDGE_MARKER" ] && [ "$_QT" = "false" ]; then - echo "" - echo "gstack can learn from your AskUserQuestion answers. Run /plan-tune to opt in" - echo "— it captures which prompts you find valuable vs noisy and (with hooks installed)" - echo "auto-decides your never-ask preferences." + printf '\ngstack can learn from your AskUserQuestion answers. Run /plan-tune to opt in: it captures which prompts you find valuable vs noisy and (with hooks installed) auto-decides your never-ask preferences.\n' mkdir -p "$GSTACK_STATE_ROOT" && touch "$_NUDGE_MARKER" fi ``` @@ -1216,10 +1212,9 @@ The last line printed is the result line a parent greps (docs/unattended.md): ~/.claude/skills/gstack/bin/gstack-ship-receipt result --pr # handoff: --body .gstack/tmp/ship-receipt.md ``` -It binds the receipt to HEAD, writes `/ship/runs/-/` and prints -`GSTACK_RESULT: skill=ship status=complete run=`. `QUEUE_RECEIPT_STALE`: HEAD moved after -the receipt; rewrite, repost, rerun. A run that STOPs earlier ends with the literal -`GSTACK_RESULT: skill=ship status=refused run=-` after its reason. +It binds the receipt to HEAD, writes the run record and prints `GSTACK_RESULT: skill=ship +status=complete run=`; `QUEUE_RECEIPT_STALE` means HEAD moved after the receipt (rewrite, +repost, rerun). A run that STOPs earlier ends with `GSTACK_RESULT: skill=ship status=refused run=-`. --- diff --git a/test/fixtures/golden/codex-ship-SKILL.md b/test/fixtures/golden/codex-ship-SKILL.md index a4f52d763..742e165c2 100644 --- a/test/fixtures/golden/codex-ship-SKILL.md +++ b/test/fixtures/golden/codex-ship-SKILL.md @@ -1177,9 +1177,9 @@ Lookup failure or ambiguous matches **STOP** for resolution, never mean no PR. Save the result for Step 19's recheck. The pr-body section prepares the title from that result, then publishes; -`--no-pr` or an automation lane takes the handoff section. Unattended -(`UNATTENDED_SHIP:` echoed): an open PR at HEAD takes the pr-body section's -existing-PR path (body and title only, never `pr-create` or a push); else handoff. +`--no-pr` or an automation lane takes the handoff section. Unattended (`UNATTENDED_SHIP:` +echoed): an open PR at HEAD takes pr-body's existing-PR path (body and title only, no +`pr-create`, no push); else handoff. > **STOP.** Before preparing the title and creating or updating the PR/MR with the verified documentation outcome (Steps 18-19), Read `sections/pr-body.md` relative to the installed `gstack-ship` SKILL.md directory and execute it > in full. Do not work from memory — that section is the source of truth for this step. @@ -1198,13 +1198,12 @@ $GSTACK_ROOT/bin/gstack-review-log '{"skill":"ship","timestamp":"'"$(date -u +%Y ``` Substitute from earlier steps: -- **COVERAGE_PCT**: Step 7 diagram's integer percentage; encode null/undetermined as -1 -- **COVERAGE_PCT_VALUE**: Step 7's `coverage_pct_value` (the gate's X) as an integer, or `null` when missing or ignored -- **WEAK_GAPS**, **TESTS_EXTENDED**, **TESTS_REJECTED**: counts of Step 7's `weak_gaps`, `tests_extended` and `tests_rejected` (0 when the key is missing or ignored) -- **REGRESSION_PROOF**: `{"red_at_head":N,"base_green":N,"base_unavailable":N}` from Step 7, or `null` when missing -- **PLAN_TOTAL**: total plan items extracted in Step 8 (0 if no plan file) -- **PLAN_DONE**: count of DONE + CHANGED items from Step 8 (0 if no plan file) -- **VERIFY_RESULT**: "pass", "fail", or "skipped", set after Step 9 executes Step 8.1's verification list +- **COVERAGE_PCT**: Step 7's integer percentage; -1 when null or undetermined +- **COVERAGE_PCT_VALUE**: Step 7's `coverage_pct_value` (the gate's X) as an integer; `null` when missing or ignored +- **WEAK_GAPS**, **TESTS_EXTENDED**, **TESTS_REJECTED**: counts of Step 7's `weak_gaps`, `tests_extended`, `tests_rejected` (0 when missing or ignored) +- **REGRESSION_PROOF**: Step 7's `{"red_at_head":N,"base_green":N,"base_unavailable":N}`; `null` when missing +- **PLAN_TOTAL** / **PLAN_DONE**: Step 8's plan items, total and DONE + CHANGED (0 with no plan file) +- **VERIFY_RESULT**: "pass", "fail" or "skipped", set when Step 9 runs Step 8.1's verification list - **VERSION**: `NEW_VERSION` from Step 12; `null` (unquoted) under NO_VERSION The shell supplies the branch. Run it without confirmation. @@ -1221,10 +1220,7 @@ GSTACK_STATE_ROOT=$($GSTACK_ROOT/bin/gstack-paths --get GSTACK_STATE_ROOT); : "$ _NUDGE_MARKER="$GSTACK_STATE_ROOT/.plan-tune-nudge-shown" _QT=$($GSTACK_ROOT/bin/gstack-config get question_tuning 2>/dev/null || echo "false") if [ ! -f "$_NUDGE_MARKER" ] && [ "$_QT" = "false" ]; then - echo "" - echo "gstack can learn from your AskUserQuestion answers. Run /plan-tune to opt in" - echo "— it captures which prompts you find valuable vs noisy and (with hooks installed)" - echo "auto-decides your never-ask preferences." + printf '\ngstack can learn from your AskUserQuestion answers. Run /plan-tune to opt in: it captures which prompts you find valuable vs noisy and (with hooks installed) auto-decides your never-ask preferences.\n' mkdir -p "$GSTACK_STATE_ROOT" && touch "$_NUDGE_MARKER" fi ``` @@ -1242,10 +1238,9 @@ The last line printed is the result line a parent greps (docs/unattended.md): $GSTACK_ROOT/bin/gstack-ship-receipt result --pr # handoff: --body .gstack/tmp/ship-receipt.md ``` -It binds the receipt to HEAD, writes `/ship/runs/-/` and prints -`GSTACK_RESULT: skill=ship status=complete run=`. `QUEUE_RECEIPT_STALE`: HEAD moved after -the receipt; rewrite, repost, rerun. A run that STOPs earlier ends with the literal -`GSTACK_RESULT: skill=ship status=refused run=-` after its reason. +It binds the receipt to HEAD, writes the run record and prints `GSTACK_RESULT: skill=ship +status=complete run=`; `QUEUE_RECEIPT_STALE` means HEAD moved after the receipt (rewrite, +repost, rerun). A run that STOPs earlier ends with `GSTACK_RESULT: skill=ship status=refused run=-`. --- diff --git a/test/fixtures/golden/factory-ship-SKILL.md b/test/fixtures/golden/factory-ship-SKILL.md index 7a6f9426e..fce7d1702 100644 --- a/test/fixtures/golden/factory-ship-SKILL.md +++ b/test/fixtures/golden/factory-ship-SKILL.md @@ -1158,9 +1158,9 @@ Lookup failure or ambiguous matches **STOP** for resolution, never mean no PR. Save the result for Step 19's recheck. The pr-body section prepares the title from that result, then publishes; -`--no-pr` or an automation lane takes the handoff section. Unattended -(`UNATTENDED_SHIP:` echoed): an open PR at HEAD takes the pr-body section's -existing-PR path (body and title only, never `pr-create` or a push); else handoff. +`--no-pr` or an automation lane takes the handoff section. Unattended (`UNATTENDED_SHIP:` +echoed): an open PR at HEAD takes pr-body's existing-PR path (body and title only, no +`pr-create`, no push); else handoff. > **STOP.** Before preparing the title and creating or updating the PR/MR with the verified documentation outcome (Steps 18-19), Read `sections/pr-body.md` relative to the installed `gstack-ship` SKILL.md directory and execute it > in full. Do not work from memory — that section is the source of truth for this step. @@ -1179,13 +1179,12 @@ $GSTACK_ROOT/bin/gstack-review-log '{"skill":"ship","timestamp":"'"$(date -u +%Y ``` Substitute from earlier steps: -- **COVERAGE_PCT**: Step 7 diagram's integer percentage; encode null/undetermined as -1 -- **COVERAGE_PCT_VALUE**: Step 7's `coverage_pct_value` (the gate's X) as an integer, or `null` when missing or ignored -- **WEAK_GAPS**, **TESTS_EXTENDED**, **TESTS_REJECTED**: counts of Step 7's `weak_gaps`, `tests_extended` and `tests_rejected` (0 when the key is missing or ignored) -- **REGRESSION_PROOF**: `{"red_at_head":N,"base_green":N,"base_unavailable":N}` from Step 7, or `null` when missing -- **PLAN_TOTAL**: total plan items extracted in Step 8 (0 if no plan file) -- **PLAN_DONE**: count of DONE + CHANGED items from Step 8 (0 if no plan file) -- **VERIFY_RESULT**: "pass", "fail", or "skipped", set after Step 9 executes Step 8.1's verification list +- **COVERAGE_PCT**: Step 7's integer percentage; -1 when null or undetermined +- **COVERAGE_PCT_VALUE**: Step 7's `coverage_pct_value` (the gate's X) as an integer; `null` when missing or ignored +- **WEAK_GAPS**, **TESTS_EXTENDED**, **TESTS_REJECTED**: counts of Step 7's `weak_gaps`, `tests_extended`, `tests_rejected` (0 when missing or ignored) +- **REGRESSION_PROOF**: Step 7's `{"red_at_head":N,"base_green":N,"base_unavailable":N}`; `null` when missing +- **PLAN_TOTAL** / **PLAN_DONE**: Step 8's plan items, total and DONE + CHANGED (0 with no plan file) +- **VERIFY_RESULT**: "pass", "fail" or "skipped", set when Step 9 runs Step 8.1's verification list - **VERSION**: `NEW_VERSION` from Step 12; `null` (unquoted) under NO_VERSION The shell supplies the branch. Run it without confirmation. @@ -1202,10 +1201,7 @@ GSTACK_STATE_ROOT=$($GSTACK_ROOT/bin/gstack-paths --get GSTACK_STATE_ROOT); : "$ _NUDGE_MARKER="$GSTACK_STATE_ROOT/.plan-tune-nudge-shown" _QT=$($GSTACK_ROOT/bin/gstack-config get question_tuning 2>/dev/null || echo "false") if [ ! -f "$_NUDGE_MARKER" ] && [ "$_QT" = "false" ]; then - echo "" - echo "gstack can learn from your AskUserQuestion answers. Run /plan-tune to opt in" - echo "— it captures which prompts you find valuable vs noisy and (with hooks installed)" - echo "auto-decides your never-ask preferences." + printf '\ngstack can learn from your AskUserQuestion answers. Run /plan-tune to opt in: it captures which prompts you find valuable vs noisy and (with hooks installed) auto-decides your never-ask preferences.\n' mkdir -p "$GSTACK_STATE_ROOT" && touch "$_NUDGE_MARKER" fi ``` @@ -1223,10 +1219,9 @@ The last line printed is the result line a parent greps (docs/unattended.md): $GSTACK_ROOT/bin/gstack-ship-receipt result --pr # handoff: --body .gstack/tmp/ship-receipt.md ``` -It binds the receipt to HEAD, writes `/ship/runs/-/` and prints -`GSTACK_RESULT: skill=ship status=complete run=`. `QUEUE_RECEIPT_STALE`: HEAD moved after -the receipt; rewrite, repost, rerun. A run that STOPs earlier ends with the literal -`GSTACK_RESULT: skill=ship status=refused run=-` after its reason. +It binds the receipt to HEAD, writes the run record and prints `GSTACK_RESULT: skill=ship +status=complete run=`; `QUEUE_RECEIPT_STALE` means HEAD moved after the receipt (rewrite, +repost, rerun). A run that STOPs earlier ends with `GSTACK_RESULT: skill=ship status=refused run=-`. --- diff --git a/test/fixtures/workflow-required-steps.json b/test/fixtures/workflow-required-steps.json index 4b005e1ee..50c3ddfc8 100644 --- a/test/fixtures/workflow-required-steps.json +++ b/test/fixtures/workflow-required-steps.json @@ -118,7 +118,8 @@ "## Step 17: Push", "## Step 18: Prepare publication metadata", "## Step 20: Persist ship metrics", - "## Step 21: Plan-tune discoverability nudge (first-successful-ship only)" + "## Step 21: Plan-tune discoverability nudge (first-successful-ship only)", + "## Step 22: Terminal line (every run)" ], "sections/adversarial.md": [ "## Step 11: Adversarial review (always-on)" diff --git a/test/helpers/carve-guards.ts b/test/helpers/carve-guards.ts index 611b64727..53cddce87 100644 --- a/test/helpers/carve-guards.ts +++ b/test/helpers/carve-guards.ts @@ -155,7 +155,7 @@ export const CARVE_GUARDS: Record = { }, behavioral: 'external', externalTest: 'test/skill-e2e-ship-section-loading.test.ts', - maxSkeletonBytes: 82_000, // + v2.0 {{ASIDE_RESEARCH}} (Aside first, WebSearch fallback); measured 78_275. + gate integrity (HONEST_WORK_GATE_INTEGRITY W3): Step 16 stage 4 ZERO-RUN/unknown receipt rows, stage 5 honesty inventory, Step 17 open-gate ready-PR gate; measured 80,540 (2026-10-10). + rule 22 / GBRA-108 (2026-10-25): Step 22's terminal line (gstack-ship-receipt result, the GSTACK_RESULT line a parent greps) and Step 18's unattended routing (an open PR at HEAD gets its body updated, else handoff), both written as tight as they go after the 2026-10-14 tightening left 2 bytes of headroom; measured 81,711. + maxSkeletonBytes: 81_600, // + v2.0 {{ASIDE_RESEARCH}} (Aside first, WebSearch fallback); measured 78_275. + gate integrity (HONEST_WORK_GATE_INTEGRITY W3): Step 16 stage 4 ZERO-RUN/unknown receipt rows, stage 5 honesty inventory, Step 17 open-gate ready-PR gate; measured 80,540 (2026-10-10). + rule 22 / GBRA-108 (2026-10-25): Step 22's terminal line (gstack-ship-receipt result, the GSTACK_RESULT line a parent greps) and Step 18's unattended routing (an open PR at HEAD gets its body updated, else handoff), offset in part by tightening Steps 14, 16, 18 and 20 prose after the 2026-10-14 tightening left 2 bytes of headroom; measured 81,535. minUnionBytes: 181_000, // token-reduction Phases 1-2 (v1.69.x branch); measured union 201,464 mustContain: ['VERSION', 'CHANGELOG', 'review', 'merge', 'PR'], // v1.58.5.0: pre-push-guard install (#2077) stacks on the shared first-run-guidance preamble. @@ -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.6760, // 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). + gate integrity (HONEST_WORK_GATE_INTEGRITY W3): the shared GATE_SCAN_BLOCK in the core checklist (2.5) and after Step 7's child, the four-option gate question and record fields in 9.4, tests_ran states in Step 5, Gate edits and per-lane counts in the PR body with draft-while-open; measured 300,143 / 187,706 = 1.5990 (2026-10-10). + Honest Work wave merged (W2/W3 gate integrity in review/ship, W4 kernel + DONE line in every tier-2+ skill, W5/W7 in spec/ship): re-measured on the integrated tree (2026-10-10). + Oct 10 multi-agent wave PR E2 (ship/sections/handoff.md: the no-PR automation handoff, with its Section-index row and STOP pointer in the skeleton), offset by tightening Steps 1–3, 12, 14–17 and 20–21 prose so the skeleton stays under 81,000 bytes (80,997); C-pregate landed 1,123 union bytes in tests.md in between; measured 308,619 / 187,706 = 1.6442 on the integrated tree (2026-10-10). + next-wave Lane D (GBRA-40 item 12): the pr-body Issue links step (promotion candidates and `fix #N`, owner-confirmed Supersedes/credit, `--author` for app-identity gh, lookup failures, ISSUE_LINKS_MISSING) and the handoff's issue-links run, with the `## Issues` placeholder shortened; Step 15's `Fixes:` trailer rule offset by tightening Step 15 so the skeleton stays at 80,998; measured 309,483 / 187,706 = 1.6488 (2026-10-14). + GSTA-61 Capy merge asks: the on-demand capy-pr section (What changed with before/after images, Why, Approvals; loads only when Step 19 prints CAPY_PR: on, so a non-Capy ship pays one manifest line and the three-line CAPY_PR check); measured 313,265 / 187,706 = 1.6689 (2026-10-20). + rule 22 / GBRA-108 (2026-10-25): Step 22 terminal line and Step 18 unattended routing in the skeleton, the pr-body section's receipt-check sentence and the handoff's Step 22 pointer; measured 314,204 / 187,706 = 1.6739. + maxSizeRatio: 1.6740, // 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). + gate integrity (HONEST_WORK_GATE_INTEGRITY W3): the shared GATE_SCAN_BLOCK in the core checklist (2.5) and after Step 7's child, the four-option gate question and record fields in 9.4, tests_ran states in Step 5, Gate edits and per-lane counts in the PR body with draft-while-open; measured 300,143 / 187,706 = 1.5990 (2026-10-10). + Honest Work wave merged (W2/W3 gate integrity in review/ship, W4 kernel + DONE line in every tier-2+ skill, W5/W7 in spec/ship): re-measured on the integrated tree (2026-10-10). + Oct 10 multi-agent wave PR E2 (ship/sections/handoff.md: the no-PR automation handoff, with its Section-index row and STOP pointer in the skeleton), offset by tightening Steps 1–3, 12, 14–17 and 20–21 prose so the skeleton stays under 81,000 bytes (80,997); C-pregate landed 1,123 union bytes in tests.md in between; measured 308,619 / 187,706 = 1.6442 on the integrated tree (2026-10-10). + next-wave Lane D (GBRA-40 item 12): the pr-body Issue links step (promotion candidates and `fix #N`, owner-confirmed Supersedes/credit, `--author` for app-identity gh, lookup failures, ISSUE_LINKS_MISSING) and the handoff's issue-links run, with the `## Issues` placeholder shortened; Step 15's `Fixes:` trailer rule offset by tightening Step 15 so the skeleton stays at 80,998; measured 309,483 / 187,706 = 1.6488 (2026-10-14). + GSTA-61 Capy merge asks: the on-demand capy-pr section (What changed with before/after images, Why, Approvals; loads only when Step 19 prints CAPY_PR: on, so a non-Capy ship pays one manifest line and the three-line CAPY_PR check); measured 313,265 / 187,706 = 1.6689 (2026-10-20). + rule 22 / GBRA-108 (2026-10-25): Step 22 terminal line and Step 18 unattended routing in the skeleton, the pr-body section's receipt-check sentence and the handoff's Step 22 pointer; measured 314,027 / 187,706 = 1.6730. }, 'plan-ceo-review': { skill: 'plan-ceo-review',