fix(board): one spec for next-cost, and it is the rubric's
The board line's cost field had two specifications and one of them was this script. `--help` prescribed a versionless `sonnet/xhigh`; the global model rubric it points at spells the model `Sonnet 5 / xhigh`. A session following either was correct by its own source, so the field drifted with nobody making a mistake. Measured across a real 44-repo tree: 14 board lines carrying eight distinct strings, and not one of them the form documented here - the only spelling nobody used was ours. The help now prescribes the rubric's, which is also what most lines already carry. The parser is untouched and stays lenient: it reads to `;` or `-->` so the rubric's spacing survives, and the fixtures still vary the spelling on purpose to pin that. Read-side leniency was never the defect; it is what makes a documentation-only fix sufficient. No normalization at read, deliberately. Board lines are rewritten every session by convention, so an unambiguous spec self-heals the existing lines in about one session per active repo - mapping variants would be permanent code migrating data that migrates itself. Nothing compares the field mechanically today either: KOST is a display column and the board sorts on a numeric bucket key, so the defect was real but latent. Two checks (28 -> 30) pin the documented form, red first, because cleaning the data cannot fix a spec that regenerates the divergence every session. Validation at write has no write path to attach to: nothing in this repo emits a board line outside the fixtures. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U6EixQo6hpoRCVtiAXdnFs
This commit is contained in:
parent
f7ad4741a3
commit
305f1687b7
5 changed files with 54 additions and 5 deletions
28
CHANGELOG.md
28
CHANGELOG.md
|
|
@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- **The board line's `next-cost` field had two specs, and one of them was
|
||||
ours.** `board.sh --help` prescribed a versionless `sonnet/xhigh` while the
|
||||
global model rubric it points at spells the model `Sonnet 5 / xhigh`. Neither
|
||||
a session following the help nor one following the rubric was doing anything
|
||||
wrong, so the field drifted: measured across a real 44-repo tree, the 14
|
||||
existing board lines carried **eight** distinct strings — and not one used the
|
||||
form documented here. The help now prescribes the rubric's spelling
|
||||
(`Sonnet 5/xhigh`), which is also the one most lines already use.
|
||||
|
||||
**The parser is unchanged and stays lenient.** It still reads to `;` or
|
||||
`-->` rather than stopping at the first non-lowercase character, precisely so
|
||||
the rubric's spacing survives; the selftest fixtures still vary the spelling
|
||||
on purpose to pin that. Leniency on the read side was never the defect — it
|
||||
is what makes a documentation-only fix sufficient.
|
||||
|
||||
**No normalization was added, deliberately.** Board lines are rewritten every
|
||||
session by convention, so an unambiguous spec self-heals the existing lines
|
||||
within about one session per active repo. Mapping variants at read time would
|
||||
be permanent code migrating data that migrates itself, and nothing compares
|
||||
the field mechanically today: `KOST` is a display column, and the board sorts
|
||||
on a numeric bucket key. Two new `board-selftest.sh` checks (30 total) pin the
|
||||
documented form, because a spec that contradicts the rubric regenerates the
|
||||
divergence no matter how often the data is cleaned up.
|
||||
|
||||
## [0.9.0] - 2026-07-28
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -31,7 +31,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` (28 checks).
|
||||
STATE.md and no mailbox. Pinned by `board-selftest.sh` (30 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
|
||||
|
|
@ -78,7 +78,7 @@ halves together for exactly that reason.
|
|||
builtins only in hook and tests.
|
||||
- TDD: no behavior change without a failing selftest check first.
|
||||
`bash scripts/coord-selftest.sh` must exit 0 (136/136) and
|
||||
`bash scripts/board-selftest.sh` must exit 0 (28/28).
|
||||
`bash scripts/board-selftest.sh` must exit 0 (30/30).
|
||||
- English for all code, docs, and commit messages (public repo). Norwegian
|
||||
trigger aliases in the skill description are deliberate.
|
||||
- Conventional Commits: `type(scope): description`.
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ Note that raising the inbox's priority (Rule 7) deliberately does **not** widen
|
|||
## Development
|
||||
|
||||
bash scripts/coord-selftest.sh # 136 checks against a throwaway mailbox
|
||||
bash scripts/board-selftest.sh # 28 checks against a throwaway repo tree
|
||||
bash scripts/board-selftest.sh # 30 checks against a throwaway repo tree
|
||||
npm test # both selftests via node --test
|
||||
|
||||
TDD is the house rule: every behavior change lands with a failing selftest check first.
|
||||
|
|
|
|||
|
|
@ -213,6 +213,23 @@ mkrepo "$ROOT/repo-f"
|
|||
# Unreadable root is a no-op, not a crash.
|
||||
"$BOARD" --roots "$ROOT/does-not-exist" >/dev/null 2>&1; check "missing root is a clean no-op" $?
|
||||
|
||||
# --- 8. The documented next-cost form IS the convention --------------------
|
||||
# The cost field is free text on purpose: the parser reads to ';' or '-->' so
|
||||
# the rubric's spacing survives, and the fixtures above deliberately vary the
|
||||
# spelling to pin that leniency. But leniency on the read side means the ONLY
|
||||
# thing holding the field uniform is what --help prescribes, and --help once
|
||||
# prescribed a versionless `sonnet/xhigh` while the global rubric spelled
|
||||
# `Sonnet 5 / xhigh`. Two specs for one field: measured across the real tree,
|
||||
# not one board line used ours, and eight distinct strings were in circulation.
|
||||
# Pinned here because cleaning the DATA cannot fix that - a spec that
|
||||
# contradicts the rubric regenerates the divergence every session.
|
||||
HELP="$("$BOARD" --help 2>/dev/null)"
|
||||
printf '%s' "$HELP" | grep -q 'next-cost=Sonnet 5/xhigh'
|
||||
check "--help prescribes the canonical next-cost form" $?
|
||||
# The versionless form is what the rubric does NOT use; no example may show it.
|
||||
if printf '%s' "$HELP" | grep -qE '(sonnet|opus|fable)/(high|xhigh)'; then rc=1; else rc=0; fi
|
||||
check "--help shows no versionless model example" "$rc"
|
||||
|
||||
echo ""
|
||||
echo "board-selftest: $PASS passed, $FAIL failed"
|
||||
[ "$FAIL" -eq 0 ] || exit 1
|
||||
|
|
|
|||
|
|
@ -18,11 +18,15 @@
|
|||
#
|
||||
# Board line (optional, one per STATE.md, directly under the NESTE heading):
|
||||
#
|
||||
# <!-- board: status=in-progress; blocked-on=-; next-cost=sonnet/xhigh -->
|
||||
# <!-- board: status=in-progress; blocked-on=-; next-cost=Sonnet 5/xhigh -->
|
||||
#
|
||||
# status planned | in-progress | blocked | deferred | done
|
||||
# blocked-on <repo-name> or - (only meaningful with status=blocked)
|
||||
# next-cost <model>/<effort> from the global model rubric, e.g. opus/xhigh
|
||||
# next-cost <model>/<effort>, the model spelled EXACTLY as the global rubric
|
||||
# spells it: Sonnet 5/xhigh, Opus 5/high. The parser below accepts
|
||||
# any spelling, but this field is compared across repos by eye, so
|
||||
# one form is the whole point - and a second spelling documented
|
||||
# here is how a field with no write path drifts.
|
||||
#
|
||||
# ATTENTION AXIS, NOT A TOPIC AXIS. This status vocabulary is deliberately NOT
|
||||
# the vocabulary a cross-repo TOPIC register uses. A topic register answers
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue