---
id: CAP-PFM-INT-020
title: Publish event-driven automation and follow its work
feature: FEAT-PFM-INT-06
product_area: platform
module: integrations
revision: 1
status: draft
product_intent: proposed
implementation_evidence: partially-observed
supersedes: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  macroservice-libraries: 54536a441935c6e09fdb7f96f0bec71c52ba4e03
intent_sources:
  - 'services-platform:docs/proposals/application-processes-and-workflow-actions/14-decisions.md#D-10'
  - 'services-platform:docs/proposals/application-processes-and-workflow-actions/14-decisions.md#D-03'
purpose: Administrators publish conditions and actions for business events and inspect the resulting runs and timers.
outcomes:
  - A run refers to the published version responsible for its actions.
  - Shared lists make application runs and timers inspectable together.
concepts:
  - CON-PFM-INT-006
actors:
  - ACT-PFM-022
  - ACT-PFM-020
  - ACT-PFM-006
surfaces:
  - api
  - job
preconditions: []
postconditions: []
permissions:
  - key: platform.workflow-actions.automation-manage
    where_checked: api
    scope: tenant
  - key: platform.workflow-actions.registry-read
    where_checked: api
    scope: tenant
  - key: platform.workflow-actions.runs-read
    where_checked: api
    scope: tenant
  - key: platform.workflow-actions.runs-resolve
    where_checked: service
    scope: tenant
rules:
  - id: BR-CAP-PFM-INT-020-01
    proved_by: [ATS-PFM-INT-020-01, ATS-PFM-INT-020-09, TST-PFM-INT-594]
    statement: >-
      Creation gives an automation rule and its first version draft status under the event owner; name and
      event can change before first publication, while the event is fixed afterwards.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/workflow-actions/tests/integration/services/persistence/automation-rules.integration.spec.js#creates
      the rule as a draft, owned by the event’s application, with its first version as the draft
    origin: 'services-platform:docs/proposals/application-processes-and-workflow-actions/14-decisions.md#D-10'
  - id: BR-CAP-PFM-INT-020-02
    proved_by: [ATS-PFM-INT-020-02, ATS-PFM-INT-020-09, TST-PFM-INT-588, TST-PFM-INT-594]
    statement: 'A rule has one editable draft version, and saving after publication opens the next numbered draft.'
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/workflow-actions/tests/integration/db/workflow-actions-tables.integration.spec.js#refuses
      a second draft of one rule
    origin: none
  - id: BR-CAP-PFM-INT-020-03
    proved_by: [ATS-PFM-INT-018-08, ATS-PFM-INT-020-03, ATS-PFM-INT-020-09, TST-PFM-INT-589]
    statement: >-
      Publishing requires a registered automation event, declared condition facts, at least one registry-valid
      action at that event and all automation and action permissions, storing those permissions with the
      version.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/workflow-actions/tests/integration/services/automation/publish-automation-rule.integration.spec.js#refuses
      a publisher without the permission an action’s type requires
    origin: 'services-platform:docs/proposals/application-processes-and-workflow-actions/14-decisions.md#D-10'
  - id: BR-CAP-PFM-INT-020-04
    proved_by: [ATS-PFM-INT-019-09, ATS-PFM-INT-020-04, ATS-PFM-INT-020-09, ATS-PFM-INT-020-10, ATS-PFM-INT-021-05, TST-PFM-INT-588, TST-PFM-INT-589]
    statement: >-
      Publication freezes the condition, actions and fingerprint with publisher and time, selects the current
      version and enables a draft rule; subsequent content changes are refused even for direct writers.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/workflow-actions/tests/integration/db/workflow-actions-tables.integration.spec.js#refuses
      a change to a published version’s actions
    origin: none
  - id: BR-CAP-PFM-INT-020-05
    proved_by: [ATS-PFM-INT-020-05, ATS-PFM-INT-020-09, TST-PFM-INT-594]
    statement: >-
      Enabled and disabled rules may exchange states, any non-retired rule may retire, drafts enable only
      through publication and retired rules cannot move; published rules cannot be deleted but unpublished
      drafts can.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/workflow-actions/tests/integration/services/persistence/automation-rules.integration.spec.js#refuses
      to delete a published rule, which is retired instead (409)
    origin: 'services-platform:docs/proposals/application-processes-and-workflow-actions/14-decisions.md#D-10'
  - id: BR-CAP-PFM-INT-020-06
    proved_by: [ATS-PFM-INT-020-06, TST-PFM-INT-003, TST-PFM-INT-007]
    statement: >-
      The event owner evaluates at most two hundred enabled rules at their current published versions and
      raises matching actions in its own transaction with rule and version attribution.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      macroservice-libraries:packages/workflow-actions/src/tests/integration/automation.integration.spec.ts#raises
      each matching rule’s actions as platform.automation_rule, rule and version, at event, once per event
    origin: 'services-platform:docs/proposals/application-processes-and-workflow-actions/14-decisions.md#D-10'
  - id: BR-CAP-PFM-INT-020-07
    proved_by: [ATS-PFM-INT-020-07, ATS-PFM-INT-022-06, TST-PFM-INT-598]
    statement: >-
      Shared run and timer lists filter application, host, instance, status, type and time, order runs newest
      first and timers by due time, identify failed or blocked work and skip unavailable host views with a
      warning.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/workflow-actions/tests/integration/services/persistence/cross-workflow-views.queries.integration.spec.js#skips
      a host with no view, and one whose view lacks a column, naming each
    origin: none
  - id: BR-CAP-PFM-INT-020-08
    proved_by: []
    statement: The shared runs-resolve permission governs host-owned retry and skip operations on each host’s routes.
    kind: permission
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/workflow-actions/README.md#Routes'
    origin: none
  - id: BR-CAP-PFM-INT-020-09
    proved_by: [ATS-PFM-INT-020-08, TST-PFM-INT-587]
    statement: >-
      Registry read covers rules and versions, automation manage covers edits and publication and runs read
      covers run and timer lists.
    kind: permission
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/workflow-actions/tests/e2e/workflow-actions.e2e.spec.js#refuses a reader the
      publish (403)
    origin: none
