Skip to content

Complete #140: analyze cascade-payload logs, expand SessionEnd skip-list, restore LOADOUT/AGENT preservation #151

Description

@martin-conur

Context

Follow-up from PR #150 (closes #140 partially) — reviewer findings #1 + nit.

PR #150 ships three pieces for the radio session corruption bug:

This issue is the cleanup pass to finish Bug A and unblock Bug C.

The dependency

PR #150's sidecar is swept whenever `cmd_unregister` doesn't bail on the skip-list (`reason=clear|resume` only). The cascade fires with non-skip reasons, blasts both the session file AND the sidecar, and `_ensure_session_file` then re-seeds with no sidecar to read → `LOADOUT=unknown` returns.

The complete fix is:

  1. Collect cascade logs from a few real worker runs (PR Radio session corruption: unregister cascade → re-seed loses TAB_ID + LOADOUT #150 adds the logging mechanism).
  2. Identify which `reason` values the cascade actually fires with.
  3. Expand `cmd_unregister`'s skip-list to include those values (treat the cascade-trigger reasons the same as `clear` / `resume` — known intra-session events that must not delete state).
  4. Re-test the corruption scenario: with the cascade skipped, the sidecar survives, `_ensure_session_file` reads it, LOADOUT is preserved.

Includes: AGENT env-loss (reviewer nit)

`_ensure_session_file` writes `AGENT=${TASK_FORCE_AGENT:-claude}`. `$TASK_FORCE_AGENT` has the same hook-subshell unset problem `$TASK_FORCE_LOADOUT` had — kiro-* workers re-seed with `AGENT=claude` instead of `AGENT=kiro`. No runtime consumer today, but a silent footgun if anyone adds one.

Fix: apply the same sidecar pattern (or whatever mechanism solves LOADOUT) to AGENT. Same place, same code, trivial.

Deliverables

  1. Diagnose the cascade — run a few `--auto` workers long enough to trigger the cascade (one PM session is enough; we've reproed it twice today on issue-144 and issue-140). Inspect `~/.task-force/radio/log` for the new full-payload lines and identify the `reason` values. Document in the issue / PR body.
  2. Expand `cmd_unregister`'s skip-list in all 7 radio scripts (drift-grouped `# region:body`) to include the observed cascade reasons.
  3. Add AGENT sidecar (or fold into LOADOUT mechanism) — same code path as LOADOUT.
  4. Tests — extend `tests/radio_lifecycle.bats` with a cascade scenario using the newly-skipped reason; assert sidecar + LOADOUT + AGENT survive.
  5. CHANGELOG `[Unreleased]` — promote the Fix C entry from "sidecar mechanism" to "sidecar mechanism + cascade reasons fully skipped" before Cut v0.3.0 release (post-#142 merge + dogfooding gate) #143's v0.3.0 cut.

Verification

  • After fix, dispatch a worker via `task-work --auto`; run for several hours including events that previously triggered the cascade (intra-session `/clear`, `/compact`, idle Stop hooks, etc.).
  • `cat ~/.task-force/radio/sessions/worker-*.info` — TAB_ID populated, LOADOUT correct, AGENT correct.
  • PM `radio send --to ` wakes the worker via tab-id; no silent queueing.
  • `tail ~/.task-force/radio/log` — no "_ensure_session: re-seeded" lines after long-running sessions.

Out of scope

  • Other forms of session corruption not driven by the SessionEnd cascade (e.g. SIGKILL'd workers, disk-full scenarios). Heartbeat-based orphan reaper is tracked in Radio orphan self-heal: heartbeat-based stale-session unregister #127.
  • Backporting to dogfood projects' existing degraded sessions — users can `rm ~/.task-force/radio/sessions/.info` and let `_ensure_session_file` rebuild from intact sidecars (after this fix lands).

Why this matters for v0.3.0 (#143)

This is the second half of the #140 fix. With only PR #150 merged, the symptom that prompted #140 — LOADOUT lost on long workers, --auto wake-up dies — still happens in practice. Shipping v0.3.0 with PR #150 alone is shipping a half-fixed reliability bug. The diagnostic logging that #150 adds is the prerequisite for this issue's work.

Priority: P1, milestone v0.3.0 — same gating as #140.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions