feat(board): nested repos enter on a STATE.md, and the scan reports its nevner

Order 20260903T190201Z-238406410-from-.claude (.claude, operator decision
2026-09-03). A git repo nested under a depth-1 REPO was invisible: discovery
adds a depth-1 repo and stops, and the else-branch container scan - the only
place children are ever looked at - is unreachable for an entry that is itself
a repo. Measured before writing anything: 12 nested repos across the real tree,
exactly 1 with a STATE.md (from-ai-to-chitta/content-sadhguru), which had been
running work and reporting to nobody.

Admission is criterion (a) and nothing wider. add_nested_repos() sits beside
add_dot_repos(), never a widening of the `*` loops - the same argument ordre
20260818T124828Z made for dot repos, and the order made it again before this
repo wrote a line: routing a depth-1 repo into the container branch would admit
every vendored clone under claude-code-100x/. One level only; depth 3 is pinned
as NOT admitted. A dot-prefixed depth-1 repo gets the same nested scan, since
nothing in the criterion distinguishes it.

A nested repo now carries TWO names. The board KEY is <parent>/<child> as the
order specifies. The MAILBOX name is not that key: a mailbox is addressed by
basename(git toplevel), so $COORD/<parent>/<child>/inbox finds no directory and
INN/ORDRE/FLY would print 0 for a repo that may have mail - a failed
measurement wearing the reassuring value, in three columns at once. The record
loop carries `mbox` beside `name`; --voyage's order lookup takes
basename($vy_dir) for the same reason. Which dirs are nested is RECORDED by
discovery (NESTED_LIST), not re-derived from "is my parent a repo?", which
would prefix every depth-1 repo if a scan root were ever a checkout.

The denominator line is independent of all of that and went in regardless:
"undersoekt: N katalog(er) depth 1, M polyrepo-container(e), K nestede repo
(J med STATE.md tatt med)". The header count answers how many were found and
nothing about how many were looked at, so a criterion excluding 11 of 12 was
invisible at the surface built to show it. Real tree 2026-09-04: 43 / 5 / 12
(1 tatt med). A non-repo dot-dir counts in N and never in M - it is a
denominator, not a partition.

Its wording broke an existing check: "polyrepo container itself is not listed
as a repo" grepped the whole output for `polyrepo` and matched the footer's own
`polyrepo-container(e)` - the same class as a grep reading a comment that
EXPLAINS a pattern as an instance of it. Now anchored at column 1, which is
what it always meant.

Verified with board.sh, not from memory: from-ai-to-chitta/content-sadhguru
in-progress, Sonnet 5/high, and --plan gives it a real tab with paste=.
Mutation-verified: reverting the eight $COORD/$mbox reads turns exactly the
three mailbox checks red with the rest of the section green.

Bounded gaps, stated rather than closed: the mailbox-keyed JOINS ($OWED,
brief_orphans, --inbox-plan) still key on the board name - neither created nor
worsened here, since the repo was previously absent from RECORDS entirely; a
34-char key overflows the table's %-32s REPO column (same class as Fable
5.1/xhigh in KOST, and widening moves three cut -c89- helpers); a dot-prefixed
NESTED repo is not looked for.

board-selftest 368 -> 393. Suites: coord 257, board 393, route 73, orders 116,
guard 54 = 893. npm test 11/11.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-04 21:35:55 +02:00
commit cde185979c
10 changed files with 428 additions and 23 deletions

View file

