Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a regression test in the manual-commit strategy area to cover a PostCommit edge case where an ACTIVE session can be incorrectly treated as “read-only” (and skipped for condensation) when another concurrent session’s FilesTouched overlaps the committed files.
Changes:
- Add a new strategy-level test (
TestPostCommit_ReadOnlyHeuristic_BlocksActiveSession) that exercises PostCommit condensation behavior under concurrent-session overlap conditions. - Introduce a local fake agent implementing transcript-analyzer capabilities to simulate “no new writes since last condensation offset”.
| func (f *fakeAgentWithTranscriptAnalyzer) GetTranscriptPosition(_ string) (int, error) { //nolint:unparam // interface conformance | ||
| return len(f.transcript), nil | ||
| } |
There was a problem hiding this comment.
GetTranscriptPosition is expected to return a transcript position (line count for JSONL or message count for JSON), but this stub returns len(transcript) in bytes. That can make hasNewTranscriptWork/offset comparisons behave incorrectly if the fake is reused in other tests; consider counting JSONL lines (or delegating to the real parser) instead.
| } | ||
|
|
||
| func (f *fakeAgentWithTranscriptAnalyzer) ExtractModifiedFilesFromOffset(_ string, _ int) ([]string, int, error) { //nolint:unparam // interface conformance | ||
| return f.modifiedFiles, 0, nil |
There was a problem hiding this comment.
ExtractModifiedFilesFromOffset returns currentPosition=0 unconditionally. The TranscriptAnalyzer contract expects currentPosition to reflect the current transcript position (line/message count), and callers may persist that value as the next offset; returning 0 can cause repeated rescans or incorrect offset updates if this stub is reused elsewhere.
| return f.modifiedFiles, 0, nil | |
| return f.modifiedFiles, len(f.transcript), nil |
| fakeAgent := &fakeAgentWithTranscriptAnalyzer{ | ||
| fakeExternalAgent: fakeExternalAgent{name: agentBName, agentType: agentBType}, | ||
| transcript: transcriptContent, | ||
| modifiedFiles: nil, // No new file modifications since last condensation offset | ||
| } | ||
| agent.Register(agentBName, func() agent.Agent { return fakeAgent }) |
There was a problem hiding this comment.
agent.Register factories are expected to create a new agent instance, but this closure always returns the same shared *fakeAgentWithTranscriptAnalyzer pointer. If any code calls agent.Get/GetByAgentType multiple times (or tests run in parallel), this can introduce shared mutable state and data races; return a fresh fake instance from the factory (or clone the struct) instead.
| fakeAgent := &fakeAgentWithTranscriptAnalyzer{ | |
| fakeExternalAgent: fakeExternalAgent{name: agentBName, agentType: agentBType}, | |
| transcript: transcriptContent, | |
| modifiedFiles: nil, // No new file modifications since last condensation offset | |
| } | |
| agent.Register(agentBName, func() agent.Agent { return fakeAgent }) | |
| agent.Register(agentBName, func() agent.Agent { | |
| return &fakeAgentWithTranscriptAnalyzer{ | |
| fakeExternalAgent: fakeExternalAgent{name: agentBName, agentType: agentBType}, | |
| transcript: append([]byte(nil), transcriptContent...), | |
| modifiedFiles: nil, // No new file modifications since last condensation offset | |
| } | |
| }) |
Note
Low Risk
Low risk because it only adds a new strategy-level test and test-only fake agent; production logic is unchanged.
Overview
Adds
readonly_heuristic_test.go, a regression test that reproduces an edge case whereshouldCondenseWithOverlapCheckcan skip condensation for an ACTIVE session when another concurrent session claims overlappingFilesTouchedbut transcript-basedfilesTouchedBeforeis empty.The test introduces a test-only
fakeAgentWithTranscriptAnalyzerto simulate “no new modifications since last condensation,” then assertsPostCommitstill writes the checkpoint toentire/checkpoints/v1(soentire explaincan resolve theEntire-Checkpointtrailer) and updates the session’sLastCheckpointID.Reviewed by Cursor Bugbot for commit b9f5775. Configure here.