Files
ci/opencode/ci/workflows/ship.md
T
Jon Chery f478088797 refactor(P06): rename milestone type schema-breaking → major, reinforce release flow
---ci---
phase: 6
milestone: v0.10
status: execute
decisions:
  - id: D-001
    decision: Rename MilestoneType schema-breaking to major for clarity
    rationale: Major better describes the semver impact (major version bump) and aligns with standard semver terminology
    confidence: 0.95
    alternatives: [schema-breaking, breaking, major-change]
  - id: D-002
    decision: Add autopilot rules, PR+QA gates, and merge validation to ship workflow
    rationale: Release flow was documented but not enforced in the workflow. Zero-HITL rules, branch hierarchy validation, and coreci packaging steps ensure consistent releases
    confidence: 0.90
    alternatives: [keep-as-documentation-only, add-to-AGENTS.md-only]
---/ci---
2026-06-01 15:29:43 +00:00

10 KiB
Raw Blame History


description: Ship CIAgent phase or milestone — Full autopilot release: validate, test, merge, tag, push, release. Zero HITL

CIAgent Ship

Ship a CIAgent phase or milestone. Every ship creates a release — no exceptions.

Usage: ciagent-ship [phase_number|milestone]

Autopilot Rules

These rules are non-negotiable. The ship workflow runs in full autopilot mode:

  • Zero HITL — no confirmation prompts, no approval gates, no requests for human input. The agent executes the entire release flow autonomously.
  • No Shortcuts — deep validation, testing, and merge checks must all run in full. The lack of HITL is not an excuse to skip steps.
  • Notification Only — status updates are informational, not requests for approval. Report outcomes, never ask permission.
  • Autonomous Loop on Failure — if any step fails (tests, pipeline, merge conflicts), iterate autonomously until success. Do NOT ask the user for guidance on how to fix a failing test or pipeline.
  • Branch Hierarchy Enforcedmain > milestone/vX.X-slug > phase/NN-slug. Phase merges into milestone, milestone merges into main. This is validated, not assumed.

Milestone Type and Versioning

The milestone type is determined before any development work and governs all versioning for the entire milestone.

Define semver at milestone start: establish the version and milestone type before writing code.

Determine milestone type by calling getMilestoneType() which returns "nfr" | "feature" | "major":

Milestone Type Condition Phase release Milestone release
NFR All phases are fix/chore/docs/perf/refactor/test Patch — v1.8.1, v1.8.2, ... None — final patch IS the deliverable
Feature At least one phase has new features (feat) Patch — v1.8.1, v1.8.2, ... Next minor — v1.9.0
Major Breaking schema changes or complete refactor Minor — v2.1.0, v2.2.0, ... Major — v3.0.0

Tag rules (CRITICAL):

  • Milestone tags are always the NEXT version, never the base:
    • Feature: patches v0.5.1v0.5.5 → milestone tag is v0.6.0 (NOT v0.5.0)
    • Major: minors v0.3.0, v0.4.0, v0.5.0 → milestone tag is v1.0.0
    • NFR: no milestone tag — the final patch release IS the deliverable
  • Tags must be strictly greater than all existing tags on the same major.minor line
  • NEVER create a milestone tag that is semantically below existing phase tags

Step 0: Confirm Active Project

Check ci listProjects() or read .ciagent/config.json to determine if multi-project mode is active.

If .ciagent/config.json has projects[] with length > 0:

  • Confirm active_project is correct for this ship
  • If not, set it with ci setActiveProject(<slug>)
  • All commit messages must include project: <slug> in ---ci--- block
  • Branch names are prefixed with <slug>/ in multi-project mode

If single-project mode: proceed with existing conventions.

Step 1: Pre-Flight Validation

git log --max-count=10
git branch -a
git tag -l

Determine what is being shipped: a single phase or an entire milestone.

Read .ciagent/ROADMAP.md to determine:

  • Current milestone version (e.g., v0.2)
  • Phase number within the milestone
  • Whether this is the last phase in the milestone

Read .ciagent/config.json for autonomy level.

Validation gates — all must pass before proceeding:

  1. Milestone type resolvedgetMilestoneType() must return "nfr" | "feature" | "major". Stop if undefined.
  2. Branch hierarchy correct — phase branch exists and targets the correct parent (milestone branch, or main if no milestone branch exists).
  3. No unmerged phase branches — if shipping a milestone, all phase branches for this milestone must be merged into the milestone branch.
  4. Tag sequence valid — the computed tag must be strictly greater than all existing tags on the same major.minor line. Check with git tag -l.
  5. Autonomy confirmed.ciagent/config.json autonomy level must be full. This is the zero-HITL enforcement point.

If any validation fails: stop and report. Do NOT proceed past a failed gate.

Step 2: Run Tests

npm test
npm run typecheck
npm run build

If any fail: iterate autonomously until tests pass. Do NOT ask the user for guidance — debug and fix.

Step 3: Create PR and Quality Assurance

Open a Pull Request for the merge target:

tea pr create --base <target-branch> --head <source-branch> --title "ship: [phase-name or milestone-name]"
  • For a phase ship: PR from phase/NN-slug into milestone/vX.Y-slug (or main if no milestone branch).
  • For a milestone ship: PR from milestone/vX.Y-slug into main.

Auto-merge configuration:

Set the PR to auto-merge upon pipeline success:

tea pr merge <pr-number> --auto --squash

Review:

