feat(board): ORDRE and FLY carry the age of the oldest order

Both columns were pure counts (ls | wc -l), so ORDRE 2 read identically
whether both orders arrived yesterday or both had sat for ten days. The
defect was never that orders sit there - that is a prioritisation
question owned by humans. It was that no surface showed the AGE ACROSS
REPOS: coord-order-inbox.sh does show one, but only inside the one repo
at SessionStart, so a repo nobody opens shows nobody anything.

Measured across the live mailbox 2026-08-29 with `find ~/.claude/coord
-path '*/orders/*.md' -maxdepth 3 -type f`: 30 pending orders over 22
repos, 5 of them ten days old. Re-measured here after this session
consumed two of them: 29 over 23 mailboxes, still 5 at ten days. The
residual delta is not attributable from this repo - the mailbox has
other writers - and is reported rather than reconciled away.

Rendered N:Md. This is not a new mechanism in the file: ALDER (STATE.md
mtime) and SISTE (last commit) already read a clock the same way.

The age is the OLDEST order, never the newest and never a mean - a repo
holding one fresh order and one ten-day-old order has a ten-day-old
problem, and the newest reading is exactly what would hide it. FLY
carries the identical reading, and there it matters at least as much:
nothing un-claims an order when the session that took it dies, so a
claim with no age is the 117-hour claim with its only counter-evidence
removed.

An empty queue prints a BARE 0, never "0:0d": "no orders" and "an order
that arrived today" are different facts, the same reason FLY exists
beside ORDRE. An unreadable mtime prints "?" for the WHOLE reading
rather than skipping the file, because an unmeasured file could be the
oldest one - the same token coord-count and DRT already use.

NO NEW SORT AXIS. The age is display-only; putting it in the ranking
would silently reorder a parser living in another repo. --plan's fly=
and every other emitted key=value block are untouched: the requirement
is that a human reading the board sees an order is old without opening
the repo, and the table is where that is read. Nothing here writes -
board.sh stays read-only, and no cron, hook or notifier was added.

TDD: board-selftest.sh section 28 written first and RED before board.sh
was touched. It builds a throwaway coord tree with touch -t mtimes and
asserts its OWN ground truth (the stale fixture really is 10 days old)
before anything depends on it. Known-positive control: a second repo
with two genuinely fresh orders, so the 10d assertion is proven able to
fail. Mutation-verified: flipping -lt to -gt in oldest_order_age turns
exactly the two oldest-specific checks red, all controls green.

Four pre-existing assertions in board-selftest and orders-selftest
matched the old bare-count cell and were updated to the N:Md form; the
claim each pins - INN, ORDRE and FLY are never summed - is unchanged.

Suites under real /bin/bash 3.2: board 325/325 (was 314), coord 242/242,
route 69/69, orders 110/110, guard 54/54. npm test 11/11.

No version bump, no tag, no catalog ref - as ordered.

Order: 20260829T045435Z-276822386-from-.claude

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-08-29 07:29:13 +02:00
commit ee5a86a40b
4 changed files with 238 additions and 20 deletions

View file

@ -411,7 +411,7 @@ marketplace plugin. Three components, one boundary:
- **Board (`scripts/board.sh`):** cross-repo attention board. Reads STATE.md
next-step blocks + board lines, `git status`, and mailbox pending counts, and
prints one line per repo. Read-only by construction: it writes to no repo, no
STATE.md and no mailbox. Pinned by `board-selftest.sh` (314 checks).
STATE.md and no mailbox. Pinned by `board-selftest.sh` (325 checks).
**It lives here because the mailbox is one of its three inputs, and it carries
the same axis distinction the mailbox does.** A pending count means *others
@ -990,6 +990,49 @@ marketplace plugin. Three components, one boundary:
count. Selftest section 24 pins the denial as a check on the legend TEXT, so
the wording is engine behavior and not prose.
**Order 20260829T045435Z-276822386 (2026-08-29): both columns were pure
COUNTS, so ORDRE 2 read identically whether both orders arrived yesterday or
both had sat for ten days.** They now render `N:Md` - the count and the age of
the oldest order. The defect was never that orders sit there; that is a
prioritisation question owned by humans. It was that NO SURFACE SHOWED THE AGE
ACROSS REPOS: `coord-order-inbox.sh` does show one ("1d old"), but only inside
the one repo at SessionStart, so a repo nobody opens shows nobody anything.
Measured across the live mailbox that day with `find ~/.claude/coord -path
'*/orders/*.md' -maxdepth 3 -type f`: 30 pending orders over 22 repos, 5 of
them ten days old. This is not a new mechanism in the file - ALDER (STATE.md
mtime) and SISTE (last commit) already read a clock the same way; it is a
third application of a measurement `board.sh` was already making.
**The age is the OLDEST order, never the newest and never a mean.** A repo
holding one fresh order and one ten-day-old order has a ten-day-old problem,
and the newest reading is precisely what would hide that case. Mutation-
verified: flipping `-lt` to `-gt` in `oldest_order_age()` turns exactly the
two oldest-specific checks red while every control stays green. FLY carries
the identical reading, and there it matters at least as much: nothing
un-claims an order when the session that took it dies, so a claim with no age
is the 117-hour claim above with its only counter-evidence removed.
**An empty queue prints a BARE 0, and an unreadable mtime prints `?`.** "No
orders" and "an order that arrived today" are two different facts - the same
reason FLY exists beside ORDRE in the first place - so `0` never grows a
`:0d`. `?` is reported for the WHOLE reading rather than skipping the file,
because an unmeasured file could be the oldest one, which makes "oldest" a
claim the function is no longer entitled to make; it is the same token
`coord-count.sh` and DRT already use for a measurement that failed.
**The age is DISPLAY only - it is deliberately NOT in the sort.** Putting it
in the ranking would silently reorder a parser living in another repo, which
is the standing rule two sections up, and the order made it an explicit
condition: a new sort axis would have to be stated in the commit message and
in `--help`. It was not needed, so it was not taken. `--plan`'s `fly=` key and
every other emitted `key=value` block are likewise untouched: the requirement
is that a HUMAN reading the board can see an order is old without opening the
repo, and the table is where that is read. Selftest section 28 builds a
throwaway coord tree with `touch -t` mtimes and asserts its OWN ground truth
(the stale fixture really is 10 days old) before anything depends on it, so a
broken `touch -t` fails there rather than turning the section into a test of
nothing.
**There is deliberately NO process inspection, and the selftest asserts it
structurally** (no live `pgrep`/`pkill`/`lsof` in `board.sh`, with a
known-positive control proving the grep can find a planted call). Four
@ -1079,7 +1122,7 @@ obligations in another repo.
builtins only in hook and tests.
- TDD: no behavior change without a failing selftest check first.
`bash scripts/coord-selftest.sh` must exit 0 (242/242),
`bash scripts/board-selftest.sh` must exit 0 (314/314),
`bash scripts/board-selftest.sh` must exit 0 (325/325),
`bash scripts/route-selftest.sh` must exit 0 (69/69),
`bash scripts/orders-selftest.sh` must exit 0 (110/110) and
`bash scripts/state-line-guard-selftest.sh` must exit 0 (54/54).