M10 - OpenClaw Concrete Executor, Agent-Node Pilot, and Safety Gates
Status: delivered.
M9 proved the orchestration-runtime seam and piloted one read-only node (track_progress) through
a fake executor. M10 (issues #82-
#88) replaces the fake executor with a real,
gateway-backed one; extends the pilot to one state-only agent node; adds a centralized,
code-owned capability policy so config alone can never widen what OpenClaw may execute; and adds
the machine-checkable flip-readiness gate operators run before switching a real environment onto
the pilot.
Result
- Concrete executor (M10-1..M10-4, issues #82-#85):
OpenClawGatewayNodeExecutorandOpenClawExecutorGatewayClient(bloom/workflow/openclaw_executor.py) implement the pilot'sPOST /tools/invokecontract against a real OpenClaw Gateway.create_appwires the concrete executor wheneverBLOOM_OPENCLAW_ORCHESTRATION_EXECUTOR_BASE_URLis configured, falling back toUnavailableOpenClawNodeExecutorotherwise;Settingsfails fast iffail_closedis selected without that config. An integration harness (bloom/workflow/openclaw_track_progress_harness.py) provestrack_progressend to end through the real code path - request shape, idempotency/cached-success reuse, validated writes, and Bloom's own reducer application - offline by default, with an opt-in live-gateway check. - Second pilot node (M10-5, issue #86):
prd_authoring, a state-onlyagentnode that writes onlyprdand never messages the user directly, routed through a separate, empty-by-defaultBLOOM_OPENCLAW_ORCHESTRATION_PILOT_AGENT_NODESallowlist. Explicit by node id, never inferred fromnode.type == "agent"alone. - Capability policy and safety gates (M10-6, issue #87):
OpenClawCapabilityPolicy(bloom/workflow/openclaw_policy.py) is a third, code-owned gate above the operator-configured allowlists and below the executor's own tool/agent maps. It rejects any node that is not atool/agentnode, is side-effecting (Telegram sends, GitHub mutations, deploy/CI triggers, PR review publication, merge decisions), falls outside its own hard-coded node set, or declares writes outside what that node id is allowed to write. Policy rejection follows the same fallback/fail-closed semantics as an executor failure and is always logged (openclaw_policy.rejected), never silent./health'sorchestration.policyfield exposes a secret-safe summary. - Flip-readiness command and runbook (M10-7, issue #88, this milestone's closing issue):
bloom.workflow.openclaw_readiness(run viauv run python -m bloom.workflow.openclaw_readiness) is a machine-checkable gate that verifiesSettingsconstruction, the configured allowlists against the policy's hard-coded node set,/health, concrete-executor availability, correlation-store health, capability-policy wiring, and an offline run of thetrack_progressexecution harness - entirely in-process, no live OpenClaw gateway required by default - plus an optional, explicitly-marked local-gateway-only live harness check. See docs/deployment.md for the full rollout runbook and docs/design/openclaw-orchestration-runtime.md for the design reference.
Exact M10 Routable Node Set
At the end of M10, exactly these two nodes may ever route through OpenClaw, and only when also present in the operator's configured allowlist:
track_progress(tool): read-only GitHub status refresh, writes onlyprogress.prd_authoring(agent): state-only PRD draft, writes onlyprd.
Every other node in workflows/bloom-sdlc.workflow.json - human, event_wait, map, router,
passthrough, and every side-effecting tool node (GitHub mutations, Telegram sends, deploy/CI
triggers) - remains built-in-only, enforced by the capability policy regardless of any future
config change. Widening this set requires a deliberate, separately-reviewed change to
openclaw_policy.py and its tests, never a runtime config value alone.
Retained In Bloom
Unchanged from M9 - Bloom still owns product state and persisted RunState, workflow graph
traversal and reducers, GitHub coordination semantics, account/session state, Telegram and GitHub
webhook routing, durable job enqueue and event dedupe, GitHub and Telegram side effects, Product
Owner review and merge gates, and milestone closure.
Out Of Scope
M10 does not:
- remove the built-in runtime,
- route any node beyond
track_progress/prd_authoringthrough OpenClaw, - enable any side-effecting node through OpenClaw,
- move webhook routing, account/product state storage, or business invariants into OpenClaw,
- automatically flip any real environment's
BLOOM_ORCHESTRATION_RUNTIME- the flip-readiness command is a check operators run manually before that decision, not an automated gate.
Next Recommended Expansion Milestone
Not started. The recommended next candidate - noted in Pilot Path Recommendation - is one additional read-only or advisory node (e.g. a status/monitoring answer path, or a pre-publication specialist-review draft), added through the same double-allowlist-plus-capability-policy pattern this milestone established, only after the M10 pilot has run in production behind the flip-readiness check for a full soak period.