Phase 9c · Change: v1 → v2 of a signed process (Mode B)
Produce v2: the change list, the redrawn BPMN, an impact report with real counts, the migrations,
and a new sign-off superseding v1. A conversation first, then autonomous work. Back: dodil://erp/build.
The signed BPMN drives every change; the code follows, never the reverse. Strict order: (1) redraw, the changes marked; (2) ask "are you confirming these changes?" with the consequences in plain words; (3) re-sign; (4) only then change the code. Found the code already changed? Stop and take the diagram to the customer. Why: agents forget follow-ups, and the end user can't read code.
Steps
-
Understand, interactively. Restate the request in their words; ask one to three questions with choices: what about existing records, who may do it, what should happen automatically, what else depends on it. A new capability ("can it also invoice?") is not a change: go to phase 0.
-
Locate by element id on the signed diagram, then the stories, rows, tables and screens it touches. Classify each item's depth (configure / extend / own) and check the foundation (fit card).
-
Redraw (v0.8.2, one process: add
--process <playbook>when the module has several):uvx --from git+https://git.dodil.io/dodil/erp-platform.git@v0.9.13 erp-compose change propose --module <m> --from ERP_<MODULE>.md(or--bpmn):signoff/<m>/<process>.change.bpmnmarks each element added / removed / changed; the summary names lost scenarios, deviations and refusals. Pending: plan, migrate and CI refuse until signed. -
Count, read-only, before asking: how many records each change touches (test copy; live read-only).
-
Send the change view and the impact as its own message, then ask "Are you confirming these changes?":
bricks and depth · rows before → after · code (their brick or fork) · migrations with counts ("12 open runs stay on playbook v1") · how to undo it.
-
On their typed yes: add
CR-<n>, thensignoff record … --reason "CR-<n>: …" [--implemented-by 00007_<migration>]: version n+1, append-only (signoff/<m>/history/<process>.v<n>.json). Forward only: a revert is a new version equal to an old one, with its reason. -
Execute: rows, code, tests; migrate the test copy; show localhost. Work in flight keeps the version it started under (brick-hr freezes a run's playbook version); new work uses the latest.
-
Go live on their word: export the affected live tables, migrate live, deploy, self-check, and report what changed, how many records, and how to undo it. Mark the CR live.
Migrations
Versioned migrations per brick (migrations/NNNNN_<name>/up.sql + down.sql, a journal
<prefix>_schema_migrations per brick, erp-migrate up/down, bricks in dependency order) are the
design, and not built yet. Until they are, by hand: add a column at the END of its CREATE in
schema.sql and as an explicit ALTER, run erp-compose migrate compose.yaml on the test copy,
read the table back (reads settle in minutes). A rename or type change is add → backfill → switch
reads → drop later. Write every step idempotently.
Example (a backfill they chose)
-- depth 3, in their fork of brick-hr: "record the laptop serial at return" (also end of its CREATE)
ALTER TABLE hr_engagement ADD COLUMN laptop_serial VARCHAR;
UPDATE hr_engagement SET laptop_serial = 'unknown' WHERE laptop_serial IS NULL; -- the value they chose
Done when
- v2 is signed, superseding v1; the CR names element ids; v1 runs still behave as v1.
- The migration ran on the test copy, then live, and re-running it changed nothing.
Back to: dodil://erp/phase/operate