fix(core): a trace that no gateway will take, written by three commands - #90
Merged
Merged
Conversation
Spec §2.3: `run.start` and `run.end` bracket a run, exactly one of each. Nothing enforced it, and three commands got it wrong three different ways. record --mcp-config a note at seq 0, run.start behind it (fixed in #85) attach neither event, ever replay --from / compare opened on `fork`, closed on run.end All three produce a trace `orca show`, `orca replay` and the viewer render happily, and that a gateway refuses: invalid trace: run.start at seq 1, must be seq 0 invalid trace: 0 run.start and 1 run.end events (exactly one of each) The cost of finding out late is the whole recording — the user learns at `orca push`, after the agent session is over, that there is nothing to push. Worse for `compare`: forking a checkpoint onto several models is what the tool is pitched on, and its output could not be shared with anyone. `TraceWriter.append` now refuses the three a deliberate fragment cannot reach by accident: run.start anywhere but seq 0, a second run.start, and a run.end with no run.start. "seq 0 must BE run.start" is deliberately not one of them — this writer also builds fixtures and conformance vectors, which are allowed to be a few events with no bracket at all. The flags are set after the write, so a bracket that failed to reach disk is not one, and a refused append leaves no hole in the dense order (spec §2.1). Then the two commands that were violating it: - `attach` writes run.start before `createProxy`, which is listening by the time it returns — after it, the first thing a remote agent sends wins seq 0. It writes run.end before sealing, which `close` does not do for it. - a fork writes run.start before `fork`, keeping everything that makes it a fork; it just is not the first line any more. Verified against the live gateway, three rounds of record / fork / attach: 9 of 9 push, and all three render in the console with their layers intact. `attach-command.test.ts` asserted the model exchange and nothing about the bracket, which is how a command that wrote neither went unnoticed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🐳 OrcaCode Review
✅ No findings — nothing to flag in this PR. Great work!
OrcaCode Review — Route Smarter. Ship Safer. Spend Less.
Engine-reported: 693 calls · 73.2M tokens · 99% cached
❤️ Share · Install OrcaCode Review
Free on GitHub — the review runs on your own OrcaRouter key. If it helped, a shout-out goes a long way.
Share: X · Reddit · LinkedIn
Follow: X · Discord · LinkedIn · OrcaRouter
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.
Orca-Code-Review — push 1
✅ no blocking findings
Spec §2.3: "
run.start/run.end— Bracket the run. Exactly one of each." Nothing enforcedit, and three commands got it wrong three different ways.
record --mcp-confignoteattachmodel.request, and norun.endat allreplay --from N/compareforkAll three produce a trace that
orca show,orca replayand the viewer render happily:The cost of finding out late is the whole recording — the user learns at
orca push, after theagent session is over, that there is nothing to push. It is worse for
compare: forking onecheckpoint onto several models is what the tool is pitched on, and its output could not be
shared with anyone.
The guard
TraceWriter.appendrefuses the three a deliberate fragment cannot reach by accident:run.startanywhere but seq 0run.startrun.endwith norun.start"seq 0 must BE
run.start" is deliberately not one of them. This writer also buildsfixtures and conformance vectors, and those are allowed to be a handful of events with no bracket
at all — the stronger rule would have meant editing 43
TraceWriter.createsites across the coretests to say something none of them are about.
The flags are set after the write, so a bracket that failed to reach disk is not one, and a
refused append leaves no hole in the dense order (spec §2.1) — pinned by a test.
The two commands that were violating it
attachwritesrun.startbeforecreateProxy, which is listening by the time it returns;after it, the first thing a remote agent sends wins seq 0. It writes
run.endbefore sealing,which
closedoes not do on its behalf. The proxy URL thatrecord'srun.startcarries isnot known that early and is read by nothing.
run.startbeforefork. Theforkevent keeps everything that makes it afork; it just is not the first line any more.
Verification
Against the live gateway, three rounds of record → fork → attach, 9 of 9 push:
All three then open in the gateway console with their layers intact — the fork shows
OTHER fork seq 1, its twoRouterows, theLLM callrows and the request diff,Routes 2.Suite: 10 failed / 2420 passed / 40 skipped — the same 10 pre-existing Windows platform failures
as
main, six more passing tests.prettier --check,tsc --build,scripts/conformance.mjs(61 events, 0 failures) and
scripts/fidelity.mjs --check(1 recording, 0 regressions) all cleanlocally this time.
How it went unnoticed
attach-command.test.tsopened the trace it produced and asserted the model exchange count —nothing about the first or last event. That assertion is now there, and fails on
mainwithfirst event was model.request.🤖 Generated with Claude Code