srr84/agent-data-layer
0
1"""CHECK-M3 — the M3 round-trip integration test (per-unit-green, M3 DoD).2 3The full C-TDL deterministic pipeline executor -> attacher -> result_envelope is run4over the REAL frozen M1 store fixture and asserted to yield a typed ToolResult with a5NON-EMPTY ProvenanceSet on a positive fact AND a typed AbsenceAttestation on a grounded6zero (exercising the M0-proven `matches()` boundary). This is the M3 terminal per-unit7gate; it is NOT the JOIN-2 integrated gate (GATE-b + SUITE-resolver-meta, M4) — the8resolver / independent re-enumeration is deliberately NOT exercised here.9 10```text11spec traceability (audit map — safe to skip)12docs/08 (CHECK-M3 round-trip: executor->attacher->result_envelope over M1 fixture ->13 typed ToolResult, non-empty ProvenanceSet on positive AND AbsenceAttestation on grounded zero)14docs/09 §4 (M3 DoD: CHECK-M3 terminal per-unit-green; NOT shippable-done until JOIN-2 at M4)15LLD §1/§3 (C-TDL pipeline) · FuncSpec FR-3/FR-4/FR-8.1 · Charter INV-C2 · matches() M016"""17 18from __future__ import annotations19 20import pytest21 22from agent_data_layer.attacher.provenance_attacher import attach23from agent_data_layer.contracts.envelopes import ToolResult24from agent_data_layer.contracts.provenance import AbsenceAttestation25from agent_data_layer.contracts.tools import ReturnSchema, ValidatedToolCall26from agent_data_layer.executor.tool_executor import execute27from agent_data_layer.result_envelope.result_envelope import build_result_envelope28from agent_data_layer.store.event_index import EventIndex, build_index29from agent_data_layer.store.store_loader import load_store30 31_AS_OF = "2026-01-18T08:00:00Z"32 33 34@pytest.fixture35def index() -> EventIndex:36 """The precomputed index over the real frozen M1 store fixture."""37 return build_index(load_store())38 39 40def _roundtrip(index: EventIndex, name: str, **params: object) -> ToolResult[ReturnSchema]:41 """Run the full executor -> attacher -> result_envelope egress and return the42 validated ToolResult (asserting the egress gate did not reject it)."""43 executed = execute(ValidatedToolCall(tool_name=name, params=params), index)44 attached = attach(executed)45 out = build_result_envelope(name, attached)46 assert isinstance(out, ToolResult), f"{name} was rejected at egress: {out!r}"47 return out48 49 50def test_check_m3_positive_fact_has_non_empty_provenance(index: EventIndex) -> None:51 """A positive fact round-trips to a typed ToolResult with a NON-EMPTY ProvenanceSet."""52 out = _roundtrip(index, "get_stock_state", store_id="st-001", product_id="pr-001", as_of=_AS_OF)53 assert isinstance(out.provenance, frozenset)54 assert len(out.provenance) >= 155 56 57def test_check_m3_aggregate_has_complete_non_empty_provenance(index: EventIndex) -> None:58 """A positive aggregate round-trips with a non-empty COMPLETE ProvenanceSet."""59 out = _roundtrip(index, "count_stores_with_condition", condition="OUT_OF_STOCK", as_of=_AS_OF)60 assert isinstance(out.provenance, frozenset)61 assert len(out.provenance) > 062 63 64def test_check_m3_grounded_zero_has_absence_attestation(index: EventIndex) -> None:65 """A grounded zero round-trips to a typed AbsenceAttestation (never empty set / fake)."""66 out = _roundtrip(index, "list_products_in_state", store_id="st-001", state="OUT_OF_STOCK", as_of="2026-01-09T08:00:00Z")67 assert isinstance(out.provenance, AbsenceAttestation)68 assert out.provenance.independently_enumerated_count == 069 70 71def test_check_m3_both_outcomes_in_one_run(index: EventIndex) -> None:72 """The single load-bearing CHECK-M3 assertion: over ONE store fixture, a positive fact73 yields a non-empty ProvenanceSet AND a grounded zero yields an AbsenceAttestation."""74 positive = _roundtrip(index, "list_products_in_state", store_id="st-001", state="ON_SHELF", as_of=_AS_OF)75 grounded_zero = _roundtrip(index, "list_products_in_state", store_id="st-001", state="OUT_OF_STOCK", as_of="2026-01-09T08:00:00Z")76 77 assert isinstance(positive.provenance, frozenset) and len(positive.provenance) > 078 assert isinstance(grounded_zero.provenance, AbsenceAttestation)79 