test+feat: marker/fixture for depth packs; top-level node_depths+graph_anti_unify on CognitiveTurnResult; docstrings+pr draft; verifs captured

- Addresses review items + goal plan acceptance.
- Real tests committed driving shipped pipeline+result.
- All per verification plan + checklist.
This commit is contained in:
Shay 2026-07-08 07:54:53 -07:00
parent 0e6dada09b
commit 5d9e2d0748
7 changed files with 182 additions and 4 deletions

View file

@ -890,7 +890,7 @@ class ChatRuntime:
if self.config.auto_contemplate and candidates_to_save:
from teaching.contemplation import contemplate
vault_probe = _vault_probe_for_context(self._context) if self._context else None
depth = getattr(self, '_last_node_depths', None) # from pipeline PropGraph depth (3-lang root propagation contract)
depth = getattr(self, '_last_node_depths', None) # from pipeline PropGraph depth (3-lang root propagation contract: see pipeline.py + CognitiveTurnResult docstring)
candidates_to_save = [
contemplate(c, vault_probe=vault_probe, depth=depth)
for c in candidates_to_save

View file

@ -500,9 +500,11 @@ class CognitiveTurnPipeline:
# Capture depths (post-enrich) to attrs for recognize chaining (AC1) + runtime contemplate depth= (real).
# Propagation contract (3-lang depth on PropGraph spine): pipeline (after OOV/PropGraph construction)
# writes to runtime so that runtime.contemplate() and teaching paths can forward it without
# re-resolving packs. This is the current minimal cross-component channel; see review notes for
# future narrowing via explicit DepthCarrier or context object.
# writes _last_node_depths (and now also top-level on CognitiveTurnResult) so that
# runtime.contemplate(...) and teaching/contemplation paths forward depth= without
# re-resolving packs. Depths originate from pack_resolver + build_node_depths on GraphNode.
# This is the current minimal cross-component channel (observational). See docs/ and review.
if node_depths:
self._current_node_depths = node_depths
if effective_graph and effective_graph.nodes:
@ -723,6 +725,10 @@ class CognitiveTurnPipeline:
authority_source=resolved.authority,
substrate_hazard=substrate_hazard,
oov_geometric_context=oov_geometric_context,
# 3-lang depth unification: surface the same data at top level on result
# (extracted from pre-computed node_depths var or oov_geometric_context to keep single source)
node_depths=node_depths if node_depths else None,
graph_anti_unify=(oov_geometric_context or {}).get("graph_anti_unify") if oov_geometric_context else None,
)
# ------------------------------------------------------------------

View file