@ -467,7 +467,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` (368 checks).
STATE.md and no mailbox. Pinned by `board-selftest.sh` (393 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
@ -902,6 +902,101 @@ marketplace plugin. Three components, one boundary:
it was exactly the unmeasured side effect the order flagged, and nothing
in `~/repos` currently needs it (`.claude` has no repo children today).
**Ordre 20260903T190201Z-238406410 (2026-09-03, operator decision the same
day): a git repo nested under a depth-1 REPO was invisible to the board, and
the admission that closes it is criterion (a) - a STATE.md - never "all
nested repos".** Discovery adds a depth-1 repo and stops; the else-branch
container scan is the only place children are ever looked at, and it is
unreachable for an entry that is itself a repo. Measured on the real tree
before anything was written: **12 nested repos across the tree, exactly 1
with a STATE.md** (`from-ai-to-chitta/content-sadhguru`, which had been
running work and reporting to nobody). The other 11 are vendored or
experimental checkouts under `claude-code-100x/`; the operator's decision is
that they stay invisible ON PURPOSE - they do not even reach the `UTEN
STATE.md` bucket, because that bucket is for repos someone opens. Verified
after the fix with `board.sh`, not from memory:
`from-ai-to-chitta/content-sadhguru in-progress ... Sonnet 5/high`, and
`--plan` gives it a real tab with a `paste=` line.
**`add_nested_repos()` beside `add_dot_repos()`, never a widening of the `*`
loops - the same argument ordre 20260818T124828Z made for dot repos, and the
order made it again before this repo wrote a line.** Routing a depth-1 repo
into the container branch would admit every nested checkout, which is exactly
what criterion (a) declines. One level only: a repo inside a nested repo is a
checkout of a checkout, and the selftest pins that depth 3 is NOT admitted. A
dot-prefixed depth-1 repo gets the same nested scan an ordinary one gets
(`add_dot_repos` takes a `d1` flag for it) - the asymmetry would otherwise be
arbitrary, and nothing in the criterion distinguishes them.
**A nested repo now has TWO names, and conflating them would have put a
fabricated 0 in three columns.** The board KEY is `<parent>/<child>` as the
order specifies - a bare basename says nothing about where the checkout lives
and would collide with a same-named depth-1 repo. The MAILBOX name is not
that key: a mailbox is addressed by `basename(git toplevel)`, which is
`coord-send.sh`'s own rule and the only name a session in that repo can hold,
so `$COORD/<parent>/<child>/inbox` finds no directory and INN/ORDRE/FLY print
0 for a repo that may have mail. That is the failed measurement wearing the
reassuring value, in three columns at once. The record loop therefore carries
`mbox` beside `name`, and `--voyage`'s order lookup takes `basename($vy_dir)`
for the same reason. Mutation-verified: reverting the eight `$COORD/$mbox`
reads to `$COORD/$name` turns exactly the three mailbox checks red with every
other check in the section green.
**Which nested dirs those are is RECORDED by discovery, not re-derived.** The
obvious re-derivation ("is my parent directory a git repo?") answers a
slightly different question and would prefix every depth-1 repo if a scan
root ever happened to be a checkout; `NESTED_LIST` cannot drift from the
criterion because discovery is what writes it.
**The denominator line is independent of all of that and went in regardless,
because the order said so and because it is ansikt 4 pointed at the board's
own reading.** `undersoekt: N katalog(er) depth 1, M polyrepo-container(e),
K nestede repo (J med STATE.md tatt med).` The header's repo count answers
"how many were found"; nothing answered "how many were looked at", so a
criterion excluding 11 of 12 nested repos was invisible at the surface built
to show it. Real tree, 2026-09-04: `43 katalog(er) depth 1, 5
polyrepo-container(e), 12 nestede repo (1 med STATE.md tatt med)`. A
non-repo dot-dir counts in N (it WAS examined) and never in M (it is
deliberately not a container - ordre 20260818's decision), so the line is a
denominator, not a partition. Selftest section 32 pins each number against a
fixture, then changes the tree and asserts the numbers move, so a hardcoded
constant cannot pass.
**The line's own wording broke an existing check, and that is the finding
worth recording.** `check "polyrepo container itself is not listed as a
repo"` grepped the WHOLE output for `polyrepo`, so the footer's
`polyrepo-container(e)` matched and the check went red on a board that was
behaving correctly - the same defect class as coord-selftest section 38's
cache grep reading a comment that EXPLAINS a pattern as an instance of it,
and as the done-guard's rule that prose saying `status=done` must not trigger
it. The check is now anchored at column 1, which is what it always meant: a
container has no ROW.
**Bounded gap, stated rather than closed (1): the mailbox-keyed JOINS still
key on the board name.** `--brief`/`--plan`'s `$OWED` join, `brief_orphans`
and `--inbox-plan` match `coord-count.sh`'s mailbox names against RECORDS
field 3, so a nested repo owing a reply would not get a debt tab and would be
listed under `UTENFOR REPO-SKANNEN`. This change neither creates nor worsens
that: before it, the repo was not in RECORDS at all, so both readings were
already exactly as wrong. Closing it means threading a mailbox key through
six awk programs, which was not ordered and is not a discovery change.
Reported to `.claude` for its own order.
**Bounded gap, stated rather than closed (2): a 34-character key overflows
the table's `%-32s` REPO column**, shifting `from-ai-to-chitta/content-sadhguru`'s
row two characters right. Same class as `Fable 5.1/xhigh` overflowing the
`%-14s` KOST column, and handled the same way: parsing is unaffected (every
rendering that a driver reads is `key=value`), widening the column moves every
fixed offset including three `cut -c89-` selftest helpers, and it is a
rendering change nobody ordered. Truncating instead would be worse - it would
destroy the very identity the compound key exists to carry, and break
copy-paste into `--dispatch --repo`.
**Bounded gap, stated rather than closed (3):** a DOT-prefixed *nested* repo
is not looked for. The `*` glob in `add_nested_repos()` has no dotglob, the
combination was neither measured nor ordered, and `add_dot_repos` exists for
the depth-1 and container cases only because those were.
**Ordre 20260820T204409Z (2026-08-20): `route_cmd_for()`'s four trait
extractions searched the WHOLE route line, and `.*trait=` is greedy, so a
rationale that names a trait won the match over the field itself.**
@ -1351,7 +1446,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 (257/257),
`bash scripts/board-selftest.sh` must exit 0 (368/368),
`bash scripts/board-selftest.sh` must exit 0 (393/393),
`bash scripts/route-selftest.sh` must exit 0 (73/73),
`bash scripts/orders-selftest.sh` must exit 0 (116/116) and
`bash scripts/state-line-guard-selftest.sh` must exit 0 (54/54).