Skip to content

Commit 06473ef

Browse files
authored
Merge pull request #3505 from schlessera/epic/1341-shared-core-ops
CONTRACT: refactor(core): land epic #1341 — shared CLI/MCP core operations
2 parents 559fe7b + bd2deca commit 06473ef

35 files changed

Lines changed: 1698 additions & 541 deletions

‎.changeset/1352-cli-flag-values.md‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
"@schlessera/brain": minor
3+
---
4+
5+
**Breaking (#1352):** core CLI commands now read flag values through one typed accessor, so a malformed value is a usage error (exit 1, message on stderr, nothing on stdout) in human and JSON modes, refused before any query runs. Valid values keep their meaning, a repeated flag still keeps its last value, and no new upper bound is introduced.
6+
7+
- **`brain search --limit`**, before: read with `parseInt`, so `10abc` searched with 10, `1.5` with 1, `abc` came back empty with an `FTS search failed: datatype mismatch` warning, and `0` or `-5` was passed on to the query. **After:** a whole number of 1 or more; `abc`, `0`, `-5`, `1.5`, `10abc` and an empty value are refused.
8+
- **`brain search --mode`**, before: an unknown mode ran neither lane and returned nothing without a warning. **After:** `fts`, `vector` or `hybrid`; anything else, including an empty value, is refused (`--mode must be one of fts, vector, hybrid, got "bogus"`).
9+
- **`brain context --max-tokens`** and **`brain briefing --limit`**, before: `parseInt`, so `abc` reached the assembler as `NaN` and briefing silently fell back to 15. **After:** a whole number of 1 or more; `abc`, `0`, `1.5`, `10abc` and an empty value are refused.
10+
- **A value flag with no value** (`brain search q --type`, `brain list --tag --status active`, `brain add "…" --tags`), before: flowed on as `true`, or for `add --tags` failed with exit 2. **After:** `--<flag> needs a value`.
11+
12+
`brain search --sort` and the date filters keep their existing usage errors.

‎.changeset/cli-commands-no-sql.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@schlessera/brain": patch
3+
---
4+
5+
Internal refactor (#1353): the `accept-mtime`, `briefing`, `doctor`, `eval` and `tags` commands no longer run SQL themselves; they call named index functions in core's library, and `brain briefing`'s Silently Modified section and `brain hygiene`'s silent-edit check now share one query. No command's output changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@schlessera/brain": patch
3+
---
4+
5+
Core's two graph readers, behind `brain graph` and the supported `./queries` graph reads, now share one internal reader with an explicit CLI profile and UI profile (#1354). Both keep their former results, defaults, caps, ordering and errors. No `--json` shape, query result or export changes.

‎docs/decisions/claude-code-runtime.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ next to it.
6666
`packages/ui-server/src/brain/client.ts:180-248`, called at
6767
`probeBrainCliVersion(config.brainPath`, `packages/ui-server/src/app.ts:451`).
6868
`brain doctor` runs `claude mcp list` from `PATH` (`which("claude")`,
69-
`packages/core/src/cli/commands/doctor.ts:503-507`) — the user's own Claude
69+
`packages/core/src/cli/commands/doctor.ts:505-509`) — the user's own Claude
7070
Code on their own machine, to check the MCP registration, not the server's
7171
binary.
7272
- **Two moving parts.** The SDK is a runtime dependency of

‎docs/decisions/hygiene-review.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ an invalidation can name the fields that changed.
180180
entries in `context/hygiene/dismissed.md`, snoozed ones in `snoozed.md`. Each
181181
records its time and the fingerprint it applied to. `until:` takes an ISO
182182
date-time or a date; a date is due at the start of that UTC day, as before
183-
(`function dueAt`, `packages/core/src/lib/hygiene.ts:863-873`). A recorded
183+
(`function dueAt`, `packages/core/src/lib/hygiene.ts:899-909`). A recorded
184184
fingerprint that no longer matches reopens the finding at once, with an
185185
`invalidated:` receipt naming the changed fields and the disposition's date.
186186
A snooze that comes due reopens it with no receipt.
@@ -190,7 +190,7 @@ identity), the new finding carries the receipt only when the pairing is
190190
unambiguous. In one run, exactly one disposition in force with that category
191191
and path stops being detected, and exactly one new finding with them appears
192192
(`if (prior.length === 1 && siblings.length === 1)`,
193-
`packages/core/src/lib/hygiene.ts:1538`). Otherwise the new finding opens
193+
`packages/core/src/lib/hygiene.ts:1574`). Otherwise the new finding opens
194194
without one. Either way the old disposition does not suppress it. Entries
195195
moved by hand carry no fingerprint, so they keep their earlier behaviour.
196196

