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: seed → questions → interview → law
The seeder reads and asks; a human answers; the agent drafts; the human enacts. Never skip the human.
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:
# 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.sqlA declared repo missing locally is reported unevaluated; run
mvac repos sync first if you need full coverage.
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 ends with 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:db/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
proposed rows never block verify. 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, counted,
non-blocking. Never bulk-accept to finish faster — an enacted lie is worse
than an unvalidated truth.
7. Project the doors
$ mvac doors
brain: door + hooks updated
api: door + hooks updatedWrites the brain door 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. 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.