PR #9 broadened token invalidation in two spots that also fired on
non-terminal results, breaking resume continuity for parked runs:
- _persist_session cleared the canonical role token and the task's
resume pin on any result.status != DONE. An approval park
(AWAITING_HUMAN) therefore wiped continuity right before the human
approved, and the retry restarted the external thread from scratch.
Both clears are now gated on _SESSION_INVALIDATING_RESULT_STATUSES
(terminal failures only).
- _stored_provider_token_allows_resume returned False whenever the
newest row for a token was not done/suspended, so a run parked on
approval vetoed its own token at the next restore. The verdict is
now tri-state: terminally failed rows still return False (wipe),
finalized rows return True, and live-but-unfinalized rows return
None (keep the pin) — except provider_stream tokens, which keep the
strict pre-existing rule via strict=True since an unfinalized stream
row may belong to a crashed attempt.
Regression tests: approval park keeps role token and task metadata;
restore keeps a canonical token whose newest row is awaiting_human;
unfinalized provider_stream tokens are still rejected.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>