Elnor Repo Reader

DOC80_Core_Charter_Draft.md

Memory Rebuild Docs/Stage_6_Charters/E0_DOC80_Core/DOC80_Core_Charter_Draft.md

Short text page ac1b16fc2285. Generated 2026-06-09T01:23:58.539Z from commit dbaa25962edc11ab30e8d4ca1715f9ae5bf77331. Worktree: clean.

Open readable HTML page · Open raw txt · Open path URL

ELNOR REPO READER TEXT MIRROR
Original path: Memory Rebuild Docs/Stage_6_Charters/E0_DOC80_Core/DOC80_Core_Charter_Draft.md
Source repo: /Users/OpenClaw1/Elnor/Elnor Specs
Git branch: main
Git commit: dbaa25962edc11ab30e8d4ca1715f9ae5bf77331
Generated: 2026-06-09T01:23:58.539Z

---

# DOC80 — Memory Control Plane Core (Stage 6 E0 Charter Draft — R2+R3 patch applied, ratification pending)

**Repository:** github.com/wbrody/Elnor-Specs — branch `main`
**Document status:** `charter-draft` (Stage 6 E0, **patch applied — ratification pending**). Becomes the operative DOC80 member spec after architect review + red-team rounds + ratification. (R1 draft + the fully-adjudicated `DOC80 S6 E0 RT Adj Card R2.md` package — ~80 edits — + `…R3.md` §22 egress replacement + non-egress lock patch applied per `E0_Application_Commission_Claude_Code.md`. Ratification is the architect's separate act via `Ratification.md`; this draft is NOT ratified.)
**Versioning discipline:** git-native — stable filename `DOC80_Core_Charter_Draft.md`, no version suffix. Git history is the version record (per Skeletal Baseline B5).
**Family member:** DOC80 (member 1 of 8 — the core/contracts member). Family = Memory Control Plane (ADQ-210).
**Governing inputs:** `Charter_Opening_Brief.md` (20 draft targets), `Charter_Input_Deck.md` (8 ADQs + Skeletal §10/§11 fold-ins), `DOC80_Skeletal_Target_Baseline.md` (§1–§11), `DOC80_Owner_Map.md`, `DOC80_Import_Graph.md`, `DOC80_Retired_Names.md`, `Architect_Decision_Queue.md`, `Supersession_Matrix.md`.

---

## §0. How to read this draft

This is the **core/contracts member** of the DOC80 family. It owns no domain plane; it owns the cross-cutting registries, the consumption contracts that downstream members bind to, the proof spine, the memory-object taxonomy, the family-wide budget/quota envelope, the observability seam, and the external-dependency posture. Every other family charter (E1–E10 + E_org) imports from here.

**Citation convention (per Commission §3.2 + §8).** Every contract traces to one of: an ADQ resolution (`ADQ-NNN`), a Skeletal Baseline section (`Skeletal §10.x` / `§11.x`), an Owner Map row (`Owner Map line N`), a Supersession Matrix row (`SM-NNN`), or an Import Graph edge. Untraceable claims are flagged `OPEN_FOR_ARCHITECT_REVIEW` in §16, never invented.

**Schema convention.** Full schemas are paste-ready TypeScript-style interfaces. Three concepts are **NAMED-only** (§5) — fully scoped (what they carry, producer, consumer, placement) but with the field-level schema deferred to Stage 7 per the Input Deck. NAMED-only concepts MUST NOT receive field schemas here (Commission Hard Constraint §6).

**Owner-cell convention (one-owner rule, Skeletal §1.2 / B3).** Every schema names exactly one `schema_owner`. DOC80 core holds a schema **only** when it has no plane (a registry, the proof spine, shared vocabulary, `MemoryCoordinationTrace`) **or** is a cross-cutting *contract* whose implementation is owned downstream. Secondary relationships use the closed verb set **owns / stores / executes / generates / consumes**.

---

## §1. Identity, scope, and non-goals

### §1.1 Member identity (family member 1 of 8)

DOC80 is the **core/contracts member** of the Memory Control Plane family (Skeletal §1; ADQ-220 fixes the family at 8 members). The family:

| member | E-slice(s) | domain |
|---|---|---|
| **DOC80** | **E0** (cross-cutting) | Core / contracts — registries, proof spine, `MemoryCoordinationTrace`, memory-object taxonomy, compute-budget/quota envelope, `ExternalDependencyRecord`, shared runtime vocabulary, cross-cutting lint suite |
| DOC81 | E1 + E2 | Scope & Policy |
| DOC82 | E3 + E4 | Canonical Knowledge + Source/Evidence |
| DOC83 | E5 + E6 | Extraction Spine + Temporal/Working-State |
| DOC87 | E_org | Organization & Membership (slice inserted between E6 and E7, per ADQ-220) |
| DOC84 | E7 + E8 | Runtime Delivery + Prompt/Proof (the **DAMS V5 substrate** lives inside DOC84, not as its own doc — ADQ-210 / SM-020) |
| DOC85 | E9 | Memory Learning |
| DOC86 | E10 | UI / Inspector / SearchAffordance |

DOC80 **owns** (Skeletal §1 DOC80 row; Owner Map §8): the ReasonCode registry, the ContextProduct registry, the PromptShellRegistry, the warrant-degradation-trigger registry, the domain-profile registry, `ExternalDependencyRecord`, `MemoryCoordinationTrace`, the memory-object taxonomy table, the family-wide compute-budget envelope (extended to `MemoryOperationQuota`), the proof spine (`ContextPacketProof` + the `RenderSafetyProof` contract + `MemoryFlowCertificate`), the `SemanticProjectionContract` umbrella, shared runtime vocabulary, and the cross-cutting lint suite.

DOC80 **does not own** any planeful schema. Per the one-owner rule (Skeletal §1.2), a schema with a clear plane belongs to that plane's member (DOC81–DOC87) or to an external owner doc (DOC72/DOC73/DOC25/DOC24/KDA/EC/PropA/…), which are **not re-chartered** by the flatten. DOC80 holds only registries, the proof spine, shared vocabulary, `MemoryCoordinationTrace`, and cross-cutting contracts whose implementation is downstream.

### §1.2 Family naming convention (ADQ-210)

The family is the **Memory Control Plane (DOC80 family)** (ADQ-210). Cite the member doc (`DOC83`) for ownership and the E-slice (`E5`) for the charter/conceptual band. **DAMS is one substrate inside DOC84**, not an independent owner doc (ADQ-210; SM-020 retires "DAMS as memory truth owner"). Any text asserting a "7-member family" is stale — DOC87 was added at Stage 5R (ADQ-220), making the family 8.

### §1.3 V5 non-goal (Skeletal §10.1)

> **DOC80 V5 is local-first, single-principal, single-node, single-EC-writer unless a later spec explicitly extends it.** Multi-device sync, cross-user memory, mobile sync, shared Project writes, and remote write authority are **out of scope for V5** (Skeletal §10.1; synthesis must-fix #12).

Durable objects nevertheless carry stable IDs / generation refs (`AssertionIdentitySignature`, `policy_generation_id`, `EpisodePolicyEpoch`, `MemoryCoordinationTrace`) sufficient for future replay and conflict-detection analysis if V5 is later extended. The forward-compatibility question for Phase-1 sharing is tracked at **ADQ-222** (open; `batch_for_architect`) and explicitly **does not block any Stage 6 charter** — it conditionally gates only Stage 7 schema-body work for `PublishedViewEnvelope` / `TaskSharedMemoryExposureContract` / `PublishedLibraryCorpusExposureContract`. Phase-2 networking is out of scope for V5 regardless.

### §1.4 EC manual-deletion + unreachable=uninjectable (Skeletal §10.2)

> **EC can delete any memory object on request.** A memory object that is not reachable for retrieval/injection is, by the same token, not reachable for use — **unreachability is self-limiting** (Skeletal §10.2).

Hard destruction is a manually-driven append-an-event; **automated destruction-cascade machinery is NOT in scope for V5** (architect adjudication 2026-05-27: *degradation, not destruction, is the privileged-clawback default*). This interacts with `LegalHoldState` (DOC81, Skeletal §10.3): every automated destructive job MUST check `LegalHoldState` and skip held objects; hard destruction itself remains manual. The family-wide invariant is enforced via OPA-033 against the known destructive jobs (DOC72 §42 nightly graph cleanup; DOC23 task-output retention/expiry; DOC25 source-deletion / materialization-clearing).

**Erasure-state distinctness (UR-29; keep-lints/reject-engine).** *Retired, stale, suppressed, reference-only, archived, revoked, tombstoned, and hard-deleted are NOT synonyms; downstream contracts MUST NOT treat any non-erasure state as erased.* E0 captures this as a set of lints, **not** a lifecycle state machine — the new per-event `ErasureMFC` / `RestampMFC` / `RestoreMFC` certificates (§3.3) *record* erasure/restamp/restore events; they do **not** introduce an erasure lifecycle engine (UR-29 stands; the full lifecycle/erasure state machine is rejected — §16.1 considered-and-declined).

**Lints (Stage 9):** `erasure.retired_used_as_erased` [canonical]; `erasure.legal_hold_bypassed_without_adq_resolution` [canonical]; `erasure.stale_is_not_erased` [proposed]; `erasure.suppressed_is_not_erased` [proposed]; `erasure.reference_only_is_not_erased` [proposed]; `erasure.archived_is_not_erased` [proposed]; `erasure.revoked_is_not_hard_deleted` [proposed].

### §1.5 Consistency model (Skeletal §11.2)

> **Consistency model (V5):** single-node, single-EC-writer, single-principal (per §1.3). **EC's serialized write is the ordering authority.** Concurrent submissions from multiple chat windows / scheduled runs / background jobs serialize through EC; `AssertionDedupeOutcome` is revalidated against current state inside EC's serialized write (compare-and-swap via `dedupe_basis_generation_id`, per OPA-031 `ECSeamContract`). **Family-level mutation ordering is provided by `MemoryMutationEnvelope`** (§5.1; Stage 7 schema body), which carries `transaction_time` and `valid_time` (§8.2 bitemporal). No eventual-consistency / CRDT semantics in V5; deferred to V6+ if multi-device sync is later approved (ADQ-222).

The consistency model is a **named assumption of the core**, not a runtime object: every durable mutation in the family is serialized through EC and represented as a `MemoryMutationEnvelope` event in EC's replay/audit log (§11 replay-completeness invariant). The extraction-side companion rule — re-gate at Step 0 if `policy_generation_id` changes between extraction admission and resolution — is in §8.3 (Skeletal §11.3).

**Cross-charter consumption:** every member that performs a durable write (DOC82 assertions, DOC87 memberships, DOC85 learning write-back, DOC81 policy stamps) binds to this model; DOC84 implements pipeline park/resume on `PolicyDisambiguationRequest` (F-async).

### §1.6 Shared runtime vocabularies (Skeletal §4 / B10) — restored

**Source:** Skeletal §4 (B10); UR-38 (DECIDED ACCEPT — restore the dropped section); A6/A9/F7 (E0DurableRecord base + RegistryEntryLifecycleState rename); R3 §(b) items 4 + 6. **Placement note (deviation):** the baseline section map calls this "§4," but the draft's §4 is the proof spine; restoring it as a top-level §4 would force a renumber of §4–§17 and break every cross-reference. It is placed here as **§1.6** — foundational shared vocabulary belongs with the §1 foundation, and definitions then precede their use in §2–§12. All internal references to the shared value types point to §1.6.

This is the **single home** for runtime-only enums/value types used by ≥2 family members; it carries **no** process/non-runtime vocabulary (B10). **Anti-junk-drawer rule:** a type lands in §1.6 only if (a) it is runtime, **and** (b) it is used by ≥2 members, **and** (c) it is not owned by a specific member's domain. **Helper-type ownership:** `UseWarrant`, `SupportRole`, `MemoryObjectRole` are **DOC82-owned** — referenced here, never redefined; `OwnerDocId`, `ProducerDocRef`, `BudgetBand` are §1.6-owned.

#### §1.6.1 Declared shared runtime value types

```typescript
type OwnerDocId = string;        // a DOC80-family or external owner-doc id, e.g. "DOC82" | "DOC84" | "EC"
type ProducerDocRef = { doc_id: string };  // §1.6-owned; the same shape used inline at §2.1
type BudgetBand = 'xs' | 's' | 'm' | 'l';

/** Registry-entry lifecycle ONLY — NOT memory-object lifecycle (A9/F7 rename of the generic LifecycleState).
 *  R3 §(b)#4 adds 'candidate': candidate entries are NOT runtime-emittable unless a registry-specific
 *  rule allows test fixtures. */
type RegistryEntryLifecycleState = 'candidate' | 'active' | 'deprecated' | 'retired';

type EffectiveStateGenerationId = string;  // EC §1 effective-state gating token (carried on every MFC, §3.3)
type SchemaVersionRef = string;            // schema_version pin on durable records (UR-26)
type ContentHash = string;                 // 'sha256' digest (UR-27)
// branded-ID base + RFC3339-UTC timestamp rule (UR-26/27) — declared globally at §8.5.

// ContextProductDecisionDisposition (ABC §9.4) is declared at §3.2 and referenced family-wide.
```

**RegistryEntryLifecycleState rule (R3 §(b)#4).** `'candidate'` entries are not runtime-emittable unless a registry-specific rule explicitly allows them (e.g. test fixtures). Lint `registry.candidate_entry_emitted_at_runtime` [proposed].

#### §1.6.2 E0DurableRecord base (A6)

```typescript
/** Common base for durable E0 records. The extending-records list below is ILLUSTRATIVE, not
 *  exhaustive (R3 §(b)#6): every durable registry / retained-proof / audit artifact carries
 *  schema_version + created_at. */
interface E0DurableRecord {
  schema_version: SchemaVersionRef;
  created_at: string;   // RFC3339-UTC (§8.5)
}
```

Records that extend `E0DurableRecord` (illustrative): `ContextProductRegistryEntry` (§3.1), every `MemoryFlowCertificate` variant (§3.3), every `MemoryDestructionLedger` entry (§3.7), `ExternalDependencyRecord` (§7), `ProofArtifactRetentionRule` (§4.4), `ReasonCode` (§2.1), `WarrantDegradationTrigger` (§2.4), `DomainProfile` (§2.2), `MemoryOperationQuota` (§10).

**Lints (Stage 9):** `runtime_vocab.value_type_redefined_per_member`; `runtime_vocab.process_vocab_in_runtime_core` (B10); `runtime_vocab.owner_missing`; `runtime_vocab.registry_lifecycle_used_as_memory_lifecycle`; `registry.candidate_entry_emitted_at_runtime`; `durable_record.missing_e0_durable_base`.

**Cross-charter consumption.** Every member references the §1.6 value types rather than redefining them; `RegistryEntryLifecycleState` is the lifecycle for registry entries family-wide (distinct from `MembershipLifecycleState`, §4.1, which is the membership-object lifecycle).

---

## §2. Cross-cutting registries

DOC80 owns four cross-cutting registries. Each is a core-held schema because it has **no plane** — it is shared vocabulary that every member references. The one-owner rule is satisfied: DOC80 owns the *registry contract + allocation rules*; producer docs own their *entries* within an allocated namespace.

### §2.1 ReasonCode registry (ADQ-310)

**Source:** ADQ-310 (`architect_stop`/resolved — "DOC80 core owns the canonical ReasonCode registry + namespace rules; producers own producer-specific entries; unblocks E0/E1/E2"); SM-213 (`absorb_as_target_rule`, resolved); Owner Map line 86. **Owner:** DOC80 core (registry contract + namespace allocation). **Producers:** EC / PropA / DOC24 / DOC20 / DOC25 / DOC81–DOC87 own entries within their allocated namespace. **Consumers:** every member that emits an operator- or UI-facing signal.

The registry exists so that no member invents a local reason-code system (ADQ-310). DOC80 owns the *shape* and the *namespace allocation*; each producer owns its namespace's *entries*. A reason code is never minted ad hoc at runtime — it must pre-exist in the registry, which makes operator triage, UI mapping (via DOC86 `SafeLabelPolicy`), and proof-failure attribution deterministic.

```typescript
/** A single entry in the canonical cross-doc reason-code registry.
 *  Registry owned by DOC80 core (ADQ-310 / SM-213 / Owner Map line 86);
 *  each entry owned by its producer doc via an allocated namespace prefix. */
interface ReasonCode {
  reason_code_id: string;          // fully-qualified: "<namespace>.<category>.<local_code>", e.g. "EC.policy.blocked_by_scope_boundary"
  namespace: ReasonCodeNamespace;  // producer-domain prefix; must be allocated in the registry
  local_code: string;              // snake_case; unique within (namespace, category)
  category: ReasonCodeCategory;
  human_summary: string;           // one-line operator-facing meaning; NOT user copy (DOC86 SafeLabelPolicy maps to user text)
  severity: 'info' | 'notice' | 'warning' | 'block';
  surfaces_to_user: boolean;       // eligible to drive a user-visible notice (DOC86 still gates the actual surfacing)
  lifecycle_state: RegistryEntryLifecycleState; // §1.6 (A9/F7): registry-entry lifecycle, not memory-object lifecycle
  superseded_by?: string;          // replacement reason_code_id when deprecated/retired
  introduced_in: string;           // provenance: spec/charter/ADQ ref
  owner_doc: ProducerDocRef;       // the single authority for this namespace
}

type ReasonCodeNamespace = string; // pattern '^[A-Z][A-Z0-9_]{1,31}$' (UR-10); validated against ReasonCodeRegistry.registered_namespaces

type ReasonCodeCategory = // E0-owned base category set (ADQ-310); Stage 7 may EXTEND only via the namespace-governance process — it does not re-confirm or replace this base vocabulary
  | 'policy' | 'scope' | 'extraction' | 'delivery' | 'learning'
  | 'membership' | 'source' | 'proof' | 'ui' | 'system';

interface ProducerDocRef { doc_id: string; } // "EC" | "PropA" | "DOC24" | "DOC20" | "DOC25" | "DOC81".."DOC87"

/** Canonical cross-doc reason-code registry. schema_owner = DOC80 core (ADQ-310). */
interface ReasonCodeRegistry {
  registry_id: 'doc80.reason_code_registry';
  schema_owner: 'DOC80';
  registered_namespaces: ReasonCodeNamespaceAllocation[];
  entries: ReasonCode[];
}

interface ReasonCodeNamespaceAllocation {
  namespace: ReasonCodeNamespace;  // pattern '^[A-Z][A-Z0-9_]{1,31}$'; e.g. "EC", "PropA", "DOC24", "DOC20", "DOC25", "DOC81"
  owner_doc: ProducerDocRef;       // sole authority to add/deprecate entries in this namespace
  state: 'reserved' | 'active' | 'deprecated' | 'retired' | 'legacy_reserved'; // UR-10: namespace lifecycle
  allocated_in: SchemaVersionRef;  // UR-10: provenance pin (lifecycle-bearing; was a bare string)
  replacement_namespace?: ReasonCodeNamespace; // UR-10: redirect target when deprecated/retired
  legacy_allowed_only?: boolean;   // UR-10: namespace usable only in legacy/historical context, never runtime-emitted
}
```

**Namespace lifecycle mechanics (UR-10).** A namespace is itself a lifecycle-bearing object: a `legacy_reserved` or `retired` namespace must never be the source of a runtime-emitted code; a `deprecated` namespace redirects via `replacement_namespace`. The `^[A-Z][A-Z0-9_]{1,31}$` pattern is enforced (case + length). **Reason-code negative-outcome invariant (UR-10):** *every withheld / blocked / degraded outcome across the family carries ≥1 reason code* — the lint family `*.negative_outcome_without_reason_code` [proposed] spans policy / scope / render / learning / erasure.

**Namespace rules (ADQ-310).** Every `reason_code_id` is `<namespace>.<category>.<local_code>`. A producer may write entries **only** under a namespace it owns (`registered_namespaces`). Cross-doc consumers reference a code by `reason_code_id` and never re-declare it. Deprecation requires `superseded_by`; a `retired` code emitted at runtime is a hard error. **Producer authority list** (ADQ-310 / Owner Map line 86): EC, PropA, DOC24, DOC20, DOC25, and each DOC80-family member for its own plane.

**DOC25 producer scoping (UR-37 — DECIDED ACCEPT, scoped; veto-able at ratification).** DOC25 is confirmed as the originating owner of its own reason codes (the originating doc owns its codes), but its grounding is **narrowed to parse / materialization / ingestion conditions only**; **source-revocation reason codes route to DOC82**, not DOC25 (DOC82 owns the source/evidence plane that revocation acts on). The earlier "ungrounded DOC25 producer" flag is converted to a *grounding obligation* recorded in the preservation matrix (§17.4) and OP-A; the **Owner Map line-86 amendment is a discharge item — recorded, not applied here** (Hard Constraint §1).

**Lifecycle.** `active → deprecated → retired`. Deprecation keeps the code resolvable (audit/lineage) but emits a migration warning; retirement makes emission a block-level lint hit.

**Unhappy paths.** *Unregistered* — a producer emits a code absent from the registry → blocked, `reason_code.unregistered_emission`. *Cross-namespace write* — a producer writes under a namespace it does not own → rejected. *Deprecated still emitted* → warning + `superseded_by` redirect. *Retired emitted* → block. *Entry without namespace owner* → registry-integrity lint.

**Lints (Stage 9):** `reason_code.unregistered_emission`; `reason_code.namespace_written_by_non_owner`; `reason_code.retired_code_emitted`; `reason_code.entry_without_namespace_owner`; `reason_code.namespace_collision` (UR-10); `reason_code.namespace_state_legacy_emitted_runtime_code` (UR-10); `reason_code.case_pattern_violation` (UR-10); the `*.negative_outcome_without_reason_code` family [proposed] (UR-10).

**Fixtures (Stage 8):** `fixture.reason_code.producer_emits_only_owned_namespace`; `fixture.reason_code.unregistered_code_blocked`; `fixture.reason_code.deprecated_code_redirects_to_successor`.

**Cross-charter consumption.** **E1/E2 (DOC81)** is the primary early consumer — it must reference the registry for policy/scope reason codes rather than inventing local ones (ADQ-310 "unblocks E0/E1/E2"). Every member that produces operator- or user-facing signals (DOC84 delivery, DOC85 learning, DOC86 UI, DOC87 membership, DOC83 extraction) consumes the registry.

### §2.2 Domain profile registry + fallback (ADQ-313)

**Source:** ADQ-313 (resolved — "central domain profile registry; missing profile → use 'conservative' default profile (highest restrictiveness)"). **Owner:** DOC80 core (registry + the fallback rule). **Producers:** the planes own the *values* behind each knob (DOC25/E4 parse thresholds per ADQ-303; DOC82/E3 warrant policy; DOC81/E2 disclosure + retention defaults); DOC80 owns only the *registry and the fallback contract*. **Consumers:** every member that varies behavior by domain.

A domain profile is a named bundle of restrictiveness defaults (legal-litigation, default-conservative, etc.). DOC80 owns the registry and the **fail-safe fallback**; it deliberately does **not** own the profile knob *values*, because those have planes (parse-quality thresholds are a DOC25 concern, warrant policy a DOC82 concern). The core's job is to guarantee that a missing profile never fails open.

```typescript
type DomainProfileId = string; // e.g. "legal.litigation" | "default.conservative"

/** Per-axis restrictiveness (UR-11) — replaces the scalar restrictiveness_rank.
 *  DOC81 owns the axis vocabulary/semantics; DOC80 owns only the meet rule + fail-closed. */
type RestrictivenessLevel = 'open' | 'normal' | 'restricted' | 'highly_restricted' | 'blocked';

interface DomainProfileRestrictivenessVector {
  extraction: RestrictivenessLevel;
  rendering: RestrictivenessLevel;
  disclosure: RestrictivenessLevel;
  export: RestrictivenessLevel;
  carryover: RestrictivenessLevel;
  delegation: RestrictivenessLevel;
  learning: RestrictivenessLevel;
  retention: RestrictivenessLevel;
  source_authority: RestrictivenessLevel;
}

interface DomainProfile {
  profile_id: DomainProfileId;
  display_name: string;
  restrictiveness_vector: DomainProfileRestrictivenessVector; // UR-11: per-axis vector (NOT a scalar rank)
  is_conservative_fallback: boolean;   // EXACTLY ONE profile in the registry has this true (every axis most-restrictive)
  // Knob VALUES are owned by the planes; the core only references them:
  parse_quality_thresholds_ref?: ExternalContractRef; // DOC25 / E4 owns values (ADQ-303)
  warrant_policy_ref?: ExternalContractRef;            // DOC82 / E3 owns DomainProfileWarrantPolicy (§13)
  disclosure_defaults_ref?: ExternalContractRef;       // DOC81 / E2 owns
  retention_defaults_ref?: ExternalContractRef;        // DOC81 / E2 owns
  lifecycle_state: RegistryEntryLifecycleState; // §1.6 (A9/F7): registry-entry lifecycle, not memory-object lifecycle
}

interface DomainProfileRegistry {
  registry_id: 'doc80.domain_profile_registry';
  schema_owner: 'DOC80';
  profiles: DomainProfile[];
  conservative_fallback_id: DomainProfileId; // MUST resolve to a profile with is_conservative_fallback = true
}

interface ExternalContractRef { owner_doc: string; contract_id: string; } // a pointer, not the value
```

**Fallback rule (ADQ-313) + per-axis meet (UR-11).** If a lookup names a `profile_id` that is absent, or a context resolves to no profile, the system MUST use the `conservative_fallback` profile (the profile whose `restrictiveness_vector` is most-restrictive on **every** axis). The core **never fails open**; the absence of a profile resolves to the *most* restrictive behavior, not the least. **E0 meet rule (UR-11):** the effective restrictiveness for an action is the **per-axis most-restrictive meet** across all applicable profiles; a `missing`, `unknown`, or `incomparable` axis resolves **conservative** (fail-closed); a **multi-axis action is allowed only if EVERY touched axis allows it**. DOC81 owns the axis vocabulary and per-level semantics; DOC80 owns only the meet + fail-closed rule.

**Lifecycle.** `active → deprecated → retired`; a deprecated profile resolves but warns; a context pinned to a retired profile resolves to the conservative fallback.

**Unhappy paths.** *Missing profile* → conservative fallback (the defining behavior). *Zero or >1 `is_conservative_fallback`* → registry-integrity block. *Core holds knob values* → one-owner violation (the core must only reference, never own, plane knob values). *Deprecated profile referenced* → warn + continue.

**Lints (Stage 9):** `domain_profile.missing_resolves_to_conservative`; `domain_profile.no_unique_conservative_fallback`; `domain_profile.knob_value_owned_by_core`; `domain_profile.scalar_rank_used` (UR-11); `domain_profile.incomparable_axis_without_fail_closed` (UR-11).

**Fixtures (Stage 8):** `fixture.domain_profile.unknown_profile_falls_back_conservative`; `fixture.domain_profile.exactly_one_conservative_fallback`; `fixture.domain_profile.core_references_not_owns_knobs`.

**Cross-charter consumption.** DOC81 (policy/disclosure/retention defaults), DOC82 (warrant policy per domain), DOC25/E4 (parse-quality thresholds, ADQ-303), DOC84 (delivery behavior by domain). The conservative-fallback guarantee is a precondition every plane relies on.

### §2.3 PromptShellRegistry + PromptShellVariant + PromptShellLearningContract (ADQ-208)

**Source:** ADQ-208 (resolved — "cross-cutting contract in DOC80 core; DOC24 + KDA + BDSM consume it"); SM-203 (`absorb_as_target_rule`); Owner Map lines 144–146. **Owner:** DOC80 core (registry + variant schema + learning contract). **Consumers:** DOC24 + KDA (runtime selection), DOC85 (learning weight via the learning contract, with BDSM as `partial` substrate). **Executor of runtime selection:** DOC84 (§7 of DOC84 section map).

Prompt shells are the system/developer/tool-preamble frames wrapped around assembled context. They are cross-cutting (every delivery path uses them) and must be **load-bearing for the final-prompt proof** (SM-203), so they live in the core registry rather than scattered across DOC24/KDA. Shell text is **hash-pinned** so it can anchor both KV-cache reuse and `ContextPacketProof` (cf. ADQ-305 stability rule).

```typescript
type PromptShellVariantId = string;

interface PromptShellVariant {
  variant_id: PromptShellVariantId;
  shell_family: string;                 // e.g. "extraction" | "delivery" | "inspector"
  role: 'system' | 'developer' | 'tool_preamble' | 'user_frame';
  content_hash: string;                 // hash-pinned text (KV-cache + proof anchor; ADQ-305)
  policy_invariant: boolean;            // true iff content does NOT vary by policy/profile/scope/model-class (ADQ-305)
  applicable_domains: DomainProfileId[]; // [] = all domains
  load_bearing_for_proof: boolean;      // if true, must appear in ContextPacketProof.shell_refs (SM-203)
  kv_cache_eligible: boolean;           // DERIVED (UR-13): content_hash present && policy_invariant && lifecycle_state==='active'
  lifecycle_state: RegistryEntryLifecycleState; // §1.6 (A9/F7): registry-entry lifecycle, not memory-object lifecycle
  introduced_in: string;
}

interface PromptShellRegistry {
  registry_id: 'doc80.prompt_shell_registry';
  schema_owner: 'DOC80';
  variants: PromptShellVariant[];
}

/** Governs how learning may adjust shell selection. schema_owner = DOC80 core.
 *  Producers = DOC85 (E9), via the BDSM partial substrate (ADQ-221). */
interface PromptShellLearningContract {
  contract_id: 'doc80.prompt_shell_learning_contract';
  schema_owner: 'DOC80';
  adjustable: 'selection_weight_only';  // learning may reweight selection among REGISTERED variants only
  may_not: (
    | 'synthesize_new_shell_text'
    | 'bypass_content_hash_pinning'
    | 'alter_policy_gating_of_policy_variant'
  )[];
  requires_proof_gate: true;            // no shell-selection learning without ContextPacketProof (ADQ-207 / SM-050)
  substrate_dependency_status: 'partial'; // BDSM partial per ADQ-221; specific surfaces named at E9 (two-phase, Skeletal §11.12)
}
```

**Lifecycle.** Variants move `active → deprecated → retired`; a retired variant selected at runtime is blocked. Learning may change *which* registered variant is selected (weighting) but never the *content*.

**Unhappy paths.** *Unregistered variant selected* → block. *Learning mints shell text* → block + lint (guards "phantom" prompt content and silent auto-promotion of learned text into the prompt). *`load_bearing_for_proof` variant absent from `ContextPacketProof.shell_refs`* → proof-integrity lint. *`policy_invariant = false` variant treated as stable for KV-cache* → cache-safety lint (ADQ-305).

**Lints (Stage 9):** `prompt_shell.unregistered_variant_selected`; `prompt_shell.learning_minted_shell_text`; `prompt_shell.load_bearing_variant_absent_from_proof`; `prompt_shell.policy_variant_treated_as_stable`; `prompt_shell.cache_eligible_without_content_hash` (UR-13); `prompt_shell.cache_eligible_policy_variant` (UR-13); `prompt_shell.retired_variant_used_for_new_packet` (UR-13).

**Fixtures (Stage 8):** `fixture.prompt_shell.only_registered_variants_selected`; `fixture.prompt_shell.learning_adjusts_weight_not_text`; `fixture.prompt_shell.load_bearing_variant_in_proof`.

**Cross-charter consumption.** DOC84/E7–E8 (runtime selection + render integration), DOC24 + KDA (consume the registry for assembly/rendering), DOC85/E9 (learning weighting under the learning contract — Phase 2 names the BDSM surfaces it reads, Skeletal §11.12). Field-level schema must be stable before DOC84 binds (Input Deck open seam).

### §2.4 Warrant-degradation-trigger registry (ADQ-312; Owner Map line 171)

**Source:** ADQ-312 (resolved — "ABC §7.13 list is the INITIAL CONTROLLED REGISTRY (not permanently exhaustive); new trigger kinds require architect approval via the ADQ"); Owner Map line 171; Skeletal §11 (registry in core, producers in DOC85). **Owner:** DOC80 core (the registry). **Producers:** DOC85 owns the producer logic; the per-trigger execution owners are named below. **Consumers:** DOC82 (warrant ladder), DOC81 (policy_change → restamp eligibility).

The trigger registry is **initial and controlled**, not frozen: the ABC §7.13 list seeds it, and any new trigger kind requires an architect decision (a new ADQ). It lives in the core because the *vocabulary* of degradation triggers is cross-cutting; the *producers* live in DOC85 and the per-trigger execution owners are external/plane docs (ADQ-312).

```typescript
type WarrantDegradationTriggerKind =
  | 'user_correction' | 'time_window' | 'confidence' | 'contrary_source'
  | 'policy_change' | 'supporting_CU_stale' | 'parse_quality_audit'
  | 'proof_gated_outcomes' | 'session_bound_expiry';

interface WarrantDegradationTrigger {
  trigger_kind: WarrantDegradationTriggerKind;
  producer_owner: ProducerDocRef;     // per the ADQ-312 owner table below
  description: string;
  trigger_emission_effect: 'lowers_or_holds_eligibility'; // effect of EMITTING this trigger ONLY; the §12.1 source-revocation recompute is polarity-aware (a contrary-source removal MAY raise net warrant)
  allowed_producers: ProducerDocRef[];   // UR-14b: who may emit this trigger
  allowed_consumers: ProducerDocRef[];   // UR-14b: who may consume it (DOC82 warrant ladder; DOC81 restamp eligibility)
  payload_schema_ref?: string;           // UR-14b: ref to the trigger's payload schema (Stage 7 / owning plane)
  introduced_in: string;                 // UR-14b: provenance pin
  deprecated_in?: string;                // UR-14b
  retired_in?: string;                   // UR-14b
  replacement_trigger_kind?: WarrantDegradationTriggerKind; // UR-14b: redirect when deprecated/retired
  default_reason_code?: string;          // UR-14b: ReasonCode id (§2.1) emitted on this trigger by default
  lifecycle_state: RegistryEntryLifecycleState; // §1.6 (A9/F7): registry-entry lifecycle, not memory-object lifecycle
}

interface WarrantDegradationTriggerRegistry {
  registry_id: 'doc80.warrant_degradation_trigger_registry';
  schema_owner: 'DOC80';
  is_initial_controlled_registry: true;   // ADQ-312: initial, not permanently exhaustive
  triggers: WarrantDegradationTrigger[];
  // a new trigger_kind MUST arrive via a new ADQ (architect approval)
}
```

**Per-trigger execution owners (ADQ-312, as reframed at Stage 5R2c):** `user_correction` → EC; `time_window` → DOC84 (DAMS substrate); `confidence` → DOC84 (DAMS substrate); `contrary_source` → EC; `policy_change` → PropA/EC; `supporting_CU_stale` → DOC73; `parse_quality_audit` → DOC25; `proof_gated_outcomes` → DOC85; `session_bound_expiry` → DOC24. The Stage 5R2c reframe reassigned the former `DAMS V5` owner to `DOC84 (DAMS substrate)` per SM-020 and purged `DOC8` per ADQ-221 (its `proof_gated_outcomes` trigger moved to DOC85).

**Warrant-degradation carveout (UR-22).** Certain content is **exempt** from time/confidence-style degradation: user-asserted durable facts, authority-fixed content, static facts, fixed citations / dates / named entities, and user-locked memories. The exemption is keyed off an `authority_class` enum — `'user_asserted' | 'authority_fixed' | 'source_derived' | 'inferred'` — that is **owned by DOC82/DOC81** (the knowledge/policy planes), referenced here, not redefined. A degradation trigger MUST NOT lower eligibility on `user_asserted`, `authority_fixed`, or user-locked content; only `source_derived` / `inferred` content degrades on time/confidence triggers. (Re-proof through a fresh `EvidenceSupportEdge`, §12, remains the only eligibility-raising path for any class.)

**Carveout lints (Stage 9):** `warrant_degradation.authority_fixed_fact_degraded`; `warrant_degradation.static_fact_degraded`; `warrant_degradation.user_locked_memory_degraded`.

**Lifecycle + monotonicity.** *Emitting* a warrant-degradation trigger lowers or holds warrant eligibility — trigger emission never raises it (§12; Skeletal §11.9). This rule governs **trigger emission only**; it does **not** govern the §12.1 source-revocation recompute, where removing a *contrary* source MAY raise net warrant if the recompute trace proves why (the polarity-aware case in §12). Re-proof through a fresh `EvidenceSupportEdge` to a non-revoked source also raises eligibility, and that path runs through DOC82, not this registry.

**Unhappy paths.** *New trigger kind without an ADQ* → blocked, `warrant_trigger.new_kind_without_adq`. *A trigger raises eligibility* → monotonicity violation (§12). *Producer owner unassigned* → registry-integrity lint.

**Lints (Stage 9):** `warrant_trigger.new_kind_without_adq`; `warrant_trigger.emission_raised_eligibility` (ties §12 `monotonicity.revocation_raised_eligibility`); `warrant_trigger.producer_owner_unassigned`.

**Fixtures (Stage 8):** `fixture.warrant_trigger.registry_matches_adq312_owner_table`; `fixture.warrant_trigger.degradation_is_monotonic`.

**Cross-charter consumption.** DOC85/E9 (producers — the learning member emits degradation signals), DOC82/E3 (the warrant ladder `EpistemicKind / UseWarrant / EffectiveWarrant` consumes degradation), DOC81/E2 (`policy_change` feeds restamp eligibility per ADQ-316). The DAMS-substrate triggers (`time_window`, `confidence`) are executed inside DOC84 (E7).

---

## §3. Cross-cutting consumption contracts

These are the contracts downstream members **bind to** for context-of-use. DOC80 owns the contract; the implementation/assembly is owned downstream (Skeletal §1.2 cross-cutting-contract carve-out). Field-level stability here is a precondition for DOC84 (E7/E8) authoring (Input Deck open seam).

### §3.1 ContextProduct contract (ADQ-203)

**Source:** ADQ-203 (resolved — "define ContextProduct contract in DOC80 core; DOC24 owns packet assembly using it"); **ABC R0.2 §9.2 (canonical 17-kind registry — senior per DR-001/Skeletal §3.3; target-freeze input)**; SM-060 (`merge_into_target` — closed registry; ad-hoc cards retired; its stale "14" superseded by ABC §9.2's 17, no 17→14 merge exists); Owner Map lines 125–126 (B3 split: registry @ DOC80, assembly @ DOC84). **Owner:** DOC80 core (registry). **Assembly owner:** DOC84. **Executor:** DOC24. **Consumers:** DOC86 (surfaces several kinds), DOC83 (orientation inputs), DOC87 (membership inputs).

The ContextProduct registry is a **fixed set of 17 product kinds** enumerated by **ABC R0.2 §9.2** (UR-01; verified directly — ABC is senior per DR-001/Skeletal §3.3 and a target-freeze input). SM-060's earlier "14" count is **superseded** (there is no 17→14 merge rationale; the earlier draft's 14 names matched no canonical source). Ad-hoc "memory cards" / "KDA render cards" are retired (Retired Names SM-060) — every product passing through delivery must be a registered kind, which guards the "unregistered content type" failure (Commission §1.6; cf. DOC20 §6.18.2 lesson). The registry is the *what*; DOC84 owns the *how* (assembly contract); DOC24 *executes*.

```typescript
/** Canonical 17-kind registry — ABC R0.2 §9.2 (senior per DR-001/Skeletal §3.3; target-freeze input).
 *  Supersedes SM-060's stale "14" (no 17→14 merge exists).
 *  The registry is closed: a product not in this canonical union is an unregistered
 *  content type (block + lint). NOTE: resume is now ResumeProjection/ResumeCard (§5.3,
 *  a NAMED concept), NOT a ContextProductKind. */
type ContextProductKind =
  | 'assertion_packet' | 'direct_memory_item' | 'topic_notice' | 'topic_slice'
  | 'library_notice' | 'library_source_slice' | 'cu_source_bound_synthesis'
  | 'recent_work_orientation' | 'issue_frame_orientation' | 'directive_block'
  | 'procedure_block' | 'warning_constraint' | 'null_result_notice'
  | 'conflict_notice' | 'search_affordance' | 'reference_only_notice' | 'blocked_scope_notice';

/** ABC §9.3-aligned registry entry (UR-01; replaces the prior ContextProductDescriptor).
 *  MemoryObjectRole / UseWarrant / SupportRole are DOC82-owned (§1.6 helper-type ownership);
 *  WarrantedItemHeader is ABC §9.6 (DOC82-owned). All referenced, never redefined here. */
interface ContextProductRegistryEntry extends E0DurableRecord {
  kind: ContextProductKind; registry_owner: 'DOC80'; payload_schema_owner: OwnerDocId;
  assembly_contract_owner: 'DOC84'; packet_executor: 'DOC24';
  role_band: 'constraint' | 'assertion' | 'source' | 'orientation' | 'affordance';   // ABC §9.3
  allowed_roles: MemoryObjectRole[];                                                  // ABC §9.3
  allowed_warrants: UseWarrant[]; allowed_support_roles: SupportRole[];               // ABC §9.3 (DOC82-owned types)
  header_fields_required: (keyof WarrantedItemHeader)[];                              // ABC §9.3 keyof typing
  header_fields_na: (keyof WarrantedItemHeader)[];                                    // ABC §9.3
  default_budget_band: BudgetBand; evictable: boolean; degrades_to?: ContextProductKind;
  learning_target: 'allowed' | 'disallowed' | 'manifest_only';                        // == ABC LearningTarget
  candidate_injectable: boolean; final_prompt_instance_spine_required: boolean;       // ties UR-02 / ABC §9.5
  policy_gated: true;               // every product passes EffectiveMemoryPolicy (DOC81) before delivery
  membership_consumed?: boolean;    // true if the product reads MemoryMembershipEdge (DOC87); must honor injection_eligible
  audit_replay_class: 'canonical' | 'durable_audit' | 'derived' | 'transient' | 'external_ref' | 'named_only';  // A11
}

/** schema_owner = DOC80 core (ADQ-203). DOC84 binds; DOC24 executes; each instance
 *  carries a MemoryCoordinationTrace ref (§3.4). */
interface ContextProductProductionContract {
  contract_id: 'doc80.context_product_production_contract';
  schema_owner: 'DOC80';
  registry: ContextProductRegistryEntry[];   // the canonical 17 kinds (ABC R0.2 §9.2)
  determinism_rule: 'product_is_a_pure_function_of_named_inputs'; // guards "magical context behavior"
  required_inputs_by_kind: Record<ContextProductKind, ContextProductInputSpec>; // input object REFS only; per-kind assembly bodies are DOC84 (UR-16)
}

interface ContextProductInputSpec {
  named_inputs: string[];   // explicit input object refs — NO implicit "the system figures it out"
  policy_inputs: string[];  // EffectiveMemoryPolicy / ScopeResolutionResult refs (DOC81)
  proof_outputs: string[];  // proof artifacts the assembly must produce
}
```

**Determinism (anti-"magical context").** A ContextProduct MUST be a pure function of its `named_inputs` + `policy_inputs`. Nothing is assembled from inputs not named in the descriptor; this is what makes a packet reproducible and proof-anchorable.

**Lifecycle.** A product instance moves `planned (MemoryContextPlan) → assembled (DOC24) → policy-gated (DOC81) → proven (proof spine) → delivered`. Orientation-`role_band` products (`recent_work_orientation`, `issue_frame_orientation`) carry the can-orient-only invariant and may never cross into evidence (ADQ-405 / SM-108; enforced at §6 taxonomy + §12). Resume is delivered as `ResumeProjection`/`ResumeCard` (§5.3) — a NAMED projection, **not** a `ContextProductKind`.

**Unhappy paths.** *Unregistered kind* → block + `context_product.kind_not_in_registry`. *Assembled without policy gate* → block. *Non-deterministic inputs* → lint. *Orientation product used as evidence* → block (RecentActivityRollup `can_orient_only`). *Membership-consuming product injects a `removed`/`blocked` edge* → block (DOC87 `injection_eligible` totality, §12). *Empty* — no eligible content → emit `null_result_notice` (itself a registered kind), never a silent empty packet.

**Lints (Stage 9):** `context_product.kind_not_in_registry`; `context_product.assembled_without_policy_gate`; `context_product.nondeterministic_inputs`; `context_product.orientation_used_as_evidence`; `context_product.injected_removed_or_blocked_membership`.

**Fixtures (Stage 8):** `fixture.context_product.registry_has_exactly_17_kinds`; `fixture.context_product.deterministic_from_named_inputs`; `fixture.context_product.policy_gate_precedes_delivery`; `fixture.context_product.empty_emits_null_result_notice`.

**Cross-charter consumption.** **DOC84/E7–E8** owns the assembly contract and binds directly; **DOC24** executes assembly (the primary external consumer — DOC24 binds to this contract per ADQ-203); **DOC86/E10** surfaces `search_affordance`, `null_result_notice`, `reference_only_notice`, `blocked_scope_notice`, `conflict_notice`, `topic_notice`, `library_notice` (the affordance/notice-band kinds; Inspector explanation is backed by `MemoryCoordinationTrace` §3.4, not a `ContextProductKind`); **DOC83/E5–E6** supplies orientation inputs (`recent_work_orientation`, `issue_frame_orientation`); **DOC87/E_org** supplies membership inputs.

#### §3.1.1 Registry seed table (UR-01 / A3/A10 — ABC §9.3-confirmed cells only; owners NOT guessed)

One row per ABC §9.2 kind. **`role_band`** is filled where ABC §9.2's `RoleBand` enum + §9.7 product-specific rules make it unambiguous; **`payload_schema_owner`**, **`candidate_injectable`**, **`default_budget_band`**, and the genuinely-ambiguous `role_band` cells are marked **`⚠owner-confirm@E3/E4/E7`** — ABC §9.3 defines these as *columns* but does not tabulate per-kind *values*, and owners are not guessed (Commission §3 fork 2). Each ⚠ cell is confirmed at the owning member's charter.

| kind | role_band | payload_schema_owner | candidate_injectable | default_budget_band |
|---|---|---|---|---|
| `assertion_packet` | assertion | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `direct_memory_item` | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `topic_notice` | affordance | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `topic_slice` | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `library_notice` | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `library_source_slice` | source | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `cu_source_bound_synthesis` | source | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `recent_work_orientation` | orientation | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `issue_frame_orientation` | orientation | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `directive_block` | constraint | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `procedure_block` | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `warning_constraint` | constraint | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `null_result_notice` | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `conflict_notice` | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `search_affordance` | affordance | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `reference_only_notice` | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |
| `blocked_scope_notice` | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 | ⚠owner-confirm@E3/E4/E7 |

**Column → confirming charter (M-1).** `payload_schema_owner` is confirmed at the kind's payload-owning plane (E3/E4); `role_band`, `candidate_injectable`, and `default_budget_band` are confirmed at delivery (E7/E8). Each `⚠owner-confirm@E3/E4/E7` cell resolves per this column mapping at the owning member's charter.

**Lint (Stage 9):** `registry.context_product_owner_guessed` [proposed] — fires on any non-`⚠` `payload_schema_owner` cell lacking an ABC/Owner-Map citation. The disposition decision (per-kind) is the **`ContextProductDecision`** (NAMED-only; body owned by **DOC84** per ABC §9.4):

```typescript
/** Per-product runtime disposition. NAMED-only here; body owned by DOC84 (ABC §9.4 disposition enum).
 *  Disposition vocabulary == ContextProductDecisionDisposition (§3.2; ABC §9.4) — do NOT coin a parallel set. */
interface ContextProductDecision {
  context_product_instance_id: string;     // ABC §9.5 instance-ID spine
  product_kind: ContextProductKind;
  disposition: ContextProductDecisionDisposition;  // §3.2 / ABC §9.4
  // remaining fields (omission_cost, contamination_risk, policy_decision_refs, scope_relation,
  // dams_output_ref?, reason_codes) are DOC84 body — ABC §9.4; NAMED-only at E0.
}
```

#### §3.1.2 ReproducibilityKey (UR-19) — determinism over content + selected-product set

```typescript
/** A packet is reproducible iff its ReproducibilityKey is. Ranges over content + the selected-product set.
 *  Branded-string IDs per §8.5 / §1.6. (N2 adds the three registry-version inputs.) */
interface ReproducibilityKey {
  request_input_hash: ContentHash;
  policy_generation_id: PolicyGenerationId;
  context_product_registry_version: SchemaVersionRef;
  memory_context_plan_version: SchemaVersionRef;
  prompt_shell_variant_id: PromptShellVariantId;
  shell_weight_generation_id: GenerationId;
  utility_bundle_generation_id: GenerationId;
  source_generation_id: GenerationId;
  membership_generation_id: GenerationId;
  budget_profile_id: BudgetProfileId;
  domain_profile_id: DomainProfileId;
  warrant_degradation_trigger_registry_version: SchemaVersionRef;   // N2
  reason_code_registry_version: SchemaVersionRef;                   // N2
  domain_profile_registry_version: SchemaVersionRef;                // N2
}
```

**Invariant:** *identical key ⇒ identical content + selected set; any learned weight MUST be a named input.* **Lints (Stage 9):** `determinism.learned_weight_not_named_input`; `determinism.degradation_or_reasoncode_registry_version_not_named_input` (N2).

### §3.2 MemoryContextPlan contract (ADQ-211; three-plan model per ADQ-209)

**Source:** ADQ-211 (resolved — "define contract in DOC80 core; DOC24 owns packet assembly"); ADQ-209 (three-plan model necessary; `MemoryCoordinationTrace` ties them); Owner Map lines 127–128 (B3 split: contract @ DOC80, implementation @ DOC84). **Owner:** DOC80 core (contract). **Implementer:** DOC84. **Consumer:** DOC24. **Sibling planes:** `ExtractionContextPlan` (DOC83-owned), `UserContextSurfacePlan` (DOC86-owned).

The three-plan model (ADQ-209) deliberately separates extraction, injection, and UI so they are never treated as one blob. DOC80 owns **only** the `MemoryContextPlan` (the injection/context-of-use plane); the other two planes are owned by their members. What ties the three together is `MemoryCoordinationTrace` (§3.4). The `EffectiveMemoryPolicy` reference here is a *consumption-protocol pointer* only — the schema is wholly DOC81's (Owner Map line 80 / B4 correction; ADQ-211 covers `MemoryContextPlan`, not `EffectiveMemoryPolicy`).

```typescript
/** Context-of-use contract. schema_owner = DOC80 core (ADQ-211). DOC84 implements;
 *  DOC24 consumes. One of three planes (ADQ-209); the others — ExtractionContextPlan
 *  (DOC83) and UserContextSurfacePlan (DOC86) — are sibling planes tied by
 *  MemoryCoordinationTrace (§3.4 / SM-100). */
interface MemoryContextPlan {
  plan_id: string;
  schema_owner: 'DOC80';
  coordination_trace_ref: MemoryCoordinationTraceRef;   // ties the three planes (ADQ-209 / SM-100)
  scope_resolution_ref: ScopeResolutionResultRef;       // DOC81-owned
  effective_policy_ref: EffectiveMemoryPolicyRef;       // consumption-protocol pointer only; schema @ DOC81 (Owner Map line 80)
  policy_generation_id: string;                          // epoch this plan was computed under (EpisodePolicyEpoch / SM-101)
  requested_products: MemoryContextProductRequest[];     // per-product request grammar (UR-15 / ADJ-1); see below
  determinism_inputs_ref: string;                        // MemoryContextPlanDeterminismInputs @ DOC84 (Owner Map line 153)
  sibling_plans: {
    extraction_context_plan_ref?: string;                // DOC83-owned (ExtractionContextPlan)
    user_context_surface_plan_ref?: string;              // DOC86-owned (UserContextSurfacePlan)
  };
  degraded_mode?: MemoryContextPlanDegradedMode;
}

type MemoryContextPlanDegradedMode = // proposed value set — Stage 7 confirms
  | 'policy_disambiguation_pending'  // PolicyDisambiguationRequest interrupted assembly → pipeline park/resume @ DOC84 (F-async)
  | 'scope_unresolved_conservative'  // scope resolution incomplete → conservative domain profile (§2.2)
  | 'proof_artifact_missing'         // a required proof is absent → affected product withheld
  | 'membership_unavailable';        // DOC87 read-model unavailable → membership products withheld

type MemoryCoordinationTraceRef = string;
type ScopeResolutionResultRef = string;
type EffectiveMemoryPolicyRef = string;
```

**Per-product request/disposition grammar (UR-15 + ADJ-1).** Each requested product is an explicit request with allowed dispositions, a budget ceiling, an optional fallback, and required proofs:

```typescript
interface MemoryContextProductRequest {
  request_id: string;
  kind: ContextProductKind;
  purpose: 'answer' | 'orientation' | 'constraint' | 'source_support' | 'search_affordance' | 'warning' | 'carryover';
  priority: 'must_include' | 'high' | 'normal' | 'low';
  allowed_dispositions: ContextProductDecisionDisposition[];
  max_budget_band: BudgetBand;
  fallback_kind?: ContextProductKind;
  required_proofs: ('context_packet_proof' | 'render_safety_proof' | 'memory_flow_certificate' | 'final_prompt_truth_ref')[];
}

/** ABC §9.4 disposition enum — canonical (ADJ-1); do NOT coin a parallel set. */
type ContextProductDecisionDisposition =
  | 'inject_inline' | 'inject_compact' | 'reference_only' | 'notice_only'
  | 'search_affordance_only' | 'blocked' | 'suppressed_manifest_only';

// DOC84 records MemoryContextProductOutcome { request_id; decision_ref /* ABC §9.4 */; reason_codes } — body @ DOC84.
```

The **three-plan model (ADQ-209)** is CONFIRMED: `MemoryContextPlan` (this plane), `ExtractionContextPlan` (DOC83), `UserContextSurfacePlan` (DOC86), tied by `MemoryCoordinationTrace` (§3.4).

**Lifecycle.** A plan is computed under a `policy_generation_id`; if that generation changes before delivery, the plan MUST be recomputed (re-plan), never silently delivered (ties §8.3 extraction-side re-gate and OPA-031 resolution-side re-gate).

**Unhappy paths.** *Stale policy generation used* → block + re-plan. *Missing coordination trace* → integrity lint (the three planes must share one trace). *Requested product not in the registry* → block (§3.1). The four `degraded_mode` values enumerate the non-happy assembly outcomes explicitly (guards "missing degraded states").

**Lints (Stage 9):** `memory_context_plan.stale_policy_generation_used`; `memory_context_plan.missing_coordination_trace`; `memory_context_plan.requested_product_not_in_registry`; `context_plan.must_include_product_silently_dropped` (UR-15); `context_plan.fallback_kind_not_in_registry` (UR-15); `context_plan.required_proof_missing_for_product` (UR-15); `context_plan.product_request_without_outcome` (UR-15); `context_plan.disposition_not_in_abc_94_enum` (ADJ-1).

**Fixtures (Stage 8):** `fixture.memory_context_plan.three_planes_share_coordination_trace`; `fixture.memory_context_plan.policy_change_forces_replan`; `fixture.memory_context_plan.degraded_modes_enumerated`.

**Cross-charter consumption.** DOC84/E7–E8 (implements), DOC24 (consumes/binds per ADQ-211), DOC83/E5–E6 (`ExtractionContextPlan` sibling), DOC86/E10 (`UserContextSurfacePlan` sibling), DOC81 (scope/policy refs). Field-level stability is a precondition for DOC84 authoring (Input Deck open seam).

### §3.3 MemoryFlowCertificate (ADQ-207; Owner Map line 150)

**Source:** ADQ-207 (resolved — "mandatory for durable write, render, export, carryover, delegation, learning attribution; NOT required for every internal candidate read"); SM-050; Owner Map line 150. **Owner:** DOC80 core. **Executors:** EC / DOC1 / DOC24 / KDA / DOC11 / DOC85 (Owner Map line 150 — DOC8 purged per ADQ-221; runtime learning execution is DOC85). **Issuing seam:** EC.

The `MemoryFlowCertificate` is the mandatory certificate for the **nine** privileged memory movements (the six original flows + the litigation proof layer `erasure` / `policy_restamp` / `restore`, added as per-event **certificate shells, not a lifecycle engine** — UR-29 stands). It is the contract that makes "every durable effect leaves a proof" enforceable. Internal candidate reads are exempt (ADQ-207) so the certificate does not become bureaucratic overhead on hot-path reads.

```typescript
/** MFC discriminated union (UR-03/04). Nine flow kinds. Ref/ID types (…Ref / …Id) are branded
 *  strings per §8.5 / §1.6. `initiating_member_ref` (R3 §(b)#2) names the member that initiated the
 *  flow; EC remains the sole `issued_by` / durable executor. */
type MemoryFlowKind =
  | 'durable_write' | 'render' | 'export' | 'carryover' | 'delegation' | 'learning_attribution'
  | 'erasure' | 'policy_restamp' | 'restore';   // +3 litigation proof layer

interface BaseMFC extends E0DurableRecord {
  certificate_id: MemoryFlowCertificateId;
  schema_owner: 'DOC80';
  issued_by: 'EC';                                   // EC is the sole durable-writer / certifier seam (§1.5)
  initiating_member_ref: ProducerDocRef;             // R3 §(b)#2: who initiated (was per-variant `executor`); EC still issues
  coordination_trace_ref: MemoryCoordinationTraceRef;
  policy_generation_id: PolicyGenerationId;
  effective_policy_ref: EffectiveMemoryPolicyRef;
  effective_state_generation_id: EffectiveStateGenerationId;  // EC §1 effective-state gating
  ec_path: 'serialized_durable' | 'anchored_attestation';
}

interface WithheldMFC extends BaseMFC { outcome: 'withheld'; flow_kind: MemoryFlowKind;
  withheld_reason_codes: ReasonCodeId[]; }                                          // plural (N6)
interface DurableWriteMFC extends BaseMFC { outcome: 'issued'; flow_kind: 'durable_write'; ec_path: 'serialized_durable';
  mutation_envelope_ref: MemoryMutationEnvelopeRef; }
interface RenderMFC extends BaseMFC { outcome: 'issued'; flow_kind: 'render'; ec_path: 'anchored_attestation';
  render_target: 'executed_prompt' | 'preview' | 'export_render';                  // F5/A4
  context_packet_proof_ref: ContextPacketProofRef; render_safety_proof_ref: RenderSafetyProofRef;
  outbound_destination_class: E0OutboundDestinationClass;                          // render_to_model→cloud_api is egress (§22, S-1)
  disclosure_scope_attestation_ref?: DisclosureScopeAttestationRef;                // required iff outbound_destination_class !== 'same_machine_local_runtime'; resolves to E0EgressAttestation (§22)
  final_prompt_truth_ref?: FinalPromptTruthRefId; }                                // required iff render_target==='executed_prompt'
interface ExportMFC extends BaseMFC { outcome: 'issued'; flow_kind: 'export'; ec_path: 'anchored_attestation';
  context_packet_proof_ref: ContextPacketProofRef; export_manifest_ref: ExportManifestRef;
  outbound_destination_class: E0OutboundDestinationClass;                          // R3 §(b)#10 (N8): destination carried on the MFC
  disclosure_scope_attestation_ref: DisclosureScopeAttestationRef;                 // resolves to E0EgressAttestation (§22)
  final_prompt_truth_ref?: FinalPromptTruthRefId; }
interface CarryoverMFC extends BaseMFC { outcome: 'issued'; flow_kind: 'carryover'; ec_path: 'anchored_attestation';
  context_packet_proof_ref: ContextPacketProofRef; carryover_capsule_ref: CarryoverCapsuleRef; }
interface DelegationMFC extends BaseMFC { outcome: 'issued'; flow_kind: 'delegation'; ec_path: 'anchored_attestation';
  context_packet_proof_ref: ContextPacketProofRef; delegation_payload_ref: DelegationPayloadRef;
  outbound_destination_class: E0OutboundDestinationClass;                          // R3 §(b)#10 (N8)
  disclosure_scope_attestation_ref: DisclosureScopeAttestationRef; }               // resolves to E0EgressAttestation (§22)
interface LearningAttributionMFC extends BaseMFC { outcome: 'issued'; flow_kind: 'learning_attribution'; ec_path: 'serialized_durable';
  context_packet_proof_ref: ContextPacketProofRef; final_prompt_truth_ref: FinalPromptTruthRefId; learning_signal_ref: LearningSignalRef; }
// ---- litigation proof layer (certificate shells; NOT lifecycle engines — UR-29 affirmed) ----
interface ErasureMFC extends BaseMFC { outcome: 'issued'; flow_kind: 'erasure'; ec_path: 'serialized_durable';
  erasure_kind: 'soft_tombstone' | 'hard_destruction' | 'redaction'; mutation_envelope_ref: MemoryMutationEnvelopeRef;
  legal_hold_clearance_ref?: LegalHoldClearanceRef;   // R3 §(b)#8: required iff erasure_kind ∈ {hard_destruction, redaction}; soft_tombstone ungated
  authorized_by: ActorRef; irreversibility_attested: boolean; reason_codes: ReasonCodeId[]; }
interface RestampMFC extends BaseMFC { outcome: 'issued'; flow_kind: 'policy_restamp'; ec_path: 'serialized_durable';
  mutation_envelope_ref: MemoryMutationEnvelopeRef; prior_policy_generation_id: PolicyGenerationId;
  original_ceiling_ref: PolicyCeilingRef; ceiling_compliance_attested: boolean;     // restamp cannot exceed original ceiling (ADQ-316)
  authorized_by: ActorRef; reason_codes: ReasonCodeId[]; }
interface RestoreMFC extends BaseMFC { outcome: 'issued'; flow_kind: 'restore'; ec_path: 'serialized_durable';
  restored_from: 'recycle_bin' | 'backup';
  prior_erasure_certificate_ref?: MemoryFlowCertificateId;   // R3 §(b)#9: required iff restored_from==='recycle_bin'
  mutation_envelope_ref: MemoryMutationEnvelopeRef;          // R3 §(b)#2: `executor` removed; use BaseMFC.initiating_member_ref
  authorized_by: ActorRef; reason_codes: ReasonCodeId[]; }
type MemoryFlowCertificate =
  | WithheldMFC | DurableWriteMFC | RenderMFC | ExportMFC | CarryoverMFC | DelegationMFC | LearningAttributionMFC
  | ErasureMFC | RestampMFC | RestoreMFC;

type ContextPacketProofRef = string;
type RenderSafetyProofRef = string;
```

**Mandatory invocation points (ADQ-207, extended):** the nine `flow_kind` values. Internal candidate reads are exempt — a certificate is required only when memory crosses a durable / external / learning / erasure / restamp / restore boundary. **Delivery attestations (`render` / `export` / `carryover` / `delegation`) take `ec_path: 'anchored_attestation'` — EC-signed against a read-consistent policy generation, and MUST NOT take a write-queue lock**; durable flows (`durable_write` / `learning_attribution` / `erasure` / `policy_restamp` / `restore`) take `ec_path: 'serialized_durable'`.

**Lifecycle.** A flow is either `issued` (proof obligations satisfied) or `withheld` (an obligation failed → carries `withheld_reason_codes`). A withheld certificate blocks the movement; it is never a silent no-op.

**Unhappy paths.** *Durable write without certificate* → block + `proof.durable_write_without_memory_flow_certificate`. *Export / carryover / delegation / learning without certificate* → the corresponding `proof.*` lint (Skeletal §5). *Issued by a non-EC actor* → `proof.durable_write_by_non_ec_actor`. *Withheld* → blocked movement + reason code surfaced to operator.

**Lints (Stage 9):** `proof.durable_write_without_memory_flow_certificate`; `proof.render_without_memory_flow_certificate`; `proof.export_without_memory_flow_certificate`; `proof.carryover_without_memory_flow_certificate`; `proof.delegation_without_memory_flow_certificate`; `proof.learning_attribution_without_memory_flow_certificate`; `proof.learning_signal_without_context_packet_proof`; `proof.durable_write_by_non_ec_actor`; `proof.withheld_certificate_missing_reason_code`; `proof.flow_kind_required_ref_missing`; `proof.executed_prompt_render_missing_final_prompt_truth`; `ec.delivery_attestation_on_serialized_write_path`; `mfc.effective_state_generation_missing`; `mfc.uses_executor_field_instead_of_initiating_member` (R3 §(b)#2). **Erasure/restamp/restore lints:** `erasure.without_memory_flow_certificate`; `erasure.hard_destruction_without_legal_hold_clearance_ref`; `erasure.redaction_under_legal_hold_without_clearance` (R3 §(b)#8); `erasure.certificate_not_durable_audit_retained`; `restamp.without_memory_flow_certificate`; `restamp.exceeds_original_ceiling` (ADQ-316); `restamp.certificate_not_durable_audit_retained`; `restore.without_memory_flow_certificate`; `restore.reintroduces_revoked_or_held_material` (R3 §(b)#9); `restore.of_hard_destruction` (R3 §(b)#9); `learning.credit_from_preview_render` (F5). (All erasure/restamp/restore tokens `[proposed]`; `proof.*` + the two canonical erasure tokens in §1.4 are verbatim-source.)

**Fixtures (Stage 8):** `fixture.memory_flow.durable_write_requires_certificate`; `fixture.memory_flow.internal_candidate_read_exempt`; `fixture.memory_flow.withheld_carries_reason_code`; `fixture.memory_flow.executed_prompt_render_requires_final_prompt_truth`; `fixture.memory_flow.delivery_attestation_off_write_queue`.

**Cross-charter consumption.** EC (issuing seam + executor), DOC85/E9 (learning attribution), DOC84/E7–E8 (render/carryover), DOC11 (finalizes), DOC1 (write-gate execution), DOC24 (export/packet). Every member's durable/delivery/export path binds here.

### §3.4 MemoryCoordinationTrace (SM-100; ADQ-209) — full schema

**Source:** SM-100 (`absorb_as_target_rule` — "connects ExtractionContextPlan / MemoryContextPlan / UserContextSurfacePlan + manifests + proofs + learning events; Inspector explanation backed by trace"); ADQ-209; Owner Map line 204. **Owner:** DOC80 core. **Placement justification (deviation note):** the §3.1 outline lists three subsections; `MemoryCoordinationTrace` is added here as §3.4 because ADQ-209 makes it the object that *ties the three plans together* — it is topically inseparable from §3.2 and is a DOC80-core-owned schema (Owner Map line 204), so it earns a full schema body even though it is not in the Commission §3.3 mandatory list (overshoot-not-miss, Commission §1.5).

`MemoryCoordinationTrace` is the **per-request** spine that threads a single memory operation across the three plans, the injection manifests, the proof artifacts, and any learning events. It is distinct from `MemoryProvenanceGraph` (§5.2), which is the **durable cross-request** PROV graph.

```typescript
/** Per-request coordination spine. schema_owner = DOC80 core (SM-100 / Owner Map line 204).
 *  Distinct from MemoryProvenanceGraph (§5.2 — durable, cross-request). */
interface MemoryCoordinationTrace {
  trace_id: string;
  schema_owner: 'DOC80';
  session_ref: string;              // UR-20: correlation across turns
  turn_id: string;                  // UR-20
  request_correlation_id: string;   // UR-20: ties all plans/proofs/events of one request
  parent_trace_ref?: string;        // UR-20: nested/derived requests
  request_kind: 'extraction' | 'delivery' | 'inspection' | 'learning' | 'membership_mutation';
  policy_generation_id: string;
  plan_refs: {
    extraction_context_plan_ref?: string;   // DOC83
    memory_context_plan_ref?: string;        // DOC80 contract / DOC84 impl (§3.2)
    user_context_surface_plan_ref?: string;  // DOC86
  };
  manifest_refs: string[];                   // PacketInjectionManifest / FinalPromptInjectionManifest (DOC24-owned) refs
  proof_refs: {
    context_packet_proof_ref?: ContextPacketProofRef;
    render_safety_proof_ref?: RenderSafetyProofRef;
    memory_flow_certificate_refs?: string[];
  };
  learning_event_refs?: string[];            // DOC85 learning signals attributed to this request
  reason_code_refs?: string[];               // ReasonCode ids explaining decisions (§2.1)
  outcome: 'completed' | 'degraded' | 'blocked';
}
```

**Lifecycle.** `open → (plans attached) → (manifests + proofs attached) → completed | degraded | blocked`. The Inspector (DOC86 §2) renders an explanation *backed by* the trace — the trace is the audit substrate for "why did the system do that."

**Unhappy paths.** *Trace missing for a delivery/durable request* → integrity lint. *Degraded* — a plan or proof is missing → `outcome = degraded` with reason codes. *Blocked* — a hard gate failed → `outcome = blocked` with reason codes. A trace is never silently absent on a privileged flow.

**Instance-ID spine (ADJ-2; ABC §9.5).** The `context_product_instance_id` spine (ABC §9.5) threads each product through manifests, render patches, and the final-prompt injection manifest, and is what **utility/learning attribution uses** — attributed to **DOC85** (the DOC8 reference is phantom per ADQ-221; runtime learning is DOC85). A learning attribution missing the instance-ID is caught by `context_product.instance_id_missing_from_learning_attribution`.

**Lints (Stage 9):** `coordination_trace.missing_on_privileged_flow`; `coordination_trace.proof_ref_dangling`; `coordination_trace.plan_ref_dangling`; `memory_coordination_trace.missing_turn_correlation` (UR-20); `context_product.instance_id_missing_from_learning_attribution` (ADJ-2).

**Fixtures (Stage 8):** `fixture.coordination_trace.threads_three_planes`; `fixture.coordination_trace.backs_inspector_explanation`.

**Cross-charter consumption.** Every plane references the trace; DOC86/E10 renders it in the Inspector; DOC85/E9 attaches learning events; DOC84/E7–E8 attaches manifests + proofs.

### §3.5 FinalPromptTruthRef — NAMED-only E0 hook (UR-02; Skeletal §18; ADQ-207)

**NAMED-only.** **Runtime-truth body owner:** DOC11 / OpenClaw. **E0 role:** names the dependency + binds the family invariants; it does **not** draft the schema (ChatGPT's full schema is REJECTED — mis-owns DOC11). It **carries** (Stage 7 / DOC11 drafts the fields, *conceptually not as a schema here*): `final_prompt_text_hash`, the injection-manifest ref, rendered / trimmed / suppressed span refs, the `context_product_instance_id` spine, `prompt_shell_variant` refs, the DOC11 finalizer ref, and the runtime session / model-execution ref.

**Invariant.** Final-prompt truth is **required for executed-prompt render and for ANY learning/utility credit**; preview/export-only render may use other proof targets but yields **no** learning credit. (Wired into the MFC union: `RenderMFC.final_prompt_truth_ref` is required iff `render_target==='executed_prompt'`; `LearningAttributionMFC.final_prompt_truth_ref` is required — §3.3.)

**Lints (Stage 9):** `learning.utility_without_final_prompt_proof` [canonical]; `learning.utility_credit_for_trimmed_span` [proposed]; `learning.utility_credit_for_suppressed_span` [proposed]; `render.context_product_instance_id_lost_before_final_prompt` [proposed]. **Cross-charter:** DOC11 (body), DOC85/E9 (learning gate), DOC84/E7–E8 (render). *Traceability:* Skeletal §18, ADQ-207, ABC §9.5.

### §3.6 SemanticProjectionContract (UR-31) — umbrella + axis registration

**Source:** UR-31 (ACCEPT · BUG · P1 — define the named-but-undefined contract); Skeletal §11.10 (SemanticProjection narrowed at Stage 5R2b); Owner Map line 209. **Owner:** DOC80 core (the umbrella contract). A projection is a derived view that **may never own truth**; the four concrete projections are owned by their planes.

```typescript
interface SemanticProjectionContract {
  schema_owner: 'DOC80';
  projection_may_own_truth: false;
  required_fields: ['source_refs', 'generation_id', 'invalidation_policy_ref', 'projection_owner', 'proof_or_read_model_refs'];
  allowed_axes: ('delivery' | 'ui' | 'organization' | 'knowledge')[];
}

interface SemanticProjectionAxisRegistration {
  axis: 'delivery' | 'ui' | 'organization' | 'knowledge';
  concrete_projection_schema: 'DeliveryProjection' | 'UIProjection' | 'OrganizationProjection' | 'KnowledgeProjection';
  schema_owner: 'DOC82' | 'DOC84' | 'DOC86' | 'DOC87';   // knowledge→DOC82, delivery→DOC84, ui→DOC86, organization→DOC87
  canonical_truth_owner: OwnerDocId;
  invalidation_policy_owner: OwnerDocId;
}
```

`ResumeProjection`/`ResumeCard` (§5.3) is a `DeliveryProjection`-axis case; `SourceBoundSynthesisAdapter` is a `KnowledgeProjection` wrapper case (Owner Map). **Lints (Stage 9):** `projection.used_as_canonical_truth` [canonical]; `projection.owner_missing` [canonical]; `projection.missing_invalidation_policy` [canonical]; `projection.missing_source_refs` [canonical]; `projection.generation_id_missing` [proposed]. Cross-refs updated at §6.3 (taxonomy projection invariant) and §17.3 (Owner Map line 209).

### §3.7 MemoryDestructionLedger — NAMED-only seam (destruction ledger; R3 §(b)#1 EC-owned)

**NAMED-only.** **Owner:** `schema_owner = DOC80` (names the seam + binds the invariant); **EC owns the durable append / write path** (R3 §(b)#1 — these entries are `serialized_durable`, so EC-written is correct; **contrast** the §22 convergence ledger, which is `anchored_attestation`, NOT EC durable-write). **DOC84 / DOC85 / DOC11 are consumers / surfaces / effects** (delivery/audit surface, learning-eligibility effects, runtime/durability) — *not* owners of the write path.

A single **append-only, hash-chained `MemoryDestructionLedger`** records every `ErasureMFC` / `RestampMFC` / `RestoreMFC` (§3.3) as a chain-of-custody for litigation holds. **Invariant:** *every erasure/restamp/restore certificate is appended to the ledger with a prior-hash link before its effect is acknowledged.* This is a **named seam, not a lifecycle engine** (UR-29 affirmed). **Lints (Stage 9):** `destruction_ledger.entry_missing_for_erasure_restamp_restore` [proposed]; `destruction_ledger.hash_chain_broken` [proposed]. Enrolled in §16.2 (deferral register, body) + §15.4 (gate) + §17.4 (matrix).

### §3.8 PromptShellExposure — NAMED-only (F11 + R3 §(b)#3 proof-shaped)

**NAMED-only.** **Owner:** named at DOC80 core; **body Stage 7 (DOC85 / DOC84 runtime exposure)**. Coverage orphan (F11): prompt-shell weights influence learning but had no named exposure record. Per **R3 §(b)#3** the exposure is **proof-shaped, not boolean** — it carries (conceptually, not as a drafted schema) a required `final_prompt_truth_ref` (§3.5) + rendered / trimmed / suppressed span refs (+ `context_product_instance_ids` where applicable), **replacing** any `exposed_in_final_prompt: boolean`. The companion `PromptShellLearningContract` is already defined at §2.3. **Lint (Stage 9):** `prompt_shell.exposure_boolean_without_final_prompt_truth_ref` [proposed]; `prompt_shell.learning_credit_without_exposure_in_final_prompt` [proposed].

### §3.9 DebugModeContract — NAMED-only (F30, scoped to F30's text only)

**NAMED-only.** **Owner:** named at DOC80 core; **body deferred (Stage 7)**. Names a debug/inspection mode that **must carry a non-learning guarantee — debug reads never produce learning credit**. **Scope is exactly F30's stated concern**: no broader debug subsystem is invented. **Lint (Stage 9):** `debug_mode.flow_without_non_learning_guarantee` [proposed].

---

## §4. Proof spine

**Source:** Skeletal §9 (proof spine member) + §10.7; SM-050 / SM-051; Owner Map lines 147–150; B8 failure-mode → proof-artifact → lint mapping. The proof spine is the family's central anti-phantom mechanism: no durable effect or rendered prompt exists without a proof artifact.

### §4.1 ContextPacketProof contract (SM-051)

**Source:** SM-051 (`ContextPacketProof + RenderSafetyProof`); Owner Map line 149 (DOC80 core; DOC24 + DOC11 execute). **Owner:** DOC80 core. **Executors:** DOC24, DOC11. **Consumers:** DOC85 (learning-eligibility gate, §4.1); DOC86 (Inspector renders proof outcome) — the consolidated proof-spine cross-charter note is in §4.3.

```typescript
/** Packet-level proof. schema_owner = DOC80 core (SM-051 / Owner Map line 149).
 *  Executors: DOC24 (assembly-time) + DOC11 (finalize-time). */
interface ContextPacketProof {
  proof_id: string;
  schema_owner: 'DOC80';
  executor: 'DOC24' | 'DOC11';
  packet_ref: string;
  context_product_refs: string[];          // every ContextProduct in the packet (§3.1)
  shell_refs: PromptShellVariantId[];       // MUST include every load_bearing_for_proof shell variant (§2.3)
  policy_generation_id: string;
  effective_policy_ref: EffectiveMemoryPolicyRef;
  scope_resolution_ref: ScopeResolutionResultRef;
  coordination_trace_ref: MemoryCoordinationTraceRef;
  membership_eligibility_results: MembershipEligibilityProof[];  // EDGE-LEVEL (UR-05); removed/blocked excluded (DOC87 injection_eligible, §12)
  included_set_hash: string;                // UR-05: hash of the included membership set
  excluded_set_hash: string;                // UR-05: hash of the excluded membership set
  outcome: 'pass' | 'fail';
  failure_reason_codes?: string[];          // ReasonCode ids (§2.1) when outcome = fail
}

/** Edge-level membership eligibility (UR-05). MembershipLifecycleState is owned here (proof spine);
 *  referenced by §1.6, §6, §12. MemoryMembershipEdgeRef / ReasonCodeId / PolicyGenerationId are branded refs (§8.5). */
type MembershipLifecycleState = 'candidate' | 'active' | 'blocked' | 'removed' | 'stale' | 'suppressed' | 'archived';

interface MembershipEligibilityProof {
  membership_edge_ref: MemoryMembershipEdgeRef;
  lifecycle_state: MembershipLifecycleState;
  injection_eligible: boolean;              // total function of lifecycle_state; {removed, blocked} → false (§12)
  gate_owner: 'DOC87' | 'DOC84';
  policy_generation_id: PolicyGenerationId;
  reason_codes: ReasonCodeId[];
}
```

The `ContextPacketProof` is the gate for **learning eligibility** (SM-051 / ADQ-207): no learning signal flows without it (`proof.learning_signal_without_context_packet_proof`). It is also the carrier that proves every product in a packet was policy-gated and that load-bearing shells were present. **Membership eligibility is necessary, not sufficient (UR-40):** an injection-eligible membership edge does not by itself authorize injection — policy and scope still gate independently. **Edge-level proof (UR-05):** the proof records a per-edge `MembershipEligibilityProof` (not a single boolean), plus included/excluded set hashes, so an injected `removed`/`blocked` edge is provably caught.

**Membership-proof lints (Stage 9):** `proof.membership_eligibility_boolean_only`; `proof.injected_membership_without_edge_level_result`; `proof.membership_lifecycle_not_active`; `proof.membership_eligibility_missing_reason_codes`.

### §4.2 RenderSafetyProof contract (DOC84 executes; DOC11 finalizes)

**Source:** Owner Map lines 147–148 (B3 split: contract @ DOC80 core; execution @ DOC84; DOC11 finalizes); Round D §9.2. **Owner:** DOC80 core (the *contract*). **Executor:** DOC84. **Finalizer:** DOC11. **Consumers:** DOC84 / DOC11 (execution / finalize), DOC86 (Inspector renders outcomes) — the consolidated proof-spine cross-charter note is in §4.3. DOC80 specifies the contract DOC84 must satisfy; DOC84 owns the executed instance body (its §6.1).

```typescript
/** The contract DOC84 must satisfy at render time; DOC11 finalizes at the native-session
 *  boundary. schema_owner = DOC80 core (Owner Map line 147); execution @ DOC84 (line 148). */
interface RenderSafetyProofContract {
  contract_id: 'doc80.render_safety_proof_contract';
  schema_owner: 'DOC80';
  executor: 'DOC84';
  finalizer: 'DOC11';
  required_checks: RenderSafetyCheck[];
}

type RenderSafetyCheck = // CLOSED E0 check vocabulary (F13); per-check payload/registry is Stage 7. Each check maps to a cited invariant below.
  | 'no_protected_content_in_safe_labels'  // safe labels not derived from protected content (SM-105)
  | 'dynamic_header_ledger_consistent'     // stable headers hash-pinned AND policy-invariant (ADQ-305)
  | 'no_removed_or_blocked_membership'     // DOC87 injection_eligible totality (§12)
  | 'policy_generation_current'            // not rendered under an obsolete policy_generation_id
  | 'all_products_policy_gated'            // every ContextProduct passed EffectiveMemoryPolicy
  | 'context_packet_proof_present';        // a passing ContextPacketProof exists for the packet

/** The executed instance — body owned by DOC84 (§6.1); the contract is owned here.
 *  DOC80 specifies the shape DOC84 must produce. */
interface RenderSafetyProof {
  proof_id: string;
  contract_ref: 'doc80.render_safety_proof_contract';
  executor: 'DOC84';
  finalized_by?: 'DOC11';
  checks_passed: RenderSafetyCheck[];
  checks_failed: RenderSafetyCheck[];
  outcome: 'pass' | 'fail';
  failure_reason_codes?: string[];
}
```

**Outcome-derivation invariant (UR-06).** `outcome === 'fail'` **iff** `checks_failed` is non-empty — the outcome is **derived, not independently writable**. A failed check MUST block the render (it is never recorded as failed-but-passed). The executed `RenderSafetyProof` body is owned by **DOC84** (its §6.1); DOC80 owns only the contract, so the executed body must not be defined here. **Lints (Stage 9):** `render_safety.outcome_not_derived_from_checks` (UR-06); `render_safety.failed_check_did_not_block_render` (UR-06); `render_safety.executed_body_defined_in_doc80` (UR-06); `render_safety.provisional_check_used_as_required_contract` (F13).

### §4.3 Proof spine invariants + lints (B8 failure-mode → proof-artifact → lint mapping)

The proof spine is governed by the **B8 mapping table** (Skeletal §9.4): every named failure mode maps to the proof artifact that catches it and the Stage 9 lint that enforces it.

| failure mode | proof artifact that catches it | Stage 9 lint |
|---|---|---|
| durable write with no certificate | `MemoryFlowCertificate` (§3.3) | `proof.durable_write_without_memory_flow_certificate` |
| render with no packet proof | `ContextPacketProof` (§4.1) | `proof.render_without_context_packet_proof` |
| render with no safety proof | `RenderSafetyProof` (§4.2) | `proof.render_without_render_safety_proof` |
| export with no certificate | `MemoryFlowCertificate` | `proof.export_without_memory_flow_certificate` |
| carryover with no certificate | `MemoryFlowCertificate` | `proof.carryover_without_memory_flow_certificate` |
| delegation with no certificate | `MemoryFlowCertificate` | `proof.delegation_without_memory_flow_certificate` |
| learning signal with no packet proof | `ContextPacketProof` | `proof.learning_signal_without_context_packet_proof` |
| durable write by a non-EC actor | `MemoryFlowCertificate.issued_by` | `proof.durable_write_by_non_ec_actor` |
| erasure with no certificate | `ErasureMFC` (§3.3) | `erasure.without_memory_flow_certificate` [proposed] |
| hard destruction or redaction without legal-hold clearance | `ErasureMFC.legal_hold_clearance_ref` | `erasure.hard_destruction_without_legal_hold_clearance_ref` [proposed]; `erasure.redaction_under_legal_hold_without_clearance` [proposed] |
| policy restamp with no certificate or over original ceiling | `RestampMFC` (§3.3) | `restamp.without_memory_flow_certificate` [proposed]; `restamp.exceeds_original_ceiling` [proposed] |
| restore with no certificate, hard-destruction restore, or revoked/held material reintroduced | `RestoreMFC` (§3.3) | `restore.without_memory_flow_certificate` [proposed]; `restore.of_hard_destruction` [proposed]; `restore.reintroduces_revoked_or_held_material` [proposed] |
| executed-prompt render missing final-prompt truth | `RenderMFC.final_prompt_truth_ref` + `FinalPromptTruthRef` (§3.5) | `proof.executed_prompt_render_missing_final_prompt_truth` [proposed] |
| render with no memory-flow certificate | `RenderMFC` (§3.3) | `proof.render_without_memory_flow_certificate` |
| learning attribution with no memory-flow certificate | `LearningAttributionMFC` (§3.3) | `proof.learning_attribution_without_memory_flow_certificate` |

**Proof-spine invariants.** (a) Every privileged flow (the nine `MemoryFlowKind` values) terminates in at least one proof artifact or withheld certificate. (b) Every proof artifact names a `coordination_trace_ref` so it is auditable (§3.4). (c) A failed proof blocks the effect and surfaces a `ReasonCode`; it is never a silent pass. (d) Learning is downstream of `ContextPacketProof` and `FinalPromptTruthRef` where final-prompt survival is required — the proof is a *precondition*, not a *byproduct*.

**Unhappy paths.** Each row of the table above is an unhappy path with a named lint. Additionally: *proof artifact present but `outcome = fail`* → effect blocked + reason codes; *proof artifact references a dangling trace* → `coordination_trace.proof_ref_dangling` (§3.4).

**Fixtures (Stage 8):** `fixture.proof.no_durable_effect_without_proof`; `fixture.proof.failed_proof_blocks_and_explains`; `fixture.proof.learning_gated_on_context_packet_proof`; `fixture.proof.render_requires_both_packet_and_safety_proof`.

**Cross-charter consumption.** DOC24 + DOC11 (ContextPacketProof execution), DOC84 (RenderSafetyProof execution), DOC85 (learning gate), EC (MemoryFlowCertificate issuance), DOC86 (Inspector renders proof outcomes). The proof spine is the single most-consumed E0 contract across the family.

### §4.4 Proof retention classes (UR-07)

**Source:** UR-07 (ACCEPT · GAP · blocking — a defined-but-unenforceable proof spine needs retention rules). **Owner:** DOC80 core. Placement note: the baseline numbers this "§11.4," but in the draft the proof spine is §4 and §11 is recovery/replay; retention classes belong with the proof spine, so they land as §4.4 (cross-referenced from §11).

```typescript
type ProofRetentionClass =
  | 'durable_audit_required'
  | 'durable_if_effect_committed'
  | 'transient_allowed_only_if_effect_not_committed'
  | 'derived_rebuildable';

interface ProofArtifactRetentionRule extends E0DurableRecord {
  artifact_type: string;
  retention_class: ProofRetentionClass;
  retained_by: 'EC' | 'DOC11' | 'DOC84' | 'DOC85';
  replay_required: boolean;
  audit_required: boolean;
}
```

**Rule (UR-07).** Any proof gating a durable write / final-prompt render / export / carryover / delegation / learning attribution **/ erasure / policy_restamp / restore** is `durable_audit_required` (append-only) **or** referenced by its originating `MemoryMutationEnvelope` (§5.1). The litigation-proof-layer flows (erasure / restamp / restore) are explicitly `durable_audit_required`. **Lints (Stage 9):** `proof.gated_effect_without_retained_proof`; `proof.retention_class_missing`; `proof.transient_proof_used_for_durable_effect`. **Fixtures (Stage 8):** `fixture.proof.gated_effect_has_durable_audit_proof`; `fixture.proof.erasure_restamp_restore_certificate_durable_audit_retained`.

---

## §5. Named cross-cutting concepts (schema body deferred to Stage 7)

These three concepts are **NAMED-only** (Input Deck; Commission §3.3 + Hard Constraint §6). Each is fully scoped — what it carries conceptually, its producer/consumer, and where it sits — but the **field-level schema is Stage 7 charter material and MUST NOT be written here.**

### §5.1 MemoryMutationEnvelope (Skeletal §10.5; §11.2; §11.8)

**Source:** Skeletal §10.5 (named at Stage 5R2; body deferred to Stage 7), §11.2 (consistency model), §11.8 (bitemporal carrier). **NAMED-only.** **Owner:** DOC80 core (the name + the role); Stage 7 owns the schema. **Producer:** every member performing a durable mutation, *serialized through EC*. **Consumer:** EC (ordering authority), the replay/audit log, and any rebuild path.

`MemoryMutationEnvelope` is the shared **event-sourced mutation wrapper** for durable writes, membership changes, source invalidation, policy restamps, delivery proofs, and learning write-back. Per Skeletal §10.5 it carries — *conceptually, not as a drafted schema* — the actor, the policy epoch, the source epoch, the transaction time, the valid time, an idempotency key, proof refs, and rollback/invalidation refs. It **subsumes the EC concurrency-revalidation rule** from OPA-031 (the compare-and-swap on `dedupe_basis_generation_id`, §1.5). It is the family-level **mutation-ordering primitive**: every durable mutation becomes one envelope event in EC's serialized log, which is what makes the replay-completeness invariant (§11.3) checkable. Per §11.8 it is the **bitemporal carrier** — it propagates `transaction_time` as a top-level field and `valid_time` as a payload field; Stage 7 owns those field definitions. **Stage 5R2 lands the name; Stage 7 drafts the schema** (Skeletal §10.5).

**Stage-7 handoff vocabulary (F19/F20 — NAMED-only, no field bodies).** When Stage 7 drafts the schema, the envelope is expected to carry (field *names* only — types are Stage-7 work, Class D): `event_type`, `aggregate_ref`, `idempotency_key`, `causation_id`, `correlation_id`, `actor_ref`, `transaction_time`, `valid_time`, `policy_generation_id`, `proof_refs`, `reason_codes`, `replay_order`, `migration_metadata`.

**Cross-charter consumption.** Every member's durable mutation references an envelope; DOC87 must declare its membership transitions as envelope instances with explicit ordering + idempotency (Skeletal §10.10 / OPA-032); DOC82/DOC85/DOC81 durable writes likewise. **Stage 7 schema-body authoring is the next step for this concept** (§16.2).

### §5.2 MemoryProvenanceGraph (Skeletal §10.6)

**Source:** Skeletal §10.6 (named at Stage 5R2; body deferred to Stage 7). **NAMED-only.** **Owner:** DOC80 core (the name + role); Stage 7 owns the schema. **Producer:** the pipeline (each stage appends provenance); **Consumer:** audit, the Inspector (DOC86), recovery/replay (§11).

`MemoryProvenanceGraph` is the durable **PROV-style provenance graph** spanning `SourceArtifact → ExtractionResult → AssertionCandidateEmission → Assertion/Edge/Membership → ContextProduct → final prompt → learning signal` (Skeletal §10.6). It is **distinct from `MemoryCoordinationTrace`** (§3.4): the coordination trace is per-request and ephemeral; the provenance graph is the **durable, cross-request** artifact that lets the system answer "what is the full lineage of this fact, across every request that touched it." **Stage 5R2 lands the name; Stage 7 drafts the schema.**

**Stage-7 handoff vocabulary (F19/F20 — NAMED-only, no field bodies).** Stage 7 is expected to provide (Class D — no field bodies at E0): node-kind and edge-kind registries, proof-attachment for gated edges, a redaction / retention policy, and revoked-source cascade edges.

**Cross-charter consumption.** DOC82 (assertion/evidence lineage), DOC83 (extraction lineage), DOC87 (membership lineage), DOC84 (delivery lineage), DOC85 (learning lineage), DOC86 (Inspector renders lineage). It is the durable backbone the recovery/replay seam (§11) rebuilds against.

### §5.3 ResumeProjection / ResumeCard (Skeletal §10.13)

**Source:** Skeletal §10.13 (`CognitiveDiff` → `ResumeProjection` / `ResumeCard` rename). **NAMED-only.** **Owner:** DOC80 core names the concept; it is a `DeliveryProjection`-class object whose body is Stage 7 (and whose runtime surface is DOC84/DOC86). **Producer:** DOC84 (delivery); **Consumer:** DOC86 (renders the card).

`ResumeProjection` / `ResumeCard` is the **demotion of the retired `CognitiveDiff`** (do not use `CognitiveDiff` as a canonical name — Skeletal §10.13; the canonical names are `ResumeProjection` / `ResumeCard`). It is a **derived presentation** over `IssueFrame`, `RecentActivityRollup`, `PriorDeliveryLedger`, `MemoryCoordinationTrace`, and DOC87 membership. It is **NOT truth-bearing and NOT evidence**, and it is **invalidated when its source refs invalidate** (Skeletal §10.13). Because it is a projection, it carries source refs + generation id + invalidation policy (the projection invariants, §8 / Skeletal §11.10) — but those fields are Stage 7 schema body, not drafted here.

**Cross-charter consumption.** DOC84/E7–E8 (produces as a `DeliveryProjection`), DOC86/E10 (renders), DOC83 (supplies `IssueFrame` + `RecentActivityRollup` inputs). Lints `resume_card_used_as_evidence` and `cognitive_diff.canonical_without_architect_approval` (Skeletal §10.13) protect the non-truth invariant.

---

## §6. Memory-object classification table (Skeletal §10.12)

**Source:** Skeletal §10.12 (column set confirmed at Stage 5R2; seed rows); Skeletal §14 (F-struct #1 — "the single index Stage 7 charters check against"). **Owner:** DOC80 core. This table is the canonical taxonomy: every durable or delivery-relevant memory object appears exactly once, and Stage 7 charters check their objects against it.

### §6.1 Column set

The column set is fixed (Skeletal §10.12; deliberately no premature `network_compatibility_required?` column, per the V5 non-goal §1.3), **plus the `audit_replay_class` column added per A11 (UR-30)**: `object_family` / `owner` / `truth_apt?` / `source_bound?` / `durable?` / `derived_projection?` / `policy_gated?` / `delivery_eligible?` / `ui_visible?` / `learning_eligible?` / `audit_replay_class` / `notes`. The `audit_replay_class` ∈ `{canonical, durable_audit, derived, transient, external_ref, named_only}` (A11) classifies how each object participates in recovery/replay (§11) and audit. (N12: ref-types are normalized to branded strings family-wide — see §8.5 — so there is no separate `ContentReference` object; and the phantom DOC8 `importing_member` cell is absent — V7 closed.)

### §6.2 Seed rows

Seed rows per Skeletal §10.12. (`Y`/`N` are seeds for Stage 6; Stage 7 charters confirm and extend. `owner` uses the post-flatten one-owner assignment from the Owner Map.)

| object_family | owner | truth_apt? | source_bound? | durable? | derived_projection? | policy_gated? | delivery_eligible? | ui_visible? | learning_eligible? | audit_replay_class | notes |
|---|---|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|---|
| Assertion | DOC82 | Y | Y | Y | N | Y | Y | Y | Y | canonical | Canonical reusable truth (ADQ-201); bitemporal (§8.2) |
| AssertionVariant | DOC82 | Y | Y | Y | N | Y | Y | Y | Y | canonical | Scoped/conditional variant |
| ConsolidatedUnderstanding | DOC73 (DOC82 consumes) | N | Y | Y | N | Y | Y | Y | N | canonical | Source-bound synthesis only — **never canonical reusable truth** (ADQ-219) |
| EvidenceRecord | DOC82 | N | Y | Y | N | Y | Y | Y | Y | canonical | Evidence, not truth-apt itself |
| EvidenceSupportEdge | DOC82 | N | Y | Y | N | Y | Y | Y | Y | canonical | `support_relation` enum; contrary edges mandatory (SM-200) |
| MemoryMembershipEdge | DOC87 | N | N | Y | N | Y | Y | Y | N | canonical | Confers no truth/warrant; only `injection_eligible` states deliver (§12) |
| TopicLens | DOC87 | N | N | Y | N | Y | Y | Y | N | canonical | Organization semantics; no truth ownership (ADQ-204) |
| TopicCollectionDirective | DOC83 | N | N | Y | N | Y | N | Y | N | canonical | Governed extraction rule; references DOC87 Topic identity (lateral) |
| IssueFrame | DOC83 | N | N | Y | N | Y | Y | Y | N | canonical | Workbench, **not** an Assertion store (SM-081) |
| RecentActivityRollup | DOC73 gen / DOC83 consumption | N | N | Y | Y | Y | Y | Y | N | derived | **`can_orient_only`** — never evidence/warrant (ADQ-405 / SM-108) |
| NullResultMemory | DOC83 | N | N | Y | N | Y | Y | Y | N | canonical | Freshness-tracked (SM-103 generation ids) |
| ContextProduct | DOC80 registry / DOC84 assembly | N | per-kind (§3.1.1) | N | Y | Y | Y | Y | N | transient | Per-request delivery product; **17 fixed kinds** (ABC §9.2; §3.1); per-kind `source_bound?` enumerated at §3.1.1 |
| ResumeCard | DOC84 produces / DOC86 renders | N | N | N | Y | Y | Y | Y | N | derived | Projection over IssueFrame+rollup+ledger+trace; not truth/evidence (§5.3) |
| LearningSignal | DOC85 | N | N | Y | Y | Y | N | Y | Y | durable_audit | **Proof-gated** via `ContextPacketProof` (§4.1); the learning artifact itself |
| ContextPacketProof | DOC80 | N | N | Y | N | Y | N | Y | N | durable_audit | Packet-level proof (§4.1); learning-eligibility gate (seed) |
| RenderSafetyProof | DOC80 contract / DOC84 exec | N | N | Y | N | Y | N | Y | N | durable_audit | Render proof (§4.2); executed body @ DOC84 (seed) |
| MemoryFlowCertificate (+ Erasure/Restamp/Restore variants) | DOC80 | N | N | Y | N | Y | N | Y | N | durable_audit | 9-flow union (§3.3); EC-issued; litigation variants are per-event certificates, not an engine (seed) |
| MemoryDestructionLedger | DOC80 schema / EC write path | N | N | Y | N | Y | N | Y | N | durable_audit | Append-only hash-chained (§3.7); EC-written (R3 §(b)#1) (seed) |
| MemoryCoordinationTrace | DOC80 | N | N | Y | N | Y | N | Y | N | durable_audit | Per-request spine (§3.4); backs Inspector explanation (seed) |
| MemoryMutationEnvelope | DOC80 (Stage 7 body) | N | N | Y | N | Y | N | N | N | canonical | Mutation-ordering primitive (§5.1); the replay source (§11.3) (seed) |
| MemoryProvenanceGraph | DOC80 (Stage 7 body) | N | N | Y | N | Y | N | Y | N | canonical | Durable cross-request lineage (§5.2) (seed) |
| PromptShellVariant | DOC80 | N | N | Y | N | Y | N | Y | N | canonical | Registry entry (§2.3); hash-pinned (seed) |
| FinalPromptTruthRef | DOC11/OpenClaw (E0 names) | N | N | Y | N | Y | N | Y | Y | external_ref | Runtime-truth hook (§3.5); body @ DOC11 (seed) |
| SemanticProjectionContract | DOC80 | N | N | N | N | Y | N | N | N | named_only | Umbrella contract (§3.6) (seed) |
| DeliveryProjection | DOC84 | N | N | N | Y | Y | Y | Y | N | derived | Projection axis (§3.6); ResumeProjection/ResumeCard is a case (seed) |
| UIProjection | DOC86 | N | N | N | Y | Y | N | Y | N | derived | Projection axis (§3.6) (seed) |
| OrganizationProjection | DOC87 | N | N | N | Y | Y | N | Y | N | derived | Projection axis (§3.6) (seed) |
| KnowledgeProjection | DOC82 | N | Y | N | Y | Y | Y | Y | N | derived | Projection axis (§3.6); `SourceBoundSynthesisAdapter` is a case (seed) |
| ExternalDependencyRecord | DOC80 | N | N | Y | N | N | N | N | N | canonical | Dependency pin (§7) (seed) |
| MemoryPlaneHealthReadModel | DOC80 vocab / EC-Q host | N | N | N | Y | N | N | Y | N | derived | Health read-model (§9) (seed) |
| MemoryOperationQuota | DOC80 | N | N | Y | N | N | N | N | N | canonical | Quota envelope (§10) (seed) |

### §6.3 Classification invariants

Three invariants govern the table. First, **`truth_apt? = Y` only within the Assertion family** (`Assertion`, `AssertionVariant`) — nothing else in the family is truth-apt, which is the structural defense against the "parallel truth store" failure (SM-070: Topic/Library/Project facts retired). Second, **every `derived_projection? = Y` object carries source refs + generation id + an invalidation policy** (the projection invariants, §8 / Skeletal §11.10), governed by the `SemanticProjectionContract` (§3.6, `projection_may_own_truth: false`), and is `truth_apt? = N` by construction — a projection can never become canonical truth. Third, **membership and organization objects (`MemoryMembershipEdge`, `TopicLens`) confer no truth, no warrant, no policy override, and no source authority** (DOC87 membership invariants; Skeletal §10.4 non-overlap). The table is the **single index Stage 7 charters check against** (Skeletal §14): a Stage 7 object absent from this table is unclassified and must be added before its schema body is drafted.

**Unhappy paths.** *Object unclassified* (a Stage 7 object not in the table) → `taxonomy.object_unclassified`. *Derived object marked truth-apt* → `taxonomy.derived_marked_truth_apt`. *`truth_apt = Y` outside the Assertion family* → `taxonomy.truth_apt_outside_assertion_family`.

**Lints (Stage 9):** `taxonomy.object_unclassified`; `taxonomy.derived_marked_truth_apt`; `taxonomy.truth_apt_outside_assertion_family`.

**Fixtures (Stage 8):** `fixture.taxonomy.only_assertion_family_is_truth_apt`; `fixture.taxonomy.every_projection_has_invalidation_policy`; `fixture.taxonomy.stage7_object_present_before_schema_body`.

**Cross-charter consumption.** Every Stage 7 charter checks its objects here before drafting; DOC82 (Assertion family rows), DOC87 (membership/topic rows), DOC83 (workbench/orientation rows), DOC84 (ContextProduct/ResumeCard rows), DOC85 (LearningSignal row).

---

## §7. ExternalDependencyRecord posture

**Source:** Skeletal §13 / §3.2 (B7 — one `ExternalDependencyRecord` per external dependency); Skeletal §10.9 (ECSeamContract / OPA-031); Import Graph §3. **Owner:** DOC80 core. Every external owner doc the family imports from receives one record; the record pins the dependency and declares the drift response. This is the anti-"cross-doc seam that sounds good but isn't wired" mechanism (Commission §1.6).

```typescript
type DependencyStatus = 'stable' | 'partial' | 'moving' | 'aspirational' | 'phantom';

interface ExternalDependencyRecord extends E0DurableRecord {
  record_id: string;
  schema_owner: 'DOC80';
  dependency_doc: string;        // "EC" | "DOC72" | "DOC73" | "DOC25" | "DOC24" | "KDA" | "BDSM" | "DOC8" | "DOC11" | "DOC15" | "DOC20" | "DOC23" | "DOC1" | "DOC3" | "DOC26" | "PropA"
  source_freeze_ref: string;     // Target_Freeze pin
  repo_path: string;
  content_hash: string;
  hash_algorithm: 'sha256';      // UR-12: reproducible-pin algorithm
  git_commit_sha: string;        // UR-12: exact commit the pin was taken against
  source_line_ranges: string[];  // UR-12: the imported line/section ranges
  last_verified_at?: string;     // UR-12: RFC3339-UTC of last drift check
  header_version: string;
  dependency_status: DependencyStatus;
  drift_response: DriftResponse;
  importing_members: string[];   // which DOC80-family members import this dependency
}

type DriftResponse = // proposed value set — Stage 7 confirms (the drift_response FIELD is required per B7; these values are design)
  | 'halt_and_request_refresh'   // a pinned-baseline mismatch on a stable dependency
  | 'reconcile_at_charter'       // expected drift (e.g., BDSM revision; DOC73 CU reconciliation)
  | 'treat_as_capability_input'; // phantom (DOC8) — requirements source, not a runtime dependency
```

### §7.1 ECSeamContract (Skeletal §10.9; OPA-031)

EC is marked **`dependency_status = partial / moving`** (Skeletal §10.9; Owner Map line 238) — EC is the sole durable writer but is itself in motion, so the family must not assume it as a stable import; it binds through a named contract. The `ECSeamContract` (OPA-031) covers: durable write execution (Assertion / membership / learning write-back), policy enforcement, `ScopeResolutionResult` computation, command execution, source-revocation execution, audit + replay, **transaction ordering**, the **compare-and-swap / `dedupe_basis_generation_id` optimistic-concurrency token**, and **policy-generation re-gating** (Skeletal §10.9; §1.5). EC is the `issued_by` of every `MemoryFlowCertificate` (§3.3) and the executor of every durable `MemoryMutationEnvelope` (§5.1).

```typescript
/** Structured EC seam (UR-17). EC surfaces are referenced, never redefined here. */
interface ECSeamContract {
  contract_id: 'doc80.ec_seam_contract';   // OPA-031
  owns_read_model_refresh: true;
  non_ec_durable_writers_forbidden: true;
}
```

**ECSeamContract pins (UR-17; R3 §(b)#7 adds EC §4) — referenced-not-redefined; one `ExternalDependencyRecord` row each:**

- **EC §1** — off-switch / incognito / collection gate (effective-state source; enforces `TopicCollectionDirective` suppression)
- **EC §1.1** — global retention-window setting ("Empty now" / "Save N days") for the recycle bin (ADQ-407)
- **EC §1.3** — incognito (composes most-restrictive with §1 toggles + topic suppression)
- **EC §3** — compiled policy engine (single policy evaluator; `policy_generation_id` source)
- **EC §4** — `BackgroundJobOrchestrator` (retention/expiry sweeps for the recycle bin) — R3 §(b)#7
- **EC §7** — migration / import-merge (restore-into-fresh-install path, ADQ-408)
- **EC §8** — export / `full_raw_backup` (restore/provision source, ADQ-407/408)

Add `ExternalDependencyRecord` rows for EC §1, §3, §4, §7, §8 (with the §1.1 / §1.3 sub-pins noted). OPA-031 + (Stage 5R2c) the three committed §6.Z obligations.

**ECSeam lints (Stage 9):** `ec.dependency_not_marked_partial_or_moving`; `ec.durable_write_without_ec_execution`; `ec.dedupe_write_without_generation_revalidation`; `ec.policy_generation_changed_without_regate`; `ec.learning_writeback_without_ec_execution`; `proof.durable_write_by_non_ec_actor`; `ec.non_ec_durable_writer_detected` (UR-17); `ec.read_model_refresh_without_ec_receipt` (UR-17); `learning.writeback_without_ec_execution` [canonical]; `external_dependency.ec_seam_pin_missing` [proposed] (UR-17).

### §7.2 BDSM posture (ADQ-221; `dependency_status = partial`)

BDSM is **`partial`** (ADQ-221): BDSM v6.5 Draft v0.3.1 (`Current Specs/DOC24/DOC24_Addendum_A_BDSM_V6_5_DRAFT_v0_3_1.md`) is the operative source — well-drafted but incomplete, and being revised *alongside* the DOC80 memory system. Its record carries `header_version = "v6.5 Draft v0.3.1"` and `drift_response = reconcile_at_charter`. The specific BDSM surfaces DOC85 consumes are **deferred to the E9 charter, which is explicitly two-phase** (Skeletal §11.12): Phase 1 charters the learning architecture without naming BDSM surfaces; Phase 2 names them after BDSM's next revision. **Every E0 contract that depends on BDSM (the `PromptShellLearningContract` §2.3, the warrant-degradation producers §2.4) states the partial-coverage behavior explicitly** (guards "silent degradation").

### §7.3 DOC8 capability-mining-only posture (ADQ-221)

DOC8 is **`phantom`** (`dependency_status = phantom`; ADQ-221 / Skeletal §10.18 / Stage 5R review §II-3): it is a legacy skeleton, **capability-mining input only, NOT a runtime dependency**. No row anywhere in the family may say "DOC8 computes," "DOC8 executes," "DOC8 owns runtime learning," or treat DOC8 as a current owner. Its record carries `drift_response = treat_as_capability_input`. The runtime learning execution that legacy material attributed to DOC8 lives in **DOC85** (Owner Map lines 150, 168–174).

**DOC8/learning lints (Stage 9):** `doc85.runtime_dependency_on_legacy_doc8`; `doc85.learning_computation_owned_by_phantom_doc8`.

### §7.4 External dependency table

One record per external dependency (Import Graph §3). Seed (status + drift response):

| dependency_doc | dependency_status | drift_response | importing members | basis |
|---|---|---|---|---|
| EC | partial / moving | halt_and_request_refresh | all (durable writes / policy / scope) | Skeletal §10.9; OPA-031 |
| EC §1 (+§1.1/§1.3) | partial / moving | halt_and_request_refresh | DOC81, DOC83, DOC87 (effective-state / collection gate / incognito / recycle-bin retention) | UR-17; ADQ-406/407 |
| EC §3 | partial / moving | halt_and_request_refresh | DOC81, all (compiled policy engine; `policy_generation_id` source) | UR-17 |
| EC §4 | partial / moving | halt_and_request_refresh | DOC84, DOC85 (BackgroundJobOrchestrator; retention/expiry sweeps) | UR-17 (R3 §(b)#7) |
| EC §7 | partial / moving | halt_and_request_refresh | DOC80 family (migration / import-merge; restore-into-fresh-install) | UR-17; ADQ-408 |
| EC §8 | partial / moving | halt_and_request_refresh | DOC84, DOC80 family (export / full_raw_backup; restore/provision source) | UR-17; ADQ-407/408 |
| DOC72 | stable | halt_and_request_refresh | DOC82, DOC87 (graph payload storage) | Import Graph §3 |
| DOC73 | partial | reconcile_at_charter | DOC82 (CU), DOC83 (RecentActivityRollup gen) | ADQ-219; ADQ-405 |
| DOC25 | stable | halt_and_request_refresh | DOC82, DOC87 (LibrarySourceBinding) | Import Graph §3 |
| DOC24 | stable | reconcile_at_charter | DOC84 (packet assembly) | ADQ-203/211 |
| KDA | stable | reconcile_at_charter | DOC84 (rendering) | Import Graph §3 |
| DOC11 | stable | halt_and_request_refresh | DOC84 (final runtime / proof finalize) | Import Graph §3 |
| DOC15 | stable | reconcile_at_charter | DOC84, DOC86 (CIL seams) | Skeletal §11.5 |
| BDSM | partial | reconcile_at_charter | DOC85 (learning) | ADQ-221 |
| DOC8 | phantom | treat_as_capability_input | DOC85 (capability-mining only) | ADQ-221 |
| DOC20 | stable | reconcile_at_charter | DOC86 (UI implementation) | Import Graph §3 |
| DOC23 | stable | reconcile_at_charter | DOC83 (task outputs) | Import Graph §3 |
| DOC1 | stable | halt_and_request_refresh | DOC83 (Write Gate) | Import Graph §3 |
| DOC3 | stable | reconcile_at_charter | DOC83 (procedural seams) | Import Graph §3 |
| PropA | stable | reconcile_at_charter | DOC81 (policy rules); ReasonCode producer | Import Graph §3 |
| DOC26 | aspirational | reconcile_at_charter | DOC86 (conditional UI seam) | ADQ-202/404; Skeletal §11.6 |

**DOC9 is not imported** (Skeletal §3.2 / Import Graph §3 — F4 disclaimer); there is no record because there is no seam. **DOC26** is `aspirational`, conditional on ADQ-202 / ADQ-404; Stage 6 verifies whether it is a real current owner doc (Skeletal §11.6).

**Lints (Stage 9):** `external_dependency.unpinned` (a §7.4 dependency without a record); `external_dependency.drift_unhandled` (a record without a `drift_response`); plus the EC and DOC8 lints above.

**Fixtures (Stage 8):** `fixture.external_dependency.every_import_has_record`; `fixture.external_dependency.ec_marked_partial_moving`; `fixture.external_dependency.doc8_phantom_no_runtime_contract`; `fixture.external_dependency.bdsm_partial_status_stated`.

**Cross-charter consumption.** Every family member that imports an external doc cites its record; DOC85/E9 (BDSM + DOC8 posture, two-phase), DOC82/E3–E4 (DOC72/DOC73/DOC25), DOC84/E7–E8 (DOC24/KDA/DOC11/DOC15), DOC81/E1–E2 (PropA/EC).

---

## §8. Cross-cutting field conventions

These conventions are stated unambiguously here so E1+ charters bind to them **without re-asking** (Opening Brief exit criterion #3). Each is a *field rule* the planes apply, not a DOC80-owned object.

### §8.1 Embedding-model-migration refs (Skeletal §10.14)

**Source:** Skeletal §10.14. **Convention:** any schema where embeddings contribute to equivalence or similarity MUST carry `embedding_model_ref` and `embedding_generation_id`. `AssertionIdentitySignature` (DOC82) and any `semantic_equivalence` dedupe basis (`AssertionDedupeOutcome`, DOC82) are the primary carriers. **Migration rule:** an embedding-model migration invalidates or rechecks semantic-equivalence dedupe results, related projections, vector indexes, and affected retrieval hints — it is never silently absorbed.

```typescript
// Field convention (not a standalone object): mixed into any embedding-using schema.
interface EmbeddingProvenanceFields {
  embedding_model_ref: string;       // which model produced the embedding
  embedding_generation_id: string;   // generation token; changes on model migration
}
```

**Comparability invariant (F28).** Similarity / merge comparisons are valid **only within the same `embedding_generation_id`**; a cross-generation comparison requires re-embedding or explicit review — never a silent cross-generation match. **Un-merge rule (UR-41).** An embedding-model migration may require **un-merging previously-merged assertions**; that split MUST route through review, **never a silent split**.

**Lints (Stage 9):** `embedding.semantic_equivalence_without_model_generation`; `embedding.model_migration_without_dedupe_recheck_plan`; `embedding.cross_generation_comparison_without_reembed` (F28); `embedding.silent_unmerge_on_model_migration` [proposed] (UR-41). **Cross-charter:** DOC82/E3 (`AssertionIdentitySignature`, dedupe, un-merge review), any member doing vector retrieval (DOC84).

### §8.2 Bitemporal axes carrier (Skeletal §11.8)

**Source:** Skeletal §11.8. **Convention:** the bitemporal axes — `valid_time` (when the proposition holds in the world) and `transaction_time` (when the system recorded it) — are **carried family-wide by `MemoryMutationEnvelope`** (§5.1): it propagates `transaction_time` as a top-level field and `valid_time` as a payload field. The **axes themselves are owned by DOC82** (`Assertion` / `AssertionVariant` carry `valid_time_start/end` + `transaction_time_start/end`; `EvidenceSupportEdge` carries the source-span snapshot's temporal axes). E0 states only the **cross-cutting carrier rule**; DOC82/E3 owns the field-level schema and Stage 7 owns the envelope body. **Linkable, not collapsed (UR-18):** the `MemoryMutationEnvelope` mutation/replay-time axis and the DOC82 `Assertion`/`EvidenceSupportEdge` valid/transaction-time axes are **linkable but distinct** — the envelope's `replay_order` is NOT the assertion's `valid_time`, and the two are never collapsed into one axis.

**Lints (Stage 9):** `bitemporal.assertion_missing_valid_time`; `bitemporal.assertion_missing_transaction_time`; `bitemporal.evidence_edge_missing_source_span_temporal_snapshot`; `memory_mutation_envelope.valid_time_used_as_replay_order` (UR-18). **Cross-charter:** DOC82/E3 (owns the axes), every durable mutation (carries them via the envelope).

### §8.3 Policy-generation carrier (ADQ-305 + Skeletal §11.3)

**Source:** ADQ-305 (header stability); Skeletal §11.3 (extraction-side re-gate); SM-101 (`EpisodePolicyEpoch`). **Convention:** `policy_generation_id` is carried on every plan, proof, certificate, and durable mutation. Two rules attach. First, **header stability (ADQ-305):** a prompt header/shell is stable (KV-cache-reusable) **only if it is BOTH hash-pinned AND policy-invariant**; `policy_generation_id`, scope resolution, and policy stamps are always volatile and must not be cached across a policy change. Second, the **extraction-side re-gate (Skeletal §11.3):** if `policy_generation_id` changes between extraction admission (ABC §7.7 Step 0) and resolution (Step 11 / EC durable write), the candidate MUST be re-gated at Step 0 under the new generation. Owner of the re-gate: **DOC83 (extraction triage) + DOC81 (policy-generation boundary)**; the resolution-side companion is EC's `ECSeamContract` (§7.1).

**Lints (Stage 9):** `extraction.policy_generation_changed_without_step_0_regate`; `policy.extraction_started_under_obsolete_policy_generation`. **Cross-charter:** DOC83/E5 + DOC81/E1–E2 (re-gate owners), DOC84/E7–E8 (header stability at render), EC (resolution re-gate).

### §8.4 Charter-input cross-ref convention

**Source:** Stage 6 charter-input discipline (STAGE_6_CHARTER_INPUT_INDEX). **Convention:** ADQ rows are cited by number with their pinned charter (e.g. *ADQ-405 → E6*); cross-doc seams use the `OPA-0xx` namespace (e.g. *OPA-024* RecentActivityRollup E6 lint; *OPA-031* ECSeamContract; *OPA-032* DOC83↔DOC87 Topic identity; *OPA-035* SourceBoundSynthesisAdapter convergence). A charter that is a **pre-condition** for another names it explicitly (e.g. DOC87 publishes the `TopicIdentityContract` that DOC83/E5 imports before drafting `TopicCollectionDirective`, per Import Graph §2.1 / OPA-032). This convention governs how the §17 landing tables and every downstream charter cite their inputs.

### §8.5 Global schema + naming conventions (UR-26 / UR-27 / UR-28b)

**Source:** UR-26 (ACCEPT · P1), UR-27 (ACCEPT), UR-28b (ACCEPT — naming convention lands in E0; the meta-schemas UR-28 are REJECTED to Stages 7/8/9). **Convention (stated once; applies family-wide):**

- **`schema_version`** on every durable record (the `E0DurableRecord` base, §1.6). A **breaking change requires a named migration plan** — *Stage 7 owns the plan schema*; **E0 does NOT build `MemorySchemaMigrationPlan`** (UR-28 reject).
- **Branded-string IDs** with schema prefixes (e.g. `MemoryFlowCertificateId`, `PolicyGenerationId`); **all cross-object refs are branded strings** — there is **no separate `ContentReference` object** (N12 normalization).
- **Casing:** `snake_case` JSON / `PascalCase` interfaces / `snake_case` enum members (unless source-canonical, e.g. ABC enums).
- **Timestamps** RFC3339-UTC; **hashes** `sha256`.
- **Lint/fixture naming (UR-28b):** lints are `<domain>.<failure_condition>`; fixtures are `fixture.<domain>.<scenario>.<expected_result>`; **every error lint has ≥1 Stage-8 negative-fixture handoff**.

**Lints (Stage 9):** `schema.version_missing`; `schema.migration_plan_required_for_breaking_change`; `schema.timestamp_not_rfc3339_utc`; `schema.hash_algorithm_missing`.

---

## §9. Observability + health seam (Skeletal §10.15)

**Source:** Skeletal §10.15. **Owner:** DOC80 core owns the **health-signal vocabulary** and the read-model **contract**; **EC / Q host/execute** the read model; **family members contribute counters**. (Placement note: the read-model *instance* is hosted by EC/Q per §10.15; DOC80 owns the vocabulary + contract under the cross-cutting-contract carve-out, §1.2.)

### §9.1 MemoryPlaneHealthReadModel

```typescript
type MemoryPlaneHealthSignal =
  | 'source_revocation_backlog' | 'membership_restamp_backlog' | 'policy_restamp_failures'
  | 'proof_artifact_missing_count' | 'topic_future_watch_budget_exhausted'
  | 'search_affordance_preflight_failure_count' | 'learning_signal_suppression_count'
  | 'review_queue_depth' | 'contested_assertion_rate' | 'warrant_distribution';

interface MemoryPlaneHealthCounter {
  signal: MemoryPlaneHealthSignal;
  contributing_member: string;             // which family member emits this counter
  value: number | Record<string, number>; // scalar, or a distribution (warrant_distribution)
  quota_bound_ref?: string;                // MemoryOperationQuota bound (§10), when this counter is budgeted
  measurement_window: string;              // UR-23: the window the value covers
  generated_at: string;                    // UR-23: RFC3339-UTC
  last_successful_refresh_at?: string;     // UR-23: RFC3339-UTC of last good refresh
  freshness_status: 'fresh' | 'stale' | 'failed';   // UR-23
  severity: 'info' | 'warning' | 'degraded' | 'blocked';  // UR-23
  source_trace_refs: string[];             // UR-23: MemoryCoordinationTrace refs backing the counter
}

/** Health read-model. Vocabulary + contract owned by DOC80 core (§10.15);
 *  hosted/executed by EC / Q; members contribute counters. */
interface MemoryPlaneHealthReadModel {
  read_model_id: 'doc80.memory_plane_health';
  vocabulary_owner: 'DOC80';
  host_executor: 'EC_or_Q';
  counters: MemoryPlaneHealthCounter[];
}
```

### §9.2 Seed counters

The seed counters (Skeletal §10.15): `source_revocation_backlog`, `membership_restamp_backlog`, `policy_restamp_failures`, `proof_artifact_missing_count`, `topic_future_watch_budget_exhausted`, `search_affordance_preflight_failure_count`, `learning_signal_suppression_count`, `review_queue_depth`, `contested_assertion_rate`, `warrant_distribution`. Each names a `contributing_member` so the source of every signal is unambiguous, and several map to a `MemoryOperationQuota` bound (§10) so the health seam and the quota envelope agree on what "exhausted" means.

### §9.3 Health-signal vocabulary

The vocabulary is **closed and core-owned**: a counter whose `signal` is not in `MemoryPlaneHealthSignal` is unregistered (the same anti-phantom discipline as the ReasonCode and ContextProduct registries). Each family member declares which counters it contributes; a member that should emit a counter but does not is caught by `member.missing_health_counters`.

**Unhappy paths.** *Member emits no health counters* → `member.missing_health_counters`. *Counter with an unregistered signal* → vocabulary lint. *Budgeted counter with no `quota_bound_ref`* → reconciliation lint against §10.

**Lints (Stage 9):** `member.missing_health_counters`; `health.unregistered_signal`; `health.budgeted_counter_without_quota_bound`; `health.counter_window_missing` (UR-23); `health.counter_stale_without_status` (UR-23); `health.counter_missing_last_successful_refresh` (UR-23).

**Fixtures (Stage 8):** `fixture.health.every_member_declares_counters`; `fixture.health.signal_vocabulary_closed`.

**Cross-charter consumption.** Every member contributes counters (DOC83 review_queue_depth + topic_future_watch; DOC87 membership_restamp_backlog; DOC81 policy_restamp_failures; DOC82 contested_assertion_rate + warrant_distribution; DOC85 learning_signal_suppression_count; DOC86 search_affordance_preflight_failure_count). EC/Q hosts.

---

## §10. MemoryOperationQuota + scale assumptions (Skeletal §10.16)

**Source:** Skeletal §10.16 (extends `FamilyWideComputeBudget` toward `MemoryOperationQuota`); Skeletal §15 (family-wide compute-budget envelope; B9 #d). **Owner:** DOC80 core. The quota envelope is the family's defense against unbounded background work (Topic future-watch runaway, review-queue gridlock, revocation-cascade fan-out, learning-replay floods).

### §10.1 Family-wide compute budget

```typescript
/** The family-wide envelope. Each member declares its hot-path cost against it (B9 #d). */
interface FamilyWideComputeBudget {
  budget_id: 'doc80.family_wide_compute_budget';
  schema_owner: 'DOC80';
  member_hot_path_costs: Record<string, HotPathCostDeclaration>;
}

interface HotPathCostDeclaration {
  member: string;                      // DOC81..DOC87
  declared: boolean;                   // false → compute_budget.member_cost_undeclared fires
  cost_class: 'low' | 'medium' | 'high';
  notes?: string;
}
```

Each member declares its hot-path cost (`HotPathCostBudget` at DOC84 is one such declaration against this envelope, Owner Map line 143). A member that fails to declare is caught by `compute_budget.member_cost_undeclared`.

### §10.2 Quota fields

```typescript
/** Per-bound spec (UR-24): every quota bound is a rich object, not a bare number. */
interface MemoryOperationQuotaBound {
  unit: 'items' | 'tokens' | 'runs' | 'seconds' | 'bytes';
  window: string;
  default_value: number;
  hard_max: number;
  enforcement_owner: string;                      // which member/EC enforces this bound
  on_exhaustion: 'pause' | 'degrade' | 'queue_for_review' | 'suppress_noncritical' | 'block';
  resume_policy_ref?: string;
}

/** Bounds on background / batch memory operations. schema_owner = DOC80 core (§10.16). */
interface MemoryOperationQuota extends E0DurableRecord {
  quota_id: 'doc80.memory_operation_quota';
  schema_owner: 'DOC80';
  topic_future_watch_runs: MemoryOperationQuotaBound;          // ties topic_future_watch_budget_exhausted (§9.2)
  review_queue_backlog: MemoryOperationQuotaBound;             // ties review_queue_depth
  source_invalidation_fanout_per_cycle: MemoryOperationQuotaBound; // ties source_revocation_backlog
  learning_replay_per_window: MemoryOperationQuotaBound;
  search_affordance_prefetch: MemoryOperationQuotaBound;
  membership_restamp_batch_size: MemoryOperationQuotaBound;    // ties membership_restamp_backlog
  revocation_cascade_batch_size: MemoryOperationQuotaBound;
  // UR-25: background execution strategy (replaces the bare `background_yield_to_hot_path: boolean`)
  background_execution_strategy: 'cooperative_chunking' | 'worker_thread' | 'child_process' | 'deferred_queue_only';
  max_chunk_ms: number;
  yield_checkpoint_required: boolean;
  hot_path_preemption_supported: boolean;
  cancellation_checkpoint_required: boolean;      // DOC11 / OpenClaw executes the background strategy
}
```

### §10.3 Bound-enforcement model

Every quota bound is a **hard bound, not a soft target** (`hard_max`, UR-24): when reached, the per-bound `on_exhaustion` action fires (`pause` / `degrade` / `queue_for_review` / `suppress_noncritical` / `block`) — and may surface a `topic_future_watch_budget_exhausted`-class health signal (§9.2) — rather than degrading the hot path. The **background execution strategy (UR-25)** is structural: `background_execution_strategy` + `yield_checkpoint_required` + `hot_path_preemption_supported` + `cancellation_checkpoint_required` replace the old `background_yield_to_hot_path` boolean, and DOC11/OpenClaw executes the strategy so background memory work (revocation cascades, restamp batches, learning replay) always yields to interactive hot-path requests. An unbounded background operation (a bound absent or set to "unlimited") is caught at Stage 9.

**Unhappy paths.** *Topic future-watch unbounded* → `quota.topic_future_watch_unbounded`. *Review queue unbounded* → `quota.review_queue_unbounded`. *Source-revocation fan-out unbounded* → `quota.source_revocation_fanout_unbounded`. *Membership restamp unbounded* → `quota.membership_restamp_unbounded`. *Learning replay unbounded* → `quota.learning_replay_unbounded`. *Member hot-path cost undeclared* → `compute_budget.member_cost_undeclared`.

**Lints (Stage 9):** the five `quota.*_unbounded` lints above + `compute_budget.member_cost_undeclared`; per-bound `quota.unit_missing` / `quota.window_missing` / `quota.enforcement_owner_missing` / `quota.exhaustion_behavior_missing` / `quota.resume_policy_missing` (UR-24); `quota.background_yield_boolean_without_runtime_strategy` (UR-25).

**Fixtures (Stage 8):** `fixture.quota.background_yields_to_hot_path`; `fixture.quota.every_background_op_is_bounded`; `fixture.quota.member_declares_hot_path_cost`.

**Cross-charter consumption.** DOC83/E6 (topic future-watch + review queue), DOC87/E_org (membership restamp), DOC82/E3–E4 (source-invalidation fan-out), DOC85/E9 (learning replay), DOC84/E7–E8 (search prefetch + `HotPathCostBudget` declaration). The quota envelope and the health seam (§9) are two views of the same bounds.

---

## §11. Recovery / replay seam (Skeletal §11.1)

**Source:** Skeletal §11.1 (recovery/replay seam — EC + DOC72 + DOC25 owned; DOC80-family rebuild hooks); §10.5 (`MemoryMutationEnvelope`); §11.2 (consistency model). **Owner of recovery/replay:** EC + DOC72 + DOC25 (external). **DOC80 posture:** the family does **not** own backup/recovery/corruption-recovery — it *depends* on it and provides rebuild hooks.

### §11.1 Owner posture (EC + DOC72 + DOC25 owned)

Recovery and replay are owned by **EC** (the audit/replay log + serialized write), **DOC72** (graph payload storage), and **DOC25** (source materialization) (Skeletal §11.1). The DOC80 family contributes **rebuild hooks**, not a recovery engine. This is the correct posture: the durable substrate (EC's log, DOC72's graph, DOC25's sources) is the system-of-record, and the memory-control-plane members are rebuildable projections on top of it.

### §11.2 DOC80 family rebuild hooks

Every DOC80-family member MUST classify each of its artifacts as either **`canonical`** (durable; a replay source) or **`derived`** (a projection, rebuilt from canonical sources) — this is the same `durable? / derived_projection?` distinction the taxonomy table draws (§6). **Every `derived` artifact names its rebuild sources**, so the recovery path can reconstruct it. A derived artifact that does not name its rebuild sources is caught by `recovery.derived_artifact_without_rebuild_source`. Proof artifacts (§4) must name the canonical reference they attest to (`recovery.proof_artifact_missing_canonical_ref`).

### §11.3 Replay-completeness invariant

> **Replay-completeness invariant (Skeletal §11.1):** for any durable `Assertion` / `AssertionVariant` / `MemoryMembershipEdge` / `EvidenceSupportEdge` / `PolicyStamp` / learning signal in the system, the EC audit log contains the originating `MemoryMutationEnvelope` event (§5.1) sufficient to rebuild the canonical state by replay.

This invariant is the reason every durable mutation is wrapped in a `MemoryMutationEnvelope` serialized through EC (§1.5 / §5.1): the envelope event *is* the replay source. The invariant is checkable precisely because the consistency model is single-EC-writer — there is exactly one serialized log to replay.

**Unhappy paths.** *Derived artifact without rebuild source* → `recovery.derived_artifact_without_rebuild_source`. *Proof artifact missing canonical ref* → `recovery.proof_artifact_missing_canonical_ref`. *Membership edge without a replay source* → `recovery.membership_edge_without_replay_source`. *Learning signal without replay/audit source* → `recovery.learning_signal_without_replay_or_audit_source`. *A durable object whose originating envelope is absent from the log* → `recovery.replay_completeness_invariant_violated`.

**Lints (Stage 9):** `recovery.derived_artifact_without_rebuild_source`; `recovery.proof_artifact_missing_canonical_ref`; `recovery.membership_edge_without_replay_source`; `recovery.learning_signal_without_replay_or_audit_source`; `recovery.replay_completeness_invariant_violated`.

**Fixtures (Stage 8):** `fixture.recovery.every_derived_artifact_names_rebuild_source`; `fixture.recovery.durable_object_replayable_from_envelope`.

**Cross-charter consumption.** Every member classifies its artifacts (canonical/derived) and names rebuild sources; EC owns the replay log; DOC72/DOC25 own the durable substrate; Stage 7's `MemoryMutationEnvelope` body makes the envelope event concrete.

---

## §12. Invariant enforcement-point naming (Skeletal §11.4)

**Source:** Skeletal §11.4 (each named invariant has BOTH a runtime gate and a Stage 9 lint); §11.9 (monotonicity / algebraic invariants); ADQ-316 (restamp ceilings). **Owner:** DOC80 core **names** the cross-family invariants and their enforcement points; the **runtime gates live in the member docs**. This is the anti-"invariant that sounds good but is never enforced" mechanism: every invariant has a named gate (where violation is prevented) *and* a named lint (where violation is detected at Stage 9).

### §12.1 Cross-family invariants table

The load-bearing invariants and their enforcement points (Skeletal §11.4 + §11.9):

The load-bearing invariants, their enforcement points, and their Stage-8 negative fixture (UR-48 adds the fixture column):

| invariant | runtime gate (owner / location) | Stage 9 lint | Stage 8 negative fixture |
|---|---|---|---|
| `can_orient_only` (RecentActivityRollup never becomes evidence) | DOC83 `RecentActivityRollupConsumptionContract`; DOC84 packet-assembly check | `revocation.recent_activity_used_as_evidence` | `fixture.golden.recent_activity_used_as_evidence_fails` |
| removed/blocked membership edge never reaches injection | DOC87 `MembershipLifecycleState` gate at DOC84 ContextProduct planning; DOC84 packet-assembly check | `membership.removed_or_blocked_edge_used_for_injection` | `fixture.golden.removed_membership_cannot_inject` |
| no learning signal without proof | DOC85 learning-signal eligibility check; DOC11 `ContextPacketProof` presence at handoff | `proof.learning_signal_without_context_packet_proof` | `fixture.golden.learning_signal_without_proof_fails` |
| **no learning/utility/prompt-shell credit without final-prompt survival** (UR-02) | DOC85 eligibility; DOC11 `FinalPromptTruthRef` at handoff (§3.5) | `learning.utility_without_final_prompt_proof` [canonical] | `fixture.golden.learning_credit_without_final_prompt_truth_fails` |
| **delivery attestations are EC-signed against a read-consistent generation and MUST NOT take a write-queue lock** (UR-03/04) | EC `anchored_attestation` path; DOC84 | `ec.delivery_attestation_on_serialized_write_path` | `fixture.golden.delivery_attestation_off_write_queue` |
| DAMS eligibility ceiling never exceeded | EC `PolicyCappedDAMSInput` construction at DOC81; DOC84 DAMS-substrate enforcement | `dams.eligibility_ceiling_violation` | `fixture.golden.dams_eligibility_ceiling_exceeded_fails` |
| EC is the sole durable writer | EC write API; all non-EC writers blocked at the seam | `proof.durable_write_by_non_ec_actor` | `fixture.golden.non_ec_write_detected` |
| ABC §7.8 anti-overlap (no duplicate resolution/disposition enums) | DOC82 resolution-authority check at `AssertionResolution` | `assertion.overlapping_resolution_disposition_enum` | `fixture.golden.overlapping_disposition_enum_fails` |
| `LegalHoldState` honored by destructive jobs | DOC81 `LegalHoldState` query at every destructive-job invocation (DOC72 §42 / DOC23 / DOC25) | `legal_hold.destructive_job_skipped_check` | `fixture.golden.hard_destruction_without_legal_hold_clearance_fails` |
| **effective-state gating** (memory ops gate on EC off-switch / incognito / collection state; ADQ-406 family) | EC §1 effective-state; DOC81 `collection_mode` | `ec.flow_issued_while_subsystem_disabled` [proposed] | `fixture.collection_suppression.disabled_subsystem_flow_fails` |
| **collection-suppression gating** (a collection-suppressed "privacy" topic is not admitted; ADQ-406) | DOC81 `collection_mode` suppression; EC §1 enforces | `collection.suppressed_topic_admitted` [proposed] | `fixture.collection_suppression.suppressed_topic_admitted_fails` |
| **portability / separation** (exported/portable memory preserves separation; no cross-principal bleed) | EC §8 export; DOC81 | `portability.cross_principal_bleed` [proposed] | `fixture.golden.portability_separation_preserved` |
| **export/delegation boundary-disclosure re-evaluation** (N8; generalized to all egress at §22) | EC; `E0EgressAttestation` (§22) | `egress.outbound_action_without_destination_policy_decision` [proposed] | `fixture.egress.destination_mismatch_fails_closed` |
| **restore re-evaluation** (R3 §(b)#9 — a restore re-evaluates current policy + source-revocation + legal-hold at restore time; a `hard_destruction` cannot be restored) | EC §7/§8 restore; DOC81 | `restore.reintroduces_revoked_or_held_material`; `restore.of_hard_destruction` | `fixture.golden.restore_of_hard_destruction_fails` |
| **membership monotonicity** (membership never raises warrant) | DOC87 `MembershipLifecycleState` transition gate; DOC82 warrant evaluation | `monotonicity.membership_raised_warrant` | `fixture.golden.membership_raised_warrant_fails` |
| **policy monotonicity** (policy only narrows without a `PolicyStampRestamp`; restamp cannot exceed original ceilings, ADQ-316) | DOC81 `EffectiveMemoryPolicy` meet + restamp gate (ADQ-316) | `monotonicity.policy_widened_without_restamp` | `fixture.golden.policy_tighten_between_plan_and_render_blocks_or_restamps` |
| **source-revocation monotonicity** (revocation only lowers eligibility until re-proof; **polarity-aware** — a contrary-source removal MAY raise net warrant, UR-09) | EC `CascadingSourceInvalidation` execution; DOC82 re-proof path | `monotonicity.revocation_raised_eligibility` | `fixture.golden.revoked_source_invalidates_support_membership_delivery_learning_ui` |
| **learning monotonicity** (learning cannot increase warrant **beyond the non-learning ceiling** — UR-47) | DOC85 learning eligibility; DOC82 AssertionCandidate pipeline | `monotonicity.learning_upgraded_warrant_without_evidence` | `fixture.golden.learning_upgraded_warrant_beyond_ceiling_fails` |
| **injection-eligibility totality** (`injection_eligible: MembershipLifecycleState → bool` is total; `{removed, blocked} → false`, structural) | DOC87 (total function, structural not lint-only); DOC84 packet-assembly check | `injection_eligibility.non_total_function` | `fixture.golden.injection_eligible_non_total_fails` |

The monotonicity laws (Skeletal §11.9) are stated as **algebraic invariants**: membership and learning may adjust eligibility/staleness but never *raise* warrant — and learning specifically may not raise it **beyond the non-learning ceiling** (UR-47); policy meets are monotone-restrictive with restamp as the only (ceiling-bounded, ADQ-316) widening path; source revocation is monotone-down until re-proof through a fresh `EvidenceSupportEdge`. **Finding 2 scoping:** the monotonicity law applies to **supported** assertions only — a *contradicted* assertion's net warrant MAY rise on recompute when a contrary source is removed (UR-09 polarity; tie `monotonicity.revocation_raised_eligibility` to a polarity-aware recompute trace, not a flat prohibition). The injection-eligibility totality is **structural, not lint-only** — `{removed, blocked}` always map to `false` by construction (the strongest form of the "removed/blocked edge never injects" invariant).

**SourceRevocationCascade (UR-08/09; N3 — 5 planes, no 6th, no promotion-time invariant; clawbacks manual).** The cascade is the existing **5 planes of effect** (DOC82 / DOC84 / DOC85 / DOC86 / DOC87); **no 6th plane is added and no promotion-time invariant is added** — clawbacks are rare (~twice in 23 years) and handled manually (recorded so no later charter silently re-inherits a 6th plane). Per-plane execution lives in DOC82/84/85/86/87; E0 owns the invariant shape:

```typescript
interface SourceRevocationCascade {   // invariant in E0; per-plane execution in DOC82/84/85/86/87
  source_ref: SourceRef;
  revocation_event_ref: MemoryMutationEnvelopeRef;
  affected_set_manifest_ref: SourceRevocationAffectedSetManifestRef;  // R3 §(b)#5: names the affected set; per-plane scan bodies downstream
  required_outcomes: {
    doc82_support_edges: 'invalidated' | 'verify_required';
    doc87_memberships: 'restamped' | 'removed' | 'hidden';
    doc84_delivery_artifacts: 'invalidated';
    doc85_learning_signals: 'ineligible_for_future_utility';
    doc86_surfaces: 'safe_labeled' | 'suppressed';
  };
  ec_receipt_refs: ECReceiptRef[];
  reason_codes: ReasonCodeId[];
}
```

**Revocation lint set (tagged per the lint-status convention):** `revocation.support_edge_survives_revoked_source` [canonical]; `revocation.membership_survives_revoked_source_without_restamp` [canonical]; `revocation.carryover_capsule_survives_revoked_source` [canonical]; `revocation.learning_credit_after_revocation` [canonical]; `revocation.learning_signal_survives_revoked_source` [canonical — Synthesis §4]; `revocation.inspector_leaks_revoked_source` [canonical]; `revocation.published_view_not_invalidated_after_revocation` [canonical] (Skeletal §10.11 = these planes-of-effect) + polarity lints `revocation.supporting_source_removed_without_recompute` [proposed]; `revocation.contrary_source_removed_without_recompute` [proposed]; `revocation.net_warrant_changed_without_recompute_trace` [proposed]; `revocation.cascade_missing_affected_set_manifest` [proposed] (R3 §(b)#5).

### §12.2 Stage 9 lint roll-up

E0 *names* these invariants and their lints; **DOC80 does not implement them** (Stage 9 implements). Stage 6 charters add member-specific runtime-gate owners for any invariant not in the §12.1 table (Skeletal §11.4). The full E0-named lint inventory is consolidated in §16.3.

**Cross-charter consumption.** DOC83 (`can_orient_only`), DOC87 (membership monotonicity + injection-eligibility totality), DOC85 (learning monotonicity + proof gate), DOC81 (policy monotonicity + LegalHoldState + DAMS ceiling), DOC82 (ABC §7.8 anti-overlap + revocation monotonicity), DOC84 (packet-assembly enforcement of several), EC (sole-writer + revocation execution).

---

## §13. ABC §21 normalization-object placement check (Skeletal §10.17)

**Source:** Skeletal §10.17 (Stage 6 charter input — verify/add Owner Map rows for seven normalization objects; "anything missing should be slotted; nothing requires a new family member"). **This is an E0 *input-verification* obligation, not an E0 *ownership* obligation** — the brief is explicit that these objects most likely land in DOC82 / DOC84 / DOC85, **not DOC80** (Opening Brief target 20). E0 verifies each object, assigns it to a member, and — because E0 cannot write the Owner Map (Hard Constraint §1) — defers the actual row addition to that member's charter.

### §13.1 Verification table per object

| ABC §21 object | current Owner Map row? | disposition (assign) | basis |
|---|---|---|---|
| `WarrantEvaluationResult` | none | **DOC82 / E3** (§1.8 warrant family, beside `WarrantEvaluationInput` + `EffectiveWarrant`) | Skeletal §10.17 explicit hint ("likely DOC82 §1.8"); Owner Map line 37 |
| `WarrantConsequenceRegistry` | none | **DOC82 / E3** (the warrant plane owns the vocabulary of warrant consequences; ABC §7.13) | warrant-semantic; brief steer "not DOC80"; see §16.1 note on the core-registry alternative |
| `DomainProfileWarrantPolicy` | none (referenced) | **DOC82 / E3** (warrant policy per domain) — **referenced** by DOC80 domain-profile registry via `warrant_policy_ref` (§2.2) | ADQ-313 + warrant plane; the value has a plane (warrant) |
| `IngestionCostBudget` | none | **DOC25 / E4 seam** (ingestion cost), **declared against** DOC80 `FamilyWideComputeBudget` (§10.1) | ingestion is DOC25's plane; AC-001/ADQ-401; see §16.1 (external-doc row nuance) |
| `PromotionGateRecord` | none | **DOC82 / E3** (record of an Assertion promotion-gate decision; DOC1 Write Gate executes) | promotion to canonical Assertion is DOC82's plane; DOC1 executes |
| `ConsideredItemLedger` | none | **DOC84 / E7** (records items considered at assembly), **consumed by DOC85** false-suppression sampling | delivery records what it considered; Owner Map line 174 (FalseSuppressionSampling consumes) |
| `PromptShellExposure` | none | **DOC84 / E8** (runtime record of which shells were exposed), **references** DOC80 `PromptShellRegistry` (§2.3) | runtime exposure has a delivery plane; registry stays in core |

**Distribution:** DOC82 ×4, DOC84 ×2, DOC25 ×1. **None lands in DOC80** (consistent with the brief steer), and **none requires a new family member** (consistent with Skeletal §10.17). This satisfies the ABC §21 check: every object is verified and slotted.

### §13.2 Owner Map gap dispositions

None of the seven objects currently has an explicit Owner Map row (they are ABC §21 normalization objects not yet slotted — which is precisely why §10.17 is an E0 input). Because E0 is **read-only on the Owner Map** (Hard Constraint §1), the disposition is: **E0 assigns each object to its member above; the member's charter (E3 / E4 / E7–E8) adds the actual Owner Map row** when it drafts that object's schema. The dispositions are reasoned from object names + the warrant/ingestion/delivery plane logic; the named charters should **verify against ABC §21 source** when adding the rows (ABC §21 is not in the E0 read-list — noted in §16.1). The two dispositions carrying genuine placement nuance (`WarrantConsequenceRegistry` core-registry alternative; `IngestionCostBudget` external-doc row) are flagged in §16.1.

**Lints (Stage 9):** `abc21.normalization_object_unslotted` (any of the seven still without an Owner Map row at its member's charter ratification).

**Fixtures (Stage 8):** `fixture.abc21.seven_objects_slotted_no_new_member`.

**Cross-charter consumption.** DOC82/E3 (WarrantEvaluationResult, WarrantConsequenceRegistry, DomainProfileWarrantPolicy, PromotionGateRecord), DOC84/E7–E8 (ConsideredItemLedger, PromptShellExposure), DOC25/E4 (IngestionCostBudget).

---

## §14. Future completion obligations (AC-004 + AC-005)

**Source:** ADQ-403 (AC-004); ADQ-404 (AC-005); Input Deck "AC-004 / AC-005." **Owner:** posture recorded by DOC80 core; completion is future. These are `include_as_future_completion_obligation` items — recognized now, with their `minimum_completion_for_v5` enum carried into E0, but completed later.

### §14.1 Memory Intake & At-Use Disciplines (ADQ-403 / AC-004)

**Per ADQ-403:** the Memory Intake & At-Use Disciplines proposal is `include_as_future_completion_obligation`; **`minimum_completion_for_v5 = schema_plus_lints_and_fixtures`**; owner **Memory Control Plane (DOC80 core) + DOC25 + DOC73**. The disciplines govern what is admitted into memory (intake) and how it may be used at delivery (at-use) — directly adjacent to the over-aggressive-ingestion and silent-auto-promotion failure modes (§1.6). The minimum bar for V5 is not merely a schema and an owner boundary; it is **schema + lints + fixtures**, because intake/at-use disciplines without enforcement quietly fail open. **AC-004 completion criteria (UR-33):** `schema + owner + positive fixture + negative fixture + Stage-9 lint` — all five before AC-004 is "done." E0 records the obligation and its owners; the discipline content is completed as a future obligation coordinated across DOC80 core + DOC25 (intake) + DOC73 (source-bound synthesis at-use).

### §14.2 EC Core Addendum A intake-routing (ADQ-404 / AC-005)

**Per ADQ-404:** the EC Core Addendum A intake-routing for corpus bindings is `include_as_future_completion_obligation`; owner **EC Core + Memory Control Plane (DOC80 core)**; **depends on ADQ-202 (Corpus hierarchy)**. ADQ-202 is resolved at the **E4 charter** as a HARD COMMITMENT (not an infinite defer) — internal Corpus/SourceCollection/CorpusIndex structures sit *behind* user-visible Libraries (ADQ-202). AC-005 therefore has a **soft dependency on ADQ-202**: it does **not** block E0 entry or completion (Input Deck pre-conditions: "AC-005 has a soft dependency on ADQ-202 … not blocking E0 entry but blocking AC-005 completion"), but AC-005 *completion* must wait for ADQ-202/E4. **AC-005 completion gates (UR-33):** it is gated on **ADQ-202 AND `ECSeamContract` (§7.1) AND DOC25 materialization / source-binding AND DOC82 source/evidence** — all four. E0 records the obligation, its owners (EC Core + DOC80 core), and these gates.

### §14.3 minimum_completion_for_v5 summary

| obligation | ADQ | minimum_completion_for_v5 | owners | gate |
|---|---|---|---|---|
| Memory Intake & At-Use Disciplines | ADQ-403 (AC-004) | `schema_plus_lints_and_fixtures` | DOC80 core + DOC25 + DOC73 | none (recognized at E0; completed future) |
| EC Core Addendum A intake-routing (corpus bindings) | ADQ-404 (AC-005) | (per ADQ-404; completion-gated) | EC Core + DOC80 core | **ADQ-202** (resolves at E4) |

For reference, the two adjacent AC obligations pinned elsewhere (not E0-owned) carry: AC-001/ADQ-401 (`schema_plus_owner_boundary`, DOC25 + DOC80 core); AC-002/ADQ-402 (`schema_plus_lints_and_fixtures`, depends ADQ-202); AC-003/ADQ-405 (`schema_plus_lints_and_fixtures`, RecentActivityRollup, E6). E0's own AC obligations are AC-004 and AC-005.

**Cross-charter consumption.** E4 (ADQ-202 resolution unblocks AC-005 completion + the Corpus side of AC-004 intake); DOC25/DOC73 (AC-004 co-owners); EC Core (AC-005 co-owner).

---

## §15. Stage 6 charter exit + cross-charter dependencies

### §15.1 What E0 unblocks

E0 is the foundation; its completion unblocks (Opening Brief; Input Deck pre-conditions):

- **E1 / E2 (DOC81 Scope & Policy)** — via the **ReasonCode registry** (§2.1; ADQ-310 "unblocks E0/E1/E2") and the **domain-profile registry** (§2.2). E1 cannot draft policy/scope reason codes until §2.1's namespace rules are stable.
- **E7 / E8 (DOC84 Delivery + Prompt/Proof)** — via **ContextProduct** (§3.1; DOC24 binds), **MemoryContextPlan** (§3.2; DOC24 binds), **PromptShellVariant/Registry** (§2.3), and the **proof spine** (§4). These field-level schemas must be stable before DOC84 authoring (Input Deck open seam).
- **E9 (DOC85 Learning)** — via the **PromptShellLearningContract** (§2.3), the **warrant-degradation-trigger registry** (§2.4; DOC85 owns producers), and **MemoryFlowCertificate** learning-attribution (§3.3) + the **ContextPacketProof** learning gate (§4.1).
- **E_org (DOC87 Organization & Membership)** — via the **injection-eligibility totality** invariant (§12) and the **memory-object taxonomy** (§6; membership/topic rows).
- **E3 / E4 (DOC82 Knowledge + Source/Evidence)** — via the **taxonomy** (§6), the **bitemporal carrier** convention (§8.2; DOC82 owns the axes), the **ExternalDependencyRecord** posture (§7; DOC72/DOC73/DOC25), and the **ABC §21** warrant-object slots (§13).

### §15.2 What E0 depends on (none — foundational)

**E0 has no upstream charter dependency** (Opening Brief Pre-conditions; Input Deck "None upstream — E0 is foundational"). The DOC80 baseline (Skeletal + Owner Map + Import Graph + Retired Names) provided all upstream context, and the Import Graph topological order confirms DOC80 is the root (`DOC80 < DOC81 < DOC82 < DOC87 < DOC83 < DOC84 < {DOC85, DOC86}`; Import Graph §2.5). The single soft, non-blocking note is **AC-005's** completion dependency on **ADQ-202** (resolves at E4) — this gates AC-005 *completion only*, not E0 entry or completion (§14.2).

### §15.3 Discharge sweep checklist

At ratification (architect + red-team), the following discharge sweep runs (Opening Brief exit criterion #7; Skeletal §10.19 closing-step discipline):

1. **8 ADQ landings** confirmed in §17.1 (203, 208, 210, 211, 310, 313, 403, 404) — mark resolved-by-this-charter in `Architect_Decision_Queue.md` (post-E0; architect step — E0 is read-only on the ledger).
2. **Skeletal §10/§11 fold-in landings** confirmed in §17.2 — mark landed.
3. **0 OPA V4 rows** target DOC80 core (Input Deck) — this is housekeeping only.
4. **Closing-step drift sweep** (Skeletal §10.19): after ratification, sweep companion files (OP-A, Owner Map placeholder rows, plan §12 slice list, ADQ status references, Supersession Matrix + Retired Names citations) for consistency.
5. **Cross-charter pre-conditions published** — confirm §2.1/§2.3/§3.1/§3.2/§4 schemas are stable before E1/E2 and E7/E8 begin.

### §15.4 Cross-charter gate table (UR-32)

The stop a future charter hits before it can proceed. Every §16.2 deferral has a row here (the §15.5(d) regression check enforces the §16.2 ↔ §15.4 ↔ §17.4 triangle).

| Gate | Source | Blocked charter(s) | Required before | Owner | Blocking? |
|---|---|---|---|---|---|
| UR-01 ContextProduct **17**-kind registry | ABC §9.2 / §3.1 | E7/E8 | DOC84 binds assembly | DOC80 | **yes** |
| UR-02 `FinalPromptTruthRef` | §3.5 / ADQ-207 | E8/E9 | DOC85 learning credit; DOC84 executed render | DOC11/DOC80 | **yes** |
| UR-08 `SourceRevocationCascade` (5-plane) | §12.1 | E3/E4/E7/E8/E9/E10 | per-plane execution drafted | DOC82/84/85/86/87 | **yes** |
| UR-31 `SemanticProjectionContract` | §3.6 | E3/E7/E8/E10 | 4 concrete projections drafted | DOC82/84/86/87 | **yes** |
| `TopicIdentityContract` stub | OPA-032 / §8.4 | E5 | DOC87 stub before DOC83 `TopicCollectionDirective` | DOC87 | **yes (ordering)** |
| `IngestionCostBudget` | §13.1 / Finding 7 | E3 (E4 confirm) | DOC25 declares against §10.1 envelope | DOC25/DOC80 | **yes** |
| `WarrantConsequenceRegistry` | §13.1 / Finding 7 | E4 (E3 confirm) | DOC82 warrant plane | DOC82 | **yes** |
| ADQ-406 DOC81 `collection_mode` suppression | §12.1 / OPA §6.Z | E1/E2 | DOC81 governance; EC §1 enforces | DOC81/EC | **yes** |
| DOC81 per-topic privacy-layer gate | §12.1 | E1/E2 | DOC81 privacy layer | DOC81 | **yes** |
| ADQ-407 EC global recycle bin + retention | §7.1 / OPA §6.Z | EC charter | EC deletion-&-recovery machinery | EC | **yes** |
| ADQ-408 EC restore-from-backup | §7.1 / OPA §6.Z | EC charter | EC §7/§8 | EC | **yes** |
| Destruction-ledger body | §3.7 | EC (write path) + DOC84/DOC85/DOC11 (consumers) — R3 §(b)#1 | EC durable storage + consumer surfaces | EC/DOC84/85/11 | **yes** |
| PromptShellExposure / DebugModeContract / `embedding_generation_id` bodies | §3.8/§3.9/§8.1 | DOC85 / Stage 7 | Stage 7 schema bodies | DOC85/Stage 7 | **yes** |
| `SourceBoundSynthesisAdapter` convergence | OPA-035 / §3.6 | E3/E4 | DOC73 CU reconciliation | DOC73/DOC82 | conditional |
| DOC85 two-phase | ADQ-221 / §7.2 | E9 | BDSM revision (Phase 2 names surfaces) | DOC85/BDSM | phased |
| DOC15 CIL seam | §7.4 / Skeletal §11.5 | E7/E8, E10 | delivery/UI seam confirmed | DOC15/DOC80 | no (stable) |
| DOC26 UnifiedWorkspaceLibrary | §7.4 / Skeletal §11.6 | E10 | ADQ-202/404 resolution | DOC26 | conditional (aspirational) |
| ADQ-202 Corpus hierarchy | §14.2 | E4/E_org/E10 | AC-005 completion; Library/Corpus structures | architect/E4 | gates completion, not E0 entry |
| `MemoryMutationEnvelope` field body | §5.1 / §16.2 | Stage 7 / durable-mutation charters | Stage 7 envelope body drafted before durable mutation schemas depend on its fields | DOC80/EC | **yes** |
| `MemoryProvenanceGraph` field body | §5.2 / §16.2 | Stage 7 / lineage-consuming charters | Stage 7 provenance body or explicit member handoff drafted | DOC80 + consuming members | **yes** |
| `ResumeProjection` / `ResumeCard` body | §5.3 / §16.2 | E7/E8/E10 | Delivery/UI body and render surface drafted | DOC84/DOC86 | **yes** |
| DOC81 policy-axis enum values | §2.2 / §16.2 | E1/E2 | DOC81 owns and drafts axis semantics | DOC81 | **yes** |
| DOC84 `RenderSafetyProof` executed body | §4.2 / §16.2 | E7/E8 | DOC84 executed proof body drafted against E0 contract | DOC84 | **yes** |
| Lint / fixture / migration meta-schemas | §8.5 / §16.2 | Stage 7/8/9 | Meta-schema ownership and fixture/lint manifests assigned | Stage 7/8/9 | conditional |
| §20 per-member obligation instances | §20 / §16.2 | E1-E10 / E_org | Member-specific obligation rows filled in each charter | each member | **yes** |
| DOC25 ReasonCode-producer grounding | §2.1 / §16.2 | Owner Map / OP-A discharge | DOC25 scoped producer grounding recorded in Owner Map / OP-A | architect/DOC25 | **yes** |
| §19/§20 final bodies | §19-§20 / §16.2 | E0 ratification | Architect accepts or patches first-draft amendment and member-obligation bodies | DOC80 | **yes** |
| Seven ABC §21 Owner Map rows | §13.2 / §16.2 | E3/E4/E7-E8 | Owner Map rows added or explicitly deferred by each owning charter | DOC82/DOC25/DOC84 | **yes** |
| AC-004 / AC-005 completion | §14 / §16.2 | future completion | Completion criteria met or explicitly deferred in owner charter | DOC80+DOC25+DOC73 / EC | conditional |
| BETTER_IDEA UR-43/44/45 | §16.4 / §16.2 | Stage 7+ | Later charter accepts, rejects, or re-defers each better-idea item | DOC84/DOC86 | no |
| ADQ-222 Phase-1 sharing schemas | §1.3 / §16.2 | Stage 7 if architect says draft now | Architect decision recorded before schema bodies are drafted | architect / Stage 7 | conditional |

### §15.5 Post-patch regression gate (R2 §15.5)

After the R2 + R3 patch is applied, a single regression pass MUST confirm — before E0 is marked ratifiable — that:

- (a) `ContextProductKind` reads **17** everywhere (no stale "14" outside the fold-in-count numerals in §16.1/§17.2);
- (b) the MFC union has all **nine** flow kinds and every `issued` variant carries its required refs;
- (c) every new lint name is either `[canonical]` (verbatim source) or `[proposed]` (Stage-9 confirm) — none silently promoted;
- (d) every §16.2 deferral has a matching §15.4 gate row **and** a §17.4 matrix row;
- (e) `SemanticProjectionContract` (§3.6) is defined and §18 is present;
- (f) §1.6 / §19 / §20 restored (the baseline's §4/§19/§20);
- (g) no retired/invented name reintroduced (cross-checked against `DOC80_Retired_Names.md`);
- (h) the three committed OPA §6.Z obligations + ADQ-406/407/408 are referenced from the gate table and preservation matrix.

Lint bundle `regression.e0_post_patch_*` [proposed] backs this gate. The application-time run of this gate is recorded in `E0_Application_Report.md` §15.5.

### §15.6 Family-wide acceptance standard (ADJ-3)

A family member's E-charter is **accepted** when it satisfies the family-wide standard: (1) the **flatten-plan §19** completeness bar; (2) the **§15.3 discharge sweep** (no stale cross-artifact drift); and (3) the **§12 invariant gates** (every invariant it touches has both a runtime gate owner and a Stage-9 lint, and a Stage-8 negative fixture per §12.1). This standard is the union of the per-member acceptance criteria; §17 (this charter) + §14/§15.3 carry the DOC80-specific instances.

---

## §16. Open items + architect-review flags

### §16.1 OPEN_FOR_ARCHITECT_REVIEW items

The draft traces every contract to a citation; genuine open items are now **two**, well under the ≤5 target — two placement nuances from the ABC §21 check (§13). (The earlier `ContextProductKind` enumeration-fidelity flag is **RESOLVED** by UR-01 — see item 3.)

1. **`IngestionCostBudget` lands on an external doc (DOC25).** The §13.1 disposition assigns `IngestionCostBudget` to DOC25/E4 (ingestion plane), declared against DOC80's `FamilyWideComputeBudget` (§10.1). DOC25 is external and not re-chartered by the flatten, so the Owner Map row is unusual (an external-doc row added at the E4 seam). *Alternative:* treat it as a DOC82/E4 source-evidence-seam object instead. **Recommended:** DOC25/E4 declaration against the DOC80 envelope (keeps ingestion cost with the ingestion owner). Architect to confirm the external-row vs DOC82-seam choice at E4.
2. **`WarrantConsequenceRegistry` placement — DOC82 plane vs DOC80 cross-cutting registry.** §13.1 assigns it to DOC82/E3 (the warrant plane owns its consequence vocabulary), following the brief steer "not DOC80." *Alternative:* a core cross-cutting registry (by analogy to the warrant-degradation-trigger registry, §2.4, which is core with DOC85 producers). **Recommended:** DOC82/E3, because warrant consequences have a clear plane (warrant) whereas the degradation-*trigger* vocabulary is genuinely cross-producer. Architect to confirm if a core registry is preferred.
3. **`ContextProductKind` enumeration fidelity (§3.1) — RESOLVED (UR-01).** The earlier draft used an illustrative 14-kind reconstruction. This is now resolved: **ABC R0.2 §9.2 enumerates exactly 17 kinds and is senior** (DR-001 / Skeletal §3.3; verified directly against the source), so §3.1 now carries the canonical 17 and SM-060's "14" is superseded (discharge: SM-060 row update, §16-discharge). No longer an open item.

(Process note, not an architect-stop: the seven §13 dispositions are reasoned from object names + plane logic; **ABC §21 source is not in the E0 read-list**, so E3/E4/E7 should verify against ABC §21 when adding the Owner Map rows. Tracked in §16.2.)

### §16.2 Deferral register — every deferral has a pickup trigger (R2 §7)

The spec tracks every deferral; the architect tracks nothing out-of-band. Each row pairs to a §15.4 gate row and (where load-bearing) a §17.4 preservation-matrix row — the §15.5(d) regression check enforces the triangle.

| Deferred item | Why not in E0 | Owner / landing | Recorded in (pickup trigger) |
|---|---|---|---|
| `MemoryMutationEnvelope` field body | NAMED-only by plan | Stage 7 | §5.1 + §15.4 + §17.4 |
| `MemoryProvenanceGraph` field body | NAMED-only by plan | Stage 7 | §5.2 + §15.4 |
| `ResumeProjection`/`ResumeCard` body | NAMED-only by plan | Stage 7 (DOC84/86) | §5.3 + §15.4 |
| DOC81 policy-axis enum values | DOC81 owns axis semantics | DOC81 / E1–E2 | §2.2 + §15.4 (UR-11) |
| DOC84 `RenderSafetyProof` executed body | DOC84 owns execution | DOC84 / E7–E8 | §4.2 + §15.4 (UR-06) |
| `FinalPromptTruthRef` runtime body | DOC11/OpenClaw owns runtime truth | DOC11 / Stage 7 | §3.5 + §15.4 (UR-02) |
| Lint / fixture / migration meta-schemas | Stages 7/8/9 (UR-28 reject) | Stage 7/8/9 | §8.5 (UR-28b) + gates |
| §20 per-member obligation instances | filled as each member charters | E1–E10 / E_org | §20 + §15.4 |
| DOC25 ReasonCode-producer grounding (scoped) | bookkeeping ratification (scoped to parse/materialization/ingestion) | architect / Owner Map | §2.1 + §17.4 (UR-37) |
| §19/§20 final bodies | first-draft now; refine | E0 ratification | §19/§20 + §17.4 (UR-38) |
| Destruction-ledger body/storage | NAMED-only seam in E0 | **EC write path** + DOC84/DOC85/DOC11 consumers (R3 §(b)#1) | §3.7 + §15.4 + §17.4 |
| `PromptShellExposure` (proof-shaped) | NAMED-only orphan (R3 §(b)#3) | DOC85 / Stage 7 | §3.8 + §15.4 (F11) |
| `DebugModeContract` | NAMED-only orphan (F30-scoped) | Stage 7 | §3.9 + §15.4 (F30) |
| `embedding_generation_id` body | NAMED-only orphan | DOC82/DOC85 / Stage 7 | §8.1 + §15.4 (F28) |
| ADQ-406 DOC81 `collection_mode` suppression | DOC81 owns governance; EC §1 enforces | DOC81 / E1–E2 | §12.1 + §15.4 + OPA `OBL-D81-TOPIC-COLLECTION-SUPPRESSION-01` |
| ADQ-407 EC global recycle bin + retention | EC owns deletion-&-recovery machinery | EC charter | §7.1 + §15.4 + OPA `OBL-EC-GLOBAL-RECYCLE-BIN-01` |
| ADQ-408 EC restore-from-backup into fresh install | EC §7/§8 owns | EC charter | §7.1 + §15.4 + OPA `OBL-EC-RESTORE-FROM-BACKUP-01` |
| N3 clawback decision (5 planes, no 6th, no promotion invariant; manual) | DECIDED | architect note | §12.1 UR-08 note + §17.4 (so no later charter re-adds a 6th plane) |
| Seven ABC §21 Owner Map rows | E0 is read-only on the Owner Map (Hard Constraint §1) | E3 / E4 / E7–E8 | §13.2 + §15.4 |
| AC-004 completion / AC-005 completion | future; AC-005 gated on ADQ-202 | DOC80+DOC25+DOC73 / EC Core | §14 + §15.4 |
| BETTER_IDEA UR-43/44/45 (UR-42 partly promoted to §3.7) | forward capability | DOC84/86 + Stage 7+ | §16.4 + §17.4 |
| ADQ-222 (V5 Phase-1 networking) | does not block Stage 6 | architect / Stage 7 | §1.3 + ADQ ledger |
| `WarrantConsequenceRegistry` core-registry alternative | lower-severity placement nuance | DOC82/E3 (recommended) vs DOC80 core | §16.1 item 2 |

**Mechanism (R3 §(b)#11).** No out-of-band memory is required once the §16.2 deferral register, the §15.4 gate table, the §17.4 preservation matrix, the OP-A rows, the ADQ ledger, and the cross-artifact sweep entries are updated: §15.4 is the stop a future charter hits, §17.4 proves nothing was silently lost, OP-A carries cross-doc obligations (incl. the three committed §6.Z rows), and the ADQ ledger carries decisions (incl. ADQ-406/407/408).

### §16.3 Lint and fixture roll-up for Stage 9 / Stage 8

**Lint-status rule for this charter.** This §16.3 inventory is the authoritative lint-status table. Every lint token listed below is `[proposed]` unless it appears in the explicit canonical set here or is individually tagged `[canonical]` at its local definition. Canonical tokens currently recognized in E0 are: `learning.utility_without_final_prompt_proof`; `erasure.retired_used_as_erased`; `erasure.legal_hold_bypassed_without_adq_resolution`; `projection.used_as_canonical_truth`; `projection.owner_missing`; `projection.missing_invalidation_policy`; `projection.missing_source_refs`; `revocation.support_edge_survives_revoked_source`; `revocation.membership_survives_revoked_source_without_restamp`; `revocation.carryover_capsule_survives_revoked_source`; `revocation.learning_credit_after_revocation`; `revocation.learning_signal_survives_revoked_source`; `revocation.inspector_leaks_revoked_source`; `revocation.published_view_not_invalidated_after_revocation`; `policy.bare_render_action`; `policy.export_stamp_without_destination`; `learning.writeback_without_ec_execution`. Local section lint lists inherit this status table; any new lint added after ratification MUST carry an inline `[canonical]` or `[proposed]` tag.

E0 **names** lints (Stage 9 implements) and fixtures (Stage 8 implements); E0 implements neither. Per UR-46 the inventory is split by owner: **(a) DOC80-substance** (Stage-9 names, below, by section); **(b) flatten-governance** lints (`import_graph.*` / `owner_map.*` / `opa.*`) owned by the flatten-governance suite, acknowledged in the §17.4 preservation matrix, not re-listed here; **(c) provenance caveat** — coined tokens are marked `[proposed]` (Stage 9 confirms); canonical source tokens (`learning.utility_without_final_prompt_proof`, `erasure.retired_used_as_erased`, `projection.*`, `revocation.*`) are verbatim. The **(a) DOC80-substance** inventory, by section:

- **§2.1 ReasonCode:** `reason_code.unregistered_emission`, `reason_code.namespace_written_by_non_owner`, `reason_code.retired_code_emitted`, `reason_code.entry_without_namespace_owner`.
- **§2.2 DomainProfile:** `domain_profile.missing_resolves_to_conservative`, `domain_profile.no_unique_conservative_fallback`, `domain_profile.knob_value_owned_by_core`.
- **§2.3 PromptShell:** `prompt_shell.unregistered_variant_selected`, `prompt_shell.learning_minted_shell_text`, `prompt_shell.load_bearing_variant_absent_from_proof`, `prompt_shell.policy_variant_treated_as_stable`.
- **§2.4 WarrantDegradationTrigger:** `warrant_trigger.new_kind_without_adq`, `warrant_trigger.emission_raised_eligibility`, `warrant_trigger.producer_owner_unassigned`.
- **§3.1 ContextProduct:** `context_product.kind_not_in_registry`, `context_product.assembled_without_policy_gate`, `context_product.nondeterministic_inputs`, `context_product.orientation_used_as_evidence`, `context_product.injected_removed_or_blocked_membership`.
- **§3.2 MemoryContextPlan:** `memory_context_plan.stale_policy_generation_used`, `memory_context_plan.missing_coordination_trace`, `memory_context_plan.requested_product_not_in_registry`.
- **§3.4 MemoryCoordinationTrace:** `coordination_trace.missing_on_privileged_flow`, `coordination_trace.proof_ref_dangling`, `coordination_trace.plan_ref_dangling`.
- **§4 Proof spine (B8):** `proof.durable_write_without_memory_flow_certificate`, `proof.render_without_context_packet_proof`, `proof.render_without_render_safety_proof`, `proof.export_without_memory_flow_certificate`, `proof.carryover_without_memory_flow_certificate`, `proof.delegation_without_memory_flow_certificate`, `proof.learning_signal_without_context_packet_proof`, `proof.durable_write_by_non_ec_actor`.
- **§6 Taxonomy:** `taxonomy.object_unclassified`, `taxonomy.derived_marked_truth_apt`, `taxonomy.truth_apt_outside_assertion_family`.
- **§7 ExternalDependency / ECSeam / DOC8:** `external_dependency.unpinned`, `external_dependency.drift_unhandled`, `ec.dependency_not_marked_partial_or_moving`, `ec.durable_write_without_ec_execution`, `ec.dedupe_write_without_generation_revalidation`, `ec.policy_generation_changed_without_regate`, `ec.learning_writeback_without_ec_execution`, `doc85.runtime_dependency_on_legacy_doc8`, `doc85.learning_computation_owned_by_phantom_doc8`.
- **§8 Field conventions:** `embedding.semantic_equivalence_without_model_generation`, `embedding.model_migration_without_dedupe_recheck_plan`, `bitemporal.assertion_missing_valid_time`, `bitemporal.assertion_missing_transaction_time`, `bitemporal.evidence_edge_missing_source_span_temporal_snapshot`, `extraction.policy_generation_changed_without_step_0_regate`, `policy.extraction_started_under_obsolete_policy_generation`.
- **§9 Health:** `member.missing_health_counters`, `health.unregistered_signal`, `health.budgeted_counter_without_quota_bound`.
- **§10 Quota:** `quota.topic_future_watch_unbounded`, `quota.review_queue_unbounded`, `quota.source_revocation_fanout_unbounded`, `quota.membership_restamp_unbounded`, `quota.learning_replay_unbounded`, `compute_budget.member_cost_undeclared`.
- **§11 Recovery:** `recovery.derived_artifact_without_rebuild_source`, `recovery.proof_artifact_missing_canonical_ref`, `recovery.membership_edge_without_replay_source`, `recovery.learning_signal_without_replay_or_audit_source`, `recovery.replay_completeness_invariant_violated`.
- **§12 Invariants/monotonicity:** `revocation.recent_activity_used_as_evidence`, `membership.removed_or_blocked_edge_used_for_injection`, `dams.eligibility_ceiling_violation`, `assertion.overlapping_resolution_disposition_enum`, `legal_hold.destructive_job_skipped_check`, `monotonicity.membership_raised_warrant`, `monotonicity.policy_widened_without_restamp`, `monotonicity.revocation_raised_eligibility`, `monotonicity.learning_upgraded_warrant_without_evidence`, `injection_eligibility.non_total_function`.
- **§13 ABC §21:** `abc21.normalization_object_unslotted`.
- **§1.6 / §3 / §22 new tokens (v2 + R3, all `[proposed]` unless tagged):** `runtime_vocab.*`, `registry.candidate_entry_emitted_at_runtime`, `durable_record.missing_e0_durable_base`; `registry.context_product_owner_guessed`; `determinism.learned_weight_not_named_input`, `determinism.degradation_or_reasoncode_registry_version_not_named_input`; `erasure.*` (incl. `redaction_under_legal_hold_without_clearance`), `restamp.*`, `restore.*` (incl. `reintroduces_revoked_or_held_material`, `of_hard_destruction`), `destruction_ledger.entry_missing_for_erasure_restamp_restore`, `destruction_ledger.hash_chain_broken`; `mfc.effective_state_generation_missing`, `mfc.uses_executor_field_instead_of_initiating_member`, `ec.delivery_attestation_on_serialized_write_path`, `ec.flow_issued_while_subsystem_disabled`; `collection.suppressed_topic_admitted`, `portability.cross_principal_bleed`; `prompt_shell.exposure_boolean_without_final_prompt_truth_ref`, `debug_mode.flow_without_non_learning_guarantee`; the `*.negative_outcome_without_reason_code` family; and the full `egress.*` set (§22, UR-51).

Representative E0 **fixtures** (Stage 8): the proof-spine round-trip (`fixture.proof.no_durable_effect_without_proof`), the conservative-fallback fixture (`fixture.domain_profile.unknown_profile_falls_back_conservative`), the **17-kind registry fixture** (`fixture.context_product.registry_has_exactly_17_kinds`), the replay fixture (`fixture.recovery.durable_object_replayable_from_envelope`), the erasure/restore fixture (`fixture.golden.restore_of_hard_destruction_fails`), the collection-suppression fixture (`fixture.collection_suppression.suppressed_topic_admitted_fails`), the egress fixtures (§22, UR-52), and the per-contract fixtures named in each section above. The **end-to-end round-trip golden scenario** (§18; F-struct #2) is the family-level integration fixture E0 anchors but §18 (and the member charters) populate.

### §16.4 BETTER_IDEA annex (non-blocking; deferred)

Recorded so they are not lost (R2 §J): **UR-42** tamper-evident hash-chained proof log — *partly promoted* to the §3.7 destruction ledger; the broader as-of/verifiable layer remains deferred. **UR-43** "as-of" time-travel queries. **UR-44** click-to-provenance verifiable-memory Inspector (DOC86/E10). **UR-45** scoped/redacted co-counsel export (`ExportMFC` + per-axis redaction + the `disclosure_scope_attestation_ref` / `E0EgressAttestation`, §22). All DEFER; pickup triggers in §17.4.

---

## §17. Sources + lineage

### §17.1 ADQ landings table (every ADQ pinned to E0 → its section)

| ADQ | resolution (abbrev.) | landing section |
|---|---|---|
| **ADQ-203** | ContextProduct contract in DOC80 core; DOC24 assembles | §3.1 |
| **ADQ-208** | PromptShellVariant cross-cutting in DOC80 core; DOC24/KDA/BDSM consume | §2.3 |
| **ADQ-210** | Family name "Memory Control Plane (DOC80 family)"; DAMS = substrate in DOC84 | §1.2 |
| **ADQ-211** | MemoryContextPlan contract in DOC80 core; DOC24 assembles | §3.2 |
| **ADQ-310** | DOC80 core owns canonical ReasonCode registry + namespace rules | §2.1 |
| **ADQ-313** | Central domain-profile registry; missing → conservative fallback | §2.2 |
| **ADQ-403** (AC-004) | Memory Intake & At-Use Disciplines; `schema_plus_lints_and_fixtures`; DOC80+DOC25+DOC73 | §14.1 |
| **ADQ-404** (AC-005) | EC Core Addendum A intake-routing; depends ADQ-202; EC Core + DOC80 | §14.2 |

Cross-cutting ADQs cited (pinned elsewhere, but load-bearing for E0 contracts): **ADQ-207** (MemoryFlowCertificate mandatory) → §3.3; **ADQ-209** (three-plan model) → §3.2 + §3.4; **ADQ-305** (header stability) → §8.3 + §4.2; **ADQ-312** (warrant-degradation triggers) → §2.4; **ADQ-316** (restamp ceilings) → §12; **ADQ-202** (Corpus hierarchy, E4) → §14.2; **ADQ-220** (8th member DOC87) → §1.1; **ADQ-221** (BDSM partial / DOC8 phantom) → §7.2–§7.3; **ADQ-405** (RecentActivityRollup `can_orient_only`) → §6 + §12; **ADQ-222** (V5 networking, open) → §1.3 + §16.2.

### §17.2 Skeletal §10/§11 fold-in landings table

| Skeletal § | content | landing section |
|---|---|---|
| §10.1 | V5 non-goal | §1.3 |
| §10.2 | EC manual deletion / unreachable=uninjectable | §1.4 |
| §10.5 | `MemoryMutationEnvelope` NAMED | §5.1 |
| §10.6 | `MemoryProvenanceGraph` NAMED | §5.2 |
| §10.7 | DOC82↔DOC83 disposition/resolution seam (UR-39 correction — was mislabeled "→ §4") | §12.1 (ABC §7.8 anti-overlap invariant: disposition stays DOC83, resolution authority DOC82) + §3.1.1 (`ContextProductDecision`) |
| §10.9 | `ECSeamContract` (OPA-031) | §7.1 |
| §10.12 | Memory-object classification table | §6 |
| §10.13 | `ResumeProjection`/`ResumeCard` rename | §5.3 |
| §10.14 | Embedding-model-migration refs | §8.1 |
| §10.15 | Observability / health seam | §9 |
| §10.16 | `MemoryOperationQuota` + scale | §10 |
| §10.17 | ABC §21 normalization-object placement check | §13 |
| §11.1 | Recovery / replay seam | §11 |
| §11.2 | Consistency / concurrency / ordering model | §1.5 |
| §11.3 | EpisodePolicyEpoch extraction-side re-gate | §8.3 |
| §11.4 | Invariant enforcement-point naming | §12 |
| §11.8 | Bitemporal axes (carrier = MemoryMutationEnvelope) | §8.2 |
| §11.9 | Monotonicity / algebraic invariants | §12 |
| §4 (baseline) | Shared runtime vocabularies (B10) — **restored** (UR-38) | §1.6 |
| §18 (baseline) | Golden scenario — **restored** (UR-35) | §18 |
| §19 (baseline) | Per-external-doc amendment-magnitude — **restored** (UR-38) | §19 |
| §20 (baseline) | Per-member obligations tables — **restored** (UR-38) | §20 |

**Count reconciliation:** the Input Deck headline says "14 Skeletal §10/§11 fold-ins"; the Input Deck table itself enumerates **17** rows (12 §10 + 5 §11 — its §11 list is {11.1, 11.2, 11.4, 11.8, 11.9}). **All 17 enumerated fold-ins land above.** This table additionally lands **§11.3** (extraction-side EpisodePolicyEpoch re-gate → §8.3), a Skeletal fold-in beyond the Input Deck's §11 list — so the table holds **18 rows (12 §10 + 6 §11)**: the 17 enumerated plus the §11.3 bonus. Nothing is dropped; the "14" headline is the count of distinct fold-in *topics*, which the 17 enumerated rows (and §11.3) supersede. (Flagged so the discharge sweep does not read a missing-fold-in where there is none.)

### §17.3 Owner Map row references

Key Owner Map rows this charter binds to (cite line numbers per Commission §2.2): **line 80** `EffectiveMemoryPolicy` (wholly DOC81; core holds consumption-protocol ref only) → §3.2; **line 86** `ReasonCode` (DOC80 core; producers namespaced) → §2.1; **lines 125–126** `ContextProduct` registry/assembly split → §3.1; **lines 127–128** `MemoryContextPlan` contract/implementation split → §3.2; **lines 144–146** `PromptShellRegistry`/`PromptShellVariant`/`PromptShellLearningContract` → §2.3; **lines 147–148** `RenderSafetyProof` contract/execution split → §4.2; **line 149** `ContextPacketProof` → §4.1; **line 150** `MemoryFlowCertificate` → §3.3; **line 171** warrant-degradation-trigger registry (core; producers DOC85) → §2.4; **line 204** `MemoryCoordinationTrace` → §3.4; **lines 198–209** DOC80 core registries/contracts summary → §2–§4; **line 238** EC `partial/moving` → §7.1; **line 209** `SemanticProjectionContract` umbrella → §6/§8 (projection invariants). Supersession Matrix rows: **SM-050** (MemoryFlowCertificate) → §3.3; **SM-051** (ContextPacketProof + RenderSafetyProof) → §4; **SM-060** (ContextProduct registry — "14" superseded by ABC §9.2's **17**, UR-01) → §3.1; **SM-100** (MemoryCoordinationTrace) → §3.4; **SM-203** (PromptShellVariant family) → §2.3; **SM-213** (ReasonCode registry) → §2.1.

**Retired-name compliance (DOC80_Retired_Names.md):** this draft uses canonical names only — `AlternativeExtractionRouting` (not `NonAssertionExtractionOutcome`), `SourceBoundSynthesisAdapter` (not `SourceBoundSynthesisProjection`), `ResumeProjection`/`ResumeCard` (not `CognitiveDiff` as canonical), `AssertionCandidateDisposition` (7-value ABC §7.8), and DAMS as a substrate inside DOC84 (not a truth owner). No retired name is introduced outside an explicit lineage citation. The **14 invented `ContextProductKind` names** (the prior `assertion_pack` / `orientation_rollup` / `resume_card` / `inspector_explanation` / `search_affordance_result` etc.) are removed from the draft and logged for Retired Names as do-not-reintroduce (discharge, §8-discharge below).

### §17.4 Preservation matrix (UR-36)

Assurance that every Stage-5R/5R2/5R2b decision either **lands**, **defers** (with a pickup trigger), or **exits** (consumed/decided) — nothing silently lost.

| decision / item | disposition | where | note |
|---|---|---|---|
| UR-01 ContextProduct **17**-kind registry | lands | §3.1 / §3.1.1 | ABC §9.2 senior; SM-060 "14"→"17" is a discharge edit |
| UR-02 `FinalPromptTruthRef` | lands (NAMED) / body defers | §3.5 → Stage 7 (DOC11) | learning/utility gate |
| UR-03/04 MFC discriminated union (9 flows) | lands | §3.3 | + litigation proof layer (certificate shells) |
| UR-05 edge-level membership proof | lands | §4.1 | replaces boolean |
| UR-07 proof retention classes | lands | §4.4 | erasure/restamp/restore = durable_audit |
| UR-08/09 5-plane cascade + polarity | lands | §12.1 `SourceRevocationCascade` | **N3: 5 planes, no 6th, no promotion invariant; clawbacks manual** |
| UR-31 `SemanticProjectionContract` | lands | §3.6 | umbrella + 4 axis registrations |
| UR-35 §18 golden scenario | lands (skeleton) / bodies defer | §18 → Stage 8 | family-level integration fixture |
| UR-38 restored §4/§19/§20 | lands | §1.6 / §19 / §20 | + §17 acceptance standard (§15.6) |
| UR-46 named-lint inventory | lands | §16.3 | split (a)/(b)/(c) by owner |
| UR-37 DOC25 ReasonCode grounding (scoped) | lands (rule) / Owner Map row defers | §2.1 → discharge | scoped to parse/materialization/ingestion; revocation codes → DOC82 |
| Destruction ledger | lands (NAMED) / body defers | §3.7 → EC write path + DOC84/85/11 | R3 §(b)#1 EC-owned |
| ADQ-406 / ADQ-407 / ADQ-408 | resolved + committed | §12.1 / §7.1 + OPA §6.Z | collection suppression / recycle bin / restore-from-backup |
| **ADQ-209 (three-plan), ADQ-207 (MFC mandatory), ADQ-312 (warrant triggers)** | **consumed-not-resolved (A2)** | §3.2/§3.4, §3.3, §2.4 | E0 *honors* these (does not re-decide them); resolution authority recorded, not re-opened |
| bitemporal axes (§11.8) / monotonicity laws (§11.9) | lands | §8.2 / §12.1 | linkable-not-collapsed; supported-assertion scope (Finding 2) |
| Stage-5R2b renames | preserved | §17.3 | canonical names only; old names → Retired Names lineage |
| BETTER_IDEA UR-42/43/44/45 | defers (UR-42 partly promoted) | §16.4 | forward capability |
| ADQ-222 V5 Phase-1 networking | defers | §1.3 + ADQ ledger | does not block Stage 6 |
| `MemoryMutationEnvelope` field body | defers | §5.1 → Stage 7 + §15.4 | NAMED-only now; field body later |
| `MemoryProvenanceGraph` field body | defers | §5.2 → Stage 7 + §15.4 | durable lineage graph body later |
| `ResumeProjection` / `ResumeCard` body | defers | §5.3 → DOC84/DOC86 + §15.4 | canonical names land; body later |
| DOC81 policy-axis enum values | defers | §2.2 → DOC81 + §15.4 | DOC81 owns axis semantics |
| DOC84 `RenderSafetyProof` executed body | defers | §4.2 → DOC84 + §15.4 | E0 owns contract only |
| Lint / fixture / migration meta-schemas | defers | §8.5 / §16.3 → Stage 7/8/9 + §15.4 | UR-28 rejected from E0, not lost |
| §20 per-member obligation instances | defers | §20 → each member + §15.4 | member charters fill instances |
| Seven ABC §21 Owner Map rows | defers | §13.2 → E3/E4/E7-E8 + §15.4 | E0 assigns landing; owner charters add rows |
| AC-004 / AC-005 completion | defers | §14 → future completion + §15.4 | completion criteria preserved |
| `WarrantConsequenceRegistry` core-registry alternative | architect review | §16.1 item 2 + §15.4 | placement must be confirmed, not silently resolved |

**No deferral is lost:** every "defers" row has a §16.2 register entry **and** a §15.4 gate row (§15.5(d) enforces).

---

## §18. Golden scenario (UR-35) — restored

**Source:** UR-35 (ACCEPT · BUG · high — restore the dropped end-to-end scenario); Skeletal §18 / F-struct #2. **Owner:** E0 owns the **skeleton** (the phase order + fixture taxonomy); **Stage 8 owns the fixture bodies**; the member charters populate their phase.

**15-step phase order** (the canonical end-to-end memory round-trip):

1. request / observation → 2. policy preflight (DOC81) → 3. extraction admission (DOC83; ABC §7.7 Step 0) → 4. source materialization (DOC25) → 5. candidate emission (`AssertionCandidateEmission`, DOC83→DOC82) → 6. canonical resolution (DOC82) → 7. membership assignment (DOC87) → 8. policy re-check (re-gate on `policy_generation_id` change) → 9. context-product planning (`MemoryContextPlan`, §3.2) → 10. packet assembly (DOC24) → 11. rendering (DOC84/KDA) → 11.5 egress gate (§22; `E0EgressAttestation` for any non-`same_machine_local_runtime` render / export / delegation) → 12. final-prompt proof (`FinalPromptTruthRef`, §3.5; DOC11) → 13. learning eligibility (DOC85; proof-gated) → 14. UI / Inspector (DOC86; trace-backed) → 15. replay / audit (§11; `MemoryMutationEnvelope` replay).

**Fixture taxonomy:** `contract_fixture`, `negative_contract_fixture`, `cross_charter_integration_fixture`, `policy_change_fixture`, `source_revocation_fixture`, `replay_fixture`, `migration_fixture`, `final_prompt_truth_fixture`, `learning_attribution_fixture`, `golden_scenario_fixture`, `erasure_restore_fixture`, `collection_suppression_fixture`, `egress_fixture`.

**Negative-fixture names (Stage 8 bodies):** `fixture.golden.learning_credit_without_final_prompt_truth_fails`; `fixture.golden.revoked_source_invalidates_support_membership_delivery_learning_ui`; `fixture.golden.removed_membership_cannot_inject`; `fixture.golden.non_ec_write_detected`; `fixture.golden.context_product_kind_unknown_blocks_assembly`; `fixture.golden.learned_weight_missing_from_deterministic_input_fails`; `fixture.golden.policy_tighten_between_plan_and_render_blocks_or_restamps`; `fixture.golden.hard_destruction_without_legal_hold_clearance_fails`; `fixture.golden.collection_suppressed_topic_admitted_fails`; `fixture.golden.restore_without_certificate_fails`; `fixture.golden.privileged_render_to_cloud_without_egress_attestation_fails`.

**Cross-charter consumption.** Every member owns its phase; the golden scenario is the family-level integration fixture that proves the phases compose end-to-end. **Lint:** `golden_scenario.phase_order_violated` [proposed].

---

## §19. Per-external-doc amendment-magnitude assessment (UR-38) — restored

**Source:** UR-38 / Skeletal §19 / F-struct #3. One-line amendment magnitude per §7.4 external dependency, derived from `dependency_status`:

- **EC** = major (moving — the seam is in motion; ECSeamContract pins, §7.1)
- **BDSM** = moderate (partial, ADQ-221; two-phase at E9)
- **DOC73** = minor–moderate (partial; CU reconciliation per ADQ-219)
- **DOC8** = none (phantom, ADQ-221 — capability-mining only)
- **DOC26** = conditional (aspirational, ADQ-202/404)
- **DOC72 / DOC25 / DOC24 / KDA / DOC11 / DOC15 / DOC20 / DOC23 / DOC1 / DOC3 / PropA** = minor (stable)

**Lint:** `external_dependency.amendment_magnitude_missing` [proposed]. **Cross-charter:** each external-doc amendment is sized here; the actual amendment lands at the consuming member's charter (discharge).

---

## §20. Per-member obligations tables (UR-38) — restored

**Source:** UR-38 / Skeletal §20 / F-struct #4. Each member declares (a) its `MemoryCoordinationTrace` obligations and (b) the degraded/blocked states it must handle (seed; per-member instances completed at each member's charter):

| member | (a) MemoryCoordinationTrace obligations | (b) degraded / blocked states it must handle |
|---|---|---|
| DOC81 | policy/scope decision refs + `policy_generation_id` | `policy_disambiguation_pending`; `scope_unresolved` → conservative |
| DOC82 | assertion / evidence / resolution refs | `contested_assertion`; revocation recompute |
| DOC83 | extraction-plan + candidate refs | extraction re-gate on `policy_generation` change |
| DOC84 | packet / manifest / proof refs (+ destruction-ledger surface) | `proof_artifact_missing`; `membership_unavailable`; `degraded_mode` |
| DOC85 | `learning_signal` + `final_prompt_truth` refs | learning withheld (no proof / no final-prompt truth) |
| DOC86 | Inspector read-model refs backed by trace | read-model stale/failed; safe-label on blocked content |
| DOC87 | `membership_mutation` refs | membership removed/blocked → suppressed |

**Lints:** `member.coordination_trace_obligation_undeclared`; `member.degraded_states_undeclared`. **(Per-member instances completed at E1–E10 / E_org — see §15.4 gate table.)**

---

## §22. Egress enforcement binding (R3 §(a) — replaces R2 §22)

*(Numbering note: the baseline's §21 retired-names pointer lands at §17.3 in this draft; this section keeps its card/review identity as **§22**. **Value-tier: Critical ratification blocker** — "must-fold-first": E0 does not ratify until §22-with-fixes is folded; folding the NAMED binding is the unblock — enforcement bodies are downstream cross-doc obligations (§22 UR-53), so this does not stall the build and does not reopen DOC80 architecture.)*

**Audit result (one line).** The egress *model* exists and is strong (PropA P1 privilege classifier; PropA §2 outbound taxonomy; fail-closed default), but **no lint binds every send-site to a destination-correct policy decision**, and DOC24 §21.1 `SharedActionHandlerLayer` (validate → idempotency → receipt → emit) has **no policy-decision gate step**. UR-49 makes the PropA "every outbound boundary runs through the policy engine" rule mechanically provable.

**Grounding (verified against the cited sources — do NOT re-spec):** PropA P1 privilege classifier; PropA §2 destination enum (`same_machine_local_runtime | local_file_export | local_network_peer | firm_server | remote_peer | cloud_api | email_outbound | agent_messaging`); PropA `SharingActionSchema` = `allow|warn|block|strip|redact`; PropA fail-closed (`provisional_source_only | unclassified | deferred_unavailable | quarantined_review` SHALL fail closed for all outbound except same-machine); KDA §3.2C `enforceKdaRenderPolicy` (render-only); EC §8.1; DOC24 §21.1.

> **INV-E0-EGRESS-1 (DOC80-owned).** No outbound action may cross an egress boundary without an attached, destination-correct `E0EgressAttestation`. The egress gate (EC/DOC24 `SharedActionHandlerLayer`) resolves the **actual terminal destination** before dispatch; any destination that is (a) not `same_machine_local_runtime` and (b) **either** not a recognized PropA §2 destination **or** lacks a resolved `policy_decision` whose destination class equals the actual terminal destination and whose outcome permits or constrains the payload → **fail closed**. Unrecognized destination, unresolved terminal destination, stale policy generation, destination mismatch, permissive-by-omission, or dispatched bytes ≠ `dispatched_payload_hash` → fail closed. `same_machine_local_runtime` is no-lookup only for execution that stays on the machine and invokes no outbound tool; any terminal outbound tool call creates a new egress action and must be attested. Generalizes the MFC N8 export-boundary disclosure re-evaluation to **all** outbound destinations. *(CR2 default-deny is a **gate rule, pre-attestation**: a destination that does not resolve to one of PropA's eight cannot be typed into the attestation and is blocked before any attestation is issued.)*

**UR-50 — `E0EgressAttestation` (schema_owner DOC80; enforcement bodies cross-doc).** Trimmed discriminated union; vocabularies reference PropA, not redeclared.

```typescript
export type E0OutboundDestinationClass =
  | "same_machine_local_runtime" | "local_file_export" | "local_network_peer"
  | "firm_server" | "remote_peer" | "cloud_api" | "email_outbound" | "agent_messaging"; // == PropA §2

export type E0EgressDecisionOutcome = "allow" | "warn" | "block" | "strip" | "redact";   // == PropA SharingActionSchema; "scope" intentionally NOT a value

export type E0EgressActionKind =
  | "render_to_model" | "raw_artifact_export" | "connector_send"
  | "agent_message" | "channel_projection" | "cloud_api_call" | "network_transfer";

export type E0InteractionMode = "interactive" | "background_non_interactive" | "scheduled" | "agent_initiated";

type E0EgressAttestationBase = {
  schema_version: 1;
  attestation_id: string;
  created_at: string;                                 // RFC3339 UTC
  action_envelope_ref: string;
  action_kind: E0EgressActionKind;
  outbound_destination_class: E0OutboundDestinationClass;
  declared_destination_ref: string;
  actual_terminal_destination_ref: string;            // resolved after connector/adapter/channel; dereferenceable to terminal identity sufficient for policy replay
  decision_outcome: E0EgressDecisionOutcome;
  interaction_mode: E0InteractionMode;
  attempted_payload_hash: string;                     // payload submitted to the gate BEFORE the outcome is applied; required for EVERY attempted egress, incl. block (B1)
  dispatched_payload_hash?: string;                   // actual dispatched bytes AFTER strip/redact; required iff decision_outcome ∈ {allow,warn,strip,redact}; FORBIDDEN iff decision_outcome === 'block' (B1)
  payload_privilege_classes: PrivilegeClassPropA[];   // PropA P1 — referenced, not redeclared
  receipt_ref: string;                                // required for ALL non-same-machine egress, including "allow"
  memory_coordination_trace_ref: string;
  memory_flow_certificate_id?: string;                // link to Render/Export/DelegationMFC chain
  disclosure_reevaluated_at_boundary: true;           // the N8 attestation, generalized — verifiable via policy_generation_id
  redaction_map_ref?: string;                         // required iff decision_outcome === "redact"; reconciles attempted_payload_hash → dispatched_payload_hash
};

type SameMachineEgressAttestation = E0EgressAttestationBase & {
  outbound_destination_class: "same_machine_local_runtime";
  policy_lookup_required: false;
  policy_decision_id?: never;
  decision_outcome: "allow" | "block";                // S1: same-machine no-lookup; warn/strip/redact require the policy-bound branch
};

type PolicyBoundEgressAttestation = E0EgressAttestationBase & {
  outbound_destination_class: Exclude<E0OutboundDestinationClass, "same_machine_local_runtime">;
  policy_lookup_required: true;
  policy_decision_id: string;
  policy_decision_destination: E0OutboundDestinationClass;  // MUST === outbound_destination_class
  policy_generation_id: string;                              // required — boundary-freshness proof
  policy_evaluator_hash?: string;                            // optional pending EC §8 confirmation; compiled_policy_ref deferred to EC
};

export type E0EgressAttestation = SameMachineEgressAttestation | PolicyBoundEgressAttestation;
```

**Egress attestation invariants (B1 / S-1 / S1).** (a) **Attempted vs dispatched (B1).** Every attempted egress — *including* a `block` — carries `attempted_payload_hash`; only non-block outcomes carry `dispatched_payload_hash` (the post-transform bytes the gate signs). If the bytes presented to the terminal adapter differ from `dispatched_payload_hash`, dispatch fails closed and a new attestation is required. A `block` has no dispatched bytes: it records `attempted_payload_hash` + the blocking `receipt_ref`. (b) **MFC link (S-1).** If an outbound action is also an MFC-covered privileged flow, the `E0EgressAttestation` MUST carry the covering `memory_flow_certificate_id` **and** the covering MFC MUST carry the reciprocal `disclosure_scope_attestation_ref` (mutual traceability): `render_to_model` → `RenderMFC`; `raw_artifact_export` of memory/source-derived content → `ExportMFC`; `agent_message` / `connector_send` / `network_transfer` of memory/source-derived content → `DelegationMFC` or `ExportMFC`. The attestation is the egress-policy proof; the MFC is the memory-flow proof. (c) **Same-machine (S1).** `same_machine_local_runtime` is no-lookup and may only be `allow` or `block`; `warn` / `strip` / `redact` are policy-decision outcomes that require the policy-bound branch.

**Convergence ledger — one record, two facets (EC-signed, DOC24-appended).** Same primitive the egress binding and the learning feature both need — but two facets, not one column; a delivery/audit (`anchored_attestation`) object, **NOT** a mutation: EC-signed against a read-consistent generation and **DOC24-appended off the write-queue** (do not route through EC's `serialized_durable` path — per the §3.3 "delivery attestations MUST NOT take a write-queue lock" invariant; contrast the §3.7 destruction ledger, which IS `serialized_durable` / EC-written).

```typescript
// schema_owner: DOC80. EC-signed (issued_by:'EC', read-consistent generation), DOC24-appended OFF the write-queue
// (anchored_attestation; NOT serialized_durable). Consumed by DOC84/DOC85. One record, two facets — not one column.
export type SourceDeliveryDisposition =
  "delivered" | "truncated" | "dropped" | "suppressed" | "redacted" | "stripped" | "blocked";

export type E0PerSourceTurnLedgerRow = {
  schema_version: 1;
  row_id: string;
  trace_ref: string;            // -> MemoryCoordinationTrace (correlates serialized_durable + anchored_attestation records)
  turn_id: string;
  source_ref: string;
  context_product_instance_ref?: string;
  prompt_span_ref?: string;
  final_prompt_disposition?: SourceDeliveryDisposition;   // facet 1 -> learning attribution feeds LearningAttributionMFC (serialized_durable, downstream/off hot path)
  final_prompt_truth_ref?: string;
  egress_disposition?: SourceDeliveryDisposition;         // facet 2 -> egress boundary
  egress_attestation_ref?: string;
  outbound_destination_class?: E0OutboundDestinationClass;
  actual_terminal_destination_ref?: string;
  reason_codes: string[];
  issued_by: "EC";              // EC-signed
  created_at: string;
};
```

**UR-51 — lints** (canonical = inherited from Flatten §17.4; rest `[proposed]`, Stage-9 confirm):

```text
[canonical] policy.bare_render_action
[canonical] policy.export_stamp_without_destination
[proposed]  egress.outbound_action_without_egress_attestation            # umbrella
[proposed]  egress.outbound_action_without_destination_policy_decision
[proposed]  egress.destination_mismatch_between_action_and_policy
[proposed]  egress.unrecognized_destination_not_failed_closed            # CR2
[proposed]  egress.terminal_destination_unresolved_before_dispatch
[proposed]  egress.policy_generation_missing
[proposed]  egress.redaction_without_redaction_map
[proposed]  egress.enforced_outcome_without_receipt                      # subsumes strip/redact/allow-to-external receipt checks
[proposed]  egress.warn_background_not_coerced_to_block
[proposed]  egress.dispatched_payload_differs_from_attested_hash         # TOCTOU; applies only when decision_outcome ∈ {allow,warn,strip,redact} (B1)
[proposed]  egress.fanout_attestation_count_mismatch                     # multi-destination
[proposed]  egress.destination_class_enum_drift_from_propa               # don't redeclare PropA §2
[proposed]  egress.same_machine_runtime_invoked_outbound_tool_without_attestation
[proposed]  egress.mfc_covered_action_missing_mfc_ref                     # S-1: MFC-covered outbound lacks memory_flow_certificate_id
[proposed]  proof.non_same_machine_render_without_disclosure_scope_attestation_ref   # S-1: RenderMFC to a non-local destination lacks the egress-attestation ref
[proposed]  egress.same_machine_outcome_warn_strip_redact_without_policy_lookup       # S1
```

**UR-52 — golden fixtures** (`gate_level: final_switchover`; negative/invariant cases first):

```text
egress.destination_mismatch_fails_closed                              # the core INV check
egress.unrecognized_destination_fails_closed                          # CR2
egress.unclassified_source_fails_closed_except_same_machine           # PropA fail-closed
egress.same_machine_allows_without_lookup
egress.same_machine_runtime_invoked_outbound_tool_requires_new_attestation
egress.allow_to_external_emits_receipt
egress.dispatched_payload_differs_from_attested_hash_fails_closed     # TOCTOU
egress.fanout_per_destination_decisions                               # privileged email: internal=allow, external=block
egress.privileged_to_email_outbound_blocks
egress.privileged_to_agent_messaging_blocks
egress.sensitive_to_cloud_api_redacts
egress.raw_artifact_export_to_non_local_blocks_or_redacts
egress.local_file_export_privileged_requires_policy_decision
egress.local_network_peer_privileged_blocks
egress.firm_server_client_confidential_warns
egress.remote_peer_privileged_blocks
egress.channel_projection_applies_policy
egress.warn_background_non_interactive_coerces_to_block
egress.render_to_model_requires_render_mfc_link                       # S-1
egress.privileged_render_to_cloud_without_egress_attestation_fails    # S-1
egress.same_machine_render_requires_no_egress_attestation             # S1/D-2: a local render is not egress
egress.block_outcome_records_attempted_not_dispatched_hash           # B1
```

**UR-53 — cross-doc / OPA implications (discharge like §8 — NOT edited from this draft; recorded in OPA §6.Z3):**

- **EC / DOC24 §21.1:** ADD the policy-decision gate step — validate → resolve terminal destination → destination policy decision → egress attestation → execute.
- **DOC24:** emit the per-turn per-source ledger (final_prompt + egress facets), EC-signed / DOC24-appended off the write-queue (`anchored_attestation`; NOT EC durable-write). Owner split: appender DOC24 / signer EC / consumers DOC84–DOC85.
- **KDA / DOC84:** `enforceKdaRenderPolicy` is the render-safety / sharing-action policy layer for rendered content — *in addition to*, not a substitute for, the egress-attestation gate. A render to any non-`same_machine_local_runtime` destination is **additionally** subject to INV-E0-EGRESS-1 at the EC/DOC24 gate (which produces the destination-correct `E0EgressAttestation`). KDA is NOT the universal gate for raw artifact export, connector send, or DOC12 channel projection — those use the EC/DOC24 gate.
- **PropA:** bind §2 outbound matrix mechanically; **PATCH §2.6 principle #2 to include `local_file_export`**, or reword as "all destinations except `same_machine_local_runtime` are outbound." **[NEW cross-doc item]**
- **DOC11 / OpenClaw:** EXTEND `OBL-D11/OPENCLAW-NEW-FINAL-PROMPT-SPAN-01` for as-sent capture; ADD separate egress-gate obligations for native/connector dispatch outside final-prompt render.
- **DOC12:** channel projection applies egress policy before dispatch.
- **DOC16 / connectors / DOC4:** provider/native outbound adapters expose terminal destination before dispatch; MUST NOT bypass the gate.
- **DOC23:** outbound task modules call the EC/DOC24 egress gate before provider execution.
- **DOC20 / DOC21 / DOC22:** egress policy-decision receipts (allow/warn/block/strip/redact) visible on send/export/share surfaces; register new UI.
- **DOC84 / DOC85:** consume the source ledger for learning attribution (`LearningAttributionMFC` = `serialized_durable`, downstream/off hot path).
- **PHASE-2 FLIP (named gate row, ADQ-222):** `remote_peer` / `firm_server` / `local_network_peer` flip fail-closed → gated-allow when networking ships; anchor for the local↔networked memory boundary.

**Tracking.** UR-49/50/51/52 = active DOC80 §22 additions (Critical tier; folded above). UR-53 = OPA obligations (OPA §6.Z3, discharge). **Two genuinely-new cross-doc items: the PropA `local_file_export` patch and the EC-owned destruction ledger.** The empirical piece (do connector / DOC11 / DOC12 dispatch actually call the gate at runtime) is a Claude Code probe, enrollable in §16.2 + §15.4.

---

*End of DOC80 — Memory Control Plane Core (Stage 6 E0 Charter Draft — R2+R3 patch applied, ratification pending).*