Repository navigation
v1.46.0: map builders can fork one shared session - #291
Merged
Merged
Conversation
test_concurrent_replay runs 8 workers in one process. On Windows the ChangeTime of state.sqlite3 can move alone under live writers. Attach then raises StoreMetadataDrift. The fence stays, because stat cannot tell this move from a rename away and back. A real worker exits 75 and the supervisor respawns it. Each test writer now respawns its attach the same way, up to _ATTACH_RESPAWN_LIMIT. The CLI await tests now wait 10 s, like the MCP await tests. The job is complete, so the read returns at once. With 1 s, a loaded Windows runner gave status unavailable before the first store read. The compact body of a job that is not terminal keeps summary "". The TypeScript client types summary as a string and reads it on a timeout.
On a starved Windows runner, source_stamp raised "source metadata did not stabilize" after 8 samples. The OSError had no contention mark, so it escaped every retry path. Attach raised it at once, the helper ended its session, and a worker exited 1. The supervisor did not respawn it. Mark the error with source_open_contention, like a share violation. Attach and launch bindings retry it inside their budget. Ordinary reads still fail fast. _transient_attach_failure counts source contention as transient, so a worker exits 75 if the budget runs out. The helper retries contention only before its session opens. After the open, a contention error made the helper wait for a new open and crash with KeyError on the next statement or release.
A map takes fork: {"from": <agent node>}. Each item's code builder forks
that node's recorded session on its first visit; a repair resumes the
builder's own fork; judges never fork. Codex runs codex exec fork with no
thread lease, the full build contract and the write sandbox. The receipt
records the fork's own thread, and attempt usage comes from its own
rollout.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Map builders can fork one shared session. Codex R169 and R179 (PM
1.45.1, N16 grouped, Sol 6.1 high): each cold group builder started a fresh
session and read the same contracts, rubric, world API and checks again. A
builder took 178-261 s for 4 regions. Native built all 16 regions in about
350 s, and its builders start from the pilot's context.
fork: {"from": "<agent node>"}. When that node has a recordedsession, each item's code builder forks it on its first visit
(
payload.fork_from). A repair visit resumes the builder's own fork.Judges never fork. Validation refuses a
forkthat is not{"from": <agent node>}.fork_fromhas the shape ofresume_from. The resolved record carriesmode: "fork".resume_fromwins when both are present.codex exec fork <id>. It takes no thread lease, because afork leaves the source thread as it was. Any number of tasks can fork one
thread. The fork gets the full build contract (no resume delta), the
write sandbox, and
--disable memories --disable multi_agent.thread_id. Attempt usage comes fromthe fork's own rollout. The SDK
turn.completedtotal includes the copiedsource turns, so it stays
session_cumulative.--fork-session, so a fork needs noadapter change there.
where the SDK total says 126,420. The cache covers only the system prefix,
so each fork pays once for the copied history at the uncached rate.
Metadata that a live writer keeps in motion is source contention. On a
starved Windows runner, 6 of 200 attach loops failed with
source metadata did not stabilize.source_stamptakes 8 samples of size, LastWriteTimeand ChangeTime. When a writer moves them on every sample, it raises an
OSError. That error had no contention mark, so it escaped every retrypath. In the parent, attach raised it at once. In the helper, the session
ended with
source changed or unavailable. A worker then exited 1, not 75,so the supervisor did not respawn it and the job failed.
source_open_contention, like a share violation.Attach and launch bindings retry it inside their budget. Ordinary reads
still fail fast.
_transient_attach_failurecounts source contention as transient, so aworker that still meets it at the end of the budget exits 75.
After the open, the parent sends statements and
release, not a newopen. Before, a share violation after the open made the helper wait foran
openand crash withKeyErroron the next request.attach budget: 57
ReadTimeout(Windows admits one reader per store at atime) and 21
source changedthat the helper could not prove to be awrite. A worker respawns on both. Synthetic CPU, disk-flush and parallel
load (5 lanes, 0 failures) did not reproduce that runner.
Two Windows CI tests wait like the clients they model. Product code is
unchanged.
test_concurrent_replayfailed on a Windows CI run withStoreMetadataDrift. The first open saw a write and retried. On the retrythe ChangeTime of
state.sqlite3moved, but its size and LastWriteTime didnot, and the metadata fence refused the binding. A Windows probe saw the same
ChangeTime-only move under live writers, with no rename or chmod. The fence
cannot tell this move from a rename away and back, so it stays. A worker
that hits it exits 75, and the supervisor respawns it (1.27.40). The test
runs 8 workers in one process, so each writer now respawns its attach like
the supervisor does (
_ATTACH_RESPAWN_LIMIT).test_cli_json_defaults_to_the_mcp_compact_bodygotstatus: unavailableafter
--timeout-seconds 1: no store read was available in 1 s on a loadedrunner. The CLI await tests now wait 10 s, like the MCP await tests (1.33.5).
The job is complete, so the read returns at once.
summary: "". TheTypeScript client types
summaryas a string and reads it on a timeout.source changedstill fails closed. A proven same-store writealready has a bounded retry in the helper.