A stalled sub-agent (provider stream never settling after the final tool
call, or a throwing session-event listener recursing through the SDK's
run-failure path to stack overflow) left the phase stuck in_progress with
no state save, no error, and no completion message — observed twice in
freno-dev, both times after comments wrote findings.md.
- agent-runner: 60-min settle watchdog on every agent phase
(PYGIENIUM_AGENT_TIMEOUT_MS, env-tunable); timeout disposes the session
and fails the phase loudly with a /pygienium-resume hint instead of
hanging the check-runner's await forever.
- agent-runner: applySessionEvent — the session.subscribe listener can no
longer throw into the SDK event pipeline (guards for partial/malformed
events, optional-chained message_update, throwing chat forwarder).
- comments: scan no longer regenerates the full report as its final
message (findings.md is the source of truth); fix phase reads
findings.md with embedded fallback.
- check-runner: failing state-save inside the catch path can't double-
fault or escape as an unhandled rejection; completion posting is
best-effort.
- tests: watchdog timeout test, comments task-text regression tests,
applySessionEvent malformed-shape unit tests. 146 pass, tsc clean.
- README: document PYGIENIUM_AGENT_TIMEOUT_MS.