docs(adr): ADR-171 — brain daemon: profile state leaves the domain process - #2153
Merged
Conversation
…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
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
commented
Aug 25, 2026
ohdearquant
left a comment
Owner
Author
There was a problem hiding this comment.
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.
# Conflicts: # docs/adr/README.md
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.
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