feat(charon): add GET /chain/{id} and split entry call by store flag#87
Merged
Conversation
Add a read-only chain-fetch endpoint (GET /chain/{id}) and a corresponding
GetChain client method so the proxy can rehydrate context without opening
a staging record or committing the current turn's request blob.
The proxy now picks its Charon entry call based on the request's store
value:
store:true -> POST /staging[?prev=...] (commits request blob,
returns staging_id)
store:false -> GET /chain/{prevID} (read-only, no commit)
(or no Charon call at all on the first turn)
This makes store:false turns leave zero residue in Charon: no staging
record, no per-chunk PUTs, no Complete. The previous implementation
called POST /staging unconditionally and only skipped the response-side
store call, leaving a request-blob staging record behind even when the
response was discarded.
All three proxy paths (HandleCreate, handleStream, wsTurn) funnel
through a new Handler.hydrateContext helper so the entry-call decision
is made in one place. The /responses atomic-write endpoint is unchanged
and remains available for clients that prefer one-shot single-turn
writes.
Tests:
- server: TestGetChain{UnknownID,DoesNotCommit}
- client: TestClientGetChain{NotFound,IsReadOnly}
- proxy: handler_test additions for store:false continuation
and a new backend_routing_test.go that wraps the Charon
mux in a recording middleware and pins, per
(stream, store, first-turn|continuation) combination,
which endpoint the proxy chose.
elevran
commented
Jul 9, 2026
elevran
left a comment
Owner
Author
There was a problem hiding this comment.
Clean, well-motivated change. The hydrateContext helper that all three proxy paths funnel through is the right shape, and the routing tests that pin the wire pattern are a good addition. A few minor issues below.
- Rename TestStoreFalseContinuation -> TestStoreTrueContinuation; the body was already a store:true->store:true continuation. The store:false->store:true wire pattern is pinned separately in backend_routing_test.go. - backend_routing_test.go: drop dead stagingHits/chainHits locals and the json.RawMessage import-retention trick; inline hitsContaining into the asserts. - handlers.go HandleGetChain docstring: drop the stale claim that buffered store:true turns use this endpoint (they go through POST /staging, not /chain).
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.
Adds a read-only chain-fetch endpoint so the proxy can rehydrate context for store:false turns without committing the current turn's request blob. Prior behaviour called POST /staging on every turn and only skipped the response-side store, which left a request-blob staging record behind when the response was discarded.
What changes
All three proxy paths (HandleCreate, handleStream, wsTurn) funnel through the helper so the entry decision lives in one place. The atomic POST /responses endpoint is unchanged and remains available for clients that prefer one-shot single-turn writes.
Wire surface after change
Tests
make presubmit is green.