Skip to content

docs(adr): ADR-171 — brain daemon: profile state leaves the domain process - #2153

Merged
ohdearquant merged 8 commits into
mainfrom
feat/brain-daemon-adr
Aug 25, 2026
Merged

docs(adr): ADR-171 — brain daemon: profile state leaves the domain process#2153
ohdearquant merged 8 commits into
mainfrom
feat/brain-daemon-adr

Conversation

@ohdearquant

Copy link
Copy Markdown
Owner

Phase 2 of the store decomposition, building on the primitive ADR-170 (#2151/#2152) validated.

Design in one paragraph: the brain pack's profile posterior state (three pack-internal tables plus warm in-memory state) moves behind a brain daemon owning brain.db, using the same socket pattern (framing, peer-uid admission, flock guard, supervision, kill-switch). Feedback reaches it by tailing the ADR-170 events lane with a checkpointed cursor — no push protocol, catch-up after downtime for free. Recall keeps its existing verb-level seam (brain.profile) and receives only the few coefficient numbers it already consumes; when the daemon is unreachable, recall proceeds un-reweighted and never blocks — feedback rides the events lane, so nothing is lost during an outage.

Two verified seam facts distinguish this from the events split: the brain tables have no raw-SQL co-residency consumers outside the brain pack, and consumers reach brain state through verbs — so the whole state can move, where the events plane could not.

Draft for spec-gate review.

🤖 Generated with Claude Code

…ocess

Phase 2 of the store decomposition, on the socket/supervision primitive
ADR-170 validated. Two verified seam facts drive the design: the three brain
tables are pack-internal (no raw-SQL co-residency consumers, unlike the
events table), and recall reaches brain state through the brain.profile verb
— so the whole state moves behind a brain daemon owning brain.db, feedback
arrives by tailing the events lane with a checkpointed cursor, coefficient
queries are bounded socket round-trips, and recall fails soft to
un-reweighted ranking when the daemon is unreachable.

🤖 Generated with Claude Code
…on, schema ownership, cutover arm

The draft's event feed contradicted the ADR-170 routing it builds on:
feedback, recall, and serve events are plain-append classes on the domain
store (and serve/selection events are graph-query endpoints there, one of
the enumerated co-residency consumers), so the brain daemon cannot tail the
audit lane for them. Restated: the daemon tails both event-plane files, each
under its own monotone per-store checkpoint cursor — deliberately not one
merged cursor, since the writers share no ordering — with no cross-store
fold ordering claimed. Also folded: the true four-file consumer enumeration
with a mechanized pack-internality guard committed for implementation;
schema ownership moves with the state (brain daemon owns brain.db DDL,
khive-db migrations stop creating the tables in new stores); fail-soft
attribution stated (unattributed feedback retained in the plane, refused
for profile folds, counted); cutover carries a double-fold/gap test arm
comparing against an uninterrupted single-pass fold.

🤖 Generated with Claude Code
…ing sequencing note

Implementation-depth enumeration corrections: brain_scorer_dedup (the
exactly-once scorer claim, written inside the fold transaction) is the
fourth pack-internal table and moves with the state; and the feedback
dispatch path commits its public event-plane row in the same transaction
as the fold, so implementation order is fold-decouple first, storage
relocation second, daemon boundary third. Decision boundary unchanged.

🤖 Generated with Claude Code
@ohdearquant
ohdearquant marked this pull request as ready for review August 25, 2026 00:47
…ursor, signal carrier, error split, response contract, kill-switch DDL

Substantial revision of the brain-daemon split contract:
- Socket boundary stated explicitly and fail-closed on both ends: bind-side
  directory trust predicate + swap-resistance + 0600 + peer-uid admission,
  connect-side path vetting against pre-bound impostor listeners.
- brain_serve_ledger added to the moved inventory (five tables); ledger rows
  become fold-side output materialized from durable RecallExecuted events,
  idempotent under the existing UNIQUE key; brain.record_serve retired.
- Authoritative replay cursor: per-store insertion-order rowid high-water
  mark, fold + cursor advance in one brain.db transaction — no double-fold
  window, immune to delayed rows landing with older timestamps.
- Recall signal carrier: durable RecallExecuted gains the target_id stamp
  the synthetic dispatch event carries today; the synthetic hook is deleted
  in the same change so each recall folds exactly once.
- Typed error split: transport/liveness failures degrade fail-soft on both
  profile-resolution paths (explicit included); typed unknown-profile
  refusals stay invalid-input on the explicit path.
- Daemon response contract: byte-compatible with the current brain.profile
  document (state_snapshot, section_posteriors) — the serving projection,
  not fold-side state.
- Kill-switch works on post-cutover stores: idempotent compatibility DDL
  applied on legacy activation, symmetric snapshot-plus-fence hand-off in
  both mode-switch directions.
…r event store

The routing paragraph justified tailing the domain store but ordered tailing
both files without naming what the sidecar cursor folds. Named it: dispatch-
audit rows interpreted as note-access and search signals travel the
idempotent audit batch routed to the sidecar, so both cursors cover live
fold-input classes.

@ohdearquant ohdearquant left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review. Posted by this repository's automated pull-request review pipeline; this is not a human read and does not gate the merge by itself.

Verdict on head d7067c0: REQUEST-CHANGES, 3 blocking findings. Finding details are delivered to the review's recipients rather than posted here. Do not merge this head while blocking findings are outstanding; a pipeline comment on a newer head supersedes this one.

…ed five-table hand-off

Three cutover/replay gaps closed:

- RecallExecuted now carries a stable serve id (the event's own id) and
  the exact served_at captured at the response boundary, and the durable
  append moves out of the detached background task into recall dispatch,
  committing before the response returns. Serve-before-feedback ordering
  becomes a guarantee instead of an assumption, and fold-side ledger
  materialization reproduces byte-identical key columns under re-fold.

- The replay cursor pairs the last folded rowid with that row's TEXT id
  as a stability witness: implicit rowids are renumbered by VACUUM,
  which the store supports as top-level writer-lane maintenance. On
  witness mismatch the daemon rebases by id; on a purged id it rewinds
  to the oldest remaining row rather than skipping, with rebases counted.

- Cutover and kill-switch fences are captured under a writer-lane hold
  (folding stopped alone leaves appends landing below the fence,
  unfolded and unreplayable), and the hand-off payload is enumerated as
  all five brain tables in both directions — dedup claims, serve ledger
  rows with grades, implicit mass — with per-table row-count equality
  verified before the new mode serves.
@ohdearquant
ohdearquant merged commit bf02b44 into main Aug 25, 2026
26 checks passed
@ohdearquant
ohdearquant deleted the feat/brain-daemon-adr branch August 25, 2026 13:07
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