feat(board): add --inbox-plan, a fourth rendering independent of --plan's admission
morning-driver's own regression (0.22.0 narrowed --plan's admission gate, and morning --innboks derives its population from --plan, so 21 mailboxes with unhandled post produced only 3 openable tabs): --plan answers "which repos deserve a tab today" (admission, ranking, a cap), --inbox-plan answers "which repos have unhandled post" (population, no judgement, no cap) - a superset of --plan's candidates, not a complement. One block per name with pending>0 in the mailbox, classified against board.sh's own RECORDS scan (no new discovery logic): class=repo (STATE.md present), no-state (scanned repo, no STATE.md), orphan-mailbox (no matching directory at all). pending=/owed= surface coord-count.sh's two counts directly. TDD-first: board-selftest.sh section 15 (6 fixtures, isolated root+mailbox) written and confirmed red before implementation. Accepted work order: morning-driver 20260814T175317Z, corrected 20260814T180854Z. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014mKC7v8gytdsota36tL7oP
This commit is contained in:
parent
bf11cbf89d
commit
09fd4b74fa
2 changed files with 303 additions and 5 deletions
|
|
@ -1286,6 +1286,185 @@ check "zero-debt briefing still states the true claim: nobody owes a reply" $?
|
|||
|
||||
/bin/rm -rf "$NODEBT_ROOT" "$NODEBT_COORD" 2>/dev/null
|
||||
|
||||
# --- 15. Inbox-plan rendering (--inbox-plan) --------------------------------
|
||||
# A FOURTH rendering, ordered by morning-driver (20260814T175317Z, corrected
|
||||
# 20260814T180854Z): --plan answers "which repos deserve a tab today"
|
||||
# (admission, ranking, a cap); --innboks (in the driver) answers "which repos
|
||||
# have unhandled post" (population, no judgement) - and deriving the second
|
||||
# from the first was always a shortcut, since --plan's admission gate can and
|
||||
# does exclude repos that still hold real, unhandled mail (done/deferred with
|
||||
# FYI-only mail, for instance). --inbox-plan is the population question,
|
||||
# answered directly: one block per NAME with pending>0 in the mailbox,
|
||||
# independent of --plan's admission gate entirely - admitted or not.
|
||||
#
|
||||
# Isolated root+mailbox, not the shared fixture tree: this section needs a
|
||||
# repo with pending mail that --plan would EXCLUDE (done + FYI-only), a repo
|
||||
# with NO STATE.md at all that still has mail, and a mailbox with no matching
|
||||
# repo directory anywhere in the scan - three distinct "why can't I open this"
|
||||
# reasons the work order says must never collapse into one undifferentiated
|
||||
# "kan ikke aapnes".
|
||||
IP_ROOT="$(mktemp -d)"
|
||||
IP_COORD="$(mktemp -d)"
|
||||
|
||||
# ip-repo-done-fyi: real repo, STATE.md + route line present, status=done with
|
||||
# 2 pending messages that are BOTH FYI (reply-expected: no). --plan excludes
|
||||
# this repo entirely (owed=0, status=done) - it is exactly one of the "7 ekte
|
||||
# repo" the work order measured as invisible. class=repo, pending=2, owed=0.
|
||||
mkrepo "$IP_ROOT/ip-repo-done-fyi"
|
||||
{
|
||||
echo "# STATE - ip-repo-done-fyi"
|
||||
printf '## %s NESTE %s START HER\n' "$HAND" "$EMDASH"
|
||||
echo "<!-- board: status=done; blocked-on=-; next-cost=Sonnet 5/high -->"
|
||||
echo "<!-- route: path=known; verification=strong; reversibility=cheap; scope=local; rationale=x -->"
|
||||
echo "Ferdig, men to FYI-varsler ligger fortsatt i innboksen."
|
||||
} > "$IP_ROOT/ip-repo-done-fyi/STATE.md"
|
||||
mkdir -p "$IP_COORD/ip-repo-done-fyi/inbox"
|
||||
for n in 1 2; do
|
||||
{
|
||||
echo "---"
|
||||
echo "from: w"
|
||||
echo "to: ip-repo-done-fyi"
|
||||
echo "reply-expected: no"
|
||||
echo "---"
|
||||
echo "fyi only"
|
||||
} > "$IP_COORD/ip-repo-done-fyi/inbox/2026-msg$n-from-w.md"
|
||||
done
|
||||
|
||||
# ip-repo-instate-owes: already admitted by --plan (in-progress + owed). Must
|
||||
# STILL appear in --inbox-plan: the mode is independent of admission, not a
|
||||
# complement of it - a superset, not "only what --plan dropped".
|
||||
mkrepo "$IP_ROOT/ip-repo-instate-owes"
|
||||
{
|
||||
echo "# STATE - ip-repo-instate-owes"
|
||||
printf '## %s NESTE %s START HER\n' "$HAND" "$EMDASH"
|
||||
echo "<!-- board: status=in-progress; blocked-on=-; next-cost=Sonnet 5/high -->"
|
||||
echo "<!-- route: path=known; verification=strong; reversibility=cheap; scope=local; rationale=x -->"
|
||||
echo "Skylder ett svar."
|
||||
} > "$IP_ROOT/ip-repo-instate-owes/STATE.md"
|
||||
mkdir -p "$IP_COORD/ip-repo-instate-owes/inbox"
|
||||
echo "msg" > "$IP_COORD/ip-repo-instate-owes/inbox/2026-msg1-from-w.md"
|
||||
|
||||
# ip-repo-no-state: a real, scanned git repo (dir + .git) with NO STATE.md at
|
||||
# all, holding one unhandled (owed-by-default) message. This is the
|
||||
# content-sadhguru case: a repo the scan finds but that has no plan file, so
|
||||
# no NESTE and no route line can ever exist for it - class=no-state.
|
||||
mkrepo "$IP_ROOT/ip-repo-no-state"
|
||||
mkdir -p "$IP_COORD/ip-repo-no-state/inbox"
|
||||
echo "msg" > "$IP_COORD/ip-repo-no-state/inbox/2026-msg1-from-w.md"
|
||||
|
||||
# ip-repo-clean: real repo, real STATE.md, but NO pending mail at all. Proves
|
||||
# the population is exactly "has pending mail" - nothing else earns a block.
|
||||
mkrepo "$IP_ROOT/ip-repo-clean"
|
||||
{
|
||||
echo "# STATE - ip-repo-clean"
|
||||
printf '## %s NESTE %s START HER\n' "$HAND" "$EMDASH"
|
||||
echo "<!-- board: status=planned; blocked-on=-; next-cost=Sonnet 5/high -->"
|
||||
echo "Ingenting i innboksen."
|
||||
} > "$IP_ROOT/ip-repo-clean/STATE.md"
|
||||
|
||||
# ip-orphan: a mailbox with pending mail but NO matching repo directory
|
||||
# anywhere under the scanned roots (the ktg-plugin-marketplace / svv /
|
||||
# llm-ingestion-guard case: "ingen katalog", never opened as a tab).
|
||||
mkdir -p "$IP_COORD/ip-orphan/inbox"
|
||||
echo "msg" > "$IP_COORD/ip-orphan/inbox/2026-msg1-from-w.md"
|
||||
|
||||
IPLAN="$(CLAUDE_COORD_DIR="$IP_COORD" "$BOARD" --roots "$IP_ROOT" --inbox-plan 2>/dev/null)"; rc=$?
|
||||
check "--inbox-plan exits 0" "$rc"
|
||||
|
||||
printf '%s' "$IPLAN" | grep -q '^# INBOX-PLAN '
|
||||
check "inbox-plan carries a header naming what it is" $?
|
||||
|
||||
# The class the work order asks to be distinguished, never collapsed.
|
||||
printf '%s\n' "$IPLAN" | grep -A6 '^repo=ip-repo-done-fyi$' | grep -q '^class=repo$'
|
||||
check "a real repo with STATE.md is class=repo" $?
|
||||
printf '%s\n' "$IPLAN" | grep -A6 '^repo=ip-repo-no-state$' | grep -q '^class=no-state$'
|
||||
check "a scanned repo with no STATE.md is class=no-state" $?
|
||||
printf '%s\n' "$IPLAN" | grep -A6 '^repo=ip-orphan$' | grep -q '^class=orphan-mailbox$'
|
||||
check "a mailbox with no matching repo directory is class=orphan-mailbox" $?
|
||||
|
||||
# Independence from --plan's admission gate: a done+FYI-only repo --plan would
|
||||
# never seat still gets a block here.
|
||||
IPLAN_PLAN="$(CLAUDE_COORD_DIR="$IP_COORD" "$BOARD" --roots "$IP_ROOT" --plan 2>/dev/null)"
|
||||
printf '%s' "$IPLAN_PLAN" | grep -q '^repo=ip-repo-done-fyi$'; [ $? -ne 0 ]
|
||||
check "fixture check: --plan itself excludes the done+FYI-only repo" $?
|
||||
printf '%s' "$IPLAN" | grep -q '^repo=ip-repo-done-fyi$'
|
||||
check "--inbox-plan includes a repo --plan's admission gate would exclude" $?
|
||||
|
||||
# Superset, not a complement: an already-admitted repo still gets a block.
|
||||
printf '%s' "$IPLAN" | grep -q '^repo=ip-repo-instate-owes$'
|
||||
check "--inbox-plan also includes a repo --plan already admits" $?
|
||||
|
||||
# A repo with zero pending mail earns no block at all.
|
||||
printf '%s' "$IPLAN" | grep -q '^repo=ip-repo-clean$'; [ $? -ne 0 ]
|
||||
check "--inbox-plan excludes a repo with no pending mail" $?
|
||||
|
||||
# Owed vs FYI (ask #2 of the work order): coord-count's debt field, surfaced
|
||||
# directly rather than re-derived.
|
||||
printf '%s\n' "$IPLAN" | grep -A6 '^repo=ip-repo-done-fyi$' | grep -q '^pending=2$'
|
||||
check "ip-repo-done-fyi reports 2 pending messages" $?
|
||||
printf '%s\n' "$IPLAN" | grep -A6 '^repo=ip-repo-done-fyi$' | grep -q '^owed=0$'
|
||||
check "ip-repo-done-fyi reports 0 owed (both messages are FYI)" $?
|
||||
printf '%s\n' "$IPLAN" | grep -A6 '^repo=ip-repo-no-state$' | grep -q '^pending=1$'
|
||||
check "ip-repo-no-state reports 1 pending message" $?
|
||||
printf '%s\n' "$IPLAN" | grep -A6 '^repo=ip-repo-no-state$' | grep -q '^owed=1$'
|
||||
check "ip-repo-no-state reports 1 owed (no reply-expected: no declared)" $?
|
||||
|
||||
# class=repo still derives the exact startup command from the repo's own
|
||||
# route line - same single copy of the rubric every other rendering uses.
|
||||
printf '%s\n' "$IPLAN" | grep -A8 '^repo=ip-repo-done-fyi$' \
|
||||
| grep -q '^command=claude --model sonnet --effort high --advisor opus$'
|
||||
check "class=repo block derives its command from the repo's own route line" $?
|
||||
|
||||
# class=no-state and class=orphan-mailbox can never fabricate a command - ask
|
||||
# #1 requires an accurate reason, not an undifferentiated "kan ikke aapnes".
|
||||
printf '%s\n' "$IPLAN" | grep -A6 '^repo=ip-repo-no-state$' | grep -q '^command=$'; [ $? -ne 0 ]
|
||||
check "class=no-state never emits an empty command= line" $?
|
||||
printf '%s\n' "$IPLAN" | grep -A8 '^repo=ip-repo-no-state$' | grep -q '^command_missing=.*STATE.md'
|
||||
check "class=no-state names the missing STATE.md as the reason, not a guess" $?
|
||||
printf '%s\n' "$IPLAN" | grep -A8 '^repo=ip-orphan$' | grep -q '^command_missing=.*katalog'
|
||||
check "class=orphan-mailbox names the missing directory as the reason" $?
|
||||
printf '%s\n' "$IPLAN" | grep -A6 '^repo=ip-orphan$' | grep -q '^dir=-$'
|
||||
check "class=orphan-mailbox has no directory to cd into" $?
|
||||
|
||||
# Every block is complete: a driver reading a partial block has no safe
|
||||
# default. Same invariant section 10 pins for --plan.
|
||||
n_ip_tab="$(printf '%s\n' "$IPLAN" | grep -c '^tab=')"
|
||||
n_ip_rep="$(printf '%s\n' "$IPLAN" | grep -c '^repo=')"
|
||||
n_ip_dir="$(printf '%s\n' "$IPLAN" | grep -c '^dir=')"
|
||||
n_ip_cls="$(printf '%s\n' "$IPLAN" | grep -c '^class=')"
|
||||
n_ip_pnd="$(printf '%s\n' "$IPLAN" | grep -c '^pending=')"
|
||||
n_ip_owe="$(printf '%s\n' "$IPLAN" | grep -c '^owed=')"
|
||||
n_ip_sta="$(printf '%s\n' "$IPLAN" | grep -c '^status=')"
|
||||
n_ip_nes="$(printf '%s\n' "$IPLAN" | grep -c '^neste=')"
|
||||
n_ip_cmd="$(printf '%s\n' "$IPLAN" | grep -c '^command=')"
|
||||
n_ip_cms="$(printf '%s\n' "$IPLAN" | grep -c '^command_missing=')"
|
||||
[ "$n_ip_tab" -gt 0 ] && [ "$n_ip_rep" -eq "$n_ip_tab" ] && [ "$n_ip_dir" -eq "$n_ip_tab" ] \
|
||||
&& [ "$n_ip_cls" -eq "$n_ip_tab" ] && [ "$n_ip_pnd" -eq "$n_ip_tab" ] \
|
||||
&& [ "$n_ip_owe" -eq "$n_ip_tab" ] && [ "$n_ip_sta" -eq "$n_ip_tab" ] \
|
||||
&& [ "$n_ip_nes" -eq "$n_ip_tab" ] && [ $(( n_ip_cmd + n_ip_cms )) -eq "$n_ip_tab" ]
|
||||
check "every inbox-plan block carries every field exactly once" $?
|
||||
|
||||
# Dense, consecutive numbering - a driver opening tab 4 of 3 is a real failure.
|
||||
seq_ok=0
|
||||
printf '%s\n' "$IPLAN" | grep '^tab=' | cut -d= -f2 > "$IP_ROOT/tabs.txt"
|
||||
[ -s "$IP_ROOT/tabs.txt" ] || seq_ok=1
|
||||
i=0; while read -r t; do i=$((i+1)); [ "$t" = "$i" ] || seq_ok=1; done < "$IP_ROOT/tabs.txt"
|
||||
check "inbox-plan tab numbers are dense and consecutive" "$seq_ok"
|
||||
|
||||
# Read-only, same invariant as every other rendering.
|
||||
p5="$(snap "$IP_COORD")"
|
||||
CLAUDE_COORD_DIR="$IP_COORD" "$BOARD" --roots "$IP_ROOT" --inbox-plan >/dev/null 2>&1
|
||||
[ "$p5" = "$(snap "$IP_COORD")" ]
|
||||
check "inbox-plan writes nothing to the mailbox (reading is delivering)" $?
|
||||
|
||||
printf '%s' "$IPLAN" | iconv -f UTF-8 -t UTF-8 >/dev/null 2>&1
|
||||
check "inbox-plan output is valid UTF-8" $?
|
||||
|
||||
"$BOARD" --help 2>/dev/null | grep -q '\-\-inbox-plan'
|
||||
check "--help documents --inbox-plan" $?
|
||||
|
||||
/bin/rm -rf "$IP_ROOT" "$IP_COORD" 2>/dev/null
|
||||
|
||||
echo ""
|
||||
echo "board-selftest: $PASS passed, $FAIL failed"
|
||||
[ "$FAIL" -eq 0 ] || exit 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue