Repository navigation
Preserve verified artifacts before Smithers worktree reaping #122
Description
Problem
Verified task artifacts can be deleted before Ultrafuzz publishes them from a Smithers worktree into the canonical run artifact directory.
The current lifecycle is:
- The generated prompt directs the agent to a task-owned
artifacts/<attempt>mirror inside its Smithers worktree. - The artifact-aware agent wrapper and verifier validate the files in that mirror before reporting task success.
- Ultrafuzz runs Smithers detached and an out-of-process polling synchronizer later copies mirror files into canonical storage.
- With
keep_workspaces=false, Smithers 0.28 reaps worktrees when a workflow finishes successfully. - Smithers' Git cleanliness check uses ordinary
git status --porcelain, which does not report ignored files. In a repository that ignoresartifacts/, a worktree containing only the required outputs can therefore look clean and be deleted. - If the workflow finishes between synchronization polls, the next Ultrafuzz artifact gate sees required outputs as missing even though the in-workflow verifier already accepted them.
This is a publication/reaping race across the Ultrafuzz-Smithers boundary. It is not a Zod-output failure: the Smithers task schema covers the summary object, while the filesystem contract is validated separately before Smithers parses or repairs that summary.
Secondary recovery livelock
The resulting failed run can also enter a permanent Modal relaunch loop:
- Runtime finalization records an
artifact-contractfailure, but missing required artifacts do not receive the narrowtask-output-validation-failureterminal marker. - Terminal-disposition inspection reports an operational or incomplete outcome.
- The Modal worker sees the linked durable run is already
failed, treats it as terminal, and does not invoke durable resume. - Eval-record repair refuses to finalize the operational/incomplete outcome.
- That refusal becomes
sandbox-exited; because model work already started, launch-state classification maps it toresume-requiredwith a relaunch action. - Every replacement worker follows the same path without running or resetting a node, so the durable checkpoint never advances.
Strict artifact validation is correct and must remain fail-closed. The controller must not advertise a state as resumable when the worker has no transition that can resume it.
This recovery portion is related to #111, but is a narrower deterministic zero-progress cycle.
Why current tests do not catch it
The generated-workflow tests inspect source structure, and reconciliation tests exercise a mirror that still exists. They do not run a real successful Smithers worktree lifecycle with ignored artifact files, automatic reaping, and delayed external synchronization.
Modal tests also establish the individual recovery behaviors but do not compose them end to end:
- a missing required artifact is an operational failure;
- eval-record repair rejects operational terminal failures; and
- a post-model
sandbox-exitedresult becomesresume-required.
Expected behavior
Validated task artifacts must become durable canonical artifacts before their worktree is eligible for reaping. Possible implementations include publishing atomically inside the artifact-aware completion boundary or retaining task worktrees until Ultrafuzz records a publication acknowledgement. Merely weakening validation or generating placeholder outputs is not acceptable.
For a terminal run that already has an artifact-contract failure, recovery must then choose one explicit, bounded outcome:
- perform a budget-preserving reset/retry of the identified failed task and its dependents; or
- emit a typed, non-resumable terminal operational failure.
Completed tasks and valid artifacts must not be rerun or fabricated.
Synthetic reproduction
- Create a generated Git fixture whose
.gitignoreignores/artifacts/. - Run one generated agent task that writes a valid required artifact only to its task worktree mirror.
- Let the artifact-aware wrapper and verifier succeed, allow the Smithers workflow to finish with
keep_workspaces=false, and delay external synchronization until after completion. - Confirm that automatic worktree reaping removes the only copy and the canonical artifact gate fails.
- Start Modal recovery against the persisted failed state and confirm that no resume/reset command runs while outer classification requests another relaunch.
The fixture must contain only generated repository content and synthetic artifact names.
Acceptance criteria
- An integration test covers a real successful Smithers worktree lifecycle with
/artifacts/ignored,keep_workspaces=false, and synchronization after workflow completion. - Every verifier-approved required artifact is present in canonical storage after Smithers worktree cleanup.
- Publication is atomic, path-safe, contract-validated, and durable before cleanup can remove the mirror.
- An end-to-end synthetic test covers artifact-gate failure through Modal recovery classification.
- Recovery either advances the durable checkpoint through an explicit bounded task reset, or terminates with a typed non-resumable failure.
- A failed terminal run cannot produce an unbounded sequence of
resume-requiredgenerations with an unchanged checkpoint. - Completed nodes are preserved and retry accounting remains exact.
- Strict artifact contracts remain enforced; no placeholder or fabricated artifact is introduced.
- Tests and diagnostics contain no private target names, paths, prompts, findings, reports, or credentials.
Activity
[-]Prevent Modal relaunch livelock after terminal artifact-contract failures[/-][+]Preserve verified artifacts before Smithers worktree reaping[/+]fix(modal): charge the pre-model retry budget to pre-model attempts (#…
fix(modal): reset the pre-model streak on the overseer relaunch path (#…
Modal launch budget: stop charging post-model sandbox exits against t…
aviggiano commentedon Aug 7, 2026
Closing. PR #140 (
75da43c) shipped the artifact preservation but declared only "Fixes #139", which left this open by omission. The integration test is atpackages/runtime/test/smithers-artifact-publication.integration.test.ts:11.The remaining piece — the composed artifact-gate → Modal-recovery-classification path — shipped separately in #337 (
d3eebcd, closing #326), and the bounded-outcome half is PR #288, now merged.Tracked in #327.