Skip to content

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.

DONE wave 0 · p0 · deep-work profile · parallel safe

Part of fly-deployment — The container image is a projection of the repository model, and its smoke is its evidence.

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

The kind exists on the trunk: share/kinds.yaml declares deployment against the schema majordomus.deployment/v1, share/allow/deployment.txt closes its keys and is generated from that schema, and .ai/repo/deployments/majordomus.yaml describes this repository's own deployment beside the directory's README. The work reached master with feature/deployment-core and nothing was ever recorded against this issue, so the milestone reads PLANNED 0/32 while its first artifacts are on the trunk. Measured on master 6042f4286, 2026-09-10; not marked complete here because this issue's own validation (bash test/run.sh, bin/majordomus doctor) has not been rerun against that tree.

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

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

coverstypecommandresultat commit
kind_registeredartifactgrep -n -A3 '^ deployment:' share/kinds.yamlshare/kinds.yaml declares kind deployment against schema majordomus.deployment/v1; share/allow/deployment.txt (41 keys) is generated from that schemaf075170
object_indexedtestbin/majordomus-cli run objects.list --input '{\"kind\":\"deployment\"}' --format json; bin/majordomus-cli run objects.get --input '{\"uri\":\"majordomus://deployment/majordomus\"}'objects.list returns one object majordomus://deployment/majordomus at .ai/repo/deployments/majordomus.yaml; objects.get reads it (state succeeded); the generic object surface, no deployment-specific listing codef075170
keys_closedtestbash test/run.sh 84_deployment_contractok 84_deployment_contract: doctor refuses an unknown key by name (key(s) the contract does not have: fly_api_token), a foreign schema, a missing region, a credential, a duplicate identity; the restored object is acceptedf075170
directory_contractartifactgrep -nE 'uthoritative|enerated|egenerat' .ai/repo/deployments/README.md; bin/majordomus doctor | grep deploymentthe context/v1 README ai.repo.deployments has sections 'What is authoritative and what is generated' and 'Regenerate' (ADR 0011); doctor: OK deployment .ai/repo/deployments/ — 1 deployment(s), no credential, one identity eachf075170

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
2026-10-04T09:55:21Z
verified
2026-10-04T09:59:52Z
completed
2026-10-04T10:00:11Z

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.

Searches the titles and descriptions of every page this site publishes.