Files
orca/.ciagent/PLAN_v0.5.md
T
Jon Chery 2d1c2de585 docs(P00): create phase plans
4-phase plan for v0.5 Distribution:
P1: namespace unification (ORCA_HOME + --system) - REQ-041/042
P2: install.sh + in-place update - REQ-043/044/016
P3: docker release (Dockerfile + Gitea registry) - REQ-046
P4: final review + ship + audit (milestone release v0.4.5=v0.5.0)
Tags: v0.4.1..v0.4.5 on the v0.4.x patch line

---ci---
project: orca
phase: 0
milestone: v0.5
status: plan
---/ci---
2026-08-03 18:01:16 +00:00

8.3 KiB

milestone, milestone_slug, type, phase_count
milestone milestone_slug type phase_count
v0.5 distribution feature 4

Plan: Orca v0.5 — Distribution

Vertical-slice plan for the v0.5 Distribution milestone. Each phase is a vertical slice that ships independently as a patch on the v0.4.x line. The final phase (P4) is the milestone release (promoted to v0.5.0).

Requirement → Phase Mapping

REQ Phase Priority
REQ-045 (public releases) P0 ship (operational) High
REQ-041 (ORCA_HOME unified namespace) P1 High
REQ-042 (--system flag) P1 High
REQ-043 (install.sh 1-liner) P2 High
REQ-044 (in-place update) P2 High
REQ-046 (docker release) P3 Medium
REQ-016 (README quickstart) P2 Medium (completion)

Phase 1 — Namespace Unification (REQ-041, REQ-042)

Goal: Single ORCA_HOME env var as namespace root for all on-disk state; --system flag selects /root/.orca.

Persona: backend-engineer (store/certpaths routing) + cli-engineer (--system flag).

Wave 1 (single wave — no inter-task dependencies):

Task File(s) Persona REQ
T1.1: Route store.Open("") through certpaths.DBPath() internal/store/store.go backend-engineer REQ-041
T1.2: Route init command through certpaths.Dir() internal/cli/init.go backend-engineer REQ-041
T1.3: Add --system persistent flag on rootCmd + PersistentPreRunE that sets ORCA_HOME=/root/.orca internal/cli/root.go cli-engineer REQ-042
T1.4: Add namespace_test.go covering user-level, ORCA_HOME override, --system internal/cli/namespace_test.go cli-engineer REQ-041/042
T1.5: Update docs/namespace.md (paths reference) docs/namespace.md backend-engineer REQ-041

Must-haves:

  • go test ./... passes (including new namespace_test.go).
  • ORCA_HOME=/tmp/x orca init creates /tmp/x (not ~/.orca).
  • orca --system init creates /root/.orca (when run as root).
  • Empty ORCA_HOME + no --system~/.orca (backward compat).

Verification: 4-layer (structural: gofmt/vet; behavioral: namespace_test

  • existing doctor_test; security: no new secret surface; quality: no regression in existing tests).

Ship: tag v0.4.2.

Phase 2 — install.sh + In-Place Update (REQ-043, REQ-044, REQ-016)

Goal: 1-liner installer from public Gitea releases; idempotent update-in-place; README quickstart.

Persona: devops-engineer.

Wave 1:

Task File(s) Persona REQ
T2.1: Write scripts/install.sh (curl 1-liner, user/system, latest/pinned, in-place update) scripts/install.sh devops-engineer REQ-043/044
T2.2: Write scripts/install_test.sh (mocked download, path verification, update-in-place) scripts/install_test.sh devops-engineer REQ-043/044
T2.3: Update README quickstart with 1-liner install + --system variant README.md devops-engineer REQ-016
T2.4: Write docs/install.md (full install reference, troubleshooting, ORCA_HOME) docs/install.md devops-engineer REQ-043

install.sh spec (per R-006):

  • Default: user-level. Binary → ~/.local/bin/orca. Namespace → ~/.orca.
  • --system: binary → /usr/local/bin/orca, namespace → /root/.orca. Requires root (uid 0).
  • --version vX.Y.Z: pin version. Default: query /api/v1/repos/coreci/orca/releases/latest.
  • Download orca-{tag}-linux-{arch}.tar.gz from the release asset.
  • In-place update: if orca exists at install path, run orca version --json, parse version, print "updated from X to Y". Overwrite binary. Never touch the namespace dir.
  • Detect arch: amd64 (x86_64), arm64 (aarch64).
  • Idempotent: re-running with same version is a no-op (or reinstalls).

Must-haves:

  • bash scripts/install_test.sh passes (mocked).
  • curl -fsSL <url> | bash works on a fresh system (verified in P4 e2e).
  • curl -fsSL <url> | bash -s -- --system installs to /usr/local/bin (as root).
  • Re-running updates the binary; ~/.orca/orca.db preserved.

