tasks: card 63 — a phase in flight is work happening
From a board showing 11 of 14 merged with member 31 in review/ and its CI still running: the phase was advancing and every surface keyed to a running agent said the board was idle. The tab title went back to the plain project name, the live chip fell through to "you, working", and the member the phase was waiting on wore "waiting on you" — which is the opposite of true, since the phase merges it by itself on green. The reading already exists client-side (phasesInFlight()), and the snapshot already carries running/halted/stopped plus per-member states. Nothing is missing but the question being asked, in three places that answer it with runningAgents() instead. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
# 63 — A phase in flight is work happening, and the board should say so without an agent
|
||||
|
||||
**Status:** Backlog
|
||||
**Priority:** High — a phase advancing between members reads as an idle
|
||||
board on every surface keyed to a running agent, including the one surface
|
||||
a backgrounded tab has left
|
||||
**Type:** Bug
|
||||
|
||||
The board has one word for "something is happening" and it is spelled
|
||||
"an agent is running". A phase does not need one: it advances on a beat,
|
||||
and it spends much of its life with no agent alive at all — while a
|
||||
member's checks run, between a merge and the next launch, while a
|
||||
dependency lands. In all of those the phase is working and every
|
||||
agent-keyed signal on the board says nothing is. The tab title goes back
|
||||
to the plain project name, the live chip falls through to "you, working
|
||||
1 session", and the member the phase is actually waiting on wears
|
||||
`waiting on you` — which is the opposite of true, because nothing is
|
||||
waiting on you and the phase will merge it by itself the moment CI goes
|
||||
green.
|
||||
|
||||
## Context
|
||||
|
||||
Observed on a phase with 11 of 14 merged, member #31 in `review/` with
|
||||
`CI ◌` in flight and the phase chip reading
|
||||
`⟶ Phase: platform harde… 11/14 · on #31`. The phase was healthy and
|
||||
advancing; nothing but that chip said so.
|
||||
|
||||
- `manager/core/board.html:1225` — `tabTitle(S.state.project, S.view,
|
||||
runningAgents().length)`. The count is agents and only agents, so a
|
||||
phase in flight with no agent produces the quiet title, byte for byte.
|
||||
This is the surface that matters most: the comment above it argues the
|
||||
count leads *because* "a backgrounded window" is the only place the
|
||||
state can still be read — and a phase is exactly the long-running thing
|
||||
you background the tab on.
|
||||
- `manager/core/board.html:1026-1028` — `runningAgents()`, described as
|
||||
"one reading of 'an agent is working', shared by the header chip and
|
||||
the tab title, so the two can never disagree". Correct as far as it
|
||||
goes; there is no equivalent reading of "the board is working".
|
||||
- `manager/core/board.html:1099-1104` — `phasesInFlight()` already exists
|
||||
and already answers it: `p.running || p.halted`, straight off the
|
||||
snapshot. The title has the fact available and does not consult it.
|
||||
- `manager/core/board.html:766-768` — `pillFor(stage, working)`: `working`
|
||||
is agent-driven, and every other `review/` card is `waiting on you`
|
||||
unconditionally. A phase member whose checks are still running is not
|
||||
waiting on anyone.
|
||||
- `manager/core/phases.py:286-322` — the snapshot the UI reads carries all
|
||||
of it already: `running`, `halted`, `stopped`, and per-member states
|
||||
including `waiting` ("its checks are still running") and `ready`. No new
|
||||
server state is needed for any of this.
|
||||
- `AGENTS.md`, "Watching one run, and watching it stop" — "Only a run
|
||||
wears the working vocabulary … because only a run is work happening."
|
||||
That sentence is the source of the gap: a phase run *is* a run. It
|
||||
needs saying in a way that does not read as "only an agent".
|
||||
|
||||
**Affected areas:** `manager/core/board.html` — the header, the tab title
|
||||
and `pillFor`; `AGENTS.md` for the working-vocabulary rule and the tab
|
||||
title's description.
|
||||
|
||||
## What to build
|
||||
|
||||
- **The tab title says a phase is in flight.** A board with a phase
|
||||
running and no agent on anything must not render the quiet title.
|
||||
Reuse `phasesInFlight()` rather than adding a second reading of it.
|
||||
- **Without ever implying an agent that is not there.** The count is a
|
||||
count of agents and stays one — `1◌` when a phase runs and nothing is
|
||||
launched would be a lie, and the tab is the one place nobody can check
|
||||
it against the board. Use the phase's own glyph (`⟶`, as the chip and
|
||||
the member chips already do) so the two states are distinguishable at a
|
||||
glance and can appear together.
|
||||
- **A halted or held phase wears none of it.** A halt is stopped work and
|
||||
already says so in `--alarm` in the chip, the switcher and a toast;
|
||||
putting it in the working position of the title would make "something
|
||||
is happening" mean "something has stopped".
|
||||
- **The member the phase is waiting on stops claiming to wait on you.**
|
||||
A `review/` card whose phase is running and whose checks are still
|
||||
running should read as what it is — the phase's business, not yours.
|
||||
It keeps its CI chip; this is the pill only.
|
||||
- **Say the rule properly in `AGENTS.md`.** The working vocabulary
|
||||
belongs to work in flight, and a phase beat is work in flight; the tab
|
||||
title's paragraph should say what it leads with when the work is a
|
||||
phase.
|
||||
|
||||
**Out of scope** — nearby and deliberately untouched:
|
||||
|
||||
- **The header's phase chip.** It is already correct and already the
|
||||
fullest statement of this on the screen. This card is about the
|
||||
surfaces that contradict it.
|
||||
- **The breathing animation's meaning.** One looping animation, one
|
||||
meaning — work in flight. Nothing here adds a second animated state.
|
||||
- **Any new server-side state or event.** The snapshot already carries
|
||||
every fact needed; a change to `phases.py` would be a sign of solving
|
||||
it in the wrong layer.
|
||||
- **What a phase member's pill says in every other situation.** Only the
|
||||
running-phase, checks-running case is wrong today.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [ ] Given a phase running with a member in `review/` whose CI is still
|
||||
running and no agent alive anywhere, when the tab is backgrounded,
|
||||
then the title says work is in flight.
|
||||
- [ ] Given the same board, the title does not state an agent count — a
|
||||
reader cannot conclude an agent is running when none is.
|
||||
- [ ] Given both an agent running and a phase in flight, the title says
|
||||
both, and still fits a narrow tab well enough to read the leading
|
||||
mark.
|
||||
- [ ] Given a phase that has halted, the title carries no working mark;
|
||||
given a phase held with **‖ hold**, likewise.
|
||||
- [ ] Given a board with no phase and no agent, the title is exactly the
|
||||
plain `<project> · bench` it is today, byte for byte.
|
||||
- [ ] Given a member in `review/` whose phase is running and whose checks
|
||||
are still running, its pill does not say `waiting on you`.
|
||||
- [ ] Given a member in `review/` whose phase has halted, or a `review/`
|
||||
card in no phase at all, the pill is unchanged.
|
||||
- [ ] Edge case: two phases in flight at once — the title says work is
|
||||
happening once, not twice, and does not grow with the number of
|
||||
phases.
|
||||
|
||||
## Open questions
|
||||
|
||||
- None.
|
||||
|
||||
## Notes
|
||||
|
||||
The confusion this fixes is specific and worth keeping in mind while
|
||||
choosing the wording: the board was not wrong anywhere, it was *silent*
|
||||
in the places a person looks when they are not looking at the board. The
|
||||
Phases view said 11 of 14 and named the member in flight; the header chip
|
||||
breathed. Both require the tab to be in front of you, which is the state
|
||||
a phase is least likely to be in — a phase is the feature you start and
|
||||
walk away from, and walking away is when the tab title becomes the whole
|
||||
interface.
|
||||
|
||||
**Risks** — the tab title is read at a glance and truncates hard, so the
|
||||
temptation is to pack it. Every character added to the lead costs the
|
||||
project name, which is what tells two bench tabs apart. Prefer one glyph
|
||||
over a word.
|
||||
Reference in New Issue
Block a user