scenarios:
  - id: SC-CAP-PFM-INT-020-01
    given: Accounting declares the overdue-invoice event.
    when: Staff publish a rule creating a task and sending e-mail for that event.
    then: Publication enables the first version and later runs identify that version.
    provenance: test
    source: >-
      services-platform:modules/workflow-actions/tests/e2e/workflow-actions.e2e.spec.js#publishes it, enabled,
      with the version as its current one
edge_cases: []
constraints: []
depends_on:
  - CAP-PFM-INT-018
related:
  - CAP-PFM-INT-019
journeys:
  - JNY-PFM-INT-006
open_questions: []
evidence:
  - >-
    services-platform source inventory: modules/workflow-actions/services/automation/*,
    persistence/automation-rules.ts, persistence/cross-workflow-views.ts, db/automation-rules.table.ts,
    db/automation-rule-versions.table.ts, db/cross-workflow-views.view.ts; rule-level automated test
    references; docs/workflow-actions/automation-rules.md, cross-service-views.md; 14-decisions.md (D-10).
  - >-
    macroservice-libraries source inventory: packages/workflow-actions/src/automation.ts, raise.ts; associated
    integration tests.
  - >-
    Operation coverage: listAutomationRules, createAutomationRule, getAutomationRule, replaceAutomationRule,
    deleteAutomationRule, saveAutomationRuleDraft, publishAutomationRule, enableAutomationRule,
    disableAutomationRule, retireAutomationRule, listAutomationRuleVersions, listWorkflowActionRuns,
    listWorkflowTimers.
  - 'Persistent record coverage: automation_rules, automation_rule_versions.'
  - 'End-to-end definition inventory: workflow-actions.e2e.spec.js.'
controls: [TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CHG-005, TC-CHG-006, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-IAM-001, TC-IAM-006, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-INT-06-01, FAS-PFM-INT-06-02, FAS-PFM-INT-06-03, FAS-PFM-INT-06-04, FAS-PFM-INT-06-05]
suites: [TST-PFM-INT-003, TST-PFM-INT-007, TST-PFM-INT-587, TST-PFM-INT-588, TST-PFM-INT-589, TST-PFM-INT-594, TST-PFM-INT-598]
---
# Publish event-driven automation and follow its work

## Purpose

Administrators publish conditions and actions for business events and inspect the resulting runs and timers.

## How It Works

An administrator drafts a condition and action list for a registered business event. Publication checks the configuration and the publisher’s action permissions. The published version becomes the stable explanation for later work. When its owning application raises an event, that application evaluates applicable rules in its transaction. Draft edits prepare a later version without changing the one already running. Disabling stops new use while retirement preserves the reference needed by history. Shared views help staff find failed runs and blocked timers across hosts. Hosts remain responsible for execution and resolution on their own records. The product should prove a real event-producing host before presenting configured automation as active end-to-end behaviour.

## Relationships

- Requires keep the action builder aligned with deployed applications to supply the prerequisite configuration or operation.
- Connects with reuse workflow recipes and working-time configuration through shared integration records.
