chant scenario
Synopsis
Section titled “Synopsis”chant scenario check [flags]Description
Section titled “Description”chant scenario check evaluates every Scenario declared in the project. For each one it builds a ChangeSet the same way chant lifecycle plan does, with one substitution: the scenario’s given fixture stands in for a live observation, so no plugin’s describeResources ever runs and no credentials are ever read. It is safe to run in CI on every PR.
No provider is contacted on either fixture form. A given of snapshot("fixtures/….json") is a file read and reaches no network; a given of snapshot(env) first runs git fetch <remote> chant/lifecycle to refresh the recorded snapshots, which reaches the git remote the repository is already cloned from and nothing else. Network Egress lists both, with the guard test that holds them.
The resulting change set is checked against the scenario’s expect clauses. Output is pass/fail per scenario. Each failing clause shows what was expected and what the plan proposes, naming resources for deletes and unobserved failures.
A lexicon the fixture has no data for is never silently read as “nothing declared, all absent”. Every entity it declares is in the change set as unobserved, the same as a live read that could not look (#1089). A hole the fixture can’t fill is reported as a hole.
A declared effect receipt gets the same treatment chant lifecycle plan gives it: its own effect classification against the fixture, not the generic create/update/delete axis. An unfired receipt never reads as a bare create; a receipt present in the fixture with a stale or mismatched value never reads as a clean noop. See Plan Scenarios for what a fixture needs to carry for a receipt to resolve offline.
See Plan Scenarios for the Scenario/snapshot() declaration API and the full expect vocabulary.
| Flag | Description |
|---|---|
--json | Emit every scenario’s verdict as structured JSON instead of the human report |
Example
Section titled “Example”import { Scenario, snapshot } from "@intentius/chant";
export const composeIsNeutral = Scenario("extracting the composite is plan-neutral", { given: snapshot("fixtures/prod-baseline.json"), expect: { noop: true },});$ chant scenario check
extracting the composite is plan-neutral [composeIsNeutral] — given fixtures/prod-baseline.json, env prod: PASS
1/1 scenario(s) passedA declaration that changes the plan against the same fixture fails, with the failing clause and the resource named:
extracting the composite is plan-neutral [composeIsNeutral] — given fixtures/prod-baseline.json, env prod: FAIL noop: expected noop (no create/update/delete/effect) but the plan proposes 1 create, 0 update, 0 delete, 0 effect — newDatabase (AWS::RDS::DBInstance) [create]
1/1 scenario(s) failedFixtures
Section titled “Fixtures”given: snapshot("fixtures/prod-baseline.json") reads a checked-in file, in the same JSON shape chant lifecycle snapshot <env> writes (one lexicon’s recorded resources per file). Record one, copy it into the project, and commit it:
chant lifecycle snapshot prod# then copy the recorded snapshot out of the chant/lifecycle branch:git show chant/lifecycle:prod/aws.json > fixtures/prod-baseline.jsongiven: snapshot("prod") reads the current last-recorded snapshot for that environment straight off the chant/lifecycle branch. There is no file to keep in sync, but the scenario’s answer moves whenever a new snapshot is recorded.
A cost clause reads the fixture’s behaviour block, the BehaviourResult a lexicon’s predictBehaviour() returned for that estate, recorded on the snapshot beside its resources. The block is held to the behaviour contract on the way in, so a hand-edited fixture with a negative rate is refused as not a prediction. A fixture with no block, or whose block is a refusal, fails the clause with that reason:
the checkout path stays under 12.50 USD an hour at peak [peakStaysUnder] — given fixtures/prod-baseline.json, env prod: FAIL cost: the fixture's prediction is a refusal (no-engine), and a bound cannot be checked against no figure: behaviour: refused (no-engine) — predictBehaviour has the chant estate to predict and no engine to predict it with. …See Plan Scenarios for which figure the clause bounds.
Exit Codes
Section titled “Exit Codes”| Exit | Meaning |
|---|---|
0 | Every declared scenario passed (or none are declared) |
1 | The build failed, a fixture could not be resolved, or at least one scenario failed |
See Also
Section titled “See Also”- Plan Scenarios — the declaration API, the
expectvocabulary, and whyupdatecan only ever assert0 lifecycle plan— the live command a scenario mirrors offline- Core Type System: ScenarioDeclaration — the type reference