Component Contract
A component is declarative data. Its deploy is a composition of capabilities, not a script. The authoring form is TypeScript; it projects to a portable JSON contract that a non-chant or legacy component can hand-write and the same orchestrator can drive.
The shape
Section titled “The shape”interface Component { name: string; dependsOn: string[]; // ordering only — no logic
build?: BuildSpec; // optional: source → BuildArchive (image/zip/jar, held in the archive)
deploy: Phase[]; // the component's own composition over shared capabilities // verify + rollback fall out of the capabilities used
liveNames?: string[]; // optional: live entity/resource name(s), when they differ from `name`}build is optional: a config-only component has none. deploy is a composition using the same grammar as Ops — phases, parallel, gate, onFailure, dependsOn. See Composition & Wiring.
Archetypes
Section titled “Archetypes”Because deploy is a composition, build-only and apply-only shapes are first-class, not special cases.
| Archetype | Phases | Example |
|---|---|---|
| Service | build → publish → apply → verify | An ECS service behind an ALB |
| Infra | apply → verify (no build) | A DynamoDB table, an EMR cluster, RDS/OpenSearch |
| Producer / library | build → publish (no service apply) | A Java/JAR build published to S3 for EMR |
A producer emits an artifact other components consume; its deploy is a single Publish phase. See cross-component wiring.
A worked service
Section titled “A worked service”An ALB/ECS target: build an image, promote it at deploy time, apply the stack that registers the service on a shared ALB, wait for steady state. The shared-ALB values arrive as cross-stack outputs, resolved by the graph rather than by a describe-stacks shell script.
import { phase, type Component } from "@intentius/chant/components/component";import { dockerBuild, publishImage, cfnDeploy, ecsUpdateService, waitSteadyState } from "@intentius/chant/components";
export const searchService: Component = { name: "search-service", dependsOn: ["shared-alb"], build: dockerBuild({ context: ".", into: "archive" }), deploy: [ phase("Publish", [publishImage({ from: "archive", to: "$env.registry" })]), // → digest phase("Apply", [ cfnDeploy({ template: "archive:search.template.json", inputs: { ...sharedAlb.outputs, image: "@Publish.digest" } }), ecsUpdateService({ cluster: "$env.cluster", service: "search" }), ]), phase("Verify", [waitSteadyState({ service: "search" })]), ],};The JSON projection
Section titled “The JSON projection”The authoring form projects to a portable, versioned JSON contract. This is the substrate: the same document can be hand-written for a legacy component and driven by the same orchestrator.
{ "name": "search-service", "dependsOn": ["shared-alb"], "build": { "kind": "docker-build", "context": ".", "into": "archive" }, "deploy": [ { "phase": "Publish", "steps": [{ "kind": "publish-image", "from": "archive", "to": "$env.registry" }] }, { "phase": "Apply", "steps": [ { "kind": "cfn-deploy", "template": "archive:search.template.json", "imageRef": "@Publish.digest" }, { "kind": "ecs-update-service", "cluster": "$env.cluster", "service": "search" } ] }, { "phase": "Verify", "steps": [ { "kind": "wait-steady-state", "service": "search" } ] } ]}Discovery
Section titled “Discovery”A component is discovered the same way chant already discovers resources — by convention, from source, with no registration step. Export a Component (any export name) from a *.component.ts file anywhere under the project (excluding node_modules and a nested project’s own chant.config.ts scope) and chant finds it. archetype does not have to be authored explicitly: when omitted, chant infers it from the composition’s shape (a build present or absent, and whether every step in deploy is publish-family) — the same inference projectToJson applies before validating against the schema.
export const searchService: Component = { name: "search-service", // archetype omitted — inferred as "service" (build + a non-publish Apply step) dependsOn: ["shared-alb"], build: dockerBuild({ context: ".", into: "archive" }), deploy: [ /* … */ ],};chant list --components # inventory: name, archetype, dependsOn, phaseschant describe search-service --components # one component's full JSON projectionchant graph --components # dependency order + parallel-safe wavesRead next
Section titled “Read next”- Capabilities — the verbs a
deploycomposes. - Composition & Wiring — phases, fan-out, cross-stack and cross-component references.
chant list,chant describe,chant graph— the--componentssurfaces.