dodil/erp-method

erp/phase/deploy.md

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.

  1. Signed first: the customer's erp-compose signoff record --all --approver "<name>" --reason "…"; erp-compose signoff verify --all must pass, or deploy refuses.
  2. .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-app with k3.editor on 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.yaml as the app's own service account.
    • files: Dockerfile, app.py, build.yml (dodil git ci init, check build/build), ci.yml (check ci/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).
  3. Every later release is git push. A process changed without a new signature fails ci/signoff.
  4. 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

  1. deploy's self-check: /healthz 200, then MCP initialize + tools/list with the machine client's token. A 401 on the public URL proves only that the gateway is up.
  2. 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.
  3. Their agent connects as them: Claude.ai registers itself and arrives pending: dodil appid client list acme-dev, then dodil appid client approve acme-dev <id>. A machine (a job, Claude Code) uses a service client instead; never a person's agent.
  4. 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