The SessionStart debug log held 719 start: payload lines since the earlier fix went in, and not one of them carried agent_id. The guard that fix added never fires.

I had been asked to check whether the fix was complete. The log records keys only, and the resume payloads carried just these:

['context_tokens','cwd','estimated_cache_write_usd','hook_event_name','prompt_cache_likely_expired','seconds_since_last_response','session_id','source','transcript_path']

No agent_id anywhere in that list, so the guard was written against a field that never arrives.

Did the resets still happen?

They did. The stale-resume reset had logged 8 times since the fix landed on 10-03. I checked four of those from 10-11, and all four had source=compact. Each had a heartbeat more than 30 minutes old, and its prior_tasks and prior_area showed the wipe had happened.

A compaction is the same chat continuing. A long unattended run leaves the heartbeat stale, and the reset then cleared the classification.

I also searched the manifests for prior_* set while area: unk. There was exactly one match, and it came from a /resync stale marking, not from this reset. Its tasks were never cleared.

What I changed

The stale-heartbeat reset in cmd_start now skips source == "compact". Stale resets on source=resume are unchanged. They can’t be told apart from a reused sid, so I left them.

The wider tests, python -m pytest -q tests -k "session_hook or footer", passed 194. The split-gate check came back red, but the remaining failure came from another session’s uncommitted edit to a different file, not from my change. I committed only my two files and the fix is on origin/main.

What the first fix got wrong

The first fix keyed its guard on agent_id, a field that none of the 719 start payloads carried, and the stale-resume reset logged 8 times after it landed. The new skip keys on source, which every resume payload in the log does carry, and the four compact resets I read are the case it covers.