mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-01 22:45:02 +01:00
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>
This commit is contained in:
1 parent
2acf1a44a8
commit
ebb8f9f8e6
3 files changed
+49
No files matched your search
@@ -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
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user