"""L1: tht phase meta --json -- the gate reads workflow facts from here (F2). Kills the JS/Python drift (no mirrored constants): workflow.yaml is the single source. """ import json from typer.testing import CliRunner from tht.cli import app runner = CliRunner() def test_phase_meta_json_returns_workflow_data(): result = runner.invoke(app, ["phase", "meta", "--json"]) assert result.exit_code == 0 data = json.loads(result.stdout) assert data["max_phase"] == 8 assert len(data["phases"]) == 8 # F8 must be present — this is the exact JS-drift bug (PHASE_NAMES truncated to 7). assert data["phases"][7]["name"] == "datamart" assert data["phases"][7]["num"] == 8 assert "advance" in data["phases"][0] assert "artifacts_out" in data["phases"][0] def test_phase_meta_each_phase_carries_id_and_name(): result = runner.invoke(app, ["phase", "meta", "--json"]) data = json.loads(result.stdout) for i, p in enumerate(data["phases"], start=1): assert p["num"] == i assert p["id"], f"phase {i} missing id" assert p["name"], f"phase {i} missing name" def test_phase_meta_exposes_emits(): # Il gate filtra il ledger per fase con `emits` (recap deterministico v2). result = runner.invoke(app, ["phase", "meta", "--json"]) data = json.loads(result.stdout) f1 = data["phases"][0] assert f1["emits"] == ["concept_clarified", "ambiguity_open"]