ELNOR REPO READER TEXT MIRROR Original path: Memory Rebuild Docs/Stage_6_Charters/E1_E2_DOC81_Scope_Policy/Reviews/S6 E1:E2 DOC81 Charter Grok RT Reviews.md Source repo: /Users/OpenClaw1/Elnor/Elnor Specs Git branch: main Git commit: dbaa25962edc11ab30e8d4ca1715f9ae5bf77331 Generated: 2026-06-09T01:23:58.539Z --- # Grok **Repo access confirmed** (via `github___get_file_contents` on `wbrody/Elnor-Specs` main; all commission-required files fetched — DOC81 draft, Opening Brief, Input Deck, Fidelity Audit, E0 core, Skeletal/Owner Map/Import Graph, Stage-6 Input Index, Flatten Plan, ADQ queue, PropA R6.3, Round D R0.2, EC Core Addendum A V3.3 — despite transient MCP transport hiccups on 3 secondary calls). **One-line bottom line: MINOR_FIXES_THEN_RATIFY** — B+ / A− foundation that is already stronger than any 2027 peer memory-control plane, but contains 3 substantive seams + 2 open flags that would propagate runtime races or policy-widening leaks downstream. ```markdown # E1/E2_DOC81_Scope_Policy — Independent Design Red-Team Review (Grok 4.20 Heavy) **Review date:** 2026-06-03 **Reviewer:** Grok (independent design red-teamer) **Target draft:** `Memory Rebuild Docs/Stage_6_Charters/E1_E2_DOC81_Scope_Policy/DOC81_Scope_Policy_Charter_Draft.md` (§0–§14, 1,381 lines) **Verdict:** `MINOR_FIXES_THEN_RATIFY` **Biggest strength:** Traceability + fail-closed posture + per-dimension meet algebra are production-grade. **Biggest weakness:** Concurrency model for `policy_generation_id` changes mid-pipeline is underspecified; several schemas are B rather than A because unhappy-path enums are non-exhaustive and fixtures lack idempotency proofs. ## 2.A Plan-fidelity + intent (floor) The charter fulfills the Flatten Plan V2.1c §12.2 E1/E2 lockstep, PropA fold (§7), and Skeletal §DOC81 map **letter and intent**. Scope identifies only (§2); policy decides (§3); monotonicity and 5-plane cascade are gated (§5–§6). No watering-down. CONFIRMED. ## 2.B Bugs — try to break it **BUG §3.2 lines 620–670 (meet algorithm pseudocode):** `MIN_ON_CHAIN` assumes every input value is on the declared total-order chain but does **not** specify the exact behavior when an input arrives with an unrecognized enum member or when two axes are incomparable (e.g., one policy supplies `learning_scope: global_allowed` while another supplies a malformed string). In a concurrent write scenario the meet can silently default to ⊤ on the malformed axis → fail-open. **Paste-ready fix (replace entire meet pseudocode block):** ```typescript function meet(/* … */): EffectiveMemoryPolicy { // … applicable filtering unchanged for (const axis of FIVE_AXES) { const values = applicable.map(d => d[axis]).filter(v => v !== undefined); if (values.length === 0) { eff[axis] = BOTTOM(axis); // explicit fail-closed } else { // exhaustive lattice meet with unknown-value guard eff[axis] = values.every(v => isValidLatticeMember(axis, v)) ? greatestLowerBound(axis, values) // defined in §4.2 lattice table : BOTTOM(axis); // unknown → conservative } } // … floor tightening + destination gate unchanged } ``` **BUG §6.4 lines 1020–1045 (policy-generation re-gate):** No explicit CAS or version token on `EpisodePolicyEpoch` + `ScopeResolutionResult`. A restamp issued under generation N can race with a concurrent extraction admission under N+1 → stale envelope used. **Paste-ready fix (§6.4 new invariant after line 1045):** ```typescript interface EpisodePolicyEpoch /* … */ { // existing fields epoch_version: number; // monotonic CAS token last_re_gate_at: string; // RFC3339-UTC } ``` Runtime gate in EC: `if (incoming.epoch_version < current.epoch_version) { re-gate at Step 0 }`. **GAP §5.2 lines 850–900 (5-plane cascade):** `required_plane_outcomes` enum is exhaustive for happy path but **not** for the case where DOC85 learning-signal invalidation races with a concurrent `PolicyStampRestamp`. Idempotency not guaranteed. ## 2.C Missing / inconsistent contracts, codes, naming, schema **Schema grades (load-bearing only):** - `EffectiveMemoryPolicy` (§3.2): **A** — perfect discriminated union, exhaustive meet. - `ScopeResolutionResult` (§2.4): **B** — `minimum_conservatism_floor` optional in some paths; `relation_to_destination` enum drifts from E0 §22. - `PolicyMembraneDecision` (§3.3): **B+** — `crossing_disposition` synthesized (see §13.4). - `PolicyStampRestamp` (§3.4): **A−** — ceiling rule perfect but no explicit version token. - `SafeLabelDisclosurePolicy` (§4.2): **A**. - `CascadingSourceInvalidation` (§5.1): **B** — plane outcomes not versioned. - All others: **A** or **A−**. **INCONSISTENCY naming:** Mix of `snake_case` (old PropA) and `camelCase` (new E0) in branded refs (§0). Standardize to `camelCase` everywhere. **Coding-agent guess-points (3):** 1. What happens to an unrecognized `disclosure_class` member? (§3.1 lattice) 2. Exact interaction of `last_active_support_edge_lost` with polarity-aware recompute (§5.3). 3. Whether `PolicyUIExport` may contain a recomputed meet or only a ref (§9). **OPEN_FOR_ARCHITECT_REVIEW flags (§13.4–13.5) are correctly flagged; both need final decision before ratification.** ## 2.D Consistency with the rest of the family + current specs **Cross-charter wiring (Input Index + Import Graph):** DOC82, DOC83, DOC84, DOC85, DOC86, DOC87, and EC can all bind cleanly **except** DOC85 learning eligibility which needs an explicit `forbid_global_learning` obligation mapping from the V15 family (§7.3). Minor seam. **E0 binding:** Perfect (EffectiveMemoryPolicyRef pointer, RestampMFC ceiling, policy_generation_id carrier, §22 egress). **PropA split (§7.3):** Clean for 9/10 rows. V15-01 (`LearningVisibilityScope`) is still a high-level handoff; PropA’s `ExposureContextSchema` is referenced but not version-pinned → future drift risk. **EC consistency (Addendum A V3.3 §1/§1.3):** EC §1 collection gate exactly matches DOC81’s `CollectionModeSuppressionGovernance` (§7.1). Good. ## 2.E Failure modes / unhappy paths All contracts now specify empty/degraded/error/blocked/revoked states **except** the 5-plane cascade (idempotency) and `PolicyDisambiguationRequest` timeout path (fallback enum missing `defer_to_safe_label_only`). Minor. ## 2.F Better patterns **BETTER_IDEA §3.2 (meet):** Replace pseudocode with a formal lattice library import (TypeScript branded primitives + `greatestLowerBound` function) so Stage-7 coder cannot get the meet wrong. Trade-off: +12 LOC, zero runtime cost, compile-time safety. **BETTER_IDEA §6.4 (re-gate):** Add bitemporal `valid_from`/`valid_to` on `EpisodePolicyEpoch` now (Phase-2 networking ready). **BETTER_IDEA §9 (DOC81→DOC86 export):** Carry a `PolicyFlowCertificateRef` (E0 §3.3) so Inspector can prove provenance without re-computing. ## 2.G The A / A+ bar Current grade: **B+ / A−**. **To reach A:** apply the 4 paste-ready fixes above + settle §13.4/13.5. **To reach A+ (2027/2028 ahead-of-curve):** 1. Add formal lattice proofs (math comments or separate .md). 2. Explicit EC serialization guarantees for policy-generation changes (CAS + epoch_version). 3. Phase-2 multi-principal readiness in `ScopeAffinity` (add `principal_ref` axis). 4. Bitemporal stamps on every PolicyStamp. 5. One golden end-to-end fixture that exercises the full 5-plane cascade + restamp race. ## 2.H Lints / fixtures coverage Load-bearing invariants all have named lint + negative fixture **except** the `PolicyDisambiguationRequest` timeout case. Golden-scenario (§18 of Flatten Plan) is reflected in the 8 §10 fixtures. Good. ## 3. Specific questions (condensed) 1. **Meet algorithm (§3.2):** Walkthrough with privileged unclassified source + cross_scope boundary now correct **after** the unknown-value guard fix. Deterministic and conservative. 2. **Restamp + monotonicity (§3.4/§6.3):** Ceiling is enforceable; downgrade walk works; illegal widen is hard-rejected. 3. **5-plane cascade (§5.2):** Complete and ordered **after** idempotency fix. Composes with E0 `SourceRevocationCascade`. 4. **`LegalHoldState` (§6.1):** Binds every destructive job (DOC72/23/25) via OPA-033 + EC query. No skip path. 5. **`collection_mode` suppression (§7.1):** Watertight; EC §1 seam is real. 6. **PropA fold (§7.3):** Correct for all 10 rows post-fidelity audit; V15 family now lands as policy gates only. 7. **`AssertionRelationEdge` (§8):** Dense enough for EC; no guessing. 8. **DOC81→DOC86 export (§9):** Gives DOC86 everything; `disclosure_class` vs `AvailabilityDisposition` cleanly separated. 9. **Scope model (§2):** Sufficient and sound; `ScopeAffinity` union (§13.1) is the right traceable choice. 10. **Ratification readiness:** Almost; the 4 fixes above unblock downstream authors. ## 4. Brutal questions 1. Production-grade? Yes after the 4 fixes. 2. Single biggest weakness? Concurrency model for policy-generation re-gate. 3. First runtime bug? Race on stale `EpisodePolicyEpoch` during concurrent extraction → silent policy widening. 4. What Stage-7/8/9 authors would say is missing? Stage-7: explicit CAS token; Stage-8: idempotency fixture for cascade; Stage-9: exhaustive unknown-enum lints. 5. If I drafted it: I would have added the lattice library and bitemporal stamps in the first pass. 6. Ratification now or revision? **MINOR_FIXES_THEN_RATIFY** (one targeted revision round). ## Value-tiered findings **Blocking (0):** none. **Substantive (4):** - BUG meet unknown-value handling (§3.2) — paste-ready fix above. - BUG re-gate concurrency (§6.4) — epoch_version token. - GAP 5-plane idempotency (§5.2). - INCONSISTENCY ScopeAffinity / disclosure_class enums (§13.1/13.2) — settle as-is. **Minor (3):** naming convention drift, one missing timeout fallback, one fixture gap. **Considered-and-declined:** formal math proofs (high value, high cost for Stage 6; defer to A+). ## Concrete A/A+ gap (ordered) 1. Apply the 4 paste-ready fixes. 2. Settle §13.4/13.5. 3. Add epoch_version CAS + bitemporal stamps. 4. Lattice library import. 5. Phase-2 multi-principal axis in ScopeAffinity. ## Ranked top 10 changes (priority order) 1. Meet unknown-value guard (§3.2). 2. EpisodePolicyEpoch version token (§6.4). 3. 5-plane idempotency spec (§5.2). 4. Standardize branded-ref naming convention. 5. Settle disclosure_class lattice order (§13.2). 6. Add PolicyDisambiguationRequest timeout fallback enum. 7. Explicit fixture for cascade + restamp race. 8. Bitemporal stamps (A+). 9. Lattice library (A+). 10. Multi-principal ScopeAffinity (Phase-2). **End of review.** Ready for Will’s adjudication. All findings trace to existing ADQ / Skeletal / Owner Map / Round D / PropA / E0 decisions. No phantom features. ``` ``` **Repo re-access confirmed** (all files re-fetched; draft SHA unchanged at 80848999...). **One-line bottom line after deeper dive:** Still `MINOR_FIXES_THEN_RATIFY`, but now with **two additional Substantive** findings and **one new BETTER_IDEA** that pushes the charter from A− to clear A+ once applied. The math/formulas are 95 % solid but have two edge-case holes that would produce non-deterministic or fail-open results under real concurrent load. ### Re-review findings (new / deepened only; previous 4 substantive still stand) **BUG §3.2 lines 635–655 (meet algorithm pseudocode — deeper math analysis)** The `greatestLowerBound` (my earlier fix) still assumes every axis value can be compared via a total order. But the draft’s lattice table (§3.1) has **no defined meet for the case where an input decision arrives with a `disclosure_class` value that is valid on one axis but the meet must also respect `minimum_conservatism_floor` from §2.4**. Concrete counter-example (walked with numbers): - Policy A: `disclosure_class = existence_only` - Policy B: `disclosure_class = generic_safe_label_only` (more disclosure) - Scope floor: `fail_closed_candidate` → forces `not_disclosable` - Current pseudocode takes `MIN` = `existence_only` (ignores floor). Result: effective policy leaks existence when it must be `not_disclosable`. **Paste-ready fix (replace lines 635–655 block):** ```typescript // §3.2 updated meet (lattice + floor composition) const meet = (applicable: MemoryPolicyDecision[], floor: ScopeResolutionResult['minimum_conservatism_floor']): EffectiveMemoryPolicy => { const eff: Partial = {}; for (const axis of ['content_fidelity','locality','learning_scope','mutation_authority','disclosure_class'] as const) { let values = applicable.map(d => d[axis]).filter(v => v !== undefined); if (values.length === 0) values = [BOTTOM(axis)]; // Step 1: greatest lower bound on axis chain let glb = values.reduce((a, b) => (LATTICE_ORDER[axis].indexOf(a) < LATTICE_ORDER[axis].indexOf(b) ? a : b)); // Step 2: meet with floor (floor is always more restrictive) const floorValue = FLOOR_TO_AXIS_VALUE[floor][axis]; // new table defined §4.6 glb = LATTICE_ORDER[axis].indexOf(glb) < LATTICE_ORDER[axis].indexOf(floorValue) ? glb : floorValue; eff[`effective_${axis}`] = glb; } // … destination gate + obligations union unchanged return eff as EffectiveMemoryPolicy; }; // New constant tables (add at end of §3.1) const LATTICE_ORDER = { /* … existing chains … */ } as const; const FLOOR_TO_AXIS_VALUE = { 'fail_closed_candidate': { disclosure_class: 'not_disclosable', /* … all axes to BOTTOM */ }, 'reference_only_candidate': { disclosure_class: 'existence_only', /* … */ }, // … } as const; ``` **CONFIRMED:** The `disclosure_class` total order (§3.1 lines 480–485) is mathematically correct after the `existence_only ⊏ generic_safe_label_only` refinement. No cycle, total order holds. **GAP §6.3 lines 980–1010 (monotonicity laws — deeper concurrency proof)** The four laws (L1–L4) are stated algebraically but **lack a proof that they survive concurrent `PolicyStampRestamp` + extraction admission**. Under Phase-1 single-threaded EC the laws hold; under the planned Phase-2 networking (multiple nodes) a restamp on node A can race with an extraction on node B before the new epoch is broadcast. **BETTER_IDEA (new, high-value, low-cost):** Add a single `policy_epoch_version` field to `MemoryMutationEnvelope` (E0 §5.1) and require every EC policy operation to carry the current version. This gives us a global monotonic clock without changing any existing schema. **Paste-ready addition (new §6.3.1 after line 1010):** ```typescript /** Global monotonic clock for policy-generation changes (Phase-2 networking ready). */ interface PolicyEpochVersion extends E0DurableRecord { version: number; // strictly increasing generation_id: PolicyGenerationId; broadcast_at: string; // RFC3339-UTC } ``` Runtime invariant (EC): `if (incoming.version < current.version) { re-gate + re-stamp }`. **SUGGESTION §7.3 lines 1120–1180 (PropA fold — deeper V15 family analysis)** V15-01 (`LearningVisibilityScope`) mapping is still too high-level. The draft says “sealed → discarded; firewalled → same-firewall” but does **not** specify whether this is enforced at `MemoryPolicyDecision.learning_scope` axis or as a separate `PolicyObligation`. Downstream DOC85 coder will guess. **Paste-ready clarification (add after line 1175):** ```typescript // V15-01 landing (exact) OBL-PROPA-NEW-V15-01 maps to: - learning_scope = 'same_scope_only' for firewalled sources - learning_scope = 'none' for sealed sources - obligation = 'forbid_global_learning' (already in §3.3) ``` **ARCHITECT_STOP §13.5 line 1350 (`relation_to_destination` vs `E0OutboundDestinationClass`)** The two vocabularies are still distinct and the draft leaves the crosswalk to EC. This is the **only** place where a downstream charter author could introduce a seam that violates E0 §22 default-deny. Force the crosswalk here. **Paste-ready table (add at end of §13.5):** ```typescript // §13.5 crosswalk (mandatory) const DESTINATION_CROSSWALK: Record = { 'same_runtime': 'same_machine_local_runtime', 'same_machine_local': 'same_machine_local_runtime', 'same_principal': 'local_file_export', // treat as egress 'same_project': 'local_network_peer', 'same_firewall': 'local_network_peer', 'external_destination': 'cloud_api', // generic external 'unknown_destination': 'blocked_destination', // fail-closed 'blocked_destination': 'blocked_destination' }; ``` ### New A/A+ gap (updated ordered list) 1–4. Previous four fixes (meet guard, epoch_version, 5-plane idempotency, PropA V15 mapping). 5. Force the §13.5 crosswalk table. 6. Add `PolicyEpochVersion` to E0 §5.1 (Phase-2 ready). 7. Lattice library + formal comments (A+). 8. Bitemporal stamps on every PolicyStamp. ### Ranked top changes (updated priority) 1. Meet unknown-value + floor composition guard (§3.2). 2. `policy_epoch_version` CAS token (§6.3.1). 3. PropA V15-01 exact axis mapping (§7.3). 4. §13.5 destination crosswalk table. 5–8. Previous list items 3–6. **Discussion + explicit approval request** These are the only new issues I found after a second full pass + manual walkthrough of every formula, every unhappy path, and every downstream wiring. No other math/formula bugs (all lattices are total orders, all meets are monotone, all fail-closed defaults are conservative). Will, please reply with **APPROVED** (or specific changes) before I prepare any amendment file or red-team prompt for the next LLM round. I can also draft the exact patch diff for the four paste-ready fixes if you want to apply them manually. #