Repository navigation
Description
Summary
The exact-backend spike chose toolexec (RFC-0002 §4.5, decided 2026-10-24). This epic ships it on main. The faultline-toolexec wrapper, run as go test -toolexec, rewrites the test binary's packages so that goroutine starts, channel operations, select, sync primitives, map ranges and math/rand go through sched, a user-space scheduler in the nested module runner/toolexec. The goroutine-mode driver releases one parked goroutine per pass with the seeded toolexec/release stream through internal/gosched, so the same seed gives the same trace hash and the same goroutine order. Runs are labeled exact, replay commands carry the wrapper, FAULTLINE_EXACT=1 refuses a run that would not be exact, and what the rewriter cannot control is listed as coverage gaps. The code moves from spike/exb at d91b8a7 file by file, and the spike's measurements become permanent acceptance tests.
Deliverables
internal/gosched, the driver hook and XTE-082's stall rule- Nested module
runner/toolexecwith theschedruntime and thefaultline-toolexecwrapper (prepare, state directory, version line, rewrite set, stale-state message) - The rewriter with position directives, sorted gaps and the rows of XTE-041 (
sync, maps, rand, reflect) - Package
faultline: exact labels, the toolexec replay command,FAULTLINE_EXACTas a bool,toolexec-gaps.txt - Acceptance package
runner/toolexec/acceptancewith AT-XTE-26 to AT-XTE-42 - Recorded measurements: point cost, C1 to C3 slowdown, final size
Open questions for the owner
The plan's Task 0 has 12 open questions that wait for the owner, among them exact replay only with Procs 1, FAULTLINE_EXACT as a bool, no trace records for sched decisions, and the size estimate against the 3,000-line limit. Each has a default, and spec XTE is written to the defaults. The refresh task (2.5-00, first in the list below) records the answers, and no code task starts before they are in.
Tasks
- [2.5-00] Refresh plan 2.5, record the owner's answers and apply XTE §12 #335
- [2.5-01] Exact backend: internal/gosched, the driver hook and the watchdog rule #336
- [2.5-02] Exact backend: runner/toolexec module and the sched core #337
- [2.5-03] Exact backend: sched helpers for the new rewrite rows #338
- [2.5-04] Exact backend: wrapper state: prepare, state directory and version line #339
- [2.5-05] Exact backend: wrapper builds: test main, wrapper path, stale state and rewrite set #340
- [2.5-06] Exact backend: rewriter base: positions, gap registry and new points #341
- [2.5-07] Exact backend: rewriter sync rows #342
- [2.5-08] Exact backend: rewriter map, rand and reflect rows; the gap table #343
- [2.5-09] Exact backend: faultline labels, replay command, FAULTLINE_EXACT and gaps #344
- [2.5-10a] Exact backend: end-to-end tests for builds, labels, replay, stalls and gaps #345
- [2.5-10b] Exact backend: end-to-end tests for hangs and orders #346
- [2.5-11] Exact backend: acceptance corpus and the EXB criteria as permanent tests #347
- [2.5-12] Exact backend: measurements and close-out #348
Done when
- Each task's PR is merged into
mainin task order, one squash commit per task;spike/exbis not merged - CI's
nestedjob is green on all four runners with the acceptance package (AT-XTE-43) - The backend's final size is at most 3,000 lines, recorded with each task's line count
- XTE §12's changes are applied (2.5-00) and XTE §9 carries the measured values (2.5-12)
Depends on
- Epic 2.4: Exact backend spike (decision recorded in RFC-0002 §4.5)
- Epics 2.1 to 2.3 merged to
main(at or after4b77273)
References
Private planning docs (
.helper/docs/, gitignored).
- Plan:
.helper/docs/plans/phase-2/2.5-exact-toolexec.md - Specs:
.helper/docs/specs/exact-toolexec.md,.helper/docs/rfcs/0002-goroutine-determinism.md§4.5,.helper/docs/specs/exact-backend-spike.md,.helper/docs/specs/goroutine-mode.md,.helper/docs/specs/test-api.md
Activity
hmdsefi commentedon Nov 1, 2026
All done-when items hold:
mainin task order, one squash commit per task: feat(gosched): add the toolexec scheduler seam and the driver hook #570, feat: label exact toolexec seeds, replay them with the wrapper and honor FAULTLINE_EXACT=1 #572, feat(runner/toolexec): add the toolexec module and the sched runtime #571, feat(runner/toolexec): add sched helpers for conds, lockers, once, maps and reflect #573, feat(runner/toolexec): add the faultline-toolexec wrapper with its prepared state #574, feat(runner/toolexec): link sched into test binaries and record the wrapper path #575, feat(runner/toolexec): register coverage gaps in rewritten packages and keep source positions #576, feat(runner/toolexec): rewrite sync method values, interface locks, conds and once functions #577, feat(runner/toolexec): order map keys, maps iterators and reflect selects, and record the remaining gaps #578, test(runner/toolexec): add end-to-end acceptance tests of the toolexec backend #580, test(runner/toolexec): check the hang and order rows end to end #581, test(runner/toolexec): carry the spike's corpus and criteria over as acceptance tests #582, test(runner/toolexec): measure the cost of a scheduling point #583. Task 9 (feat: label exact toolexec seeds, replay them with the wrapper and honor FAULTLINE_EXACT=1 #572) depends only on Task 1 and ran as a second track, so it landed right after Task 1. Task 0 ([2.5-00] Refresh plan 2.5, record the owner's answers and apply XTE §12 #335) changed only the planning docs.spike/exbwas not merged.mainat fd28b63 passed every job, including thenested modulesjob with the acceptance package on ubuntu-latest and macos-15 with Go 1.26 and 1.27 (AT-XTE-43). CI moved from macos-14 to macos-15 in ci: run the macOS jobs on macos-15 #579, because GitHub retires the macos-14 image on 2026-11-02.net/httprewritten too).One known gap stays open: a goroutine woken by timers firing at the same instant may not replay if, before its next scheduling point, it starts a goroutine, registers an
AfterFunc, draws a random number or is the first to call aOnce.