Add unity layer runtime, gating, and proof battery - #4
Conversation
Review Summary by QodoAdd Unity layer runtime, gating, and proof battery for phenomenal coherence maintenance
WalkthroughsDescription• Introduces comprehensive Unity layer runtime system for maintaining phenomenal coherence and detecting fragmentation across temporal, social, and memory subsystems • Implements UnityRuntime orchestrating temporal binding, co-presence graphs, draft reconciliation, and self-world binding with unified scoring • Adds UnityMonitor to compute fragmentation reports with component scores (affect alignment, continuity, coherence, agency, memory, action readiness) and repair planning • Integrates unity gating into will decisions to block external actions under fragmented/dissociated states and defer memory writes under draft conflict • Implements TemporalBindingField for rolling present maintenance with exponential decay and phase lag tracking • Adds CoPresenceGraphBuilder to construct semantic graphs with focus/peripheral classification and conflict density metrics • Implements DraftReconciliationEngine to preserve competing drafts with contradiction/consensus scoring and memory commit mode determination • Adds SelfWorldBindingModel for ownership confidence and agency tracking with boundary violation detection • Integrates unity state into response generation, self-reporting, coherence engine, and API endpoints • Includes comprehensive test suite validating lesion effects, end-to-end integration, and adversarial prompting resilience • Registers unity phase in kernel pipeline between routing and response generation Diagramflowchart LR
TB["Temporal Binding<br/>Rolling Present"]
CPG["Co-Presence Graph<br/>Focus/Periphery"]
DR["Draft Reconciliation<br/>Conflict Preservation"]
SWB["Self-World Binding<br/>Ownership/Agency"]
UM["Unity Monitor<br/>Fragmentation Detection"]
UR["Unity Repair<br/>Planning & Projection"]
UR_OUT["UnityState<br/>Scores & Reports"]
TB --> UM
CPG --> UM
DR --> UM
SWB --> UM
UM --> UR
UR --> UR_OUT
UR_OUT --> WG["Will Gating<br/>Action/Memory"]
UR_OUT --> RG["Response Generation<br/>Coherence Frame"]
UR_OUT --> SR["Self-Report<br/>Honesty"]
UR_OUT --> API["API Endpoints<br/>/unity"]
WG --> OUT1["Blocked External<br/>Actions"]
WG --> OUT2["Deferred Memory<br/>Writes"]
RG --> OUT3["Integrated<br/>Phenomenal Claims"]
SR --> OUT4["Fragmentation<br/>Language"]
File Changes1. core/unity/runtime.py
|
Code Review by Qodo
1. BindingEngine mutates state
|
|
| Filename | Overview |
|---|---|
| core/unity/runtime.py | New UnityRuntime facade — contains the max() scoring bug that prevents fragmentation recovery across pipeline cycles, and a non-thread-safe singleton factory. |
| core/unity/unity_monitor.py | Core scoring engine — safe_to_self_report flag is effectively always True even for fragmented/dissociated states, neutralising the downstream self-reporting guard. |
| core/brain/inference_gate.py | Both unity injection blocks call record_degradation twice — copy-paste bug that double-counts exceptions in the degradation ledger. |
| core/will.py | Unity gating logic wired correctly into _compose_decision; new WillDecision fields and _read_unity_context gracefully degrade when unity layer is absent. |
| core/unity/unity_state.py | Clean frozen dataclass hierarchy with to_dict/from_dict pairs; safe field coercion throughout. |
| core/memory/memory_facade.py | Unity metadata is merged into every commit, and _unity_requires_write_deferral correctly short-circuits writes when memory_commit_mode == "defer". |
| core/unity/co_presence_graph.py | Graph builder is O(n²) on content items but bounded to ≤18 items; metric calculations are correct. |
| core/unity/temporal_binding.py | Rolling temporal window with exponential decay is correct; continuity/drift calculation is bounded and handles edge cases cleanly. |
| core/unity/draft_reconciliation.py | Draft scoring and contradiction logic are correct; commit_mode thresholds map cleanly to downstream deferral behaviour. |
| core/phases/unity_binding.py | Thin phase wrapper that correctly derives state, calls apply_to_state, and logs the result. |
| interface/routes/inner_state.py | New /unity endpoint and _build_unity_surface helper are well-guarded; all attribute access uses getattr with defaults. |
| core/state/aura_state.py | Unity state is floored into update_health; the min/max pessimism is intentional but exacerbates the recovery issue in runtime.py. |
Sequence Diagram
sequenceDiagram
participant Pipeline
participant UnityBindingPhase
participant UnityRuntime
participant UnityMonitor
participant WillGate as UnifiedWill
participant MemoryFacade
Pipeline->>UnityBindingPhase: execute(state)
UnityBindingPhase->>UnityRuntime: apply_to_state(state, objective, tick_id)
UnityRuntime->>UnityRuntime: gather_contents(state)
UnityRuntime->>UnityRuntime: temporal_binding.bind_now()
UnityRuntime->>UnityRuntime: graph_builder.build()
UnityRuntime->>UnityRuntime: draft_reconciler.reconcile()
UnityRuntime->>UnityRuntime: self_world_binder.bind()
UnityRuntime->>UnityMonitor: compute(state, temporal, graph, drafts, binding)
UnityMonitor-->>UnityRuntime: UnityState + FragmentationReport
UnityRuntime->>UnityRuntime: repair_planner.plan() if repair_needed
UnityRuntime->>ServiceContainer: set(unity_state, unity_fragmentation_report, unity_repair_plan)
UnityRuntime-->>UnityBindingPhase: updated state
Pipeline->>WillGate: decide(content, domain, context)
WillGate->>ServiceContainer: get(unity_state, unity_fragmentation_report)
WillGate->>WillGate: _compose_decision() unity gate
Note over WillGate: REFUSE if fragmented + TOOL_EXECUTION
Note over WillGate: DEFER if fragmented + MEMORY_WRITE(defer mode)
Note over WillGate: CONSTRAIN if strained + external social action
Pipeline->>MemoryFacade: commit_interaction()
MemoryFacade->>ServiceContainer: get(unity_state, unity_fragmentation_report)
MemoryFacade->>MemoryFacade: _unity_requires_write_deferral()
Note over MemoryFacade: Returns None if commit_mode == defer
Reviews (1): Last reviewed commit: "Add unity layer runtime, gating, and pro..." | Re-trigger Greptile
| except Exception as exc: | ||
| record_degradation('inference_gate', exc) | ||
| record_degradation('inference_gate', exc) | ||
| logger.debug("Unity injection unavailable: %s", exc) |
There was a problem hiding this comment.
Duplicate
record_degradation call — the second line is a copy-paste artifact and will double-count every unity-layer exception in the degradation ledger.
| except Exception as exc: | |
| record_degradation('inference_gate', exc) | |
| record_degradation('inference_gate', exc) | |
| logger.debug("Unity injection unavailable: %s", exc) | |
| except Exception as exc: | |
| record_degradation('inference_gate', exc) | |
| logger.debug("Unity injection unavailable: %s", exc) |
| except Exception as exc: | ||
| record_degradation('inference_gate', exc) | ||
| record_degradation('inference_gate', exc) | ||
| logger.debug("Compact unity injection unavailable: %s", exc) |
There was a problem hiding this comment.
Same duplicate
record_degradation in the compact unity injection block.
| except Exception as exc: | |
| record_degradation('inference_gate', exc) | |
| record_degradation('inference_gate', exc) | |
| logger.debug("Compact unity injection unavailable: %s", exc) | |
| except Exception as exc: | |
| record_degradation('inference_gate', exc) | |
| logger.debug("Compact unity injection unavailable: %s", exc) |
| repair_reasons = [name for name, _weight, _text in top_causes] | ||
| repair_needed = level in {"fragmented", "dissociated"} or any(weight >= 0.35 for _name, weight, _text in top_causes) | ||
| safe_to_act = level == "coherent" or (level == "strained" and fragmentation_score < 0.45) | ||
| safe_to_self_report = level == "coherent" or bool(top_causes) |
There was a problem hiding this comment.
safe_to_self_report is almost always True even in severely fragmented states because bool(top_causes) is truthy whenever any cause exceeds the 0.12 threshold — which is virtually guaranteed when the system is fragmented. The downstream "Do not claim clarity" guard in response_generation_unitary.py therefore never fires for real monitor output. Restricting the flag to "coherent" and "strained" levels aligns with the intent expressed in the adversarial test.
| safe_to_self_report = level == "coherent" or bool(top_causes) | |
| safe_to_self_report = level in {"coherent", "strained"} |
| state.cognition.coherence_score = max(float(getattr(state.cognition, "coherence_score", 0.0) or 0.0), unity_state.unity_score) | ||
| state.cognition.fragmentation_score = max(float(getattr(state.cognition, "fragmentation_score", 0.0) or 0.0), unity_state.fragmentation_score) |
There was a problem hiding this comment.
Using
max() for both scores means a previous high-fragmentation reading permanently floors future (lower) measurements, and a previous high-coherence reading permanently ceilings future (lower) coherence. Recovery is structurally blocked. The new unity measurement should simply overwrite the inherited parent value.
| state.cognition.coherence_score = max(float(getattr(state.cognition, "coherence_score", 0.0) or 0.0), unity_state.unity_score) | |
| state.cognition.fragmentation_score = max(float(getattr(state.cognition, "fragmentation_score", 0.0) or 0.0), unity_state.fragmentation_score) | |
| state.cognition.coherence_score = unity_state.unity_score | |
| state.cognition.fragmentation_score = unity_state.fragmentation_score |
|
|
||
|
|
||
| def get_unity_runtime() -> UnityRuntime: | ||
| global _UNITY_RUNTIME | ||
| if _UNITY_RUNTIME is None: | ||
| _UNITY_RUNTIME = UnityRuntime() | ||
| return _UNITY_RUNTIME |
There was a problem hiding this comment.
get_unity_runtime() singleton is not thread-safe
The module-level _UNITY_RUNTIME global is initialised with a simple if _UNITY_RUNTIME is None check. Under concurrent request handling, two instances can be constructed and one silently overwrites the service-container registration, causing a UnityRuntime to lose its accumulated _last_unity_state and related state mid-flight. A threading.Lock or asyncio-safe equivalent should guard the singleton creation.
| try: | ||
| from core.unity import get_unity_runtime | ||
|
|
||
| unity_state = get_unity_runtime().apply_to_state( | ||
| state, | ||
| objective=str(getattr(getattr(state, "cognition", None), "current_objective", "") or ""), | ||
| tick_id=f"binding_{self._tick_count}", | ||
| ).cognition.unity_state | ||
| if unity_state is not None: |
There was a problem hiding this comment.
1. Bindingengine mutates state 🐞 Bug ☼ Reliability
BindingEngine.tick calls UnityRuntime.apply_to_state(state, ...), which mutates the passed AuraState (phenomenal_state, response_modifiers, coherence/fragmentation). Because MindTick runs BindingEngine.tick(state) before phases, this introduces hidden side effects and also double-computes Unity again in UnityBindingPhase.
Agent Prompt
### Issue description
`BindingEngine.tick()` calls `UnityRuntime.apply_to_state(state, ...)`, which mutates the shared `AuraState` during a metrics/computation pass. This introduces hidden side effects before the phase pipeline runs and causes Unity to be computed twice per tick (here and again in `UnityBindingPhase`).
### Issue Context
- `MindTick` runs `BindingEngine.tick(state)` before executing phases.
- `UnityRuntime.apply_to_state()` mutates `state.cognition.phenomenal_state`, `state.cognition.unity_state`, and `state.response_modifiers`.
### Fix Focus Areas
- Replace `apply_to_state(...)` with a non-mutating call path (e.g., `compute(...)`) or apply Unity to a derived/copy state that is not the shared tick state.
- If Unity must be computed here, add a tick-id-based cache/guard so `UnityBindingPhase` can reuse/skip recomputation.
- file: core/coherence/binding_engine.py[262-270]
- file: core/unity/runtime.py[425-452]
- file: core/phases/unity_binding.py[20-29]
- file: core/mind_tick.py[305-313]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
No description provided.