Isolation and bundle snapshot integrity
Name the evidence for each boundary. A scan detects; it does not deny. A policy object is not an
active OS boundary. Report the weakest live layer.
The three isolations
- The Builder may read the user request, admitted public context, approved public sources, and its candidate tree.
- The Built Harness sees only the public task projection and registered solve tools.
- The verifier runs at the host boundary on artifact-only requests.
Evidence for an isolation
IsolationStrength is physical | contractual. Tool absence or prompt wording alone is isolation: none.
Missing, stale, or mismatched evidence is a typed non-result, never a score.
The probe must prove both sides: the denied read is refused under the deny profile and the control
read returns the canary under the permissive profile. If the probe cannot run, use
available: false; this is different from a leak. Both are contractual.
composedIsolation is physical only when the executed probe is physical and the session handshake
shows the built role used the isolated permissions profile.
Candidate workspace access rules
execFile, path containment, bounded output, and a scrubbed environment do not make the Builder
toolkit isolated. bun install and uv add can run package lifecycle code. The research and install
interface needs an executed OS-isolation check. proveCandidateIsolation returns proof, refusal, or
unavailable. Unavailable is not proof.
Bundle snapshot identity
validate candidate → fingerprint bytes → create bundle snapshot → evaluate.
Candidate validation checks the bundle before acceptance. Fingerprinting gives its bytes a stable
identity. The immutable bundle snapshot binds later evaluation and scores to those exact bytes.
Executed means that the evaluated snapshot carries the matching fingerprint.
agentHash: solve side.
correctnessModelHash: correctness-model/ except tasks.json.
taskSetHash: correctness-model/tasks.json, ids, and content.
Keep task identity out of correctnessModelHash, otherwise a task edit looks like verifier drift. A candidate
that fails validation has no accepted fingerprint. Claim.create() requires all three hashes.
What each layer proves
| Evidence | Claim |
|---|
| import or token scan | named imports are statically refused |
| allowlisted projection | known public fields cross |
| scrubbed environment | named and shaped secrets are removed from this child |
| executed deny read and control read | tested reads are denied under that profile |
| session profile handshake | verified session used the declared profile |
| provider session outside sandbox | provider confinement is unproven |
| post-run scan | later tampering is detectable |
Do not call detection prevention or generalise process evidence into full per-case isolation.
Public projection and authority
Build public objects by allowlist:
const publicTask = {
taskId: hidden.taskId,
visibleSpec: structuredClone(hidden.visibleSpec),
};
Do not clone hidden data and delete known secrets. New hidden fields would leak. Break references
so solve-side mutation cannot reach evaluator state.
The controller keeps the submission handle and reads accepted facts from it. Generated code gets a
narrow port and may propose but cannot create the accepted fact. Generated verification code may name a pinned engine but
cannot choose a command.
Threats and checks
Treat solve code, tool arguments, model text, retrieved pages, generated files, and verifier stdout
as untrusted. Protect hidden expectations and control literals, verifier inputs and raw findings,
credentials, sibling workspaces and evidence, controller handles, and immutable evidence.