feat(board): FLY column and free-capacity lines, no process inspection
ORDRE counted pending orders only, so a repo with one order in flight and a repo with no orders at all both printed 0 - the same digit for two opposite facts. Measured 2026-08-23: two panes stood open and idle for 45 hours holding finished orders, with full quota authorised, and no column on the board reported it. FLY counts orders/claimed/ - the same queue in its other state, never summed with ORDRE and never a fourth axis. It does NOT mean a session is alive: nothing un-claims an order when the claiming session dies, and one order on the live mailbox had been claimed for 117 hours. The legend denies the liveness reading in those words, pinned as a check on the legend text. --plan now names free capacity as ledig_antall=N plus one ledig=<repo> (<status>) line per repo with nothing owed, no pending order, nothing in flight, a clean tree, at done or deferred. All four conditions are required: measured on the real tree, 4 of 17 done/deferred repos were not free. Lines, never blocks - the plan's second consumer discards a block with no tab=, so a block would be visible to the operator and invisible to the driver. Process inspection was considered and refused; the selftest asserts the absence of pgrep/pkill/lsof structurally with a known-positive control. The full argument, and the gap left open, are in docs/2026-08-23-free-capacity-investigation.md. board-selftest: 259 -> 281 checks, all green. npm test 11/11. Order 20260823T162951Z-941745020-from-.claude Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hfbfr8ERC63kuAfWeHYHQb
This commit is contained in:
parent
2377735554
commit
3beef2a603
12 changed files with 532 additions and 25 deletions
127
docs/2026-08-23-free-capacity-investigation.md
Normal file
127
docs/2026-08-23-free-capacity-investigation.md
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
# Which repos are free? The investigation, and where it stopped
|
||||
|
||||
Ordered 2026-08-23. The operator's words, translated: *"we need more precision
|
||||
about you knowing which repos are finished and can take more work."* What was
|
||||
ordered was an investigation and a design, not a named column — the sending repo
|
||||
supplied the problem and the measurements and left the shape of the answer here.
|
||||
|
||||
Repos are unnamed throughout. This is a public mirror, and which repo was idle
|
||||
for how long is not a fact this file needs to carry to make its argument.
|
||||
|
||||
## The incident
|
||||
|
||||
A session read the board's `ORDRE` column, ran `pgrep -fl claude`, and told the
|
||||
operator that four sessions were working. The operator looked at their screen:
|
||||
one was. Measured afterwards, two of the four processes had accumulated ~38
|
||||
minutes of CPU across **45 hours** of wall clock. They were open panes sitting at
|
||||
a prompt, holding finished orders, during a window in which full quota had been
|
||||
authorised against a deadline four days out.
|
||||
|
||||
Nothing on the board reported it, and that is the part this file is about.
|
||||
|
||||
## Three blind spots, one of which was ours
|
||||
|
||||
1. **`ORDRE` counted pending orders only.** So a repo with one order in flight
|
||||
and a repo with no orders at all both printed `0`. The same digit for two
|
||||
opposite facts — "work is happening here" and "nothing is waiting here" —
|
||||
with no way to tell them apart. This one is a defect in this repo's own
|
||||
rendering, and it is fixed.
|
||||
2. **`STATUS` describes the plan, not the capacity.** `done` does mean "no open
|
||||
step", which is close to what the operator wanted; `planned` and
|
||||
`in-progress` say nothing about whether anyone is actually sitting there. One
|
||||
of the idle repos was `planned` for the full 45 hours, entirely correctly.
|
||||
3. **A process proves existence, not activity.** `pgrep` finds a session that
|
||||
finished everything and went quiet. This one is not ours to fix — see below.
|
||||
|
||||
## What was changed
|
||||
|
||||
### `FLY`: the order queue's other state
|
||||
|
||||
A second count over `orders/claimed/`, printed in its own column beside `ORDRE`
|
||||
and never summed with it. Same queue, other state — **not a fourth axis**, which
|
||||
is why it is a second reading of a source the board already had rather than a new
|
||||
source.
|
||||
|
||||
Verified live on the day it shipped: one repo went from `ORDRE 0` (reading as
|
||||
"nothing here") to `ORDRE 0 / FLY 1`, next to another repo still reading
|
||||
`ORDRE 0 / FLY 0` and genuinely holding nothing. Those two rows had been
|
||||
byte-identical the day before.
|
||||
|
||||
**What `FLY` does not mean, and must never be reworded into: that a session is
|
||||
alive.** A claim is a `mv` a session performed once. Nothing un-claims it when
|
||||
that session dies — which is exactly why the order queue's read path already
|
||||
shows claimed orders with their in-flight age. Measured on the live mailbox the
|
||||
same day: one order had been sitting claimed for **117 hours**. `FLY` is evidence
|
||||
that someone took the order. It is not evidence that anyone is still working it,
|
||||
and the on-screen legend says so in those words, because a column that read as "a
|
||||
session is running here" would be the process axis smuggled in as a file count.
|
||||
|
||||
### `--plan` names free capacity
|
||||
|
||||
`ledig_antall=N`, then one `ledig=<repo> (<status>)` line per free repo. Free
|
||||
means all four at once: nothing **owed** (not merely nothing pending — a notice
|
||||
is not an obligation), no pending order, nothing in flight, clean tree, at
|
||||
`done` or `deferred`.
|
||||
|
||||
All four conditions are load-bearing. Measured on the real tree the same day: of
|
||||
17 `done`/`deferred` repos, **13 were free and 4 were not** — two held a pending
|
||||
order, one owed a reply, one had an uncommitted tree. `status=done` alone would
|
||||
have named the wrong set roughly a quarter of the time.
|
||||
|
||||
It is emitted as **lines, never as blocks**, and that is the whole design rather
|
||||
than a formatting preference. The plan's second consumer opens one pane per
|
||||
block and discards any block without a `tab=` key; a free repo written as a block
|
||||
would therefore be visible to the operator and invisible to the driver. A line is
|
||||
visible to both and can never be opened as a tab by accident. The count prints
|
||||
even when it is zero, so "none found" and "not computed" cannot render as the
|
||||
same output.
|
||||
|
||||
A tab block whose repo already holds a claimed order additionally carries
|
||||
`fly=N`. The driver types into live panes; it should be able to see that first.
|
||||
|
||||
## What was NOT changed, and the argument for it
|
||||
|
||||
**The board still inspects no processes.** No `pgrep`, no `ps`, no `lsof`, and a
|
||||
structural check in the selftest now says so with a known-positive control
|
||||
proving the grep can find a planted call. This was the order's open design
|
||||
question, and the answer is no, for four reasons that compound:
|
||||
|
||||
1. **Every other column is a durable filesystem fact.** They survive a reboot and
|
||||
they are reproducible in a throwaway fixture tree under `CLAUDE_COORD_DIR`. A
|
||||
process column measures the operator's machine at one instant. There is no
|
||||
fixture for it, so it would ship as an unmeasured assumption wearing a passing
|
||||
test — this repo's own named defect class.
|
||||
2. **Mapping a process to a repo needs its working directory**, which on macOS
|
||||
means `lsof`. That is a new external dependency against a stated zero-
|
||||
dependency convention, for a number that would still not mean what a reader
|
||||
would take it to mean.
|
||||
3. **The discriminator is a threshold, and a threshold is a verdict.** "38
|
||||
minutes of CPU across 45 hours is idle" is a judgement about a session's
|
||||
liveness. Encoding it makes the board decide that a session is dead. The order
|
||||
queue is already forbidden from doing exactly this: nothing there expires
|
||||
anything, because building expiry would require the engine to know something
|
||||
it cannot. A process column is that same rule broken on a different surface.
|
||||
4. **The file-based signal is not a substitute either**, and pretending otherwise
|
||||
would just move the error. The 117-hour claim is the proof. So the board
|
||||
reports the claim and refuses the inference, which is what "prints evidence
|
||||
and takes no position" has always meant here.
|
||||
|
||||
The gap this leaves is real and is stated rather than closed: **a pane that is
|
||||
open and idle with no claimed order and no queued work is still invisible to the
|
||||
board.** Such a repo now shows up in `ledig=` if it is `done`/`deferred` and
|
||||
clean, which covers the common case; a `planned` repo with an idle pane does not,
|
||||
and cannot, because nothing in the filesystem distinguishes it from a `planned`
|
||||
repo nobody has opened. Closing that needs a terminal-side measurement, and that
|
||||
belongs to whatever drives the terminal, not to the mailbox.
|
||||
|
||||
## What this does not answer
|
||||
|
||||
The order asked whether the board should say anything about open tabs *at all*.
|
||||
It now says nothing about them, deliberately. If the operator later wants pane
|
||||
occupancy on the board, the honest construction is for the terminal driver —
|
||||
which already probes panes and already consumes `--plan` — to supply that fact
|
||||
inward, the same way `--dispatch` requires `--target-pane` to be measured by the
|
||||
caller and passed in rather than looked up here. That direction keeps the
|
||||
dependency running one way and keeps this repo unable to break on a terminal
|
||||
API. It was not built, because it was not ordered and the operator has not asked
|
||||
for it.
|
||||
Loading…
Add table
Add a link
Reference in a new issue