Reads stop handling what the retired verbs wrote; colour fixes; accepted enquiries say why - #611
Merged
Merged
Conversation
FORCE_COLOR in the developer's shell made Bun colour the child's stderr, and the endpoint read back carried an escape code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWZHuy7xJbVqxyLipnvwdY
`rows()` padded each cell by its string length, escape codes included, so a coloured `holding up` cell pushed the work handle out of the gate handle's column. It pads by visible width now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWZHuy7xJbVqxyLipnvwdY
…reopen it Both were on `--json` only. The `accept` help text pointed there; it points at plain `why` now. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWZHuy7xJbVqxyLipnvwdY
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWZHuy7xJbVqxyLipnvwdY
`colourWanted` moves to core-db, beside the daemon, with `stderrLine` writing one line through it. The daemon's log, the wire host's two lines, the daemon entry's usage line, the client's "replacing it" line and the CLI's refusals all go through it rather than `console.error`, which Bun colours whenever FORCE_COLOR is set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWZHuy7xJbVqxyLipnvwdY
No live write produces any of these, so the code reading them is gone: - the `closed` gate state and a gate's `closure` (`closeGate`); - the `undecided` verdict and standing, and the GRADES lookup behind them; - the `retracted` filters on reads, `retractedIn`, and the `retracting` line in `happened` (`undo`); - `revisedBy`, the implied supersession that rested on it, and the BASED_ON a review it carried (`replaceAnalysis`); - the review behind a revised analysis, a superseded finding and an invalidated artefact; - the sharpening arm of the check for a question's origin (`sharpen`); - the `ReviewRef` alias and the minted `reviewRef` codec. The `review` kind stays: `search` walks every searchable label in the schema, `Review` is one, and it refuses a label with no kind. `closed` leaves the CLI vocabulary, since no schema can say it now. The test that reads hid retracted nodes goes with the filters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWZHuy7xJbVqxyLipnvwdY
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWZHuy7xJbVqxyLipnvwdY
danbarua
enabled auto-merge (squash)
October 1, 2026 00:52
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The follow-up to #608, #609 and #610. Measured with the compiled binary (
bun run cli:build) against throwaway records, always with--db. The "before" binary was built frommainat e4250a4.1. Reads stop handling shapes only the retired verbs wrote
For each shape, I grepped every staged write in
packages/core-domain/write/*.ts(unitOfWork.node/edge).UnitOfWork.setandsetEdgehave no callers, so no live write sets any property,retractedincluded. None of the shapes below is produced by a live write:reviewkind inwhyrecordReviewReviewRefalias and the mintedreviewRefcodecoriginAlready(Decision MOTIVATES Question + SHARPENS)sharpenoriginAlreadynow reads only the noteclosedgate state (Decision CLOSES Gate)closeGateGateStatus.closure, theclosedlookups ingateStatus/gateList, theexplainGatecase,closedinGATE_STATESand in thewhydescriptionsundecidedstanding (GRADES)isUndecidedstandingsConferred, the view branch, the vocabulary wordundoretracted IS NULL/retracted !== truefilter inexplain,happened,inventory,standing,core;everGatedand the unlabelledevermatch inworkList;retractedInand theretractingline inhappenedrevisedBy(Decision MOTIVATES/SUPERSEDES Computation) and the review behind itreplaceAnalysisrevisedBy,impliedSupersession,conclusionsOf, the BASED_ON-review edge inconcluding; the Review match andbecauseonanalysisRevision; the Review lookups inwhySupported(EVALUATES, BASED_ON Review, INVALIDATED_BY)Not done: the
reviewkind.searchwalks every searchable label inSEARCHABLE_TEXT(core-db/domain.ts) and refuses a label with no kind.Reviewis one of them. With the kind removed, every search failed:Removing the kind needs one of two changes that this PR does not make: take
Reviewout of the schema's searchable annotations, or makesearchskip a label with no kind (its comment says that case should fail loudly). The kind is back, and so is ", review" in thewhydescriptions.Tests: the undecided view test and the undecided verdict case are gone; the
workStateFromtest lost its retracted-gate case;tests/events/retraction.test.tsis gone, since it checked that reads hide retracted nodes.closedleaves the CLI vocabulary becausetests/cli/vocabulary.test.tsfailed once no schema could say it (+ "closed"). The enquiry list still printsclosed, uncoloured.The same reads over two records, before and after: the throwaway record (
happened52 lines,now16 lines,why CLM_6on a replaced claim) and the rebuilt Bonsai record (now82 lines,claims51,enquiries29,work11,gates20).diffprinted nothing for any of them. The one visible change isgates --state closed:bun run bonsai:recordwith this binary:What nothing writes any more
Graph schema and migrations are unchanged. Declared: 14 node labels and 31 edge labels; written: 13 and 25.
Review.REVERIFIES,GRADES,KEEPS,SHARPENS,EVALUATES,INVALIDATED_BY.retracted(nothing callsUnitOfWork.set).ClaimProps.kindstill allows"undecided".provisioning.tsstill installs the<label>_hide_retractedRLS policy, and withretraction.test.tsgone no test exercises it.Reads of these that were outside this brief and are still in place:
reverifiedBy/REVERIFIES inwhySupportedand the "Re-checked by" view; the Computation lineage, KEEPS and the changed/restated/unpaired lists inanalysisRevision, which now always return the empty shape; and the withdrawn-verdict helper inchecks.ts.2.
labkit gateslines its columns up with colour onrows()padded by string length, escape codes included. It now pads by visible width. The test rendersrenderGateListwith colour on, strips the escape codes, and compares the result with the plain rendering. It failed before the fix:Compiled binary,
FORCE_COLOR=1 labkit gates | strip-ansi:3. The record daemon's log lines take the CLI's colour decision
colourWantedmoves topackages/core-db/colour.ts, because core-db cannot import app-cli.stderrLinesits beside it and writes one line to stderr, in red whencolourWantedsays so. The daemon'slog(), the wire host's two lines, the daemon entry's usage line, the client's "replacing it" line and the CLI's refusals all go through it. core-db has no access to--no-ansi, so the daemon decides from the environment alone. Bun coloursconsole.errorwheneverFORCE_COLORis set, even besideNO_COLOR=1:Daemon log, fresh
--dbeach, underFORCE_COLOR=3 NO_COLOR=1:tests/persistence/daemon-log-colour.test.tsruns the daemon entry underFORCE_COLOR=1(the control, which must be coloured),FORCE_COLOR=3 NO_COLOR=1andFORCE_COLOR=0.4. The
--httplauncher test clears the colour variables for its childThe child now gets
process.envwithoutFORCE_COLOR,NO_COLOR,CIandTERM, which are the variablescolourWantedreads.5.
labkit whyon an accepted enquiry prints the reason and the reopening conditionThe
accepthelp text now points atlabkit whyand no longer atlabkit --json why.tests/cli/enquiries.test.tsasserts both lines through the CLI.6. The deleted root README
infra/ci/triggers.tfno longer listsREADME.mdinignored_files.infra/ci/README.mdhad the same list in prose, and it is updated too. No other file referred to the root README; every otherREADME.mdhit is a package README or test data.Not in this PR: removing the MCP read-only mode
The coordinator also passed on a request to remove
labkit mcp --read-only, thereadOnlypaths inapp-mcp/server.tsanddocs.tswith their tests, and theMCP_CALL_WRITEswitch in the skill'smcp-call.sh. I made the change, and typecheck, the MCP tests (22 pass) andmcp-call.sh tools/list(9 tools, 4 withreadOnlyHint) all passed. The permission system then refused the commit as test removal. The change is not in this branch. It is saved as a patch outside the repo for Dan to decide on.Checks
bun test, before: 1644 pass, 2 skip, 1 fail (http.test.tsunder this shell'sFORCE_COLOR=3), 1647 tests across 221 files.bun test, after: 1647 pass, 2 skip, 0 fail, 1649 tests across 221 files. The difference: +1 gates-colour test, +3 daemon-colour tests in a new file, −1 undecided view test, −1retraction.test.ts(one test, one file).bun run check:quick: all 25 passed.origin/main(e4250a4) before pushing.🤖 Generated with Claude Code
https://claude.ai/code/session_01FWZHuy7xJbVqxyLipnvwdY