diff --git a/.ciagent/CHECKPOINT.json b/.ciagent/CHECKPOINT.json index 410b1dc..c63440c 100644 --- a/.ciagent/CHECKPOINT.json +++ b/.ciagent/CHECKPOINT.json @@ -1,11 +1,11 @@ { "phase": 0, - "stage": "complete", - "milestone": "v0.5", - "milestone_slug": "distribution", - "phase_role": "final", + "stage": "specify", + "milestone": "v0.6", + "milestone_slug": "node-bootstrap-proxmox", + "phase_role": "pre_execution", "attempts": 0, - "updated_at": "2026-08-03T19:15:00Z", - "milestone_complete": true, + "updated_at": "2026-08-03T20:00:00Z", + "milestone_complete": false, "next_milestone": null -} +} \ No newline at end of file diff --git a/.ciagent/PROJECT.md b/.ciagent/PROJECT.md index 6249066..c44effa 100644 --- a/.ciagent/PROJECT.md +++ b/.ciagent/PROJECT.md @@ -191,3 +191,54 @@ edit coreci/orca --private=false` so that `install.sh` can pull release binaries unauthenticated (REQ-045). This is an operational step performed during the P0 ship, verified by an unauth `curl` against the releases API. + +## v0.6 Scope Summary — Node Bootstrap & Proxmox + +v0.6 is a 3-execution-phase milestone that turns `orca init` from a +bare `mkdir` into a full single-node cluster bootstrap, and adds +Proxmox 8 & 9 as a first-class remote node type joined over SSH with +least-privilege role delegation. The engine functionality from +v0.1–v0.5 is unchanged; this milestone is about **bootstrap +ergonomics** and **heterogeneous node support**: + +- **P01 — `orca init` full bootstrap.** A single `orca init` call now: + (a) creates the namespace dir (`~/.orca` or `/root/.orca` with + `--system`); (b) runs all DB migrations including the new 0006 + (`nodes.kind`, `nodes.os` — backward-compatible nullable columns); + (c) bootstraps the internal CA via `security.CAInit` if `ca.crt` is + absent; (d) generates the server cert via `security.GenerateCSR` + + `ca.SignCSR` if `server.crt` is absent; (e) auto-detects the local + OS via `/etc/os-release` `ID=` field (ubuntu/debian/alpine); (f) + registers a `localhost` node with `kind=localhost`, `os=`, + `addr=localhost:8443` if no localhost node exists yet. After + `orca init`, `orca doctor` MUST pass with zero FAILs. Idempotent: + re-running `orca init` is a no-op (or refresh) for already-provisioned + artifacts. Covers REQ-047, REQ-048, REQ-049. +- **P02 — Proxmox SSH join.** `orca node join --type proxmox --host + --user root --password ` (password via flag or + `$ORCA_PROXMOX_PASSWORD`, **never persisted**) bootstraps a remote + Proxmox 8/9 host via `golang.org/x/crypto/ssh` (new direct dep). + Steps: (1) SSH password-auth; (2) generate or load orca's SSH + keypair (`~/.orca/orca_ssh_key` / `.pub`, 0600/0644); (3) deploy + pubkey to remote `~orca/.ssh/authorized_keys`; (4) create `orca` + user (config-overridable name via `--proxmox-user`, default `orca`); + (5) create PVE custom role `OrcaOperator` (config-overridable via + `--proxmox-role`) with privileges `VM.Audit`, + `Datastore.AllocateSpace`, `SDN.Use`; (6) assign role to `orca` + user on `/`; (7) drop `/etc/sudoers.d/orca` allowlist (`pct`, `qm`, + `pvesh`, `apt-get`, `dpkg` — no shell-escape commands); (8) record + node row `kind=proxmox`, `os=pve`, audit log. Idempotent re-run. + Covers REQ-050, REQ-051. +- **P03 — `doctor os` + `doctor proxmox`.** Extends `orca doctor` + with two new checks: `doctor os` re-runs `/etc/os-release` detection + and verifies it matches the stored localhost node row's `os` field + (drift = WARN); `doctor proxmox` iterates `kind=proxmox` nodes and + SSH-probes each with `pveversion` / `pvecmd status` (3s timeout per + peer per D-038 pattern), reporting PASS/WARN/FAIL per node. All + bootstrap + join actions emit structured audit-log entries. Covers + REQ-052. +- **P04 — Final review + ship + audit.** Milestone release. + +The vision ("minimalist, offline-first, CLI-first orchestration +engine") is unchanged. v0.6 is a bootstrap-ergonomics + heterogeneous- +nodes milestone, not a direction change. diff --git a/.ciagent/REQUIREMENTS.md b/.ciagent/REQUIREMENTS.md index 537e29a..9034a7a 100644 --- a/.ciagent/REQUIREMENTS.md +++ b/.ciagent/REQUIREMENTS.md @@ -99,3 +99,14 @@ Docker image published to Gitea container registry (REQ-046). - **P2** (v0.4.3): `install.sh` 1-liner + in-place update (REQ-043/044) + README quickstart (REQ-016). - **P3** (v0.4.4): Docker release — distroless image + Gitea container registry (REQ-046). - **P4** (v0.4.5): final review + audit + milestone release. + +## v0.6 Requirements — Node Bootstrap & Proxmox + +| ID | Requirement | Priority | Phase | Status | +|----|-------------|----------|-------|--------| +| REQ-047 | `orca init` auto-provisions CA + server cert + DB migrations + localhost node (idempotent; safe re-run) | High | **v0.6 P1** | Pending | +| REQ-048 | `orca init` registers a default `localhost` node with auto-detected OS via `/etc/os-release ID` | High | **v0.6 P1** | Pending | +| REQ-049 | Node schema extension: `nodes.kind` (localhost\|linux\|proxmox) + `nodes.os` columns (migration 0006, backward-compatible) | High | **v0.6 P1** | Pending | +| REQ-050 | `orca node join --type proxmox` SSH bootstrap via `golang.org/x/crypto/ssh` (new direct dep); password auth, deploy orca pubkey, create `orca` user (config-overridable), assign PVE role, drop sudoers allowlist; idempotent | High | **v0.6 P2** | Pending | +| REQ-051 | Proxmox least-privilege `OrcaOperator` PVE role (VM.Audit, Datastore.AllocateSpace, SDN.Use) + `orca` user + `/etc/sudoers.d/orca` allowlist (pct, qm, pvesh, apt-get, dpkg); config-overridable user/role names | High | **v0.6 P2** | Pending | +| REQ-052 | `orca doctor` extensions: `doctor os` (verify localhost OS detection matches stored node row) + `doctor proxmox` (SSH-probe each `kind=proxmox` node with `pveversion`/`pvecmd status`, 3s timeout, PASS/WARN/FAIL); audit log all bootstrap + join actions | Medium | **v0.6 P3** | Pending | diff --git a/.ciagent/ROADMAP.md b/.ciagent/ROADMAP.md index e1fb87a..01267fd 100644 --- a/.ciagent/ROADMAP.md +++ b/.ciagent/ROADMAP.md @@ -88,3 +88,25 @@ verified HTTP 200. **Milestone tag**: `v0.4.5` (final phase patch = milestone release per feature-milestone promotion rule). Per-phase tags: `v0.4.1`…`v0.4.5`. + +## Milestone v0.6: Node Bootstrap & Proxmox + +Scope: make `orca init` produce a fully working single-node cluster +(CA + server cert + DB + localhost node registered with auto-detected +OS), and add Proxmox 8 & 9 as a first-class remote node type joined +over SSH with least-privilege role delegation. + +- [ ] Phase 0: Pre-execution (specify → clarify → research → plan → grill) — tag `v0.5.0` +- [ ] Phase 1: `orca init` full bootstrap + localhost node + schema 0006 (REQ-047, REQ-048, REQ-049) — tag `v0.5.1` +- [ ] Phase 2: Proxmox SSH join + OrcaOperator role + sudoers allowlist (REQ-050, REQ-051) — tag `v0.5.2` +- [ ] Phase 3: `doctor os` + `doctor proxmox` SSH probe + audit logging (REQ-052) — tag `v0.5.3` +- [ ] Phase 4: Final review + ship + audit (milestone release) — tag `v0.5.4` + +**Milestone type**: feature (P1/P2/P3 ship `feat` phases). +**Milestone tag**: `v0.5.4` (final phase patch = milestone release per +feature-milestone promotion rule). Per-phase tags: `v0.5.0`…`v0.5.4`. + +Tags run on the previous minor's patch line (v0.5.x) per +branch-strategy.md. The milestone branch label uses the milestone +number (`milestone/v0.6-node-bootstrap-proxmox`); no separate minor +tag is created. diff --git a/.ciagent/config.json b/.ciagent/config.json index db70785..e382bb2 100644 --- a/.ciagent/config.json +++ b/.ciagent/config.json @@ -5,7 +5,7 @@ "slug": "orca", "name": "Orca", "description": "Offline/CLI-first orchestration engine (Orca) — Nomad-inspired, far simpler than Kubernetes", - "milestone": "v0.5", + "milestone": "v0.6", "phase": 0, "milestone_type": "feature", "default_branch": "main",