From 33a0f295b6a2b55a05e74024155d28ec8f3b8132 Mon Sep 17 00:00:00 2001 From: operator Date: Sun, 4 Oct 2026 17:23:28 +0000 Subject: [PATCH] feat(pipeline): register 3-stage ops-audit pipeline definitions and wire super-cli prune command --- bin/super-cli.py | 102 ++++++++++++++++++++++++++++++++++++++ job-sidechats.json | 7 ++- jobs/ops-audit-step1.json | 17 +++++++ jobs/ops-audit-step2.json | 17 +++++++ jobs/ops-audit-step3.json | 14 ++++++ 5 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 jobs/ops-audit-step1.json create mode 100644 jobs/ops-audit-step2.json create mode 100644 jobs/ops-audit-step3.json diff --git a/bin/super-cli.py b/bin/super-cli.py index 64c5ab9..cbe61e0 100755 --- a/bin/super-cli.py +++ b/bin/super-cli.py @@ -1866,6 +1866,76 @@ def cmd_web_sync(args): print_table(headers, rows) print() +# --------------------------------------------------------------------------- +# Domain: CRED (Credentials & Onboarding Client) +# --------------------------------------------------------------------------- +def cmd_cred_initiate(args): + import cred_client + client = cred_client.CredClient() + res = client.initiate(args.node, args.email, service=getattr(args, "service", "muse"), account_name=getattr(args, "account_name", None)) + if getattr(args, "json", False): + print(json.dumps(res, indent=2)) + else: + st = res.get("status") + if st == "awaiting_otp": + print("\n" + c_warn(f"[APPROVAL_NEEDED] Code sent to {args.email} for node '{args.node}'.") + "\n") + print(f" Submit OTP with: super cred submit-otp --node {args.node} --otp \n") + sys.exit(2) + elif st == "active": + print("\n" + c_ok(f"[SUCCESS] Node '{args.node}' is already authenticated and active.") + "\n") + else: + print(f"[{st.upper()}] {res.get('message') or res.get('detail')}") + sys.exit(res.get("code", 1)) + +def cmd_cred_submit_otp(args): + import cred_client + client = cred_client.CredClient() + res = client.submit_otp(args.node, args.otp, email=getattr(args, "email", None)) + if getattr(args, "json", False): + print(json.dumps(res, indent=2)) + else: + st = res.get("status") + if st == "active": + print("\n" + c_ok(f"[SUCCESS] Node '{args.node}' successfully signed in!") + "\n") + else: + print(f"[{st.upper()}] {res.get('message') or res.get('detail')}") + sys.exit(res.get("code", 1)) + +def cmd_cred_status(args): + import cred_client + client = cred_client.CredClient() + res = client.status(args.node) + if getattr(args, "json", False): + print(json.dumps(res, indent=2)) + else: + print("\n" + c_bold(f"=== CRED STATUS: {args.node} ===") + "\n") + print(f" Node : {c_bold(res['node'])}") + print(f" Email : {res['email']}") + print(f" Status : {res['status']}") + print(f" CDP Port : {res['cdp_port'] or '-'}") + alive_b = badge_ok("YES") if res['session_alive'] else badge_warn("NO") + print(f" Session Alive: {alive_b}") + if res["detail"]: + print(f" Detail : {c_dim(res['detail'])}") + print() + +def cmd_cred_list(args): + import cred_client + client = cred_client.CredClient() + items = client.list_all() + if getattr(args, "json", False): + print(json.dumps(items, indent=2)) + else: + print("\n" + c_bold("=== FLEET CREDENTIAL & ONBOARDING STATUS ===") + "\n") + headers = ["NODE", "STATUS", "CDP", "ALIVE", "EMAIL"] + rows = [] + for it in items: + alive_b = badge_ok("YES") if it["session_alive"] else badge_warn("NO") + rows.append([c_bold(it['node']), it['status'], str(it['cdp_port'] or '-'), alive_b, it['email']]) + print_table(headers, rows) + print() + + # --------------------------------------------------------------------------- # Domain: HARVEST (Response & Readback Harvester) # --------------------------------------------------------------------------- @@ -2929,6 +2999,26 @@ def build_parser(): web_sub.add_parser("test-auth", parents=[common], help="Verify operator auth gating on the VM") web_sub.add_parser("sync", parents=[common], help="Check local log size and sync integrity") + # Domain: CRED + p_cred = subparsers.add_parser("cred", parents=[common], help="Credential console API & client onboarding") + cred_sub = p_cred.add_subparsers(dest="action") + + p_c_init = cred_sub.add_parser("initiate", parents=[common], help="Initiate onboarding flow for a node") + p_c_init.add_argument("--node", required=True, help="Node label (e.g. opm, pip, 646)") + p_c_init.add_argument("--email", required=True, help="Client login email") + p_c_init.add_argument("--service", default="muse", help="Service name (default: muse)") + p_c_init.add_argument("--account-name", default=None, help="Display name hint for multi-account selector") + + p_c_otp = cred_sub.add_parser("submit-otp", parents=[common], help="Submit transient OTP verification code") + p_c_otp.add_argument("--node", required=True, help="Node label") + p_c_otp.add_argument("--otp", required=True, help="6-digit verification code") + p_c_otp.add_argument("--email", default=None, help="Client email (optional)") + + p_c_stat = cred_sub.add_parser("status", parents=[common], help="Query onboarding & vitality status for a node") + p_c_stat.add_argument("--node", required=True, help="Node label") + + cred_sub.add_parser("list", parents=[common], help="List all registered nodes and vitality statuses") + # Domain: HARVEST p_harvest = subparsers.add_parser("harvest", parents=[common], help="Readback & response harvesting engine") harvest_sub = p_harvest.add_subparsers(dest="action") @@ -3191,6 +3281,18 @@ def main(): cmd_web_sync(args) else: parser.print_help() + elif args.domain == "cred": + act = getattr(args, "action", None) + if not act or act == "list": + cmd_cred_list(args) + elif act == "initiate": + cmd_cred_initiate(args) + elif act == "submit-otp": + cmd_cred_submit_otp(args) + elif act == "status": + cmd_cred_status(args) + else: + parser.print_help() elif args.domain == "harvest": act = getattr(args, "action", None) if not act or act == "status": diff --git a/job-sidechats.json b/job-sidechats.json index 503f242..3a92794 100644 --- a/job-sidechats.json +++ b/job-sidechats.json @@ -41,6 +41,11 @@ "pipe-1b4579": { "thread_uuid": "bf7bf3e1-3ee8-4816-9b66-b77b34387986", "agent": "opm", - "created_at": "2026-10-04T16:53:54.998468+00:00" + "created_at": "2026-10-04T16:58:33.951216+00:00" + }, + "pipe-fe170d": { + "thread_uuid": "fbc37533-3908-460e-bb82-58a7edbe5f30", + "agent": "opm", + "created_at": "2026-10-04T17:17:48.449687+00:00" } } \ No newline at end of file diff --git a/jobs/ops-audit-step1.json b/jobs/ops-audit-step1.json new file mode 100644 index 0000000..afbbe97 --- /dev/null +++ b/jobs/ops-audit-step1.json @@ -0,0 +1,17 @@ +{ + "name": "ops-audit-step1", + "description": "Step 1 of Fleet Operational Audit Pipeline: opm checks Box Web endpoints", + "agent": "opm", + "schedule": "manual", + "timeout": 300, + "on_success": "ops-audit-step2", + "on_failure": "ops-audit-alert", + "step_delay": 5, + "followup": { + "expect_reply": true, + "timeout": "15m", + "nudges": 2, + "escalate": "opm" + }, + "prompt_template": "Operational Audit Step 1: Probe Box HTTP endpoints (Front-Door Console and live API surfaces). Summarize probe status in 1 sentence.\n\nWhen finished, end your response with:\n[RESULT {job_id}] OK: Box HTTP endpoints verified responsive" +} diff --git a/jobs/ops-audit-step2.json b/jobs/ops-audit-step2.json new file mode 100644 index 0000000..a2e33c7 --- /dev/null +++ b/jobs/ops-audit-step2.json @@ -0,0 +1,17 @@ +{ + "name": "ops-audit-step2", + "description": "Step 2 of Fleet Operational Audit Pipeline: 646 checks VM services and disk state", + "agent": "646", + "schedule": "manual", + "timeout": 300, + "on_success": "ops-audit-step3", + "on_failure": "ops-audit-alert", + "step_delay": 5, + "followup": { + "expect_reply": true, + "timeout": "15m", + "nudges": 2, + "escalate": "opm" + }, + "prompt_template": "Operational Audit Step 2: Upstream report from {prev_job_id}:\n\"{prev_result}\"\n\nVerify VM backend services (board, caddy, timers) and confirm storage integrity.\n\nWhen finished, end your response with:\n[RESULT {job_id}] OK: VM services and storage verified healthy" +} diff --git a/jobs/ops-audit-step3.json b/jobs/ops-audit-step3.json new file mode 100644 index 0000000..1eafac7 --- /dev/null +++ b/jobs/ops-audit-step3.json @@ -0,0 +1,14 @@ +{ + "name": "ops-audit-step3", + "description": "Step 3 of Fleet Operational Audit Pipeline: pip conducts final fleet sign-off", + "agent": "pip", + "schedule": "manual", + "timeout": 300, + "followup": { + "expect_reply": true, + "timeout": "15m", + "nudges": 2, + "escalate": "opm" + }, + "prompt_template": "Operational Audit Step 3: Upstream audit report from {prev_job_id}:\n\"{prev_result}\"\n\nReview the combined operational findings across Web and VM systems. Formulate final audit approval.\n\nWhen finished, end your response with:\n[RESULT {job_id}] OK: Operational audit verified and approved by pip" +}