Repository navigation
Description
Current state: PR #268 is Ready at fc9d2328. The current-head review reports earlier fixes in code but retains two blockers: the production serve CLI omits the required now argument, and the namespace smoke test errors rather than skipping when namespaces are unavailable. Its focused run reported 23 passed / 1 failed. This partial offline slice does not complete M0–M2.
Decision needed: none now; the responsible maintainers decide the full M0–M2 scope and goal acceptance after the PR #268 findings are addressed.
Next action: Assignee NumberWan addresses those blockers with targeted CLI and unavailable-namespace evidence. Actual OS confinement remains unqualified on the reported host; code-level fixes and test results do not establish milestone acceptance or M3 authorization.
Current decision and outstanding contracts — 2026-10-31
- Current assignee: NumberWan. The earlier offline M0–M2 request and comments saying assignment was pending are historical. Assignment does not itself accept the full proposed M0–M2 scope, M3, paid model calls, accelerator time or a speed pilot.
- Draft #268, head
56a40049148ced7bb80e60249a8f5df40d5c1587, is an open partial offline prepare/submit/serve slice, not M0–M2 completion. Its body explicitly excludes Claude Code/Codex drivers, SwarmFlow template, close/incumbent advancement and campaign-template fields. Its historical “no assignee” sentence is superseded by the Issue assignment. No synthetic latency or fixture backend is hardware or OS-confinement evidence. - The latest technical follow-up, inspected at
37166b6f7323c76a091e423a7163ac99c4ae01ac, recognizes the direction of distinct attempt binding and build/smoke/trial confinement, but retains these unverified contracts:- Timeout after claim/execution must preserve settlement or ambiguity/charges, not cancel a reserved attempt. Any next attempt requires a new canonical binding rooted in the unchanged round contract and sufficient cumulative capacity; restart must not reset identity/accounting.
- Persistent absolute deadline enforcement must cover claim/launch, submission intake and running work, not only reservation. Include reserved-before/launch-after and started-before/late-submission cases across restart.
- Confinement covers build/import/smoke and trial/validation. Actual OS denial (or fail-closed refusal when unavailable) is required; mocked path filtering, cwd or a callable is not isolation evidence.
- Current code review requires changes: review 5709723274 is
REQUEST_CHANGESon the same56a40049head. Its existing findings are P1 protected reads/coordinator environment exposure, P2 durable execution claim written after execution, and P2 deadline gaps at submission/launch. The additional same-head review 5722796981 also requests changes for P1 submission intake following lane-controlled symlinks: a synthetic external-canary, function-level reproduction confirmed an outside file was copied into the outbox before candidate execution. This is distinct from execution confinement; reject symlinks/nonregular entries before content reads and use root-confined, race-resistant no-follow intake, with the requested synthetic rejection evidence. The author should address those boundaries with the requested targeted evidence; fixture tests and source review are not OS-confinement qualification. No current-head Ready full-check/installed-package evidence was observed by that review. This records existing findings, not a new review or new scope. - The proposed pilot remains a workflow-policy comparison, not isolated concurrency speedup: sequential and parallel lanes see different incumbent histories.
- Next: the existing assignee addresses the scoped contract/review gaps; responsible maintainers retain the scope/acceptance decision and task: measure whether InferRSI helps Claude Code and Codex optimize inference tasks #248 driver coordination. This summary grants no broader scope, budget, incumbent advancement or milestone acceptance.
The original proposal, constraints and completion criteria below are preserved; suggestions above are not silently promoted to accepted implementation.
Goal and acceptance
-
Problem / desired outcome: An InferRSI campaign advances one candidate at a time. Each round names its parent revision and builds one candidate in isolation (campaign plan RFC, #30), and each step changes one declared plane (AGENTS.md). Multi-agent harnesses could explore several independent directions at once: jiuwenswarm SwarmFlow workflows fan out Claude Code or Codex workers, and a script can start several Claude Code or Codex sessions directly. InferRSI gives them no safe way to do it today:
- Each agent would run the runner itself, on devices other agents may be using.
- The only composition rule, in harness improvement, covers at most two skill-text edits, not engine code.
- SwarmFlow's own worktrees start from the remote default branch, not from the campaign incumbent.
- Nothing records a round of parallel results, including the negative ones, against the campaign plan.
This issue proposes a parallel round owned by InferRSI:
- A frozen round plan declares N lanes with disjoint file scopes and one plane each.
- Every lane gets its own clone of the repository at the incumbent.
- A candidate counts only when it is submitted to InferRSI, which measures it against the incumbent with the existing AB/BA runner under a local device lease.
- Passing lanes are added to the incumbent one at a time, and each addition is measured again from a fresh checkout.
- The round ends with a new incumbent, or the old one, and a ledger that keeps the negative results.
The orchestrator only proposes. InferRSI measures, selects and records.
-
Completion criteria:
- Model-free round tooling, schemas and tests merged through the normal lanes. A synthetic multi-lane fixture exercises scope rejection, idempotent resubmission, selection, stepwise composition, an interacting pair of lanes and the incumbent update.
- Lane drivers for Claude Code and Codex, and a SwarmFlow script template for jiuwenswarm, each tested offline with stub executables or
MockBackend. - One authorized pilot comparing parallel and sequential rounds at an equal agent budget on the same task. Its frozen plan digest is posted here before any paid call, and every run is retained. The report states wall-clock time and device-hours to a frozen fraction of a reference gain fixed before the pilot, per-lane outcomes, interaction ratios, measurement queue wait and limitations. A null result satisfies this criterion.
Scope and constraints
- In scope:
- A round plan and a round ledger that extend the campaign plan's
search_planandsearch_stateinstead of replacing them. tools/parallel_round.pyand its library code: lane checkouts, submission intake, the measurement queue and device lease, selection, stepwise composition and the incumbent update.- Lane drivers for Claude Code and Codex, and a SwarmFlow template with an operation guide.
- A speed report comparing parallel and sequential rounds.
- A round plan and a round ledger that extend the campaign plan's
- Out of scope:
- Multi-host scheduling, SSH dispatch and distributed leases, which stay future work per architecture.md.
- Automatic conflict resolution or patch synthesis. Lane scopes are disjoint by construction, so nothing is merged textually, by hand or by a model.
- Changes to jiuwenswarm or agent-core.
- Engine performance claims. A round's new incumbent is development evidence. Acceptance still follows the campaign's own acceptance issue and held-out split.
- Ranking harnesses or models. Whether InferRSI helps a given agent at all is #248.
- Relevant dependencies, shared interfaces or limits:
- Reuse
run_experiment,evaluate,qualify_devices,repository_identity, the campaign plan template, the select, compose and rerun discipline of harness improvement (#93) and the chain and branch layouts ofcampaign_summary_chart. Add no second runner. - Lane count, budgets, gates and the device map live in the frozen round plan, not in code defaults.
- Lane agents never hold measurement devices.
- Paid lanes need runner-enforced isolation. jiuwenswarm ships with its permission layer disabled.
- Reuse
Ownership and authorization
- Proposed by / actual requester: @david6666666. Drafted with Claude Code (
claude-opus-5-5) at the requester's direction. - Status: Proposed
- Accountable parent (Issue-level owner, if assigned): TBD
- Slice implementer(s) / acting contributor (if assigned): TBD
- Goal-acceptance owner: TBD
- Accepted decision or scoped delegation: Not yet granted. Paid model calls, accelerator time and evidence publication each need separate authorization.
Inputs and deliverables
- Relevant sources, revisions or linked issues:
- Expected artifacts:
tools/parallel_round.pywithprepare,launch,serve,statusandclose, and a standalone lane wrapper withsubmitandstatus.- Round plan, ticket and ledger schemas, and the matching campaign plan template fields, coordinated with #30.
- Claude Code and Codex lane drivers, shared with the adapters of #248.
- A SwarmFlow template under
docs/examples/parallel-round/and an operation guide. - The synthetic multi-lane fixture and its tests.
- The pilot evidence bundle.
The full plan is in the English comment below. A Chinese translation follows it.
Completion and closure
- Who accepts completion and may close: the goal-acceptance owner above.
- Remaining uncertainty / next decision:
- The pilot task and device class, and how many device sets measurement gets.
- The lane count and the per-lane budget.
- Whether lanes may get exploration devices separate from measurement devices.
- Whether a joint, single-rerun composition is acceptable later. This plan uses stepwise composition only.
Activity
david6666666 commentedon Oct 29, 2026
Full plan: parallel optimization rounds with multi-agent harnesses
1. Why rounds are serial today
search_stateholdsincumbent_revision,next_candidate_parent,isolationandimport_path(template).run_experimentwith AB/BA ordering (runner.py) andevaluate(evaluation.py)qualify_devicesrefuses a GPU that already has a compute process (cuda.py)choose)search_planentries with status and evidence, and append-onlysearch_plan_revisions(template). Negative experiment memory in the search policy.SwarmFlow gives deterministic fan-out, but its defaults do not fit a campaign:
origin/<default branch>(backend.py), not from the campaign incumbent. Dirty ones stay "for the leader to merge" (worktree.py).agent()takes no working directory, environment or device option (_ENGINE_OPTIONS).verify()is a reviewer vote with a one-vote veto and a 0.85 score threshold (swarmflow.md, verify.py). It is model judgment, not measurement.enable_swarmflow: trueand theexternal_cli_agentsallowlist (guide). Codex members run without approvals or sandbox unless configured otherwise, "matching the Claude member'sbypassPermissionsbehavior" (team.py, validator), and the shipped config disables the permission layer (config.yaml).Benchmarks are also slow relative to agent tool limits. In #220 a benchmark took 5 to 13 minutes, longer than Claude Code's 2-minute foreground limit, so every benchmark became a background job. agent-core's Bash tool defaults to 300 seconds (_tool.py). Submission therefore has to be asynchronous.
(agent-core also ships an
openjiuwen.rsipackage, "Recursive self-improvement for standalone Expert Harnesses" (__init__.py). It shares the acronym only. This plan does not use it.)2. Principle: the orchestrator proposes, InferRSI decides
search_planand freeze the round planlaunch.inferrsi/round submitwrapperservecloseAgent narrative, agent-run timings and
verify()votes are recorded but never decide anything, per "Evaluator + evidence win" (AGENTS.md).3. Choosing orthogonal lanes
A lane is one
search_planentry plus the files it may change. The campaign owner chooses lanes before the round, from evidence. Nobody adds a lane mid-round.4. Round protocol
The commands live in
tools/parallel_round.py. The library code goes undersrc/inferrsi/harness/and obeys the existing module boundary tests. A round keeps its working state in a round directory outside the InferRSI tree: the lane clones underlanes/, the queue, the measurement checkouts and the ledger.closeexports the evidence toevidence/<campaign-id>/rounds/<round-id>/.prepare reads the frozen campaign plan and writes
round-plan.json:search_state.incumbent_revision.ab_ba_pairs, repetitions, the rollback line, and the validator with its hashes. A round can tighten a gate but never loosen one.search_planentry it pursues, whose plane and hypothesis it inherits;preparerefuses the plan in any of these cases:planned.The plan digest is posted on the campaign's issue before
launch.launch sets up each lane:
lanes/<id>, detached at the incumbent SHA, with itsoriginremote removed. Git hardlinks the object files when the round directory is on the same filesystem. Each lane has its own index, refs and objects inside its directory, so no two lanes share an index, and without a remote a lane has nowhere to push. Commits are optional, becausesubmitreads the working tree.--candidate-repochanges only the working directory (quickstart.md)..inferrsi/directory holdinglane.json, theroundwrapper (a standalone standard-library script, so the lane environment needs no InferRSI install), scratch space, an outbox and a status mirror, listed in the clone's.git/info/exclude. Everything a lane writes stays inside its clone.It writes
launch.json, the manifest the drivers in section 6 take as input. With--drive claudeor--drive codexit also starts one driver per lane.--drive swarmflowrenders a SwarmFlow script instead (section 6).submit (
.inferrsi/round submit) is the only way a lane hands over a candidate. It compares the working tree with the incumbent commit and copies the changed files under the lane's globs into.inferrsi/outbox/, with a manifest of paths, modes, deletions and SHA-256 hashes. Changes outside the globs are listed back to the agent and never submitted. The wrapper does not need to write to.git, so it also works under a sandbox that keeps.gitread-only. It returns a ticket at once:{"ticket": "r03-L2-7f3a9c1e", "status": "queued", "duplicate": false}Submission is idempotent per round digest, lane and manifest digest: the same files always return the same ticket. As a result, SwarmFlow retries, cache-hit replays and driver restarts cannot queue a candidate twice. The submission cap counts distinct manifests. The wrapper checks scope early so the lane gets fast feedback.
serverepeats every check and trusts nothing inside a lane clone: it takes globs and gates from the round plan, never fromlane.jsonor the wrapper, so editing them gains a lane nothing.status returns a ticket's state (
queued,measuring,measuredorrejected), plus the verdict and gain once it has been measured.servemirrors each ticket's state into the lane's.inferrsi/status/, so the command also works inside a sandbox.status --wait <seconds>blocks until the ticket changes state or the time runs out. Drivers set the limit below the harness's foreground tool timeout: two minutes by default in Claude Code, 300 seconds for the agent-core Bash tool. A lane may read it to iterate. The authoritative copy is the ledger in the round directory.serve is one local process that owns the measurement devices. For each ticket:
qualify_devices. It then runsrun_experiment, with the incumbent checkout as baseline and the materialized candidate as candidate, followed byevaluate. If a device is busy, the ticket stays queued instead of failing.repository_identityof both checkouts, the verdict and the gain against the ticket.The queue is served round-robin across lanes, so one fast lane cannot starve the others. Lane agents never hold measurement devices.
Every k tickets, with k frozen in the plan,
servealso measures the incumbent against itself. If that A/A check fails the noise gate, or device qualification drifts, the queue pauses, in line with the RFC's rule to stop a round when the stack or device state drifts (RFC).close runs once every lane has stopped or the round deadline has passed. Section 5 describes it.
5. Closing a round: select, compose, rerun, record
Orthogonality has two parts here:
closemeasures it one lane at a time.closeruns these steps:Select. Each lane contributes at most one candidate: the ticket with the largest gain among those
evaluatepassed. A gain below two sigma of the measured noise is "not measured" under the campaign test plan and counts as no gain. A lane with no passing ticket is a negative result.Order. Eligible lanes are sorted by measured gain, largest first, with the lane ID breaking ties.
Compose stepwise. Let I0 be the incumbent and C0 = I0. For each lane k in order:
closewrites the lane's files onto a fresh checkout of C(k-1), commits the result as one step, and measures it against C(k-1) withrun_experimentandevaluate.Step 1 reuses the lane's own measurement against I0, so composing m lanes costs m - 1 measurements. Each step adds one lane, so each step changes one plane, as AGENTS.md requires.
Rerun. The final head runs once more against I0 from fresh checkouts.
closereruns the best single lane against I0 once. If that also fails, I0 stays.Harness improvement keeps H0 after a failed rerun without trying another candidate. This plan allows exactly one fallback because every lane already passed on its own. A plan may freeze the stricter rule instead.
Record. The round's results go into the campaign record:
round-ledger.jsoncovers every lane: its entry, plane, harness, model and agent cost; every ticket with its verdict and gain; the selected ticket; the composition outcome; and the interaction ratio. Negative results stay in the ledger.search_plan_revisionsrows. A composed lane becomeskept, and a lane with no passing ticket becomesrejected. A lane that passed alone but lost its gain in composition goes back toplanned. For that lane, the new incumbent is the changed condition the RFC asks for, so a later round may retry it.search_state.incumbent_revisionandincumbent_evidencemove to the new head and the ledger.branchlayout for a round's lanes, which all start from one incumbent, and thechainlayout for composition steps and for rounds over time (campaign-summary-chart.md).For each composition step, the interaction ratio is the step's measured improvement over C(k-1) divided by the lane's standalone improvement over I0, both in the metric's own unit:
The next round's
preparestarts from the new incumbent. Lane clones are deleted once the evidence is exported.6. Lane drivers
Every driver reads
launch.jsonand runs one agent per lane inside that lane's clone. All drivers give the agent the same lane prompt, which states:Each lane names its harness and model, so a round may mix them. The speed comparison in section 7 keeps them fixed.
submitrefuses candidates after the lane's deadline, and the deadline holds across harness retries. Each driver works without changes to the harness itself.Claude Code. The driver runs one
claude -pprocess per lane, with the lane clone as its working directory. It uses the flags and environment of theClaudeCodeClientin #248:--max-turnsand--max-budget-usd;--permission-mode dontAskwith a frozen--allowedToolslist that includes the lane wrapper;--strict-mcp-config.Each lane gets its own
CLAUDE_CONFIG_DIR. The driver does not pass--worktree, which would create a second checkout under<repo>/.claude/worktrees/that InferRSI does not track (CLI reference).Codex. The driver runs one
codex exec --json -C <lane clone>per lane. It reuses the argv and isolated configuration of the existingCodexClient(argv,client_config()), in the long-horizon mode from #248.Both CLIs. The wrapper only reads and writes files inside the lane clone. It needs no network access, no socket and no write access to
.git. Paid lanes run under the runner-enforced isolation of #248: only the lane clone and its environment are writable, and no measurement device is visible.jiuwenswarm SwarmFlow.
launch --drive swarmflowrenders a round script from the template indocs/examples/parallel-round/. The Leader of a team session runs it throughscript_path(swarmflow.md). The Process CLI does not accept Team or Workflow roots (Process_CLI_Machine.md), so a SwarmFlow round starts from an interactive Team-mode session, such as the TUI (guide). The template follows SwarmFlow's rules:args, a string the script parses withjson.loads(swarmflow.md).agent()has none, so each worker's prompt names its lane clone by absolute path. M2 checks whether native workers' file tools reach paths outside the team workspace. If they do not,launchputs the round directory inside it. The template never setsisolation='worktree', because those worktrees start from the default branch and a replay does not recreate them.METAmust be a pure literal (swarmflow.md), solaunchwrites the frozen token limit intoworkflow_token_limitas a literal. Per-lane wall-clock limits use thetimeoutoption.agent_type. That type must be declared inexternal_cli_agents, andenable_swarmflowmust be on (guide).min(16, CPU cores - 2)workers run at once (swarmflow.md). Further lanes queue.SwarmFlow's runtime behavior meets the round contract as follows:
verify()may run as an optional review before submission, for example a readability check. Its votes are recorded and never gate a candidate.serveruns outside the container and reads each outbox from the shared mount. Inside the container, nothing at the OS level stops one worker from writing another lane's clone.serverejects files outside the submitting lane's globs, which limits the damage but does not prevent interference. Rounds that need lanes isolated from each other use the Claude Code or Codex drivers.7. Measuring the speedup
The question is whether parallel rounds reach a given gain sooner than serial rounds at the same agent budget, and what they cost in device time. The pilot answers it for one task, one harness and one model.
close, so S is today's serial campaign with the same tooling. A real serial campaign could also reorder its directions after each result; this comparison does not capture that.search_planentries that the owner expects to be orthogonal and whose files are disjoint. A reference gain G* is frozen before the pilot, from a reference solution as in #248 or from earlier campaign evidence.launchuntil the incumbent first reaches a frozen fraction f of G*, for example f = 0.8, with a passing rerun. A run that never reaches it is censored at budget exhaustion, and the report says so.As a rough guide, suppose each lane spends A minutes of agent work and submits s candidates that take M minutes each to measure. On one device set:
The speedup approaches N when agent work dominates and approaches 1 when measurement does. Each extra device set divides the measurement term. Composition costs the same in both arms: a parallel round measures N - 1 steps and one rerun, and N serial rounds measure N reruns. The report includes queue wait so readers can see whether devices were the limit.
The speed pilot is separate from #248, which asks whether InferRSI helps an agent at all. It reuses that issue's adapters, isolation and claim-reliability measures for each lane.
8. Milestones
M0 to M2 need no paid calls and can merge before anyone decides on M3.
M0, round tooling.
tools/parallel_round.pywithprepare,launch,serve,statusandclose.submitandstatus.budget.lanes_per_roundandsearch_state.last_round_ledger, with layout tests, coordinated with #30.metrics.latency_ms, like the existing synthetic fixture.closeadvancessearch_stateand appendssearch_plan_revisionsrows.M1, Claude Code and Codex drivers.
claudeandcodexexecutables that perform the scripted lanes.--worktreeis never passed.M2, SwarmFlow template.
META, and notime,randomoruuidcalls (loader.py).b2a0a248and runs the script throughrun_workflow(runner.py) withMockBackendfixtures keyed by lane label. The fixtures are callables, so each one can perform a scripted lane (mock.py).M3, speed pilot. The pilot from section 7. Its plan digest is posted here first, and every run is retained. Paid calls and device time need separate authorization.
9. Risks and mitigations
plannedservebuilds from the incumbent plus the lane's files under its globs, and takes the benchmark command and environment from the planservepins its CPU set where the plan says so, and A/A checks pause the queue on driftserveresultsstatus --waitstays below each harness's foreground limitplannedlaneservetreats every outbox as untrusted dataserveruns candidate codeworkflow_token_limitand a cost line per lane in the ledger10. What a pilot result will and will not show
A positive pilot shows that, for one task, harness and model, parallel rounds reached a frozen fraction of a known gain sooner than serial rounds at the same agent budget, and what that cost in device-hours. It does not show that the lanes' optimizations generalize, that one harness beats another, or that the final engine passes acceptance. A null result still guides the next step: if queue wait dominates, add measurement device sets before adding lanes.
Dong1017 commentedon Oct 29, 2026
Proposal review of the full plan, against the Issue body updated 2026-10-29T07:50:08Z. Assessed main:
a8215b3ec314b8bc5cee152cdebbf4bb76ba4188; plan source pins: InferRSI509531c681479fbdd7ddd0e8b0032239e64a44c1, agent-coreb2a0a248c554753ba31727415fe17a03eed60b46, jiuwenswarm053c82b07056cf503e2b0229e1cbbb45a9c2bf7f. Design/source inspection only; no model, device or workflow execution.Central measurement ownership, asynchronous submissions, stepwise composition and retaining negative results are sound directions. Please resolve these two protocol gaps:
P2 — Manifest idempotence does not make worker retries budget-idempotent (§4, §6). The pinned runtime allows two extra attempts. If attempt 1 submits bytes D1 and times out, attempt 2 can edit the same clone into D2 and obtain a different ticket while under the distinct-manifest cap. Thus “a retry cannot add submissions” is false; retries can also consume additional agent time and tokens without submitting anything. Retain content-based deduplication, but freeze a cumulative lane budget and absolute lane deadline across attempts/restarts, with authoritative submission counts and expiry checks outside the writable lane clone. Record all attempt costs. Add an offline timeout-after-submit → changed-bytes retry case, plus a restart after budget exhaustion.
P2 — Extend execution isolation to the candidate measurement path (§4, §9). The plan puts lane agents in a container but leaves
serveoutside it, then builds and executes lane-supplied code in fresh measurement checkouts. A fresh checkout and source hashes establish provenance; they do not stop candidate build/import code from writing the coordinator's ledger, other checkouts or trusted grading files. The current executor supplies a working directory and process environment, not filesystem confinement. Specify the execution boundary for build/smoke/benchmark/validation: candidate-private writable scratch and outputs, protected grading inputs, and no write access to coordinator state or other candidates. Keep plan validation, lease ownership and verdict persistence in the trusted coordinator. An offline candidate that attempts an out-of-checkout write should demonstrate that boundary before a paid-host pilot.For §7, P starts all lanes from I0 while S advances the incumbent between lanes. This is a useful comparison of the two campaign policies, but it also changes the code/history later agents see; label the result as a workflow-policy comparison rather than isolated concurrency speedup. No additional paid arm is needed for that narrower claim.
Next: @david6666666 and a named accountable/acceptance owner should settle these contracts and the adapter responsibility shared with #248 before authorizing implementation. Offline M0/M1 and the separately authorized pilot remain distinct; no incumbent advance, campaign acceptance or resource authorization results from this review.
NumberWan commentedon Oct 30, 2026
I would like to take this task. Please assign @NumberWan.
I am asking for the offline slices only: M0 (round tooling, schemas, synthetic fixture), M1 (Claude Code and Codex drivers against stub executables), and M2 (SwarmFlow template and its loader checks). I am not asking to own M3. Paid model calls, accelerator time, and the speed pilot stay with the goal-acceptance owner as a separate authorization. This comment does not request a budget, and it does not start implementation.
Static reading of main
6e6ee245(2026-10-30) and of the plan pinned at509531c6. I did not run a model, a device, or a workflow.P2 — attempt budget, not manifest identity
Agreed that content-addressed tickets do not make SwarmFlow retries budget-idempotent. A second attempt can edit the same clone into new bytes, take a new ticket under the distinct-manifest cap, and a timed-out attempt can spend tokens without submitting.
tools/skill_eval_budget.pyalready has the transition algebra this needs. The charge unit there is an attempt binding, not a content digest:Bindingis(plan_digest, run_id, worst_case). Its comment requiresrun_idto include the workflow attempt, not only the run number.reserveis idempotent only for the exact same binding. The same plan digest with a differentrun_idis aBudgetError, so a retry is not a free extra submission.advance(..., "claimed")is deliberately not idempotent: a second claimant must not execute.Ledger.chargedsumsworst_caseover every entry, and no phase frees capacity, so a timed-out attempt still occupies the lane budget.AtomicStore/claim_oncekeeps that count outside the writable tree, behind a compare-and-set token.Manifest idempotence stays, and only deduplicates measurement. The lane budget is a sequence of attempt bindings.
Two adaptations, without changing the transitions:
PR_LIMIT_MICROUSDis a module constant. Per the repository rule that thresholds stay out of the tree, the cap becomes a field on the ledger, supplied by the frozen round plan. No numeric default in code.PRKeybecomes(round_digest, lane_id).Offline cases I would add in M0, matching the review:
claim_oncedoes not authorize another attempt. Every attempt's reserved cost is in the ledger, including attempts that submitted nothing.P2 — confine the measurement path through the existing executor
Agreed that a fresh checkout and source hashes establish provenance and do not stop candidate build or import code from writing the coordinator ledger, another checkout, or trusted grading files.
execute_commandinsrc/inferrsi/infra/executors/local.pysets a working directory and an environment. It does not confine the filesystem.I would not add a second runner.
run_experimentalready takesexecutewith the same signatureexecute_trialuses, andtests/test_module_boundaries.pyalready injects that callable.servewould pass a confinement wrapper of that signature.docs/architecture.mdalready requires the offline harness lane to reuserun_trialand the local executor rather than create another execution backend. Plan validation, lease ownership, and verdict persistence stay in the trusted coordinator.The writable set cannot be "the candidate checkout, and nothing else." The executor rewrites
{result}totrial_dir/result.jsonand setsINFERRSI_RESULT_PATH, so the candidate command has to be able to write that trial directory. The boundary I would freeze:trial_dir.Offline case before any paid-host pilot: a candidate command that writes outside the checkout and its own
trial_diris rejected, and the ledger is unchanged.Where the device lease lives
Section 4 places the lease in
src/inferrsi/harness/next to the queue.docs/architecture.mdgives device qualification and process ownership to Infra, and gives the harness AB/BA order, deadlines, evidence, and adjudication. I would put the lease undersrc/inferrsi/infra/, besideprocesses.py, and leave the queue and selection in the harness.qualify_devicesis CUDA-specific (src/inferrsi/infra/platforms/cuda.py). The lease key should be the platform-neutral identity frominspect_device, so a round on another platform can take a lease too. Today that CUDA check refuses a GPU that already has a compute process, so two lanes measuring at once fail rather than silently contend. The lease turns that failure into a queue, which is what section 4 already requires. Lane agents still never hold measurement devices.Section 7
I accept the label. P starts every lane from I0 while S advances the incumbent between lanes, so later agents see different code. The pilot is a workflow-policy comparison, not an isolated concurrency speedup. No extra paid arm.
A zero-model replay can bound the measurement term: resubmit the content-addressed manifests from a finished ledger and measure them again. It does not reproduce agent adaptation, reordering, or a lane that would have written different bytes after seeing an earlier result. I would report it as a measurement-queue bound, not as a third policy that replaces the pilot.
If this scope is accepted and the issue is assigned, M0 is a separate PR. This comment does not advance an incumbent and does not close any completion criterion.
Dong1017 commentedon Oct 30, 2026
Technical follow-up to @NumberWan's offline M0–M2 proposal, checking source at
6e6ee245d9e92ee9365976f2e4e262304999f147. The cumulative-charge direction, separate trial output, and workflow-policy comparison label address the intent of the previous review. Two contract details remain before treating those P2 concerns as cleared:Retry identity and expiry. Ledger validation/reserve rejects the same
plan_digestwith a newrun_id, even when budget remains. Changing only the cap and PRKey therefore does not admit the proposed second attempt. Specify an immutable, distinct attempt-plan binding rooted in the unchanged round/lane contract (or explicitly choose no retries), retaining all prior charges. Also retain the original review's absolute lane deadline and authoritative submission/expiry checks across restarts; reservation accounting alone enforces neither. Include a retry with budget remaining as well as the exhausted-budget case.AtomicStoreis a storage contract, not itself an implemented filesystem boundary.Apply confinement before measurement too. The
executehook in run_experiment is an appropriate reuse point, but plan §4 builds and smoke-tests the candidate before calling it. Those stages can execute candidate code as well. Explicitly route build/import/smoke through the same protected boundary, with their own bounded writable outputs. Demonstrate denied coordinator writes from a build step as well as a trial command, and fail closed when confinement is unavailable. Passing a callable/cwd is not confinement evidence.The offline-only split is clear, and M3 remains separate. Assignment and acceptance of M0–M2 still require the responsible maintainer's decision; this reply neither assigns the task nor authorizes implementation, paid execution, device replay or incumbent advancement. Coordinate the driver contract with #248 rather than creating competing adapters.
NumberWan commentedon Oct 30, 2026
Thank you, both points land. The previous reply's
reserve()claim does not hold, and the confinement answer stopped one stage too early. Concrete fixes, checked against mainc97f25e2and the plan pinned at509531c6. Still no code, no PR, no branch.Retry identity: an attempt-scoped
plan_digest, zero changes toreserve/advance/LedgerConfirmed the collision:
reserve()rejects any entry whoseplan_digestmatches an existing one, regardless ofrun_id:Treating
plan_digestas the round plan's digest, as the previous reply did, means attempt 2 collides with attempt 1 under that same check, regardless of budget. The fix is not to change this function; it is to stop overloadingplan_digestwith the round's identity.plan_digest = SHA256(round_digest, lane_id, attempt_ordinal). Each attempt mints its own plan identity.reserve()'s existing "one entry per plan_digest" rule then means exactly "one reservation per attempt," with no change to the transition algebra — this is the "immutable, distinct attempt-plan binding rooted in the unchanged round/lane contract" from the review.run_idcarries the workflow run id and the attempt ordinal together, per the existing comment requirement.worst_caseis the lane's frozen per-attempt cap from the round plan, not a shared value across attempts.PRKeybecomesLaneKey(round_digest, lane_id); one ledger per lane, shared across its attempts.PR_LIMIT_MICROUSDbecomes acapfield on that ledger, sourced from the lane's frozen budget in the round plan, not a module constant.Ledger.chargedalready sumsworst_caseover every entry regardless of phase, so retaining all prior charges, including attempts that submitted nothing, needs no new mechanism; it already works that way.This still leaves time separate from money. The ledger has no notion of an absolute deadline. The round plan gets a frozen
deadline_utcper lane, andserve, as the trusted coordinator, checksnow > deadline_utcbefore callingreserve()for any new attempt, independent of remaining budget. That check reads the frozenround-plan.jsonon disk, not an in-memory timer a restarted lane process could reset.Offline cases:
reservedtocancelledon timeout; attempt 2 reserves under a new attempt-scopedplan_digestand succeeds;chargedsums bothworst_casevalues and stays at or undercap.reserve()fails atLedger.__post_init__before any claim is possible.On
AtomicStore: agreed that it is a storage contract.claim_once's compare-and-set gives one property only, that a second claimant cannot execute against the same stored ledger state. It says nothing about what a running candidate can write to the filesystem. That is a separate mechanism, addressed below, not a consequence of the storage contract.Confinement: one primitive, applied before the build and the smoke command too
Agreed
executeis the right reuse point for the trial phase, and that it is not itself confinement evidence. The gap is earlier: plan section 4 builds and smoke-tests the candidate before any call intorun_experiment, and both stages execute candidate code thatexecute's injection point never sees.One primitive, called at both points, with the enforcement at the OS level rather than inside the callable:
execute=value passed intorun_experiment.writable_pathsis the candidate checkout's scratch plus that trial'strial_dir, which has to stay writable because the executor rewrites{result}into it and setsINFERRSI_RESULT_PATHthere.servecalls the same primitive directly, before anyrun_experimentcall exists.writable_pathsis the candidate checkout plus its own build-output directory. Notrial_direxists yet at this point.src/inferrsi/infra/executors/local.py'sexecute_commandtoday is a plainsubprocess.Popenwith acwdand anenv; nothing stops a child process from writing anywhere its OS permissions allow. Confinement has to come from outside the Python call, for example a mount namespace that bind-mounts everything exceptwritable_pathsread-only, or a container whose only writable mount iswritable_paths. Section 6 of the plan already asks for exactly this around the worker itself; this extends the same boundary to the build and smoke stages the coordinator runs locally.Fail closed: if the host cannot set up that boundary,
confined_executerefuses to run the candidate at all. It does not fall back to an unconfined subprocess.Offline cases, in addition to the trial-write denial the plan already lists:
confined_executerefuses the run and reports why, instead of executing unconfined.#248
Agreed. The Claude Code and Codex lane drivers would share the argv and isolation contract with #248's adapters rather than create a second one.
No code, no branch, and no PR accompany this comment. Assignment and acceptance of M0 through M2 stay with the responsible maintainer.
Dong1017 commentedon Oct 30, 2026
Follow-up to 6516547428, source checked at
37166b6f7323c76a091e423a7163ac99c4ae01ac:The distinct attempt identity and explicit build/smoke/trial OS boundary resolve the earlier proposal ambiguity in direction; they remain designs, not implemented or tested clearance. Two acceptance cases still need correction:
Timeout after execution is not reserved → cancelled. The existing transition table requires claiming before execution; a claimed attempt can only finish with trusted settlement, and a crash stays ambiguous/charged. Cancellation applies only before claim. Make the timeout-after-submit fixture start from
claimed, retain that charge/ambiguity, and admit any separately authorized next attempt with a new binding and sufficient cumulative capacity—never replay or cancel the old execution claim.Check the persistent deadline beyond reservation. Reserving immediately before expiry does not prevent a later claim/launch or a late changed-byte submission after expiry. Freeze the boundary semantics and recheck in the trusted coordinator at claim/launch and submission intake, and bound running work by the same absolute deadline. Add “reserved before expiry, launch after expiry” and “started before expiry, submit new manifest after expiry” cases, including coordinator restart. Reading the deadline only before
reserve()does not yet close the original expiry/submission concern.Keep the attempt digest canonically encoded and bound to the frozen round contract; the ordinal must not let a restart reset identity or accounting. The confinement-denial tests must exercise actual OS enforcement (or fail closed when unavailable), not only a mocked callable.
M0–M2 assignment/scope acceptance remains a maintainer decision; no implementation completion, paid/device authorization or M3 acceptance is inferred from this discussion.
fix(harness): close the parallel-round execution boundary
fix(harness): keep parallel-round launches inside the deadline and th…