I0901 — The deployment description is a kind of the layer, not a provider file
Register `deployment` as a kind of the AI layer — allowed keys, schema, directory contract — and describe this repository's own deployment as one object under .ai/repo/deployments/, so that every later projection reads one file and no provider file is ever authoritative.
READY wave 0 · p0 · deep-work profile · parallel safe
Ready. Every dependency is done, so majordomus plan start I0901 will be accepted.
Objective
Register `deployment` as a kind of the AI layer — allowed keys, schema, directory contract — and describe this repository's own deployment as one object under .ai/repo/deployments/, so that every later projection reads one file and no provider file is ever authoritative.
Why
A Dockerfile and a fly.toml written by hand would restate the port, the routes, the resources and the build inputs that the repository already knows. The layer already has a mechanism for canonical facts: a kind, its allowed keys, its schema and its directory contract. Deployment is a kind, and everything downstream is a projection.
Current state
No deployment kind, no .ai/repo/deployments directory, no allow file and no schema exist. share/kinds.yaml registers every other kind the layer holds.
Desired state
A deployment object is indexed, readable through the same object surface as every other kind, closed by an allow file, described by a schema, and living in a directory that carries its own context document.
Scope
- .ai/repo/deployments
- share/kinds.yaml
- share/allow/deployment.txt
- share/schemas
Out of scope
- Any provider artifact; this issue writes no Dockerfile and no fly.toml
- Any Rust; the typed model is I0902
- Any secret value, credential name or token
Dependencies
None. This issue is a root of the graph.
What waits on this
- I0902BLOCKED The deployment object becomes typed Rust that refuses nonsense
- I0924BLOCKED The decision is recorded where architecture decisions are recorded
Acceptance criteria
- The object states the generic deployment facts — application identity, package and binary, listen port, health and readiness routes, resources, machine count, region, autostart and autostop, build inputs, budgets — and keeps provider-specific facts in a named provider block rather than mixed through the generic ones
- Keys are closed by share/allow/deployment.txt and an unknown key is refused
- The directory carries a context README that says what is authoritative, what is generated and how to regenerate it, per ADR 0011
- The object is listed and read through the existing object surface with no code that special-cases it
- No secret value or credential name appears in the object
Validation
- bash test/run.sh
- bin/majordomus doctor
Evidence required
- kind_registered
- keys_closed
- directory_contract
- object_indexed
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 schema written for one deployment becomes either a Kubernetes-grade abstraction nobody needs or a Fly file with a different extension. It has to be generic where a second provider would plausibly reuse it and concrete everywhere else.
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/I0901.yaml. Read it back with majordomus plan show I0901.