From 8dd3c44fc661d59feb5df46b653b335b15d7671b Mon Sep 17 00:00:00 2001 From: garrytan Date: Tue, 29 Sep 2026 21:49:46 +0000 Subject: [PATCH] fix(qa): checkpoint receipts print the report link for their exploration file qa-functional-webhook-report failed in two of three censuses because the report linked .qa-evidence/NNN capture folders as "checkpoints" and never linked exploration-NNN.json. The checkpoint receipt now prints link: [checkpoint NNN](exploration-NNN.json), and the functional report template says capture folders are not checkpoints. --- lib/qa-evidence.ts | 3 ++- qa/templates/functional-report-template.md | 1 + test/qa-evidence.test.ts | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/qa-evidence.ts b/lib/qa-evidence.ts index 0b04ab54d..d47d004e1 100644 --- a/lib/qa-evidence.ts +++ b/lib/qa-evidence.ts @@ -193,7 +193,8 @@ function checkpoint(root: string, checkpointId: string, source: string | Record< const captured = readQaCapture(root, intent.capture); const value = { observationCommand: intent.observationCommand, observed: captured.observed, hypothesis: intent.hypothesis, nextCommand: intent.nextCommand }; const sha256 = publish(root, `exploration-${checkpointId}.json`, value); - return { action: 'checkpoint', id: checkpointId, status: 'complete', sha256, capture: intent.capture, captureSha256: captured.sha256, intentSha256: hash(bytes), exitCode: 0 }; + return { action: 'checkpoint', id: checkpointId, status: 'complete', sha256, capture: intent.capture, captureSha256: captured.sha256, intentSha256: hash(bytes), + link: `[checkpoint ${checkpointId}](exploration-${checkpointId}.json)`, exitCode: 0 }; } function materialize(root: string, source: string) { diff --git a/qa/templates/functional-report-template.md b/qa/templates/functional-report-template.md index 1838fc585..96a3189c2 100644 --- a/qa/templates/functional-report-template.md +++ b/qa/templates/functional-report-template.md @@ -33,6 +33,7 @@ evidence and regression baselines. Do not combine their scores or outcomes. ## Discoveries and permanent tests Link each `exploration-NNN.json` checkpoint, saved before its next probe, in this report. +Each checkpoint receipt prints its `link`; `.qa-evidence/NNN` capture folders are not checkpoints. Use one Markdown entry per checkpoint, for example: - [checkpoint 001](exploration-001.json) — how this observation shaped the next probe. diff --git a/test/qa-evidence.test.ts b/test/qa-evidence.test.ts index b54e0e8fe..9ec3f7ea9 100644 --- a/test/qa-evidence.test.ts +++ b/test/qa-evidence.test.ts @@ -43,7 +43,7 @@ test('native capture executes once, preserves exact JSON and stderr, and materia f.json('intent.json', { capture: '001', observationCommand: 'first native command', hypothesis: 'The successful boundary suggests testing the rejected input next.', nextCommand: 'second native command' }); const checkpoint = f.run('checkpoint', f.root, '001', 'intent.json'); expect(checkpoint.status, checkpoint.stderr).toBe(0); - expect(receipt(checkpoint.stdout)).toMatchObject({ action: 'checkpoint', status: 'complete', id: '001' }); + expect(receipt(checkpoint.stdout)).toMatchObject({ action: 'checkpoint', status: 'complete', id: '001', link: '[checkpoint 001](exploration-001.json)' }); expect(JSON.parse(fs.readFileSync(path.join(f.root, 'exploration-001.json'), 'utf8'))).toEqual({ observationCommand: 'first native command', observed, hypothesis: 'The successful boundary suggests testing the rejected input next.', nextCommand: 'second native command', });