Two-session arc where engine derives connective+object from corpus decomposition; operator ratifies rather than authors. Distinguishes from learning-loop (operator-authored) and directly exercises W-018 checkpoint contemplation and W-017 auto-proposal provenance path.
98 lines
3.5 KiB
Python
98 lines
3.5 KiB
Python
"""Learning-arc demo — pins the headline claim for W-019/ADR-0151.
|
|
|
|
If any assertion fails, the claim ("engine authored the proposal
|
|
structure through autonomous contemplation; operator only ratified")
|
|
no longer holds.
|
|
|
|
Module-scoped fixture: one run_demo() invocation shared across all
|
|
tests. Same pattern as test_learning_loop_demo.py — one worker pays
|
|
the demo cost (~3-4s) once.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from evals.learning_arc.run_demo import run_demo
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def demo_report() -> dict:
|
|
return run_demo(emit_json=True)
|
|
|
|
|
|
def test_learning_arc_closes(demo_report: dict) -> None:
|
|
assert demo_report["learning_arc_closed"] is True
|
|
assert demo_report["all_claims_supported"] is True
|
|
assert len(demo_report["scenes"]) == 5
|
|
|
|
|
|
def test_active_corpus_untouched(demo_report: dict) -> None:
|
|
assert demo_report["active_corpus_byte_identical"] is True
|
|
|
|
|
|
def test_before_is_ungrounded(demo_report: dict) -> None:
|
|
assert demo_report["before"]["grounding_source"] != "teaching"
|
|
|
|
|
|
def test_after_is_teaching_grounded(demo_report: dict) -> None:
|
|
assert demo_report["after"]["grounding_source"] == "teaching"
|
|
|
|
|
|
def test_s1_cold_session_persists_candidate(demo_report: dict) -> None:
|
|
s1 = demo_report["scenes"][0]
|
|
assert s1["scene"] == "S1_cold_session"
|
|
assert s1["detail"]["candidates_persisted"] >= 1
|
|
assert s1["detail"]["grounding_source"] != "teaching"
|
|
|
|
|
|
def test_s2_enrichment_has_engine_derived_chain(demo_report: dict) -> None:
|
|
s2 = demo_report["scenes"][1]
|
|
assert s2["scene"] == "S2_checkpoint_enrichment"
|
|
assert s2["detail"]["engine_chain_found"] is True
|
|
assert s2["detail"]["sub_questions_count"] > 0
|
|
chain = s2["detail"]["engine_chain"]
|
|
assert chain["connective"] == demo_report["engine_connective"]
|
|
assert chain["object"] == demo_report["engine_object"]
|
|
|
|
|
|
def test_s3_proposal_source_is_contemplation(demo_report: dict) -> None:
|
|
s3 = demo_report["scenes"][2]
|
|
assert s3["scene"] == "S3_engine_authored_proposal"
|
|
assert s3["detail"]["source_kind"] == "contemplation"
|
|
assert s3["detail"]["state"] == "pending"
|
|
chain = s3["detail"]["proposed_chain"]
|
|
assert chain["connective"] == demo_report["engine_connective"]
|
|
assert chain["object"] == demo_report["engine_object"]
|
|
|
|
|
|
def test_s3_replay_gate_passes(demo_report: dict) -> None:
|
|
s3 = demo_report["scenes"][2]
|
|
ev = s3["detail"]["replay_evidence"]
|
|
assert ev["replay_equivalent"] is True
|
|
assert ev["regressed_metrics"] == []
|
|
|
|
|
|
def test_s4_corpus_byte_identical_after_accept(demo_report: dict) -> None:
|
|
s4 = demo_report["scenes"][3]
|
|
assert s4["scene"] == "S4_operator_ratifies"
|
|
assert s4["detail"]["active_corpus_byte_identical"] is True
|
|
assert s4["detail"]["transient_lines_after"] == s4["detail"]["transient_lines_before"] + 1
|
|
|
|
|
|
def test_before_and_after_surfaces_differ(demo_report: dict) -> None:
|
|
assert demo_report["before"]["surface"] != demo_report["after"]["surface"]
|
|
|
|
|
|
def test_engine_connective_and_object_not_operator_provided(demo_report: dict) -> None:
|
|
"""Connective+object in the proposal came from engine decomposition.
|
|
|
|
The demo's _ENGINE_CONNECTIVE and _ENGINE_OBJECT constants are
|
|
derived from _decompose() output, not hard-coded operator choices.
|
|
S2 confirms engine_chain_found=True, proving the chain appeared
|
|
in the autonomous decomposition set.
|
|
"""
|
|
s2 = demo_report["scenes"][1]
|
|
assert s2["detail"]["engine_chain_found"] is True
|
|
s3 = demo_report["scenes"][2]
|
|
assert s3["detail"]["source_kind"] == "contemplation"
|