feat: add production assurance dashboard flow

This commit is contained in:
thanhnv
2026-07-28 21:49:15 +07:00
parent ee5d1f7af5
commit cce3cbfd42
39 changed files with 1873 additions and 91 deletions
+139 -27
View File
@@ -47,7 +47,8 @@ PROJECT_RE = re.compile(r"^[a-z][a-z0-9-]{1,62}$")
# Packaging levels (docs/packaging/CASAN_PACKAGING_PLAN.md, packaging/levels.json).
# Cumulative: devkit⊃core, platform⊃devkit, enterprise⊃platform.
LEVEL_NAME = {"1": "core", "2": "devkit", "3": "platform", "4": "enterprise",
"core": "core", "devkit": "devkit", "platform": "platform", "enterprise": "enterprise"}
"core": "core", "devkit": "devkit", "platform": "platform",
"platform-preview": "platform", "enterprise": "enterprise"}
LEVEL_NUM = {"core": 1, "devkit": 2, "platform": 3, "enterprise": 4}
SUPPORTED_CLIENTS = ("claude", "codex", "vscode-copilot")
VSCODE_EXTENSION_IDS = {
@@ -149,8 +150,10 @@ def _render_init(result):
_details([
("Project", result["project_id"]),
("Location", result["target"]),
("Level", "%s (%s)" % (
result["target_level_name"].capitalize(), result["target_level"])),
("Edition", result["target_level_name"].capitalize()),
("Maturity", str(
(result.get("maturity") or {}).get("status", "not_assessed")
).replace("_", " ")),
("Runtime", "%s — %s" % (
result["runtime_mode"].capitalize(), result["runtime_path"])),
("Mode", result["enforcement_mode"]),
@@ -193,22 +196,29 @@ def _render_verify(result):
def _render_level(result):
_heading("CASAN packaging level")
_heading("CASAN product status")
maturity = result.get("project_maturity") or {}
maturity_level = maturity.get("level")
maturity_status = str(
maturity.get("status", "not_assessed")
).replace("_", " ")
_details([
("Installed", str(result.get("installed_level") or "unknown")),
("Project", ("%s (%s)" % (
result.get("project_target_level_name"),
result.get("project_target_level")))
if result.get("project_target_level") else "not initialized"),
("Installed edition", str(result.get("installed_edition") or "unknown")),
("Project edition", str(
result.get("project_edition") or "not initialized")),
("Edition status", str(
result.get("project_edition_status") or "unknown")),
("Maturity", "%s — %s" % (maturity_level, maturity_status)
if maturity_level else maturity_status),
("Runtime", ("%s — %s" % (
result.get("project_runtime_mode"),
result.get("project_runtime_path")))
if result.get("project_target_level") else "not initialized"),
("Status", str(result.get("project_level_status") or "unknown")),
])
print()
for level, description in result["levels"].items():
print(" %-14s %s" % (level, description))
print(_color("2", "Editions are product packages; L1–L5 maturity is assessed from evidence."))
for edition, description in result["editions"].items():
print(" %-18s %s" % (edition, description))
def _render_doctor(result):
@@ -1083,15 +1093,20 @@ def cmd_init(args):
sys.stderr.write("casan init: --project must match ^[a-z][a-z0-9-]{1,62}$ (got %r)\n" % project)
return 64
# Packaging level to adopt into the project.
# Product edition to adopt into the project. Legacy level fields remain in
# the persisted schema for backward compatibility only.
lvl_name = LEVEL_NAME.get(str(args.level).lower())
if not lvl_name:
sys.stderr.write("casan init: --level must be 1..4 or core|devkit|platform|enterprise\n")
sys.stderr.write(
"casan init: --edition must be core|devkit|platform-preview|enterprise "
"(--level remains a deprecated compatibility alias)\n")
return 64
lvl = LEVEL_NUM[lvl_name]
if lvl == 4:
sys.stderr.write("casan init: Level 4 (enterprise) is FUTURE / not shipped — refusing "
"(no fake-complete adoption). See packaging/levels.json.\n")
sys.stderr.write(
"casan init: Enterprise edition is not shipped — refusing a "
"fake-complete adoption. Product edition is separate from L1–L5 "
"operational maturity. See packaging/levels.json.\n")
return 3
preview = (lvl == 3) # platform is a separate preview SERVICE; init applies the L2 base
apply_devkit = (lvl >= 2)
@@ -1172,8 +1187,39 @@ def cmd_init(args):
# ── .casan/config.json ──
cfg_dir = os.path.join(target, ".casan")
previous_control_plane = previous_config.get("control_plane")
if not isinstance(previous_control_plane, dict):
previous_control_plane = {}
dashboard_url = (
args.dashboard_url
if args.dashboard_url is not None
else previous_control_plane.get("dashboard_url")
or os.environ.get("CASAN_DASHBOARD_URL")
)
dashboard_url = str(dashboard_url).strip().rstrip("/") if dashboard_url else None
if dashboard_url and not re.match(r"^https?://[a-zA-Z0-9]", dashboard_url):
sys.stderr.write("casan init: --dashboard-url must be an http(s) URL\n")
return 64
ingest_url = (
args.ingest_url
if args.ingest_url is not None
else previous_control_plane.get("ingest_url")
)
ingest_url = str(ingest_url).strip() if ingest_url else None
if ingest_url and not re.match(r"^https?://[a-zA-Z0-9]", ingest_url):
sys.stderr.write("casan init: --ingest-url must be an http(s) URL\n")
return 64
token_env = (
args.ingest_token_env
or previous_control_plane.get("token_env")
or "CASAN_CONTROL_PLANE_TOKEN"
)
if not re.match(r"^[A-Z_][A-Z0-9_]{1,127}$", str(token_env)):
sys.stderr.write("casan init: --ingest-token-env must be an uppercase environment variable name\n")
return 64
cfg = {
"schema_version": "21.2",
"schema_version": "21.3",
"project_id": project,
"created_at": now_iso(),
"enforcement_mode": args.mode,
@@ -1199,8 +1245,26 @@ def cmd_init(args):
else "vendored-project"),
"runtime_mode": runtime_mode,
"runtime_path": runtime_path,
# Edition names describe what is packaged. CASAN maturity levels are a
# separate assessment axis and must never be inferred from installation.
"edition": lvl_name,
"edition_status": (
"implemented" if lvl <= 2 else "preview" if lvl == 3 else "future"
),
"target_level": lvl,
"target_level_name": lvl_name,
"maturity": {
"level": None,
"status": "not_assessed",
"evidence": None,
},
"control_plane": {
"dashboard_url": dashboard_url,
"ingest_url": ingest_url,
"token_env": token_env,
"delivery": "async_hmac" if ingest_url else "local_spool",
"receipt_links_enabled": bool(dashboard_url),
},
}
p = os.path.join(cfg_dir, "config.json")
mark_owned_if_absent(p)
@@ -1378,6 +1442,9 @@ def cmd_init(args):
"target": target,
"target_level": lvl,
"target_level_name": lvl_name,
"edition": lvl_name,
"edition_status": cfg["edition_status"],
"maturity": cfg["maturity"],
"harness_version": version,
"harness_hash": hhash,
"runtime_mode": runtime_mode,
@@ -1406,9 +1473,10 @@ def cmd_init(args):
"still needs review in: %s\n" %
", ".join(legacy_migration["manual_review"]))
if preview:
sys.stderr.write("casan init: NOTE — Level 3 (platform) is a PREVIEW SERVICE (Control "
"Panel/Dashboard), adopted by DEPLOYING it, not by repo config. "
"Applied the Level 2 base here; deploy platform separately.\n")
sys.stderr.write(
"casan init: NOTE — Platform Preview is a separate Control Plane "
"service. The DevKit base was adopted here; deploy the dashboard "
"separately.\n")
if hsource == "error":
sys.stderr.write("casan init: WARNING — could not compute harness hash; "
"pin verification will be unavailable.\n")
@@ -1447,7 +1515,10 @@ def cmd_verify(args):
def cmd_level(args):
"""Show the installed packaging level and the project's target level."""
"""Backward-compatible alias for edition status.
Packaging edition and CASAN maturity are intentionally separate axes.
"""
harness = resolve_harness(args.harness)
installed = None
if harness:
@@ -1461,16 +1532,34 @@ def cmd_level(args):
status_map = {1: "implemented", 2: "implemented", 3: "preview", 4: "future"}
tl = cfg.get("target_level")
out = {
"taxonomy": {
"edition": "packaged product capability",
"maturity": "evidence-based operational assessment (L1-L5)",
},
"installed_edition": installed,
"project_edition": cfg.get("edition") or cfg.get("target_level_name"),
"project_edition_status": cfg.get("edition_status") or (
status_map.get(tl, "unknown") if tl else None
),
"project_maturity": cfg.get("maturity") or {
"level": None, "status": "not_assessed", "evidence": None},
"installed_level": installed,
"project_target_level": tl,
"project_target_level_name": cfg.get("target_level_name"),
"project_runtime_mode": cfg.get("runtime_mode", "managed"),
"project_runtime_path": cfg.get("runtime_path"),
"project_level_status": status_map.get(tl, "unknown") if tl else None,
"editions": {
"core": "implemented — harness, H1–H7 gates, receipts and local spool",
"devkit": "implemented — adoption tooling, CI and domain-pack",
"platform-preview": "preview — live Control Plane service",
"enterprise": "future — not shipped",
},
# Deprecated machine-readable alias retained through the 1.x line.
"levels": {
"1 core": "implemented — harness + gates + CLI",
"2 devkit": "implemented — + adoption tooling (casan init, CI, domain-pack)",
"3 platform": "preview — Control Panel/Dashboard SERVICE (deploy separately)",
"1 core": "implemented — harness, H1–H7 gates, receipts and local spool",
"2 devkit": "implemented — adoption tooling, CI and domain-pack",
"3 platform": "preview — live Control Plane service",
"4 enterprise": "future — not shipped",
},
}
@@ -2134,8 +2223,22 @@ def main(argv=None):
"--vscode-install", choices=["auto", "yes", "no"], default="auto",
help=("install the local CASAN @casan VSIX when vscode-copilot is selected "
"(default auto: install when `code` is available)"))
pi.add_argument("--level", default="core",
help="packaging level to adopt: 1|core (default), 2|devkit, 3|platform (preview), 4|enterprise (refused)")
pi.add_argument(
"--edition", "--level", dest="level", default="core",
help=("product edition: core (default), devkit, platform-preview, "
"enterprise (refused); --level is a deprecated alias"))
pi.add_argument(
"--dashboard-url",
help=("Control Plane base URL used for clickable prompt receipts; "
"omit to keep Core offline and use `casan report latest`"))
pi.add_argument(
"--ingest-url",
help=("optional Control Plane POST /api/v1/ingest/turn endpoint; Core "
"always spools first and delivers asynchronously"))
pi.add_argument(
"--ingest-token-env", default=None,
help=("environment variable holding the HMAC ingest secret "
"(default CASAN_CONTROL_PLANE_TOKEN; the secret is never stored)"))
pi.add_argument(
"--runtime", choices=["managed", "vendored"],
help=("Core runtime placement: managed uses the pinned global install "
@@ -2164,6 +2267,15 @@ def main(argv=None):
pl.add_argument("--json", action="store_true",
help="emit the complete machine-readable result")
pe = sub.add_parser(
"edition",
help="show installed/project product edition (preferred over `level`)")
pe.add_argument("--show", action="store_true", help="(default) show edition")
pe.add_argument("--target", help="project root (default: cwd)")
pe.add_argument("--harness", help="override harness root")
pe.add_argument("--json", action="store_true",
help="emit the complete machine-readable result")
pd = sub.add_parser("doctor", help="verify selected client integrations end-to-end")
pd.add_argument("--target", help="project root (default: cwd)")
pd.add_argument("--client", action="append",
@@ -2196,7 +2308,7 @@ def main(argv=None):
return 77
if args.cmd == "verify":
return cmd_verify(args)
if args.cmd == "level":
if args.cmd in ("level", "edition"):
return cmd_level(args)
if args.cmd == "doctor":
return cmd_doctor(args)