Phase 4 · Build: compose the bricks, then apply the signed change list
Produce the customer's repo: it depends on the bricks at their tags and holds only what is the
customer's. Build only from a signed change list. Back: dodil://erp/build.
Steps
- Already ran
initat Discover (HR)? Skip to step 2: that folder is the build. Otherwise run one command IN THE PROJECT FOLDER (your current working directory: the customer's repo; never/tmpor a scratch path, or the customer can't find what you built), naming the module(s); no DODIL login needed:
Nouvx --from git+https://git.dodil.io/dodil/erp-platform.git@v0.7.3 erp-compose init hruvx?python3 -m venv ~/.erp-compose && ~/.erp-compose/bin/pip install git+https://git.dodil.io/dodil/erp-platform.git@v0.7.3 && ~/.erp-compose/bin/erp-compose init hr. It reads this method'sreference.reposandbrick_entries, clones each repo at its tag intobricks/, installs them into.venv(erp-platform first), writesrequirements.txt,compose.yamlandtests/test_composition.py, and runserp-compose checkand the test. It must end withReady; if it exits non-zero, fix what it names. Never hand-write these files. Then read each brick's README.md and AGENTS.md (bricks/<repo>/) before writing anything. - Configure: apply the change list in order, by depth:
- depth 1: rows, through the bricks' own use cases (for HR the signed
config/hr.calls.yaml, replayed as is; never an INSERT into a brick's table, never an edit underbricks/). Then regenerate the process view (erp-compose process) and runerp-compose signoff verifyon it.
- depth 1: rows, through the bricks' own use cases (for HR the signed
- Extend (depth 2): a new brick in the customer's org from
erp-platform/templates/brick-example/(BRICKS.md) providing the capability, added tocompose.yaml. A module no brick covers is a new brick in the same shape (modules/pattern.md§2), its logic generated fromERP_<MODULE>.md, with the story id in each use case's docstring. - Own (depth 3):
dodil git repo fork <brick>into their org; record in the fork's README the upstream tag and the change items it carries; pin the fork's tag incompose.yaml. - The gate (erp-platform v0.8.0, its own step):
uvx --from git+https://git.dodil.io/dodil/erp-platform.git@v0.8.0 erp-compose plan compose.yamlREFUSES a module with nosignoff/<module>.json, a pending change, or a BPMN that no longer matches what was signed; so doesmigrate. Never route around it:--unsigned "<reason>"is recorded insignoff/<module>.unsigned.jsonand the bench sees it. From v0.8.0initPINS the bricks in requirements.txt (nobricks/;--read-copyto read them); depth 3 iserp-compose own <brick> --reason "<CR>"(copies it toowned/, records the upstream tag). - Show it on localhost (
.venv/bin/erp-compose serve compose.yaml, test copy only); tick each change item built in Deviations.
What init writes, for reference (HR, in a folder named acme)
name: acme-hr
version: 0.1.0
tier: 1
bricks:
- { name: hr, brick: "brick_hr.application.use_cases:HR", version: 0.3.0 }
- { name: bp, brick: "brick_bp.application.use_cases:BP", version: 0.3.0 }
Done when
-
erp-compose checkis clean andtests/test_composition.pypasses. - Every change item is built, and the regenerated process view matches the signed one.
- No brick clone differs from its tag except a declared fork.
-
erp-compose planpasses the gate with no--unsigned.
Next: dodil://erp/phase/test