Skip to content

fix(cockpit): derive accurate live task state — no more phantom in-flight workers - #126

Merged
robercano-ghbot merged 1 commit into
mainfrom
fix/cockpit-accurate-live-state
Jul 16, 2026
Merged

fix(cockpit): derive accurate live task state — no more phantom in-flight workers#126
robercano-ghbot merged 1 commit into
mainfrom
fix/cockpit-accurate-live-state

Conversation

@robercano-ghbot

Copy link
Copy Markdown
Collaborator

Problem

The cockpit showed tasks (e.g. #70 "reviewing", #81 "implementing") as in-flight a week after they finished and their PRs merged.

Two compounding causes in the live-progress panel:

  1. Worker identity was keyed on the raw task string. Workers log the same task inconsistently (81, issue-81, issue-70-worker-inspector), so a done logged under one variant never overwrote the reviewing logged under another — the stale identity rendered as active forever.
  2. No task-level terminal state. The orchestrator logged done for the task, but sub-workers that crashed or never emitted their own done (e.g. Harden PR-loop tick: deterministic loop-tick.sh with single verdict, in-flight detection, spawn lock #81's implementer) kept their last phase indefinitely, with no staleness cutoff.

Fix — three derivation rules

  • Identity = (role, normalized task, lens): variants collapse via the existing taskGroupKey() normalizer, so later phases actually overwrite earlier ones. Lens stays in the key (same-role reviewers under different lenses are distinct workers).
  • Orchestrator done finishes the task: a group whose orchestrator's latest event is done, with no worker activity after it (file order), renders as one done-badged header — no phantom rows. Falls back to every-worker-done when there are no orchestrator events; activity logged after an orchestrator done (re-scoped task) keeps the group active.
  • Staleness: unfinished groups silent for >COCKPIT_STALE_AFTER_SECONDS (default 2h; same override style as COCKPIT_NOW) get a stale · no events for Nh/Nd badge with muted rows — a wedged worker shows as wedged, never as active work.

Verified on the real event log

#70, #81 and 8 other finished tasks now render done; 3 genuinely-abandoned groups (#90, #106, #107) render stale; the one task the loop is actually driving right now (#95, scoped 25 min before the check) still renders active with its warn badge.

Tests

+10 checks in cockpit.test.sh (fixture mirrors the exact production log shape that exposed the bug: implementer that never logs done, reviewer whose done lands under an id variant, orchestrator close, post-done re-scope, 49h-silent group, threshold override). All 80 existing checks pass unchanged. Gates: buildlinttest

🤖 Generated with Claude Code

…ight workers

The live-progress panel keyed worker identity on the RAW task string, so
the same worker logging "81" then "issue-81" (or
"issue-70-worker-inspector") became several identities, and a "done"
logged under one variant never overwrote the "reviewing" logged under
another. Combined with workers that crash or simply never emit their own
done, the cockpit showed tasks 70/81 as reviewing/implementing a week
after their PRs merged.

Three derivation rules fix it:

- Worker identity is (role, normalized task, lens): id variants collapse
  via the existing taskGroupKey() normalizer, so a later done actually
  overwrites the earlier phase. Lens stays in the key — reviewers of the
  same task under different lenses are distinct workers.
- The orchestrator owns the task lifecycle: a group whose orchestrator's
  latest event is done — with no worker activity logged after it (file
  order) — renders as a single done-badged header, not a table of
  phantom in-flight rows. No orchestrator events falls back to
  every-worker-done. Activity logged AFTER an orchestrator done (task
  re-scoped) keeps the group active.
- Unfinished groups silent for >COCKPIT_STALE_AFTER_SECONDS (default 2h,
  same override style as COCKPIT_NOW) are badged "stale · no events for
  Nh/Nd" with muted rows — a wedged worker should be visible as wedged,
  never as active work.

Verified against the real event log: 70/81 (and 8 other finished tasks)
now render done, three genuinely-abandoned groups render stale, and the
one task the loop is actually driving (#95, scoped 25 min ago) still
renders active.

Adds 10 checks to cockpit.test.sh (fixture mirrors the exact production
log shape that exposed the bug); all 80 existing checks pass unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@robercano-ghbot
robercano-ghbot merged commit 911232b into main Jul 16, 2026
9 checks passed
@robercano-ghbot
robercano-ghbot deleted the fix/cockpit-accurate-live-state branch July 16, 2026 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants