fix(board): a missing coord-count.sh sibling warns instead of lying

Review finding 1 (docs/2026-08-14-confident-zero-review.md), tier 1 #2,
prioritized by .claude 2026-08-14T21:24:16Z coord message.

board.sh:381,395,409,516-517 gated four coord-count.sh invocations on
`[ -f "$SELFDIR/coord-count.sh" ]` and silently continued with empty
lookups when it failed - the 0.12.1 deployed-copy incident shape, a real
deployment state, not hypothetical. Reproduced exactly as the review
measured it (copy board.sh + route.sh to a scratch dir without
coord-count.sh, fixture mailbox with one reply-owing message): --brief
claimed "Ingen repo skylder noen et svar i dag." and then actively
mislabeled the reply-owing repo as "bare FYI-post" - a false statement,
not merely an absent one, since inbox>0/owed==0 looks identical whether
owed is genuinely 0 or simply uncomputed. --inbox-plan silently rendered
0 blocks instead of 1.

Fixed by computing HAVE_COUNT once and checking it everywhere a missing
sibling would otherwise read as "checked, found nothing": brief() no
longer enters the zero-debt/FYI-mislabel branch when the sibling is
missing, printing a warning instead; brief_orphans() and
brief_deadletters() warn instead of silently returning nothing (the
review's "dead-letter and orphan cross-checks vanish silently too");
plan() and inbox_plan() emit a key=value `advarsel=` line (not a '#'
comment - the driver consumer drops comment lines by rule, same
reasoning as the existing fokus= disclosure). plan()'s `keep` membership
logic is deliberately untouched: changing which repos appear in --plan
under this condition is a policy change to a format with a second
consumer in another repo that no test here can hold stable, and is a
proposal for the operator, not this fix.

Verified red before fixing: the reviewer's exact reproduction against
`git show HEAD:scripts/board.sh` (pre-fix) confirmed the mislabel and
the silent 0-block --inbox-plan, so the new board-selftest.sh section 17
fixture is red for the right reason, not by accident. Smoke-tested
against the real ~/repos tree (coord-count.sh present, HAVE_COUNT=1):
unchanged output, no warning.

All four selftest suites green: coord 200/200, board 183/183 (5 new
checks in section 17), route 69/69, guard 21/21.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F1mzsaUmjqFHArbArG7EpF
This commit is contained in:
Kjell Tore Guttormsen 2026-08-14 23:53:31 +02:00
commit 87194fe574
2 changed files with 104 additions and 6 deletions

View file

@ -377,8 +377,16 @@ trap '/bin/rm -f "$RECORDS" "$UNBLOCKS" "$OWED" "$ALLMAIL" "$DEADLETTERS" 2>/dev
# mailbox beyond what RECORDS already read, and paying an extra coord-count.sh
# subprocess on every invocation would tax that path for a lookup it never
# uses.
# HAVE_COUNT, computed once: a missing sibling (the 0.12.1 deployed-copy
# incident shape - review finding 1, 2026-08-14) must never read as "coord-
# count.sh ran and found nothing". Every site below that would otherwise
# treat an empty $OWED/$DEADLETTERS/$ALLMAIL as a confident zero checks this
# flag first and warns instead - see brief(), plan(), inbox_plan().
HAVE_COUNT=1
[ -f "$SELFDIR/coord-count.sh" ] || HAVE_COUNT=0
: > "$OWED"
if { [ "$BRIEF" -eq 1 ] || [ "$PLAN" -eq 1 ]; } && [ -f "$SELFDIR/coord-count.sh" ]; then
if { [ "$BRIEF" -eq 1 ] || [ "$PLAN" -eq 1 ]; } && [ "$HAVE_COUNT" -eq 1 ]; then
ow_tab="$(printf '\t')"
bash "$SELFDIR/coord-count.sh" 2>/dev/null \
| awk -F"$ow_tab" -v OFS='|' '{print $1, $3}' > "$OWED"
@ -392,7 +400,7 @@ fi
# 3-day threshold reach $DEADLETTERS, so brief_deadletters() below never has to
# re-parse the raw column or re-apply the threshold itself.
: > "$DEADLETTERS"
if [ "$BRIEF" -eq 1 ] && [ -f "$SELFDIR/coord-count.sh" ]; then
if [ "$BRIEF" -eq 1 ] && [ "$HAVE_COUNT" -eq 1 ]; then
dl_tab="$(printf '\t')"
bash "$SELFDIR/coord-count.sh" 2>/dev/null \
| awk -F"$dl_tab" -v OFS='|' '$4 != "-" && $4+0 >= 3 {print $1, $4}' > "$DEADLETTERS"
@ -406,7 +414,7 @@ fi
# gated: an extra coord-count.sh subprocess on every table/plain invocation
# would tax a path that never reads it.
: > "$ALLMAIL"
if [ "$INBOX_PLAN" -eq 1 ] && [ -f "$SELFDIR/coord-count.sh" ]; then
if [ "$INBOX_PLAN" -eq 1 ] && [ "$HAVE_COUNT" -eq 1 ]; then
am_tab="$(printf '\t')"
bash "$SELFDIR/coord-count.sh" 2>/dev/null \
| awk -F"$am_tab" -v OFS='|' '{print $1, $2, $3}' > "$ALLMAIL"
@ -513,10 +521,13 @@ brief_cmd() {
# coord-count.sh is the right source and the only safe one: it counts without
# delivering, where coord-inbox.sh would mark broadcasts seen just by looking.
brief_orphans() {
bo_count="$SELFDIR/coord-count.sh"
[ -f "$bo_count" ] || return 0
if [ "$HAVE_COUNT" -ne 1 ]; then
echo ""
echo "UTENFOR REPO-SKANNEN: kan ikke sjekke - coord-count.sh mangler."
return 0
fi
bo_tab="$(printf '\t')"
bo_out="$(bash "$bo_count" 2>/dev/null \
bo_out="$(bash "$SELFDIR/coord-count.sh" 2>/dev/null \
| awk -F"$bo_tab" '$2+0>0 {print $1"'"$bo_tab"'"$2}' \
| while IFS="$bo_tab" read -r bo_name bo_n; do
[ -n "$bo_name" ] || continue
@ -539,6 +550,11 @@ brief_orphans() {
# claimed-repo in board-selftest.sh section 16 both do). The action half
# (report to sender / retract) is unapproved design and is not built here.
brief_deadletters() {
if [ "$HAVE_COUNT" -ne 1 ]; then
echo ""
echo "ALDRI LEST: kan ikke sjekke - coord-count.sh mangler."
return 0
fi
[ -s "$DEADLETTERS" ] || return 0
echo ""
echo "ALDRI LEST - postkasser uten .origin med post eldre enn 3 dogn:"
@ -568,6 +584,19 @@ brief() {
echo "Kilder: STATE.md (NESTE + route-linje), git, coord-innboks. 0 modellkall."
echo ""
# A missing coord-count.sh sibling (review finding 1, 2026-08-14 - the
# 0.12.1 deployed-copy incident shape) must never be read as "checked, zero
# debt": $OWED is empty for the same reason it would be on a genuinely
# debt-free day, and continuing into the branch below actively mislabeled a
# reply-owing repo as FYI-only (inbox>0, owed==0 looks identical either way).
if [ "$HAVE_COUNT" -ne 1 ]; then
echo "ADVARSEL: coord-count.sh mangler - kan ikke avgjore hvem som skylder svar."
echo "Gjeldstall er IKKE null, bare ikke beregnet. Se ${SELFDIR}/coord-count.sh."
brief_orphans
brief_deadletters
return 0
fi
if [ "${n_owe:-0}" -eq 0 ]; then
# Only the debt claim, never "no repo has unhandled inbox": n_owe counts
# OWED repos since 0.22.0, so this branch can fire while a repo still
@ -909,6 +938,13 @@ plan() {
# consumer drops every comment line by rule - a disclosure written as a
# comment would reach the operator on the terminal path and vanish on the
# driver path, which is the one case where the cutoff is applied unseen.
# Same rule applies to the coord-count.sh warning below (review finding 1,
# 2026-08-14): a missing sibling makes `owed` 0 for every repo above, which
# can silently drop a done/deferred debtor from group 2 - `keep` itself is
# intentionally left unchanged (a policy change to a format the operator
# decided has a second consumer elsewhere), but the driver must be able to
# see that the omission happened rather than read a shorter list as complete.
[ "$HAVE_COUNT" -eq 1 ] || printf 'advarsel=coord-count.sh mangler - gjeldsvekting (gruppe 2, inbox:N) er ikke beregnet\n'
if [ -n "$FOCUS" ]; then
fp_state="$(awk -F'|' '{print $10}' "$RECORDS" | while read -r fp_sd; do
[ -n "$fp_sd" ] && [ -f "$fp_sd/STATE.md" ] && echo x
@ -1023,6 +1059,13 @@ inbox_plan() {
echo "# pending=meldinger totalt, owed=derav skylder svar (resten er FYI)."
echo ""
# Review finding 1 (2026-08-14): a missing coord-count.sh sibling leaves
# $ALLMAIL empty, and the population below is entirely $ALLMAIL rows - the
# measured effect was 1 block silently becoming 0, not an empty population
# rendered as such. key=value, not '#', for the same reason as plan()'s
# advarsel= line: the driver consumer drops comment lines by rule.
[ "$HAVE_COUNT" -eq 1 ] || printf 'advarsel=coord-count.sh mangler - populasjonen er ikke beregnet, ikke tom\n'
ipn=0
while IFS='|' read -r owed pend name cls dir status cost neste; do
[ -n "$name" ] || continue