Workbook v0.4.4
Joining an existing project no longer forks it, the board tells the truth about
what it could and could not do, and the measurement harness stops leaking the
processes it prices — from fourteen reviewed pull requests.
Setup and project identity
workbook setupasksoriginbefore minting a project identity. A checkout
cut before the project adopted Workbook carries no tracked configuration, and
setup used to read that as a brand-new project — splitting the repository
into two identities and wedging it behind a guard mismatch that no
working-tree cleanup could reach. Setup now adopts the configuration
committed on origin's default branch, stops rather than guessing when origin
holds task refs but no committed configuration, and treats an unreachable
origin as an error instead of minting blind;--no-syncremains the
deliberate local-only bootstrap. The guard-mismatch error names both files,
both identities, and the recovery, which is safe because the projection
validates its stored project ID and rebuilds itself (#66).
Web board
- A refused write is no longer re-based onto a head the server just refused.
When the forced refresh after a stale-write refusal cannot read the board,
the queue stops and reports instead of sending every queued intent to the
same refusal; when only the relationship context was superseded but the
board read landed, the queue re-bases and proceeds. The outage message
appears only when the read genuinely failed (#70). - A detail save whose form was left before it landed reports its outcome
instead of being swallowed. The refusal is named in the notice and staged on
the task's own form, the server's reason lands last, and a save that lands
while detached no longer yanks the reader back to the board — which used to
silently destroy a New Task draft being typed (#73). - An editor whose task was deleted elsewhere is told so. The refused-save
message used to invite a doomed retry against a version the server no longer
holds, and the failure notice linked to a task page that no longer exists;
both now state the deletion, and the edits stay in the form to copy out
(#76). - The withdrawal that corrects an open form after a refused board change no
longer claims the unedited fields show the server's version when the forced
refresh could not read the board — the form and the card are now written
against the same fact (#78). - A new task drafted in a form the reader left before the create landed is no
longer lost in silence. A refused detached create reports into the notice
with a Restore draft button that brings back every typed field — saying
plainly that staged relationships are not restored — and a create that lands
while detached leaves the reader on the route they chose (#79).
Command line and sync reporting
workbook config unset --jsonreports"command":"config unset"instead of
claiming to beconfig set, and a test holds the two verbs apart so they
cannot drift back together (#67).- An ignored ref under origin's task namespace now reaches the surfaces where
a user actually meets one:workbook setupnames the skipped refs beneath
itsSync:line, an inline mutation's report carries them, and the sync
watcher announces each newly skipped ref once on its terminal and carries
the set inworkbook sync --status, text and JSON alike. The report keeps
its restraint: removal advice is offered only for names no project's ID
format could have produced (#69).
Performance harness and targets
- The streaming history read's memory bound is pinned by a test. A rewrite
that buffers the whole corpus before delivering it — the exact regression
the streaming work exists to prevent — used to leave the suite green and
was caught only by an off-repo bench run; it now fails an allocation
ceiling asserted on settled live heap (#68). - The local-bare sync scenarios' tracking-ref reset was filed for deletion as
defensive dead code and turned out to be load-bearing: each sample's second
measured sync populates the tracking namespace, and leaving it uncleared
inflates the initial-sync measurement by about a quarter at 500 tasks. The
reset is kept, pinned by a test that fails without it, and documented with
the measurement (#71). - The measurement harness reliably reaps the processes it spawns. The helper
that priced commands used to signal their process group only on
cancellation, so a command that exited normally could leave a busy-loop
descendant spinning at a whole core for days — observed once for a week.
Every measured group is now killed after its sample is stamped, at the
shared helper and at every remainingSetpgidexec site, and the tests
reap their own helpers even if the test binary dies mid-run (#72, #77). - Read-path scenarios carry approved duration targets:
cli-listjoins
cli-showon the 200 ms local budget, fetch-first reads likecli-next
carry the 1,000 ms synchronized budget as recorded policy, and the stale
100 ms warmapi-updatefigure in the README now reads 150 ms everywhere
it speaks in the present tense (#74, #75).