Skip to content

Spec manual deployment approval for #106 - #128

Merged
shipmill-romamo[bot] merged 1 commit into
mainfrom
spec/008-enforce-manual-approval
Oct 30, 2026
Merged

shipmill-romamo[bot] merged 1 commit into
mainfrom
spec/008-enforce-manual-approval

Conversation

@shipmill-romamo

@shipmill-romamo shipmill-romamo Bot commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Spec for #106

Adds docs/specs/008-enforce-manual-approval.md (status: approved; merging it is the approval). Spec only, no code.

Design

  • A new person-only command, cloudfall release approve COMPONENT --release RELEASE, verifies the artifact, asks the person to type the release id at a terminal (PERSON_REQUIRED off a terminal, ATTESTATION_MISMATCH on a typo, --yes never answers it), and writes one ReleaseApproval record under decisions/releases/. The record names the application, component, release, archive SHA-256, git commit, the component's servers, the approver, and an expiry (24 h by default). It deploys nothing, and it is not an MCP tool
  • deploy --yes on a manual application refuses with 4 PRECONDITION (deployment_approval_missing) unless a record names the same component, release and archive digest and the same servers and hasn't expired. The error names the exact release approve command. The plan without --yes shows an approval object (status, the record that counts, the records that don't and why, the command)
  • automatic applications deploy as today and the approvals folder is never read for them
  • migrate --yes pauses at deploy:<component> until the release is approved, then resumes without rebuilding
  • rollback and restart need no approval (see below)
  • Breaking: a ### Breaking changelog entry, with two ways to migrate: approve each release first, or switch to approval: automatic when GitHub reviewers are the real gate. The CI guide gets an approve-then-deploy flow (a build job uploads the artifact, a person approves and commits the record, the deploy job downloads the same artifact)

Decisions for you

  1. Command name. cloudfall release approve COMPONENT --release R (recommended: a short top-level group, next to deploy) or cloudfall decisions approve-release, which keeps it under the existing approvals but mixes a project-mode command into the fleet-mode decisions group
  2. Where records live. decisions/releases/ in the project, committed with it (recommended: CI finds the approval in its checkout, and the approval comes in through the project's own review), or tmp/ like other receipts, which a CI runner never sees
  3. What an approval binds to. Release id plus archive SHA-256 (recommended: it approves exact bytes) or the git commit, which would let CI rebuild after approval but approves an archive nobody checked. Binding to the digest is what forces the two-job CI flow
  4. Expiry. Default 24 h, --valid-for 1 to 168 h (recommended), or no expiry, which lets an approval from months ago push an old release through CI
  5. Reuse. Reusable until it expires (recommended: a deploy that fails its health gate can be retried, and a CI runner couldn't durably write a "used" mark anyway) or single use
  6. Rollback. No approval (recommended: it only activates a release already retained on the servers, the deploy role already rolls back on its own, and an incident is the worst time to wait for a person at a terminal) or require one, which stops an agent from rolling back to an arbitrary retained release
  7. Importer default. Keep writing manual (recommended: an imported project has no other gate, so the first migrate --yes pausing for an approval is the point) or write automatic to avoid the break for new imports
  8. Approving an automatic application's release. Refused with release_approval_not_required (recommended: the record would claim a gate that doesn't exist) or allowed, so a team can approve ahead of switching to manual
  9. Server check. An approval names the component's servers, and a config change that moves the component voids it (recommended: this stands in for spec 001's staleness, which doesn't apply since an approval has no observation basis), or drop the server check and bind only to component, release and digest

Plan

  • Serves: G-2
  • Files: docs/specs/008-enforce-manual-approval.md
  • Order: the spec alone; build issues are split from it once it merges
  • Proof: approved by @romamo's answer on this PR (all nine choices as recommended)

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@shipmill-romamo

Copy link
Copy Markdown
Contributor Author

@romamo Decision needed: does spec 008, enforcing approval: manual on deploy (#106), set the behaviour the way you want, with the choices under "Decisions for you" in this PR's body?

In short: a person approves a release with cloudfall release approve <component> --release <id> at a terminal (no MCP tool for it); deploy --yes on a manual application refuses without a matching, unexpired approval; automatic is unchanged; rollback needs no approval. Projects that declare manual and deploy with --yes today break until they approve each release or switch to automatic, and CI deploys move to a build job, a person's approval, then a deploy job.

  1. Take every recommendation (recommended): your answer is the approval; shipmill merges this PR once it is green, then files its build issues under Application approval: manual is validated but deploy never enforces it #106. You may still merge it by hand
  2. Change some of them: reply with the numbers from "Decisions for you" and what you want instead; the spec is revised in this PR and you're asked again, and nothing merges until then

Reply here with a number or your own answer; shipmill takes this up on the tick after your reply.

@shipmill-romamo shipmill-romamo Bot added the needs-decision A shipmill session asked a question here; waits for a reply label Oct 27, 2026
@romamo

romamo commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

Decision by @romamo, relayed by Claude Code

  1. Take every recommendation: approved, all nine choices under "Decisions for you" as recommended.

@shipmill-romamo shipmill-romamo Bot removed the needs-decision A shipmill session asked a question here; waits for a reply label Oct 30, 2026
@shipmill-romamo
shipmill-romamo Bot merged commit 4432a30 into main Oct 30, 2026
1 check passed
@shipmill-romamo
shipmill-romamo Bot deleted the spec/008-enforce-manual-approval branch October 30, 2026 13:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant