let pb = import "schemas/lib/playbook.ncl" in pb.make_playbook { id = "switch_to_vm_ops", name = "Switch to VM-Ops (Auto-Sign) Mode", description = "Ensures keeper policy is current in policy- Radicle repo, starts keeper-daemon on ops-vm, and verifies it picks up the pending ops backlog.", version = 1, preconditions = [ "policy- Radicle repo has been updated and propagated to ops-vm seed", "ops-vm is accessible via SSH", "KEEPER_PRIVATE_KEY_PATH is set on ops-vm", "NATS JetStream OPS_PENDING_ stream exists in libre-wuji", ], params = [ { name = "workspace", description = "Target workspace name (e.g. libre-wuji)", required = true, default_val = "" }, { name = "ops_vm_host", description = "ops-vm SSH hostname or IP", required = true, default_val = "" }, ], steps = [ { id = "validate_policy", name = "Validate keeper policy against keeper_policy.ncl schema", script = "steps/validate_policy.nu", dry_run_arg = "--dry-run", on_error = 'Stop, depends_on = [], }, { id = "sync_policy_repo", name = "Sync policy- Radicle repo to ops-vm", script = "steps/sync_policy_repo.nu", dry_run_arg = "--dry-run", on_error = 'Stop, depends_on = ["validate_policy"], }, { id = "start_keeper_daemon", name = "Start keeper-daemon on ops-vm via SSH", script = "steps/start_keeper.nu", dry_run_arg = "--dry-run", on_error = 'Stop, depends_on = ["sync_policy_repo"], }, { id = "verify_daemon_running", name = "Verify keeper-daemon health endpoint responds", script = "steps/verify_keeper_health.nu", dry_run_arg = "--dry-run", on_error = 'Stop, depends_on = ["start_keeper_daemon"], }, { id = "verify_backlog_processing", name = "Verify keeper-daemon picks up pending ops backlog", script = "steps/verify_backlog.nu", dry_run_arg = "--dry-run", on_error = 'Continue, depends_on = ["verify_daemon_running"], }, { id = "emit_mode_change", name = "Emit audit event: mode switched to vm-ops", script = "steps/emit_audit.nu", params = { event_type = "mode_switch", new_mode = "vm-ops" }, dry_run_arg = "--dry-run", on_error = 'Continue, depends_on = ["verify_daemon_running"], }, ], rollback_strategy = 'manual, success_criteria = [ "keeper-daemon active on ops-vm (systemctl is-active keeper-daemon = active)", "keeper-daemon /health endpoint responds 200", "OPS_PENDING queue depth decreasing as backlog is processed", "ops history shows mode-switch audit event", ], emit_audit = true, adr_refs = ["adr-037"], }