Skip to content

A deployment object that breaks its closed contract, whether by a key the contract does not have, another schema version, a missing field, an interface, port, machine count or health route that could not work, a value that reads as a credential or an identity two files claim, is refused by doctor with the reason named

A deployment of the executable is one YAML object under the layer's deployments section,

declared statusdeclared status: guaranteed Declared deterministic and blocking, implemented, and naming the behavioural test that is to prove it. Whether a recorded run supports it is the evidence verdict, shown beside it.

recorded evidencerecorded evidence: not run Declared guaranteed, and not supported by a recorded run: the test is named, and no passing run of the current inputs is recorded. how evidence is recorded

This is the shell half of the contract, decided without a Rust toolchain present. The semantic half, a health route no capability registers or a package the workspace does not contain, belongs to apps/majordomus-cli/src/deploy/mod.rs and is proven by that module's own tests, not by this case. The case matches each refusal by its reason; it does not require the finding to name the object, does not check doctor's exit status and does not show the object reaching the index or the object listing, so none of those is claimed here.

What it means

A deployment of the executable is one YAML object under the layer's deployments section, read against the deployment/v1 contract. majordomus doctor refuses an object that could not work or must not exist, with a FAIL finding under the deployment category that names the reason:

  • a key the contract does not have, including a field invented to hold a token;
  • a schema version other than the one this tool reads;
  • a field every deployment states, missing;
  • a listen interface that is neither loopback nor all;
  • a port outside the unprivileged range, since the deployed process does not run as root;
  • more machines kept running than the deployment has;
  • a health route written as a URL rather than a path;
  • a value that reads as a credential, in a field that does exist;
  • two objects claiming one identity.

init seeds the section with its contract and no objects, an empty section is not a finding, and a valid object added as one file is accepted and counted by doctor.

How it works

mj_validate_deployments in lib/deployment.sh is the validator the vendored rule majordomus.deployment-contract declares, dispatched from doctor and watch. It flattens each object, compares its keys with share/allow/deployment.txt (an allow-list generated from the contract's schema, never written by hand), and then checks the schema version, the required fields, the interface, the port range, the machine counts, the health routes, the values that match known credential prefixes and the identities already seen. Each violation is a FAIL finding under the deployment category with the reason and the command that shows the offending lines.

test/cases/84_deployment_contract.sh proves it by mutation. It initialises a repository, confirms an empty section is not a finding, adds one valid deployment and confirms doctor accepts and counts it, then applies each violation above to that object in turn and requires doctor to refuse it with the reason named. It also checks that the allow-list is the projection of the schema, and that the restored object is accepted again, so each refusal is known to come from the mutation rather than from the shape of the fixture.

How to see it

majordomus doctor                                  # FAIL deployment <object> — <reason>
bash test/run.sh 84_deployment_contract            # the refusals, one mutation at a time
cat share/allow/deployment.txt                     # the keys the contract allows

What it does not cover

The case matches each refusal by its reason, not by the object it names. A finding that named the wrong file, or no file, would still pass it, so which object a refusal names is not part of this guarantee. It does not check the exit status doctor returns on a refusal, and it does not show that an accepted object reaches the index or the object listing.

This is the half of the contract that is decided without a Rust toolchain. Whether a deployment works against this repository in particular, whether its health routes are routes a capability registers and whether its package and build inputs exist in the workspace, is decided by apps/majordomus-cli/src/deploy/mod.rs and proven by that module's own tests, not by this case.

The credential check matches the prefixes of known token formats. A secret in a format it does not know, written into a field the contract allows, is not recognised as one.

It does not prove that the generated container definition and its ignore file match the object; majordomus generate --check holds that, and its own case proves it. Nothing here contacts a hosting provider or proves that a deployment, once accepted, will start.

Why it exists

A deployment that cannot work should cost a failing test rather than a failed rollout, and a credential must never reach a file every clone of the repository carries. Both failures are cheap to find while the object is being written and expensive after it has shipped, so the contract is closed and checked locally, and every refusal names its reason, so the fix is one edit rather than an investigation.

Detail rendered from docs/claims/deployment-contract-refuses-by-name.md.

From the statement to the proof

  1. 1 · the public statement

    A deployment object that breaks its closed contract, whether by a key the contract does not have, another schema version, a missing field, an interface, port, machine count or health route that could not work, a value that reads as a credential or an identity two files claim, is refused by doctor with the reason named

    No feature or README responsibility names it; this page is where it is stated.

  2. 2 · the canonical claim

    deployment-contract-refuses-by-namedeclared status: guaranteed in docs/CLAIMS.yaml

    Defined in .ai/repo/rules/vendor/majordomus/rules/deployment-contract.v1.md

  3. 3 · the implementation

    lib/deployment.sh

  4. 4 · the test and the scenarios

    Test: test/cases/84_deployment_contract.sh

  5. 5 · the recorded runs

    recorded evidence: not run how evidence is recorded

Verify it yourself

The test runs in a disposable temporary repository and asserts the behaviour, not a string in the source.

from a clone of the repository
bash test/run.sh 84_deployment_contract

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