Skip to content

basou: Measure the workspace on the spot when the board has no record - #334

Merged
takashi-matsuyama merged 2 commits into
mainfrom
board/view-live
Oct 8, 2026
Merged

takashi-matsuyama merged 2 commits into
mainfrom
board/view-live

Conversation

@takashi-matsuyama

@takashi-matsuyama takashi-matsuyama commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Summary

basou view's board page (/board) now measures the workspace on the spot when there is no record to draw, so every workspace gets the measurable half of a board with no declaration, no record and no agent.

  • When: with no record yet, or no board/board.yaml read (the manifest does not declare the workspace's own repo private), /board measures and draws instead of only saying why there is nothing. A page that draws a record links to the same measurement (/board?live=1), and a button measures again.
  • What: the built-in sections of basou board measure that need nothing from a declaration, measured as that command measures them:
    • the period and effort (the same tiles, charts and weekly table as a record), from the day of the first session in this host's time zone;
    • each repository the manifest declares (the workspace's own repo when it declares none or the manifest cannot be read, which is said): HEAD, branch, last commit, commits, uncommitted paths, commits behind origin/main as of the last fetch;
    • the decisions and open tracks, the sessions and how many basou verify does not find verified, the review gaps, the newest session and the sessions not yet imported (the dry run basou orient runs);
    • the components the markers find, held against no registry.
  • What it is not: nothing is judged (no reach matrix, lanes or operator's turns), nothing is written, no digest or diff. Because it writes nothing it needs no private repo; like the board, it is not served in portfolio mode. The heading says it was measured now and is not a record, and the footnotes say how to get the judged board.
  • Routes: GET /api/board/live and /api/ws/<key>/board/live, checked before the record route (which would take live for an id). Like every page of basou view, a local UI and not an API. Requests that arrive while a measurement runs share it.
  • @basou/core (Internal): measureBoardLive and boardLivePage; the effort section's start may be left out (a declared start is measured as before); the effort layout of the page is shared between records and live measurements (effortOf).

No new flag, no change to compatibility.md or the README.

Why

The board needs a declaration file and a judging workflow before it shows anything, which keeps it from spreading to other workspaces. The part a board measures without judgement (period and effort, repositories, trail, components) needs none of that, so a workspace now sees it as soon as it runs basou view. Starting the effort at the first session, rather than the first commit, keeps an adopted repository's long history from filling the charts with empty months.

Verification

  • CI steps run locally on the final commit, 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 (core 2630, sdk 65, cli 1474): all 0. pnpm audit --prod: no known vulnerabilities. The board and view tests pass under TZ=UTC, America/New_York and Asia/Tokyo.

  • New tests: the effort's start with none declared (first session's day in the section's zone, today with none, today and a not_found entry when the sessions cannot be read, a session dated after today, a host zone with no name); measureBoardLive and measureLiveBoard writing nothing (each file's size, modification time and content, .git and .basou/ included, with the real dry run of an import too); declared repos, none declared, an unreadable manifest; the routes (single and portfolio mode, scoped and flat, live not taken for a record, the anchor's language); request sharing; dry runs started at once; the page's script run with a fake fetch for each way it loads; and the drawing (values not measured told from nulls that mean so, counts by status and verdict, markup in a track title shown as text, the no-board note, links).

  • Mutations: 34 applied one at a time to the final code (effort start and its cap, live measurement and layout, writing, routes, mode gating, request sharing, the capture queue, manifest fallback, page loading, drawing). All 34 are caught.

  • In a browser, with the built CLI:

    • A real workspace with records and three repositories, started from its workspace view: the record page links to the live page; the live page draws every section with no console error, and the weekly effort figures match the record's. Checked at 375px wide (no horizontal overflow) and in the dark scheme. "Measure again" shows the measuring status and redraws with a later time.
    • A fresh workspace with no board: /board measures on the spot in English and explains where records are read from.
  • Review: one round of convergent review (review only), with the decided scope given as fixed. The reviewer ran a server against scratch workspaces, compared every file before and after (size, mtime, sha256), checked that declared boards measure the same as before in eight cases, and drew a track title holding <img onerror> (shown as text). Eight findings, all fixed in the second commit:

    • The live board's dry run of an import overlapped the portfolio's (and refreshes); captures now run one at a time in the process, which also fixes overlaps that existed before (see Fixed in the changelog).
    • "Writes nothing" compared only the list of paths.
    • No test ran the page's loading path.
    • Values not measured were drawn as -, like nulls that mean something.
    • The start with no named time zone was undocumented.
    • Counts by basou verify status and by review-gaps verdict were not drawn.
    • ?live=1 linked back to records in a workspace with none.
    • The cap of the start at today was untested.

    Not taken up, as design questions rather than defects: whether the heading uses the workspace name or the repository's directory name, a cap on the number of days, disabling the button while measuring, and saying in the footnotes why there is no record.

Checklist

  • Branch is rebased on main.
  • One commit per topic.
  • 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 (no new error messages).
  • The capture fix is listed under Fixed in CHANGELOG.md.

🤖 Generated with Claude Code

takashi-matsuyama and others added 2 commits October 8, 2026 22:10
basou view's board page draws a record of board/board.yaml. With no record
yet, or no board.yaml read (the manifest does not declare the workspace's
own repo private), it said why and drew nothing. It now measures what
basou board measure measures without a declaration and draws that: the
period and effort, the repositories, the decisions and open tracks, the
sessions and how many basou verify does not find verified, the review
gaps, the newest session and the sessions not yet imported, and the
components the markers find. A page that draws a record links to the same
measurement (/board?live=1), and a button measures again.

Nothing on it is judged and nothing is written, so it needs no private
repo, and it is not served in portfolio mode. The effort starts on the day
of the first session in this host's time zone, so an adopted repository's
older history does not fill the charts with empty months.

@basou/core gains measureBoardLive and boardLivePage, and the effort
section's start may be left out; a declared start is measured as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Captures of an import's console now run one at a time in the process,
  whoever starts them: the board page's dry run overlapped the portfolio's
  (and two portfolio requests, or one and a refresh, already could), and
  one of them came out wrong.
- The page tells a value it could not measure from a null that means so
  (a detached HEAD, no commit yet, no origin/main), says when the sessions
  not imported could not be counted, and draws the sessions by basou verify
  status and the units of work by review-gaps verdict.
- With ?live=1 it leads back to the records only when there are some.
- The effort's start with no named time zone is documented: today in UTC,
  only a label, as nothing is measured then.
- Tests: "writes nothing" compares each file's size, modification time and
  content, with the real dry run of an import too; dry runs started at once
  count the same and leave the console as they found it; the page's script
  runs with a fake fetch for each way it loads; a session dated after today
  does not move the start.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@takashi-matsuyama
takashi-matsuyama merged commit 14e7c46 into main Oct 8, 2026
8 checks passed
@takashi-matsuyama
takashi-matsuyama deleted the board/view-live branch October 8, 2026 14:10
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