ELNOR REPO READER TEXT MIRROR Original path: Memory Rebuild Docs/Stage_6_Charters/E1_E2_DOC81_Scope_Policy/Reviews/E1_E2_R3_Delta_Review_GPT_5_5_Pro_RERUN.md Source repo: /Users/OpenClaw1/Elnor/Elnor Specs Git branch: main Git commit: dbaa25962edc11ab30e8d4ca1715f9ae5bf77331 Generated: 2026-06-09T01:23:58.539Z --- # DOC81 (E1/E2) R3 Delta Design Review — GPT-5.5 Pro **Repo access:** CONFIRMED. I read `README.md`, `REPO_FILE_MANIFEST.md`, the R3 delta-review prompt, the R3 target charter, and the R3 application report from `wbrody/Elnor-Specs` branch `main` by exact GitHub paths. **Verdict:** `MINOR_FIXES_THEN_RATIFY`. **One-line bottom line:** R3's unified-state meet pipeline and QF hardening are substantively sound and the four prescribed cases pass, but ratification should wait for three small text/schema cleanups: (1) cache keys must carry `PrincipalScope`, not an optional/buried principal; (2) §4.6.4's inline `same_machine_local → local_file_export` seed conflicts with §13.6 and must be corrected to `normal_policy_check` + attestation; (3) `meet_v2` should define or remove the last pseudocode-only helpers (`domainBaselineDecision`, `priorState`, `rootCeilingItems`, `toPolicyPoint`) so Stage-7 implementation does not guess. --- ## 1. Scope discipline I reviewed only the R3 delta requested by `E1_E2_R3_Delta_Review_Prompt.md`: - §3.0 `PolicyLattice` / `PolicyEffectiveState` - §3.2 `meet_v2` - §3.3 obligations - §3.4 stamp/restamp - §4.6 action-aware floors and `DestinationPolicyCrosswalk` - the QF quantitative pack - residual confirms C1–C4 - meta-test: table consumer / metric formula / hash canonicalization / state transitions / optional-field presence conditions I did not reopen R1/R2 settled decisions, forks, or declined alternatives. --- ## 2. Walked cases ### Case A — cross-matter internal retrieve → full-content-capable, not floor-blocked **Outcome:** CONFIRMED, with the precise interpretation that R3 permits full content when the applicable policy/domain grant permits full; it no longer introduces a cross-matter floor merely because the material belongs to another matter. The actual R3 text fixes the prior fifth-basis internal restriction. §4.0 states the exhaustive R-1 internal-use block list: firewalled, revoked/clawed-back, sealed/PO outside matter, malformed/F1. It also says privilege/cross-matter confidentiality/legal hold/privacy-topic issues are not internal hard blocks. §4.6 then makes Rule 3 action-aware: egress gets the rule-3 floor, but internal actions floor only on R-1 bases, and cross-matter relevance for internal actions is handled by DAMS contamination ranking, never a floor. **Break attempt:** A Matter-A object retrieved inside a Matter-B working episode, same owner principal, no firewalled/revoked/sealed-outside-matter/malformed basis, and with a full applicable retrieval policy: - step 1c does not hard-block if applicable is empty and the internal baseline condition holds; - step 3 does not apply the scope/cross-matter floor because `isEgressAction=false` and `r1_qualifying=false`; - DAMS may rank/attenuate, but DAMS cannot lower the policy point itself. **Residual:** No defect in the R-1 action-aware floor. The implementation should treat “full content” as “not degraded by DOC81 solely because cross-matter”; it still remains bounded by the actual domain/profile/policy contribution. ### Case B — empty-applicable internal → domain baseline, not block **Outcome:** CONFIRMED in intended behavior; minor pseudocode cleanup recommended under C3. §3.2 step 1c says empty applicable decisions plus same-principal internal action plus no R-1 basis yields a domain-profile-only baseline and reason `policy.domain_profile_only_internal_baseline`, not `policy.no_applicable_decision`. The hard block is retained for egress/write/learn/delegate/carryover/cross-principal. **Break attempt:** Empty decision set for same-principal local `retrieve`, no wall/revocation/sealed-outside-matter/malformed basis: - generation/freshness passes; - not egress, so destination precondition is irrelevant; - applicable set is empty; - step 1c takes the internal baseline branch; - step 2 still has the always-present domain contribution, so `meetAllStates` is non-empty. **Residual:** The pseudocode currently says `applicable = [ domainBaselineDecision(request) ]`, while step 2 independently creates `domain = domainContribution(request)` and then maps `applicable` as if each entry is a `MemoryPolicyDecision`. That is not fatal if `domainBaselineDecision` is defined as idempotent, but it is unnecessary and guess-prone. Replace with a boolean sentinel or define the helper. See C3. ### Case C — `restamp_reeval` restore-up-to-ceiling reachable **Outcome:** CONFIRMED. §3.2 step 4 explicitly distinguishes `ordinary` from `restamp_reeval`: ordinary mode meets in `priorEffective`; `restamp_reeval` skips sticky prior and clamps to the root ceiling plus current scope floor. §3.4 repeats the rule: restamps compute with `mode='restamp_reeval'`, never ordinary, and are autonomous except firewalled crossings. This makes R-2 restoration reachable. **Break attempt:** An object was lowered by a now-lifted transient floor. In ordinary mode the prior effective policy would keep it low. In `restamp_reeval`, sticky is skipped, the candidate can rise up to `MIN(root ceiling, current scope floor)`, and the restamp legality check rejects only values exceeding the root ceiling/current floor. That is exactly the desired bounded-declassification behavior. **Residual:** No design defect. Add the `priorState` helper definition under C3 so ordinary sticky cannot be implemented differently by different agents. ### Case D — scope-floor disclosure ceiling survives final scalar derivation **Outcome:** CONFIRMED. R3 structurally fixes the A-B1 leak class. §3.0 removes `disclosure_class` from `PolicyPoint`; `PolicyEffectiveState` carries `point + disclosure_vector`; `meetPolicyState` meets both together; `finalizeDisclosureAndCoherence` derives the scalar exactly once from the final vector and then coheres content. §3.2 step 3 meets `floorEff.max_disclosure_vector` into the effective state, and step 5 does the same for obligation vector ceilings. Step 6 derives the scalar from the final vector, so the floor/domain/prior/obligation disclosure ceiling cannot be overwritten by a later scalar derivation. **Break attempt:** Floor says existence-only, applicable decision says full disclosure. Step 3 AND-meets the floor vector into `eff.disclosure_vector`. Step 6 calls `deriveDisclosureClass` on that final vector. There is no independent scalar slot to set back to `full`; if content remains too high, `makeCoherent` caps content down after derivation. **Residual:** No design defect. --- ## 3. Step-order break attempts ### Disclosure rises without restamp CONFIRMED structurally blocked. Ordinary mode meets `priorEffective` into the unified state, including the disclosure vector. Restamp mode is the only widening path and clamps to root ceiling/current floor. `effective_disclosure_class` is derived once from the final vector, not independently set. ### Floor undone at finalize CONFIRMED structurally blocked. Floors carry `max_disclosure_vector` and are met into the unified state before finalize. `finalizeDisclosureAndCoherence` cannot widen disclosure; it only derives the scalar and lowers content if needed. ### Crosswalk floor skipped Mostly CONFIRMED. §3.2 step 0c is the single consumption point for `DestinationPolicyCrosswalk`; it resolves a row, blocks if the disposition/class is invalid, carries `destination_crosswalk_ref`, and combines `destination_floor` with the scope floor at step 3. **BUG:** §4.6.4's inline seed text still says `same_machine_local → local_file_export` has `reference_only_candidate`; §13.6 says the R3 seed is `normal_policy_check` with `E0EgressAttestation` retained. See finding F-2. ### Sticky/ceiling across ordinary vs `restamp_reeval` CONFIRMED. Ordinary mode uses sticky prior. `restamp_reeval` skips sticky and clamps to root ceiling/current floor. The restamp union and authority prose repeat the same rule. --- ## 4. Residual confirms C1–C4 ### C1 — V13 derived/durable **CONFIRMED coherent.** The compromise is coherent for EC consumption if the six per-request objects are treated as rebuildable derived projections, not audit-durable truth. R3 says `ScopeResolutionResult`, `ScopeBoundary`, `EffectiveMemoryPolicy`, `PolicyMembraneDecision`, `PolicyCappedDAMSInput`, and `PolicyEvaluationContext` carry `persistence_kind: 'derived_projection'`, `canonical_source_refs`, and `rebuild_key`; it also states they are not audit-durable, with durable truth instead in stamps, restamps, clusters, cascades, legal holds, governance/exclusion/topic-risk records. That is enough for Stage 7 as long as implementers key cache invalidation on the freshness/key fields and do not treat derived projections as canonical audit records. **No fix required.** ### C2 — `principal_scope` placement **BUG — fix before ratification.** R3 correctly adds `PrincipalScope` to `ScopeResolutionResult`, but the cache keys do not fully carry the same sentinel. `ScopeResolutionCacheKey` still has `principal_ref?: PrincipalRef`; `EffectivePolicyCacheKey` has no `principal_scope` at all, relying indirectly on `policy_evaluation_context_ref`. That is not enough for the R-5 residual confirm. An absent optional `principal_ref` is exactly the shape `PrincipalScope` was created to avoid; relying on a context ref also makes the cache contract less self-contained and easier for Stage-7 implementation to misuse. **Paste-ready fix:** ```typescript interface ScopeResolutionCacheKey { request_input_hash: ContentHash; request_scope_ref?: ScopeRef; object_ref: MemoryObjectRef; object_scope_ref?: ScopeRef; source_scope_ref?: ScopeRef; destination_scope_ref?: ScopeRef; principal_scope: PrincipalScope; // R3/C2 — REQUIRED sentinel; replaces principal_ref?: PrincipalRef scope_topology_generation_id: string; equivalence_binding_generation_id: string; container_relation_generation_id: string; scope_population_generation_inputs: Array<{ scope_ref: ScopeRef; scope_population_generation_id: string }>; classification_generation_id?: string; domain_profile_registry_version: SchemaVersionRef; policy_generation_id: PolicyGenerationId; effective_state_generation_id: EffectiveStateGenerationId; } interface EffectivePolicyCacheKey { object_ref: MemoryObjectRef; action: MemoryPolicyAction; destination?: E0OutboundDestinationClass; principal_scope: PrincipalScope; // R3/C2 — REQUIRED; must match PolicyEvaluationContext principal policy_evaluation_context_ref: PolicyEvaluationContextRef; scope_resolution_ref?: ScopeResolutionResultRef; policy_generation_id: PolicyGenerationId; effective_state_generation_id: EffectiveStateGenerationId; compiled_policy_evaluator_hash: ContentHash; contributing_decision_hash: ContentHash; obligation_set_hash: ContentHash; meet_mode: 'ordinary' | 'restamp_reeval'; sticky_prior_effective_policy_hash?: ContentHash; reason_code_registry_version: SchemaVersionRef; domain_profile_registry_version: SchemaVersionRef; safe_label_vocabulary_version?: SchemaVersionRef; } ``` Add lint: `cache.policy_key_missing_principal_scope`. ### C3 — pseudocode boundary **GAP — mostly confirmed, but add small helper definitions before ratification.** Most named operations have enough surrounding spec authority: - `meetFloors` is defined by the floor total order and “multiple floors ⇒ MIN.” - `FLOOR_EFFECT` is defined by `ConservatismFloorEffect`. - `rootCeilingItems` maps to `PolicyCeilingSnapshot.ceiling_items`. - `contextCompatible`, `deriveDisclosureClass`, `meetDisclosureVectors`, `domainContribution`, `evaluateThreshold`, `topicMatchAmbiguity`, `evaluateCollectionDisposition`, `validateQuotaEnvelope`, and `asUnitInterval` are defined. The unresolved/guess-prone pieces are: - `domainBaselineDecision(request)` — referenced but not defined and type-mismatched with step 2's `applicable.map(d => toPolicyPoint(d))`. - `priorState(priorEffective)` — referenced but not defined; this matters because `PolicyEffectiveState` includes obligations, attestations, floor refs, and crosswalk refs. - `toPolicyPoint(d)` — obvious but not literally defined. - `rootCeilingItems(request)` — understandable but should state exact matching by `(object, action, destination)`. **Paste-ready fix:** ```typescript function toPolicyPoint(d: MemoryPolicyDecision): PolicyPoint { return { content_fidelity: d.content_fidelity, locality: d.locality, learning_scope: d.learning_scope, mutation_authority: d.mutation_authority, }; } function priorState(e: EffectiveMemoryPolicy): PolicyEffectiveState { return { point: { content_fidelity: e.effective_content_fidelity, locality: e.effective_locality, learning_scope: e.effective_learning_scope, mutation_authority: e.effective_mutation_authority, }, disclosure_vector: e.effective_disclosure_vector, obligations: e.obligations, required_attestations: e.egress_attestation_required ? ['egress'] : [], applied_floor_refs: e.floor_effect_ref ? [e.floor_effect_ref] : [], destination_crosswalk_ref: e.destination_crosswalk_ref, sticky_prior_effective_policy_ref: e.effective_policy_id, }; } function rootCeilingItems(request): PolicyCeilingSnapshot['ceiling_items'] { // Select from the root PolicyCeilingSnapshot for the same object_ref and matching (action, destination?) // item. Missing item => blockedBottomState('restamp.missing_root_ceiling_item'). } ``` And replace the step-1c baseline line with: ```text use_domain_profile_only_internal_baseline = true # applicable remains []; step 2 still includes the always-present domainContribution(request) ``` This keeps the behavior but removes the fake decision object. ### C4 — seed values **CONFIRMED except for the §4.6.4 stale inline seed conflict.** - Threshold split is sane: no-profile fallback `{1.0, 0.0}` is maximally conservative only when no profile resolves; shipped default `{0.85, 0.70}` is conservative without self-blocking. - `contamination minimum_measurement_confidence = 0.60` is reasonable for a local-first personal OS: low-confidence contamination does not silently pass, but it can route to manual/restricted disposition instead of universal block. - `topic_match_ambiguity_band = 0.20` and admit threshold `0.70` are sane for privacy-topic ambiguity. - Traversal depth `16` is reasonable for a local single-principal graph and better than `8` for Will's litigation/research workflows; budget/quota controls handle DoS. - `local_file_export` should be `normal_policy_check` + `E0EgressAttestation`, not a content floor. §13.6 says this correctly; §4.6.4 does not. --- ## 5. New-defect findings ### F-1 — BUG — `PrincipalScope` did not fully land in cache keys **Tier:** Substantive, fix-before-ratification. **Location:** §6.6 `ScopeResolutionCacheKey` / `EffectivePolicyCacheKey`. **Problem:** `ScopeResolutionResult` uses the new `PrincipalScope` sentinel, but cache keys do not. `ScopeResolutionCacheKey` still has optional `principal_ref?: PrincipalRef`; `EffectivePolicyCacheKey` lacks an explicit principal sentinel. This violates C2 and weakens R-5 Phase-2 cache separation. **Fix:** Apply the C2 paste-ready patch above. ### F-2 — BUG — `DestinationPolicyCrosswalk` local-file seed conflict **Tier:** Minor but fix-before-ratification because it directly contradicts C4. **Location:** §4.6.4 inline seed comment vs §13.6 seed table. **Problem:** §13.6 says `local_file_export` egress floor is `normal_policy_check` with `E0EgressAttestation` retained. §4.6.4's inline seed says `same_machine_local → local_file_export` uses `reference_only_candidate`. That stale row would over-block routine local exports and contradict the R3 seed re-adjudication. **Paste-ready replacement for the §4.6.4 seed comment:** ```typescript // Seed rules (GPT §4.8; R3 §13.6 seed): same_runtime → same_machine_local_runtime, // no attestation; same_machine_local → local_file_export, floor normal_policy_check, // E0EgressAttestation REQUIRED (§7.4); external_destination → // {local_network_peer|firm_server|remote_peer|cloud_api|email_outbound|agent_messaging}, // floor fail_closed_candidate, attestation REQUIRED; unknown_destination → // block_until_terminal_destination_resolved; blocked_destination → block. // RULE: any terminal bytes leaving same-machine runtime resolve an E0 class and // (unless same_machine_local_runtime) carry an E0EgressAttestation. ``` ### F-3 — GAP — last `meet_v2` helper definitions are pseudocode-only **Tier:** Minor, fix-before-ratification. **Location:** §3.2 pseudocode. **Problem:** `domainBaselineDecision`, `priorState`, `toPolicyPoint`, and `rootCeilingItems` need one-line executable definitions or exact projection rules. The semantics are inferable, but the commission explicitly asked to eliminate Stage-7 guess-points. **Fix:** Apply the C3 paste-ready helper block above. --- ## 6. QF quantitative-pack meta-test ### Every table has a consumer **CONFIRMED with one seed-row correction.** - `AXIS_RANKS` → `LAT`, `meetPoints`, `makeCoherent`, `deriveDisclosureClass`. - `DISCLOSURE_ALLOWS` → `disclosureVectorCeilingFor`. - `OBLIGATION_DISCLOSURE_VECTOR_CEILING` → §3.2 step 5. - `ConservatismFloorEffect` / floor table → §3.2 step 3. - `DomainProfilePolicyContribution` / `LVL_*` maps → `domainContribution`. - `DestinationPolicyCrosswalk` → §3.2 step 0c. - `ActionPermissionPredicate` → §3.2 step 7. - `RelationTraversalPolicyRegistry` → §8 traversal checks. - `PolicyUIExport` → DOC86 consumption. - Cache keys → exact-match reuse/invalidation. - Quota envelope → `validateQuotaEnvelope`. The one table issue is not lack of consumer; it is the conflicting local-file-export seed value in §4.6.4. ### Every metric has a formula **CONFIRMED.** - `UnitInterval` guard via `asUnitInterval`. - Scope confidence via `requiredScopeConfidenceComponents` + min aggregation. - Coverage via `computeCoverage`. - Threshold polarity via `evaluateThreshold`. - Contamination via threshold + minimum confidence gate. - Topic ambiguity via `topicMatchAmbiguity`. - Equivalence cluster via maximum-bottleneck spanning tree + min edge confidence. - Quota arithmetic via `validateQuotaEnvelope`. ### Every hash has a canonicalization **CONFIRMED.** `CanonicalHashSpec` defines lexicographic key ordering, absent optional treatment, set ordering, number/string/enum/boolean/timestamp forms, and `sha256_hex`. ### Every stateful object has transition rules **CONFIRMED for the scoped delta.** The derived/durable split is explicit; restamp/stamp lifecycle is explicit; collection governance, traversal, cascade/quota, and cache invalidation all carry lifecycle or invalidation rules. C1 is coherent. ### Every optional field has a presence condition **MOSTLY CONFIRMED.** Strong examples: `safe_label_vocabulary_version` has a conditional presence rule; `issued_memory_flow_certificate_ref?` is post-issuance only; `user_visible_summary_ref?` is forbidden on no notice and required otherwise; `safe_label` fields have disclosure-driven presence conditions. Residual: cache principal fields should not be optional/buried. C2 fixes this by making `principal_scope` required on cache keys. --- ## 7. Is R3 ratifiable? **Yes, after the three small fixes above.** No architecture revision is needed. The core R3 design — unified `PolicyEffectiveState`, vector-first disclosure, action-aware floors, restamp re-eval, destination crosswalk consumption, obligation vector ceilings, and QF hardening — passes the scoped final gate. **Ratification status:** `MINOR_FIXES_THEN_RATIFY`.