mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-05 02:47:17 +02:00
test(ship-docsync): seed fault cases at their gate instead of replaying attempt 1
The post-dispatch fault cases (missing-marker, launch-failure, timeout-unsettled, late-result, stale-before, stale-after, recovery) now start from a fixture-owned attempt 1: the real actor prepares and dispatches it, its verbatim output is saved once, and the invocation journal carries its pre-dispatch entry with the child asset hashes. The model resumes at Parent processing with a trimmed read list, inspect named as the authoritative repository observation, and recovery's intermediate checkpoint folded into the next attempt's pre-dispatch entry. Assertions count only parent-issued transport events and require a read of the saved attempt-1 output; missing-asset and the legacy failure case keep the full model-driven first attempt, and their prompts are byte-identical.
This commit is contained in:
1 parent
dd5708e6e8
commit
fb52689822
3 files changed
+112
-20
No files matched your search
@@ -254,6 +254,38 @@ ${DOCS_CHECKPOINT_MARKER}
|
||||
return file;
|
||||
}
|
||||
|
||||
export const DOCS_SEEDED_AUDIT_ID = 'ship-docs-a1';
|
||||
const DOCS_CHILD_ASSETS = ['document-release/SKILL.md', 'document-release/sections/audit-scope.md', 'document-release/sections/release-body.md'];
|
||||
|
||||
export function docsActorSeeded(scenario: DocsFault): boolean {
|
||||
return scenario !== 'missing-asset' && scenario !== 'legacy-completion';
|
||||
}
|
||||
|
||||
export function seedDocsFirstAttempt(fixture: ReturnType<typeof fixtureDocs>, file: string) {
|
||||
const assets = DOCS_CHILD_ASSETS.map(relative => {
|
||||
const asset = path.join(fixture.skills, relative);
|
||||
if (!fs.existsSync(asset)) throw Error(`seeded attempt requires installed ${relative}`);
|
||||
return { asset, sha256: createHash('sha256').update(fs.readFileSync(asset)).digest('hex') };
|
||||
});
|
||||
const prepared = docsActorCommand(file, 'prepare', { audit_id: DOCS_SEEDED_AUDIT_ID });
|
||||
if (prepared.exit) throw Error(`seeded prepare failed: ${prepared.text}`);
|
||||
const { candidate, prompt } = JSON.parse(prepared.text) as { candidate: string; prompt: string };
|
||||
const dispatched = docsActorCommand(file, 'dispatch', { audit_id: DOCS_SEEDED_AUDIT_ID, candidate, prompt, run_in_background: 'false' });
|
||||
if (dispatched.exit === 24) throw Error(`seeded dispatch rejected: ${dispatched.text}`);
|
||||
const completion = path.join(fixture.home, `completion-${DOCS_SEEDED_AUDIT_ID}.md`);
|
||||
fs.writeFileSync(completion, dispatched.text, { flag: 'wx', mode: 0o600 });
|
||||
let handle = '';
|
||||
try { handle = JSON.parse(dispatched.text).task_id ?? ''; } catch {}
|
||||
const record = fs.readFileSync(fixture.invocation, 'utf8');
|
||||
if (record.split(DOCS_CHECKPOINT_MARKER).length !== 2) throw Error('invocation journal marker must occur exactly once');
|
||||
fs.writeFileSync(fixture.invocation, record.replace(DOCS_CHECKPOINT_MARKER, () => `### Checkpoint 1 — attempt 1 (fixture-owned prior state)
|
||||
Attempts used: 1. Prepare step 1: installed child assets present with sha256 ${assets.map(a => `${a.asset} ${a.sha256}`).join('; ')}. Prepare steps 2–3: audit ${DOCS_SEEDED_AUDIT_ID}; candidate ${candidate}; prompt ${prompt}. Launched with dispatch run_in_background=false; dispatch exit code ${dispatched.exit}; its verbatim output is saved once at ${completion}.${handle ? ` Returned child handle: ${handle}.` : ''}
|
||||
Next: Parent processing for attempt 1, starting at Collect. A repeated Prepare may confirm step 1 with one literal sha256sum of these three asset paths instead of re-reading them; a missing asset or changed hash blocks before launch.
|
||||
${DOCS_CHECKPOINT_MARKER}`));
|
||||
return { auditId: DOCS_SEEDED_AUDIT_ID, candidate, prompt, completion, exit: dispatched.exit, text: dispatched.text,
|
||||
events: load(file).events.length };
|
||||
}
|
||||
|
||||
if (import.meta.main) {
|
||||
const [action, file, ...rest] = process.argv.slice(2);
|
||||
if (action === 'hook') docsActorHook(file, fs.readFileSync(0, 'utf8'));
|
||||
|
||||
Reference in new issue
Block a user