Summary
With cli-jaw 2.1.5 using agy 1.0.10, the Antigravity transcript watcher can pin the previous conversation's existing transcript.jsonl even when the current turn is written to a newly created brain/conversation directory.
This hides all current-turn activity from cli-jaw. If agy then stalls after a compaction checkpoint, cli-jaw keeps watching the stale file until the absolute watchdog timeout and returns no response.
Reproduction observed
- A previous main-session turn completed in conversation A.
- cli-jaw retained A as its saved agy session.
- A new Telegram request started at 09:04:51 UTC.
- agy created conversation B and wrote:
USER_INPUT at 09:04:55
- a
PLANNER_RESPONSE with a read-only grep tool call
CHECKPOINT at 09:05:18
- No more rows were written after the checkpoint.
- cli-jaw logged that it was tailing conversation A, whose transcript mtime was 09:02:42 and which never contained the current turn.
- At 610 seconds, the watchdog killed the run with:
[jaw:watchdog] killing main - absolute timeout 610s
Root cause in cli-jaw
In agy-transcript-watcher.js, the watcher prefers resolveAgyTranscriptPath(...currentSessionId) whenever that old file exists. The recent-transcript fallback is therefore never evaluated. The later session-change check cannot recover because getSessionId() continues returning saved conversation A while agy is running in B.
A second issue appears after switching: the current session mismatch block discards B again on every poll because the persisted ID still points to A.
Expected behavior
- A transcript resolved from the saved session should only be accepted for the current turn if it is fresh enough and belongs to the current invocation.
- The watcher should periodically detect a newer prompt-matching transcript created after
startedAt and switch to it.
- A fresh prompt-matching transcript must take precedence while the saved session ID catches up.
- Switching should reset offset and final-planner state safely.
- A
CHECKPOINT followed by no transcript/stdout activity should produce a distinct compaction-stall reason rather than waiting for the generic absolute timeout.
Suggested fix
- Treat a saved-session transcript with
mtime < startedAt - lookback as stale for initial attachment.
- While the child is running, periodically call
resolveRecentAgyTranscriptPath(startedAt - lookback, prompt).
- If a different, newer matching path appears, atomically switch paths and reset the read offset.
- Namespace transcript tool dedupe keys by conversation ID.
- Optionally detect
CHECKPOINT inactivity separately. Do not automatically retry mutating runs; a retry is only safe when no side-effecting tool has completed.
This is separate from agy's apparent failure to resume after its own checkpoint. cli-jaw cannot necessarily repair that provider-side stall, but it can follow the correct transcript and report the failure accurately.
Local verification
A local 2.1.5 mitigation was tested with two fixtures:
- stale conversation A exists, the current prompt is written to B, and B ends at
CHECKPOINT: the watcher attaches B and reports B stalled
- the current prompt is written to C and
CHECKPOINT is followed by planner activity: no false stall
Both fixtures pass, and the production server restarts cleanly with the patch.
Environment
- cli-jaw: 2.1.5
- agy: 1.0.10
- backend: Antigravity CLI print mode
- channel: Telegram main session
Related context: #244 covers watchdog activity/timeout behavior, but this report concerns stale transcript selection and brain rotation.
Summary
With
cli-jaw 2.1.5usingagy 1.0.10, the Antigravity transcript watcher can pin the previous conversation's existingtranscript.jsonleven when the current turn is written to a newly created brain/conversation directory.This hides all current-turn activity from cli-jaw. If agy then stalls after a compaction checkpoint, cli-jaw keeps watching the stale file until the absolute watchdog timeout and returns no response.
Reproduction observed
USER_INPUTat 09:04:55PLANNER_RESPONSEwith a read-only grep tool callCHECKPOINTat 09:05:18[jaw:watchdog] killing main - absolute timeout 610sRoot cause in cli-jaw
In
agy-transcript-watcher.js, the watcher prefersresolveAgyTranscriptPath(...currentSessionId)whenever that old file exists. The recent-transcript fallback is therefore never evaluated. The later session-change check cannot recover becausegetSessionId()continues returning saved conversation A while agy is running in B.A second issue appears after switching: the current session mismatch block discards B again on every poll because the persisted ID still points to A.
Expected behavior
startedAtand switch to it.CHECKPOINTfollowed by no transcript/stdout activity should produce a distinct compaction-stall reason rather than waiting for the generic absolute timeout.Suggested fix
mtime < startedAt - lookbackas stale for initial attachment.resolveRecentAgyTranscriptPath(startedAt - lookback, prompt).CHECKPOINTinactivity separately. Do not automatically retry mutating runs; a retry is only safe when no side-effecting tool has completed.This is separate from agy's apparent failure to resume after its own checkpoint. cli-jaw cannot necessarily repair that provider-side stall, but it can follow the correct transcript and report the failure accurately.
Local verification
A local 2.1.5 mitigation was tested with two fixtures:
CHECKPOINT: the watcher attaches B and reports B stalledCHECKPOINTis followed by planner activity: no false stallBoth fixtures pass, and the production server restarts cleanly with the patch.
Environment
Related context: #244 covers watchdog activity/timeout behavior, but this report concerns stale transcript selection and brain rotation.