Conduct a thorough autonomous review of the PR diff. Check:

  • All expected files are included
  • No unintended changes slipped in
  • No secrets or credentials in the diff
  • All ---ci--- blocks have correct metadata

Finalization:

  • On pipeline success: the PR auto-merges. Proceed to Step 4.
  • On pipeline failure: iterate autonomously until the pipeline passes. Do NOT merge a PR with a failing pipeline. Do NOT ask for guidance.

Strict rule: Never merge a PR with a failed pipeline. No exceptions.

Step 4: Compute Version

What's shipping Milestone Type Phase release Milestone release Example
Single phase NFR Patch vX.Y.Z N/A v0.1.3 (3rd NFR phase)
Single phase Feature Patch vX.Y.Z N/A v0.2.3 (3rd feature phase)
Single phase Major Minor vX.(Y+N).0 N/A v0.4.0 (2nd major phase)
Milestone completion NFR Patch (last phase) None v0.1.3 (no milestone tag)
Milestone completion Feature Last patch Minor vX.(Y+1).0 v0.3.0 (NOT v0.2.0)
Milestone completion Major Last minor Major v(X+1).0.0 v1.0.0

Phase number within the milestone determines the increment:

  • NFR/Feature: 1st phase = .1, 2nd = .2, etc. (v0.5.1, v0.5.2)
  • Major: 1st phase = next minor, 2nd = minor+1, etc. (v0.3.0, v0.4.0)

Tag validation (before creating ANY tag):

  1. Tag must be strictly greater than all existing tags on the same major.minor line
  2. Milestone completion tag must be next minor (feature) or next major (major)
  3. NEVER create a milestone tag that is semantically below existing phase tags (e.g., v0.5.0 when v0.5.1 already exists)

Step 5: Merge Branch

Branch hierarchy: main > milestone/vX.X-slug > phase/NN-slug

Merge validation gates

Phase → Milestone:

  • VALIDATED — must target milestone branch when one exists
  • REJECTED if milestone branch does not exist for this phase's milestone

Phase → Main:

  • VALIDATED — only allowed when NO milestone branch exists for this phase's milestone
  • REJECTED if a milestone branch exists for this milestone

Milestone → Main:

  • VALIDATED — only after all phase branches are merged
  • REJECTED if any phase branches for this milestone are unmerged

Phase ship

If milestone branch exists:

git checkout milestone/vX.Y-slug
git merge --squash phase/NN-slug
git commit -m "docs(P##): complete [phase-name] phase

---ci---
phase: [N]
milestone: [vX.Y]
status: complete
requirements:
  covered: [REQ-01, REQ-02]
  partial: []
---/ci---"

If no milestone branch exists (single-phase milestone):

git checkout main
git merge --squash phase/NN-slug
git commit -m "docs(P##): complete [phase-name] phase

---ci---
phase: [N]
milestone: [vX.Y]
status: complete
requirements:
  covered: [REQ-01, REQ-02]
  partial: []
---/ci---"

Milestone ship (after last phase)

Validate all phase branches are merged into the milestone branch before proceeding.

git checkout main
git merge --squash milestone/vX.Y-slug
git commit -m "docs(milestone): complete [milestone-name]

---ci---
phase: 0
milestone: [vX.Y]
status: complete
---/ci---"

Step 6: Tag and Push

git tag -a vX.Y.Z -m "vX.Y.Z: [phase-name or milestone-name]"
git push origin main --tags

Tag format by milestone type:

  • NFR/Feature phase: patch format (v0.5.1, v0.5.2)
  • Major phase: minor format (v0.3.0, v0.4.0)
  • Feature milestone: next minor (v0.6.0, NOT v0.5.0)
  • Major milestone: next major (v1.0.0)

Step 7: Create Release and Package

Every ship creates a Gitea release. No exceptions.

Generate release notes

git log v[previous_tag]..vX.Y.Z --oneline

Create the Gitea release

curl -X POST "https://git.cloudinit.dev/api/v1/repos/continuous-intelligence/ci/releases" \
  -H "Authorization: token $GITEA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tag_name":"vX.Y.Z","name":"vX.Y.Z","body":"[release notes from git log]"}'

For milestone releases, include a summary of all phases completed and requirements covered.

Create distribution packages

Use coreci to create the necessary distribution packages:

coreci build --tag vX.Y.Z
coreci package --tag vX.Y.Z

Upload packages to the Gitea release:

coreci release upload --tag vX.Y.Z --files [built-artifacts]

Generate documentation

Include release notes in the Gitea release body with:

  • Summary of changes
  • Requirements covered
  • Known issues (if any)
  • Migration notes (for major milestones)

Step 8: Update .ci/ Files

  • Update .ciagent/REQUIREMENTS.md — mark shipped requirements as complete
  • Update .ciagent/ROADMAP.md — mark shipped phase as complete

Commit the file updates.

Step 9: Report

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 CIAgent ► SHIPPED
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Phase [N]: [name]
Milestone: [vX.Y] ([nfr|feature|major])
Version: vX.Y.Z
Release: https://git.cloudinit.dev/continuous-intelligence/ci/releases/tag/vX.Y.Z
Status: complete

Tests: PASS
Typecheck: PASS
Build: PASS
Pipeline: PASS

Requirements covered: [N]
Commits: [N]

[If milestone complete:]
All phases in milestone v0.2 complete. Milestone released as vX.Y.Z.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━