Phase 2 — Runtime Engine Scope

Phase 1 (built) renders the 18-model schema as an AI-Safe CRUD register: legal instruments and provisions, obligations, occurrences, controls, evidence, verifications, compliance assessments, exceptions and corrective actions — browsable, with a dashboard. But the states are static: the seed shows a Q2 occurrence already overdue, a control already tested partially_effective, assurance already at_risk. Nothing is computed or transitioned by the system.

Phase 2 is the compliance engine that makes it live — generating recurring occurrences, computing due dates and assurance, running the deadline / verification / evidence scans, and reacting to verification results and instrument changes. Same shape as the (built, cluster-proven) orchestrator engine, but single-app.

Everything below is drawn from the pack's workflows.yaml, rules.yaml and the ComplianceDashboard. It is a scope, not a design.


A. Compute engine — due dates, occurrences & assurance rollups

The compliance calculations are seeded statically today; Phase 2 computes them:

  • Recurring occurrence generation (rules.yaml → obligation_generation): for an active obligation whose frequency ∈ {daily…annual}, create the next ObligationOccurrence with its due_at from the frequency + due_rule; and create_occurrence_from_event when an external event matches the obligation's trigger_description. This is the engine's core — it turns a standing obligation into a rolling series of dated, assessable instances.
  • Overdue / due computation on each open occurrence (against due_at, grace period).
  • Assurance rollups — an obligation's assurance_status, and the dashboard's "assurance by business unit", derived from its occurrences and assessments.

Decisions: frequency→due-date rules; grace-period handling; whether obligation assurance is stored or derived.

B. State machines & guarded actions

The pack defines six workflows. Today a user free-edits status; Phase 2 exposes each transition as a guarded action.

Workflow Notable transitions & effects
legal_instrument (draft→current→superseded/revoked/expired→archived) approvals gated to legal_admin
legal_obligation (draft→active→under_review→…→retired) activate/suspend/reaffirm gated to legal_reviewer
obligation_occurrence (open→in_progress→…→ready_for_assessment→compliant/at_risk/non_compliant→closed) assess_non_compliant creates an exception; *→overdue on due date missed
control (proposed→active→ineffective→…→retired) fail_verificationineffective; remediation_verifiedactive
evidence (expected→requested→received→accepted/rejected→…) acceptance lifecycle
exception (open→…→resolved/closed) remediation lifecycle

Decisions: UI buttons vs API; role → PIN/RBAC; which transitions the scans drive automatically vs a user.

C. Deadline, verification & evidence scans

A background tick — the assurance heartbeat:

  • Occurrence deadlines — warn owner at 30 days and owner+manager at 7 days before due_at; on overdue → mark_overdue + create_exception + escalate (rules.yaml → deadlines).
  • Verification due — when VerificationPlan.active and now ≥ next_due_atcreate a verification task.
  • Evidence expiry — warn the owner 30 days before EvidenceItem.valid_to.

Decisions: cadence; business-calendar (AU_QLD) business-day math (pack ships business_calendars.yaml); exception dedupe.

D. Rules / cross-record automation

Reactive rules from rules.yaml — the assurance chain reacting to itself:

  • Ineffective controlverification.result == ineffectiveset control ineffective + create exception + set the linked obligation at_risk. (partially_effective → obligation at_risk + exception.)
  • Mandatory evidence missing — an occurrence reaching ready_for_assessment without its mandatory evidence → set assurance at_risk + create exception.
  • Instrument change — an InstrumentChange needing impact assessment → identify impacted obligations + auto-create ObligationReviews; a source that becomes superseded/revoked/expired flags its obligations for review.
  • Corrective actions / verifications feed back into control and obligation status.

Decisions: event bus (in-app vs orchestrator); how "impacted obligations" are identified (link table vs text match); notify channel.

E. Compliance dashboard & KPIs

The DSL ComplianceDashboard metrics/sections, wired via the repo KPI framework (kpi_engine.py + kpis.py):

  • Metrics: active obligations; obligations due in 30 days; overdue occurrences; at-risk obligations; non-compliant obligations; open exceptions; overdue actions; verifications due.
  • Sections: critical obligations; upcoming deadlines; recent instrument changes; ineffective controls; open breaches; assurance by business unit.

How it would be built

  1. A per-app engine module (mirror server/lib/orchestrator_engine/): occurrence generator + compute pass (A), the deadline/verification/evidence scanner (C), guarded actions (B), rules evaluator (D). Opt-in env flag, single worker.
  2. KPIs (E) via the existing framework — quick, independent win.
  3. Business-calendar + frequency rules underpin generation and deadlines.
  4. Tests per workstream (test_orchestrator_flows.py is the template).

Suggested sequencing

  1. KPIs / dashboard (E) — visible, no engine.
  2. Occurrence generation + due-date compute (A) — makes the register self-driving.
  3. Deadline / verification scans (C) — the assurance heartbeat.
  4. Verification & instrument-change rules (D) — the reactive assurance chain.
  5. State machines + guards (B) — governed transitions.

Each slice is independently shippable and demoable. The orchestrator (built and run live this session) is the working template for the engine, scheduler and tests.