@@ -209,11 +209,11 @@ made (K1 A). It lives in `context/hygiene/kept.md`, which is never created
209209
empty. It holds only while the original's fingerprint is unchanged and its
210210
copy is a contained regular file outside `.brain/` and `workspaces/` that
211211
`media.track` keeps. Otherwise the original reopens with an `invalidated:`
212-
receipt (`keptInvalidity`, `packages/core/src/lib/hygiene.ts:998-1008`).
212+
receipt (`keptInvalidity`, `packages/core/src/lib/hygiene.ts:1034-1044`).
213213

214214
Sync's count and review use one read-only function that applies these
215215
predicates to the log as it stands rather than trusting the file an entry sits
216-
in (K2 B; `mediaReviewCounts`, `packages/core/src/lib/hygiene.ts:1778-1793`).
216+
in (K2 B; `mediaReviewCounts`, `packages/core/src/lib/hygiene.ts:1814-1829`).
217217
Leave pending is a per-pass deferral in review state, never a log state: it
218218
skips the finding while its fingerprint holds, and the finding still counts.
219219

@@ -265,7 +265,7 @@ permission, premise revalidation and a real post-apply check before success.
265265

266266
Do not implement dismissal by marking a still-detected finding resolved: existing
267267
reconciliation reopens such an entry (`const prev = field(entry, "resolved-by")`,
268-
`packages/core/src/lib/hygiene.ts:1512-1515`). Keep review disposition distinct from
268+
`packages/core/src/lib/hygiene.ts:1548-1551`). Keep review disposition distinct from
269269
actual check success and from notification acknowledgement.
270270

271271
Markdown remains authoritative for findings, dispositions and confirmed content

‎docs/decisions/index-query-api.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ alone does not excuse changing the documented results or error behavior.
2929

