From ebb8f9f8e6b5ed70e8c71a53c8aaed6aa733979f Mon Sep 17 00:00:00 2001 From: garrytan Date: Mon, 26 Oct 2026 02:51:42 +0000 Subject: [PATCH] test: pin the shared-preamble provenance skip and the new Boil the Ocean wording (ship Step 7) preamble-hoist: on every host, tier and render option the pointer allows the skip only when the skill's own Read is in context. agents-digest and gstack-skill-start: the digest bullet and the lake intro say complete coverage, minimal code, never the retired phrasing. Each fails at 9af36d010. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- test/agents-digest.test.ts | 14 ++++++++++++++ test/gstack-skill-start.test.ts | 20 ++++++++++++++++++++ test/preamble-hoist.test.ts | 15 +++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/test/agents-digest.test.ts b/test/agents-digest.test.ts index 6eed47262..e598f1e38 100644 --- a/test/agents-digest.test.ts +++ b/test/agents-digest.test.ts @@ -14,6 +14,7 @@ import { DIGEST_RELPATH, DIGEST_BYTE_BUDGET, } from '../scripts/gen-agents-digest'; +import { expectAbsent, expectMentions } from './helpers/prompt-structure'; const ROOT = path.resolve(import.meta.dir, '..'); const digestPath = path.join(ROOT, DIGEST_RELPATH); @@ -53,6 +54,19 @@ describe('agents-digest', () => { // The ladder must keep the completeness reconciliation clause. }); + // Generated by /ship Step 7 coverage audit (GSTA-96). + // Value: protects=the digest's Boil the Ocean bullet says complete coverage, minimal code: the whole requirement and no code beyond it; + // fails_when=the generator's Ethos bullet returns to "do the complete thing" or drops the no-code-beyond half; + // why_new=the freshness and section tests above pass for any Ethos wording; + // seam=none; no_claim=that agents reading the digest act on it (an eval question) + test('the Ethos bullet measures completeness in coverage, not code', () => { + const ethos = fs.readFileSync(digestPath, 'utf-8').split('## Ethos')[1]!.split('\n## ')[0]!; + const bullet = ethos.split('\n').find(line => line.startsWith('- **Boil the Ocean**')); + expect(bullet).toBeDefined(); + expectMentions(bullet!, [['complete coverage', 'minimal code'], ['whole requirement', 'no code beyond']], 'digest Boil the Ocean bullet'); + expectAbsent(bullet!, ['do the complete thing', 'completeness cheap'], 'digest Boil the Ocean bullet'); + }); + test('setup never copies the digest onto a user AGENTS.md (print-path only)', () => { const setup = fs.readFileSync(path.join(ROOT, 'setup'), 'utf-8'); // The explainer arms print the digest path, anchored to the script's own diff --git a/test/gstack-skill-start.test.ts b/test/gstack-skill-start.test.ts index 63f1f9999..d97759365 100644 --- a/test/gstack-skill-start.test.ts +++ b/test/gstack-skill-start.test.ts @@ -23,6 +23,7 @@ import * as os from 'os'; import * as path from 'path'; import { generatePreamble } from '../scripts/resolvers/preamble'; import { HOST_PATHS, type TemplateContext } from '../scripts/resolvers/types'; +import { expectAbsent, expectMentions } from './helpers/prompt-structure'; const ROOT = path.resolve(import.meta.dir, '..'); const START = path.join(ROOT, 'bin', 'gstack-skill-start'); @@ -518,6 +519,25 @@ describe('gstack-skill-start behavior', () => { } }); + // Generated by /ship Step 7 coverage audit (GSTA-96). + // Value: protects=the one-time lake intro a cold home emits introduces Boil the Ocean as complete coverage, minimal code; + // fails_when=the intro returns to "do the complete thing" or drops the no-code-beyond half; + // why_new=onboarding-moved-literals pins only the intro's URL; the tests here check when it fires, not what it says; + // seam=none; no_claim=how the model paraphrases the intro to the user + test('the lake intro states complete coverage, minimal code', () => { + const freshGh = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-ss-lake-')); + fs.writeFileSync(path.join(freshGh, 'config.yaml'), 'update_check: false\n'); + try { + const out = runStart([], { GSTACK_HOME: freshGh }); + const intro = out.split(/^GSTACK_INSTRUCTION_BEGIN: lake-intro .*$/m)[1]?.split(/^GSTACK_INSTRUCTION_END$/m)[0]; + expect(intro, out).toBeDefined(); + expectMentions(intro!, [['boil the ocean', 'complete coverage', 'minimal code', 'whole requirement', 'no code beyond']], 'lake-intro'); + expectAbsent(intro!, ['do the complete thing', 'marginal cost near-zero'], 'lake-intro'); + } finally { + fs.rmSync(freshGh, { recursive: true, force: true }); + } + }); + test('display-only tips ack at emit and never re-fire (OV6)', () => { const freshGh = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-ss-refire-')); fs.writeFileSync(path.join(freshGh, 'config.yaml'), 'update_check: false\n'); diff --git a/test/preamble-hoist.test.ts b/test/preamble-hoist.test.ts index 8d914626c..c020bb5cd 100644 --- a/test/preamble-hoist.test.ts +++ b/test/preamble-hoist.test.ts @@ -23,6 +23,7 @@ import { generateSharedPreambleFile, generateSkillPreamble, hoistsPreamble } fro import { HOST_PATHS, type TemplateContext } from '../scripts/resolvers/types'; import { ALL_HOST_NAMES } from '../hosts/index'; import { SHARED_POINTER_HEADING, SHARED_PREAMBLE_FILE, readSkillEffective } from './helpers/skill-startup'; +import { expectAbsent, expectMentions } from './helpers/prompt-structure'; const SKILLS = ['ship', 'review', 'qa', 'investigate', 'retro', 'office-hours', 'plan-ceo-review', 'plan-eng-review', 'plan-design-review', 'plan-devex-review', 'make-pdf', 'gstack-upgrade', 'ios-fix']; @@ -97,4 +98,18 @@ describe('shared-preamble hoist', () => { expect(own.slice(0, start), label(ctx)).toContain(`shared preamble \`${id}\``); } }); + + // Generated by /ship Step 7 coverage audit (GSTA-96). + // Value: protects=the pointer lets a skill skip the Read only when its own Read of the shared file is in context, not any text carrying the id heading; + // fails_when=the clause reverts to "whose first heading names this id", which pasted or injected text can satisfy; + // why_new=only ship's four goldens hold the bytes, and they regenerate with the resolver; + // seam=none; no_claim=that a model honors provenance (an eval question; resolver output only) + test('the pointer ties skipping the shared Read to the skill\'s own Read, not to the id heading', () => { + for (const ctx of contexts()) { + if (!hoistsPreamble(ctx)) continue; + const pointer = generateSkillPreamble(ctx).split('\n## ', 1)[0]!; + expectMentions(pointer, [['if your read of that file', 'headed by this id', 'still in context', 'do not read it again', 'otherwise read']], label(ctx)); + expectAbsent(pointer, ['whose first heading names'], label(ctx)); + } + }); });