openova/docs
e3mrah 6e7a878b1c
feat(catalyst): NS delegation wizard step (closes #374) (#433)
Adds the post-handover wizard step that delegates the parent zone (e.g.
omani.works) to the new Sovereign's PowerDNS, plus a light catalyst-api
stub for live execution in Phase 8.

Wizard (UI):
- New StepNSDelegation slotted as terminal post-handover step (after
  StepSuccess) so the LB IP is in hand before we ask the operator to
  delegate.
- Default mode: emit-runbook only. Renders the exact set_dns2 curl
  command with add_dns_to_current_setting=yes (record-preserving) for
  copy-paste. NEVER embeds the API key — operator exports
  $DYNADOT_API_KEY in their shell.
- Auto-apply mode: gated behind a toggle + double-confirm field
  matching the parent zone. Defaults OFF. POSTs to a stub
  /api/v1/dns/parent-zone/delegate which is 501 today; the wizard
  surfaces a "Phase 8" hint instead of a generic error.
- Memory rule honoured: NO live set_dns2 call reachable on a normal
  wizard flow without explicit operator double-confirm.
- 17 new vitest cases (helper + render + auto-apply gating + 501
  stub-aware error) all green.

Catalyst-API (Go):
- Extends existing internal/dynadot package (canonical seam — no new
  package, no PDM source touched).
- New Client.AddNSDelegation(parentZone, sovereignFQDN, lbIP, extraNS)
  writes 3 NS + 1 glue A record using add_dns_to_current_setting=yes.
  Fail-closed via IsManagedDomain gate (refuses to call the API for an
  unmanaged zone).
- New pure BuildNSDelegationRunbook helper that mirrors the JSX-side
  buildDynadotRunbookCommand so wizard and API emit the same shape.
- 6 new test cases (happy path / unmanaged-zone refusal / table-driven
  validation / custom NS hosts / runbook builder) all green.

Per ticket #374 scope: wizard step + emitted runbook + light stub;
live execution deferred to Phase 8 of the omantel handover WBS. WBS
row updated to wizard-shipped state.

Co-authored-by: hatiyildiz <hatiyildiz@noreply.github.com>
2026-05-01 17:53:41 +04:00
..
adr docs(adr): 0001 — Catalyst control-plane architecture (#354) 2026-05-01 10:37:47 +04:00
lessons-learned fix(bp-flux): catalyst-cluster-reconciler ClusterRoleBinding overlay (closes #338) (#393) 2026-05-01 15:56:45 +04:00
proposals feat(wizard): job dependencies SVG DAG + (stretch) timeline view (closes #206) (#212) 2026-04-29 21:40:43 +02:00
ARCHITECTURE.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
AUDIT-PROCEDURE.md docs(component-count): update 53 → 56 anchors after Pass 105 (spire + nats-jetstream + sealed-secrets) 2026-04-28 13:48:24 +02:00
BLUEPRINT-AUTHORING.md fix(bp-*): observability toggles default false — break circular CRD dependency 2026-04-29 19:23:52 +02:00
BOOTSTRAP-KIT-EXPANSION-PLAN.md docs(bootstrap-kit): expansion plan to 40+ HRs (Wave 2 dispatch reference) (#255) 2026-04-30 17:08:16 +04:00
BUSINESS-STRATEGY.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
CHART-AUTHORING.md fix(catalyst-chart): annotate api-deployment for Flux strategy-flip recovery 2026-04-29 18:04:07 +02:00
COMPONENT-LOGOS.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
DEMO-RUNBOOK.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
FRANCHISE-MODEL.md docs(franchise),test(billing): voucher CRD propagation invariant 2026-04-28 13:59:31 +02:00
GLOSSARY.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
IMPLEMENTATION-STATUS.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
INVIOLABLE-PRINCIPLES.md docs(principles): canonical INVIOLABLE-PRINCIPLES.md — 10 non-negotiable rules 2026-04-28 13:28:11 +02:00
MULTI-REGION-DNS.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
NAMING-CONVENTION.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
omantel-handover-wbs.md feat(catalyst): NS delegation wizard step (closes #374) (#433) 2026-05-01 17:53:41 +04:00
ORCHESTRATOR-STATE.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
PERSONAS-AND-JOURNEYS.md docs(unified-repo-model): collapse SME and corporate to one shape — Application = Gitea Repo 2026-04-28 10:13:02 +02:00
PLATFORM-POWERDNS.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
PLATFORM-TECH-STACK.md docs(reconcile-pass-1): align docs with ground truth at dd578d1c 2026-04-29 09:40:10 +02:00
PRODUCT-FAMILIES.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
PROVISIONING-PLAN.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
RUNBOOK-OPERATIONS.md docs(ops): comprehensive operator runbook + remediation playbook + idempotent recovery script 2026-04-29 19:26:29 +02:00
RUNBOOK-PROVISIONING.md merge: keep k3s local-path-provisioner; mark StorageClass default before Flux runs (closes #189) 2026-04-29 19:43:59 +02:00
SECRET-ROTATION.md fix(cloudinit): create flux-system/ghcr-pull secret on Sovereign so private bp-* charts pull cleanly 2026-04-29 18:07:27 +02:00
SECURITY.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
SOVEREIGN-PROVISIONING.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00
SRE.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
TECHNOLOGY-FORECAST-2027-2030.md refactor(platform): remove k8gb — replaced by PowerDNS lua-records (#171) 2026-04-29 08:51:09 +02:00
UI-REGRESSION-GUARDS.md fix(platform): sync blueprint.yaml versions with Chart.yaml (#199) 2026-04-29 22:07:55 +04:00
VALIDATION-LOG.md docs(reconcile-pass-2): align docs with ground truth at 6afdb303 2026-04-29 11:48:57 +02:00