feat(harness): port CLI skeleton + nsp phase meta --json (F2, kills JS/Python drift)
nsp.cli app registers phase_app (the gate's workflow-fact source). phase meta
--json emits {schema_version, max_phase, phases:[{num,id,name,advance,artifacts_out}]}
from load_workflow() -- the single source of truth. F8/datamart is present (the
exact JS-drift bug in ChironeWp3, PHASE_NAMES truncated to 7, is structurally gone).
Scope: the 12 other command groups land in their porting tasks (A9 ports
db/mschema/_guards; B1 vectorstore; B3 search/lshindex). Eager-importing them now
would break the app on unported deps -- deferred to keep the suite green at each commit.
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
"""L1: nsp 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 nsp.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"
|
||||
Reference in New Issue
Block a user