What
sessions inspect <name> returns stale "Ended" / "Duration" / "Messages" data when called close to the actual end of a headless session. The values can be off by tens of minutes and many messages.
Reproducer (observed today)
Launched two headless peer-review sessions in background via nohup sessions wake <name> --headless --model anthropic/claude-opus-4-7 --message "..." &. After the foreground chat wait was killed by the user, I immediately ran sessions inspect <name> to figure out where things stood. ~17 minutes later I re-ran sessions inspect <name>. The two snapshots differed materially.
Pass 1 (ikma peer review of notes#59)
First inspect:
Started May 04 · 14:26 · (23m ago)
Ended May 04 · 14:32 · (17m ago)
Duration 5m
Messages 23 (1 user, 22 assistant)
Second inspect ~17m later:
Started May 04 · 14:26 · (23m ago)
Ended May 04 · 14:49 · (6s ago)
Duration 23m
Messages 25 (1 user, 24 assistant)
The session was not ended at first-inspect time despite "Ended" being reported. Duration was 5m vs. actual 23m. Two more assistant messages had landed in the meantime.
Pass 2 (baby-joel peer review of notes#59)
Same shape: first inspect showed a shorter duration and earlier "Ended"; the next inspect showed the full 24m run with the final BATS-test orchestration steps the agent did right before stopping.
Why this matters
The session-based peer-review pattern (peer-review-via-sessions.md in den) treats sessions inspect as the natural "did it finish?" status check. Stale snapshots cause the author to make wrong calls:
- False positives ("it's done"). I assumed the session had finished and started a resume run. The original session was actually still mid-investigation, so two reviewer processes briefly ran concurrently before my kill cleaned up the second.
- Misleading post-mortem. When triaging "why didn't the review file get written?" the cached message count made it look like the session ended cleanly mid-investigation, when in reality it had run another 17 minutes and still didn't write the file.
- Background processes orphaned. When the
nohup sessions wake shell was killed, pi exited but its bats-exec-suite / bats-exec-test children kept running orphaned in /tmp/peer-review-notes-59-pass2-…. sessions inspect reported "Ended" while these children were still touching the workspace. (Could be a separate bug — sessions wake --headless not propagating SIGTERM to descendants — but the misreport amplifies its impact.)
Hypotheses
I don't have strong evidence here, so floating possibilities for triage:
- Inspect caches the "Ended" timestamp based on the most-recent JSONL write seen at first read, even when newer writes arrive shortly after.
- Inspect uses a heuristic like "no writes for N seconds → Ended" with N too short for typical model latency between turns.
- The session JSONL writer is buffered and inspect reads what's flushed, so an inspect before the next flush sees stale state.
- Some metadata is read-once at session-end but the "session-end" determination triggers prematurely under abort/SIGINT conditions.
What I'd want as a user
Either (or both):
sessions inspect always reads fresh from the JSONL (no caching), and only reports Ended when the writer process is verifiably gone (PID check, lock file, etc.).
- An explicit "data freshness" indicator in the output (e.g.,
as of: <ts> or WARNING: writer still active) so callers know the snapshot may move.
Workaround for now
- Re-run
sessions inspect after a beat (~30s) and compare. If values drift, the session isn't actually done.
- For peer-review prompts: rely on the chat-completion-ping carve-out (
chat send --chat <author> "review complete...") as the source of truth for "done", not sessions inspect.
Related
peer-review-via-sessions.md (den)
review-session-completion.md (den) — recommends chat wait precisely because polling sessions inspect is unreliable; this issue is the underlying reason.
What
sessions inspect <name>returns stale "Ended" / "Duration" / "Messages" data when called close to the actual end of a headless session. The values can be off by tens of minutes and many messages.Reproducer (observed today)
Launched two headless peer-review sessions in background via
nohup sessions wake <name> --headless --model anthropic/claude-opus-4-7 --message "..." &. After the foregroundchat waitwas killed by the user, I immediately ransessions inspect <name>to figure out where things stood. ~17 minutes later I re-ransessions inspect <name>. The two snapshots differed materially.Pass 1 (ikma peer review of notes#59)
First inspect:
Second inspect ~17m later:
The session was not ended at first-inspect time despite "Ended" being reported. Duration was 5m vs. actual 23m. Two more assistant messages had landed in the meantime.
Pass 2 (baby-joel peer review of notes#59)
Same shape: first inspect showed a shorter duration and earlier "Ended"; the next inspect showed the full 24m run with the final BATS-test orchestration steps the agent did right before stopping.
Why this matters
The session-based peer-review pattern (
peer-review-via-sessions.mdin den) treatssessions inspectas the natural "did it finish?" status check. Stale snapshots cause the author to make wrong calls:nohup sessions wakeshell was killed,piexited but itsbats-exec-suite/bats-exec-testchildren kept running orphaned in/tmp/peer-review-notes-59-pass2-….sessions inspectreported "Ended" while these children were still touching the workspace. (Could be a separate bug —sessions wake --headlessnot propagating SIGTERM to descendants — but the misreport amplifies its impact.)Hypotheses
I don't have strong evidence here, so floating possibilities for triage:
What I'd want as a user
Either (or both):
sessions inspectalways reads fresh from the JSONL (no caching), and only reportsEndedwhen the writer process is verifiably gone (PID check, lock file, etc.).as of: <ts>orWARNING: writer still active) so callers know the snapshot may move.Workaround for now
sessions inspectafter a beat (~30s) and compare. If values drift, the session isn't actually done.chat send --chat <author> "review complete...") as the source of truth for "done", notsessions inspect.Related
peer-review-via-sessions.md(den)review-session-completion.md(den) — recommendschat waitprecisely because pollingsessions inspectis unreliable; this issue is the underlying reason.