fix(cli, tests): wire core contemplation + restore INV-02 allowlist (#60)
Two follow-up fixes from end-of-session verification of recent merges: 1. core/cli.py — wire `core contemplation` subcommand PR #55 + #58 added the contemplation CLI at python -m core.contemplation but never registered it under the `core` umbrella command, so `core --help` didn't show it. Adds a subparser mirroring the existing pattern (chat/test/check/.../doctor) that delegates to the existing core.contemplation.__main__:main() — no duplication of arg parsing. Surface preserved verbatim: reports (positional, 1+), --lane {frontier_compare, contradiction_detection}, --pack-id, --note, --report, --sink-root. 2. tests/test_architectural_invariants.py — restore INV-02 allowlist PR #57's evals/lab/phi_separation_probe.py imports normalize_to_versor for construction-time experimental rotor + embedding work, which triggered INV-02's AST-scan failure (the test enforces that normalize_to_versor is only called from a small allowed file set). evals/lab/ is research-only, never imported by runtime — adding the probe to allowed_files doesn't weaken the runtime invariant the test enforces. Verification ------------ $ core test --suite smoke -q 67 passed in 26.63s (was 66 passed / 1 failed before) $ core contemplation --help ... shows the new subcommand surface $ core contemplation evals/contradiction_detection/results/v1_public_*.json \ --lane contradiction_detection \ --sink-root /tmp/sink \ --report /tmp/run.json ... 4 SPECULATIVE findings; sink writes to /tmp/sink/2026/2026-05.jsonl
This commit is contained in:
parent
db39a5aac7
commit
83c18e4641
2 changed files with 74 additions and 0 deletions
69
core/cli.py
69
core/cli.py
|
|
@ -1103,6 +1103,30 @@ def cmd_rust_test(args: argparse.Namespace) -> int:
|
||||||
return _run("cargo", "test", "--release", cwd=_CORE_RS_DIR)
|
return _run("cargo", "test", "--release", cwd=_CORE_RS_DIR)
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_contemplation(args: argparse.Namespace) -> int:
|
||||||
|
"""Delegate to core.contemplation.__main__:main().
|
||||||
|
|
||||||
|
The contemplation module already owns its argparse surface (lane,
|
||||||
|
sink-root, report, pack-id, note); duplicating it here would
|
||||||
|
drift. We rebuild the inner argv from the parsed Namespace and
|
||||||
|
hand off.
|
||||||
|
"""
|
||||||
|
from core.contemplation.__main__ import main as _contemplation_main
|
||||||
|
|
||||||
|
inner: list[str] = [str(p) for p in (args.reports or ())]
|
||||||
|
if getattr(args, "lane", None):
|
||||||
|
inner.extend(["--lane", args.lane])
|
||||||
|
for pack_id in args.pack_id or ():
|
||||||
|
inner.extend(["--pack-id", pack_id])
|
||||||
|
for note in args.note or ():
|
||||||
|
inner.extend(["--note", note])
|
||||||
|
if args.report is not None:
|
||||||
|
inner.extend(["--report", str(args.report)])
|
||||||
|
if args.sink_root is not None:
|
||||||
|
inner.extend(["--sink-root", str(args.sink_root)])
|
||||||
|
return _contemplation_main(inner)
|
||||||
|
|
||||||
|
|
||||||
def cmd_doctor(args: argparse.Namespace) -> int:
|
def cmd_doctor(args: argparse.Namespace) -> int:
|
||||||
"""Inspect import/package health for the CLI runtime path."""
|
"""Inspect import/package health for the CLI runtime path."""
|
||||||
checks = [
|
checks = [
|
||||||
|
|
@ -3000,6 +3024,51 @@ def build_parser() -> argparse.ArgumentParser:
|
||||||
from formation.cli import register as _register_formation
|
from formation.cli import register as _register_formation
|
||||||
_register_formation(subparsers)
|
_register_formation(subparsers)
|
||||||
|
|
||||||
|
contemplation = subparsers.add_parser(
|
||||||
|
"contemplation",
|
||||||
|
help="run ADR-0080 read-only contemplation over explicit evidence files",
|
||||||
|
)
|
||||||
|
contemplation.add_argument(
|
||||||
|
"reports",
|
||||||
|
nargs="+",
|
||||||
|
type=Path,
|
||||||
|
help="report JSON path(s) to contemplate; must share --lane",
|
||||||
|
)
|
||||||
|
contemplation.add_argument(
|
||||||
|
"--lane",
|
||||||
|
choices=("frontier_compare", "contradiction_detection"),
|
||||||
|
default="frontier_compare",
|
||||||
|
help="evidence lane the reports belong to (default: frontier_compare)",
|
||||||
|
)
|
||||||
|
contemplation.add_argument(
|
||||||
|
"--pack-id",
|
||||||
|
action="append",
|
||||||
|
default=(),
|
||||||
|
help="optional pack id to include in substrate snapshot; may repeat",
|
||||||
|
)
|
||||||
|
contemplation.add_argument(
|
||||||
|
"--note",
|
||||||
|
action="append",
|
||||||
|
default=(),
|
||||||
|
help="optional operator note included in substrate snapshot; may repeat",
|
||||||
|
)
|
||||||
|
contemplation.add_argument(
|
||||||
|
"--report",
|
||||||
|
type=Path,
|
||||||
|
default=None,
|
||||||
|
help="optional output path for the contemplation run JSON blob",
|
||||||
|
)
|
||||||
|
contemplation.add_argument(
|
||||||
|
"--sink-root",
|
||||||
|
type=Path,
|
||||||
|
default=None,
|
||||||
|
help=(
|
||||||
|
"optional append-only JSONL sink root; findings land at "
|
||||||
|
"<root>/<YYYY>/<YYYY-MM>.jsonl alongside discovery candidates"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
contemplation.set_defaults(func=cmd_contemplation)
|
||||||
|
|
||||||
doctor = subparsers.add_parser("doctor", help="check runtime imports and packaging health")
|
doctor = subparsers.add_parser("doctor", help="check runtime imports and packaging health")
|
||||||
doctor.add_argument("--packs", action="store_true", help="also list discovered language packs")
|
doctor.add_argument("--packs", action="store_true", help="also list discovered language packs")
|
||||||
doctor.add_argument("--rust", action="store_true", help="also show Rust backend activation status")
|
doctor.add_argument("--rust", action="store_true", help="also show Rust backend activation status")
|
||||||
|
|
|
||||||
|
|
@ -222,6 +222,11 @@ class TestINV02GateOnlyNormalization:
|
||||||
os.path.join("ingest", "gate.py"),
|
os.path.join("ingest", "gate.py"),
|
||||||
os.path.join("tests", "test_architectural_invariants.py"),
|
os.path.join("tests", "test_architectural_invariants.py"),
|
||||||
os.path.join("tests", "test_versor_closure.py"),
|
os.path.join("tests", "test_versor_closure.py"),
|
||||||
|
# evals/lab/ is research-only, never imported by runtime.
|
||||||
|
# Lab probes need construction-time normalization to build
|
||||||
|
# experimental rotors / embeddings; this does not weaken
|
||||||
|
# the runtime invariant the test enforces.
|
||||||
|
os.path.join("evals", "lab", "phi_separation_probe.py"),
|
||||||
}
|
}
|
||||||
|
|
||||||
violations: list[str] = []
|
violations: list[str] = []
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue