Driving it from an agent
The SPA has no private channel: everything it shows rides plain JSON over HTTP, so an agent or a script can drive the same server headless. Start one and curl it:
npx @intentius/behold serve <chant-project-dir> # or preview / democurl -s http://localhost:4600/api | jqGET /api is the front door. It lists the routes with a one-line description each, the server’s version, and a link to the full contract.
The read loop
Section titled “The read loop”- observe.
GET /api/graphreturns{ ir, svg, meta }. Every node inir.nodescarriesid,kind,lexicon,attrs, andsourceLoc. Drift status, when present, isattrs._status:good= managed,warn= foreign,accent= pending,neutral= unobserved,runtime= runtime child. - focus. Narrow with query params:
?detail=0..3,?components=1,?logical=1,?lens=blast:<id>&down=1,?lens=lexicon:aws, plus theenv/stack/tier/targetaxes the UI’s Scope tab exposes. - go deeper. With an
?env=:/api/overlayis the live entity overlay,/api/diffslices per-node observed state / drift / field ownership,/api/reconcilesummarizes the pending change set./api/substratesreports substrate readiness, and/api/events(SSE) pusheschanged/op/apply/prso you re-pull only when something moved. - inspect. A node’s
sourceLoc.fileis the typed source that declared it. To change the estate, edit there: chant is the source of truth, not behold. Provenance rides on the node too:attrs._release(the recorded deploy: run id, origin, commit, digest, actor, approver),attrs._carve(the Terraform address a carved entity came from), and on a Helm chartattrs._renderDrift.identity(whether the running release was deployed from this project’s render).
A directory that is not a chant project gets a structured {code: "no-project", error, remedy} from /api/graph. Every other precondition failure (lint, not-installed, tier, eval) takes the same shape, so an agent branches on code instead of parsing prose.
The act loop, delegated and never direct
Section titled “The act loop, delegated and never direct”behold performs no cloud write of its own. The mutating endpoints trigger Ops the project committed: POST /api/apply?env=&component=, POST /api/ops/:name/run, POST /api/ops/:name/signal/:gate, POST /api/rollback?to=. All are guarded (one write at a time), gated where the Op declares a gate, and locked out entirely in preview and static modes. An environment .behold.json designates to a forge (executor) answers those with 409 executor-forge; its one deploy is POST /api/ci/dispatch?env=, through the operator’s gh, followed on the dial, with GET /api/ci/run the persisted record and POST /api/ci/readopt the re-follow after a restart. For build, lint, lifecycle diff and op status, prefer chant’s own MCP tools over shelling.
The contract
Section titled “The contract”The canonical version of this guide ships inside the npm package and lives at AGENTS.md. Hand it to your agent verbatim.