Repository navigation
Adding automations/BPMN extraction from CPG and generation in Care Plans - #197
Conversation
# Conflicts: # compose.yml
…entally committed
jaideepr97
left a comment
There was a problem hiding this comment.
thanks sam, approving with a couple minor comments
| context: . | ||
| file: cpg-ingester/deploy/pods/Containerfile.bff | ||
| - image: cpg-ingester-ui | ||
| context: cpg-ingester/ui |
There was a problem hiding this comment.
what's the reasoning behind this change specific to automations?
There was a problem hiding this comment.
Not automation-specific as such: this branch made the cpg-ingester UI consume the shared UI package (shared/ui, which now carries the BPMN viewer both UIs use). Its Containerfile copies shared/ui and so must build from the repository root, the same way the acp-writer UI entry already does. The matrix entry still pointed at cpg-ingester/ui, and the first publish run on this branch failed for that image until it was fixed. The cluster BuildConfig in cpg-ingester/deploy/setup-images.sh got the same root-context change.
| WORKDIR /app | ||
| COPY shared/ /app/shared/ | ||
| RUN pip install --no-cache-dir /app/shared/ | ||
| RUN pip install --no-cache-dir mlflow requests fastapi uvicorn "mcp[cli]>=1.0" |
There was a problem hiding this comment.
is there a specific reason for restricting mcp to the 1.x?
There was a problem hiding this comment.
Yes: the unpinned install started pulling mcp 2.x, which renamed FastMCP to MCPServer and removed the mcp.server.fastmcp module that mcp_proxy.py imports, so the freshly built MCP image crash-looped on the cluster at startup. The pin keeps the proxy working as written; nothing on the branch touched that code. Migrating mcp_proxy.py to the 2.x API is a small follow-up, tracked in the PR’s follow-up list. Worth knowing for the operator too: any image of this proxy built after the 2.x release has the same problem without the pin.
BPMN automation templates: extraction, review, synthesis and publication (interim)
What this adds
Carewright gains a second computable output from guidelines: automation templates, BPMN process definitions expressed as a JSON Process IR, compiled deterministically to Kogito-valid BPMN and validated through a static ladder that ends at the Kogito engine.
DocumentReferenceplusTaskand publishes it to the automation service.AutomationTemplate, and a shared BPMN viewer for both UIs.This is the Phase 1–3 milestone of the design plus the fixes from the first end-to-end demo. The design is captured point-in-time in
dev_docs/design/automation-design.md; the user-facing overview isdocs/automation.md. Read those two in that order.What runs where
automationservice with a shared dev token.orchestratedprofiledeploy/load-published-artifacts.sh) and read-only review all run. The automation service is not deployed; approvals record publication stateunconfigured(ornot-applicablewhen no automation is enabled) and the CarePlan is written exactly as before. No retry threads are started. The LLM gateway can be the in-cluster MaaS or the external EnMaaS gateway; both are configured throughcluster.envand the sandbox egress policies allow whichever host is configured.Behaviour changes to be aware of
AUTOMATION_SERVICE_URLno longer defaults to a localhost address. Unset means publication is skipped with stateunconfigured; a plan with no automations recordsnot-applicable. Both states are terminal.sentence-transformersto an optionallocal-embeddingsextra. Local setups using that provider needpip install -e ".[local-embeddings]".sharedgains one runtime dependency,regex, for timeout-bounded constraint matching./jit/bpmn/validateroute.quay.io/minio/minioimage was withdrawn) and uses aRecreatestrategy so a rollout can reuse its single volume; the OpenShell LLM policies allow the configured gateway host on 443; an emptyMAAS_ROUTE_SEGMENTno longer produces a trailing slash in the LLM base URL; the MCP proxy image pinsmcp<2(2.x removed the module it imports; images built before the pin crash at start); async pod callbacks to the SonataFlow engine retry three times instead of once; the BFF detects the care-plan gate from the workflow's own marker instead of inferring it from data presence, so it no longer offers Approve during FHIR review rounds.New configuration
AUTOMATION_SERVICE_URLAUTOMATION_SERVICE_TOKENBPMN_PREFLIGHT_URLACP_JOB_STORE_DIRdata/automation-publicationswhen no PHI storeAUTOMATION_STORE_DIRdata/automationswhen no PHI storeACP_AUTOMATION_DEFAULT_MONITORING_PERIODP90DSecurity
A review of this branch (
working/security/security-review-2026-10-12.md, not in the repo) listed findings introduced by the feature. Status in this PR:Known gaps and follow-up PRs, in order
apply_editsat the review gate, the parameter form, incomplete-instance handling, composition and pruning, analyst visibility of automations.--allowed-hostsso pod traces are no longer rejected, and include prior attempts' findings in the repair feedback. Needed before any further prompt tuning.cpg-ingester/deploy/verify.sh's published-BPMN check, which matches the wrong path prefix and reports a false negative; document indeploy/README.mdthatsetup-secrets.shwritesLLM_API_KEYwhile the in-cluster MaaSExternalModelneeds a Secret keyedapi-key, and that an OpenShell sandbox is restarted by re-running the component deploy, never by deleting its pod (the pod returns without its supervised process); have the deploy scripts wait on their background sandbox-create sessions before exiting.Verification
Green on the merged tree: shared, cpg-ingester, acp-writer and automation suites; all three UI typechecks, tests and builds; five Helm chart lints; loader and slice-access shell tests; golden regeneration check;
mvn testinacp-writer/decision-service(11 tests).Compose, orchestrated profile, all pods rebuilt: one guideline through both gates; one care plan generated, approved and written to Medplum; the attached automation was
incomplete(a required interval left unbound by the guideline), so the approval recordednot-applicablewith no publication attempt and no retry thread.Cluster,
sschifma-cpg-acp, images atc98ee9e, EnMaaS as the LLM gateway:deploy-all.shand the component verifiers pass; all nine OpenShell sandboxes answer their routed health check; one guideline ingested through both gates and delivered; the loader registered the DMN models and the accepted template (one template was rejected by the engine's static ladder, which the loader now reports as a warning and continues past); one care plan generated with the template attached read-only, approved,activein Medplum, publicationnot-applicable, no retry thread; a second plan set toentered-in-errorthrough the FHIR status endpoint; a fresh decision-engine sandbox starts with an empty registry and the loader re-registers the template.What the live runs did not exercise, stated plainly:
unconfiguredpublication state and thepublishedtoken path. Neither compose nor cluster run produced an enabled, fully bound automation from the demo guidelines (that needs the Phase 4 parameter form). Both states are covered by the acp-writer unit tests, andpublishedby the in-process slice test against the real automation service app.approveandrequest_changesonly; rejection of a persisted plan goes through the FHIR status endpoint, which writes the withdrawal tombstone. The description above reflects that.Suggested merge: squash.
🤖 Generated with Claude Code and Codex