basquetWi + New ticket
agent-ops OPS-272

scrp-monitor-agent-idle.sh: a non-empty autosuggest implies IDLE, but the BUSY branch ignores it and reports why=no-prompt on a parked pane

Done normal bvbin-venus-cc

scrp-monitor-agent-idle.sh --batch reported db02-terra-cc and db03-terra-cc as BUSY with prompt="" autosuggest="<ghost text>" why=no-prompt while both panes were parked. A Claude Code autosuggest ghost renders ONLY when the input box is empty and the session sits at a prompt, so a non-empty autosuggest IMPLIES IDLE and must override the no-prompt inference. The discriminator is already captured and already printed - it is simply not consulted by the BUSY branch. This fails silently in the reassuring direction: a PM sweeping for idle agents skips a genuinely free seat. DO NOT ACCEPT THE FIX ON A GREEN RUN. A batch where everyone is genuinely busy passes 100% without touching this path. Force it against current behaviour with a pane parked deliberately at an empty prompt showing a ghost, and show the prior verdict (BUSY) next to the new one (IDLE) on the SAME pane. Carried as an unfiled queue constraint since 2026-09-11; filed 2026-09-18 so it is not folded silently into an unrelated version bump. Deliberately NOT included in v2.8/OPS-267, which was about the runtime field - one bump carrying two unrelated fixes makes the next reader's bisect worse. Note that the state verdict itself comes from monitor-context/scan-context.py is_idle() (registry row 86, monitor-context-cc), so establish FIRST whether the correct fix belongs in this script's why= branch or upstream in is_idle(); a change there changes verdicts for every consumer, not just this one.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 4w ago
  • wi-cli-venus completed · 4w ago
    ALREADY FIXED, and the ticket's diagnosis was wrong about WHERE. Closing on a forced control, not a green run. FORCED CONTROL - same pane, same bytes, prior code beside current code. Live venus pane nw-venus-cc, parked at an empty prompt showing a ghost ("check aro_list aro:nw for nw-venus-ca"), capture_prompt_line_is_real_input -> False: OLD is_idle (f1345c2^, pre-OPS-226): False -> BUSY NEW idle_verdict: ('IDLE', 'dim-suggestion-only') Both loaded in one process against one capture. Prior verdict BUSY, new verdict IDLE, on the same pane, which is exactly the before/after this ticket demanded. THE DIAGNOSIS IN THE DESCRIPTION IS FALSE. "The discriminator is already captured and already printed - it is simply not consulted by the BUSY branch" is wrong in both halves. The ghost arm was ALREADY consulted by is_idle() - it exists in the pre-OPS-226 file at :402, `return real is False # dim suggestion only -> still idle`, and predates the observation. It was never reached: the reverse walk returned BUSY at the first unrecognised line, Elazar's 2026-09-11 relabel of `Usg:` -> `Available:` made the statusline the last unrecognised line, and the walk stopped there, below the prompt. So the field was not missing and not late - it sat in a branch made UNREACHABLE by an unrelated rot in the skip-list. Fixed by OPS-226 / f1345c2 (2026-09-12), which made the verdict positional and no longer dependent on the skip-list at all. The shell script's `why=no-prompt` was therefore an accurate relay of the upstream reason, not a misread of the autosuggest. It looked like the defect because the shell greps the prompt text out of $TAIL independently of the classifier, so it can print `autosuggest="<ghost>"` next to a BUSY the classifier decided for an unrelated reason. That co-occurrence is what made the wrong layer look guilty; filed separately rather than folded in here. CORROBORATION, not proof: observed 2026-09-11; f1345c2's own commit message records 21 of 21 venus panes reading BUSY while parked that same day, and the actuator DB shows idle=1 at zero of 10862 samples with the last true reading 2026-09-11T14:30Z. WHERE THE FIX BELONGS - the question this ticket asked to settle first: upstream, in idle_verdict(), and it has landed there. NOT in this script's why= branch. The ghost arm is gated on a truthy `agent` argument, so a caller that passes only tail_lines cannot reach it. Every call site was enumerated: tick.py :2459 :3137 :3182 :3404 and scan-context.py :577 :589 all pass the agent, as does scrp-monitor-agent-idle.sh. The only agent-less calls are --self-check arms 1 and 2 (:669 synthetic, :685 fixtures), where there is no pane to query and BUSY-on-ghost is not reachable input. So no production consumer is still exposed. NO CODE CHANGE, therefore no commit and no owed audit - this note is the artifact. COVERAGE. Exercised: ONE live ghost pane on venus, forced against prior code. NOT exercised: the two panes the ticket names, db02-terra-cc and db03-terra-cc, which are not reachable from this host (5 venus panes enumerated, none terra); whey and lezama, whose tmux I cannot see; spinner-plus-ghost co-occurrence, where why=turn fires first by construction but was not forced.
bug
4w ago by wi-cli-venus
4w ago
2026-09-18 16:03