I0914 — One deployment core, one command, and a dry run that mutates nothing
Implement the deployment operations — validate, plan, generate, build, status, deploy, smoke — once in the typed core, expose them through thin adapters, and provide one ergonomic command that performs the whole sequence safely and can be asked to change nothing.
BLOCKED wave 4 · p0 · deep-work profile · parallel safe
Blocked. This issue cannot start until I0903, I0909, I0913 are done. The status is derived from that, not declared.
Objective
Implement the deployment operations — validate, plan, generate, build, status, deploy, smoke — once in the typed core, expose them through thin adapters, and provide one ergonomic command that performs the whole sequence safely and can be asked to change nothing.
Why
Deployment logic spread across a script, a workflow, a Makefile target and an entrypoint means four places each knowing half the truth. One core with thin adapters is the same rule the capability registry already enforces for everything else.
Current state
Nothing performs any deployment step. Every operation named here does not exist.
Desired state
The core owns the semantics, the CLI is an adapter, CI calls the same core, and a dry run reports exactly what a real run would do without touching the provider.
Scope
- apps/majordomus-cli/src/deploy/core.rs
- apps/majordomus-cli/src/commands/deploy.rs
Out of scope
- Deployment logic in a shell script beyond thin adaptation
- Interactive prompts in a non-interactive path
- Creating a new application on every invocation
Dependencies
- I0903BLOCKED Deployment reads are declared once and projected everywhere
- I0909BLOCKED The production image is a generated projection of the build specification
- I0913BLOCKED The provider configuration is generated, and the cheap profile is declared
What waits on this
- I0915BLOCKED Deployment joins the diagnostics that already exist
- I0916BLOCKED The smoke suite is derived from the route registry, never written twice
- I0917BLOCKED A bad deployment can be undone deterministically
- I0931BLOCKED The application exists, one machine runs it, and the URL answers
Acceptance criteria
- The sequence is validate, verify projections, preflight credentials and configuration, build, deploy, wait for health, assert the machine inventory, run the smoke suite, publish a summary — and a failure at any step stops the ones after it
- A dry run performs no mutation and reports the same plan the real run would execute
- Plan and doctor are read-only, and repeated runs without a source change converge rather than creating new resources
- Failures name the source of truth, the observed state and the command that repairs it, rather than reporting that deployment failed
- No token value can appear in any output, including verbose and error paths
Validation
- cargo test --workspace --all-features
- majordomus deploy --dry-run
Evidence required
- core_operations
- dry_run
- one_command
- actionable_failures
Evidence
None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.
Risk
A single command that does everything is also a single command that does something unintended. The dry run and the read-only operations are what make it safe to run without reading its source first.
Timeline
- started
- —
- verified
- —
- completed
- —
Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.
Canonical record: .ai/repo/project/issues/I0914.yaml. Read it back with majordomus plan show I0914.