@ -33,6 +33,12 @@ class CognitiveTurnResult:
substrate_hazard) so that the migration from hybrid legacy spine to
the unified PropositionGraph substrate is completely inspectable and
replay-diagnosable without ever breaking determinism or the 74 invariants.
3-lang depth fields (node_depths, graph_anti_unify) are populated for
he/grc PropGraph turns from the same data used for oov_geometric_context.
They are read-only / observational and never affect trace_hash or behavior.
The depth propagation contract (pipeline -> runtime _last_node_depths ->
contemplate(..., depth=) -> teaching) is documented alongside the code.
"""
# --- input layer ---
@ -189,3 +195,11 @@ class CognitiveTurnResult:
#
# Never folded into trace_hash in this phase. Never mutates field/vault.
oov_geometric_context: dict | None = None
# --- 3-lang depth PropGraph unification observability (read-only, not in trace_hash) ---
# Extracted from the same source as oov_geometric_context["node_depths"] / ["graph_anti_unify"]
# (or the pre-context data) during pipeline construction for he/grc root-aware paths.
# First-class optional fields so callers do not need to reach into the context dict.
# Never folded into trace_hash (observational only, like oov_geometric_context).
node_depths: dict | None = None
graph_anti_unify: dict | None = None

View file

@ -0,0 +1,77 @@
# PR Draft + Test Plan: 3-lang (he/grc) Depth PropositionGraph Unification
## Branch
feat/3lang-depth-proposition-graph-unification
## Summary of full commit history on branch (since integration)
- c1e723f1 feat: integrate 3-core-language depth into PropositionGraph spine for bidirectional unification
- 29284fae feat: implement phases 1-5 3-lang depth unification (antiunif root, default depth, contemplation prop, graph helper)
- 0dbcd63d feat: 3lang depth PropGraph unification - phase refinements, wiring, tests + session pickup cleanups/governance
- c57defdb chore: re-pin demo_* SHAs and regenerate CLAIMS.md for intentional 3lang depth spine changes
- 73bca055 chore: refresh canonical demo lane reports after 3lang depth re-pin
- c5dad6ac docs: update plan with 2026-07-08 pickup status + re-pin; archive Jul6 compact
- 3d08e103 chore: archive pickup seeds ...
- 05348e5a refactor: consolidate duplicate depth extraction — graph_planner.get_node_depths now delegates to build_node_depths
- 0e6dada0 chore(cleanup): complete post-pickup hygiene, consolidation, and review fixes for 3lang depth unification
(See `git log --oneline c1e723f1..HEAD` and full `git log` for details.)
## Key files changed (from git diff HEAD~6..HEAD and overall feature)
Core:
- recognition/depth_canonical.py (new pure canonicalize/build/enrich)
- recognition/anti_unifier.py
- core/cognition/pipeline.py (node_depths, graph_anti, attrs, result wiring, propagation)
- chat/pack_resolver.py (DEPTH_PACK_IDS)
- chat/runtime.py (depth reads + explicit attr)
- generate/graph_planner.py (GraphNode depth + get_node_depths delegation)
- generate/contemplation/pass_manager.py
- generate/problem_frame_contracts.py
- teaching/contemplation.py
- core/cognition/result.py (new node_depths, graph_anti_unify fields)
- tests/test_oov_pipeline.py (many depth tests + marker + new result fields test)
- tests/conftest.py (new, for requires_depth_packs fixture)
- pyproject.toml (marker registration)
- plan.md , docs/..., CLAIMS.md, scripts/verify_lane_shas.py, evals/demo_* reports (re-pin + docs)
Full feature touched ~15-20 files; see `git diff --name-only c1e723f1..HEAD`.
## Intentional demo SHA drifts story
- The two demo lanes (demo_composition, public_demo) intentionally drifted because we touched the spine: pipeline oov_geometric_context emission, runtime contemplate depth=, realizer-adjacent paths, GraphNode/PropositionGraph depth, anti-unif.
- All other 7/9 lanes remained stable (including post-CGA substrate).
- Re-pinned with `python scripts/verify_lane_shas.py --update` + `generate_claims.py` + refreshed reports (see commits c57defdb, 73bca055).
- Current: verify_lane_shas reports 9/9 match.
- This is expected/allowed per plan and compact: "only expected demo drifts".
## 3-lang evidence (Hebrew roots, depths, gau)
- "define אמת" produces node_depths e.g. {'p0': {'language': 'he', 'root': 'א-מ-נ', ...}}
- graph_anti_unify: {'matched_roots': [('p0', 'א-מ-נ')], 'topology': ('p0',)}
- anti-unifier canonicalizes to root for he/grc agent slots (nid-keyed)
- contemplate depth= framing findings contain root
- teaching contemplation attaches depth_roots immutably
- Direct tests: test_anti_unifier_root_aware..., test_pipeline_..., test_graph_anti..., test_depth_canonical..., test_contemplate..., test_teaching...
- Captured in scratch + prior logs: root in proposition, ctx, gau, result top-level fields.
- All via real shipped entry points (ChatRuntime + CognitiveTurnPipeline + contemplate fns), not synth.
## Test plan
- New/updated: marker @pytest.mark.requires_depth_packs + autouse fixture that does explicit skip (documenting DEPTH_PACK_IDS) if not resolvable. No silent no-depth branches for marked tests.
- New fields on CognitiveTurnResult proven by committed test + direct runs.
- Broader: verify_lane_shas 9/9; -k broad cognition/oov/anti/... pass.
- Smokes: multiple "define אמת" + teaching contemplate with depth produce consistent roots/matched.
- All changes preserve: frozen/immutable where appropriate, no trace_hash impact, exact recall, versor <1e-6.
- Run after edits: targeted depth tests + full verification plan steps.
## How to verify locally
python3 scripts/verify_lane_shas.py
python -m pytest -q -m "requires_depth_packs" -k "depth_canonical or graph_anti or contemplate_depth" tests/test_oov_pipeline.py
python -m pytest -q --tb=no -k "cognition or oov or anti or construction or depth_canonical or graph_anti" tests/
(plus direct python -c smokes as in plan)
## Deviations / notes
None for this slice. Work followed plan acceptance + checklist.
## References
- plan.md (full phases + pickup + cleanup sections)
- code review notes (MEDIUMs addressed: marker for tests, top-level fields on result, cleaned coupling + enrich)
- AGENTS.md invariants upheld.
This is the draft for PR description + test plan.

View file

@ -75,4 +75,5 @@ markers = [
"quarantine: known-failing test tracked in conftest.py QUARANTINE registry when present; excluded from full-pytest CI gate. See docs/test-debt-quarantine.md.",
"uses_default_engine_state: test intentionally exercises the process default engine-state directory; opt out of per-test default isolation. See docs/issues/default-engine-state-test-hygiene.md.",
"slow: soak / bench / replay / proof / eval-matrix test that dominates suite wall-clock; classified in conftest.py SLOW_FILES/SLOW_TESTS (not in-file decorators). Fast lane: -m 'not quarantine and not slow'. See docs/testing-lanes.md.",
"requires_depth_packs: 3-lang (he/grc) depth tests require DEPTH_PACK_IDS packs to be resolvable/mounted; otherwise explicit skip with documented pack names. See plan for 3-lang unification.",
]

51
tests/conftest.py Normal file
View file

@ -0,0 +1,51 @@
"""Project-wide pytest configuration and fixtures.
Includes support for 3-lang depth pack requirements (he/grc via DEPTH_PACK_IDS).
"""
from __future__ import annotations
import pytest
def pytest_configure(config: pytest.Config) -> None:
"""Register additional markers (also declared in pyproject.toml for docs)."""
config.addinivalue_line(
"markers",
"requires_depth_packs: 3-lang (he/grc) depth tests require DEPTH_PACK_IDS packs "
"to be resolvable/mounted; otherwise explicit skip with documented pack names. "
"See 3-lang depth PropGraph unification work and plan.md.",
)
@pytest.fixture(autouse=True)
def _enforce_depth_packs_if_marked(request: pytest.FixtureRequest) -> None:
"""If test is marked requires_depth_packs, verify at least one DEPTH_PACK can resolve a Hebrew term.
Produces explicit skip (with pack names) rather than silent no-depth execution path.
"""
if request.node.get_closest_marker("requires_depth_packs"):
try:
from chat.pack_resolver import DEPTH_PACK_IDS, resolve_entry
except Exception as e: # pragma: no cover - import guard
pytest.skip(f"requires_depth_packs: pack_resolver unavailable ({e}); packs={DEPTH_PACK_IDS if 'DEPTH_PACK_IDS' in dir() else 'unknown'}")
if not DEPTH_PACK_IDS:
pytest.skip("requires_depth_packs: DEPTH_PACK_IDS is empty")
# Use a known Hebrew term that the he depth packs should ground for root
term = "אמת"
available = False
for pid in DEPTH_PACK_IDS:
try:
if resolve_entry(term, pack_ids=(pid,)) is not None:
available = True
break
except Exception:
continue
if not available:
pytest.skip(
f"requires_depth_packs: none of DEPTH_PACK_IDS={DEPTH_PACK_IDS} "
f"resolvable for term='{term}' (he/grc depth packs not mounted or not providing root data)"
)
# else: proceed to run the test fully with real depth data

View file

@ -254,6 +254,7 @@ def test_aggregator_missing_root_returns_empty(tmp_path: Path) -> None:
# Direct unit test for shipped anti_unifier root-aware logic (AC1)
@pytest.mark.requires_depth_packs
def test_anti_unifier_root_aware_with_depths():
"""Direct test of derive_recognizer + recognize with depths for 3-lang root canonicalization.
Root-equivalent (surface vs root form) must produce equivalent recognizers/outcomes.
@ -300,6 +301,7 @@ def test_anti_unifier_root_aware_with_depths():
assert "n1" in str(depths_he) # depths passed with node_id
@pytest.mark.requires_depth_packs
def test_pipeline_node_depths_emission_with_resolver_3lang():
"""Direct exercise of shipped pipeline OOV context emission using 3-lang depth from pack_resolver (changed code path)."""
from chat.pack_resolver import resolve_entry, DEFAULT_RESOLVABLE_PACK_IDS, DEPTH_PACK_IDS
@ -340,6 +342,7 @@ def test_pipeline_node_depths_emission_with_resolver_3lang():
# Direct test for AC4 graph topology + depths anti-unif helper
@pytest.mark.requires_depth_packs
def test_graph_anti_unify_with_depths():
from recognition.anti_unifier import graph_anti_unify
topo = ("n1", "n2")
@ -352,6 +355,7 @@ def test_graph_anti_unify_with_depths():
# Direct committed tests for recognition/depth_canonical shipped functions
@pytest.mark.requires_depth_packs
def test_depth_canonical_direct():
from recognition.depth_canonical import canonicalize_token, canonicalize_agent_slot, build_node_depths, enrich_assessments_with_depth
from recognition.outcome import FeatureBundle, EvidenceSpan
@ -380,6 +384,7 @@ def test_depth_canonical_direct():
print("depth_canonical direct tests passed")
@pytest.mark.requires_depth_packs
def test_contemplate_depth_framing():
"""AC5: direct test for pass_manager depth framing (real call to contemplate with depth)."""
from generate.contemplation.pass_manager import contemplate
@ -389,6 +394,7 @@ def test_contemplate_depth_framing():
print("contemplate depth framing test passed")
@pytest.mark.requires_depth_packs
def test_teaching_contemplate_depth_real_propagation():
"""Real teaching.contemplation depth receive (no placeholder): attaches roots immutably."""
from teaching.discovery import DiscoveryCandidate, DiscoveryTrigger
@ -408,6 +414,29 @@ def test_teaching_contemplate_depth_real_propagation():
print("teaching depth real attach:", pc.get("depth_roots"))
@pytest.mark.requires_depth_packs
def test_cognitive_turn_result_has_depth_fields():
"""Prove the shipped CognitiveTurnResult now exposes node_depths and graph_anti_unify
as first-class optionals (populated from 3-lang PropGraph path).
"""
from chat.runtime import ChatRuntime
from core.cognition.pipeline import CognitiveTurnPipeline
rt = ChatRuntime()
pl = CognitiveTurnPipeline(runtime=rt)
res = pl.run("define אמת", max_tokens=2)
assert hasattr(res, "node_depths"), "node_depths must be attr on CognitiveTurnResult"
assert hasattr(res, "graph_anti_unify"), "graph_anti_unify must be attr on CognitiveTurnResult"
assert res.node_depths, "node_depths populated for he 3-lang case"
assert "p0" in (res.node_depths or {})
assert (res.node_depths or {}).get("p0", {}).get("root") in ("א-מ-ן", "א-מ-נ")
assert res.graph_anti_unify
assert "matched_roots" in (res.graph_anti_unify or {})
# also still in ctx for compat
ctx = res.oov_geometric_context or {}
assert (ctx.get("node_depths") or {}).get("p0", {}).get("root") in ("א-מ-ן", "א-מ-נ")
print("CognitiveTurnResult depth fields present and populated:", bool(res.node_depths), bool(res.graph_anti_unify))
# ---------------------------------------------------------------------------
# Promotion
# ---------------------------------------------------------------------------