99 lines
2.7 KiB
Python
99 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Annotated
|
|
|
|
import typer
|
|
from rich.console import Console
|
|
from rich.table import Table
|
|
|
|
from k1link.simulation import S0ProfileError, run_s0_doctor
|
|
|
|
app = typer.Typer(
|
|
name="missioncore-sim",
|
|
help="Fail-closed qualification tooling for the Mission Core Polygon.",
|
|
no_args_is_help=True,
|
|
)
|
|
s0_app = typer.Typer(
|
|
help="SIM S0 compatibility and infrastructure qualification.",
|
|
no_args_is_help=True,
|
|
)
|
|
app.add_typer(s0_app, name="s0")
|
|
console = Console()
|
|
|
|
|
|
def _default_profile() -> Path:
|
|
return Path(__file__).resolve().parents[3] / "simulation" / "s0" / "qualification-profile.yaml"
|
|
|
|
|
|
DEFAULT_PROFILE = _default_profile()
|
|
|
|
|
|
@s0_app.command("doctor")
|
|
def s0_doctor(
|
|
profile: Annotated[
|
|
Path,
|
|
typer.Option(
|
|
"--profile",
|
|
help="Strict SIM S0 qualification profile.",
|
|
exists=True,
|
|
dir_okay=False,
|
|
readable=True,
|
|
),
|
|
] = DEFAULT_PROFILE,
|
|
evidence: Annotated[
|
|
Path | None,
|
|
typer.Option(
|
|
"--evidence",
|
|
help="Optional digest-bound target-worker evidence manifest.",
|
|
exists=True,
|
|
dir_okay=False,
|
|
readable=True,
|
|
),
|
|
] = None,
|
|
json_output: Annotated[
|
|
bool,
|
|
typer.Option("--json", help="Emit the complete report as JSON."),
|
|
] = False,
|
|
) -> None:
|
|
"""Inspect contracts and local target readiness without changing the host."""
|
|
|
|
try:
|
|
report = run_s0_doctor(profile, evidence_path=evidence)
|
|
except (OSError, S0ProfileError) as exc:
|
|
if json_output:
|
|
console.print_json(
|
|
json.dumps(
|
|
{
|
|
"schema_version": "missioncore.simulation-s0-doctor/v1",
|
|
"verdict": "blocked",
|
|
"error": str(exc),
|
|
}
|
|
)
|
|
)
|
|
else:
|
|
console.print(f"[red]SIM S0 profile rejected:[/red] {exc}")
|
|
raise typer.Exit(code=2) from exc
|
|
|
|
payload = report.to_dict()
|
|
if json_output:
|
|
console.print_json(json.dumps(payload))
|
|
return
|
|
|
|
table = Table(title=f"SIM S0 doctor — {report.profile_id}")
|
|
table.add_column("Check")
|
|
table.add_column("Status")
|
|
table.add_column("Detail")
|
|
colors = {"pass": "green", "fail": "red", "unknown": "yellow"}
|
|
for check in report.checks:
|
|
status = check.status.value
|
|
styled_status = f"[{colors[status]}]{status}[/{colors[status]}]"
|
|
table.add_row(check.identifier, styled_status, check.detail)
|
|
console.print(table)
|
|
console.print(f"Verdict: [bold]{report.verdict.value.upper()}[/bold]")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
app()
|