3030
Two packages currently own graph SQL. UI-server opens a short-lived read-only
3131
connection (`openBrainDb`, `packages/ui-server/src/db/brain-db.ts:75-97`), interprets graph availability ([pre-migration `getGraphMeta`](https://github.com/schlessera/brain-kit/blob/33af7e2972873286144dbcc93c232c904e3ced47/packages/ui-server/src/graph/reader.ts#L437-L471)) and walks raw links for
32-
interactive neighborhoods ([pre-migration `getNeighborhood`](https://github.com/schlessera/brain-kit/blob/33af7e2972873286144dbcc93c232c904e3ced47/packages/ui-server/src/graph/reader.ts#L525-L540)). Core has its own cluster query (`getClusterGraph`, `packages/core/src/lib/graph/queries.ts:181-204`).
32+
interactive neighborhoods ([pre-migration `getNeighborhood`](https://github.com/schlessera/brain-kit/blob/33af7e2972873286144dbcc93c232c904e3ced47/packages/ui-server/src/graph/reader.ts#L525-L540)). Core has its own cluster query (`getClusterGraph`, `packages/core/src/lib/graph/queries.ts:142-159`).
3333
Their defaults and responses differ. A wrapper around one existing helper is
3434
not automatically a behavior-preserving replacement for the other.
3535

‎docs/decisions/interpreted-briefing.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ retain sanitized tool requests.
2525
## What the source already supplies
2626

2727
`generateBriefing` performs the mechanical work
28-
(`generateBriefing`, `packages/core/src/cli/commands/briefing.ts:183-319`):
28+
(`generateBriefing`, `packages/core/src/cli/commands/briefing.ts:186-293`):
2929
focus warnings and linked documents; non-archived deadlines from today
3030
through sixty days; overdue reviews strictly before today, with a five-item
3131
cap and remaining count; module-aware audit totals and hygiene counts;
3232
recent activity, silent modifications and taxonomy-driven staleness. Its
3333
existing `now` option permits the evaluation clock without changing product
3434
code. The CLI exposes the plain-text report
35-
(`briefingCommand`, `packages/core/src/cli/commands/briefing.ts:321-340`).
35+
(`briefingCommand`, `packages/core/src/cli/commands/briefing.ts:295-314`).
3636

3737
The shipped `whatsup` skill gathers that report, may read up to three files,
3838
then interprets urgency, groups action and FYI, and writes terse bullets.

‎docs/decisions/mechanical-hygiene.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ scratch state are excluded from source-byte scoring; an input hygiene file
3636
remains protected.
3737

3838
The prototype reuses table detection (`indexTableLag`,
39-
`packages/core/src/lib/hygiene.ts:541-583`), scalar table rendering
39+
`packages/core/src/lib/hygiene.ts:577-619`), scalar table rendering
4040
(`renderRegistry`, `packages/core/src/lib/index-registry.ts:117-185`) and
4141
the surgical frontmatter editor (`editFrontmatter`,
4242
`packages/core/src/lib/frontmatter-edit.ts:216-224`). It intentionally refuses
@@ -134,7 +134,7 @@ one explicit providerless CLI planner/apply operation
134134
for this supported grammar, with `--json` and dry-run output, followed by the
135135
existing reconciliation. Re-read every consulted input and use the existing
136136
unchanged-source writer (`replaceIfUnchanged`,
137-
`packages/core/src/lib/hygiene.ts:1246-1256`) before application. Keep registry
137+
`packages/core/src/lib/hygiene.ts:1282-1292`) before application. Keep registry
138138
ownership, inbox/archive exclusions and all unhandled cases visible as log-only.
139139
The skill delegates these two mechanical operations; canonical judgment remains
140140
with it. That follow-up needs the additive contract documentation and normal

‎docs/decisions/runtime-requirements.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ Paths may appear in local diagnostics; public fixtures use temporary paths.
195195
| --- | --- | --- |
196196
| Claude backend's SDK range | Retain `^0.3.241` | It is the published declaration (`"@anthropic-ai/claude-agent-sdk"`, `packages/ui-backend-claude/package.json:49`). Registry metadata on 2026-09-30 confirms 0.3.241 exists. This is a declared compatibility bound, not proof every allowed release passed current measurements. |
197197
| ui-server's content CLI floor | Retain `0.33.0` | `--` support is the reason documented immediately above `MIN_BRAIN_CLI_VERSION` (`MIN_BRAIN_CLI_VERSION`, `packages/ui-server/src/brain/client.ts:132`); the initial boot refusal test used 0.32.9. The current test exercises the corrected floor (`a 0.40.0 brain repo pin`, `packages/ui-server/tests/brain-client.test.ts:247-259`). |
198-
| Bun engine floor | Retain existing `>=1.3.5` declarations | Existing engine metadata and the doctor's CVE-based warning (`const MIN_BUN`, `packages/core/src/cli/commands/doctor.ts:48`; `function checkRuntime`, `packages/core/src/cli/commands/doctor.ts:85-92`). This record introduces no new doctor verdict or blanket boot gate. |
198+
| Bun engine floor | Retain existing `>=1.3.5` declarations | Existing engine metadata and the doctor's CVE-based warning (`const MIN_BUN`, `packages/core/src/cli/commands/doctor.ts:50`; `function checkRuntime`, `packages/core/src/cli/commands/doctor.ts:87-94`). This record introduces no new doctor verdict or blanket boot gate. |
199199
| Pi SDK requirements | Retain existing exact `0.87.1` declarations | `packages/ui-backend-pi/package.json`; a host floor composes with each actual imported Pi dependency's existing exact requirement. The Claude range ruling does not authorize changing Pi's pins. |
200200
| Additional default Claude runtime floor | None | There is no evidenced numerical incompatibility threshold in the existing record. The successful pairs are observations, not proof that the preceding release fails. A new library floor needs a feature requirement or reproducible incompatibility and its versioning review. |
201201
| Example host SDK/runtime floors | `0.3.283` / `2.1.283` | The installed SDK manifest and `MEASURED_RUNTIME` (`export const MEASURED_RUNTIME`, `packages/ui-backend-claude/src/measured-runtime.ts:18-25`) identify this measured pair, rechecked in commit `e1ce9600`. This is a host choosing the demonstrated baseline, not a new default package floor. |

0 commit comments

Comments
 (0)