Skip to content

I3821 — The tree a provider receives is assembled from the deployment object, and master publishes it after green ci

A typed capability deploy.slug assembles, outside the checkout, the tree a provider receives: the deployment object's build.inputs read at one commit, the generated provider files of that commit made executable, the inline buildpack line, and the executable built at that same commit; a workflow builds the musl executable at master's commit after master's ci succeeds, assembles the slug and pushes it to the provider with a workflow secret, and nothing else ever pushes to the provider. ADR 0219 decisions 3 and 5.

BLOCKED wave 1 · p1 · implementation profile · runs alone

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

Blocked. This issue cannot start until I3820 is done. The status is derived from that, not declared.

Objective

A typed capability deploy.slug assembles, outside the checkout, the tree a provider receives: the deployment object's build.inputs read at one commit, the generated provider files of that commit made executable, the inline buildpack line, and the executable built at that same commit; a workflow builds the musl executable at master's commit after master's ci succeeds, assembles the slug and pushes it to the provider with a workflow secret, and nothing else ever pushes to the provider. ADR 0219 decisions 3 and 5.

Why

The live Gigalixir application was published from a slug assembled by hand, which is the parallel universe the owner refused on 2026-10-21, and it answers the release binary's commit rather than the tree it serves.

Current state

Measured on 27d017ea16a: deploy/gigalixir/{Procfile,bin/*} are generated from the object; no capability assembles a slug and no workflow publishes to the provider; the application runs a hand-assembled slug of 573df967bb5 with the v1.0.0-alpha.1 binary.

Desired state

majordomus deploy slug --deployment majordomus --commit <sha> --executable <path> --out <dir> writes exactly build.inputs, the provider files (mode 755 for bin/*), .buildpacks and the executable, refuses an out directory inside the checkout, and records the commit; .github/workflows/provider.yml runs on a successful master ci, builds the executable with MAJORDOMUS_BUILD_COMMIT set, assembles the slug and pushes it with GIGALIXIR_EMAIL/GIGALIXIR_API_KEY secrets; case 3821 assembles a fixture slug and proves its file list, modes and recorded commit.

Scope

  • apps/majordomus-cli/src/deploy
  • apps/majordomus-cli/src/capability/builtin/deploy.rs
  • .github/workflows/provider.yml
  • test/cases/3821_a_providers_tree_is_assembled_from_the_object.sh
  • docs
  • .ai/repo/project/issues/I3821.yaml

Dependencies

What waits on this

Acceptance criteria

  • The slug holds the object's build.inputs at the named commit, the provider files with bin/* executable, the buildpack line and the executable, and nothing else
  • An out directory inside the checkout is refused
  • The workflow runs only after master's ci succeeded, builds at master's commit and pushes with secrets that appear in no file or log
  • The deployed /api/v1/live answers master's commit

Validation

  • env -u MAJORDOMUS_SHARE -u MAJORDOMUS_HTTP_HOST -u MJ_ROOT bash test/run.sh 3821_a_providers_tree_is_assembled_from_the_object

Evidence required

  • slug_assembled_from_object
  • master_publishes_after_green_ci

Evidence

None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.

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/I3821.yaml. Read it back with majordomus plan show I3821.

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