Skip to content

Print the steps that judge and record a board - #337

Merged
takashi-matsuyama merged 4 commits into
mainfrom
feat/board-guide
Oct 9, 2026
Merged

takashi-matsuyama merged 4 commits into
mainfrom
feat/board-guide

Conversation

@takashi-matsuyama

Copy link
Copy Markdown
Member

Summary

Adds basou board guide (experimental): it prints, for an agent to read, the steps that judge the workspace's default board and record it, filled in with that board. A workspace no longer needs a skill of its own to keep a judged board: the agent runs the guide and follows it.

  • What it prints, for the board at board/board.yaml (read only when the manifest declares the workspace's own repo private):
    • where the board is, its last record and when, the axis's version and last review, the language the prose is written in (the anchor's), the port its page opens on (from a hash of the workspace's path, in 4400-4999, never basou view's 4319) and a working directory of its own;
    • the rules every step keeps (what not to write between measure and record, isolation both ways);
    • steps 0-10, each runnable as printed once the judging model's name is put in for $MODEL (they stop without it): take the other repos' state (HEAD and a hash of what the working tree holds beyond it), check freshness (the operator runs basou refresh), measure, review the axis when due, observe, judge, compare, write the input, record (--dry-run first), open the page, pass the commit gates, record decisions;
    • for each observation the board declares, the read-only command (npm, gh, curl and node), the value to take, its source and how to write one not made; manual ones are listed as the operator's;
    • the principles of judging, with each stage's meaning, look and notes and each lane's notes;
    • the record's input to fill in: every cell's state left empty, with the previous record's state and reason beside it under previous. record refuses both, so the template cannot be passed on unjudged;
    • the gates before a commit, and what not to do.
  • With no board declared, it says how to declare one.
  • It writes nothing and sends nothing, and has no --json: the text is for an agent and its shape is not promised.
  • It exits 1, with the reason on stderr, when the workspace's own repo is not declared private, its board.yaml does not read or is a link to nothing, or a path the commands would carry holds a control character.
  • The working directory is used only when it is the user's own and not a link, and is made readable by the user alone: it holds what the trail holds.
  • @basou/core (Internal): boardGuide, boardGuidePort, boardGuideWorkDir, shellWord, BOARD_GUIDE_PORTS, and recordIds exported.

basou board stays experimental; no change to compatibility.md or the README. docs/spec/cli-commands.md lists the subcommand.

Why

Until now each workspace that kept a judged board also carried a skill: the steps, the judging principles, a script for the observations outside basou and a config of its own. Board version 2 (#336) moved what is particular to a workspace into board.yaml; this prints the rest from basou, so the same steps reach every workspace and change with basou.

Verification

  • CI steps, run locally with exit codes: pnpm -r build, pnpm typecheck, pnpm lint (the existing 4 warnings only), pnpm lint:lang, pnpm lint:paths, pnpm test:scripts, pnpm test:coverage: all 0. The board and view tests also pass under TZ=America/New_York and Asia/Tokyo.
  • Tests run the printed commands with sh:
    • the before/after of other repos tells apart an edit to a file already changed, an untracked file and a repo with no commit, and stops on a repo it cannot read;
    • the page version reader skips generator meta tags however quoted or cased, and a version glued to a word;
    • the working directory is refused when it is a link;
    • gate (e) passes with exit 0 only when board/ alone is staged.
  • Tests check the template against record: refused as printed; taken once every cell is judged, every previous removed and every observation made.
  • Mutations: 26 on the first version, plus more on the review's fixes, applied one at a time. All are caught.
  • By hand, in a scratch workspace with the built CLI, the guide's commands were run in order:
    • measure, then the template filled in and recorded (dry run, then for real);
    • basou view started on the guide's port, and the title checked through /api/board;
    • gate (e).

Review

One round of convergent review (review only), with the decided scope given as fixed. 14 findings (3 medium, 11 low), all fixed in the fourth commit:

  • gate (d) missed a further edit to a file already changed;
  • step 0 stopped on a repo with no commit;
  • the page reader kept a generator's version when the meta tag was unquoted or uppercase;
  • the <model> placeholder passed record, and the view check was not runnable as printed;
  • the text overstated what the digest catches and when observations must match;
  • it did not say an axis review needs a summary, or how fresh decisions.md is;
  • a refused working directory failed silently;
  • gate (e) passed with exit 1;
  • control characters in paths reached the commands;
  • the language line misstated the manifest;
  • the template gave an empty error and empty lane prose;
  • the guide went to the real path rather than the root as basou resolves it.

Not taken up, as design questions:

  • a Stop hook that blocks between measure and record would move the digest;
  • step 0 stops on a declared repo that is not cloned;
  • shellWord and recordIds become exports;
  • gate (f) falls back to asking the operator for SSH host aliases.

Checklist

  • Branch is rebased on main.
  • One topic (the guide; later commits are its review's fixes).
  • Tests cover the change (happy path and failure modes).
  • pnpm lint, pnpm typecheck, and pnpm test are all green locally.
  • CHANGELOG.md ## Unreleased updated.
  • CLI stderr stays pathless (the new messages name no path).

🤖 Generated with Claude Code

takashi-matsuyama and others added 4 commits October 9, 2026 09:17
basou board guide prints, for an agent to read, how to judge the
workspace's default board and record it, filled in with that board:
where it is and its last record, the axis and its last review, the
language of the prose, the port its page opens on (from the workspace's
path) and a working directory of its own; the commands, runnable as
printed, that take the other repos' state, measure, record, open the
page and gate a commit; how to make each observation the board declares
and write it down; the principles of judging with each stage's look and
notes; and the record's input with every state empty and the previous
record's state and reason beside each cell, which record refuses as
printed. With no board declared it says how to declare one.

It writes nothing, sends nothing and has no --json: the text is not a
promised shape. This is what a per-workspace skill carried until now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The working directory the guide names may sit in a /tmp other users
share. Each block now uses it only when it is not a link and is the
user's own, and closes it to everyone else, since the files in it hold
what the trail holds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Gate (d) hashes what each other repo's working tree holds beyond HEAD
  (the diff of tracked files and the content of untracked ones), so a
  further edit to a file already changed is seen, and takes a repo with
  no commit yet instead of stopping on it.
- The page version reader drops generator meta tags however they are
  quoted or cased, and skips a version right after '_' as its text says.
- The commands carry $MODEL and the template an empty model, so neither
  runs or records as printed; the view check names the port.
- A working directory that is not the user's own says so on stderr; gate
  (e) prints whether only board/ is staged and exits 0 when it is.
- The text says when observed must match the declaration, that an
  axis_review needs a summary, how fresh decisions.md is, and what the
  digest does and does not catch. The template gives an observation no
  empty error and prose no empty lane, and names the lane ids.
- A workspace or repo path holding a control character is refused rather
  than carried into the commands; the view check prints the title as
  JSON; the workspace is gone to as basou resolves it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takashi-matsuyama
takashi-matsuyama merged commit 1e7adfb into main Oct 9, 2026
8 checks passed
@takashi-matsuyama
takashi-matsuyama deleted the feat/board-guide branch October 9, 2026 08:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant