Session zero
After init the brain is empty on purpose. The door says so and points at
the multivac skill; the skill asks the one question that matters:
Does this ecosystem already exist as code, or are we starting from scratch?
Two flows, one destination: an anchored law, doors in every repo, every
subsequent decision entering as a change.
Existing ecosystem: sync → seed → questions → interview → law
The seeder reads and asks; a human answers; the agent drafts; the human enacts. Never skip the human.
0. Sync
$ mvac repos syncDeclare repos: before the brain’s first commit, then sync. It clones every
declared repo with a url that is not on disk and installs the declared SDD in
the brain, where every change’s specs are written, so nothing is drafted over a
repo nobody can read. mvac repos check names what is still missing.
1. Seed
$ mvac seed
seed: wrote .multivac/seed-report.md — 1 repo(s) inventoried
seed: next — take the open questions to a maintainer, then draft proposed claims (see the multivac skill)seed is a deterministic inventory of where the ecosystem’s architecture
lives, grouped by category per declared repo: policy gates (semgrep,
pre-commit, eslint/biome/ruff, CODEOWNERS — the project’s law already
written in machine form), workspace / build graph (pnpm-workspace,
turbo, go.work, .sln/.csproj), deploy manifests (kubernetes, helm,
kustomize, skaffold), decisions / intent (ADRs, AGENTS.md, CONTRIBUTING
— prior art, read first), plus models/schema, migrations, runtime config,
routes, protobuf, graphql, sql, api specs, docker, terraform, ci, package
manifests and env examples. Test fixtures, examples/ and vendored trees
are excluded; every category caps at 25 listed files plus a count. No LLM,
no network. The report, abridged; it closes with the open questions and a
## next pointer:
# seed report
Deterministic boundary inventory, generated by `multivac seed`.
Nothing here is law: the agent drafts `proposed` rows from it; a human enacts.
## api (../acme-api)
### policy gates (1)
- .pre-commit-config.yaml
### migrations (1)
- sql/migrations/001_accounts.sqlThe brain also gets a ### setup section, for the SDD’s project document,
which is the brain’s: it is reported once — in a section of its own when the
brain holds no code, in the brain’s entry when it does:
## brain (the brain itself, no code)
### setup
- project document .specify/memory/constitution.md: template (byte-identical to the template recorded in .specify/memory/.constitution-template.json) → run /speckit.constitution in your agent …A declared repo missing locally is listed under ## skipped, with a hint to run
mvac repos sync to clone it, and the summary line counts it as N skipped.
2. Read by category, not by repo
All policy gates across repos, then all deploy manifests, then all models. A category read surfaces the cross-repo contract — the API the web client calls, the table two services share. A repo-by-repo read hides exactly that.
3. Take the open questions to a human
The report carries the three questions no cold reader can answer, instantiated against what seed found:
- Debt or intent? — the code violates a written rule; is the violation debt or is the rule dead?
- Law or taste? — which prose rules are enforced and which are preferences?
- Which authority wins? — semgrep vs AGENTS.md, helm vs kustomize: when sources disagree, who is right?
Each is a five-second answer from a maintainer and unresolvable without one. These questions are the interview’s input — run the interview protocol against them before drafting. A guessed answer becomes wrong law, and no metric will show it.
4. Draft the map and the proposed law
Map pages: what exists, what calls what, what contract each surface exposes. Short and factual — no adjectives, no history you don’t have. The map is the only layer that scales with the ecosystem.
Proposed claims: for each boundary that looks deliberate, a claim row
plus a tentative anchor. A REVOKE UPDATE in a migration suggests “nobody
writes accounts” — suggests. You don’t know why it’s there; the human does.
| INV-07 | Only `billing_role` may write `accounts.balance`. | proposed | proposed | 2026-08-13 | seed |
<!-- @anchor INV-07 api:sql/migrations/*.sql /revoke[[:space:]]+update[[:space:]]+on[[:space:]]+accounts/i -->Anchor to the contract site you just inventoried — that is both what you read and what moves least. Full grammar: Writing anchors.
5. File everything as proposed
The legs of proposed rows never block verify; only an anchor line that does
not parse, or names a repo key nobody declared, still fails the run. The brain
stays honest about what is validated and what is not. The agent never marks a row active itself.
6. Validate in blast-radius batches
Order the proposed rows by what breaks the most if the claim is wrong: money and data-loss surfaces first, then externally published promises, then internal contracts, then conventions. Small batches, three outcomes per row:
- accept — the human enacts: state →
active, authority set by them. - correct — statement or anchor was wrong; fix and re-present.
- discard — delete the row; an accident is not law.
Whatever the session doesn’t reach stays proposed: visible, and its legs
never block. Never bulk-accept to finish faster — an enacted lie is worse
than an unvalidated truth.
7. Write the brain’s project document
After the first batch, write the brain’s project document if its SDD declares
one, such as spec-kit’s constitution. The ecosystem has one: the SDD lives in
the brain, and no code repo is asked for its own. It comes from the human’s
answers and cites the rows it restates. Where it and an active row disagree,
the row wins. change plan refuses while it is missing, empty or still the
template. When it is amended later, the report /speckit.constitution writes
for review is removed before the commit; git keeps the record.
8. Project the doors
$ mvac doors
brain: door + hooks updated
brain: .multivac/flow.md — what your declarations oblige, sorted; generated, binds nothing
api: door + hooks updatedWrites the brain door, the generated .multivac/flow.md, and each consumer
repo’s door (managed block only —
hand-written content around it is untouched), and installs the git hooks in
every declared repo on disk — except a read-only one, declared managed: false
or a shallow clone, which gets nothing. From here run mvac verify for the
baseline; every next decision is a mvac change new.
From scratch: interview → first change
There is no code to read. The law lives in the person’s head and the interview gets it out. The interview is a protocol the skill carries and your own agent runs — multivac never calls a model itself.
Elicit in this order:
- The product’s loop. What happens end to end on the happy path — one paragraph in their words, read back in one sentence. Until the loop is stated, ask nothing else.
- The boundaries. Services, stores, external APIs, clients; what talks
to what. Becomes the first map page and, later, the
repos:registry. - The non-negotiables, and why. “What must never happen, even if the code would allow it?” Who decided; what breaks if violated. A rule without a why is a convention, not law. Push once — “is that a preference or a promise?” — then take the answer.
- What is published or promised externally. Pricing pages, API docs, contracts, SLAs. These outrank everything internal; mark them with the project’s highest authority.
One question at a time; concrete over abstract (“a user pays twice — what happens?”). Read every candidate rule back in your words and get a yes to the restatement. Capture good whys verbatim.
Stop at the first slice. Loop, boundary list, non-negotiables with whys, one thin end-to-end slice — then stop. Everything else is decided inside future changes, when reality pushes back. A speculative spec is a brain that lies from day one, the exact thing verify exists to prevent.
Output lands as: the loop and boundary list in the brain door, OUTSIDE the
managed block — doors regenerates what is between the markers, whole, from
.multivac/config.yml on every run, so anything written inside them is gone
at the next multivac doors; one map page; every non-negotiable as a
proposed row (mostly unanchored — there is no code yet; that is legal and
counted). Then:
mvac change new "first slice"Declare the repos — they may not exist; greenfield apply creates them
with first commit and door — the landing order, and the claims the slice
makes true. The brain precedes the code: the first agent session inside any
new repo already knows the law. From here:
Running changes.