From dd28170705383bebee5b30e1c6f18567f9b73031 Mon Sep 17 00:00:00 2001 From: fedster99 Date: Sun, 19 Jul 2026 11:36:05 +0200 Subject: [PATCH] feat: make ship handoffs self-contained --- ship/SKILL.md | 79 ++++++++++++++++++- ship/SKILL.md.tmpl | 79 ++++++++++++++++++- test/fixtures/golden/claude-ship-SKILL.md | 79 ++++++++++++++++++- test/fixtures/golden/codex-ship-SKILL.md | 79 ++++++++++++++++++- test/fixtures/golden/factory-ship-SKILL.md | 79 ++++++++++++++++++- test/ship-completion-report.test.ts | 91 ++++++++++++++++++++++ 6 files changed, 476 insertions(+), 10 deletions(-) create mode 100644 test/ship-completion-report.test.ts diff --git a/ship/SKILL.md b/ship/SKILL.md index eadffaa8f..204928aec 100644 --- a/ship/SKILL.md +++ b/ship/SKILL.md @@ -843,7 +843,7 @@ branch name wherever the instructions say "the base branch" or ``. # Ship: Fully Automated Ship Workflow -You are running the `/ship` workflow. This is a **non-interactive, fully automated** workflow. Do NOT ask for confirmation at any step. The user said `/ship` which means DO IT. Run straight through and output the PR URL at the end. +You are running the `/ship` workflow. This is a **non-interactive, fully automated** workflow. Do NOT ask for confirmation at any step. The user said `/ship` which means DO IT. Run straight through and include the PR URL in the final engineering handoff. **Only stop for:** - On the base branch (abort) @@ -1246,7 +1246,11 @@ Before pushing, re-verify if code changed during Steps 4-6: 2. **Build verification:** If the project has a build step, run it. Paste output. -3. **Rationalization prevention:** +3. **UI evidence gate:** For a user-visible UI diff, produce the matched + Before/After evidence from Step 22 before push. If unavailable, STOP; do not + push or create/update the PR/MR. + +4. **Rationalization prevention:** - "Should work now" → RUN IT. - "I'm confident" → Confidence is not evidence. - "I already tested earlier" → Code changed since then. Test again. @@ -1415,3 +1419,74 @@ through `gstack-version-bump`; never hand-roll the VERSION/package.json write. - **Never push without fresh verification evidence.** If code changed after Step 5 tests, re-run before pushing. - **Step 7 generates coverage tests.** They must pass before committing. Never commit failing tests. - **The goal is: user says `/ship`, next thing they see is the review + PR URL + auto-synced docs.** + +--- + +## Step 22: Full engineering handoff + +End every ship attempt with this self-contained report, even when stopped. Use each heading; +write `Not applicable` briefly when a category does not apply. + +Open with orientation, not status. Assume the reader remembers nothing from the +earlier conversation. + +```markdown +## What this work was about +Name the product, system, or feature being changed. In 2-4 sentences, state what it did before, +the concrete problem that motivated the work, and the intended outcome. Assume the reader remembers nothing from the earlier conversation. +Keep implementation, verification, and ship status in the sections below. + +## Engineering summary + +### Outcome +What shipped (version, branch, commit, PR/MR URL), or what blocked it. + +### Problem and root cause +What was wrong or missing, why, and the supporting evidence. + +### Investigation and decisions +Key findings, alternatives, decisions, and why this approach won. + +### Implementation +Changed behavior, components, data paths, APIs, migrations, infrastructure, and docs. + +### Verification +Fresh test/build/typecheck/lint/behavior/review/CI/deploy evidence; mark pass/fail/skipped. + +### Risks and operational impact +Tradeoffs, compatibility, rollout/migration, observability, rollback. + +### Remaining work +Unfinished work. Write `None` when the completion contract is fully satisfied. + +### Decision required +The user's next decision. Write `None` when no decision is required. +``` + +### UI before/after evidence + +For user-visible UI changes, include matched **Before** and **After** screenshots: + +1. Use a pre-change capture only if it faithfully represents the base; otherwise run the merge-base/base revision in an isolated worktree or use its known deployment. +2. Capture the current branch after implementation and verification. +3. Match route, application state, data, viewport, theme, and zoom. Use safe test data; never expose credentials, customer data, or private information. +4. Show `![Before](path)` and `![After](path)` inline; include both artifact paths. +5. Do not commit screenshot artifacts unless the repository explicitly requires it. + +If a faithful comparison is impossible, use the same report with Outcome blocked, +mark UI evidence incomplete, and STOP before Step 17. Do not push, create/update +the PR/MR, claim UI completion, or offer a waiver. + +### Put simply + +Final response section; nothing follows. It must stand on its own. Be intuitive, +extremely concise, and precise. Name the concrete subject before describing the +change. Never rely only on `it`, `this`, or `the change` to carry context. + +```markdown +### Put simply + +- **Why:** Why the named product, system, or feature needed to change. +- **What:** Its relevant before-and-now behavior. +- **How:** The essential mechanism, without unnecessary implementation detail. +``` diff --git a/ship/SKILL.md.tmpl b/ship/SKILL.md.tmpl index 068ac4fe5..d9d84a567 100644 --- a/ship/SKILL.md.tmpl +++ b/ship/SKILL.md.tmpl @@ -34,7 +34,7 @@ triggers: # Ship: Fully Automated Ship Workflow -You are running the `/ship` workflow. This is a **non-interactive, fully automated** workflow. Do NOT ask for confirmation at any step. The user said `/ship` which means DO IT. Run straight through and output the PR URL at the end. +You are running the `/ship` workflow. This is a **non-interactive, fully automated** workflow. Do NOT ask for confirmation at any step. The user said `/ship` which means DO IT. Run straight through and include the PR URL in the final engineering handoff. **Only stop for:** - On the base branch (abort) @@ -367,7 +367,11 @@ Before pushing, re-verify if code changed during Steps 4-6: 2. **Build verification:** If the project has a build step, run it. Paste output. -3. **Rationalization prevention:** +3. **UI evidence gate:** For a user-visible UI diff, produce the matched + Before/After evidence from Step 22 before push. If unavailable, STOP; do not + push or create/update the PR/MR. + +4. **Rationalization prevention:** - "Should work now" → RUN IT. - "I'm confident" → Confidence is not evidence. - "I already tested earlier" → Code changed since then. Test again. @@ -535,3 +539,74 @@ through `gstack-version-bump`; never hand-roll the VERSION/package.json write. - **Never push without fresh verification evidence.** If code changed after Step 5 tests, re-run before pushing. - **Step 7 generates coverage tests.** They must pass before committing. Never commit failing tests. - **The goal is: user says `/ship`, next thing they see is the review + PR URL + auto-synced docs.** + +--- + +## Step 22: Full engineering handoff + +End every ship attempt with this self-contained report, even when stopped. Use each heading; +write `Not applicable` briefly when a category does not apply. + +Open with orientation, not status. Assume the reader remembers nothing from the +earlier conversation. + +```markdown +## What this work was about +Name the product, system, or feature being changed. In 2-4 sentences, state what it did before, +the concrete problem that motivated the work, and the intended outcome. Assume the reader remembers nothing from the earlier conversation. +Keep implementation, verification, and ship status in the sections below. + +## Engineering summary + +### Outcome +What shipped (version, branch, commit, PR/MR URL), or what blocked it. + +### Problem and root cause +What was wrong or missing, why, and the supporting evidence. + +### Investigation and decisions +Key findings, alternatives, decisions, and why this approach won. + +### Implementation +Changed behavior, components, data paths, APIs, migrations, infrastructure, and docs. + +### Verification +Fresh test/build/typecheck/lint/behavior/review/CI/deploy evidence; mark pass/fail/skipped. + +### Risks and operational impact +Tradeoffs, compatibility, rollout/migration, observability, rollback. + +### Remaining work +Unfinished work. Write `None` when the completion contract is fully satisfied. + +### Decision required +The user's next decision. Write `None` when no decision is required. +``` + +### UI before/after evidence + +For user-visible UI changes, include matched **Before** and **After** screenshots: + +1. Use a pre-change capture only if it faithfully represents the base; otherwise run the merge-base/base revision in an isolated worktree or use its known deployment. +2. Capture the current branch after implementation and verification. +3. Match route, application state, data, viewport, theme, and zoom. Use safe test data; never expose credentials, customer data, or private information. +4. Show `![Before](path)` and `![After](path)` inline; include both artifact paths. +5. Do not commit screenshot artifacts unless the repository explicitly requires it. + +If a faithful comparison is impossible, use the same report with Outcome blocked, +mark UI evidence incomplete, and STOP before Step 17. Do not push, create/update +the PR/MR, claim UI completion, or offer a waiver. + +### Put simply + +Final response section; nothing follows. It must stand on its own. Be intuitive, +extremely concise, and precise. Name the concrete subject before describing the +change. Never rely only on `it`, `this`, or `the change` to carry context. + +```markdown +### Put simply + +- **Why:** Why the named product, system, or feature needed to change. +- **What:** Its relevant before-and-now behavior. +- **How:** The essential mechanism, without unnecessary implementation detail. +``` diff --git a/test/fixtures/golden/claude-ship-SKILL.md b/test/fixtures/golden/claude-ship-SKILL.md index eadffaa8f..204928aec 100644 --- a/test/fixtures/golden/claude-ship-SKILL.md +++ b/test/fixtures/golden/claude-ship-SKILL.md @@ -843,7 +843,7 @@ branch name wherever the instructions say "the base branch" or ``. # Ship: Fully Automated Ship Workflow -You are running the `/ship` workflow. This is a **non-interactive, fully automated** workflow. Do NOT ask for confirmation at any step. The user said `/ship` which means DO IT. Run straight through and output the PR URL at the end. +You are running the `/ship` workflow. This is a **non-interactive, fully automated** workflow. Do NOT ask for confirmation at any step. The user said `/ship` which means DO IT. Run straight through and include the PR URL in the final engineering handoff. **Only stop for:** - On the base branch (abort) @@ -1246,7 +1246,11 @@ Before pushing, re-verify if code changed during Steps 4-6: 2. **Build verification:** If the project has a build step, run it. Paste output. -3. **Rationalization prevention:** +3. **UI evidence gate:** For a user-visible UI diff, produce the matched + Before/After evidence from Step 22 before push. If unavailable, STOP; do not + push or create/update the PR/MR. + +4. **Rationalization prevention:** - "Should work now" → RUN IT. - "I'm confident" → Confidence is not evidence. - "I already tested earlier" → Code changed since then. Test again. @@ -1415,3 +1419,74 @@ through `gstack-version-bump`; never hand-roll the VERSION/package.json write. - **Never push without fresh verification evidence.** If code changed after Step 5 tests, re-run before pushing. - **Step 7 generates coverage tests.** They must pass before committing. Never commit failing tests. - **The goal is: user says `/ship`, next thing they see is the review + PR URL + auto-synced docs.** + +--- + +## Step 22: Full engineering handoff + +End every ship attempt with this self-contained report, even when stopped. Use each heading; +write `Not applicable` briefly when a category does not apply. + +Open with orientation, not status. Assume the reader remembers nothing from the +earlier conversation. + +```markdown +## What this work was about +Name the product, system, or feature being changed. In 2-4 sentences, state what it did before, +the concrete problem that motivated the work, and the intended outcome. Assume the reader remembers nothing from the earlier conversation. +Keep implementation, verification, and ship status in the sections below. + +## Engineering summary + +### Outcome +What shipped (version, branch, commit, PR/MR URL), or what blocked it. + +### Problem and root cause +What was wrong or missing, why, and the supporting evidence. + +### Investigation and decisions +Key findings, alternatives, decisions, and why this approach won. + +### Implementation +Changed behavior, components, data paths, APIs, migrations, infrastructure, and docs. + +### Verification +Fresh test/build/typecheck/lint/behavior/review/CI/deploy evidence; mark pass/fail/skipped. + +### Risks and operational impact +Tradeoffs, compatibility, rollout/migration, observability, rollback. + +### Remaining work +Unfinished work. Write `None` when the completion contract is fully satisfied. + +### Decision required +The user's next decision. Write `None` when no decision is required. +``` + +### UI before/after evidence + +For user-visible UI changes, include matched **Before** and **After** screenshots: + +1. Use a pre-change capture only if it faithfully represents the base; otherwise run the merge-base/base revision in an isolated worktree or use its known deployment. +2. Capture the current branch after implementation and verification. +3. Match route, application state, data, viewport, theme, and zoom. Use safe test data; never expose credentials, customer data, or private information. +4. Show `![Before](path)` and `![After](path)` inline; include both artifact paths. +5. Do not commit screenshot artifacts unless the repository explicitly requires it. + +If a faithful comparison is impossible, use the same report with Outcome blocked, +mark UI evidence incomplete, and STOP before Step 17. Do not push, create/update +the PR/MR, claim UI completion, or offer a waiver. + +### Put simply + +Final response section; nothing follows. It must stand on its own. Be intuitive, +extremely concise, and precise. Name the concrete subject before describing the +change. Never rely only on `it`, `this`, or `the change` to carry context. + +```markdown +### Put simply + +- **Why:** Why the named product, system, or feature needed to change. +- **What:** Its relevant before-and-now behavior. +- **How:** The essential mechanism, without unnecessary implementation detail. +``` diff --git a/test/fixtures/golden/codex-ship-SKILL.md b/test/fixtures/golden/codex-ship-SKILL.md index d99630c4b..df0cb54f1 100644 --- a/test/fixtures/golden/codex-ship-SKILL.md +++ b/test/fixtures/golden/codex-ship-SKILL.md @@ -829,7 +829,7 @@ branch name wherever the instructions say "the base branch" or ``. # Ship: Fully Automated Ship Workflow -You are running the `/ship` workflow. This is a **non-interactive, fully automated** workflow. Do NOT ask for confirmation at any step. The user said `/ship` which means DO IT. Run straight through and output the PR URL at the end. +You are running the `/ship` workflow. This is a **non-interactive, fully automated** workflow. Do NOT ask for confirmation at any step. The user said `/ship` which means DO IT. Run straight through and include the PR URL in the final engineering handoff. **Only stop for:** - On the base branch (abort) @@ -2429,7 +2429,11 @@ Before pushing, re-verify if code changed during Steps 4-6: 2. **Build verification:** If the project has a build step, run it. Paste output. -3. **Rationalization prevention:** +3. **UI evidence gate:** For a user-visible UI diff, produce the matched + Before/After evidence from Step 22 before push. If unavailable, STOP; do not + push or create/update the PR/MR. + +4. **Rationalization prevention:** - "Should work now" → RUN IT. - "I'm confident" → Confidence is not evidence. - "I already tested earlier" → Code changed since then. Test again. @@ -2801,3 +2805,74 @@ through `gstack-version-bump`; never hand-roll the VERSION/package.json write. - **Never push without fresh verification evidence.** If code changed after Step 5 tests, re-run before pushing. - **Step 7 generates coverage tests.** They must pass before committing. Never commit failing tests. - **The goal is: user says `/ship`, next thing they see is the review + PR URL + auto-synced docs.** + +--- + +## Step 22: Full engineering handoff + +End every ship attempt with this self-contained report, even when stopped. Use each heading; +write `Not applicable` briefly when a category does not apply. + +Open with orientation, not status. Assume the reader remembers nothing from the +earlier conversation. + +```markdown +## What this work was about +Name the product, system, or feature being changed. In 2-4 sentences, state what it did before, +the concrete problem that motivated the work, and the intended outcome. Assume the reader remembers nothing from the earlier conversation. +Keep implementation, verification, and ship status in the sections below. + +## Engineering summary + +### Outcome +What shipped (version, branch, commit, PR/MR URL), or what blocked it. + +### Problem and root cause +What was wrong or missing, why, and the supporting evidence. + +### Investigation and decisions +Key findings, alternatives, decisions, and why this approach won. + +### Implementation +Changed behavior, components, data paths, APIs, migrations, infrastructure, and docs. + +### Verification +Fresh test/build/typecheck/lint/behavior/review/CI/deploy evidence; mark pass/fail/skipped. + +### Risks and operational impact +Tradeoffs, compatibility, rollout/migration, observability, rollback. + +### Remaining work +Unfinished work. Write `None` when the completion contract is fully satisfied. + +### Decision required +The user's next decision. Write `None` when no decision is required. +``` + +### UI before/after evidence + +For user-visible UI changes, include matched **Before** and **After** screenshots: + +1. Use a pre-change capture only if it faithfully represents the base; otherwise run the merge-base/base revision in an isolated worktree or use its known deployment. +2. Capture the current branch after implementation and verification. +3. Match route, application state, data, viewport, theme, and zoom. Use safe test data; never expose credentials, customer data, or private information. +4. Show `![Before](path)` and `![After](path)` inline; include both artifact paths. +5. Do not commit screenshot artifacts unless the repository explicitly requires it. + +If a faithful comparison is impossible, use the same report with Outcome blocked, +mark UI evidence incomplete, and STOP before Step 17. Do not push, create/update +the PR/MR, claim UI completion, or offer a waiver. + +### Put simply + +Final response section; nothing follows. It must stand on its own. Be intuitive, +extremely concise, and precise. Name the concrete subject before describing the +change. Never rely only on `it`, `this`, or `the change` to carry context. + +```markdown +### Put simply + +- **Why:** Why the named product, system, or feature needed to change. +- **What:** Its relevant before-and-now behavior. +- **How:** The essential mechanism, without unnecessary implementation detail. +``` diff --git a/test/fixtures/golden/factory-ship-SKILL.md b/test/fixtures/golden/factory-ship-SKILL.md index a2acad24f..cfc9508f1 100644 --- a/test/fixtures/golden/factory-ship-SKILL.md +++ b/test/fixtures/golden/factory-ship-SKILL.md @@ -831,7 +831,7 @@ branch name wherever the instructions say "the base branch" or ``. # Ship: Fully Automated Ship Workflow -You are running the `/ship` workflow. This is a **non-interactive, fully automated** workflow. Do NOT ask for confirmation at any step. The user said `/ship` which means DO IT. Run straight through and output the PR URL at the end. +You are running the `/ship` workflow. This is a **non-interactive, fully automated** workflow. Do NOT ask for confirmation at any step. The user said `/ship` which means DO IT. Run straight through and include the PR URL in the final engineering handoff. **Only stop for:** - On the base branch (abort) @@ -2835,7 +2835,11 @@ Before pushing, re-verify if code changed during Steps 4-6: 2. **Build verification:** If the project has a build step, run it. Paste output. -3. **Rationalization prevention:** +3. **UI evidence gate:** For a user-visible UI diff, produce the matched + Before/After evidence from Step 22 before push. If unavailable, STOP; do not + push or create/update the PR/MR. + +4. **Rationalization prevention:** - "Should work now" → RUN IT. - "I'm confident" → Confidence is not evidence. - "I already tested earlier" → Code changed since then. Test again. @@ -3207,3 +3211,74 @@ through `gstack-version-bump`; never hand-roll the VERSION/package.json write. - **Never push without fresh verification evidence.** If code changed after Step 5 tests, re-run before pushing. - **Step 7 generates coverage tests.** They must pass before committing. Never commit failing tests. - **The goal is: user says `/ship`, next thing they see is the review + PR URL + auto-synced docs.** + +--- + +## Step 22: Full engineering handoff + +End every ship attempt with this self-contained report, even when stopped. Use each heading; +write `Not applicable` briefly when a category does not apply. + +Open with orientation, not status. Assume the reader remembers nothing from the +earlier conversation. + +```markdown +## What this work was about +Name the product, system, or feature being changed. In 2-4 sentences, state what it did before, +the concrete problem that motivated the work, and the intended outcome. Assume the reader remembers nothing from the earlier conversation. +Keep implementation, verification, and ship status in the sections below. + +## Engineering summary + +### Outcome +What shipped (version, branch, commit, PR/MR URL), or what blocked it. + +### Problem and root cause +What was wrong or missing, why, and the supporting evidence. + +### Investigation and decisions +Key findings, alternatives, decisions, and why this approach won. + +### Implementation +Changed behavior, components, data paths, APIs, migrations, infrastructure, and docs. + +### Verification +Fresh test/build/typecheck/lint/behavior/review/CI/deploy evidence; mark pass/fail/skipped. + +### Risks and operational impact +Tradeoffs, compatibility, rollout/migration, observability, rollback. + +### Remaining work +Unfinished work. Write `None` when the completion contract is fully satisfied. + +### Decision required +The user's next decision. Write `None` when no decision is required. +``` + +### UI before/after evidence + +For user-visible UI changes, include matched **Before** and **After** screenshots: + +1. Use a pre-change capture only if it faithfully represents the base; otherwise run the merge-base/base revision in an isolated worktree or use its known deployment. +2. Capture the current branch after implementation and verification. +3. Match route, application state, data, viewport, theme, and zoom. Use safe test data; never expose credentials, customer data, or private information. +4. Show `![Before](path)` and `![After](path)` inline; include both artifact paths. +5. Do not commit screenshot artifacts unless the repository explicitly requires it. + +If a faithful comparison is impossible, use the same report with Outcome blocked, +mark UI evidence incomplete, and STOP before Step 17. Do not push, create/update +the PR/MR, claim UI completion, or offer a waiver. + +### Put simply + +Final response section; nothing follows. It must stand on its own. Be intuitive, +extremely concise, and precise. Name the concrete subject before describing the +change. Never rely only on `it`, `this`, or `the change` to carry context. + +```markdown +### Put simply + +- **Why:** Why the named product, system, or feature needed to change. +- **What:** Its relevant before-and-now behavior. +- **How:** The essential mechanism, without unnecessary implementation detail. +``` diff --git a/test/ship-completion-report.test.ts b/test/ship-completion-report.test.ts new file mode 100644 index 000000000..a61ebd5ae --- /dev/null +++ b/test/ship-completion-report.test.ts @@ -0,0 +1,91 @@ +import { describe, expect, test } from 'bun:test'; +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +const root = join(import.meta.dir, '..'); + +const skillPaths = [ + 'ship/SKILL.md.tmpl', + 'ship/SKILL.md', + 'test/fixtures/golden/claude-ship-SKILL.md', + 'test/fixtures/golden/codex-ship-SKILL.md', + 'test/fixtures/golden/factory-ship-SKILL.md', +]; + +const engineeringHeadings = [ + '### Outcome', + '### Problem and root cause', + '### Investigation and decisions', + '### Implementation', + '### Verification', + '### Risks and operational impact', + '### Remaining work', + '### Decision required', +]; + +describe('ship completion report', () => { + for (const relativePath of skillPaths) { + test(`${relativePath} requires a self-contained engineering handoff`, () => { + const skill = readFileSync(join(root, relativePath), 'utf8'); + const handoff = skill.indexOf('## Step 22: Full engineering handoff'); + const workContext = skill.indexOf('## What this work was about', handoff); + const engineeringSummary = skill.indexOf('## Engineering summary', handoff); + const uiEvidence = skill.indexOf('### UI before/after evidence', handoff); + const putSimply = skill.lastIndexOf('### Put simply'); + const uiEvidenceGate = skill.indexOf('3. **UI evidence gate:**'); + const pushStep = skill.indexOf('## Step 17: Push'); + + expect(handoff).toBeGreaterThan(-1); + expect(workContext).toBeGreaterThan(handoff); + expect(engineeringSummary).toBeGreaterThan(workContext); + expect(skill).toContain('Use each heading'); + expect(skill.slice(workContext, engineeringSummary)).toContain( + 'Assume the reader remembers nothing from the earlier conversation.', + ); + expect(skill.slice(workContext, engineeringSummary)).toContain( + 'Name the product, system, or feature being changed', + ); + expect(skill.slice(workContext, engineeringSummary)).toContain( + 'what it did before', + ); + expect(skill.slice(workContext, engineeringSummary)).toContain( + 'the intended outcome', + ); + + let previousHeading = engineeringSummary; + for (const heading of engineeringHeadings) { + const headingIndex = skill.indexOf(heading, previousHeading); + expect(headingIndex).toBeGreaterThan(previousHeading); + previousHeading = headingIndex; + } + + expect(uiEvidence).toBeGreaterThan(previousHeading); + expect(skill).toContain('Write `None` when the completion contract is fully satisfied.'); + expect(skill).toContain('Write `None` when no decision is required.'); + expect(skill).toContain('matched **Before** and **After** screenshots'); + expect(skill).toContain('merge-base/base revision in an isolated worktree'); + expect(skill).toContain('current branch after implementation and verification'); + expect(skill).toContain('route, application state, data, viewport, theme, and zoom'); + expect(skill).toContain('Use safe test data; never expose credentials, customer data, or private information.'); + expect(skill).toContain('`![Before](path)` and `![After](path)` inline'); + expect(skill).toContain('include both artifact paths'); + expect(skill).toContain('Do not commit screenshot artifacts unless the repository explicitly requires it.'); + expect(skill).toContain('claim UI completion'); + expect(uiEvidenceGate).toBeGreaterThan(-1); + expect(pushStep).toBeGreaterThan(uiEvidenceGate); + expect(skill).toMatch(/do not\s+push or create\/update the PR\/MR/); + expect(skill).toContain('STOP before Step 17'); + expect(skill).toContain('or offer a waiver'); + expect(putSimply).toBeGreaterThan(uiEvidence); + expect(skill.slice(putSimply)).toContain('- **Why:**'); + expect(skill.slice(putSimply)).toContain('- **What:**'); + expect(skill.slice(putSimply)).toContain('- **How:**'); + expect(skill.slice(uiEvidence)).toContain('must stand on its own'); + expect(skill.slice(uiEvidence)).toContain('Name the concrete subject'); + expect(skill.slice(uiEvidence)).toContain('Never rely only on `it`, `this`, or `the change`'); + expect(skill.slice(handoff).match(/^### .+$/gm)?.at(-1)).toBe('### Put simply'); + expect(skill.slice(handoff).match(/^## Step /gm)?.length).toBe(1); + expect(skill).not.toContain('output the PR URL at the end'); + }); + } +});