From be348ba24a2487abb03e7c90ccd114491aacec0e Mon Sep 17 00:00:00 2001 From: garrytan Date: Sat, 3 Oct 2026 00:12:00 +0000 Subject: [PATCH] ship: drop issue/incident IDs and the 'continue silently' suppressor (s06 M2, s06 M3, s06 M4, s06 M7) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - M2/M3: '(#1946)' and '(#1079)' removed from the credential guard and REST fallback headings; the rules are unchanged. - M4: the audit-failure fallback states the reason (a skipped audit lets unverified plan items ship as done) instead of 'the failure shape that VAS-449 surfaced'. - M7: 'Continue silently — just note the counts briefly' -> report the pass counts in one line and continue to Step 6 (Step 16 cites these counts). Not changed: s06 M1, the Step 16 IRON LAW (UC2 gate keeps its wording). W7a pin: test/ship-plan-completion-invariants.test.ts:127 pinned the VAS-449 sentence; it now checks that the audit-failure fallback still forbids a silent fail-open (case-insensitive). Negative control: deleting that sentence turns it red. expected red until the regeneration commit --- ship/SKILL.md.tmpl | 2 +- ship/sections/plan-completion.md.tmpl | 4 ++-- ship/sections/pr-body.md.tmpl | 2 +- ship/sections/tests.md.tmpl | 2 +- test/ship-plan-completion-invariants.test.ts | 4 +++- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ship/SKILL.md.tmpl b/ship/SKILL.md.tmpl index 1154b6dcf..09b39e435 100644 --- a/ship/SKILL.md.tmpl +++ b/ship/SKILL.md.tmpl @@ -481,7 +481,7 @@ stage 4's recovery before publication. Otherwise continue to Step 17. ## Step 17: Push -**Credential pre-push guard (#1946) — run before the push:** +**Credential pre-push guard — run before the push:** ```bash _REDACT_PREPUSH=$(~/.claude/skills/gstack/bin/gstack-config get redact_prepush_hook 2>/dev/null || echo "false") diff --git a/ship/sections/plan-completion.md.tmpl b/ship/sections/plan-completion.md.tmpl index 85414a694..cada4329e 100644 --- a/ship/sections/plan-completion.md.tmpl +++ b/ship/sections/plan-completion.md.tmpl @@ -43,8 +43,8 @@ Counts map one-to-one to the classifications above and sum to total_items. No pl 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, AskUserQuestion: A) Skip audit and ship, recording the reason in the PR body and -Step 20 metrics; B) Stop and fix the audit (recommended/default). Silent fail-open -is the failure shape that VAS-449 surfaced. +Step 20 metrics; B) Stop and fix the audit (recommended/default). Never fail open +silently: a skipped audit would let unverified plan items ship as done. --- diff --git a/ship/sections/pr-body.md.tmpl b/ship/sections/pr-body.md.tmpl index 3a7b15e92..350040a74 100644 --- a/ship/sections/pr-body.md.tmpl +++ b/ship/sections/pr-body.md.tmpl @@ -142,7 +142,7 @@ or `glab mr update -d "$(cat "$PR_BODY_FILE")"` (GitLab). Update the title with the same scanned `NEW_TITLE`: `gh pr edit --title "$NEW_TITLE"` (or `glab mr update -t "$NEW_TITLE"`). -**REST fallback (#1079):** if `gh pr edit` fails with the `repository.pullRequest.projectCards` GraphQL deprecation, do not re-ask for auth. Use the SAME scanned file: `PR_NUMBER=$(gh pr view --json number -q .number)`, then `gh api "repos/{owner}/{repo}/pulls/$PR_NUMBER" -X PATCH -F body=@"$PR_BODY_FILE"`; for the title use `gh api "repos/{owner}/{repo}/pulls/$PR_NUMBER" -X PATCH -f title="$NEW_TITLE"`. +**REST fallback:** if `gh pr edit` fails with the `repository.pullRequest.projectCards` GraphQL deprecation, do not re-ask for auth. Use the SAME scanned file: `PR_NUMBER=$(gh pr view --json number -q .number)`, then `gh api "repos/{owner}/{repo}/pulls/$PR_NUMBER" -X PATCH -F body=@"$PR_BODY_FILE"`; for the title use `gh api "repos/{owner}/{repo}/pulls/$PR_NUMBER" -X PATCH -f title="$NEW_TITLE"`. **Self-check:** re-fetch the title and assert it starts with `v$NEW_VERSION `. Retry once if wrong, then surface any failure. Print the existing URL and continue to Step 20; do not run the create commands below. diff --git a/ship/sections/tests.md.tmpl b/ship/sections/tests.md.tmpl index c4e7cf871..23dfa90a1 100644 --- a/ship/sections/tests.md.tmpl +++ b/ship/sections/tests.md.tmpl @@ -44,7 +44,7 @@ for failure detail. **After triage:** If any in-branch failures remain unfixed, **STOP**. Do not proceed. If all failures were pre-existing and handled (fixed, TODOed, assigned, or skipped), continue to Step 6. -**If all pass:** Continue silently — just note the counts briefly. +**If all pass:** Report the pass counts in one line and continue to Step 6. --- diff --git a/test/ship-plan-completion-invariants.test.ts b/test/ship-plan-completion-invariants.test.ts index c9592b7bc..48d65d446 100644 --- a/test/ship-plan-completion-invariants.test.ts +++ b/test/ship-plan-completion-invariants.test.ts @@ -123,7 +123,9 @@ describe('ship/SKILL.md — Plan Completion gate invariants (VAS-449 remediation test('Subagent failure: fail-closed, not silent fail-open', () => { expect(skill).not.toMatch(/Never block \/ship on subagent failure\.\s*$/m); - expect(skill.replace(/\s+/g, ' ')).toContain('Silent fail-open is the failure shape that VAS-449 surfaced'); + // The audit-failure fallback still forbids a silent fail-open (meaning, not the old incident ID). + const fallback = skill.slice(skill.indexOf('**Audit-failure fallback:**'), skill.indexOf('**Audit-failure fallback:**') + 800); + expect(fallback).toMatch(/fail[- ]open/i); expect(skill).toMatch(/Stop and fix the audit/); });