Skip to main content
POST
Admin Control Plane Workflow Monitors
These routes are the first concrete migration seam from apps/engine workflow-monitor orchestration into Cloudflare Workflows. The ownership split is:
  • Cloudflare agent-control-plane owns due scanning cadence and durable workflow instances
  • platform-api owns the thin authenticated admin surface
  • WorkflowsFacade.tickMonitor(...) remains the deterministic shared mutation path

Scope

  • Internal-only
  • Protected by ADMIN_AUTH_SECRET_TOKEN
  • Intended for apps/agent-control-plane, not browser traffic

Endpoints

POST /v1/admin/control-plane/workflow-monitors/due

Load runnable monitor rows from the canonical workflow-monitor repository. Request body:
Response:
Notes:
  • requestId is the stable idempotency key Cloudflare should preserve when creating its own workflow instance
  • workerId is the stable worker identity passed through to tickMonitor(...)
  • due selection stays authoritative in the shared workflow repository for now

POST /v1/admin/control-plane/workflow-monitors/tick

Execute one monitor tick through WorkflowsFacade.tickMonitor(...). Request body:
triggerEvent is optional. The current accepted kinds are:
  • market_price
  • market_candles
  • approval_pending_count
  • account_buying_power_usd
  • account_cash_usd
  • portfolio_nav_usd
  • portfolio_cash_pct
  • portfolio_drift_from_target
  • portfolio_concentration
  • portfolio_held_asset_performance
  • portfolio_held_asset_metrics
Response:
Notes:
  • userId is resolved from the canonical linked wallet address when available
  • Cloudflare uses userId plus linkedPortfolioIds[0] to mirror the monitor tick into UserAgent / PortfolioAgent
  • this route is intentionally thin; it does not invent a new monitor execution model

POST /v1/admin/control-plane/workflow-monitors/notify-execution

Validate a terminal execution ref and forward it into the Cloudflare-owned enqueue-tick seam. Request body:
Response:
Notes:
  • this route is the event-driven companion to due plus tick
  • it can resolve the owning workflow from canonical workflow_execution_refs using operationId, runId, executionRequestId, and eventId
  • it also resolves the primary linked portfolioId so the Cloudflare worker can look up an already waiting monitor session on PortfolioAgent
  • if no execution ref matches, it returns 202 with enqueued: false instead of treating the callback as an error
  • it forwards into POST /api/workflow-monitors/enqueue-tick on the Cloudflare worker instead of mutating workflow state locally

POST /v1/admin/control-plane/workflow-monitors/notify-trigger-match

Forward a centralized trigger-match event directly into the Cloudflare-owned monitor workflow lane without going through due. Request body:
Response:
Notes:
  • this is the first explicit ingress for a future centralized trigger matcher
  • platform-api still validates the workflow and owner via WorkflowsFacade.get(...)
  • the optional triggerEvent payload now supports authoritative fact packets for market_price, market_candles, approval_pending_count, account_buying_power_usd, account_cash_usd, portfolio_nav_usd, portfolio_cash_pct, portfolio_drift_from_target, portfolio_concentration, portfolio_held_asset_performance, and portfolio_held_asset_metrics, plus the indexer-v4 native portfolio_held_asset_accounting_metrics packet for finalized/provisional accounting readiness, FIFO basis completeness, PnL, and source-finality metadata
  • it resolves the primary linked portfolioId so Cloudflare can mirror the resulting monitor workflow state into PortfolioAgent / UserAgent
  • today it forwards into the same POST /api/workflow-monitors/enqueue-tick seam using reason: "trigger_match"
  • this is intentionally narrower than the future global matcher fabric; it is just the authenticated trigger-delivery seam

POST /v1/admin/control-plane/workflow-monitors/recover

Replay a stale or orphaned monitor wait through the Cloudflare-owned runtime. Request body:
Response:
Notes:
  • this is an operator/admin replay surface, not a normal callback path
  • Cloudflare recovery is intentionally narrow and safe:
    • replay an active execution_completed or trigger_matched wait on the same workflow instance when possible
    • start a fresh authoritative tick only when no active instance is registered
    • fail closed when the active workflow is only sleeping on time instead of waiting on an event
  • optional triggerEvent fact packets can be supplied when recovery should replay a matcher-driven wake with authoritative dependency data

Runtime Behavior

The current flow is:
  1. Cloudflare calls due
  2. Cloudflare creates WorkflowMonitorTickWorkflow instances with the returned ids
  3. Each Cloudflare workflow calls tick
  4. platform-api delegates to WorkflowsFacade.tickMonitor(...)
  5. Cloudflare mirrors the resulting state into durable user/portfolio actors
The current event-driven companion flow is:
  1. engine persists a terminal execution update with canonical execution refs
  2. engine calls notify-execution
  3. platform-api resolves the owning workflow from canonical execution refs
  4. platform-api forwards into Cloudflare enqueue-tick with the linked portfolioId
  5. Cloudflare tries to route the callback directly into the active waiting WorkflowMonitorTickWorkflow session via sendEvent("execution_completed")
  6. if no active waiting session is registered, Cloudflare falls back to the previous create -> tick path
  7. the workflow calls tick
  8. Cloudflare mirrors the resulting state into durable user/portfolio actors
The current trigger-ingress companion flow is:
  1. a centralized matcher or other authoritative producer detects a match
  2. it calls notify-trigger-match
  3. platform-api validates the workflow and owner
  4. platform-api forwards into Cloudflare enqueue-tick with reason: "trigger_match"
  5. Cloudflare starts the durable WorkflowMonitorTickWorkflow without waiting for a global due scan
  6. the workflow calls tick
  7. Cloudflare mirrors the resulting state into durable user/portfolio actors
This keeps the durable orchestration move in Cloudflare while preserving the shared workflow facade as the mutation authority during migration.