repo-mailbox/scripts
Kjell Tore Guttormsen e5e9cbe847 feat(board): rank --plan on one score, with transitive chain-root credit
blocked-on was scanned and then used for a single display string; it never
reached the ordering. A blocked chain's root could therefore rank below the
repos waiting on it - measured on the real tree, the root opened at tab 14
while the two repos it held up opened at tabs 5 and 8.

--plan now ranks on one score instead of four hard buckets, because four
groups cannot express "this repo owes one message and releases two others":

    40 x repos released transitively + 15 x inbox
    +10 in-progress / +5 planned / +2 undeclared, +3 for a Sonnet row

Chain-root credit follows blocked-on transitively to the first repo that is
not itself blocked and credits only that root. Opening a blocked repo
releases nobody - its own next step is by definition waiting. A cycle, a
blocked-on naming an unscanned repo, and a blocked repo with no target all
credit NOBODY: inventing a root there yields a plan that looks correct and
sends the operator to the wrong repo.

Debt is deliberately uncapped. A cap was proposed alongside the credit and
declined: owing a reply is the other axis from a repo's own next step, and
answering is often what unblocks a chain. The weight carries that decision -
15 per message exceeds the sum of every other bonus (13), so one message
more still outranks any combination of status and cost. At the originally
proposed 12 a tiebreak could flip the debt order, which is the cap arriving
through the back door.

blocked-on becomes a record field, inserted BEFORE neste so no existing field
index moves: neste is free prose lifted from a STATE.md and may carry a
literal '|' from a markdown table, so it stays last.

why= now names the dominant term rather than the first rule that matched, so
a block says what opening it would release instead of repeating inbox:N.

Format is otherwise unchanged for both declared consumers: tab=, repo=, dir=,
why=, status=, neste=, command=/command_missing=, paste= and the fokus_*
header all keep their names and positions.

board-selftest 118 -> 134 (chain, cycle, dangling-edge and format fixtures
written first, all failing before the change).
2026-08-02 22:38:40 +02:00
..
board-selftest.sh feat(board): rank --plan on one score, with transitive chain-root credit 2026-08-02 22:38:40 +02:00
board.sh feat(board): rank --plan on one score, with transitive chain-root credit 2026-08-02 22:38:40 +02:00
brief-nightly.sh feat(brief): render the nightly cross-repo briefing without a model 2026-08-01 22:38:46 +02:00
coord-count.sh feat(engine): let a message say it needs no answer, and count debt without losing sight of the rest 2026-07-31 15:46:14 +02:00
coord-done.sh feat(engine): make a bulk close state what Rule 7 says must be stated 2026-07-31 15:48:42 +02:00
coord-inbox.sh feat(engine): let a message say it needs no answer, and count debt without losing sight of the rest 2026-07-31 15:46:14 +02:00
coord-selftest.sh test(sweep): stop the --days 0 check from racing a one-second cutoff 2026-08-01 23:01:32 +02:00
coord-send.sh feat(engine): let a message say it needs no answer, and count debt without losing sight of the rest 2026-07-31 15:46:14 +02:00
coord-sweep.sh feat(sweep): close the aged FYI backlog without a human in the loop 2026-08-01 22:00:42 +02:00
route-selftest.sh feat(route): give the advisor a writer, on a need and per row 2026-07-31 21:39:59 +02:00
route.sh feat(route): give the advisor a writer, on a need and per row 2026-07-31 21:39:59 +02:00