Verification: 4-layer (structural: shellcheck; behavioral: install_test.sh; security: no secret in script, no eval of remote content beyond the script itself; quality: idempotent).

Ship: tag v0.4.3.

Phase 3 — Docker Release (REQ-046)

Goal: Multi-stage Dockerfile; publish to Gitea container registry per release.

Persona: devops-engineer.

Wave 1:

Task File(s) Persona REQ
T3.1: Write Dockerfile (multi-stage: golang:1.25 → distroless/static-debian12) Dockerfile devops-engineer REQ-046
T3.2: Extend scripts/release.sh with docker build + login + push scripts/release.sh devops-engineer REQ-046
T3.3: Add container-publish step to .coreci.yml release pipeline .coreci.yml devops-engineer REQ-046
T3.4: Write docs/docker.md (docker run quickstart, volume mounts, ORCA_HOME) docs/docker.md devops-engineer REQ-046
T3.5: Add .dockerignore (exclude .git, bin, .env, *.tar.gz) .dockerignore devops-engineer REQ-046

Dockerfile spec (per R-005):

  • Stage 1 (golang:1.25): CGO_ENABLED=0 go build -trimpath -ldflags=... -o /orca ./cmd/orca.
  • Stage 2 (gcr.io/distroless/static-debian12:nonroot): COPY --from=builder /orca /orca, ENV ORCA_HOME=/var/lib/orca, ENTRYPOINT ["/orca"].
  • ARG VERSION + ARG GIT_COMMIT + ARG BUILD_TIME for ldflags injection.
  • Image runs as nonroot user (distroless default) — ORCA_HOME=/var/lib/orca must be volume-mounted.

release.sh extension:

  • After Gitea release: docker build --build-arg VERSION=$VERSION ... -t git.cloudinit.dev/coreci/orca:$VERSION -t git.cloudinit.dev/coreci/orca:latest .
  • echo "$GITEA_TOKEN" | docker login git.cloudinit.dev -u cloudinit-bot --password-stdin
  • docker push git.cloudinit.dev/coreci/orca:$VERSION + docker push git.cloudinit.dev/coreci/orca:latest
  • Skip gracefully if docker not on PATH (local dev without docker).

.coreci.yml extension:

  • New step container-publish in the release pipeline, using an image with docker CLI (e.g., docker:24-cli with docker-in-docker service, or a custom image). Per P-001 pitfall.

Must-haves:

  • docker build -t orca-test . succeeds locally.
  • docker run --rm orca-test version prints the version.
  • scripts/release.sh vX.Y.Z publishes both the Gitea release AND the container image.
  • .coreci.yml release pipeline includes the container-publish step.

Verification: 4-layer (structural: Dockerfile lint; behavioral: docker build + run; security: no secret in image, .env excluded; quality: reproducible build via ARGs).

Ship: tag v0.4.4.

Phase 4 — Final Review + Ship + Audit (Milestone Release)

Goal: Multi-persona review, audit, milestone ship.

Tasks:

Task Persona Detail
T4.1: ciagent-review all Review P1-P3 changes across personas
T4.2: ciagent-audit lead-developer Reconstruction test, file/branch/commit discipline
T4.3: End-to-end verification lead-developer Unauth curl to releases API (REQ-045 ✓), fresh install.sh (REQ-043 ✓), --system (REQ-042 ✓), update-in-place (REQ-044 ✓), docker pull+run (REQ-046 ✓)
T4.4: Milestone ship lead-developer Merge phase/04 → milestone/v0.5 → main, tag v0.4.5, create milestone release, build + upload all artifacts
T4.5: Complete milestone lead-developer Update REQUIREMENTS.md (REQ-041..046 complete), ROADMAP.md (v0.5 complete), clear CHECKPOINT.json

Ship: tag v0.4.5 (the milestone release, promoted to v0.5.0).

Wave Ordering Summary

All 4 phases are single-wave (no inter-phase dependencies within a phase). Phases execute strictly sequentially: P1 → P2 → P3 → P4.

  • P1 (Wave 1): T1.1..T1.5 — namespace unification.
  • P2 (Wave 1): T2.1..T2.4 — install.sh.
  • P3 (Wave 1): T3.1..T3.5 — docker.
  • P4 (Wave 1): T4.1..T4.5 — review + ship.

Versioning

  • P0 ship: v0.4.1 (first patch on v0.4.x line after v0.4.0 milestone tag).
  • P1 ship: v0.4.2.
  • P2 ship: v0.4.3.
  • P3 ship: v0.4.4.
  • P4 ship: v0.4.5 (final phase = milestone release, promoted to v0.5.0).

Tags run on the v0.4.x line (previous minor). The milestone branch label is milestone/v0.5-distribution. No separate minor tag — the final phase's patch IS the milestone release per run.md versioning logic for feature milestones.