PLAN stage: 8-wave structure covering 23 phases. Wave 0 (P00 cache), Wave 1 (P01/P01.5/P02 observability+identity), Wave 2 (P03/P15.5 security+ingress hybrid+doctor mTLS), Wave 3 (P04/P06 backup+alloc history+logs), Wave 4 (P05/P07 drain+migrate+recovery), Wave 5 (P10/P11/P12 txn plane+drift+lint+verify), Wave 6 (P09/P13 aggregator+ns), Wave 7 (P14a/b/c migration+upgrade+rotate-lead), Wave 8 (P08/P15/P16 integration+docs+ship). P10 is the largest phase; grill may split into P10a/P10b. ---ci--- project: orca phase: 0 milestone: v0.11 status: plan ---/ci---
25 KiB
Plan: v0.11 Production Hardening
Milestone: v0.11 — Production Hardening
- Type: feature (multiple
featphases) - Tags:
v0.10.0(P0) →v0.10.1…v0.10.20(P00…P15.5) →v0.10.21(P16 = v0.11.0 milestone release) - Branch:
milestone/v0.11-production-hardening - New rules adopted: R-017 (ingress hybrid), R-018/R-019/R-020 (drift detection)
- New decisions: D-215…D-237 (23 net-new, no collisions)
- New REQs: REQ-099…REQ-118 (20 net-new; REQ count 98→118)
Wave ordering
Wave 0 — Foundation (serial)
- P00 — CLI cache layer (R-008). Unblocks all subsequent CLI commands that need cached reads.
Wave 1 — Observability + identity (serial, gate-heavy)
- P01 — Metrics endpoint (hand-rolled text exposition). Unblocks
orca doctor mTLSlive probe (C5). - P01.5 — SPIFFE SVID minting spike (gate C-08 — if spike fails, fall back to mTLS identity). Gates P02 ACL.
- P02 — ACL (SPIFFE + token identities). Depends on P01.5.
Wave 2 — Security + secrets (serial)
- P03 — Secrets subsystem (REQ-080; gate C-19 threat model).
- P15.5 — Threat model + security review (gate C-19) + ingress hybrid (R-017; REQ-099..REQ-102) +
orca doctor mTLS(REQ-118). Per Q3=A, ingress folds in here. This phase grows ~30% but stays one phase.
Wave 3 — Data durability (serial)
- P04 — Backup/restore (tar + signed). Unblocks P07 recovery.
- P06 — Alloc history (CLI-side SQLite; R-008 cache DB) +
orca logs --all-nodes --since(REQ-117). The logs command uses the alloc-history cache DB.
Wave 4 — Lifecycle (serial)
- P05 — Drain + daemon drain-and-stop (REQ-061) +
orca job migrate --to(REQ-116; C3=drain+reschedule composite). Migrate composes P05 drain + P06 alloc history. - P07 — Recovery (
orca restore). Depends on P04 backup.
Wave 5 — Transactional plane (serial, the big one)
- P10 — Transactional plane (REQ-075, REQ-079; gate C-09) + drift detection (R-018/R-019/R-020; REQ-103..REQ-113). This is the largest phase. Grill may split into P10a (txn plane) + P10b (drift) if vertical slice is too large.
- P11 —
orca job lint(REQ-084). Depends on P10 txn plane for dry-run validation. - P12 —
orca job verify(dry-run txn through lead). Depends on P10.
Wave 6 — Namespace + aggregation (parallel)
- P09 — Collector + aggregator (opt-in; gates C-11, C-12, C-14) + drift-event aggregation extension (REQ-107, D-237). The aggregator timer is extended to pull drift-events/ and remediate. C-11 watchdog monitors this timer.
- P13 —
orca nssubcommands (full surface) + deprecation warnings (REQ-068).
Wave 7 — Migration (serial, gate-heavy)
- P14a — v0.8→v1.0 data migration (REQ-066; gate C-07) +
orca upgrade --to-vX(REQ-115; C2=thin wrapper, handles R-017 binding cutover). - P14b — Daemon cutover + running-allocation adoption +
orca cluster rotate-lead(REQ-114). - P14c — Mixed-version tolerance + no-orca-on-server enforcement (REQ-065, REQ-086; implements C-13).
Wave 8 — Integration + docs + ship (serial)
- P08 — Integration tests (expand hermetic harness, REQ-087) + drift-detection integration tests (auto-remediation success, NFS fallback, rate-limit cooldown, secret exclusion).
- P15 — README quickstart (REQ-089; Q5=A Nomad-inspired framing, honest-trade-offs table from doc 3). All cited CLI commands must exist by this phase.
- P16 — Final review + ship + audit — v0.11.0 milestone release.
Phase task tables
Phase P00 — CLI cache layer (Wave 0)
REQs: R-008 (cache floor)
Persona: backend-engineer
Territory: internal/cache/, internal/store/orca_cache.go
Vertical slice: a CLI command that reads cached state → a cache-hit returns in <1ms, a cache-miss populates from the lead.
| Task | Description | REQ |
|---|---|---|
| P00-T1 | internal/cache/ package: orca_cache SQLite schema (per-class TTLs), Get(class, key), Set(class, key, val, ttl), Invalidate(class); stdlib database/sql + modernc/sqlite |
R-008 |
| P00-T2 | Wire cache into orca node list, orca job list, orca ns list (read path only; writes bypass cache) |
R-008 |
| P00-T3 | orca cache show / orca cache invalidate CLI for debugging |
R-008 |
| P00-T4 | Tests: cache-hit/miss/invalidate/TTL-expiry; bench <1ms cache-hit | R-008 |
Must-haves: cache-hit <1ms; TTL-based invalidation; CLI commands use cache on read path.
Phase P01 — Metrics endpoint (Wave 1)
REQs: (new; metrics text exposition)
Persona: backend-engineer
Territory: internal/cli/metrics.go, internal/transport/metrics.go
Vertical slice: curl localhost:9100/metrics → prometheus text exposition.
| Task | Description | REQ |
|---|---|---|
| P01-T1 | internal/transport/metrics.go: hand-rolled Prometheus text exposition (no client_golang dep); counters for txns applied/drifted/remediated; gauges for peers/nodes/allocs |
new |
| P01-T2 | orca daemon --metrics :9100 flag (or sidecar listener); /metrics endpoint |
new |
| P01-T3 | Tests: exposition format validity; counter increments on txn apply | new |
Must-haves: /metrics returns valid Prometheus text; no client_golang dependency.
Phase P01.5 — SPIFFE SVID minting spike (Wave 1, gate C-08)
REQs: REQ-076
Persona: security-engineer
Territory: internal/identity/spiffe.go
Gate: C-08 — if spike fails, fall back to mTLS identity (decision recorded).
| Task | Description | REQ |
|---|---|---|
| P01.5-T1 | Spike: mint a SPIFFE SVID via step-ca; verify URI SAN format (spiffe://orca.local/ns/<ns>/sa/<sa>/<alloc-id>) |
REQ-076 |
| P01.5-T2 | Decision record: if spike passes, proceed to P02 with SPIFFE; if fails, fall back to mTLS identity + record in PROJECT.md | REQ-076 |
Must-haves: spike passes or fails with a recorded decision; C-08 gate cleared.
Phase P02 — ACL (Wave 1)
REQs: (new; ACL with SPIFFE + token identities)
Persona: backend-engineer + security-engineer
Territory: internal/acl/, internal/cli/acl.go
Depends on: P01.5 (SPIFFE or mTLS fallback)
| Task | Description | REQ |
|---|---|---|
| P02-T1 | internal/acl/ package: identity → permissions mapping; SPIFFE URI → namespace scope; token identities for operators |
new |
| P02-T2 | orca acl CLI: grant, revoke, list, check; scoped to namespace paths per R-002 |
new |
| P02-T3 | Tests: SPIFFE identity grants ns-scoped access; token grants operator-scoped access; deny by default | new |
Must-haves: deny-by-default; SPIFFE URI maps to namespace; tokens for operator access.
Phase P03 — Secrets subsystem (Wave 2, gate C-19)
REQs: REQ-080
Persona: security-engineer
Territory: internal/secrets/, internal/cli/secrets.go
Gate: C-19 (threat model must land in P15.5; P03 implements the crypto)
| Task | Description | REQ |
|---|---|---|
| P03-T1 | internal/secrets/ package: AES-256-GCM encrypt/decrypt with master.key (R-011); per-line nonce; LoadCredential= integration |
REQ-080 |
| P03-T2 | orca secrets CLI: set, get, rotate, list; scoped to namespace .env.secrets |
REQ-080 |
| P03-T3 | Tests: encrypt/decrypt round-trip; rotation re-encrypts; master.key 0600 enforced | REQ-080 |
Must-haves: AES-256-GCM; per-line nonce; master.key 0600; LoadCredential= integration.
Phase P15.5 — Threat model + ingress hybrid + doctor mTLS (Wave 2, gate C-19)
REQs: REQ-099, REQ-100, REQ-101, REQ-102, REQ-118; C-19
Persona: security-engineer + network-engineer + backend-engineer
Territory: internal/emitter/nft.go, internal/emitter/traefik.go, internal/cli/nft.go, internal/cli/doctor_mtls.go, threat-model doc
Vertical slice: orca init on a fresh cluster → Traefik binds 127.0.0.1:8443 + nft DNAT → orca doctor nft + orca doctor mTLS pass.
| Task | Description | REQ |
|---|---|---|
| P15.5-T1 | internal/emitter/nft.go: nftables emitter renders /etc/nftables.d/orca.nft (DNAT :443→127.0.0.1:8443, :80→127.0.0.1:8080; SYN-flood filter; ora_rl rate-limit meter; orca_trusted_probes set); idempotent nft -f apply; atomic rule-set swap (D-217, D-218) |
REQ-099 |
| P15.5-T2 | internal/emitter/traefik.go update: static config address: 127.0.0.1:8443 (default); --public-binding=traefik-on-public-ip opt-out emits :443; certs/mTLS/dynamic config unchanged (D-220, D-216) |
REQ-100 |
| P15.5-T3 | orca doctor nft: checks table exists, DNAT rules present, rate-limit meter present, file parses (nft -c -f), hash matches latest txn (D-221, D-226) |
REQ-101 |
| P15.5-T4 | orca nft CLI: show [--peer], diff --against <txn-id>, doctor, country block add <cc-list>, rate limit set --rate N/s (D-223, D-222) |
REQ-102 |
| P15.5-T5 | orca doctor mTLS: trust-chain verification (CA → server cert → workload SVIDs exist + not expired) + live mTLS handshake probe to each peer (reuses P01 metrics endpoint + P01.5 SPIFFE infra); C5=both |
REQ-118 |
| P15.5-T6 | Threat model doc: covers R-017 ingress trust boundary, R-020 drift deadlock, secret exclusion D-234, orca system user blast radius; clears C-19 |
C-19 |
| P15.5-T7 | Tests: nft emitter output validates (nft -c -f); Traefik static config has 127.0.0.1:8443; doctor nft passes on a clean cluster; doctor mTLS passes with valid chain + live probe |
REQ-099..102, 118 |
Must-haves: fresh orca init produces hybrid binding; orca doctor nft + orca doctor mTLS pass; C-19 cleared; opt-out flag works.
Phase P04 — Backup/restore (Wave 3)
REQs: (new; tar + signed backup)
Persona: backend-engineer
Territory: internal/backup/, internal/cli/backup.go
| Task | Description | REQ |
|---|---|---|
| P04-T1 | internal/backup/ package: tar ORCA_HOME (excl. secrets? or incl. with master.key?); sign with master.key (HMAC-SHA256); orca backup --out snap.tar.gz |
new |
| P04-T2 | orca restore --in snap.tar.gz (P07 owns the full recovery; P04 owns the backup format + signing) |
new |
| P04-T3 | Tests: backup→restore round-trip; signature verification; backup excludes /run/orca/* |
new |
Must-haves: backup is a signed tarball; restore verifies signature.
Phase P06 — Alloc history + logs --all-nodes (Wave 3)
REQs: REQ-071 (cache DB), REQ-117
Persona: backend-engineer
Territory: internal/store/alloc_history.go, internal/cli/logs.go
Depends on: P00 (cache DB)
| Task | Description | REQ |
|---|---|---|
| P06-T1 | internal/store/alloc_history.go: CLI-side SQLite retention for alloc state transitions; TTL-based eviction |
REQ-071 |
| P06-T2 | orca logs --all-nodes --since 5m: aggregates journald logs across peers via SSH fanout; iter.Seq streaming (D-017); --since duration; --all-nodes fans out (Q2=C) |
REQ-117 |
| P06-T3 | Tests: alloc history retention/eviction; logs --all-nodes fans out + streams + cancels via ctrl-c | REQ-071, 117 |
Must-haves: alloc history retained in cache DB; --all-nodes aggregates across peers with streaming.
Phase P05 — Drain + migrate (Wave 4)
REQs: REQ-061, REQ-116
Persona: backend-engineer
Territory: internal/cli/drain.go, internal/cli/migrate.go
Depends on: P06 (alloc history for migrate)
| Task | Description | REQ |
|---|---|---|
| P05-T1 | orca node drain <host>: drain a node (stop new allocs; migrate existing per update config); daemon drain-and-stop (REQ-061) |
REQ-061 |
| P05-T2 | orca job migrate <name> --to <node>: drain+reschedule composite (C3=a); uses P05 drain + P06 alloc history; idempotent (Q2=C) |
REQ-116 |
| P05-T3 | Tests: drain stops new allocs; migrate reschedules to target node; daemon drain-and-stop works | REQ-061, 116 |
Must-haves: drain stops new allocs + migrates existing; migrate reschedules to a specific node.
Phase P07 — Recovery (Wave 4)
REQs: (new; orca restore)
Persona: backend-engineer
Territory: internal/cli/restore.go
Depends on: P04 (backup format)
| Task | Description | REQ |
|---|---|---|
| P07-T1 | orca restore --in snap.tar.gz: verify signature, extract, reconcile with live state (don't clobber running allocs unless --force) |
new |
| P07-T2 | Tests: restore from signed backup; signature mismatch fails; --force clobbers running allocs |
new |
Must-haves: restore verifies signature; doesn't clobber running allocs without --force.
Phase P10 — Transactional plane + drift detection (Wave 5, gate C-09)
REQs: REQ-075, REQ-079, REQ-103..REQ-113; C-09; R-018/R-019/R-020
Persona: backend-engineer + devops-engineer + security-engineer
Territory: internal/drift/, internal/cli/drift.go, scripts/orca-drift-notify.sh, scripts/orca-remediate.sh, internal/emitter/systemd.go (Path units), internal/paths/paths.go
Vertical slice: operator edits /etc/traefik/dynamic/orca.yml on a peer → drift detected in ~10s → auto-remediated → orca drift watch shows the event.
Note: This is the largest phase. Grill may split into P10a (txn plane, REQ-075/079) + P10b (drift detection, REQ-103..113) if the vertical slice is too large.
| Task | Description | REQ |
|---|---|---|
| P10-T1 | internal/txn/ package: render txn bundle (tarball + apply.sh + verify.sh) on operator host; SCP to lead's /run/orca/txns/<txn-id>/; lead's systemd timer runs apply.sh idempotently; CLI polls txn status via SSH (REQ-075, C-09) |
REQ-075 |
| P10-T2 | scripts/orca-pull.sh with C-09 failure contract: idempotent re-run, bounded retry, deterministic state, structured syslog (C-09) |
REQ-079, C-09 |
| P10-T3 | internal/drift/ package: Detector interface (Watch, Aggregate, Remediate, Acknowledge), Event, Config, PathSpec, RemediationPolicy; iter.Seq2[Event, error] (D-017); signal.NotifyContext (D-023) (D-236) |
REQ-103 |
| P10-T4 | orca drift CLI tree: watch [--interval=2s] [--paths=...] [--json], show [--peer], acknowledge <peer> <path>, remediate <peer> <path> [--force], config show, config validate (D-236) |
REQ-104 |
| P10-T5 | systemd Path unit emitter: for each critical path, emit orca-drift-<name>.path (PathChanged=, RateLimitIntervalSec=1s, RateLimitBurst=5) + orca-drift-<name>.service (Type=oneshot, ExecStart=/usr/local/bin/orca-drift-notify.sh %f, User=orca, security hardening); R-001-clean (D-227, D-228) |
REQ-105 |
| P10-T6 | scripts/orca-drift-notify.sh: receives changed path as $1, computes sha256 (or "DELETED"), writes event JSON to /etc/orca/state/drift-events/<event-id>.json; stateless, idempotent; flock (D-228) |
REQ-106 |
| P10-T7 | scripts/orca-remediate.sh: re-pushes latest applied txn's per-peer render tree via rsync, runs peer-side applier; 5-min cooldown per path applies ONLY on successful remediation (C4 refinement); transient failures retry next tick (D-231, D-232) |
REQ-108 |
| P10-T8 | Drift cadence config in config.md (kind: ClusterConfig): drift.polling, drift.paths.{critical,standard,excluded}, drift.remediate; critical defaults: Traefik dynamic, nftables, sudoers, orca-alloc services; secrets + /run/orca/* + drift-events dir excluded (R-018, D-231, D-234) |
REQ-109 |
| P10-T9 | Pre-flight consistency gate in orca-pull.sh: refuses new txns if drift detected on target peer/namespace; --force overrides; per-namespace scoping (drifted peer in ns-A doesn't block ns-B) (R-020, Q4=A) |
REQ-110 |
| P10-T10 | orca system user on peers: peer-setup emits useradd -r orca (system account, no login shell); orca-drift-*.service runs as User=orca; idempotent (REQ-111) |
REQ-111 |
| P10-T11 | NFS detection at peer setup: orca node join detects NFS mounts on orca state dirs; disables Path units for NFS paths; logs warning; falls back to polling (D-233) |
REQ-112 |
| P10-T12 | orca job restart <name>: restarts an alloc to pick up EnvironmentFile drift; normal allocation lifecycle (not file-level remediation) (D-235) |
REQ-113 |
| P10-T13 | Tests: txn apply idempotent + retry on failure; drift detected via Path unit ~10s; auto-remediation re-pushes; cooldown prevents loop; --force overrides pre-flight gate; per-ns scoping isolates drift; NFS fallback; secret exclusion |
REQ-075..113 |
Must-haves: txn apply idempotent (C-09); drift detected ~10s on critical paths; auto-remediation with cooldown; --force + per-ns override; orca user created; NFS detection works.
Phase P11 — orca job lint (Wave 5)
REQs: REQ-084
Persona: backend-engineer
Territory: internal/cli/job_lint.go
Depends on: P10 (txn plane for dry-run validation)
| Task | Description | REQ |
|---|---|---|
| P11-T1 | orca job lint <spec.md>: validates jobspec schema (kinds, blocks, CEL constraints, body preservation); reports errors with line numbers |
REQ-084 |
| P11-T2 | Tests: valid spec passes; invalid spec reports errors with line numbers | REQ-084 |
Must-haves: lint catches schema errors; reports line numbers.
Phase P12 — orca job verify (Wave 5)
REQs: (new; dry-run txn through lead)
Persona: backend-engineer
Territory: internal/cli/job_verify.go
Depends on: P10 (txn plane)
| Task | Description | REQ |
|---|---|---|
| P12-T1 | orca job verify <spec.md>: dry-run txn through lead (no apply); reports what would change (allocs created/removed, config files written) |
new |
| P12-T2 | Tests: verify reports planned changes without applying; fails on pre-flight drift | new |
Must-haves: verify is a true dry-run (no side effects); reports planned changes.
Phase P09 — Collector + aggregator + drift-event aggregation (Wave 6)
REQs: (existing collector/aggregator) + REQ-107; C-11, C-12, C-14
Persona: devops-engineer + backend-engineer
Territory: scripts/orca-aggregate.sh, internal/cli/collector.go
Gates: C-11 (watchdog), C-12 (opt-in), C-14 (syncthing)
| Task | Description | REQ |
|---|---|---|
| P09-T1 | scripts/orca-aggregate.sh: existing 10s cadence (C-11); now also rsyncs each peer's /etc/orca/state/drift-events/, validates event hashes against applied txn manifest, triggers orca-remediate.sh for auto-remediable paths, consumes (deletes) event files on peers (D-229, D-237) |
REQ-107 |
| P09-T2 | Lead-side watchdog meta-timer (C-11): fires on orca-pull.sh starvation (>N seconds without successful run); structured alert path |
C-11 |
| P09-T3 | orca collector CLI: opt-in collector for per-peer state snapshots; writes to cluster.json (C-12 opt-in) |
C-12 |
| P09-T4 | Tests: aggregator pulls drift-events + triggers remediation; watchdog fires on starvation; collector opt-in | REQ-107, C-11 |
Must-haves: aggregator pulls drift-events + remediation; watchdog fires on starvation; collector opt-in.
Phase P13 — orca ns subcommands + deprecation warnings (Wave 6)
REQs: REQ-068
Persona: lead-developer
Territory: internal/cli/ns.go
| Task | Description | REQ |
|---|---|---|
| P13-T1 | Full orca ns surface: list, create, delete, inspect, validate, inherit, set-constraint (per R-002 namespace-as-path) |
REQ-068 |
| P13-T2 | Depprecation warnings: orca daemon, orca cert (v0.8 mTLS path), .hcl jobspec → printed on use; --no-deprecation-warnings suppresses (REQ-068) |
REQ-068 |
| P13-T3 | Tests: all ns subcommands work; deprecation warnings fire on deprecated surface | REQ-068 |
Must-haves: full ns surface; deprecation warnings on deprecated surface.
Phase P14a — v0.8→v1.0 data migration + orca upgrade (Wave 7, gate C-07)
REQs: REQ-066; C-07; REQ-115
Persona: data-engineer + backend-engineer
Territory: internal/migration/, internal/cli/upgrade.go
Gate: C-07 (CA migration spec)
| Task | Description | REQ |
|---|---|---|
| P14a-T1 | internal/migration/ package: v0.8 flat layout → v0.9/v0.11 multi-namespace layout; schema migration (0006→next); CA migration per spec (C-07) |
REQ-066 |
| P14a-T2 | orca upgrade --to-vX: thin wrapper (C2=a) around install.sh + orca restore; handles R-017 Traefik binding cutover (:443 → 127.0.0.1:8443) for existing v0.9/v0.10 clusters (Q2=C) |
REQ-115 |
| P14a-T3 | Tests: v0.8 layout migrates to v0.11 layout; orca upgrade handles binding cutover; idempotent |
REQ-066, 115 |
Must-haves: v0.8 data migrates to v0.11; orca upgrade handles binding cutover; C-07 cleared.
Phase P14b — Daemon cutover + rotate-lead (Wave 7)
REQs: (existing daemon cutover) + REQ-114
Persona: backend-engineer + lead-developer
Territory: internal/cli/daemon.go, internal/cli/rotate_lead.go
| Task | Description | REQ |
|---|---|---|
| P14b-T1 | Daemon cutover: orca daemon becomes drain-and-stop (REQ-061 from P05); running-allocation adoption (orphaned allocs adopted by SSH-push path) |
existing |
| P14b-T2 | orca cluster rotate-lead: moves cluster CA + lead state to a new bare-Linux peer (R-003); workloads keep running (certs distributed); SSH key rotation; idempotent (Q2=C) |
REQ-114 |
| P14b-T3 | Tests: daemon cutover adopts running allocs; rotate-lead moves CA + workloads keep running | REQ-114 |
Must-haves: daemon cutover adopts running allocs; rotate-lead moves CA without downtime.
Phase P14c — Mixed-version tolerance (Wave 7)
REQs: REQ-065, REQ-086; C-13
Persona: backend-engineer
Territory: internal/transport/, internal/cli/
| Task | Description | REQ |
|---|---|---|
| P14c-T1 | Mixed-version tolerance: lead and peers can run different orca versions during upgrade window; no-orca-on-server enforcement (R-001) | REQ-065, REQ-086 |
| P14c-T2 | Tests: mixed-version cluster operates; orca-on-server detected + refused | REQ-065, 086 |
Must-haves: mixed-version tolerance during upgrade; R-001 enforced.
Phase P08 — Integration tests + drift-detection tests (Wave 8)
REQs: REQ-087
Persona: devops-engineer
Territory: tests/integration/, scripts/tests/
| Task | Description | REQ |
|---|---|---|
| P08-T1 | Expand hermetic test harness: multi-peer setup, txn apply, drift injection, remediation verification (REQ-087) | REQ-087 |
| P08-T2 | Drift-detection integration tests: auto-remediation success (edit Traefik config → detect ~10s → remediated); NFS fallback (NFS mount → Path units disabled → polling); rate-limit cooldown (repeated drift → cooldown blocks loop); secret exclusion (edit /etc/orca/credentials/* → no drift event) |
REQ-087 |
| P08-T3 | Tests pass in CoreCI integration pipeline (nft exclusively, D-224) |
REQ-087 |
Must-haves: integration tests cover drift detection; pass in CoreCI.
Phase P15 — README quickstart (Wave 8)
REQs: REQ-089
Persona: lead-developer + docs-engineer (phase-specific)
Territory: README.md
Framing: Q5=A (Nomad-inspired, OS-as-cluster; honest-trade-offs table from doc 3; Proxmox as one node type, not the identity)
| Task | Description | REQ |
|---|---|---|
| P15-T1 | README.md: status line (v0.11 complete, v1.0 UAT-gated); install example; subcommand table expanded to ALL v0.11 commands (incl. drift, nft, migrate, rotate-lead, upgrade, logs --all-nodes, doctor mTLS); honest-trade-offs table (doc 3 §4.6); Nomad-inspired framing (Q5=A) | REQ-089 |
| P15-T2 | Verify all cited CLI commands exist in internal/cli/ (C-22-style grounding gate) |
REQ-089 |
Must-haves: README subcommand table matches internal/cli/ exactly; honest-trade-offs table present; Nomad-inspired framing.
Phase P16 — Final review + ship + audit (Wave 8)
REQs: all (REQ-099..REQ-118 + existing v0.11 REQs) Persona: lead-developer Vertical slice: milestone complete → merged to main, tagged, released.
| Task | Description | REQ |
|---|---|---|
| P16-T1 | Code review across all phases; auto-apply P0 fixes, flag P1+ for post-hoc | all |
| P16-T2 | Audit: reconstruction test (git log matches .ciagent/), file discipline, branch hygiene, commit discipline |
all |
| P16-T3 | Milestone ship: merge phase/16 → milestone → main; tag v0.10.21 (= v0.11.0 milestone release); release with Linux binary asset; delete all milestone branches |
all |
| P16-T4 | Complete milestone: mark all v0.11 REQs complete in REQUIREMENTS.md; mark v0.11 complete in ROADMAP.md; clear checkpoint | all |
Must-haves: milestone merged to main; release carries Linux binary; all REQs marked complete; checkpoint cleared.
Risks
- R1: P10 sizing — P10 is the largest phase (txn plane + drift detection, 13 tasks). Mitigation: grill may split into P10a/P10b. The plan is structured so P10a (T1-T2, txn plane) and P10b (T3-T13, drift) are separable.
- R2: R-020 deadlock — hard-gate refusal could block all new txns if a peer is permanently drifted on a require_approval path. Mitigation:
--force+ per-ns scoping (Q4=A); documented in C-09 failure contract. - R3: Ingress default migration — existing v0.9/v0.10 clusters run Traefik on
:443. R-017 makes127.0.0.1:8443+ nft the default. Mitigation:orca upgrade(REQ-115, P14a) handles the binding cutover. - R4:
orcasystem user — creating a system user on every peer is a new operational requirement. Mitigation: peer-setup emitsuseradd -r orcaidempotently (REQ-111); documented in P10. - R5: Scope ceiling — v0.11 stays at 23 phases (no new phases), but P09/P10/P15.5 grow substantially. Mitigation: wave ordering isolates the largest work (Wave 5) so it can be split without affecting other waves.