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/); });