diff --git a/.agents/architecture-rules.md b/.agents/architecture-rules.md
index e1b384458..6894d3272 100644
--- a/.agents/architecture-rules.md
+++ b/.agents/architecture-rules.md
@@ -17,7 +17,7 @@ the system itself; this file governs how new architecture is designed.
8. Feature-specific runtime APIs stay with their feature package and are not collected into a central runner context.
9. Immutable view data flows down and typed semantic actions flow up; the root alone owns route intent, selection and rebuildable application state.
10. A component lifetime may own a node; a render body may not create or own one.
-11. View data and placement cross the direct parent-child boundary and no other.
+11. View data and layout cross the direct parent-child boundary and no other.
12. Normalized host input is decided once and dispatched through the target's own ancestry; a host names a target and an event shape, never an action. Text is its own event shape carrying what the terminal decoded, and a modified chord is dropped whole rather than read off its physical key code.
13. Freedom alone owns focus; an overlay is a mounted branch, not a second tree.
14. Keyed descriptions reconcile into one mounted tree; validate the complete desired set before mutating any of it.
@@ -28,6 +28,15 @@ the system itself; this file governs how new architecture is designed.
19. Renderer output is copied out of the engine before returning, and a refused frame is redrawn on a renderer rebuilt for that frame's dimensions without changing selection, focus, actions or the frame itself.
20. A contextual adapter owns terminal modes, listeners and readers, registers their release before taking them, and restores them exactly once on every exit.
21. A narrow surface displays the one route selected; every other surface is absent from the frame, its map and its targets rather than hidden within them.
+23. Use methods on an owned handle for operations tied to that instance.
+24. Use a Context to select a scoped service; capture it for any lifetime that requires a fixed provider.
+25. Use middleware when per-call interception or transformation is an intended extension point.
+
+Rules 23–25 choose the API by ownership and intended composition. A captured
+service keeps provider selection fixed for its consumer's lifetime; its mutable
+configuration still follows that service's own update contract. A Context
+selects a trusted service, while authorization, durable identity,
+reconciliation and canonical outcomes stay with their owners.
The Architect applies these rules without another approval when they settle a
design. A new concept, ambiguous fit, conflict or proposed exception returns to
diff --git a/.agents/component-descriptions.md b/.agents/component-descriptions.md
index f5e7674a2..9f96983a6 100644
--- a/.agents/component-descriptions.md
+++ b/.agents/component-descriptions.md
@@ -55,7 +55,7 @@ structured fields cannot provide, not as a second reference entry.
9. Keep behavior that changes use.
- Activation conditions, placement rules, scope, transport choices, failure
+ Activation conditions, structural rules, scope, transport choices, failure
behavior and preflight-only forms belong when they determine what an author
writes or observes.
diff --git a/AGENTS.md b/AGENTS.md
index c900139bd..6ffc40efc 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -459,8 +459,9 @@ the corpus or enabling in-shard concurrency is not an answer to a miss.
job withholds the required `green` check until CI has proven `main`'s exact
current head. Repairing it is a pull request a maintainer labels
`ci-main-red-fix`, which runs `composability` in the gate's place.
-15. State shared across loaded copies uses stable, namespaced names: plain
- structural values for composition data and a contextual Api for operations.
+15. State shared across loaded copies uses stable, namespaced names. Use owned
+ handles for instance operations, Context for scoped service selection, and
+ contextual Api middleware for intended per-call composition.
Security enforcement, durable identity, and reconciliation never trust
replaceable context state.
16. An event listener an Effection operation installs has that operation's
diff --git a/architecture.md b/architecture.md
index 8ae2d7bae..9f0988789 100644
--- a/architecture.md
+++ b/architecture.md
@@ -2817,7 +2817,7 @@ it to decide whether a write's children may expand, and the later write repeats
the same admission from the same authored path. Nothing is handed between them,
so a check that was skipped or answered elsewhere authorizes nothing.
-Directory placement is one semantic act of its own. `
` gives
+Creating a directory is one semantic act of its own. `` gives
`ensureDirectory` the enclosing working directory and the path the author
selected; a relative path is resolved against that directory and an absolute
path keeps the component's existing meaning and is used as written. The
@@ -4212,11 +4212,19 @@ no one-off Plan timer and does not depend on that issue.
What Plan composes around the public component is recovery, not limiting:
-```mdx
-
-
-
-```
+Canonical core enforces it, and where it is enforced is the point. What a test *does*
+arrives through public middleware a handler may legitimately answer without
+delegating — that is how a second loaded copy supplies behavior — so a
+requirement asked inside that chain is a requirement a handler can skip by never
+letting it be asked. The decision is therefore taken by the invocation itself,
+before the harness is minted and before the behavior chain is dispatched,
+through a seam the testing package installs its guard on. Core supplies no
+policy there: it dispatches through a private per-invocation terminal and
+refuses an invocation whose decision was never taken, so blocking that chain
+refuses the test rather than admitting it. With nothing installed the terminal
+is reached immediately, which is what keeps core-only use of the behavior
+surface working.
+
Plan owns one fixed recovery policy: after the child's structured teardown it
turns the one narrow, typed generated-request refusal into retry context and rethrows
@@ -4897,7 +4905,7 @@ through two more declarations in that same prefix. `` contains only
its `` declarations there, and `` contains only its
`` matchers. Each wrapper may appear at most once for one ``.
They reuse the existing TestAgent scenario and Answers matcher contracts; this
-placement changes where those declarations apply, not what either language
+position changes where those declarations apply, not what either language
means. `` is refused in this position: a test that
supplied answers does not fall through to the run profile's live WebForm.
The TestAgent declaration is recognized only when ordinary resolution selected
@@ -5532,7 +5540,7 @@ a private closure name, and a reserved registration already holding the name are
configuration failures refused where they are installed rather than precedence
questions resolved by order.
-**Placement is decided from source.** A construct holds whitespace and the
+**Structure is decided from source.** A construct holds whitespace and the
regions it declares and nothing else; a region is written directly inside its
own construct and is an error anywhere else; a self-closing construct has no
regions and is accepted when that form is declared. The analysis is pure and
@@ -5549,7 +5557,7 @@ construct never enters the branch that belongs to the engine's table.
**The symbols stay version 2.** A construct and each of its regions contribute
one entry to the structural category, sorted by code point beside the engine's
-own and carrying the declared forms, props schema, placement, syntax examples,
+own and carrying the declared forms, props schema, structure, syntax examples,
description and origin. The two structural entry shapes are a closed union: an
engine entry keeps exactly the fields it always had, neither shape can inhabit a
component entry, and no category, order or existing member changed — so a
@@ -5569,7 +5577,7 @@ shared analysis, and everything else is the component import it always was. An
expansion carrying no execution environment declares nothing and reaches none
of this.
-**The handler is entered once, with everything already settled.** Placement
+**The handler is entered once, with everything already settled.** Structure
first, then the authored form of the construct and of every accepted region —
each against its own declaration, because a region declares the forms it accepts
and does not inherit its construct's — then `as` and `slot` —
@@ -6060,6 +6068,7 @@ operation the document authored. Those prohibitions are one boundary rather
than a test fixture's list of components: adding a component cannot make
validation effectful.
+
## The private REPL composition kernel
`packages/cli/src/repl/` is a private CLI feature, not a package boundary and
@@ -6238,7 +6247,19 @@ Composition is keyed. A parent describes its complete child set; the reconciler
judges all of it before mutating any of it, adds and updates before removing,
then sets canonical order, and acknowledges the offer only after that commit.
Identity is parent, key and type, so redescription preserves a node and its
-running lifetime while a changed key or type replaces it. Freedom owns the one
+running lifetime while a changed key or type replaces it.
+
+That judgment is one function, and the mounted tree publishes two methods over
+it. `validate()` answers synchronously about a described set without mounting
+it: nothing is attached, updated, drawn or removed, focus does not move and the
+frame does not advance. `apply()` makes the same judgment again on the values it
+is actually given, so an accepted judgment is an answer rather than a
+reservation and a caller that never asks is protected exactly as much. What is
+judged is what the tree owns — whether each child is a description it issued,
+whether siblings share a key, whether two children request focus, and whether a
+focus request sits inside the innermost modal. A child's layout is its parent's
+own and takes no part in it: there is no caller-supplied policy over a layout
+and no second validator. Freedom owns the one
mounted lifetime tree and the one focus store, and a component's capabilities
live in its own node's `NodeData` — an absent description therefore leaves no
node, no input, no focus, no frame contribution and no output anywhere.
@@ -6254,14 +6275,23 @@ Freedom is vendored from a pinned unpublished commit under
`packages/cli/src/repl/vendor/freedom/`, as a pristine copy and a patched copy
whose every difference belongs to one named patch. See its `PROVENANCE.md`.
-### One chronology, and the authority that answers it
+### Two owners, and the authority that answers them
+
+**Sessions has one section per owner, in a fixed order: Entry agents, then
+Sidekick.** The two histories are two files with no shared persisted scheduling
+number, so one interleaved list would have to present a timestamp, a completion
+order or an append order as a global start order. Each section keeps its own
+history's order instead, and the root composes the two detached readings rather
+than merging them into a model — Sidekick records never enter `ReplModel` and
+never acquire a fabricated entry key, marker or History position. An execution
+with no Sidekick installation keeps the entry-only reading unchanged.
-The Sessions reading is one list, not two appended: every Prompt this process
-observes takes a slot when it is scheduled and keeps it through publication, so
-a turn that becomes durable stays the same mounted node in the same place, and
-concurrent Prompts that publish out of order do not reorder each other. The
-slot, its order and its live key are process-local — no route, model, Journal
-record or public Core Api carries one.
+The Entry agents reading is one list, not two appended: every Prompt this
+process observes takes a slot when it is scheduled and keeps it through
+publication, so a turn that becomes durable stays the same mounted node in the
+same place, and concurrent Prompts that publish out of order do not reorder each
+other. The slot, its order and its live key are process-local — no route, model,
+Journal record or public Core Api carries one.
A Prompt's sequence number is local to the execution that recorded it, so it
restarts with every entry and two entries may each hold sequence `0`. Turns are
@@ -6272,13 +6302,127 @@ the pair — a durable Prompt name says where it was written, so two entries
running one source hold the same name at the same position, and correlating by
the name alone shows one turn twice and the other not at all.
-Sessions stays one execution-wide chronology grouped by the provider's session
-key and by nothing else. Selecting an entry changes which transcript is being
-read and never which conversations are listed.
+Each section stays grouped by the provider's session key and by nothing else.
+Selecting an entry changes which transcript is being read and never which
+conversations are listed.
Filtering is by the conversation key a provider actually issued; an authored
`` name is not one. Selecting or clearing changes `route.session` and
-nothing else, and background Agent work never changes it.
+nothing else, and background Agent work never changes it. It filters both
+sections, and rows are never merged across them: entry and Sidekick identities
+have separate owner domains, so an equal provider conversation or an equal turn
+number leaves one filter choice and two rows.
+
+**A Sidekick turn's filter evidence is its own saved record or its own
+publication, and nothing else.** A nonempty `sessionKey` read through
+`parsePromptRecord()` from an acknowledged canonical Prompt is evidence for that
+turn — a failed or cancelled record included — and an exact successful
+`AgentPromptPublication.association` supplies the key for its own live turn
+before append acknowledgement without making that turn saved. A prepared or
+activated CLI association, a message id, a response name, a turn number and an
+agent name are none of them a provider conversation, and an earlier turn's key
+is never substituted for a later one's. Because a chat has no position in the
+entry history, the Sidekick's complete saved facts and its exact live
+publication facts are applicable beside any entry checkpoint, while entry facts
+still come only from the selected prefix and live entry facts only from the
+head. A key absent from every applicable fact refuses rather than producing an
+apparently empty conversation. A key this owner genuinely observed stays known
+for the owner's lifetime so a selected filter does not become guessed emptiness
+after a Stop; the saved files establish none of it, so a cold reopening of a
+location naming an exclusively ephemeral key refuses.
+
+**The owner each section reads is its own.** `sidekick/model.ts` projects the
+saved turns purely from the records a pair holds, and `sidekick/owner.ts`
+remains the sole publisher in each Sidekick execution: its existing `begin()`
+announces the Sessions row even for a turn that produces no literal `