N brains, one default
brain_knowledge_bases is keyed (company_id, name) and carries a partial unique index
on is_default = true. So the store has always held many brains per company and exactly
one default, and naive brain list / naive brain create --name --default have always
driven it. The DSL now says the same thing.
One brain — unchanged, and still the shortest thing to write:
brains({ default, declared }). The record key is the name:
brain and brains are the same declaration at two arities. Writing both is
company_brain_and_brains at define time — two spellings of one declaration is the
defect, not the feature — and everything downstream reads one resolved shape, so a
company that declares one brain and a company that declares six go down the same code
path.
Connecting a brain to an agent
view() and partition() are the only ways to obtain a binding, and both are
methods on the value that declares the brain. That is what makes “this agent uses that
brain” structural rather than conventional: no expression can name a brain it was not
handed.
On the wire a binding carries
brainName. It is absent for a company that declares
one brain — and absent means the company default, exactly as is_default means it in
the database. A binding written before brains() existed is byte-identical to what it
was.
An empty ability list is how an agent gets nothing —
can: [], not a second concept
and not a second brain. No field anywhere means “a different brain, or none”.What is unwritable, by construction
These are not runtime refusals with friendly messages. They do not compile.
And these are refused at define time, because a config can also arrive as JSON:
Scope — where a brain sits, and what is inside it
scope mirrors brain_knowledge_bases.scope:
Default recall unions the caller’s project brain with the org brain, which is why a
second org trunk has to be refused rather than accepted and silently ignored.
Inside one brain the levels are unchanged:
Visibility — a ceiling and a narrowing
view({ can: [...] }) picks from recall, attach, think, remember, learn,
propose, reaffirm, pressure.
A brain may also declare visibility: { can: [...] } — the ceiling for every view of
that brain. A brain no agent may ever write into says so once, on the brain, instead of
every view() in the config having to remember. A view may only narrow it; a wider
one is brain_view_exceeds_visibility at define time, naming both levels. That is the
same direction retention moves, so adding an agent can never widen what a brain exposes.
promote and forget are not on the ability list, and cannot be added. They are the
human acceptance and the human erasure of model-authored text; an agent holding promote
could accept its own proposals, which is the one thing writes: { mode: "review" } exists
to prevent.
Retention is per content noun, and it only narrows
retention.beliefs is required: a brain with no stated belief retention keeps
everything forever, and that should be a decision somebody made rather than a default
they inherited. A partition or lane may narrow any value; widening throws at define
time, naming both levels. Everything is bounded by a 365-day ceiling.
The platform’s own numbers are exported as brainDefaults so you can read and narrow
them rather than invent one:
What governs a brain write
brain is an opt-in primitive (optIn: true in the registry), because it engages a
subprocessor. A fresh workspace does not have it: a gated brain call with no kit entry is
denied, not silently allowed.
Four brain actions are human-gated by default
(AccountKits):
brain.kb.deleteandbrain.document.delete— both, so the KB-delete gate cannot be bypassed by deleting document by document.brain.forget— company-scope forget is effectively a right-to-be-forgotten wipe.brain.proposal.accept— canonizing a claim is a review act.
501 not_configured, not a synthetic acknowledgement — see
Environments enforcement.
The read surface — what is wired
GET /v1/brain/beliefs answers from brain_claims and is keyset-paged. Its defining
property is that it shows its work: every row carries recallable and the three
filters that produced it, so “why did recall not return this?” is answerable from the
row instead of guessable.
lane_unavailable_because, shadows_unavailable_because,
expires_at_unavailable_because. A filter reporting true because it was never run is
the exact failure this shape exists to prevent.
Three schema facts worth knowing before you design against this.
- There is no agent level on any
brain_*table. The DSL has brain → partition → lane; the store hasorgandproject.level: "agent"is unreachable, and the endpoint reports it inlevels_absentrather than letting you infer it from an empty result. valid_tois temporal validity, not retention. It answers “this was true until then”, not “this expires then”. There is no retention column anywhere onbrain_*, so a belief in this build never lapses — which is whyexpires_atis absent rather thannull.- There is no lane column. Lanes are declarable in the DSL and not yet storable.
What refuses today
These operations are declared and addressable, and answer501 not_configured with
details.missing naming the absent dependency:
GET /v1/brain/levels and the belief reads are real. The knowledge-base, ingestion,
recall, proposal and writeback surfaces under /v1/brain/* are real too.
Related
- AccountKits — enabling the primitive and the approval defaults
- Approvals — how a gated brain action is frozen and replayed
- The durable runtime — where a team binds its partition
naive brain— listing, creating and selecting a brain from the CLI- Brain API — the wire surface