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---
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 initcreates/tmp/x(not~/.orca).orca --system initcreates/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.gzfrom the release asset. - In-place update: if
orcaexists at install path, runorca version --json, parseversion, 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.shpasses (mocked).curl -fsSL <url> | bashworks on a fresh system (verified in P4 e2e).curl -fsSL <url> | bash -s -- --systeminstalls to/usr/local/bin(as root).- Re-running updates the binary;
~/.orca/orca.dbpreserved.
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_TIMEfor ldflags injection.- Image runs as
nonrootuser (distroless default) —ORCA_HOME=/var/lib/orcamust 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-stdindocker push git.cloudinit.dev/coreci/orca:$VERSION+docker push git.cloudinit.dev/coreci/orca:latest- Skip gracefully if
dockernot on PATH (local dev without docker).
.coreci.yml extension:
- New step
container-publishin thereleasepipeline, using an image with docker CLI (e.g.,docker:24-cliwith 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 versionprints the version.scripts/release.sh vX.Y.Zpublishes both the Gitea release AND the container image..coreci.ymlrelease 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 tov0.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.