Milestone map¶
Milestone 32 memory reconsolidation was authorized on 2026-10-02. Its detailed design declares twenty-four gates, registered on 2026-10-03. The first two observe the frozen evaluation yardstick; all runtime and release gates remain pending. The verified ceiling stays 14.
The gate registry makes milestone a required field on every gate. Ten
specifications declared eighty-nine gates between them when this
document was written. One of the ten supplied that field per gate, four
supplied it once for a whole section, and five did not supply it at
all.
That is not a formatting complaint. Registry rule 1 says a docs check parses the hard-gate section of each spec, counts the declared gates, and compares against the registry — and that check is a Milestone 0 deliverable, which means it has to run before there is an agent to evaluate. Today it cannot be written. The gate sections carry three different headings, two different declaration forms, and in two specs the gates are interleaved with tracked metrics in a single bullet list whose gate-ness is stated mid-sentence.
This document supplies the missing field for all eighty-nine, fixes the declaration form so the check is writable, and finishes the milestone assignment for the five build sequences that carry no tags. It also closes two smaller reconciliations that turned up in the same sweep: what the tool system's persistence build step means inside an in-memory milestone, and what cancels a run at Milestone 1.
http-api-and-streaming.md was written after
this document and declares ten more gates, in the form fixed here and
with a milestone on each — which is what fixing the form was for. Its
gates appear in the table and the census below and needed no
reconciliation.
sandbox-isolation.md was written later still
and declares thirteen more, in the same form and in a new twelfth
area. skills.md followed and declares sixteen
more, in a new thirteenth area, and is the first spec to declare
gates at Milestone 10. model-gateway.md and
event-log-and-persistence.md each
gained two more on a later pass, all four at Milestone 3.
knowledge-documents.md declares twelve more, in a new
fourteenth area, all of them at Milestone 9. web-access.md
declares seven more in a fifteenth area, all at Milestone 10.
browser-automation.md adds ten more in a
sixteenth area, also at Milestone 10. scheduling.md first
declared twenty-three Milestone 11 gates in a seventeenth area, then five at
Milestone 19, six at Milestone 20, and twelve at Milestone 23.
adaptive-memory-distillation.md adds
thirty-one Milestone 21 gates in the existing memory area.
persona-surface.md adds fourteen Milestone 22 gates in
a new persona area. The current counts
are reconciled in the gate table and census below.
What this document is responsible for¶
It is a scheduling document. It decides when each stated requirement must hold, and it changes no requirement's content.
- In scope. The milestone of every declared hard gate; the identifier each gate carries in the registry; the declaration form the docs check parses; the milestone of every build-sequence step in every spec that left them untagged; the three gates that are declared in two specs at once and therefore need one owner.
- In scope, by consequence. Two reconciliations that only became answerable once the gate milestones were fixed: tool-system build steps 3 and 4 against the prohibition on early PostgreSQL, and the Milestone 1 half of the cancellation split.
- Not in scope. No gate belonging to another document is added, removed, weakened, or strengthened. Where this document splits one stated gate into two registry entries it is because the spec says "both are hard gates", and where it moves a bullet out of a gate list it is because the spec calls that bullet a metric. The seven gates under Hard gates are this document's own, and every one of them checks the corpus rather than the agent.
- Not in scope. The contents of
evals/gates/*.yaml. This document is what those files are generated against and checked against; it is not those files.
The three problems¶
Headings¶
The gate section is spelled three ways across the corpus.
heading specs
--------------------------------- -----------------------------
## Hard gates builtin-tools, evaluation-
harness, model-gateway,
runtime-loop, tool-system
## Evaluation context-engine, event-log-and-
persistence, memory-retrieval-
and-ranking, policy-and-
approvals
## Evaluation (gates the memory-formation-and-
milestone) consolidation
Two specs, bootstrap-and-composition.md and
development-toolchain.md, declare no gates at all. That is correct
and stays correct: both describe construction rather than behaviour,
and the four static checks bootstrap adds are declared as Milestone 0
consequences rather than as gates of their own. The secret scanner
bootstrap-and-composition.md specifies is a gate, but the engineering
plan declares it; bootstrap supplies the mechanism, not the
requirement.
Forms¶
Six specs declare gates as a numbered list. Four declare them as a
bullet list. The registry example's spec field points at
policy-and-approvals.md#evaluation, so the anchor a gate cites is
already the ## Evaluation spelling in at least one place, which is
why the fix below renames headings rather than leaving the check to
know three of them.
Metrics mixed into gate lists¶
memory-formation-and-consolidation.md and
memory-retrieval-and-ranking.md list gates and tracked metrics in one
list, distinguishing them in prose: "A hard gate", "The primary
metric", "A hard gate, not a metric to improve", "Both are hard
gates, not metrics to improve". A count over those lists is not
defined until they are separated, and separating them is reading what
is written rather than deciding anything.
The declaration form¶
One heading, one form, one suffix.
- Every spec that declares gates spells the section
## Hard gates. Four## Evaluationsections and one## Evaluation (gates the milestone)are renamed, and where such a section also carried tracked metrics those move to a sibling## Tracked metricssection immediately after. No sentence stating a requirement changes; the only additions are a bolded lead where a bullet had none and the milestone token. - Every gate is a numbered list item whose first bolded phrase is
its name. The four bullet-form specs convert
- **Name.**to1. **Name.**. Where a bullet had no bolded lead, one is added from the bullet's own first phrase. - Every gate ends with its milestone as a bolded token, in the
form
**M2.**, asruntime-loop.mdalready does for all fourteen of its gates. A section-level sentence such as "Milestone 3 does not pass until every one of these holds" stays where it is; it is prose about the milestone, and the per-gate token is what the check reads. - The docs check reads the token, not the prose. Its parse is:
find
## Hard gates, take every top-level numbered item, take the trailing**M<number>.**, and fail if any item lacks one. The token holds a number rather than a single digit, because skills.md declares gates at Milestone 10. This is the weak count-and-identifier check registry rule 1 describes, and it is weak on purpose. - The
specfield in the registry points at#hard-gates. The two example entries inevaluation-harness.mdare updated from#evaluation, which is the only place the old anchor is written down.
Gate identifiers¶
The registry example uses gate.policy.totality. That form is adopted
and given a grammar.
gate.<area>.<slug>
area one of: structure, runtime, tool, builtin, model, policy,
event, context, memory, harness, api, sandbox, skill,
knowledge, web, browser, schedule, device, notify, delegate,
surface, ops, email
slug lowercase, underscore-separated, unique within its area
The area is not the filename. structure exists because three gates —
the import-boundary walk, the transaction-hygiene check, and the secret
scanner — are structural statements about the repository that no single
subject spec owns, and memory covers all four memory specs because
formation, retrieval, the Milestone 16 benchmark, and the Milestone 17
read surface share a harness and their gates cross-reference each other.
It is the only area more than two specifications share, and the two that
joined it did so on the same argument:
memory-evaluation-and-lifecycle.md
measures the subject the area already names and
memory-read-api-and-browser.md shows
it, so both read the beliefs the first two declare gates over. A route
that returns a belief is a statement about the belief store rather than
about the API, which is why the read surface's gates take memory and
not api.
sandbox is the twelfth and it follows the memory precedent rather
than the structure one: one spec owns all thirteen, and they are
statements about a subject rather than about the repository. The
alternative considered was a security area, which was rejected
because an area names a subject and security is a property of many of
them — the secret scanner, the import boundary, and the cross-tenant
404 would all have a claim on it, and none of them belongs with a
sandbox escape.
skill is the thirteenth and follows the same precedent for the same
reason. The alternative considered was splitting its gates across
context, tool, and policy, which was rejected because one spec
owns all sixteen and because two halves of one governance story —
what reaches the prefix, and who may write a skill — would otherwise
land in different areas.
knowledge is the fourteenth, on the same precedent again. It is not
folded into memory even though both stores are Milestone 9 and share
a harness, because the two memory specs are one subject read and
written while a knowledge document is a different store with a
different trust label, a different isolation predicate, and a
different unit of retrieval. The alternative considered was splitting
its gates across memory, context, and tool, and it was rejected
for the reason skill rejected the same split: visibility and
no_belief_write are two halves of one governance story.
web is the fifteenth. It owns the provider contract, routing,
default-off registration, context advertisement, invocation trust, failure
normalization, and fetch confinement as one public-web governance story rather
than distributing those invariants across tool, policy, and context.
browser is the sixteenth. It owns authenticated browser navigation, observation,
action authority, profile lifecycle, authentication, and standing grants as one
origin-confined governance story.
schedule is the seventeenth area. It is not folded into event, runtime, or
api because occurrence identity, civil-time behavior, authority refresh, and
lifecycle are one control-plane subject whose gates cross all three. The
ordinary run remains owned by those existing areas after materialization.
device is the eighteenth and notify the nineteenth, both declared by
notifications-and-devices.md at Milestone 12.
They are two areas rather than one because device identity is the half of that
milestone Milestone 14's Surfaces reuse and deserves its own census line, while
notify owns the outbox, the content-free payload, dispatch, and the push
transport as one delivery story. Neither is folded into api or event: a
device has no session, and the outbox is a sibling write in the triggering
transaction rather than a new event type.
delegate is the twentieth, declared by
subagents-and-delegation.md at Milestone 13. It
owns the brief, materialization, the child-run suspension and join, derived
limits, subset scopes and tools, untrusted results, the ledger, and the
activation evidence as one delegation story; the child itself remains an
ordinary run owned by runtime, tool, and event after materialization.
surface is the twenty-first, declared by
inbound-surfaces.md at Milestone 14. It owns pairing,
the session-key resolver, the ingress transaction, the trust and attribution
rules for a paired sender, the reply path, and the surface role's confinement
as one inbound-channel story; the run a paired message creates remains an
ordinary run owned by the existing areas.
ops is the twenty-second, declared by
operational-hardening.md at Milestone 15. It is
ops rather than deploy because ADR-0048 deliberately says the delivery
jobs add no milestone gate; the subject is the operational lifecycle — backup,
restore, watch, harden, roll back — and it is one spec owning one area, as
sandbox was.
email is the twenty-third, declared by
email-integration.md at Milestone 18. It is not
folded into tool even though every one of its tools crosses the MCP
adapter the tool system owns, because its gates are statements about the
Gmail servers, their rosters, their credential ceremony, and their policy
posture rather than about the adapter that carries them — the same argument
that kept web and browser out of tool. One spec owns all seventeen, as
sandbox and ops were owned.
Every identifier in the tables below is written in full. Thirteen rows
across four of them used to carry a truncated one, which this grammar
does not admit — a slug is underscore-separated and holds no dots, so
gate.runtime.one_terminal_wr.. is not an identifier, and
gate.harness.id_grammar and gate.harness.map_bijection would both
fail on it, the first because it does not match and the second because
it cannot be compared as a set member against anything. Nine of the
twelve gates involved were spelled in full elsewhere in the corpus and
are restored from there. The other three had never been spelled
anywhere, and are completed here from their own declarations: runtime
loop gates 1, 11, and 12 are "One terminal writer", "A waiting run
holds nothing", and "Cancellation never abandons an effect", giving
gate.runtime.one_terminal_writer,
gate.runtime.waiting_holds_nothing, and
gate.runtime.cancel_keeps_effects — the last of which the census
below already reads as "cancellation keeps effects". The
malformed form above is quoted, not registered: the grammar gate
reads the registry tables and evals/gates/*.yaml, both of which
hold only real identifiers, and not the prose that explains what a
truncated one looked like.
Ownership: the three gates declared twice¶
Three statements appear as gates in two specs each. Each gets one registry entry, one owner, and an explicit alias so that a reader who finds it in the non-owning spec knows it is not a second gate.
gate id owner also stated in
--------------------------------- --------------- -----------------
gate.structure.import_boundary engineering tool-system #6
plan, M0
gate.structure.txn_hygiene event-log #7 runtime-loop #6
gate.event.checkpoint_dispensable event-log #6 runtime-loop #9
The generic import-boundary walk is one of the two registry entries
whose owner is not a detailed-design spec. It is declared in the
engineering plan's Milestone 0 acceptance criteria, alongside the
transaction-hygiene check, the secret scanner, and contract-module
coverage, and its spec field points there. tool-system.md #6
restates it in one sentence and is its only alias. The secret scanner
is the other, and the gate table below says why.
model-gateway.md #1, policy-and-approvals.md #3, and
evaluation-harness.md #4 also run on the import-boundary walk and are
not aliases: each asserts a specific edge that the generic walk
does not name — no provider SDK reachable from the runtime, exactly one
function authorizing an invocation, nothing outside the evals package
importing it. They keep their own ids.
The alias rule matters for counting. A docs check that compares a spec's gate count against the registry must count an alias in the declaring spec and not in the registry, so the map records the alias count per spec and the check subtracts it.
The gate table¶
The 36 subject specifications declare 601 gates, the engineering plan
declares 2 more, and this document declares 7 over the corpus: 610
declarations, 607 registry entries once the 3 aliases are subtracted.
make docs-check reconciles this paragraph's digits against the
registry, so the arithmetic here cannot drift silently.
Each table gives the gate's number in its own spec, its registry
identifier, its kind, and its milestone.
id kind M declared in
----------------------------------- ---------- -- ----------------
gate.structure.import_boundary structural 0 plan, Milestone 0
gate.structure.no_committed_secrets structural 0 plan, Milestone 0
The second is specified in
bootstrap-and-composition.md, which
gives its five rule families and the three properties that matter more
than its patterns. It is declared here rather than there for the same
reason as the first: both are named in the engineering plan's Milestone
0 acceptance criteria, and neither is a statement about a subject that
a detailed-design spec owns. It was carrying an identifier in a
security area that this document's grammar does not define, which is
how it went unregistered; the identifier is corrected to structure
and the arithmetic above absorbs it. ADR-0027 and ADR-0028 are not
amended — their totals are records of what was true when each was
decided, and this document is where the current one is stated.
Both are registry entries and both carry a spec field, and they are
the only two whose field does not end in #hard-gates. The
engineering plan has no such section, because it is organized by
milestone rather than by subject: it declares these two in Milestone
0's acceptance criteria and the prose beneath them, and there is
nowhere else in that file they could live. Their spec names
engineering-plan.md and the anchor of the heading that declares
them, "Milestone 0: Repository and engineering foundation", which
is the only heading in that file either one could resolve to. Hard
gate 4 below is titled "Every spec field resolves", and that is
what it checks: the anchor an entry names exists in the built site,
which is how evaluation-harness.md states it
too. The #hard-gates form in that gate's body is the shape every
other entry takes, not a further condition on these two.
Runtime loop, fourteen gates¶
Already tagged per gate. Reproduced here so the map is complete and so the two aliases are visible.
# id kind M
-- ---------------------------------- ----------- --
1 gate.runtime.one_terminal_writer structural 1
2 gate.runtime.no_ambient_time structural 1
3 gate.runtime.no_ambient_id structural 1
4 gate.runtime.step_identity case 1
5 gate.runtime.budget_stops case 1
6 (alias of gate.structure.txn_hygiene) 2
7 gate.runtime.lease_once case 2
8 gate.runtime.fenced_no_write case 2
9 (alias of gate.event.checkpoint_dispensable) 2
10 gate.runtime.resume_idempotent case 2
11 gate.runtime.waiting_holds_nothing case 4
12 gate.runtime.cancel_keeps_effects case 5
13 gate.runtime.build_fits property 7
14 gate.runtime.build_stable property 7
Tool system, sixteen gates¶
The section carried no milestone. The assignment follows the build order the same document already tags — steps 1 through 5 are Milestone 1, step 6 is Milestone 4, steps 7 and 8 are Milestone 6, step 9 is Milestone 8 — by asking which build step each gate observes.
# id kind M step
-- ------------------------------ ----------- -- ----
1 gate.tool.registration_valid structural 1 1
2 gate.tool.forced_trust structural 1 1
3 gate.tool.watermark_first case 1 4
4 gate.tool.outcome_shape case 1 5
5 gate.tool.no_external_text corpus 1 5
6 (alias of gate.structure.import_boundary) 0 --
7 gate.tool.crash_recovery case 2 4
8 gate.tool.dedup_concurrent case 2 3
9 gate.tool.normalization_stable property 1 2
10 gate.tool.reserved_domains structural 1 1
11 gate.tool.mcp_pipeline_parity case 8 9
12 gate.tool.mcp_disconnect case 8 9
13 gate.tool.mcp_sdk_confined structural 8 9
14 gate.tool.mcp_auth_config structural 8 9
15 gate.tool.mcp_reauth_bounded case 8 9
16 gate.tool.mcp_stdio_env_built case 8 9
Gates 11 through 16 are step 9's and say so themselves, so they need no derivation. Three of the rest need their reasoning stated, because the milestone is not the one a first reading gives.
- Gate 5 is Milestone 1, not Milestone 8. The statement is "No
external text appears in
messagefor any failure path", and the spec illustrates it with a fake MCP server returning a hostile string. The rule is testable at Milestone 1 over a builtin failure whosedetailcarries hostile text, and the MCP server is a corpus member added at Milestone 8. Growing a corpus strengthens a corpus gate without touching its code, which is the property the harness separates that kind for. Deferring the whole gate to Milestone 8 would leave the rule that keeps prompt injection out of the model's input unasserted for seven milestones. - Gate 7 is Milestone 2, not Milestone 1, although build step 4 is a Milestone 1 step. It requires "a recorded crash at each of the fourteen pipeline steps" recovering to a specified state, and recovery is defined over persisted rows. An in-memory adapter that dies takes its state with it, so the gate has nothing to observe until the run survives the process.
- Gate 8 is Milestone 2 for the same reason and one more. "Two concurrent submissions of the same call produce one execution" is a statement about a unique index under concurrency. The Milestone 1 in-memory adapter asserts the single-process half — a second submission in the same process returns the first result — and the concurrent half arrives with the index.
Gates 11 through 13 were added after the first pass over this document, when the census made it visible that build step 9 was the only step in the tool system with no gate observing it. They assert that the MCP adapter added no path around the pipeline, that a disconnect stays inside the outcome vocabulary, and that the SDK stops at the adapter boundary. The third is the engineering plan's last Milestone 8 acceptance criterion promoted from prose to a walk over the import graph.
Gates 14, 15, and 16 arrived later still, with the authentication
scheme the readiness review found missing behind credential_ref.
They divide by what each needs in order to run, which is why there are
three rather than one: gate 14 needs neither a server nor a broker and
tests the configuration validator alone, gate 15 needs a server that
will return 401 on demand, and gate 16 needs a child process it can
read the environment of. A single gate covering all three would be
unrunnable until the last of its dependencies existed, and the first
of them is checkable on the day the column is added.
Builtin tools, fifteen gates¶
The first nine observe math.calculate or system.current_time,
both of which ship at Milestone 1. The last six arrived with the pass
that designed the four remaining builtins, and observe the three
workspace. tools and demo.external_write at Milestone 4. Gate 10
is structural and runs over the import and call graphs; the rest
observe behaviour.
# id kind M
-- ------------------------------ ----------- --
1 gate.builtin.registration structural 1
2 gate.builtin.reserved_domain structural 1
3 gate.builtin.demonstration case 1
4 gate.builtin.parser_property property 1
5 gate.builtin.bounds_latency property 1
6 gate.builtin.int_differential property 1
7 gate.builtin.decimal_exact case 1
8 gate.builtin.clock_stability case 1
9 gate.builtin.message_table structural 1
10 gate.builtin.handle_only structural 4
11 gate.builtin.text_only case 4
12 gate.builtin.write_idempotent case 4
13 gate.builtin.listing_stable property 4
14 gate.builtin.provenance case 4
15 gate.builtin.demo_records case 4
Model gateway, twelve gates¶
The section already says Milestone 3 for all twelve, and the build order's fourteen steps carry no tags because all fourteen of them are Milestone 3 as well. Gate 10 is the one exception worth naming: it skips when credentials are absent, which registry rule 3 forbids at or past a gate's milestone.
# id kind M
-- ------------------------------ ----------- --
1 gate.model.sdk_isolation structural 3
2 gate.model.contract_identical case 3
3 gate.model.call_id_roundtrip case 3
4 gate.model.stream_invariants case 3
5 gate.model.no_secret_leak structural 3
6 gate.model.malformed_args case 3
7 gate.model.pin_survives_resume case 3
8 gate.model.cost_on_failure case 3
9 gate.model.ollama_scenario case 3
10 gate.model.live_smoke case 3
11 gate.model.metadata_closed structural 3
12 gate.model.profile_valid corpus 3
Gate 10 is registered with optional: true, a field the registry does
not yet have and which this document adds for it alone: a gate that is
allowed to report skipped when a named precondition is absent, with
the precondition recorded. Without the field the choice is a forbidden
skip or a gate that fails on every machine without vendor keys, and
both are worse than naming the exception once.
Policy and approvals, eighteen gates¶
The first thirteen are Milestone 4, which the section states and the build sequence confirms — steps 1 through 11 are Milestone 4 and step 12 is sequenced separately and is not a dependency. The last three of those arrived with the scope vocabulary, which that section owns because the check runs at this milestone and the API document that enumerated the first nine strings is Milestone 5. Gates 14 through 18 are step 12, the advisory layer, authorized as Milestone 30 by ADR-0111.
# id kind M
-- ------------------------------ ----------- --
1 gate.policy.totality property 4
2 gate.policy.determinism property 4
3 gate.policy.single_gate structural 4
4 gate.policy.monotonicity property 4
5 gate.policy.hardline_immutable case 4
6 gate.policy.revalidation case 4
7 gate.policy.cross_tenant case 4
8 gate.policy.no_leakage case 4
9 gate.policy.idempotent_resolve case 4
10 gate.policy.prompt_not_authz corpus 4
11 gate.policy.scope_grammar structural 4
12 gate.policy.scope_match case 4
13 gate.policy.scope_stamped case 4
14 gate.policy.advisory_monotonic property 30
15 gate.policy.advisory_allow_path_once case 30
16 gate.policy.advisory_abstains case 30
17 gate.policy.advisory_blind_redacted structural 30
18 gate.policy.advisory_default_off case 30
Event log and persistence, fourteen gates¶
The section says Milestone 2 for eleven of the fourteen, and three things need a word.
The first is the transaction-hygiene gate, already decided in ADR-0024: the check is a Milestone 0 deliverable and its gate is a Milestone 2 acceptance criterion. The registry entry carries Milestone 2, because a gate is the assertion and not the tool, and Milestone 0's obligation is that the tool exists and passes against a nearly empty repository.
The second is the revision-graph walk, added with the migration conventions ADR-0031 records. It registers at Milestone 0, and unlike every other early registration in this document the spec says so itself — the gate is tagged M0. where it is declared. Milestone 0 already requires that an empty Alembic migration runs, so there is a graph to walk on the day the milestone closes. The rule is the same one that produced every other assignment here: a gate lands at the milestone that builds the last thing it observes, and what this one observes is the graph.
The third is the pair of export gates, 13 and 14, which the spec tags
M3. where they are declared. Milestone 2 builds the projection's
scaffold and the export_consent column the stamp lands in; Milestone
3 builds the document builder, the redaction pipeline, and the consent
tables, which is what those two gates observe. The rule is the same
rule again.
# id kind M
-- --------------------------------- ----------- --
1 gate.event.sequence_integrity property 2
2 gate.event.projection_determ case 2
3 gate.event.upcaster_totality property 2
4 gate.event.exactly_once case 2
5 gate.event.crash_recovery case 2
6 gate.event.checkpoint_dispensable case 2
7 gate.structure.txn_hygiene structural 2
8 gate.structure.migration_graph structural 0
9 gate.event.migration_clean case 2
10 gate.event.migration_stepwise case 2
11 gate.event.revision_pinned case 2
12 gate.structure.orm_confined structural 2
13 gate.event.export_redacted case 3
14 gate.event.export_consent case 3
The build sequence's nine steps are Milestone 2, except that step 8 keeps only the projection's scaffold and the consent stamp there and places the document builder, the redaction pipeline, the consent tables, and both export gates at Milestone 3.
Context engine, six gates¶
The section says Milestone 7 for all five. One moves earlier, because
ADR-0024 already scheduled it: the Milestone 1 context builder is
build-sequence step 1, and its acceptance is that build() twice on
one checkpoint is byte-identical and that the request bytes differ in
Region B only. That is gate 1, exactly.
# id kind M
-- ------------------------------ ----------- --
1 gate.context.determinism property 1
2 gate.context.prefix_stability case 7
3 gate.context.budget_conform case 7
4 gate.context.tool_pair_integ property 7
5 gate.context.trust_preserved corpus 7
6 gate.context.history_cut property 7
Gate 2 stays at Milestone 7 because its subject is a scripted fifty-turn session with a forced compaction, a revoked tool, and a memory correction — none of which exist before Milestone 7. Gate 1 stays true from Milestone 1 onward and is the reason the builder is written deterministically from the first commit rather than retrofitted. Gate 6 was added later, when the readiness review found that history had a yield order and no rule saying which items were in the request before yielding began; it is a property gate for the same reason gate 1 is, because the claim is about every input rather than about a chosen one.
The build sequence's seven steps are Milestone 7 except step 1, which is Milestone 1 by the same decision.
Memory formation, twenty gates and four metrics¶
The original list of eight bullets separates into four Milestone 9 gates and four metrics by what the spec calls them. The trailing sentence "Gate: memory improves target eval cases without increasing policy failures" is a fifth gate, not a closing remark. Milestone 10 memory maturation adds fifteen explicit gates: five for ordinary-conversation formation and lifecycle, then ten for the governed inspection surface and evaluation-gated provider-assisted extractor.
# id kind M
-- ------------------------------ ----------- --
1 gate.memory.contradiction case 9
2 gate.memory.no_fabrication corpus 9
3 gate.memory.form_injection corpus 9
4 gate.memory.correction_durable case 9
5 gate.memory.no_policy_regress case 9
6 gate.memory.multi_candidate case 10
7 gate.memory.source_integrity property 10
8 gate.memory.idle_lifecycle case 10
9 gate.memory.formation_bounded case 10
10 gate.memory.correction_isolated case 10
11 gate.memory.inspection_governed case 10
12 gate.memory.extractor_contract structural 10
13 gate.memory.provider_activation_bound property 10
14 gate.memory.provider_boundary case 10
15 gate.memory.provider_audit_fallback case 10
16 gate.memory.provider_evidence_publish case 10
17 gate.memory.provider_claim_rendering structural 10
18 gate.memory.provider_failure_diagnostics case 10
19 gate.memory.provider_positive_coverage case 10
20 gate.memory.provider_source_safety case 10
Moved to ## Tracked metrics: formation precision, recall of
consequential facts, rejection rate, and cost. Each is described in the
spec as something measured and improved rather than something that
blocks, and the first is explicitly "The primary metric".
Memory retrieval, nine gates and seven metrics¶
# id kind M
-- ------------------------------ ----------- --
1 gate.memory.currency case 9
2 gate.memory.historical_correct case 9
3 gate.memory.recall_injection corpus 9
4 gate.memory.scope_isolation property 9
5 gate.memory.trace_faithful case 9
6 gate.memory.view_ceiling property 9
7 gate.memory.retr_correction case 9
8 gate.memory.cache_preserved case 9
9 gate.memory.no_triple_regress case 9
Gates 5 and 6 come from one bullet, because that bullet says "Both are
hard gates" about two distinct statements: that a sampled turn's trace
reproduces the rendered block the recorded hash covers, and that no
belief above min(recall ceiling, viewing ceiling) ever appears in a
view. They fail for different reasons and are separated here.
Moved to ## Tracked metrics: consequential recall@k, noise ratio,
transfer precision, transfer lift, cost, latency, and end-to-end lift.
Evaluation harness, eleven gates¶
The harness's own gates are the ones nothing else can check, and they are the earliest in the corpus: four run against a repository with no agent in it.
# id kind M
-- ------------------------------ ----------- --
1 gate.harness.registry_complete structural 0
2 gate.harness.no_stale_skip structural 0
3 gate.harness.contract_coverage structural 0
4 gate.harness.evals_isolation structural 0
5 gate.harness.no_eval_in_prod case 1
6 gate.harness.case_schema structural 1
7 gate.harness.no_egress case 1
8 gate.harness.corpus_minimum structural 4
9 gate.harness.trajectory_source structural 3
10 gate.harness.reason_code_table structural 1
11 gate.harness.mcp_no_socket case 8
Gates 1 through 4 are Milestone 0 and three of them are vacuously true
of an empty repository — no gates declared, no ports, no imports. That
is the point rather than an objection, and the engineering plan already
argues it: a structural check added later is added against existing
violations, which is the situation in which it gets relaxed rather than
obeyed. Gate 4 asserts one edge of the same walk that
gate.structure.import_boundary performs, and is a gate of its own
because the edge is specific to the evals package.
Gate 5 is Milestone 1 rather than Milestone 0 because it runs the production loader, and the loader is the composition root's refuse phase, which is Milestone 1. Gates 6, 7, and 10 are Milestone 1 for the same class of reason: each needs something the vertical slice builds. Gate 8 is Milestone 4 with the corpora, and gate 9 says its own milestone. Gate 11 is Milestone 8 because it needs MCP cases to run against, and it is a case gate rather than a structural one for the same reason gate 7 is: an offline fixture layer is proven by running the cases with egress blocked, not by reading them.
HTTP API and streaming, ten gates¶
Ten gates, all Milestone 5, all new. The spec tags each one, so the assignment is the spec's own rather than derived. They are the reason Milestone 5 stops being the milestone with one gate and the largest externally visible surface.
# id kind M
-- ------------------------------ ----------- --
1 gate.api.code_vocabulary case 5
2 gate.api.status_map_total structural 5
3 gate.api.no_request_tenant structural 5
4 gate.api.cross_tenant_404 case 5
5 gate.api.scope_declared structural 5
6 gate.api.transient_no_id case 5
7 gate.api.replay_exact case 5
8 gate.api.cancel_observed case 5
9 gate.api.submit_idempotent case 5
10 gate.api.artifact_attachment case 5
Gates 2, 3, and 5 are structural because they are assertions about the
shape of the code rather than about a run: a mapping that must be
total, an AST walk that must find no binding of tenant_id from a
request, and a walk over the route table that must find a declared
scope on every route but the two health probes. The remaining seven
need a running API and are cases.
Sandbox isolation and artifacts, thirteen gates¶
Thirteen gates, all new, in a new twelfth area. Eleven are Milestone 6, which had none; one is Milestone 1 and one is Milestone 4, because a gate lands at the milestone that builds the last thing it observes and those two observe code written before the sandbox exists. The spec tags each one.
# id kind M
-- ----------------------------------- ----------- --
1 gate.sandbox.production_refuses_dev structural 1
2 gate.sandbox.no_runtime_in_worker structural 6
3 gate.sandbox.spec_has_no_host_path structural 6
4 gate.sandbox.no_credential_reaches case 6
5 gate.sandbox.network_denied case 6
6 gate.sandbox.egress_allowlisted case 6
7 gate.sandbox.limits_enforced case 6
8 gate.sandbox.escape_denied case 6
9 gate.sandbox.workspace_isolated case 6
10 gate.sandbox.no_orphans case 6
11 gate.sandbox.artifact_checksum case 6
12 gate.sandbox.artifact_key_opaque structural 6
13 gate.sandbox.workspace_containment property 4
Gate 1 is Milestone 1 because the composition root refuses the
development mechanism from the first startup that has a mechanism to
choose, and gate 13 is Milestone 4 because WorkspaceHandle is what
the three workspace. tools resolve paths through. Gates 2, 3, and 12
are structural for the usual reason — an import walk, a check over
declared field types, and a check over a function's parameters — and
gate 13 is the corpus's sixteenth property test. The remaining eight
need a real sandbox and are cases. One of them, gate 8, is the
red-team escape test Section 28.7 has required since version 2.0 and
the harness had no case for.
Skills, sixteen gates¶
Sixteen gates, all new, in a new thirteenth area. Ten are Milestone 8 and six are Milestone 10 — the two milestones in the plan that had none, and Milestone 10 is the first milestone past 9 to acquire a census row. The split is the substrate against the authoring loop: everything that decides what a skill is, where it lives, and what it may reach is Milestone 8, and everything that lets an agent write one is Milestone 10. The spec tags each one.
# id kind M
-- ------------------------------ ----------- --
1 gate.skill.metadata_only case 8
2 gate.skill.catalog_pinned case 8
3 gate.skill.no_tool_from_skill structural 8
4 gate.skill.untrusted_body case 8
5 gate.skill.revision_pinned case 8
6 gate.skill.missing_tool_loads case 8
7 gate.skill.catalog_capped case 8
8 gate.skill.validation_total property 8
9 gate.skill.body_cap case 8
10 gate.skill.mcp_read_only case 8
11 gate.skill.authoring_trust corpus 10
12 gate.skill.authoring_scope case 10
13 gate.skill.review_confined case 10
14 gate.skill.review_never_fatal case 10
15 gate.skill.provenance_complete structural 10
16 gate.skill.edit_conflict case 10
Gates 3 and 15 are structural because each is an assertion about the shape of the code rather than about a run: a walk that must find no path from the skills package to the tool registry's write path, and an insert path with no branch that can omit provenance. Gate 8 is the corpus's seventeenth property test. Gate 11 is a corpus gate because "an untrusted turn" is a family of turns rather than one, and a single case would prove only the one it wrote. The remaining twelve need a running session and are cases.
Knowledge documents, twelve gates¶
Twelve gates, all new, in a new fourteenth area, and all of them Milestone 9 — the milestone whose second half had none. Milestone 9 goes from fourteen registry entries to twenty-six, which makes it the largest single milestone in the census after Milestone 1.
# id kind M
-- ------------------------------ ----------- --
1 gate.knowledge.ingest_trust case 9
2 gate.knowledge.no_secrets case 9
3 gate.knowledge.chunk_stable property 9
4 gate.knowledge.visibility case 9
5 gate.knowledge.verbatim property 9
6 gate.knowledge.cite_resolves property 9
7 gate.knowledge.budget_yield case 9
8 gate.knowledge.supersession case 9
9 gate.knowledge.delete_cascades case 9
10 gate.knowledge.trace_complete case 9
11 gate.knowledge.no_belief_write case 9
12 gate.knowledge.corpus_recall corpus 9
Gate 3 is the corpus's eighteenth property test, gate 5 its nineteenth, and gate 6 its twentieth — determinism, verbatim rendering, and citation resolution are each a statement over every chunk rather than over one, and a single case would prove only the chunk it wrote. Gate 12 is a corpus gate because passage recall is a distribution over a labelled question set. The remaining eight need a running session and are cases. None is structural: every one of them is a statement about what a run retrieves rather than about the shape of the repository.
Web access, seven gates¶
Seven gates in the fifteenth area, all at Milestone 10. They turn the public-web acceptance contract into blocking checks over the two shared provider operations, capability routing, default-off composition, context advertisement, durable trust, failure normalization, and fetch confinement.
# id kind M
-- ------------------------------ ----------- --
1 gate.web.provider_contract case 10
2 gate.web.capability_routing case 10
3 gate.web.default_off case 10
4 gate.web.context_advertisement case 10
5 gate.web.invocation_trust case 10
6 gate.web.failure_boundary case 10
7 gate.web.fetch_confinement property 10
The first gate executes the complete shared search-and-fetch contract against both adapters. Gate 7 is a property gate because it covers a family of hostile destinations and response/output sizes; the other five require concrete composition or run outcomes.
Authenticated browser automation, ten gates¶
Ten gates in the sixteenth area, all at Milestone 10. The first seven make the implemented provider seam, isolation boundary, read path, approval path, revision binding, and uncertain-write behavior blocking. The final three keep profiles, authentication, and standing grants visibly incomplete until their security contracts execute.
# id kind M
-- -------------------------------- ----------- --
1 gate.browser.provider_contract case 10
2 gate.browser.default_off case 10
3 gate.browser.origin_isolation property 10
4 gate.browser.observation_trust case 10
5 gate.browser.action_authority case 10
6 gate.browser.revision_binding case 10
7 gate.browser.uncertain_write case 10
8 gate.browser.profile_lifecycle case 10
9 gate.browser.authentication property 10
10 gate.browser.standing_grant case 10
Origin isolation is a property over allowed and hostile URL/resource families; authentication is a property over secret classes and user-intervention states. The remaining eight require concrete provider, run, profile, or grant outcomes.
Scheduled runs, twenty-three gates¶
Twenty-three gates, all new, in the seventeenth area and all at Milestone 11. They cover the time, authority, atomicity, lifecycle, fairness, offline-result, contract, schema, migration, erasure, and isolation boundaries introduced by a scheduler rather than resting those guarantees on generic milestone checks.
# id kind M
-- -------------------------------- ----------- --
1 gate.schedule.not_early property 11
2 gate.schedule.materialize_once case 11
3 gate.schedule.materialize_atomic case 11
4 gate.schedule.civil_time property 11
5 gate.schedule.misfire_bounded case 11
6 gate.schedule.no_overlap case 11
7 gate.schedule.authority_fresh case 11
8 gate.schedule.scope_isolated case 11
9 gate.schedule.revision_pinned case 11
10 gate.schedule.lifecycle_linear property 11
11 gate.schedule.cancel_separate case 11
12 gate.schedule.run_bounded case 11
13 gate.schedule.priority_fair case 11
14 gate.schedule.offline_results case 11
15 gate.schedule.no_credentials corpus 11
16 gate.schedule.domain_invariants property 11
17 gate.schedule.repository_contract structural 11
18 gate.schedule.persistence_schema structural 11
19 gate.schedule.migration_clean case 11
20 gate.schedule.migration_stepwise case 11
21 gate.schedule.uow_atomic case 11
22 gate.schedule.erasure_audited case 11
23 gate.schedule.persistence_isolated case 11
Gates 1, 4, and 10 are properties because early firing, civil-time resolution, state-transition linearizability are claims over generated clocks, zones, and interleavings; gate 16 applies the same standard to domain construction. Gate 15 is a corpus because credential-shaped input is a family rather than one example. Gates 17 and 18 are structural because they inspect contract coverage and declared schema. The remaining sixteen are boundary cases over the application, PostgreSQL, queue, and API seams.
Notifications and devices, twenty gates¶
Twenty gates, all new, in the eighteenth and nineteenth areas and all at
Milestone 12. Six device gates cover registration identity, live-token
uniqueness, revocation, lifecycle audit, schema, and isolation; fourteen
notify gates cover enqueue atomicity, the closed trigger catalog,
deduplication, content-free payloads, single delivery, bounded retry,
staleness, token invalidation, the APNs adapter, port contracts, the offline
inbox, default-off confinement, and the migration pair.
# id kind M
-- ---------------------------------- ----------- --
1 gate.device.register_idempotent case 12
2 gate.device.token_unique case 12
3 gate.device.revoke_immediate case 12
4 gate.device.lifecycle_audited case 12
5 gate.device.persistence_schema structural 12
6 gate.device.persistence_isolated case 12
7 gate.notify.enqueue_atomic case 12
8 gate.notify.trigger_catalog case 12
9 gate.notify.dedupe property 12
10 gate.notify.content_free corpus 12
11 gate.notify.dispatch_once case 12
12 gate.notify.retry_bounded case 12
13 gate.notify.stale_suppressed case 12
14 gate.notify.token_revoked_on_410 case 12
15 gate.notify.apns_auth case 12
16 gate.notify.port_contracts structural 12
17 gate.notify.offline_inbox case 12
18 gate.notify.default_off case 12
19 gate.notify.migration_clean case 12
20 gate.notify.migration_stepwise case 12
Gate 9 is a property because repeated triggers are a family of interleavings, not one example; gate 10 is a corpus because secret-shaped and content-bearing inputs are a family; gates 5 and 16 are structural because they inspect declared schema and contract coverage. The remaining sixteen are boundary cases over the terminal writer, the scheduler, the dispatcher, the transport, the API, and PostgreSQL.
Subagents and delegation, twenty-one gates¶
Twenty-one gates, all new, in the twentieth area and all at Milestone 13. They cover the brief, atomic materialization, the dedicated session, the child-run suspension, subset tools and scopes, derived limits, additive usage, depth, fan-out, untrusted results, the single join, child failure, cancellation, prefix stability, the separate trace, artifact references, schema, migration, default-off, and the outcome evidence the gate for multi-agent work requires.
# id kind M
-- ----------------------------------------- ----------- --
1 gate.delegate.brief_schema case 13
2 gate.delegate.materialize_atomic case 13
3 gate.delegate.dedicated_session case 13
4 gate.delegate.parent_suspends case 13
5 gate.delegate.tools_subset case 13
6 gate.delegate.scopes_intersected case 13
7 gate.delegate.limits_derived property 13
8 gate.delegate.usage_additive case 13
9 gate.delegate.depth_one case 13
10 gate.delegate.fanout_capped case 13
11 gate.delegate.result_untrusted case 13
12 gate.delegate.join_once case 13
13 gate.delegate.child_failure_is_tool_error case 13
14 gate.delegate.cancel_propagates case 13
15 gate.delegate.prefix_stable case 13
16 gate.delegate.trace_separate case 13
17 gate.delegate.artifact_refs case 13
18 gate.delegate.persistence_schema structural 13
19 gate.delegate.migration_stepwise case 13
20 gate.delegate.default_off case 13
21 gate.delegate.changes_outcome case 13
Gate 7 is a property because limit derivation is a claim over generated parents and briefs; gate 18 is structural because it inspects declared schema. The remaining nineteen are boundary cases over the tool pipeline, the terminal writer, the queue, PostgreSQL, and the evaluation harness.
Inbound surfaces, twenty-one gates¶
Twenty-one gates, all new, in the twenty-first area and all at Milestone 14. They cover the default-deny before any run, the pairing ceremony and lockout, ordinary submission, inbound idempotency, ingress atomicity, the session key, input routing, revocation, the scope ceiling, the bot token, replies, approvals and questions, rate limits, default-off, transport confinement, schema, isolation, contracts, and the migration pair.
# id kind M
-- ----------------------------------------- ----------- --
1 gate.surface.unpaired_denied case 14
2 gate.surface.pairing_ceremony case 14
3 gate.surface.pairing_lockout case 14
4 gate.surface.paired_submits_ordinary_run case 14
5 gate.surface.inbound_idempotent case 14
6 gate.surface.ingest_atomic case 14
7 gate.surface.session_key_stable case 14
8 gate.surface.input_routing case 14
9 gate.surface.revocation_immediate case 14
10 gate.surface.scope_ceiling case 14
11 gate.surface.no_token_leak corpus 14
12 gate.surface.reply_chunked_redacted case 14
13 gate.surface.approval_roundtrip case 14
14 gate.surface.rate_limited case 14
15 gate.surface.default_off case 14
16 gate.surface.transport_confined structural 14
17 gate.surface.persistence_schema structural 14
18 gate.surface.persistence_isolated case 14
19 gate.surface.repository_contract structural 14
20 gate.surface.migration_clean case 14
21 gate.surface.migration_stepwise case 14
Gate 11 is a corpus because a token can leak through a family of surfaces; gates 16, 17, and 19 are structural because they inspect the transport's declared confinement, the schema, and contract coverage. The remaining seventeen are boundary cases over the ingress transaction, the submission path, the outbox, and PostgreSQL.
Operational hardening, sixteen gates¶
Sixteen gates, all new, in the twenty-second area and all at Milestone 15. They cover the declared backup set, the round trip, the restore rehearsal and its corruption detection, client-side encryption, retention, production refusal, the health-check signal list, alert deduplication and payload closure, the dead-database fallback, rollback promotion and schema-drift refusal, unit and sudoers reconciliation, the minimal public boundary, and the worker watchdog.
# id kind M
-- ---------------------------------------------- ----------- --
1 gate.ops.backup_set_complete structural 15
2 gate.ops.backup_roundtrip case 15
3 gate.ops.restore_rehearsal_passes case 15
4 gate.ops.restore_rehearsal_detects_corruption case 15
5 gate.ops.backup_encrypted_offhost case 15
6 gate.ops.backup_retention_policy property 15
7 gate.ops.rehearsal_never_touches_production case 15
8 gate.ops.healthcheck_signals case 15
9 gate.ops.alert_enqueued_deduped case 15
10 gate.ops.alert_payload_closed structural 15
11 gate.ops.db_down_fallback case 15
12 gate.ops.rollback_promotes_previous case 15
13 gate.ops.rollback_refuses_schema_drift case 15
14 gate.ops.units_and_sudoers_reconciled structural 15
15 gate.ops.public_boundary_minimal structural 15
16 gate.ops.worker_watchdog case 15
Gate 6 is a property because retention is a claim over generated listings; gates 1, 10, 14, and 15 are structural because they inspect a manifest, a schema, unit and sudoers files, and firewall and proxy declarations. The remaining eleven are boundary cases over the scripts, a throwaway database, the outbox, and the release tree.
Memory evaluation and lifecycle, twenty gates¶
Twenty gates, all new, in the existing memory area and all at Milestone
16. Nine cover the benchmark — the corpus shape, reproducibility, the two
baseline comparisons, protected content, supersession currency, live evidence
publication, the cost ceiling, and the external dataset adapters — and ten
cover the lifecycle the two older memory specifications describe and the code
lacks: the profile document, trace retention, decay, usage feedback, the
recall delta, correction lines, established facts, conflict surfacing, the
resolver's ordering, and re-derivation. The twentieth versions the expanded
provider-formation corpus coverage independently of Milestone 10's completed
historical gate.
# id kind M
-- ---------------------------------------------- ----------- --
1 gate.memory.bench_corpus_shape structural 16
2 gate.memory.bench_reproducible property 16
3 gate.memory.bench_no_regression case 16
4 gate.memory.bench_baseline_current case 16
5 gate.memory.bench_protected_never_rendered case 16
6 gate.memory.bench_supersession_current case 16
7 gate.memory.bench_evidence_publish case 16
8 gate.memory.bench_cost_ceiling case 16
9 gate.memory.bench_external_adapters structural 16
10 gate.memory.profiles_wired structural 16
11 gate.memory.trace_retention case 16
12 gate.memory.decay_lifecycle case 16
13 gate.memory.usage_feedback case 16
14 gate.memory.recall_delta case 16
15 gate.memory.correction_lines case 16
16 gate.memory.established_facts_form case 16
17 gate.memory.conflict_surfaced case 16
18 gate.memory.authority_recency property 16
19 gate.memory.rederive_opt_in case 16
20 gate.memory.provider_positive_coverage_v2 case 16
Gates 2 and 18 are properties because reproducibility and the resolver's ordering are claims over generated inputs rather than over one scenario; gates 1, 9, and 10 are structural because they inspect a checked-in document, a set of adapters and what the repository does not contain, and a configuration document against its models. The remaining fifteen are boundary cases over the benchmark run, the belief store, the recall trace, the context builder, the command line, and the versioned provider-evidence corpus.
Memory read API and browser, ten gates¶
Ten gates, all new, in the same memory area and all at Milestone 17. Seven
are statements about what the two read routes may return — the required
ceiling, the strict ceiling filter, principal isolation, keyset paging under
concurrent writes, the filters, the exposure list, and the closed error
vocabulary — and three are statements about the surface itself: that every
route is a GET declaring exactly memory.read, that the router is absent
without its flag, and that both store adapters browse identically.
# id kind M
-- ---------------------------------------------- ----------- --
1 gate.memory.read_api_ceiling_required case 17
2 gate.memory.read_api_ceiling_filter property 17
3 gate.memory.read_api_principal_isolation case 17
4 gate.memory.read_api_pagination case 17
5 gate.memory.read_api_filters case 17
6 gate.memory.read_api_read_only structural 17
7 gate.memory.read_api_flag_absent case 17
8 gate.memory.browse_contract_parity structural 17
9 gate.memory.read_api_view_projection structural 17
10 gate.memory.read_api_error_vocabulary case 17
Gate 2 is a property because the ceiling claim is over generated pairs of belief sensitivity and request ceiling rather than over one arrangement of rows; gates 6, 8, and 9 are structural because they inspect the router's declared methods and scopes, the adapters against one contract suite, and a serialized model against its exposure list. The remaining six are boundary cases over the two routes.
Email integration, seventeen gates¶
Seventeen gates, all in the email area and all at Milestone 18.
Five are statements about the servers themselves — the package boundary, the
shared contract, the rosters, the declared classifications, and the failure
taxonomy — five are statements about credentials and configuration — the
constructed environment, token confinement, the default-off flag, scope
confinement, and the bootstrap ceremony — and three are statements about
policy and composition in use: the read-allows-write-approves split, the
untrusted-origin send, and the monitoring recipe. Four further gates cover
the owner-authorized multi-account extension: named composition, per-account
credential isolation, account-bound bootstrap, and bounded manifest parsing.
# id kind M
-- ---------------------------------------------- ----------- --
1 gate.email.package_isolation structural 18
2 gate.email.contract_parity case 18
3 gate.email.roster_confinement structural 18
4 gate.email.classification case 18
5 gate.email.read_allow_write_approve case 18
6 gate.email.untrusted_origin case 18
7 gate.email.credential_confinement property 18
8 gate.email.token_confinement case 18
9 gate.email.default_off case 18
10 gate.email.scope_confinement case 18
11 gate.email.bootstrap_consent case 18
12 gate.email.failure_taxonomy case 18
13 gate.email.monitoring_recipe case 18
14 gate.email.named_account_composition case 18
15 gate.email.account_credential_isolation property 18
16 gate.email.account_bound_bootstrap case 18
17 gate.email.multi_account_configuration_bounds case 18
Gates 7 and 15 are properties because their credential claims are over generated server configurations rather than one arrangement; gates 1 and 3 are structural because they inspect the import graph and the advertised rosters rather than a behavior. The remaining thirteen are boundary cases over the server triplets, the policy engine, the composition root, the manifest, and the bootstrap command.
Conversational schedule creation, five gates¶
Five gates extend the existing schedule area at Milestone 19. They cover the
narrow model-callable bridge from a reminder request to the already governed
schedule service: composition and classification, successful approved
creation, exact-scope denial, invalid-time rejection, and idempotent replay.
# id kind M
-- ---------------------------------------------- ----------- --
24 gate.schedule.model_create_contract structural 19
25 gate.schedule.model_create_happy_path case 19
26 gate.schedule.model_create_authorization case 19
27 gate.schedule.model_create_validation case 19
28 gate.schedule.model_create_retry case 19
Gate 24 is structural because it inspects the registered tool contract and its feature-gated composition. The remaining four are boundary cases over the tool pipeline and the schedule application service.
Calendar recurrence and conversational schedules, six gates¶
Six gates extend the existing schedule area at Milestone 20. They cover the
new calendar values and algorithms, bounded downtime behavior, the existing
HTTP control plane's widened union, and approval-gated conversational creation
and replay for every recurring kind.
# id kind M
-- --------------------------------------------------- ----------- --
29 gate.schedule.calendar_values property 20
30 gate.schedule.calendar_recurrence property 20
31 gate.schedule.calendar_misfire_bounded case 20
32 gate.schedule.calendar_http_roundtrip case 20
33 gate.schedule.model_create_recurring case 20
34 gate.schedule.model_create_recurring_validation case 20
Gates 29 and 30 are properties because canonical calendar values and civil-time resolution range over generated selectors, dates, and zones. The remaining four are boundary cases over materialization, HTTP, and the ordinary tool pipeline.
Conversational schedule lifecycle, twelve gates¶
Twelve gates extend the existing schedule area at Milestone 23. They cover
the feature-gated tool contracts, bounded summary discovery, approved
pause/resume and cancellation, exact scopes, fail-closed identity and revision
validation, state-idempotent retry, and approved content/cadence patching that
preserves hidden execution authority and replays at most once.
# id kind M
-- --------------------------------------------------- ----------- --
35 gate.schedule.model_lifecycle_contract structural 23
36 gate.schedule.model_lifecycle_discovery case 23
37 gate.schedule.model_pause_resume case 23
38 gate.schedule.model_cancel case 23
39 gate.schedule.model_lifecycle_authorization case 23
40 gate.schedule.model_lifecycle_validation case 23
41 gate.schedule.model_lifecycle_retry case 23
42 gate.schedule.model_update_contract structural 23
43 gate.schedule.model_update_happy_path case 23
44 gate.schedule.model_update_preserves_authority case 23
45 gate.schedule.model_update_validation case 23
46 gate.schedule.model_update_retry case 23
Gates 35 and 42 are structural because they inspect the registered and advertised tool contracts and the closed update schema. The remaining ten are boundary cases over the ordinary tool pipeline and existing schedule application service.
Adaptive memory distillation, thirty-one gates¶
Thirty-one gates extend the existing memory area at Milestone 21. Six cover
the three-stage provider pipeline and its persisted episode input, seven cover
high-recall grounded formation and accounting, seven cover the separation of
evidence, use, forgetting, promotion, and rendered uncertainty, four cover
corrections, migration, corpus coverage, comparative evidence, and activation,
five cover the honesty of that evidence: a scorer that cannot be fooled, a
populated evaluation store, a fallback that never fabricates, verified coverage
dispositions, and bounded segmentation, and two cover the repaired
provider-assisted control: a budget that never starves and an explicit policy
precedence.
# id kind M
-- ---------------------------------------------- ----------- --
1 gate.memory.distill_versions_frozen structural 21
2 gate.memory.episode_integration case 21
3 gate.memory.episode_repository_parity structural 21
4 gate.memory.anticipation_blinded property 21
5 gate.memory.prediction_error_calls case 21
6 gate.memory.distill_fallback case 21
7 gate.memory.direct_high_recall case 21
8 gate.memory.hypothesis_high_recall case 21
9 gate.memory.compound_recall case 21
10 gate.memory.candidate_schema structural 21
11 gate.memory.predictability_attributed case 21
12 gate.memory.source_grounding property 21
13 gate.memory.formation_reason_telemetry case 21
14 gate.memory.evidence_clock case 21
15 gate.memory.usage_clock case 21
16 gate.memory.hypothesis_retirement case 21
17 gate.memory.ongoing_retirement case 21
18 gate.memory.evidence_promotion case 21
19 gate.memory.uncertainty_rendered case 21
20 gate.memory.correction_durable_v3 case 21
21 gate.memory.schema_backfill structural 21
22 gate.memory.formation_corpus_v3 structural 21
23 gate.memory.comparative_evidence case 21
24 gate.memory.distill_activation_bound property 21
25 gate.memory.scorer_symmetric case 21
26 gate.memory.formation_corpus_seeded structural 21
27 gate.memory.fallback_never_fabricates case 21
28 gate.memory.coverage_dispositions_verified case 21
29 gate.memory.distill_segmentation case 21
30 gate.memory.provider_budget_repaired case 21
31 gate.memory.provider_policy_precedence case 21
Gates 4, 12, and 24 are properties because causal blinding, typed source admission and attribution, and exact tuple activation quantify over generated prefixes, event identities, event shapes, and tuple differences. Gates 1, 3, 10, 21, 22, and 26 are structural because they inspect frozen controls, both repositories against one contract, closed schemas, migrations, and the checked-in corpus and its seed pool. The remaining twenty-two are boundary cases over provider orchestration, formation, lifecycle, retrieval, evidence publication, scoring, fabrication, coverage verification, and segmentation.
Persona surface, fourteen gates¶
Fourteen gates open a new persona area at Milestone 22. Four cover the
prefix row — stability, the cap, trust labeling, and revision pinning — two
cover content safety at write and load, five cover curated promotion —
human-only writes, closed eligibility, durable decline, linkage, and snapshot
de-duplication — and three cover the surfaces: exact scopes with the memory
router still read-only, the revision precondition, and principal scoping.
# id kind M
-- ---------------------------------------------- ----------- --
1 gate.persona.prefix_row_stable case 22
2 gate.persona.budget_capped case 22
3 gate.persona.trust_labeled case 22
4 gate.persona.revision_pinned case 22
5 gate.persona.secret_refused case 22
6 gate.persona.injection_scanned case 22
7 gate.persona.promotion_requires_affirmation case 22
8 gate.persona.nomination_eligibility case 22
9 gate.persona.decline_durable case 22
10 gate.persona.affirmed_linked case 22
11 gate.persona.snapshot_dedup case 22
12 gate.persona.routes_exact_scope structural 22
13 gate.persona.revision_precondition case 22
14 gate.persona.principal_scoped case 22
Gate 12 is structural because it inspects the mounted routers rather than a behavior: the exact scope on every persona route and the continued GET-only shape of the memory router are properties of the application object. The remaining thirteen are boundary cases over the prefix, the write surfaces, and the promotion lifecycle.
SMS through the owner's iPhone, twelve gates¶
Twelve gates extend the existing device area at Milestone 24. They cover
the first slice of the Section 29 device channel: capability-derived
registration, the invocation lifecycle and its idempotency, the owner-tap
send boundary, ingest idempotency and untrusted triage routing, and the
confinement set — presence revalidation, the outbound secret scan, log
hygiene, and default-off.
# id kind M
-- ------------------------------------ ----------- --
1 gate.device.capability_registration structural 24
2 gate.device.invocation_idempotent case 24
3 gate.device.foreign_device_denied case 24
4 gate.device.no_send_without_result property 24
5 gate.device.offline_outcome case 24
6 gate.device.untrusted_output structural 24
7 gate.device.presence_revalidated case 24
8 gate.device.outbound_secret_scan case 24
9 gate.device.ingest_idempotent case 24
10 gate.device.untrusted_triage_routing case 24
11 gate.device.no_body_in_logs case 24
12 gate.device.default_off case 24
Gates 1 and 6 are structural because they inspect the registered tool
contract and the forced output trust. Gate 4 is a property over the
invocation state machine: no path reaches sent server-side. The
remaining nine are boundary cases over the invocation routes, the ingest
route, and the triage seeding.
The WhatsApp business surface, twelve gates¶
Twelve gates open the whatsapp area at Milestone 25. They cover the
signed webhook ingress, the handshake, string-id receipt idempotency, the
inherited surface guarantees — unpaired denial, the scope ceiling,
chunked and redacted replies, tenant isolation — and the confinement set:
token families, the fixed Meta origin, the loopback bind, the
twenty-four-hour template rule, and default-off.
# id kind M
-- ------------------------------------ ----------- --
1 gate.whatsapp.signature_required case 25
2 gate.whatsapp.handshake_confined case 25
3 gate.whatsapp.receipt_idempotent case 25
4 gate.whatsapp.unpaired_denied case 25
5 gate.whatsapp.token_confinement case 25
6 gate.whatsapp.transport_confined structural 25
7 gate.whatsapp.template_outside_window case 25
8 gate.whatsapp.reply_chunked_redacted case 25
9 gate.whatsapp.scope_ceiling case 25
10 gate.whatsapp.loopback_bind structural 25
11 gate.whatsapp.persistence_isolated case 25
12 gate.whatsapp.default_off case 25
Gates 6 and 10 are structural — the egress graph and the bind walk. The remaining ten are boundary cases over the listener, the adapter, and the surface tables.
This document, seven gates¶
The seven gates stated under Hard gates below are this document's own. Their identifiers are listed here so that the table covers every registry entry and not merely every gate this document inherited.
# id kind M
-- ------------------------------ ----------- --
1 gate.harness.token_present structural 0
2 gate.harness.map_bijection structural 0
3 gate.harness.alias_arithmetic structural 0
4 gate.harness.anchor_resolves structural 0
5 gate.harness.id_grammar structural 0
6 gate.harness.census_derived structural 0
7 gate.harness.milestone_order structural 1
They take the harness area because the harness owns the registry and
the docs check that reads it. This document declares them rather than
the harness because every one of them is a check over the scheduling
record, and the scheduling record is what this document is. Gate 7 is
Milestone 1 rather than Milestone 0 because the build-sequence table it
reads is only meaningful once there are build steps to order.
Client modes and email experience, thirty-two gates¶
email-experience.md declares thirty-two further gates in
the existing email area, all at Milestone 26 under ADR-0092. They preserve
Milestone 18 requirements and the verified sequential ceiling.
# id kind M
1 gate.email.experience_shared_mode_state case 26
2 gate.email.experience_native_layouts case 26
3 gate.email.experience_scope_and_flag case 26
4 gate.email.experience_account_identity case 26
5 gate.email.experience_foreground_admission case 26
6 gate.email.experience_sync_contract case 26
7 gate.email.experience_sync_recovery case 26
8 gate.email.experience_history_progress case 26
9 gate.email.experience_governed_tasks case 26
10 gate.email.experience_aggregate_cost case 26
11 gate.email.experience_feedback_scope case 26
12 gate.email.experience_feedback_replay case 26
13 gate.email.experience_assessment_invalidation case 26
14 gate.email.experience_priority_quality case 26
15 gate.email.experience_relationship_evidence case 26
16 gate.email.experience_style_lineage case 26
17 gate.email.experience_style_quality case 26
18 gate.email.experience_draft_relevance case 26
19 gate.email.experience_draft_revisions case 26
20 gate.email.experience_send_approval case 26
21 gate.email.experience_send_claim case 26
22 gate.email.experience_send_uncertainty case 26
23 gate.email.experience_reply_headers case 26
24 gate.email.experience_semantic_grounding case 26
25 gate.email.experience_semantic_authority case 26
26 gate.email.experience_semantic_lifecycle case 26
27 gate.email.experience_shared_recall case 26
28 gate.email.experience_source_erasure case 26
29 gate.email.experience_retention case 26
30 gate.email.experience_privacy case 26
31 gate.email.experience_api_boundaries case 26
32 gate.email.experience_release_evidence case 26
Bland calling¶
bland-calling.md declares fourteen Milestone 27 gates.
1 gate.call.default_off case 27
2 gate.call.tool_separation case 27
3 gate.call.approval_binding case 27
4 gate.call.dispatch_recovery case 27
5 gate.call.cancellation case 27
6 gate.call.provider_boundary case 27
7 gate.call.public_isolation case 27
8 gate.call.callback_authentication case 27
9 gate.call.durable_receipts case 27
10 gate.call.repository_isolation case 27
11 gate.call.retention_erasure case 27
12 gate.call.notifications case 27
13 gate.call.admission_bounds case 27
14 gate.call.live_release case 27
People and relationship memory¶
people-and-relationships.md declares 36 Milestone 28 gates.
1 gate.people.identity_precision case 28
2 gate.people.identifier_linking case 28
3 gate.people.identity_repair case 28
4 gate.people.repository_isolation case 28
5 gate.people.person_formation case 28
6 gate.people.speaker_attribution case 28
7 gate.people.source_grounding case 28
8 gate.people.durable_corrections case 28
9 gate.people.evidence_deduplication case 28
10 gate.people.temporal_history case 28
11 gate.people.lifecycle case 28
12 gate.people.interaction_roles case 28
13 gate.people.commitments case 28
14 gate.people.history_pagination case 28
15 gate.people.ambiguity case 28
16 gate.people.shared_retrieval case 28
17 gate.people.bounded_relationships case 28
18 gate.people.memory_trust case 28
19 gate.people.context_budget case 28
20 gate.people.trace_faithfulness case 28
21 gate.people.api_boundaries case 28
22 gate.people.tool_schemas case 28
23 gate.people.governed_writes case 28
24 gate.people.default_available case 28
25 gate.people.erasure case 28
26 gate.people.egress case 28
27 gate.people.email_history_bound case 28
28 gate.people.import_jobs case 28
29 gate.people.migration_compatibility case 28
30 gate.people.email_bridge case 28
31 gate.people.native_workflows case 28
32 gate.people.native_states case 28
33 gate.people.formation_quality case 28
34 gate.people.retrieval_quality case 28
35 gate.people.performance case 28
36 gate.people.release_evidence case 28
Chat thread folders¶
thread-folders.md declares thirteen Milestone 29 gates. The thirteenth arrived with ADR-0110's judgment matcher.
1 gate.folder.schema_additive case 29
2 gate.folder.crud_invariants case 29
3 gate.folder.move_semantics case 29
4 gate.folder.proposal_eligibility case 29
5 gate.folder.bounded_open_set case 29
6 gate.folder.decline_durable case 29
7 gate.folder.withdrawal case 29
8 gate.folder.grounded_grouping property 29
9 gate.folder.accept_atomic case 29
10 gate.folder.routes_exact_scope structural 29
11 gate.folder.content_free case 29
12 gate.folder.native_degradation case 29
13 gate.folder.judgment_matching property 29
Typed judgment¶
typed-judgment.md declares four Milestone 29 gates, admitted with the port by ADR-0110.
1 gate.judgment.fixed_egress case 29
2 gate.judgment.default_off case 29
3 gate.judgment.typed_failure case 29
4 gate.judgment.priced_contract property 29
Email unsubscribe assistance¶
email-unsubscribe.md declares twenty-three Milestone 31 gates in the existing email area.
1 gate.email.unsubscribe_read_contract case 31
2 gate.email.unsubscribe_eligibility property 31
3 gate.email.unsubscribe_server_derived_destination structural 31
4 gate.email.unsubscribe_fixed_request case 31
5 gate.email.unsubscribe_public_https_egress case 31
6 gate.email.unsubscribe_approval_floor case 31
7 gate.email.unsubscribe_gesture_consent case 31
8 gate.email.unsubscribe_batch_approval case 31
9 gate.email.unsubscribe_idempotent_recovery case 31
10 gate.email.unsubscribe_mailto_closed case 31
11 gate.email.unsubscribe_label_actions case 31
12 gate.email.unsubscribe_census_projection property 31
13 gate.email.unsubscribe_durable_decisions case 31
14 gate.email.unsubscribe_outcome_honesty case 31
15 gate.email.unsubscribe_routes_scope_and_flag structural 31
16 gate.email.unsubscribe_chat_tools case 31
17 gate.email.unsubscribe_privacy case 31
18 gate.email.unsubscribe_persistence_parity case 31
19 gate.email.unsubscribe_native_experience case 31
20 gate.email.spam_flag case 31
21 gate.email.spam_sender_check property 31
22 gate.email.spam_thread_gesture case 31
23 gate.email.unsubscribe_release_evidence case 31
memory-reconsolidation.md declares twenty-four Milestone 32 gates in the memory area.
1 gate.memory.recon_corpus_frozen structural 32
2 gate.memory.recon_scorer_false_merges case 32
3 gate.memory.recon_repository_parity structural 32
4 gate.memory.recon_lease_recovery case 32
5 gate.memory.recon_fair_inventory property 32
6 gate.memory.recon_bounded_groups case 32
7 gate.memory.recon_budget_admission case 32
8 gate.memory.recon_provider_contract case 32
9 gate.memory.recon_exact_merge case 32
10 gate.memory.recon_summary_fidelity case 32
11 gate.memory.recon_connection_grounding case 32
12 gate.memory.recon_dependency_fence case 32
13 gate.memory.recon_source_erasure case 32
14 gate.memory.recon_undo_durable case 32
15 gate.memory.recon_evidence_clock case 32
16 gate.memory.recon_trust_boundary case 32
17 gate.memory.recon_recall_visibility case 32
18 gate.memory.recon_snapshot_delta case 32
19 gate.memory.recon_scoped_surfaces case 32
20 gate.memory.recon_native_journeys case 32
21 gate.memory.recon_comparative_quality case 32
22 gate.memory.recon_activation_bound property 32
23 gate.memory.recon_compatibility case 32
24 gate.memory.recon_release_evidence case 32
general-memory-recall.md declares twelve Milestone 33 gates, authorized on 2026-10-11 under ADR-0178.
1 gate.memory.general_corpus_independence structural 33
2 gate.memory.general_relevance_before_limits case 33
3 gate.memory.general_visibility_parity case 33
4 gate.memory.general_shared_recall case 33
5 gate.memory.general_query_planning_bounds case 33
6 gate.memory.general_semantic_index_lifecycle case 33
7 gate.memory.general_grounded_recovery case 33
8 gate.memory.general_stage_attribution case 33
9 gate.memory.general_comparative_quality case 33
10 gate.memory.general_operational_budget case 33
11 gate.memory.general_frozen_compatibility structural 33
12 gate.memory.general_activation_evidence case 33
The census¶
What each milestone must turn green, counting registry entries and not alias restatements.
milestone new gates cumulative the earliest of them
--------- --------- ---------- -----------------------------
0 13 13 the import boundary, the secret
scanner, ten checks over documents,
and the migration graph
1 28 41 the vertical slice, both
builtins, deterministic build
2 16 57 persistence, fencing, resume, the
ORM boundary, the migration
round trips
3 15 72 five adapters, the profile schema,
the closed metadata key set, the
redacted export
4 22 94 policy, approvals, corpora, the
four remaining builtins, the
scope vocabulary
5 11 105 the API surface, the stream,
cancellation keeps effects
6 11 116 isolation, egress, artifacts
7 7 123 budgeting and compaction
8 17 140 the MCP adapter, authentication,
the pinned catalog, the metadata
boundary, package validation
9 26 166 formation, retrieval, ingestion,
and the corpus
10 38 204 the authoring loop, background review,
governed memory maturation, public-web
access, and browser automation
11 23 227 recurrence, occurrence atomicity,
authority refresh, offline results,
contracts, migration, erasure, isolation
12 20 247 device identity, the outbox, content-
free payloads, dispatch, the APNs
transport, the offline inbox
13 21 268 the brief, materialization, the
child-run suspension and join, derived
limits, the ledger, the evidence
14 21 289 pairing, the session key, ingress
atomicity, the scope ceiling, replies,
the surface role's confinement
15 16 305 the declared backup set, the
rehearsal, alerts, rollback, the
public boundary, the watchdog
16 20 325 the benchmark corpus, the baseline,
live evidence, decay, usage feedback,
the recall delta, conflicts, expanded
provider-formation coverage
17 10 335 the required ceiling, the ceiling
filter, principal isolation, keyset
paging, the read-only router, the
exposure list
18 17 352 the package boundary, the server
contract, honest classification,
credential and token confinement,
the bootstrap ceremony, named-account
isolation, the monitoring recipe
19 5 357 the model-callable schedule contract,
approval, exact-scope authorization,
time validation, idempotent replay
20 6 363 monthly and yearly calendar rules,
bounded catch-up, HTTP union parity,
recurring conversational creation
21 31 394 integrated episodes, causal anticipation,
high-recall direct and hypothesis formation,
evidence-based forgetting and activation,
honest scoring, seeded evaluation, fallback
restraint, verified coverage, segmentation,
the repaired provider control, attributed
communication sources
22 14 408 the persona row, its cap and pinning,
human-only promotion, durable decline,
snapshot de-duplication, exact scopes
23 12 420 summary-only schedule discovery,
approved lifecycle and definition mutation,
exact scopes, conflict handling,
idempotent retry
24 12 432 capability registration, the
invocation lifecycle, the owner-tap
send boundary, ingest idempotency,
untrusted triage routing
25 12 444 the signed webhook ingress, the
handshake, string-id idempotency,
the template window, the loopback
bind, inherited surface guarantees
26 32 476 shared client modes, active email sync,
feedback, style, drafts, approved sends,
shared semantic memory and lifecycle
27 14 490 Bland calling and public correspondence intake
28 36 526 People identity, temporal relationships, history and governed recall
29 17 543 chat thread folders, owner-resolved grouping proposals, grounded grouping,
the typed-judgment port and judgment folder matching
30 5 548 restrictive-only advisory approval through the judgment port
31 23 571 bulk-sender census, authenticated one-click unsubscribe, public-HTTPS egress, gesture consent,
suspected-spam flag and thread Report spam
32 24 595 memory reconsolidation: contracts, lineage, recovery, evaluation and owner controls
33 12 607 general recall: candidate relevance, semantic search, evidence use and comparative activation
Two facts fall out of the table and both are worth stating rather than leaving for someone to notice.
- No milestone with work in it adds zero gates. Milestones 6, 8, and 10 were the three exceptions, each resting entirely on its own section's criteria in the engineering plan. sandbox-isolation.md gave Milestone 6 eleven, and skills.md gave Milestone 8 ten and Milestone 10 six. The memory-formation specification later gave Milestone 10 fifteen more, for twenty-one total. That is what milestones that add a new trust boundary, a new context class, and new write paths should carry. Milestone 8's MCP half was the last to be covered: it contributed corpus members to gates 2 and 5 of the tool system and nothing of its own, which reads as the right shape for a milestone that widens an existing surface until you notice it leaves build step 9 unobserved. It now carries seven — six in the tool system and one in the harness — and they are the ones that say the widened surface is still the same surface.
- Forty-one of six hundred and seven gates are green before Milestone 2. Less than a fifth of the plan's stated invariants are checkable against the in-memory slice, and thirteen of them against a repository with no agent in it at all. That is the number that makes the in-memory tier worth building as real adapters rather than as test doubles.
The cumulative column reaches six hundred and seven, which is every
registry entry, at Milestone 33. Six of Milestone 10's gates are
gate.skill.*, fifteen are gate.memory.*, seven are gate.web.*, ten are
gate.browser.*, all twenty-three Milestone 11 gates are gate.schedule.*,
Milestone 12's twenty are six gate.device.* and fourteen gate.notify.*,
Milestone 13's twenty-one are gate.delegate.*, Milestone 14's twenty-one are
gate.surface.*, Milestone 15's sixteen are gate.ops.*, Milestone
16's twenty and Milestone 17's ten are gate.memory.* again, in the area
those specs already shared, Milestone 18's seventeen are gate.email.* in
an area of their own, Milestone 19's five return to the existing
gate.schedule.* area, Milestone 20 adds six more there, Milestone 21
adds thirty-one more to gate.memory.*, and Milestone 22's fourteen are
gate.persona.* in an area of their own; Milestone 23 adds twelve more to
gate.schedule.*, Milestone 24's twelve return to the existing
gate.device.* area, and Milestone 25's twelve open a gate.whatsapp.*
area of their own. Milestone 26 adds thirty-two gate.email.experience_*
entries to the existing email area. Milestone 27 adds fourteen gate.call.* entries,
and Milestone 28 adds thirty-six gate.people.* entries. Milestone 29 adds thirteen
gate.folder.* entries and four gate.judgment.* entries, and Milestone 30
returns to the gate.policy.* area with five. Milestone 31 adds twenty
gate.email.unsubscribe_* and three gate.email.spam_* entries to the email
area. Milestone 32 adds twenty-four
gate.memory.recon_* entries. Milestone 33 adds twelve gate.memory.general_*
entries. Every authorized milestone now has a specification
that declares its gates; the roadmap's items add none until the owner
authorizes one and a specification lands for it. Routing remains deferred and
adds none.
Build-sequence milestones¶
Six specs left their build sequences untagged. Five are single- milestone documents where the tag is the section's own milestone; the sixth is context-engine, whose step 1 moves to Milestone 1 with its gate.
spec steps assignment
------------------------- ----- ----------------------------
context-engine 7 step 1 M1, steps 2-7 M7
event-log-and-persistence 9 all M2, export step M3
memory-formation 6 all M9
memory-retrieval 7 all M9
knowledge-documents 7 all M9
model-gateway 14 all M3
Three specs already tag their build sequences and are unchanged:
evaluation-harness.md per step, policy-and-approvals.md with a
trailing rule, tool-system.md with a trailing rule.
Tool-system build steps 3 and 4 without a database¶
Build step 3 is "Persistence, steps 8, 9, and 13. The schema additions, the idempotency key, dedup on insert, the claim, the terminal write." Steps 1 through 5 are Milestone 1. The engineering plan says "Do not implement PostgreSQL persistence … until the in-memory vertical slice is complete", and Section 8.4's idempotency is a Milestone 2 implement item. Read together those say a Milestone 1 step must write schema that Milestone 1 forbids.
The two readings separate the same way ADR-0024 separated an event repository from event storage: one port, two adapters.
- The port and its semantics are Milestone 1. The idempotency
key's composition, the four terminal states a row can hold, the
rule that a duplicate key returns the first result rather than
executing again, the claim's meaning, and the terminal write's
exactly-once obligation are all statements about
ToolInvocationRepository, and all of them are asserted by the contract suite that both adapters run. - The DDL is Milestone 2. "The schema additions" names tables and a unique index. Those arrive with the rest of the schema, in the same migration, under the same review.
- The in-memory adapter satisfies the same contract suite and declares which capability groups it does not satisfy, per ADR-0024's checked-in table. It declares one gap: concurrent dedup. A dictionary keyed by the idempotency key gives correct single-process behaviour and cannot tell the truth about two processes racing on an index.
- Therefore gate 8 is Milestone 2 and the Milestone 1 obligation
is the single-process half, which the contract suite asserts. This
is the same shape as the absent in-memory
RunQueue: the parts a simulation would lie about are named rather than simulated. - Step 4's "This is where Milestone 1's builtins become real" stands unchanged. Execution, timeouts, the effect watermark, output limits, and the recovery table are all Milestone 1. What Milestone 2 adds is the recovery test — gate 7 — because recovering requires having survived.
Cancellation at Milestone 1¶
runtime-loop.md defines CancellationToken as a Protocol with
reason, raise_if_cancelled, and wait, and tabulates six
observation points. It assigns "CancellationToken, points 1-3" to
Milestone 1. Points 1, 2, and 3 are the loop's own: top of the loop,
before each model attempt, after the model stream closes.
What the assignment does not say is what sets the token at Milestone 1.
All three writers it names — the cancellation poller, the deadline
timer, and the heartbeat supervisor — live in a supervisor task that
reads runs.cancel_requested_at in the same query that refreshes the
lease. There is no lease at Milestone 1, no supervisor, and no queue.
Read literally, Milestone 1 ships a token nothing can set.
The three CancelReason values do not have the same dependencies, and
separating them resolves it.
reason needs milestone
--------- ----------------------------- ---------
DEADLINE Clock, run.deadline_at 1
FENCED lease, lease_epoch 2
REQUESTED cancel_requested_at or a 2 (poll)
process signal 5 (endpoint)
DEADLINEis Milestone 1 and needs nothing new.Clockis a Milestone 1 port andruns.deadline_atis a Milestone 1 column. The Milestone 1 token evaluates the deadline lazily insideraise_if_cancelledrather than being set by a timer, which is what makes it work without a supervisor: the loop asks, at each of points 1 through 3, whether the deadline has passed.- The Milestone 1 token has one more writer, and it is the
process. The CLI installs a
SIGINThandler that callstoken.cancel(CancelReason.REQUESTED). This is what makesCtrl-Cduringagent runproduce aCANCELLEDrun with a terminal event rather than a traceback and a half-written row, and it is the only cancellation an operator can issue at Milestone 1. wait()is on the Protocol from the first commit and returns a future that Milestone 1 never completes except through those two paths. The sandbox adapter that selects on it does not exist until Milestone 6, and the method exists earlier so that the object handed toToolExecutionContextis the same object throughout.- The effects rule holds at Milestone 1 unchanged. A
cancellation observed after
effect_sent_atis set does not abandon the call. At Milestone 1 the only tools aremath.calculateandsystem.current_time, neither of which sets a watermark, so the rule is vacuously satisfied and its test is gate 12 at Milestone 5. It is stated at Milestone 1 anyway, because the code path that would violate it is written at Milestone 1. - Gate 12 stays at Milestone 5. It asserts that no case produces a cancelled run with a set watermark, and no case can produce one until a tool sets one.
This makes the split three-way rather than two-way, and the third part
is the one the milestone table already named without saying what drove
it. Recorded as a question: if the intent was that no cancellation at
all ships before Milestone 5, the SIGINT handler is the piece to drop
and points 1 through 3 become dead observation sites for four
milestones.
What changes in each spec¶
Mechanical, and listed so the diff is reviewable as a whole.
spec heading form tokens metrics
------------------------- -------- ------ ------ -------
builtin-tools -- -- 9 --
context-engine rename bullet 5 split
evaluation-harness -- -- 10 --
event-log-and-persistence rename bullet 7 split
memory-formation rename bullet 5 split
memory-retrieval rename bullet 9 split
model-gateway -- -- 10 --
policy-and-approvals rename -- 10 split
runtime-loop -- -- 0 --
tool-system -- -- 10 --
tokens counts the **M<n>.** suffixes added; runtime-loop shows
zero because it already has fourteen. metrics marks the specs whose
tracked metrics move to a sibling ## Tracked metrics section.
Hard gates¶
- Every gate in every spec carries a milestone token. The docs
check parses each
## Hard gatessection and fails on a numbered item with no trailing**M<number>.**. M0. - Every gate identifier in this document appears exactly once in
evals/gates/*.yaml, and every registry entry appears here, compared as sets and not as counts. M0. - Every alias is declared. A spec's gate count minus its declared alias count equals the number of registry entries citing that spec's anchor. M0.
- Every
specfield resolves. Each registry entry'sdocs/plan/<file>.md#hard-gatesanchor exists in the built site. M0. - Every gate identifier matches the grammar and its area is one of the twenty-three. M0.
- The census is derived, not written. A test computes the per-milestone counts from the registry and compares them against the table in this document, so the table cannot drift. M0.
- No gate is registered at a milestone later than the build step it observes, for the specs whose build sequences carry step numbers, asserted against the build-sequence table above. M1.
Conflicts this document resolves¶
- The registry requires
milestone; nine of ten specs do not supply it per gate. Resolved by supplying it for all eighty-nine, deriving each from the build sequence or section milestone the spec already states. - Registry rule 1 requires a parseable gate section; three headings and two forms exist. Resolved by one heading, one form, and one suffix, with the registry's own example anchors updated.
- Two specs interleave gates and metrics. Resolved by the
specs' own words, moving nine bullets that carry eleven tracked
metrics to
## Tracked metricsand leaving fourteen gates. Two of the fourteen are trailingGate:sentences that were never bullets, and one bullet becomes two gates because it says "Both are hard gates". - The harness's gate table counts memory formation at seven; the spec lists eight bullets of which five are gates. Resolved at five. The table was written when the spec's list was read as entirely gates, and the spec itself calls four of those bullets metrics. The harness table is updated, and its stale sentence "The six written specs" becomes eleven specs and the engineering plan.
- Three gates are declared in two specs each. Resolved by one owner and an explicit alias, so a count check does not double-count and a reader does not implement twice.
model-gatewaygate 10 skips without credentials; registry rule 3 forbids skipping at or past a milestone. Resolved by anoptionalfield carrying its precondition, used once.- Tool-system build step 3 places persistence inside an in-memory milestone. Resolved by separating the port's semantics (Milestone 1, contract suite) from the DDL (Milestone 2), and by naming concurrent dedup as the in-memory adapter's declared gap.
- Milestone 1 ships a
CancellationTokenwith no writer. Resolved by a lazily evaluated deadline and aSIGINThandler, which are the two writers that need nothing Milestone 2 builds. - Context-engine gates are all Milestone 7 while ADR-0024 assigns the builder's determinism test to Milestone 1. Resolved by moving gate 1 and build step 1 to Milestone 1 and leaving the other four where they are.
- Hard gate 4 requires a
#hard-gatesanchor and the two entries the engineering plan owns have no such section to name. Resolved by that gate's own title: what is checked is that the anchor an entry names resolves in the built site, and those two name the Milestone 0 heading that declares them.
Decisions¶
- The milestone is a property of the gate, not of the section. A section-level sentence is prose; the token is data. Four specs that carry a section-level milestone keep the sentence and gain tokens, and two of those four turn out to have a gate that does not match the section.
- A gate lands at the milestone that builds the last thing it observes. This is the rule that produced every assignment above, and it is stated so the next gate added has an answer before the argument starts.
- A gate whose subject exists earlier than its full assertion is registered at the earlier milestone when the earlier form is a real assertion, and at the later one when the earlier form would be vacuous. Tool-system gate 5 is the first case; gate 12 of the runtime loop is the second.
- Corpus gates are registered once and grown. Adding an MCP
server to
gate.tool.no_external_textat Milestone 8 is a corpus change, not a new gate, which is exactly the separation the harness introduced the corpus kind for. - Structural gates restated across specs take the
structurearea. Two do today: the import-boundary walk and transaction hygiene. The area exists so that a gate with two declaring specs has a home belonging to neither, which is what makes the ownership rule above look like a rule rather than a tiebreak. - Aliases are declared, not deduplicated silently. The non-owning spec keeps its sentence, because a reader of the tool system should learn that the import boundary is checked; what changes is that the sentence says it is the same gate.
- The
optionalfield is added for one gate and its use is bounded: a gate may be optional only if its precondition is an external credential, and the registry records the precondition. A second use is a design smell and should be argued in review. - The census is generated. A written table drifts; a derived one fails the build when it disagrees. The table above is the expected output, not the source.
- Milestones 6, 8, and 10 adding no gates was reported, not fixed. The honest finding was that their acceptance rested on the engineering plan's own criteria, and inventing gates to fill a column would have been worse than naming the shape. All three zeros were closed the way the decision implies they should be: by specifications that had gates to declare, not by the column — sandbox-isolation.md for Milestone 6 and skills.md for Milestones 8 and 10. The decision stands for the next milestone that shows a zero. Milestones 12 through 15 each showed one on the day they were authorized and each closed it the way the decision implies, with a specification that had gates to declare. Milestones 16 and 17 never showed one: each milestone's authorization and its specification landed in the same change, so the rows they added were already twenty and ten.
- Milestone 1's cancellation is
SIGINTplus a lazy deadline. Both are cheap, both exercise the observation points from the first commit, and neither requires the queue. The alternative — three dead observation points until Milestone 5 — costs the same to write and is untested when it matters. - The idempotency port is Milestone 1 and its index is Milestone 2. One port, two adapters, one contract suite, one declared gap. This is ADR-0024's repository-versus-storage separation applied a second time, and its second application is what makes it a rule rather than a special case.
- This document is a scheduling document and owns no requirement about the agent. If a gate's statement is wrong, the fix belongs in the spec that declares it, and this document's table follows. The seven gates it does declare are checks over the scheduling record itself, which is the one thing no other document is in a position to check.
- Hard gate 7 is asserted against the build-sequence table and not against a step recorded per gate. Only the tool system records which step each of its gates observes, and two of its rows sit at Milestone 2 against a Milestone 1 step under decision 3 above, because the earlier form of each would be vacuous: nothing recovers before there is persistence to recover from, and a single-process dictionary cannot lose a race. A check reading that column per gate would fail on both and be relaxed within a milestone. The table is the input, and the question it answers is whether a spec's gates outrun the steps that build them.
Open questions for review¶
- Whether cancellation should exist at Milestone 1 at all. The
runtime loop already recorded the M1/M4/M5 split as a question. The
answer here —
SIGINTand a lazy deadline — is the cheapest thing that makes the split real rather than notional. If the intent was that nothing cancels before Milestone 5, drop the handler and the deadline check and points 1 through 3 become unreachable until then. Reversal cost: low, one handler and one predicate. - The original Milestone 9 memory-formation count is reconciled. The old harness table said seven, but the formation specification classifies four of its original bullets as tracked metrics and declares four hard gates plus the trailing no-policy-regression gate. Milestone 10 memory maturation later added fifteen more: five for ordinary-conversation formation and ten for governed inspection and provider assistance. The current formation census is therefore twenty owned gates — five at Milestone 9 and fifteen at Milestone 10 — with no unstated threshold turning formation precision or rejection rate into a gate.
- Whether Milestone 8 should acquire gates of its own —
answered yes, by skills.md, which gave it ten and
gave Milestone 10 its first six. The sentence about a skill doing something
no gate was watching turned out to describe a real hole, as the
same sentence about the sandbox had. The MCP half was answered
the same way on two later passes: three gates when this census
made build step 9 the only unobserved step in the tool system,
and three more when the readiness review found nothing behind
credential_ref. It registers six invariants of its own now, rather than corpus members in two gates belonging to the pipeline it widens. - Whether the
optionalfield is worth its precedent. One gate uses it. The alternative is a live smoke test that is not a gate at all but a manually run script, which is honest about its status and loses the registry's record of it. - Whether the engineering plan should grow a
## Hard gatessection. It owns two registry entries and is the only declaring document without one, which is why theirspecfield is the single exception to the anchor rule. Giving it the section would make the rule uniform, and would also move two requirements out of the acceptance criteria that state them and into a heading a milestone-ordered document has no natural place for. The exception is recorded instead. Reversal cost: low, one section and twospecfields. - Whether the census belongs in a document at all once it is generated. Keeping it here makes the shape of the plan visible to a reader; generating it makes it correct. The compromise taken — written here, asserted by gate 6 — costs one test and one edit whenever the numbers move.