Phases 6-8 · Deploy: provision, ship, verify with a real person
Produce a test copy and a live copy, a deploy from git push, and proof that the app reaches its
data and a real person can sign in. This is the first phase that needs a DODIL login: if you are not
signed in, ask the person to run dodil auth login. Back: dodil://erp/build.
Steps: provision + deploy, one command (erp-platform >= 0.9.12; dev first, live after "go live")
A composition ships ONLY through its own private Dodil Git repo: git push → forge CI → registry → CD
(.dodil/deploy.yaml). Never dodil ignite app deploy --code: a laptop snapshot, capped near 1 MB.
- Signed first: the customer's
erp-compose signoff record --all --approver "<name>" --reason "…";erp-compose signoff verify --allmust pass, or deploy refuses. .venv/bin/erp-compose deploy compose.yaml --org acme --name acme-dev --warm. Idempotent: a re-run resumes and keeps what exists. Every call passes--org; the active org is never switched.- provision: bucket; pool (sign-up OFF, CIMD ON, the app's callback ADDED to the redirect URIs); roles
MERGED, never replaced; service account
acme-dev-appwithk3.editoron this bucket only; a machine service client; the repo's CI secrets from stdin. Secrets stay in~/.dodil-secrets/acme-dev/. - migrate + seed
config/*.calls.yamlas the app's own service account. - files: Dockerfile,
app.py,build.yml(dodil git ci init, checkbuild/build),ci.yml(checkci/signoff),.dodil/deploy.yaml(user_pool, env from${{ secrets.… }},when: require_checks: [build/build, ci/signoff]). - ship: private repo,
dodil git ci verify,git push, then it follows the checks and the CD deploy. --warm:--reserved 1(Claude.ai allows ~10 s to connect; a cold start took 12–18 s).
- provision: bucket; pool (sign-up OFF, CIMD ON, the app's callback ADDED to the redirect URIs); roles
MERGED, never replaced; service account
- Every later release is
git push. A process changed without a new signature failsci/signoff. - A test copy or a proof comes back with
erp-compose teardown compose.yaml --org acme; it lists each kind of resource to show none remain. Then create one user per role:dodil appid user create acme-dev <email>.
Steps: verify
- deploy's self-check:
/healthz200, then MCP initialize + tools/list with the machine client's token. A 401 on the public URL proves only that the gateway is up. - A real person signs in, once per role. You never set passwords, so this is the customer's step; the module is not verified until it has happened.
- Their agent connects as them: Claude.ai registers itself and arrives pending:
dodil appid client list acme-dev, thendodil appid client approve acme-dev <id>. A machine (a job, Claude Code) uses a service client instead; never a person's agent. - Scenarios live against the dev deploy (
erp-scenarios run … --live, test card).
Example (wire settings for any driver)
pg: host=pg.uk-lon-1.dodil.io port=5432 dbname=acme-dev sslmode=require
bolt: bolt+s://bolt.uk-lon-1.dodil.io:7687 never prefer, never neo4j+s://
Done when
- deploy's self-check passes on dev, then live after "go live"; teardown leaves nothing of a test copy.
- A person per role signed in; their agent was approved and sees only their rows.
-
A person's FIRST connect from Claude.ai works on a cold attempt (no retry), with the app at
--reserved 1.
Next: dodil://erp/phase/operate