test(shared-libs): seed the lifecycle replay's first Step 3 pass instead of replaying it

shared-libs-review-lifecycle ran ~88% of its 300 s session budget (12-run
census median 265 s, 4/24 sessions timed out). The fixture now executes pass 1's
Step 3 once with the real logger and Git: a real unused REVIEW_START, then the
diff, inventories, attributes/config/index flags, gstack-review-read output and
every file's bytes and sha256, saved to one observation. The model resumes at
Step 4 with an exact four-file first read, the observation named as the
authoritative pass-1 repository read, one post-fix verification, an explicit
pass-2 read list and a twelve-line summary. Pass 2 still runs its own --start,
diff, reads, fingerprint and stage actor before --finish.

The actor scope now states that a current settled final-pass actor result
supplies the replaced QA/adversarial prerequisites and that the no-credit
disclosure is a reporting label: one r1 session persisted completed:false
from that ambiguity.

New assertions: the final binding never uses the seeded token's start or tree,
and the observation was read; free controls finish the seeded token (binding
changed) and omit the observation read, and both fail.
This commit is contained in:
garrytan committed 2026-09-30 19:36:02 +00:00
1 parent ac177337a1
commit ea7fbbcb7c
4 files changed
+127 -11

No files matched your search

+8 -2
View File
@@ -13,7 +13,7 @@ import {
installHostileGitConfig, installInterpreterCanary, installNormalizingFilter,
isGuardedGitRequest, isInternalClaudeGitRequest,
installSourceShims, readRequests, reviewLifecycleInstructions, reviewPrompt, reviewRevalidationPrompt,
reviewRecords, runSharedCapture, runSharedInteractive, seedOpportunitySources,
reviewRecords, runSharedCapture, runSharedInteractive, seedLifecycleFirstPass, seedOpportunitySources,
seedReviewSources, seedSkippedAdvisory, snapshotFixture, specialistFixture,
sharedReadOnlyViolations, standaloneInstructions, toolCommandTrace, type SharedLibsFixture,
SharedCaptureAccumulator, type SharedCaptureAttempt, SHARED_LIBS_ROOT,
@@ -155,9 +155,10 @@ describeE2E('Shared-code safety and review lifecycle (gate)', () => {
const instructions = reviewLifecycleInstructions(f);
const input = specialistFixture(f);
const stageActor = createLifecyclePrerequisiteActor(f);
const seed = seedLifecycleFirstPass(f);
let questions: any[] = [];
await recordCapture(attempt, choose, 'shared-libs-review-lifecycle', async () => {
const capture = await runSharedInteractive(f, 'shared-libs-review-lifecycle', reviewPrompt(f, instructions, input, stageActor), choose, { stageActor, attempt });
const capture = await runSharedInteractive(f, 'shared-libs-review-lifecycle', reviewPrompt(f, instructions, input, stageActor, seed), choose, { stageActor, attempt });
questions = capture.questions;
return capture.result;
}, result => {
@@ -174,6 +175,11 @@ describeE2E('Shared-code safety and review lifecycle (gate)', () => {
completed: true, converged: true });
expect(last.review_binding.state).toBe('verified');
expect(last.review_binding.branch_id).toBe(createHash('sha256').update('feature/a').digest('hex'));
// The seeded pass-1 token stays unused; the model's own post-edit start binds the final record.
expect(last.review_binding.started_at).not.toBe(seed.startedAt);
expect(last.review_binding.start_wtree).not.toBe(seed.startWtree);
expect(result.toolCalls.some((call: any) => call.tool === 'Read' && call.input?.file_path === seed.observation)
|| toolCommandTrace(result).some(command => command.includes(seed.observation))).toBe(true);
// Earlier cycles cannot stand in for the final zero-edit record. Both
// the explicit choice and its original identity must survive there.
const findings = last.findings || [];