Orient yourself first
npm run crm -- app inspect --json
Read valid, then problems[], then limitations[], in that order. Every problem is fixed or reported before anything is built on top of it, and every limitation is a hard boundary on what you may claim. Then read packages[], capabilities[], resources[], actions[], policies[] and providers[]: that list is what exists. A capability absent from the report does not exist, whatever a record name, a label or a document suggests.
If the repository documents this skill names are absent, you are in a project built from this framework rather than in the framework itself. The inspection report is then the source of truth and those documents are optional background — do not guess at their contents, and do not assume a path exists because this skill names it.
actions[] tells you which lifecycle steps already exist and their declared fromStates, which is usually the answer to step 0 below.
- First decide which tool fits. A lifecycle step on one record (qualify,
close, approve) is a record action — see the create-crm-module skill, and
docs/ACTIONS.md as background where the project carries it; the action
runtime already gives you one atomic transaction, events released only after
commit, and a trace. Use a workflow for a multi-record or multi-step process,
or when a human approval gate is involved.
0b. Do not write a task table. If the step you are adding means "a person
must now do something", that is one shared model: work-task and
work-activity, opened through the work package's declared capability
work/follow-up@1 inside your own transaction, keyed by a business
identity that never contains a clock — that last part is yours to
guarantee: Work refuses invalid syntax, not a key that looks like a
timestamp, so derive it from a committed record id and prove it with a retry
test of your own. It will also refuse to write at all if you call it outside
a transaction, rather than risk a task without its activity. Check
capabilities[] in the inspection report for it. A second per-domain task table is the divergence
Work v1 exists to stop (docs/WORK_TASKS.md, ADR-030 as background where the
project carries them). Two things it is not: it schedules nothing —
dueAt is evidence and no clock moves a status — and it notifies and assigns
nobody. If the business event does not actually imply human work, create no
task.
- Read the workflow engine and an existing workflow in this project's own
source (
packages/workflows/src/engine.js here). The engine is the contract;
copy an existing workflow's shape rather than inventing one.
- Express the business process as small named steps.
- Keep policy deterministic and explicit; an LLM may recommend but must not silently decide protected state.
- Use module services for all state changes.
- Add compensation for external reversible side effects.
- Emit domain events only after the authoritative state change succeeds.
- Test the policy boundary, failure path and final trace.
- Run
npm run verify and document any new architectural rule.
1---2name: create-crm-workflow3description: Implement a deterministic cross-module CRM process with policy, trace, audit and optional human approval. Use for stage transitions, follow-ups, onboarding, renewals and approval rules. Do not use for a stated business objective ("we need to manage renewals") — that is solve-business-goal, which discovers what exists first and may call this skill itself; nor for a single custom object (create-crm-module), a named milestone (the build-* skills) or a failing run (debug-crm-run).4---56## Orient yourself first78```bash9npm run crm -- app inspect --json10```1112Read `valid`, then `problems[]`, then `limitations[]`, in that order. Every problem is fixed or reported before anything is built on top of it, and **every limitation is a hard boundary on what you may claim.** Then read `packages[]`, `capabilities[]`, `resources[]`, `actions[]`, `policies[]` and `providers[]`: that list is what exists. A capability absent from the report does not exist, whatever a record name, a label or a document suggests.1314If the repository documents this skill names are absent, you are in a project built from this framework rather than in the framework itself. The inspection report is then the source of truth and those documents are optional background — do not guess at their contents, and do not assume a path exists because this skill names it.1516`actions[]` tells you which lifecycle steps already exist and their declared `fromStates`, which is usually the answer to step 0 below.17180. First decide which tool fits. A lifecycle step on **one record** (qualify,19 close, approve) is a **record action** — see the create-crm-module skill, and20 `docs/ACTIONS.md` as background where the project carries it; the action21 runtime already gives you one atomic transaction, events released only after22 commit, and a trace. Use a workflow for a multi-record or multi-step process,23 or when a human approval gate is involved.240b. **Do not write a task table.** If the step you are adding means "a person25 must now do something", that is one shared model: `work-task` and26 `work-activity`, opened through the `work` package's declared capability27 `work/follow-up@1` **inside your own transaction**, keyed by a business28 identity that never contains a clock — **that last part is yours to29 guarantee**: Work refuses invalid syntax, not a key that looks like a30 timestamp, so derive it from a committed record id and prove it with a retry31 test of your own. It will also refuse to write at all if you call it outside32 a transaction, rather than risk a task without its activity. Check33 `capabilities[]` in the inspection report for it. A second per-domain task table is the divergence34 Work v1 exists to stop (`docs/WORK_TASKS.md`, ADR-030 as background where the35 project carries them). Two things it is **not**: it schedules nothing —36 `dueAt` is evidence and no clock moves a status — and it notifies and assigns37 nobody. If the business event does not actually imply human work, create no38 task.391. Read the workflow engine and an existing workflow in this project's own40 source (`packages/workflows/src/engine.js` here). The engine is the contract;41 copy an existing workflow's shape rather than inventing one.422. Express the business process as small named steps.433. Keep policy deterministic and explicit; an LLM may recommend but must not silently decide protected state.444. Use module services for all state changes.455. Add compensation for external reversible side effects.466. Emit domain events only after the authoritative state change succeeds.477. Test the policy boundary, failure path and final trace.488. Run `npm run verify` and document any new architectural rule.