Skip to content

v10.1.0 — Trustworthy reads

Choose a tag to compare

@miisodev miisodev released this 06 Aug 07:52
· 28 commits to main since this release

The first tagged release. Every fix here sits in the read or audit path, and they shared one signature: returning something plausible instead of erroring. The write path was already guarded, templated, deduped, snapshotted and linted — for a system whose whole value is being trusted later, that asymmetry ran the wrong way.

New — consistency(pattern, domain?, kinds?)

The cross-note agreement check. Give it a regex with one capture group naming the value that should agree:

consistency("(\d+) Titan mailboxes")
consistency("BRAINLLM_MODE[=: ]+(\w+)")

It returns every note asserting a value, grouped, with agreement: "unanimous" or "DISAGREEMENT".

Nothing else detected the same fact recorded differently across several notes, where every copy reads as authoritative. recall() ranks by relevance; maintain() checks structure; a correction applied to one note leaves its siblings silently wrong.

Read path

  • recall() title matching is OR + per-token scoring, not AND, with an exact-title bonus. A note titled exactly Tool Surface previously scored zero from titles for tool surface full mode — "full" and "mode" are not in its title — and lost to full-text noise on recency.
  • The empty-result hint no longer recommends remember()-ing the content, which walked callers into duplicating something already stored.

Audit path

  • maintain(ack=) now covers every pass. The entity-corrupted and revision-bloat passes bypassed the acknowledgement filter, so an acknowledged finding re-fired every run — the exact failure ack= exists to prevent, occurring inside the ack mechanic.
  • The structural lint window rotates by date and names what it skipped. It read the same 40 of ~70 notes every run, leaving a third of the brain an unnamed permanent blind spot.
  • The lint checks completeness, not just well-formedness. A thread that lost its Resolution and a Sources note with no Revision table both passed every check that existed.
  • Near-title duplicate subjects are flagged within a domain. Equality-matching fires on the case that never happens; nobody writes a byte-identical title.
  • The unlabeled-node check covers Knowledge/Master and Knowledge/Domains, whose omission let an entire strategy layer sit invisible to every read path.

The untyped-note trap — three halves of one problem

A note missing #noteType is invisible to every read. Previously there was no way back:

  • Dedup now falls back to title-and-container, so remember() adopts an untyped note instead of minting a duplicate beside it.
  • label() can repair noteType on a note that has none (still refuses to change or remove an existing one).
  • undelete_note re-applies the label set for its container — Trilium's restore drops attributes, which is the root cause of the incident where two thirds of a brain went invisible.

Silent-loss guard

forget(hard=true) now refuses a note with children or multiple parents, naming what would be destroyed — Trilium deletes the whole subtree on the last branch.

Structure

The thread Resolution guard rejected the placeholder that remember() itself writes and template("thread") documents, so a thread repaired via revise() could not be made to match one created via remember(). It now rejects only a filled or duplicate Resolution.

Packaging

npm install brainllm works for the first time. The package had no bin, no main, and no files — so npm fell back to .gitignore, which ignores dist/, meaning the tarball would have shipped all of src/ and none of the built bundle.

CI

GitHub Actions was disabled at the repository level while the workflow reported state: active, which is why seven commits triggered zero runs. Re-enabled, plus an explicit tsc --noEmit step (bun build does not type-check) and oauth.test.ts added to the run — the CIMD impersonation and code-harvesting tests were outside CI entirely.