fix(session): unify cache-only readers behind openSessionContent#562
Merged
rsnodgrass merged 1 commit intomainfrom Apr 25, 2026
Merged
fix(session): unify cache-only readers behind openSessionContent#562rsnodgrass merged 1 commit intomainfrom
rsnodgrass merged 1 commit intomainfrom
Conversation
All ledger-side session content readers now go through one canonical entrypoint that hydrates on demand into the gitignored cache and never writes to the in-place git-tracked path: cmd/ox/session_content.go:openSessionContent The function carries the load-bearing CACHE-ONLY DESIGN comment in full, including both failure modes from the 2026-04-25 post-mortem (LFS-linkage break + daemon anti-entropy clobber) so the next person to touch this code can't miss the contract. Converted readers: - ox session regenerate (default mode + --summary) - ox session lint (single-session) - ox session token-optimize - (ox session view already auto-hydrates correctly) Recording-time invariant comment added to agent_session.go: state.SessionPath is the local recording cache, never the ledger path. The recording lifecycle commits an LFS POINTER to the ledger after uploading bytes via the Batch API. This was implicit before and is now explicit so future refactors don't accidentally start writing recording content directly to the ledger working tree. Tests: - TestOpenSessionContent_PrefersCacheWhenInPlaceIsPointer asserts the cache path wins when in-place is a stub, and the in-place file remains a pointer after resolution (the load-bearing case). - TestOpenSessionContent_ReturnsErrorWhenFullyDehydrated covers the caller-must-hydrate path. Co-Authored-By: SageOx <ox@sageox.ai>
Contributor
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthroughThe PR introduces a centralized cache-only session content accessor ( Changes
Sequence Diagram(s)sequenceDiagram
participant Cmd as Session Command
participant OSC as openSessionContent
participant Cache as Local Cache
participant LFS as LFS Resolver
participant Ledger as Ledger Sessions
Cmd->>OSC: openSessionContent(projectRoot, ledgerPath, sessionName, filename)
OSC->>Cache: Build cache directory path
OSC->>LFS: ResolveContentPath(cache path)
LFS-->>OSC: real content path OR empty
alt Content Found in Cache
OSC-->>Cmd: return cache path
else Content Not in Cache
OSC->>Ledger: hydrateFromLedger(ledger sessions dir, quiet mode)
OSC->>LFS: Re-attempt ResolveContentPath(cache path)
LFS-->>OSC: real content path OR empty
alt Hydration Successful
OSC-->>Cmd: return hydrated cache path
else Hydration Failed/Missing
OSC-->>Cmd: error (hydration complete but content unresolved)
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
This was referenced Apr 25, 2026
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.
Summary
Single canonical entrypoint for reading hydrated session content from the ledger, plus a recording-time invariant comment. Closes the loop on the cache-only design started in #561.
Why
After #561, only `ox session regenerate --summary` used the cache-only resolver. Other readers (`lint`, `token-optimize`, default `regenerate`) still read raw.jsonl in-place and would fail on LFS pointer stubs (or worse, in the case of `regenerate --redact`, hydrate in-place and risk re-introducing the linkage breakage that broke 2 sessions on 2026-04-25).
This PR consolidates all ledger-side readers behind one helper carrying the CACHE-ONLY DESIGN invariant comment in full, so the next person editing this code can't miss the contract.
What changed
`cmd/ox/session_content.go:openSessionContent` — canonical resolver. Cache → in-place real content → hydrate to cache via Batch API. Returns a path that is guaranteed to hold real bytes (never a pointer).
Converted readers:
`session view` already auto-hydrates correctly; daemon `session-finalize` already skips on pointer; both unchanged.
`agent_session.go` recording stop path gets an explicit invariant comment so future refactors don't start writing recording content directly to the ledger working tree.
Tests
Existing tests from #561 (`TestResolveContentPath_CacheOnlyDesign` × 4 subtests) still pass and continue to assert the contract at the lower-level resolver.
Test plan
Summary by CodeRabbit
Chores
Refactor