docs(P00): specify v0.9 re-architecture milestone — PRD adopted, REQ-061..090, supersession table
Adopts the v0.9/v1.0 PRD (.ciagent/PRD_v0.9.md) that supersedes the shipped v0.1-v0.8 architecture. The re-architecture is justified by a six-part evidence basis recorded in the PROJECT.md Supersession Table: operational daemon failure, external step-ca mandate, multi-tenancy requirement, WASM workload requirement, SSH-push deployment target, and vision correction. Appends 30 net-new requirements (REQ-061..REQ-090) to REQUIREMENTS.md, the v0.9 (13 phases) + v1.0 (19 phases) reordered plan to ROADMAP.md, the AD-series supersession table to PROJECT.md + ARCHITECTURE.md, and reactivates security-engineer + network-engineer + devops-engineer personas (implements grill C-05). ---ci--- project: orca phase: 0 milestone: v0.9 status: specify ---/ci---
This commit is contained in:
@@ -638,3 +638,83 @@ heredoc).
|
||||
| AD-019 | `orca@pam` realm (not `orca@pve`) | SSH creates a Linux system user; PAM realm maps it to PVE RBAC without a separate PVE password. `@pve` requires interactive password prompt over non-PTY SSH (hangs). |
|
||||
| AD-020 | Exclude `pvesh` from sudoers; NOEXEC on `pct`/`qm` | `pvesh` can trigger API execute endpoint bypassing NOEXEC. `pct`/`qm` are Perl scripts via dynamically-linked perl → NOEXEC effective. `apt-get`/`dpkg` need exec for maintainer scripts → no NOEXEC. |
|
||||
| AD-021 | TOFU host-key via `knownhosts.New` | Avoids deprecated `ssh.InsecureIgnoreHostKey`. Capture-on-first-connect, verify-on-subsequent. Fail closed on mismatch (operator runs key-reset). |
|
||||
|
||||
---
|
||||
|
||||
# v0.9 Architecture (Supersedes v0.8)
|
||||
|
||||
> **⚠️ v0.9 DIRECTION CHANGE**: This section supersedes the v0.1–v0.8
|
||||
> architecture described above. The re-architecture is justified by a
|
||||
> six-part evidence basis recorded in `PROJECT.md` (Supersession Table).
|
||||
> The v0.8 sections above are retained for historical context but are
|
||||
> **deprecated**. The 16 load-bearing rules (R-001…R-016) in
|
||||
> `PRD_v0.9.md` are now the canonical invariants.
|
||||
|
||||
## Superseded Decisions (AD-series reversals)
|
||||
|
||||
| Old decision | Was | Superseded by | Evidence basis |
|
||||
|---|---|---|---|
|
||||
| AD-010 (line 463 above) | step-ca/cfssl/vault-pki "too heavyweight" | **D-101** (step-ca) | External PKI mandate (override ground 2) |
|
||||
| SPIFFE rejection (line 94, PROJECT.md) | internal CA chosen over SPIFFE | **D-068** (SPIFFE SVIDs) | Multi-tenancy requires per-workload identity (override ground 3) |
|
||||
| No-container-runtime (line 477 above) | explicit anti-pattern | **D-088** (5 runtimes; wasmtime primary) | WASM is the workload profile (override ground 4) |
|
||||
| No-multi-tenancy (line 478 above) | explicit anti-pattern | **D-158 / R-002** (multi-namespace) | Hard multi-tenant product req (override ground 3) |
|
||||
| AD-007 (HCL canonical) | HCL for jobspec | **R-013 / R-014** (Markdown canonical; HCL legacy) | PRD §8 operator-facing format |
|
||||
| Daemon-on-every-node | `orca daemon` on all peers | **R-001** (no orca binary on any server) | Daemon operationally failing + SSH-push only viable target (override grounds 1 + 5) |
|
||||
|
||||
## The Five-Layer CLI (v0.9)
|
||||
|
||||
The `orca` binary is one Go program, structured internally as five layers:
|
||||
|
||||
1. **CLI subcommand tree** (cobra) — `internal/cli/`
|
||||
2. **Jobspec + config parsers** — `internal/spec/` (Markdown frontmatter
|
||||
canonical, `.md`/`.yaml`/`.hcl` dispatcher per R-013/R-014)
|
||||
3. **Cluster-state store** — `internal/store/` + `internal/paths/`
|
||||
(per-namespace modernc/sqlite DBs + CLI-side `orca_cache` DB per R-002/R-008)
|
||||
4. **Server-side config emitters** — `internal/emitter/` (pure string
|
||||
templates → systemd units, Traefik YAML, sudoers, syncthing config;
|
||||
SCP via SSH per R-001)
|
||||
5. **Workflow orchestrators** — `internal/orch/` (compose SSH + local FS
|
||||
writes into multi-step commands)
|
||||
|
||||
## The Server Side (R-001 — no Orca binary on any server)
|
||||
|
||||
Servers hold only: rendered config in `/etc/orca/actual/<txn-id>/`,
|
||||
systemd units, Traefik dynamic config, sudoers, sshd_config snippets,
|
||||
`step-ca`/`traefik`/`syncthing`/`podman`/`wasmtime`/`age`/`auditd`
|
||||
(installed via apt), and bash scripts in `scripts/` (orca-pull.sh,
|
||||
orca-drift.sh, orca-collect.sh, orca-aggregate.sh, orca-apply-render.sh,
|
||||
orca-verify-render.sh, orca-rollback-render.sh, orca-cleanup-credentials.sh).
|
||||
Nothing on any server is "Orca software" — Orca is the CLI plus a tree of
|
||||
files.
|
||||
|
||||
## Multi-namespace Layout (R-002)
|
||||
|
||||
```
|
||||
$ORCA_HOME/
|
||||
├── cluster/ # cluster-wide (NOT a workload namespace)
|
||||
│ ├── ca.crt, ca.key # step-ca root (R-006, D-101)
|
||||
│ ├── master.key # AES-256-GCM root (R-011, mode 0600)
|
||||
│ ├── config.md # Markdown frontmatter (R-014)
|
||||
│ ├── peers/<host>/
|
||||
│ ├── pve/<endpoint>/
|
||||
│ ├── txns/{desired,applied,refused}/<txn-id>/
|
||||
│ ├── txn.sqlite
|
||||
│ └── state/
|
||||
├── _defaults/ # implicit root namespace (always exists)
|
||||
│ ├── ns.md
|
||||
│ ├── .env, .env.secrets
|
||||
│ ├── db/orca.db
|
||||
│ ├── jobs/, alloc/
|
||||
│ └── syncthing/
|
||||
├── <explicit-namespace>/ # operator-created
|
||||
└── orca_cache.db # CLI-side cache (R-008)
|
||||
```
|
||||
|
||||
## Execution gates (from GRILL_v0.9.md)
|
||||
|
||||
The 19 binding conditions (C-01..C-19) and 10 phase challenges
|
||||
(PC-01..PC-10) gate specific phases. See `GRILL_v0.9.md` for the full
|
||||
list. Key gates: C-01 (wasmtime/CGO before P07b), C-07 (CA migration
|
||||
spec before P14a), C-08 (SPIFFE mint spike before P02), C-09
|
||||
(orida-pull.sh failure contract before P10), C-19 (threat model before
|
||||
P15.5).
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"phase": 4,
|
||||
"stage": "complete",
|
||||
"milestone": "v0.8",
|
||||
"milestone_slug": "coverage-trust-hardening",
|
||||
"phase_role": "final",
|
||||
"phase": 0,
|
||||
"stage": "specify",
|
||||
"milestone": "v0.9",
|
||||
"milestone_slug": "rearchitecture",
|
||||
"phase_role": "pre_execution",
|
||||
"attempts": 0,
|
||||
"updated_at": "2026-08-04T01:30:00Z",
|
||||
"milestone_complete": true,
|
||||
"updated_at": "2026-08-05T02:00:00Z",
|
||||
"milestone_complete": false,
|
||||
"next_milestone": null
|
||||
}
|
||||
+54
-41
@@ -3,57 +3,70 @@ active:
|
||||
- lead-developer
|
||||
- backend-engineer
|
||||
- data-engineer
|
||||
- security-engineer
|
||||
- network-engineer
|
||||
- devops-engineer
|
||||
deactivated:
|
||||
- cli-engineer
|
||||
- security-engineer
|
||||
- devops-engineer
|
||||
- network-engineer
|
||||
- frontend-engineer
|
||||
phase_specific: []
|
||||
reason: |
|
||||
Orca v0.8 is an NFR coverage & trust-hardening milestone. The work is
|
||||
test coverage uplift across 9 packages (P01), SSH trust-surface
|
||||
hardening in the existing proxmox + cli/node + security packages (P02),
|
||||
and a requirements-hygiene Go program + Makefile target (P03). No
|
||||
schema changes, no new security architecture, no packaging/distribution,
|
||||
no UI.
|
||||
Orca v0.9 is the first DIRECTION-CHANGE milestone in the project's
|
||||
history. It supersedes the shipped v0.1–v0.8 architecture per the adopted
|
||||
PRD (.ciagent/PRD_v0.9.md). The re-architecture deprecates the daemon/
|
||||
transport/internal-CA/HCL/single-namespace stack and builds a CLI-only/
|
||||
SSH-push/step-ca/Markdown-frontmatter/multi-namespace stack plus 8
|
||||
net-new subsystems. The user overrode the grill's Re-architecture
|
||||
Justification REPLAN with a six-part evidence basis (see PROJECT.md
|
||||
Supersession Table). The ci-griller's 19 binding conditions (C-01..C-19)
|
||||
and 10 phase challenges (PC-01..PC-10) are adopted as execution gates
|
||||
(see GRILL_v0.9.md).
|
||||
|
||||
Roster changes vs v0.7:
|
||||
- lead-developer: RETAINED — owns cmd/orca smoke test, internal/cli
|
||||
coverage (cert/doctor/audit/status/version subcommands), and the
|
||||
cmd/verify-reqs Go program (coordination + glue-code territory).
|
||||
- backend-engineer: RETAINED — owns internal/transport + internal/engine
|
||||
tests (httptest.NewTLSServer, LocalExecutor stubs, PeerRegistry) and
|
||||
the SSH trust-surface in internal/proxmox/bootstrap.go (pinned
|
||||
host-key callback, TOFU capture fix, sessionRunner seam) plus
|
||||
internal/cli/node.go (--host-key-fingerprint flag, key-reset
|
||||
subcommand). Frameworks updated: connectrpc REMOVED (not in go.mod
|
||||
per AD-014), golang.org/x/crypto/ssh ADDED (direct dep since v0.6).
|
||||
- data-engineer: RETAINED — owns internal/store tests (cert_repo_test.go
|
||||
gap + coverage uplift), internal/audit tests (sqlite-backed
|
||||
audit_log asserts), internal/certpaths tests (path-join asserts),
|
||||
and internal/jobspec tests (golden HCL fixtures). Frameworks
|
||||
updated: modernc/sqlite + iter (matches actual go.mod).
|
||||
- security-engineer: remains DEACTIVATED — v0.8 refines the existing
|
||||
proxmox SSH trust surface (pinned callback, key-reset) but does NOT
|
||||
add new security architecture. The trust work is backend-engineer
|
||||
territory (it's SSH dialer + known_hosts file manipulation, not
|
||||
X.509/CA/crypto code).
|
||||
- cli-engineer: remains DEACTIVATED — merged into lead-developer
|
||||
(cli coverage is test-only; --host-key-fingerprint and key-reset
|
||||
are 1-flag + 1-subcommand additions to the existing node.go).
|
||||
- devops-engineer: remains DEACTIVATED — verify-reqs is a Go program
|
||||
(lead-developer territory), not a CI/packaging change. The
|
||||
.coreci.yml edit is a 3-line validate-pipeline hook.
|
||||
- network-engineer: remains DEACTIVATED — no transport/mTLS surface
|
||||
change (transport coverage is test-only on the existing mTLS layer).
|
||||
- frontend-engineer: remains DEACTIVATED — no web UI (unchanged
|
||||
from v0.1 onward).
|
||||
Roster changes vs v0.8 (implements grill C-05):
|
||||
- lead-developer: RETAINED — owns the CLI subcommand tree, deprecation
|
||||
sweep (P00), path resolver (P0a1), parser dispatch (P0b), emitter
|
||||
interface (P0c), and milestone coordination.
|
||||
- backend-engineer: RETAINED — owns SSH-push transport (P01), runtime
|
||||
abstraction (P07a/b/c), transaction bundle (P10 design), step-ca
|
||||
integration, secrets crypto. Frameworks updated: golang.org/x/crypto/ssh
|
||||
(existing), golang.org/x/crypto/ssh/knownhosts (existing); pending
|
||||
deps: bytecodealliance/wasmtime-go (C-01 gate), smallstep/cli (I-B-004).
|
||||
- data-engineer: RETAINED — owns per-namespace DB schema split (P0a1,
|
||||
REQ-071), CLI cache DB (R-008), namespace inheritance resolver state
|
||||
(P0a2). Frameworks: modernc/sqlite.
|
||||
- security-engineer: REACTIVATED — owns step-ca provisioning (REQ-076),
|
||||
master.key + AES-256-GCM crypto (REQ-080, C-19 threat model), SPIFFE
|
||||
SVID minting (C-08 spike), SSH-push blast-radius review, Traefik edge,
|
||||
.env.secrets threat model. The re-architecture reverses AD-010
|
||||
(step-ca rejection) and the SPIFFE rejection at PROJECT.md:94; both
|
||||
reversals are justified in the Supersession Table.
|
||||
- network-engineer: REACTIVATED — owns socket-based service exposure
|
||||
(R-007, P08), Syncthing P2P ports (P09), Traefik routing + dynamic
|
||||
config atomicity (P02, C-10). The transport layer moves from mTLS
|
||||
HTTP daemon-to-daemon to SSH CLI-to-server; network-engineer reviews
|
||||
the new trust surface.
|
||||
- devops-engineer: REACTIVATED — owns bash scripts (scripts/orca-*.sh,
|
||||
C-15..C-18: bats/shellcheck/shfmt gate, render-format contract,
|
||||
slog-syslog), systemd timers (orca-pull/drift/aggregate, C-09 failure
|
||||
contract, C-11 watchdog), hermetic test infra (P00 bootstrap, P08
|
||||
expand, REQ-087).
|
||||
- cli-engineer: remains DEACTIVATED — CLI surface growth is owned by
|
||||
lead-developer (cobra subcommands) + backend-engineer (transport);
|
||||
reactivation optional if CLI subcommand surface exceeds lead-developer
|
||||
bandwidth.
|
||||
- frontend-engineer: remains DEACTIVATED — no web UI (unchanged from
|
||||
v0.1 onward; R-014 makes Markdown canonical, not a web UI).
|
||||
---
|
||||
|
||||
# Personas: Orca
|
||||
|
||||
## v0.8 persona assessment
|
||||
## v0.9 persona assessment (supersedes v0.8)
|
||||
|
||||
The v0.9 re-architecture introduces 5 new external apt dependencies (step-ca,
|
||||
Traefik, Syncthing, wasmtime, podman), 8 net-new subsystems, and deprecates
|
||||
~10k lines of shipped daemon/transport/CA/HCL code. The active roster grows
|
||||
from 3 to 6 to cover the new attack surfaces and deployment model. Territory
|
||||
enforcement remains in `warn` mode per config.json.
|
||||
|
||||
### lead-developer
|
||||
- **Domain**: coordination
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
# Orca — Comprehensive Product Requirements Document (v0.9/v1.0)
|
||||
|
||||
**Audience:** Operators, AI agents, downstream tooling authors
|
||||
|
||||
> This PRD SUPERSEDES the shipped v0.1–v0.8 architecture. The v0.9 and v1.0
|
||||
> milestones implement a re-architecture whose load-bearing rules (R-001…R-016)
|
||||
> and decisions (D-068…D-206) replace or demote several earlier documented
|
||||
> decisions. See §22 decision-trace and the Supersession Table in
|
||||
> `ARCHITECTURE.md` for the recorded reversals and their evidence basis.
|
||||
|
||||
## Status
|
||||
|
||||
| Item | Status |
|
||||
|---|---|
|
||||
| Spec lock-in | ✅ R-001…R-016 + D-001…D-206 settled |
|
||||
| v0.1–v0.8 implementation | ✅ shipped (REQ-001..060, D-001..D-047) |
|
||||
| v0.9 implementation | ⬜ Phase 0 pre-execution (this file is the spec input) |
|
||||
| v1.0 implementation | ⬜ planning (post-PRD) |
|
||||
| v1.x multi-host state | ⬜ parked (post-v1.0) |
|
||||
| v2.x full Nomad-HCL | ⬜ parked (post-v1.x) |
|
||||
|
||||
## Override justification (recorded for the grill supersession)
|
||||
|
||||
The v0.9/v1.0 re-architecture is justified on six independent grounds rather
|
||||
than preference. Each reverses a prior documented decision; the new evidence
|
||||
basis is recorded with the reversal in the Supersession Table:
|
||||
|
||||
1. **The v0.8 daemon model is operationally failing** in the target environment
|
||||
— R-001 ("no orca binary on any server") is a response to measured pain, not
|
||||
preference.
|
||||
2. **step-ca is externally mandated** (D-101) — the operator environment requires
|
||||
an external CA; AD-010's "too heavyweight" rationale is no longer operative.
|
||||
3. **Multi-tenancy is a hard product requirement** (R-002) — real multi-tenant
|
||||
use cases cannot be served by the single-namespace layout; the
|
||||
"no multi-tenancy" anti-pattern is obsolete.
|
||||
4. **WASM is a hard workload requirement** (D-088) — workloads are WASM, not
|
||||
processes; `os/exec` is insufficient; the "no container runtime" anti-pattern
|
||||
is reversed.
|
||||
5. **SSH-push is the only viable deployment target** for the operator's
|
||||
bare-Linux/Proxmox environment — installing/maintaining an orca daemon on
|
||||
every peer is operationally infeasible.
|
||||
6. **Simplicity/vision correction** — the v0.1-v0.8 daemon model was a wrong
|
||||
turn against the original CLI-first vision; the re-architecture corrects the
|
||||
vision.
|
||||
|
||||
## Canonical references
|
||||
|
||||
The full PRD text was provided by the operator and adopted wholesale. The
|
||||
load-bearing rules (R-001…R-016), the concept model (§4), the architecture
|
||||
(§5), the milestone plan (§23), and the decision trace (§22) are reproduced
|
||||
in the operator's original document. This file is the auditable pointer to
|
||||
that source; the substantive planning artifacts live in:
|
||||
|
||||
- `IDEATION_v0.9.md` — 30 ideas (REQ-061..REQ-090), three tiers
|
||||
- `GRILL_v0.9.md` — 9-axis adversarial review, 19 binding conditions, 10 phase challenges
|
||||
- `REQUIREMENTS.md` — REQ-061..REQ-090 appended
|
||||
- `ROADMAP.md` — v0.9 (13 phases) + v1.0 (19 phases) appended
|
||||
- `PERSONAS.md` — security/network/devops reactivated
|
||||
- `ARCHITECTURE.md` — v0.9 banners + Supersession Table
|
||||
|
||||
## The 16 load-bearing rules (invariants)
|
||||
|
||||
| ID | Rule |
|
||||
|---|---|
|
||||
| R-001 | No Orca Go binary runs on any server. The `orca` CLI on the operator's host is the only Orca software. Servers run Linux + systemd + apt-managed packages + config files written by the CLI. |
|
||||
| R-002 | Filesystem paths are namespaces. `ORCA_HOME` hosts many namespaces; each is a dir with `db/`, `.env`, `.env.secrets`, `jobs/`, `alloc/`, `ns.md`. `_defaults/` always exists. No `namespace` column in SQLite. |
|
||||
| R-003 | Cluster lead is always bare Linux; Proxmox can never be lead. |
|
||||
| R-004 | Workload migration Linux↔Proxmox supported; runtime can change at migration; SPIFFE identity preserved. |
|
||||
| R-005 | Storage replication enables migration; a Service's `count` replicas share one `runtime {}` block. |
|
||||
| R-006 | mTLS on by default; cluster CA = step-ca; Traefik + `LoadCredential=` are load-bearing. |
|
||||
| R-007 | Sockets by default (`/run/orca/alloc-<id>/port-<name>.sock`); `127.0.0.1` opt-in. |
|
||||
| R-008 | CLI results cached locally with per-class TTLs (`orca_cache` SQLite). |
|
||||
| R-009 | CLI host SPOF mitigated by external shared state in v1.x; v1.0 ships the abstractions + cache layer. |
|
||||
| R-010 | Control plane updates are transactional (ArgoCD-style desired-state/lead-applier). |
|
||||
| R-011 | Each namespace has `.env` (plaintext) and `.env.secrets` (AES-256-GCM, per-line nonce); master key per `ORCA_HOME` at `cluster/master.key`. |
|
||||
| R-012 | Workload kinds are `Job`, `Service`, `DaemonSet`; schema-separated by `kind:` in frontmatter. |
|
||||
| R-013 | Jobspec format is Markdown with YAML frontmatter (`.md` preferred); `.yaml` and `.hcl` accepted by parser dispatcher. |
|
||||
| R-014 | All user-facing config is Markdown with YAML frontmatter; body preserved verbatim. |
|
||||
| R-015 | Body of every `.md` config file is preserved verbatim and surfaced in `inspect`, `history`, diffs. |
|
||||
| R-016 | `.env` and `.env.secrets` are exempt from R-014 — standard dotenv format retained. |
|
||||
|
||||
## Milestone summary (§23, reordered per grill PC-01..PC-10)
|
||||
|
||||
### v0.9 — Workloads + Re-architecture Foundation (13 phases)
|
||||
P00 (deprecation sweep + migration-ordering + txn-design spike + test-infra bootstrap + persona reactivation + doc banners), P0a1 (path resolver + config demotion), P0a2 (namespace CRUD + inheritance), P0b (Markdown jobspec parser + fuzz), P0c (schemas + emitter interface), P01 (SSH-push transport + host-path volumes), P02 (service + Traefik emitter), P03 (update stanza), P04 (lifecycle hooks), P05 (constraints + CLI-side scheduler), P06 (task groups), P07a/P07b/P07c (process+podman / wasmtime [C-01 gated] / pve-vm+ct runtimes), P08 (sockets), P09 (Syncthing [C-02 gated]), P10 (lead rules + migration), P0X (ship + audit).
|
||||
|
||||
### v1.0 — Production Hardening (19 phases)
|
||||
P00 (CLI cache), P01 (metrics), P01.5 (SPIFFE spike [C-08 gated]), P02 (ACL), P03 (secrets), P04 (backup/restore), P05 (drain + daemon drain-and-stop), P06 (alloc history), P07 (recovery), P08 (integration tests), P09 (collector+aggregator), P10 (transactional plane [C-09 gated]), P11 (job lint), P12 (job verify), P13 (ns subcommands), P14a/P14b/P14c (data / daemon cutover / mixed-version tolerance), P15 (README), P15.5 (threat model [C-19 gated]), P16 (final review + ship — v1.0.0 release).
|
||||
|
||||
See `ROADMAP.md` for the full reordered plan and `GRILL_v0.9.md` for the 19
|
||||
binding conditions (C-01..C-19) and 10 phase challenges (PC-01..PC-10) that
|
||||
gate specific phases.
|
||||
@@ -377,3 +377,70 @@ within the `clarify_budget` (10):
|
||||
| D-045 | `--host-key-fingerprint` format — raw hex, `sha256:`-prefixed, or OpenSSH `SHA256:base64`? | **OpenSSH `SHA256:base64` (the format `ssh-keyscan -E sha256 -D -` emits and operators expect)** | Matches the fingerprint format operators already see from `ssh-keyscan` and `orca node join`'s own `Result.HostKeyFingerprint` output. Accept only `SHA256:`-prefixed base64; reject raw hex with a clear error. Internally decode base64 → compare against `ssh.PublicKey` Marshal + sha256. | 0.88 |
|
||||
| D-046 | Does `orca node key-reset <node>` also revoke the orca pubkey on the remote host, or only clear the local `known_hosts` entry? | **Local `known_hosts` entry only** | Revoking the remote authorized_keys entry would orphan a working node (next dispatch would fail auth). `key-reset` is the local "forget this host's key" operation (mirrors `ssh-keygen -R host`); re-establishing trust is a separate `orca node join` re-run. Audit-log the reset with `actor`, `node`, `event=node.key_reset`. | 0.90 |
|
||||
| D-047 | Coverage target for P01 — 70% floor or higher? | **70% floor for the 6 under-50% packages; 50% floor for the 3 zero-test packages (`internal/audit`, `internal/certpaths`, `cmd/orca`) as a first-toe-hold** | 70% across the board for the already-tested packages matches D-042's "70% target for new packages" and is achievable without heroic mock effort. For the zero-test packages, going 0→50% is the realistic single-phase step (0→70% risks a coverage rathole on `cmd/orca` which is glue code); a future milestone can lift them to 70%. | 0.82 |
|
||||
|
||||
---
|
||||
|
||||
# v0.9/v1.0 — Re-architecture Scope Summary (Supersedes v0.1–v0.8 architecture)
|
||||
|
||||
v0.9 is the first DIRECTION-CHANGE milestone in the project's history.
|
||||
It supersedes the shipped v0.1–v0.8 architecture per the adopted PRD
|
||||
(`.ciagent/PRD_v0.9.md`). The re-architecture deprecates the daemon/
|
||||
transport/internal-CA/HCL/single-namespace stack and builds a CLI-only/
|
||||
SSH-push/step-ca/Markdown-frontmatter/multi-namespace stack plus 8
|
||||
net-new subsystems.
|
||||
|
||||
## Override Justification (Re-architecture Justification axis)
|
||||
|
||||
The ci-griller returned REPLAN (0.70) on the Re-architecture Justification
|
||||
axis, noting the PRD reverses 6 documented decisions without new evidence
|
||||
and that the incremental-additive path was not evaluated. The user reviewed
|
||||
the fork and overrode the *direction* with a six-part evidence basis. The
|
||||
override is recorded verbatim below; each part addresses a reversal that
|
||||
the grill flagged as unjustified.
|
||||
|
||||
1. **The v0.8 daemon model is operationally failing** in the target
|
||||
environment — R-001 ("no orca binary on any server") is a response to
|
||||
measured pain, not preference.
|
||||
2. **step-ca is externally mandated** (D-101) — the operator environment
|
||||
requires an external CA; AD-010's "too heavyweight" rationale is no
|
||||
longer operative.
|
||||
3. **Multi-tenancy is a hard product requirement** (R-002) — real
|
||||
multi-tenant use cases cannot be served by the single-namespace layout;
|
||||
the "no multi-tenancy" anti-pattern is obsolete.
|
||||
4. **WASM is a hard workload requirement** (D-088) — workloads are WASM, not
|
||||
processes; `os/exec` is insufficient; the "no container runtime"
|
||||
anti-pattern is reversed.
|
||||
5. **SSH-push is the only viable deployment target** for the operator's
|
||||
bare-Linux/Proxmox environment — installing/maintaining an orca daemon
|
||||
on every peer is operationally infeasible.
|
||||
6. **Simplicity/vision correction** — the v0.1-v0.8 daemon model was a
|
||||
wrong turn against the original CLI-first vision; the re-architecture
|
||||
corrects the vision.
|
||||
|
||||
## Supersession Table (AD-series reversals, recorded per grill PC-09)
|
||||
|
||||
| Old decision | Was | Superseded by | Evidence basis |
|
||||
|---|---|---|---|
|
||||
| AD-010 (ARCHITECTURE.md:463) | step-ca/cfssl/vault-pki "too heavyweight" | **D-101** (step-ca) | Override ground 2 (external mandate) |
|
||||
| SPIFFE rejection (PROJECT.md:94) | internal CA chosen over SPIFFE | **D-068** (SPIFFE SVIDs) | Override ground 3 (multi-tenancy requires per-workload identity) |
|
||||
| No-container-runtime (ARCHITECTURE.md:477) | explicit anti-pattern | **D-088** (5 runtimes; wasmtime primary) | Override ground 4 (WASM is the workload profile) |
|
||||
| No-multi-tenancy (ARCHITECTURE.md:478) | explicit anti-pattern | **D-158 / R-002** (many namespaces under ORCA_HOME) | Override ground 3 (hard multi-tenant product req) |
|
||||
| AD-007 (HCL canonical) | HCL for jobspec | **R-013 / R-014** (Markdown canonical; HCL legacy) | PRD §8 (Markdown + body preservation is the operator-facing format) |
|
||||
| Daemon-on-every-node | `orca daemon` on all peers | **R-001** (no orca binary on any server) | Override grounds 1 + 5 (daemon failing; SSH-push only viable target) |
|
||||
|
||||
The 19 binding conditions (C-01..C-19) and 10 phase challenges
|
||||
(PC-01..PC-10) from `GRILL_v0.9.md` are adopted as execution gates.
|
||||
The 30 net-new requirements (REQ-061..REQ-090) from `IDEATION_v0.9.md`
|
||||
are recorded in `REQUIREMENTS.md`. The reordered phase plan is in
|
||||
`ROADMAP.md`.
|
||||
|
||||
## v0.9 Clarified Decisions (D-series, full autonomy — Phase 0 pre-execution)
|
||||
|
||||
| ID | Question | Decision | Rationale | Confidence |
|
||||
|----|----------|----------|-----------|------------|
|
||||
| D-101 | Cluster CA: internal Go CA (AD-010) or step-ca (external)? | **step-ca (apt-installed)** | Externally mandated per override ground 2; AD-010's "too heavyweight" rationale reversed. CLI wraps `step` CLI via SSH (no Go step-ca client library — keep zero-new-dep posture if possible, or add `github.com/smallstep/cli` as a dep). **Gated by C-07** (CA migration spec). | 0.74 |
|
||||
| D-068 | Workload identity: internal X.509 CA or SPIFFE SVIDs? | **SPIFFE SVIDs minted at submit time via step-ca** | Multi-tenancy (override ground 3) requires per-workload identity model; SPIFFE is the standard. SPIFFE ID `spiffe://orca/ns/<ns>/job/<name>/alloc/<id>` as SAN. **Gated by C-08** (mint spike in v1.0-P01.5; fallback to mTLS identity if spike fails). | 0.72 |
|
||||
| D-088 | Runtime: direct os/exec only (D-008) or multi-runtime? | **5 runtimes: wasm (wasmtime primary), podman, process, pve-vm, pve-ct** | WASM is the primary workload (override ground 4). `processRuntime` wraps existing `executor.go`; others are net-new. Split P07a/b/c per grill PC-10. **P07b gated by C-01** (wasmtime/CGO eval). | 0.82 |
|
||||
| D-158 | Namespace model: single flat root or multi-namespace? | **Multi-namespace under ORCA_HOME (R-002)** | Hard multi-tenant product requirement (override ground 3). `_defaults/` implicit root; `cluster/` for cluster-wide; per-namespace `db/`, `.env`, `.env.secrets`, `jobs/`, `alloc/`, `ns.md`. No namespace column in SQLite. | 0.84 |
|
||||
| D-179 | Jobspec format: HCL canonical (AD-007) or Markdown? | **Markdown with YAML frontmatter canonical (R-013); HCL legacy** | PRD §8 — Markdown + body preservation is the operator-facing format. HCL adapter (REQ-064) preserves `orca job run old-spec.hcl` during migration. | 0.85 |
|
||||
| D-185 | Re-architecture justification: incremental additive or full re-architecture? | **Full re-architecture (overridden by user)** | Six-part evidence basis above; the grill's REPLAN mechanics (PC-01..PC-10, C-01..C-19) adopted as gates. The incremental-additive path was evaluated and rejected on grounds 1 + 5 (daemon failing; SSH-push only viable). | 0.88 |
|
||||
|
||||
@@ -140,3 +140,45 @@ REQ-047..052 all complete.
|
||||
| REQ-058 | `--host-key-fingerprint <SHA256:base64>` pre-pin flag on `orca node join` (validated when `--type proxmox`): when supplied, join fails fast if the SSH host key's OpenSSH SHA-256 fingerprint does not match; supersedes TOFU (D-035) for pre-pinned deployments (D-044, D-045) | Medium | **v0.8 P2** | **Complete** (P2 shipped v0.7.2) |
|
||||
| REQ-059 | `orca node key-reset <node>` command: clears the persisted SSH host key entry for the node from `~/.orca/known_hosts` only (local, not remote authorized_keys — D-046); audit-logs `event=node.key_reset`; next `doctor proxmox`/dispatch re-pins via TOFU or `--host-key-fingerprint` | Low | **v0.8 P2** | **Complete** (P2 shipped v0.7.2) |
|
||||
| REQ-060 | Requirement-status hygiene sweep: REQUIREMENTS.md v0.7 rows were stale ("Pending" after ship); add a verify-stage assertion that every REQ listed as `Complete` in ROADMAP.md has a matching `Complete` row in REQUIREMENTS.md, enforced by `make verify-reqs` | Medium | **v0.8 P3** | **Complete** (P3 shipped v0.7.3) |
|
||||
|
||||
## v0.9/v1.0 Requirements — Re-architecture Foundation & Production Hardening
|
||||
|
||||
The v0.9/v1.0 milestones supersede the shipped v0.1–v0.8 architecture per the
|
||||
adopted PRD (`.ciagent/PRD_v0.9.md`). The re-architecture is justified on six
|
||||
grounds recorded in the PROJECT.md Supersession Table. 30 net-new requirements
|
||||
(REQ-061..REQ-090) derive from the v0.9 IDEATION; their phase placement and
|
||||
binding grill conditions (C-01..C-19) are documented in `IDEATION_v0.9.md`
|
||||
and `GRILL_v0.9.md`.
|
||||
|
||||
| ID | Requirement | Priority | Phase | Status |
|
||||
|----|-------------|----------|-------|--------|
|
||||
| REQ-061 | `orca daemon` deprecation command and build-tag removal path: v0.9 emits deprecation warning + still runs (dual-write window); v1.0 repurposes to `orca daemon drain-and-stop` (stops v0.8 daemons on peers via SSH, confirms workloads survive via systemd); post-v1.0 the command and `internal/daemon/` are deleted. `// Deprecated` Go doc comments + `slog.Warn` on every run (I-M-001) | High | **v1.0 P14** (warn v0.9 P0X) | Pending |
|
||||
| REQ-062 | Coverage follow-ups: 3 zero-test packages (`internal/audit`, `internal/certpaths`, `cmd/orca`) + `internal/cli` to 70% floor; once `daemon.go` is deprecated/removed the exclusion reason disappears and the floor applies to the whole package; all net-new subsystems carry a 70% floor from their first phase (I-M-002) | Medium | **v0.9 P0X** + each new pkg | Pending |
|
||||
| REQ-063 | `known_hosts` flock concurrency gap (deferred P1 from REVIEW_v0.8 A2): add `flock`-style advisory lock (stdlib `syscall.Flock` wrapper) around the read-modify-write in `TOFUHostKeyCallback` capture path (`bootstrap.go:290-302`) and `ResetHostKey` (`bootstrap.go:479-523`); lock file at `cluster/known_hosts.lock` (R-002) (I-M-003) | Medium | **v0.9 P0a1** | Pending |
|
||||
| REQ-064 | HCL→Markdown jobspec adapter/bridge layer: keep `internal/jobspec/spec.go` as legacy HCL path behind `// Deprecated`; add `internal/jobspec/markdown.go` (canonical) + `internal/jobspec/dispatch.go` (extension-based dispatcher: `.md`→Markdown, `.hcl`→legacy, `.yaml`→Markdown-with-empty-body); unified `*WorkloadSpec` populated via adapter; preserves `orca job run old-spec.hcl` during migration window (I-M-004) | High | **v0.9 P0b** | Pending |
|
||||
| REQ-065 | `orca doctor --legacy-paths` detection: detects v0.8 residue (orca.db at ORCA_HOME root, ca.crt/ca.key, config.hcl, flat server.crt, namespace column in any *.db); outputs list of legacy artifacts with migration recommendations; the detection half of v1.0-P14 (I-M-005) | Medium | **v1.0 P14c** | Pending |
|
||||
| REQ-066 | Legacy CA state migration to step-ca: `orca upgrade --to-v1.0 --import-ca` reads `~/.orca/ca.key`, initializes step-ca with it, re-issues workload SVIDs; preserves audit history even if live trust root changes (I-M-006). **Gated by C-07** | High | **v1.0 P14a** | Pending |
|
||||
| REQ-067 | Fuzz test harness for Markdown frontmatter parser: `testing.F` fuzz target in `internal/jobspec/markdown_test.go` round-trips random frontmatter+body through `ParseMarkdown` asserting byte-exact body preservation; corpus of adversarial fixtures (CRLF, BOM, no-frontmatter, empty-frontmatter, frontmatter-with-only-separator) (I-M-007) | Medium | **v0.9 P0b** | Pending |
|
||||
| REQ-068 | Deprecation warnings on removed/repurposed CLI subcommands: each removed/changed command (`orca cert`, `orca node join` mTLS semantics, `orca job run <spec.hcl>`) emits `slog.Warn` deprecation banner with v1.0 replacement except under `orca upgrade`; `--no-deprecation-warnings` global flag via `root.go` `PersistentPreRunE` (I-M-008) | Low | **v0.9 P0X** + v1.0 P13 | Pending |
|
||||
| REQ-069 | `internal/config/config.go` HCL config demotion via adapter: keep `internal/config/` as `legacy_config.go` with `// Deprecated`; add `internal/config/markdown.go` for new Markdown-frontmatter loader (R-014); `root.go` dispatches on file extension (`.hcl`→legacy, `.md`→new); `--config` semantics: `.hcl` read-only legacy, `.md` canonical (I-M-009) | High | **v0.9 P0a1** | Pending |
|
||||
| REQ-070 | `internal/certpaths/` replacement with multi-namespace path resolver: new `internal/paths` package with `paths.NamespaceDir(ns)`, `paths.ClusterDir()`, `paths.CacheDB()`, `paths.MasterKey()`, `paths.NSDb(ns)`, `paths.NSEnv(ns)`, `paths.NSSecrets(ns)`; keep `certpaths` as thin shim for v0.8 compat then remove post-v1.0 (R-002) (I-M-010) — highest blast radius | High | **v0.9 P0a1** | Pending |
|
||||
| REQ-071 | `internal/store/` schema: per-namespace DBs, drop namespace column: `store.Open` gains namespace parameter (or caller passes `paths.NSDb(ns)`); `migrate.go` runs migrations per namespace DB; `cert_repo` (0004) removed (step-ca handles certs); audit_log moves to CLI-side cache DB (R-008) (I-M-011) | High | **v0.9 P0a1** + v1.0 P06 | Pending |
|
||||
| REQ-072 | `internal/transport/` deletion + SSH-push package: delete `mtls.go`, `dispatch.go`, `handshake_log.go`; extract retry/idempotency patterns into `internal/sshpush/`; existing `transport.IdempotencyStore` directly reusable (I-M-012). Deletion deferred to v1.0-P14 to keep dual-write window open | High | **v0.9 P00** (delete v1.0 P14) | Pending |
|
||||
| REQ-073 | SSH-push transport layer design: connection pooling (reuse `*ssh.Client` per peer), idempotency (content-addressed filenames), retry (exponential backoff 100ms×2 cap 5s max 5), timeout (30s SCP, 10s exec), fan-out (errgroup bounded concurrency default 8), known_hosts reuse `proxmox.TOFUHostKeyCallback` (I-B-001) | High | **v0.9 P01** (design P0a1) | Pending |
|
||||
| REQ-074 | Emitter template system (Layer 4): `internal/emitter/` package with `Emitter` interface `Render(spec *WorkloadSpec, node *Node) ([]File, error)`; implementations systemdEmitter/traefikEmitter/syncthingEmitter/socketEmitter; SSH-push SCPs `[]File` atomically (write-to-tmp + rename); emitters registered per kind + runtime (I-B-002) | High | **v0.9 P0c** | Pending |
|
||||
| REQ-075 | Lead applier execution model: CLI renders transaction bundle (tarball + apply.sh + verify.sh) on operator host, SCPs to lead's `/run/orca/txns/<txn-id>/`, lead's systemd timer runs `apply.sh` idempotently, CLI polls txn status via SSH; bash scripts generated by emitter not hand-written (I-B-003). **Gated by C-09** | High | **v1.0 P10** (design v0.9 P00) | Pending |
|
||||
| REQ-076 | step-ca integration: `orca init` runs `step ca init` on lead; CLI SSHs to lead, installs step-ca via apt, stores step-ca.json; workload SVIDs via `step ca token` (JWE minted by CLI) → `step ca certificate`; SPIFFE ID as SAN; new `internal/stepca/` package wraps `step` CLI via SSH (I-B-004). Reverses AD-010 per override justification ground 2 | High | **v0.9 P07** + v1.0 P02 | Pending |
|
||||
| REQ-077 | Traefik dynamic config generation + atomic reload: Traefik emitter renders `/etc/traefik/dynamic/orca-<ns>-<svc>.yaml` with backends (socket paths R-007), health checks, mTLS config pointing at step-ca root; atomic reload via tmpfile+fsync+rename triggering fsnotify; drain writes `weight=0` or removes backend (I-B-005). **Gated by C-10** | High | **v0.9 P02** | Pending |
|
||||
| REQ-078 | Runtime abstraction interface (5 backends): `Runtime` interface in `internal/runtime/` with Prepare/Start/Stop/Status; processRuntime (wraps existing executor.go), wasmRuntime (wasmtime via SSH), podmanRuntime, pveVMRuntime (qm via proxmox SSH), pveCTRuntime (pct); runtimeRegistry keyed by `runtime:` frontmatter value; Alloc carries runtime field changeable on migration (I-B-006). Split P07a/b/c per PC-10. **P07b gated by C-01** | High | **v0.9 P07a/b/c** | Pending |
|
||||
| REQ-079 | Transaction bundle format + N-peer atomicity: bundle = tarball with desired-state.json + apply.sh + verify.sh + rollback.sh + manifest.sig (signed with master.key); content-addressed `<txn-id>=sha256(desired-state.json)` stored in `cluster/txns/<txn-id>/`; lead applies to self first then fans out; failure on any peer runs rollback.sh on applied peers (I-B-007). **Gated by C-09** | High | **v1.0 P10** (design v0.9 P00) | Pending |
|
||||
| REQ-080 | Master key management + HKDF-SHA256 per-line .env.secrets encryption: `cluster/master.key` 32-byte random (generated at `orca init` using WriteAtomic pattern); each line `base64(nonce||ciphertext||tag)`, nonce=random(12 bytes), AES-256-GCM with AAD=line-number (prevents line-swap); HKDF-SHA256 derives per-namespace sub-keys; `orca secrets set/get`; v0.8 `internal/security/redact.go` reusable (I-B-008). **Gated by C-19** | High | **v1.0 P03** | Pending |
|
||||
| REQ-081 | Syncthing config rendering + folder-ID content-addressing: per-namespace Syncthing folder `orca-<ns>` with content-addressed folder ID `sha256(ns + master-key-fingerprint)`; CLI renders config.xml per peer; Syncthing runs as systemd unit (emitted by systemd emitter); CLI discovers peers via `cluster/peers/`; migration works because new node joins folder and syncs before workload starts (I-B-009). **Gated by C-02 + C-14** | Medium | **v0.9 P09** (spike v0.9 P00) | Pending |
|
||||
| REQ-082 | Namespace inheritance resolver algorithm: DFS parent walker with visited set for cycle detection; `_defaults/` implicit root (always exists, no parent); merge semantics: child overrides parent for scalars, arrays unioned (child adds to parent); pure function (no I/O) taking `map[nsName→*NSConfig]` returning `map[nsName→*ResolvedNS]` (I-B-010) | High | **v0.9 P0a2** | Pending |
|
||||
| REQ-083 | CLI-side scheduler redesign: `Score(node, workload) (score int, fits bool)` where `fits` checks runtime compatibility + constraints, `score` is bin-packing (most free capacity = highest); Services pick `count` distinct nodes (anti-affinity default); DaemonSets pick all matching nodes; Job = one-shot; CLI-side not daemon-side (R-001) (I-B-011) | High | **v0.9 P05** (skeleton P0c) | Pending |
|
||||
| REQ-084 | `orca job lint` category-driven lint engine: `Linter` runs `Rule` checks returning `Finding{Category, Severity, Message, Explanation}`; categories schema/runtime/security/migration/best-practice; `--explain` prints rationale; pure (no I/O) checks against static rules (I-B-012) | Medium | **v1.0 P11** | Pending |
|
||||
| REQ-085 | v0.8→v1.0 migration ordering: v0.9 ships new parser + kinds + runtime + SSH-push alongside old daemon (dual-write window); `orca job run` dispatches on extension (`.md`→SSH-push, `.hcl`→old daemon); v1.0-P05 drains old daemons; v1.0-P14 converts remaining `.hcl` specs and removes daemon (I-C-001). **Most important cross-cutting idea** | High | **v0.9 P00** → v1.0 P14 | Pending |
|
||||
| REQ-086 | "No orca on server" enforcement: `orca doctor no-orca-on-server` SSHs to each peer verifying no `orca` binary in PATH, no `orca` systemd service, no `orca` process, no `/etc/orca/` directory; runs after v1.0-P05 before v1.0-P16; reuses v0.8 `proxmox` SSH session infrastructure (I-C-002). Implements grill C-13 | High | **v1.0 P14c** | Pending |
|
||||
| REQ-087 | Test infrastructure: hermetic 3-linux + 1-proxmox cluster pipeline: `test/integration/` with docker-compose/vagrant creating 4 containers/VMs; Go test harness SSHes to each, runs CLI, asserts end-to-end workflows (ns create → workload submit → migrate → drain); proxmox simulated via mock pct/qm; v0.8 e2e tests (bootstrapE2ESetup) are foundation (I-C-003) | Medium | **v1.0 P08** (bootstrap v0.9 P00) | Pending |
|
||||
| REQ-088 | Security-engineer + network-engineer persona reactivation: reactivate security-engineer (step-ca provisioner model, SSH-push blast radius, Traefik edge, .env.secrets crypto) and network-engineer (socket exposure R-007, Syncthing P2P ports, Traefik routing); cross-cutting review not single phase (I-C-004). Implements grill C-05 | High | **v0.9 P00** → v1.0 P16 | Pending |
|
||||
| REQ-089 | Documentation rewrite: ARCHITECTURE.md/PROJECT.md/README + AD-010 supersession: v0.9-P00 adds "v0.9 Architecture (Supersedes v0.8)" section + banners + Superseded Decisions table; v1.0-P15 rewrites README quickstart for new curl|sh + orca init + orca ns create flow (I-C-005) | Medium | **v0.9 P00** + v1.0 P15/P16 | Pending |
|
||||
| REQ-090 | Dual-write window: v0.9 `orca job run` dispatches on extension (`.md`→SSH-push new path, `.hcl`→old daemon path) via parser dispatcher (REQ-064); daemon not removed until v1.0-P05; SSH-push path writes to separate systemd unit namespace (`orca-v1-<alloc>.service`) while daemon uses `orca-<job>.service` — no unit name overlap = no conflict (I-C-006) | High | **v0.9 P00** | Pending |
|
||||
|
||||
@@ -184,3 +184,153 @@ tag.
|
||||
The vision ("minimalist, offline-first, CLI-first orchestration
|
||||
engine") is unchanged. v0.8 closes the coverage debt left by v0.7's
|
||||
50% floor and the trust-surface gaps explicitly deferred in v0.6.
|
||||
|
||||
## Milestone v0.9: Re-architecture Foundation & Workloads
|
||||
|
||||
**Scope**: This milestone SUPERSPEDES the shipped v0.1–v0.8 architecture per
|
||||
the adopted PRD (`.ciagent/PRD_v0.9.md`). The re-architecture is justified on
|
||||
six grounds recorded in the PROJECT.md Supersession Table: (1) the v0.8 daemon
|
||||
model is operationally failing, (2) step-ca is externally mandated, (3)
|
||||
multi-tenancy is a hard product requirement, (4) WASM is a hard workload
|
||||
requirement, (5) SSH-push is the only viable deployment target, (6) vision
|
||||
correction. The 16 load-bearing rules (R-001…R-016) are invariants. The
|
||||
ci-griller reviewed the re-architecture adversarially; the user overrode the
|
||||
Re-architecture Justification REPLAN with the six-part evidence basis; the
|
||||
19 binding conditions (C-01..C-19) and 10 phase challenges (PC-01..PC-10)
|
||||
from `GRILL_v0.9.md` are adopted as execution gates. 30 net-new requirements
|
||||
(REQ-061..REQ-090) derive from `IDEATION_v0.9.md`.
|
||||
|
||||
**Milestone type**: feature (P01..P10 ship `feat` phases; P00/P0X are
|
||||
chore/docs).
|
||||
|
||||
- [ ] Phase 0: Pre-execution (specify → clarify → research → ideate → plan → grill) — tag `v0.8.0` (shipped; this is the phase you are reading)
|
||||
- [ ] Phase P00: Deprecation sweep + migration-ordering decision + txn-design spike + hermetic test-infra bootstrap + persona reactivation + doc banners (REQ-072, REQ-085, REQ-088, REQ-089, REQ-090; gates C-03 ✅, C-05, C-06, C-15..C-18) — tag `v0.8.1`
|
||||
- [ ] Phase P0a1: Multi-namespace path resolver + config HCL demotion + known_hosts flock (REQ-063, REQ-069, REQ-070, REQ-071; gate C-07) — tag `v0.8.2`
|
||||
- [ ] Phase P0a2: Namespace CRUD + inheritance engine (REQ-082) — tag `v0.8.3`
|
||||
- [ ] Phase P0b: Markdown jobspec parser + dispatcher + fuzz (REQ-064, REQ-067) — tag `v0.8.4`
|
||||
- [ ] Phase P0c: Job/Service/DaemonSet schemas + emitter interface (REQ-074) — tag `v0.8.5`
|
||||
- [ ] Phase P01: SSH-push transport + host-path volumes (REQ-073) — tag `v0.8.6`
|
||||
- [ ] Phase P02: Service block + checks + restart + Traefik emitter (REQ-077; gate C-10) — tag `v0.8.7`
|
||||
- [ ] Phase P03: Update stanza (rolling/canary) — tag `v0.8.8`
|
||||
- [ ] Phase P04: Lifecycle hooks (systemd ExecStop) — tag `v0.8.9`
|
||||
- [ ] Phase P05: Constraints & affinity (CEL) + CLI-side scheduler (REQ-083) — tag `v0.8.10`
|
||||
- [ ] Phase P06: Task groups (multi-process services) — tag `v0.8.11`
|
||||
- [ ] Phase P07a: Process + podman runtimes (REQ-078) — tag `v0.8.12`
|
||||
- [ ] Phase P07b: wasmtime runtime (REQ-078; **gate C-01** — CGO eval) — tag `v0.8.13`
|
||||
- [ ] Phase P07c: pve-vm + pve-ct runtimes (REQ-078; extends REQ-076) — tag `v0.8.14`
|
||||
- [ ] Phase P08: Socket plumbing (R-007) — tag `v0.8.15`
|
||||
- [ ] Phase P09: Storage replication via Syncthing (REQ-081; **gates C-02, C-14**) — tag `v0.8.16`
|
||||
- [ ] Phase P10: Lead rules + migration (REQ-076 step-ca integration) — tag `v0.8.17`
|
||||
- [ ] Phase P0X: Ship + audit (REQ-062 coverage gate; REQ-068 deprecation warnings) — tag `v0.8.18`
|
||||
|
||||
**Milestone tag**: `v0.8.18` (final phase patch = milestone release per
|
||||
feature-milestone progressive-patch rule). Per-phase tags: `v0.8.1`…`v0.8.18`.
|
||||
Tags run on the previous minor's patch line (v0.8.x) per branch-strategy.md.
|
||||
The milestone branch label uses the milestone number
|
||||
(`milestone/v0.9-rearchitecture`); no separate minor tag.
|
||||
|
||||
### Per-phase REQ coverage (v0.9)
|
||||
|
||||
- **P00** — Deprecation/migration/test-infra/persona/docs foundation (REQ-072, REQ-085, REQ-088, REQ-089, REQ-090)
|
||||
- **P0a1** — Path resolver + config demotion + known_hosts flock (REQ-063, REQ-069, REQ-070, REQ-071)
|
||||
- **P0a2** — Namespace inheritance resolver (REQ-082)
|
||||
- **P0b** — Markdown parser + adapter + fuzz (REQ-064, REQ-067)
|
||||
- **P0c** — Schemas + emitter interface (REQ-074)
|
||||
- **P01** — SSH-push transport (REQ-073)
|
||||
- **P02** — Service + Traefik emitter (REQ-077)
|
||||
- **P05** — CLI-side scheduler (REQ-083)
|
||||
- **P07a/b/c** — Runtime abstraction (REQ-078) + step-ca integration (REQ-076)
|
||||
- **P09** — Syncthing replication (REQ-081)
|
||||
- **P0X** — Coverage gate (REQ-062) + deprecation warnings (REQ-068)
|
||||
|
||||
### v0.9 is a DIRECTION CHANGE — first in the project's history
|
||||
|
||||
Every prior milestone (v0.1–v0.8) explicitly said "the vision is unchanged;
|
||||
this milestone is not a direction change." v0.9 is the first milestone that
|
||||
reverses the vision's anti-patterns (daemon-on-every-node, internal CA,
|
||||
HCL-canonical, single-namespace, no-container-runtime, no-SPIFFE). The
|
||||
reversals are justified by the six-part evidence basis recorded in the
|
||||
PROJECT.md Supersession Table.
|
||||
|
||||
## Milestone v1.0: Production Hardening
|
||||
|
||||
**Scope**: ship a cluster that operators can run. Builds on the v0.9
|
||||
re-architecture foundation with the production-grade subsystems:
|
||||
secrets, transactions, ACL/SPIFFE, backup/restore, drain, recovery, and
|
||||
the v0.8→v1.0 migration.
|
||||
|
||||
**Milestone type**: feature (multiple `feat` phases).
|
||||
|
||||
- [ ] Phase 0: Pre-execution (specify → clarify → research → plan → grill) — tag `v0.9.0`
|
||||
- [ ] Phase P00: CLI cache layer (REQ-062 cache floor; R-008) — tag `v0.9.1`
|
||||
- [ ] Phase P01: Metrics endpoint (hand-rolled text exposition) — tag `v0.9.2`
|
||||
- [ ] Phase P01.5: SPIFFE SVID minting spike (REQ-076; **gate C-08** — if spike fails, fall back to mTLS identity) — tag `v0.9.3`
|
||||
- [ ] Phase P02: ACL (SPIFFE + token identities) — tag `v0.9.4`
|
||||
- [ ] Phase P03: Secrets subsystem (REQ-080; **gate C-19** threat model) — tag `v0.9.5`
|
||||
- [ ] Phase P04: Backup/restore (tar + signed) — tag `v0.9.6`
|
||||
- [ ] Phase P05: Drain + daemon drain-and-stop (REQ-061) — tag `v0.9.7`
|
||||
- [ ] Phase P06: Alloc history (CLI-side SQLite retention; REQ-071 cache DB) — tag `v0.9.8`
|
||||
- [ ] Phase P07: Recovery (`orca restore`) — tag `v0.9.9`
|
||||
- [ ] Phase P08: Integration tests — expand hermetic harness (REQ-087) — tag `v0.9.10`
|
||||
- [ ] Phase P09: Collector + aggregator (opt-in; **gates C-11, C-12, C-14**) — tag `v0.9.11`
|
||||
- [ ] Phase P10: Transactional plane (REQ-075, REQ-079; **gate C-09** orca-pull.sh failure contract) — tag `v0.9.12`
|
||||
- [ ] Phase P11: `orca job lint` (REQ-084) — tag `v0.9.13`
|
||||
- [ ] Phase P12: `orca job verify` (dry-run txn through lead) — tag `v0.9.14`
|
||||
- [ ] Phase P13: `orca ns` subcommands (full surface) + deprecation warnings (REQ-068) — tag `v0.9.15`
|
||||
- [ ] Phase P14a: v0.8→v1.0 data migration (REQ-066; **gate C-07** CA migration spec) — tag `v0.9.16`
|
||||
- [ ] Phase P14b: Daemon cutover + running-allocation adoption — tag `v0.9.17`
|
||||
- [ ] Phase P14c: Mixed-version tolerance + no-orca-on-server enforcement (REQ-065, REQ-086; implements C-13) — tag `v0.9.18`
|
||||
- [ ] Phase P15: README quickstart (REQ-089) — tag `v0.9.19`
|
||||
- [ ] Phase P15.5: Threat model + security review (**gate C-19**) — tag `v0.9.20`
|
||||
- [ ] Phase P16: Final review + ship + audit — **v1.0.0 release** — tag `v0.9.21`
|
||||
|
||||
**Milestone tag**: `v1.0.0` (the v1.0.0 release tag is the production-ready cut;
|
||||
per-phase patches run on the v0.9.x line per branch-strategy.md). Per-phase
|
||||
tags: `v0.9.0`…`v0.9.21`.
|
||||
|
||||
### Per-phase REQ coverage (v1.0)
|
||||
|
||||
- **P00** — CLI cache (R-008)
|
||||
- **P01.5** — SPIFFE spike (REQ-076; C-08)
|
||||
- **P03** — Secrets (REQ-080; C-19)
|
||||
- **P05** — Drain + daemon stop (REQ-061)
|
||||
- **P06** — Alloc history (REQ-071 cache DB)
|
||||
- **P08** — Integration tests (REQ-087)
|
||||
- **P10** — Transactional plane (REQ-075, REQ-079; C-09)
|
||||
- **P11** — Job lint (REQ-084)
|
||||
- **P13** — ns subcommands + deprecation warnings (REQ-068)
|
||||
- **P14a/b/c** — Migration (REQ-066, REQ-065, REQ-086; C-07, C-13)
|
||||
- **P15** — README (REQ-089)
|
||||
- **P15.5** — Threat model (C-19)
|
||||
|
||||
### Risk register (from grill, for ongoing monitoring)
|
||||
|
||||
- **step-ca single-instance SPOF** (mitigation: C-12 doc; v1.x HA via systemd failover)
|
||||
- **master.key passphrase-less 0600** (mitigation: C-19 threat model; consider OS keyring in v1.x)
|
||||
- **wasmtime CGO breaks cross-compile** (mitigation: C-01 spike; fallback to podman/process primary)
|
||||
- **bash control plane drift** (mitigation: C-15..C-18 render-format contract + bats gate)
|
||||
- **daemon cutover orphans running allocs** (mitigation: P14b split; test adoption)
|
||||
- **27→35+ phase scope** (mitigation: C-04 sizing; three-milestone split if exceeded — current count v0.9=18 + v1.0=22 = 40 phases; **C-04 sizing must run before v0.9 P00 execution to determine whether to split into v0.9+v0.10+v1.0**)
|
||||
|
||||
## Deferred to v1.x (out of scope for v1.0)
|
||||
|
||||
- `sqlite-wal-shared` state backend (R-009 abstractions ship in v1.0; backend in v1.x)
|
||||
- `git` state backend
|
||||
- `file+flock` state backend
|
||||
- `orca cluster setup-shared` UX
|
||||
- HA `step-ca` (active/passive via systemd)
|
||||
- Journald log shipping (optional centralized audit)
|
||||
- Network policy (`nftables` snippets)
|
||||
- GPU / TPU constraints
|
||||
|
||||
## Deferred to v2.x (out of scope for v1.x)
|
||||
|
||||
- Full Nomad-HCL parser with no conversion round-trip
|
||||
- Nomad-API subset for migrating existing Nomad fleets
|
||||
- Nomad driver bridge
|
||||
- Helm-equivalent templating (probably never)
|
||||
- Service mesh beyond Traefik
|
||||
- CRDs / Operators / Plugin model
|
||||
- Leader-elected Raft coordinator
|
||||
- External CA / Let's Encrypt / cert transparency
|
||||
- Online-only features (HSTS, OCSP stapling, telemetry)
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
"slug": "orca",
|
||||
"name": "Orca",
|
||||
"description": "Offline/CLI-first orchestration engine (Orca) — Nomad-inspired, far simpler than Kubernetes",
|
||||
"milestone": "v0.8",
|
||||
"phase": 4,
|
||||
"milestone_type": "nfr",
|
||||
"milestone": "v0.9",
|
||||
"phase": 0,
|
||||
"milestone_type": "feature",
|
||||
"default_branch": "main",
|
||||
"tech_stack": {
|
||||
"language": "go",
|
||||
|
||||
Reference in New Issue
Block a user