docs/decisions, tests: add ADR-0145 and tests for energy-modulated vault surface readback

This commit is contained in:
Shay 2026-05-25 07:35:19 -07:00
parent d94ea7e2d1
commit 151ff8c43b
2 changed files with 144 additions and 0 deletions

View file

@ -0,0 +1,64 @@
# ADR-0145: Energy-Modulated Vault Surface Readback
**Status:** Proposed
**Date:** 2026-05-25
**Related:** ADR-0006 (field energy operator), ADR-0004 (vault), W-004 (rethaw)
---
## Context
Under the current architecture:
- Vault recall re-thaws to energy class `E2` (defined in W-004).
- The realized output surface currently ignores the energy class of the grounded turn.
- ADR-0006 §Integration Points explicitly specifies that surface readback should be modulated by the energy class of the grounding source.
This creates a gap where vault-grounded turns are realized without their appropriate energy-modulated prefix, violating the specification of ADR-0006.
---
## Decision
To align surface readback with the energy-modulation requirements of ADR-0006:
1. **Energy Modulation Function:**
Implement `energy_modulated_surface(base: str, energy_class: EnergyClass | str | None) -> str` in [realizer.py](file:///Users/kaizenpro/.gemini/antigravity/worktrees/core/adr-w005-surface-readback/generate/realizer.py). This function will prepend the appropriate prefix based on the energy class:
| Energy Class | Prefix | Example Output |
|---|---|---|
| `E0` | `"From memory: "` | `"From memory: {surface}"` |
| `E1` | `"I seem to recall: "` | `"I seem to recall: {surface}"` |
| `E2` | `"I recall: "` | `"I recall: {surface}"` |
| `E3`, `E4` | *None* | `"{surface}"` |
If the base string is empty, the returned value remains empty.
2. **Threading the Energy Class:**
- Add `recall_energy_class: str | None` to `CognitiveTurnResult` in [result.py](file:///Users/kaizenpro/.gemini/antigravity/worktrees/core/adr-w005-surface-readback/core/cognition/result.py).
- Thread the `recall_energy_class` from the pipeline to `ChatResponse` in [runtime.py](file:///Users/kaizenpro/.gemini/antigravity/worktrees/core/adr-w005-surface-readback/chat/runtime.py).
3. **Modulation Application:**
Apply the modulation explicitly in [runtime.py](file:///Users/kaizenpro/.gemini/antigravity/worktrees/core/adr-w005-surface-readback/chat/runtime.py) on grounding pathways where `grounding_source == "vault"`.
---
## What is NOT done
- **E3/E4 Vault Modulation:** While the prefix table handles `E3` and `E4` by prepending nothing, no current vault recall pathways produce energy states reaching `E3` or `E4`.
- **Readback from Intent:** Rules relating to `readback_from_intent` in `runtime_rules.py` are deferred to W-006 scope.
---
## Consequences
- Surfaces retrieved from the vault (which default to `E2` on re-thaw) will now be prefixed with `"I recall: "`.
- Pack-grounded and teaching-grounded surfaces remain unaffected and will not receive energy modulation prefixes.
- `recall_energy_class` is exposed as an inspectable property on `ChatResponse` and `CognitiveTurnResult`.
---
## References
- **ADR-0006**: Field Energy Operator
- **ADR-0004**: Vault Design
- **W-004**: Vault Re-thaw

View file

@ -0,0 +1,80 @@
"""Tests for ADR-0145: Energy-Modulated Vault Surface Readback.
These tests pin the contract that surface readback is modulated by the energy
class of the grounding source. In particular, vault-grounded turns should prepended
with energy-dependent prefixes, and the recall energy class must be threaded to
ChatResponse.
"""
from __future__ import annotations
import pytest
from chat.runtime import ChatRuntime, ChatResponse
from core.physics.energy import EnergyClass
from generate.realizer import energy_modulated_surface
def test_energy_modulated_surface_e2_prepends_recall_prefix() -> None:
assert (
energy_modulated_surface("Light is coherence.", EnergyClass.E2)
== "I recall: Light is coherence."
)
def test_energy_modulated_surface_e0_prepends_from_memory() -> None:
assert (
energy_modulated_surface("Truth is settled.", EnergyClass.E0)
== "From memory: Truth is settled."
)
def test_energy_modulated_surface_e1_prepends_seem_to_recall() -> None:
result = energy_modulated_surface("Light is coherence.", EnergyClass.E1)
assert result.startswith("I seem to recall: ")
assert result == "I seem to recall: Light is coherence."
def test_energy_modulated_surface_e3_no_prefix() -> None:
assert (
energy_modulated_surface("Clarity.", EnergyClass.E3)
== "Clarity."
)
def test_energy_modulated_surface_empty_base_unchanged() -> None:
assert energy_modulated_surface("", EnergyClass.E2) == ""
def test_vault_grounded_response_has_recall_prefix() -> None:
runtime = ChatRuntime()
# Establish a turn state
runtime.chat("logos arche")
# Store the turn manually in the session vault
runtime.session.vault.store(runtime.session.state.F, metadata={"role": "assistant"})
# Recall the turn
response = runtime.chat("logos arche")
assert response.grounding_source == "vault"
assert response.surface.startswith("I recall: ")
assert response.recall_energy_class == "E2"
def test_pack_grounded_response_has_no_recall_prefix() -> None:
runtime = ChatRuntime()
response = runtime.chat("What is truth?")
assert response.grounding_source in {"pack", "teaching"}
assert not response.surface.startswith("I recall: ")
assert response.recall_energy_class is None
def test_recall_energy_class_is_e2_on_vault_hit() -> None:
runtime = ChatRuntime()
runtime.chat("logos arche")
runtime.session.vault.store(runtime.session.state.F, metadata={"role": "assistant"})
response = runtime.chat("logos arche")
assert response.recall_energy_class == "E2"