Files
reporting-governance-plugin/docs/specs/reporting-governance-event-model.md

18 KiB

Reporting Governance Event Model

Purpose

This document defines the canonical event model for the reporting-governance plugin. It gives adapters and policy evaluators a stable envelope, a shared event-type catalog, and validation rules for the reporting failure modes that recently caused blackhole behavior.

The model is designed to support four enforcement gates:

  1. Pre-dispatch report-anchor gate
  2. Subagent failure immediate-report gate
  3. Silent-task launch blocker
  4. Result-forwarding integrity gate

Design goals

  • Provide one portable envelope for all reporting-governance events.
  • Separate common metadata from event-specific payloads.
  • Make high-risk reporting failures explicit and machine-detectable.
  • Preserve enough evidence and operator context for audit and escalation.
  • Support adapters that translate runtime-specific activity into canonical events.

Canonical envelope

Every event MUST use the following top-level envelope.

Field Type Required Notes
event_id string yes Unique event identifier. UUID recommended.
event_type string yes Canonical event type name.
runtime string yes Runtime source, such as openclaw, claude-code, or another adapter target.
adapter_version string yes Version of the adapter emitting the canonical event.
agent_id string yes Canonical identifier for the agent responsible for the event.
task_id string yes Task identifier. May be runtime-generated, but must be present on all governed task events.
correlation_id string yes Correlates related events within a workflow, dispatch chain, or review thread.
timestamp string yes RFC 3339 timestamp.
payload object yes Event-specific body validated by event type.
evidence_refs array yes Zero or more evidence references unless the event type requires at least one.
operator_context object yes Reporting context visible to governance logic and auditors.

Envelope semantics

event_id

  • Must be globally unique within the event store.
  • Should be immutable and idempotency-safe.

event_type

  • Must be one of the canonical event types defined in this document.
  • Event types are stable governance API surface.

task_id

  • Required for all events in this model, including alert and gate events.
  • Enables policy evaluation for checkpointing, silence windows, completion claims, and forwarding integrity.

correlation_id

  • Binds related task, subagent, review, and escalation events.
  • A subagent chain should usually retain the same correlation_id while using event-specific payload fields for child linkage.

evidence_refs

Each evidence reference object should use this shape:

{
  "kind": "command_output",
  "ref": "artifacts/verify/test-output.txt",
  "label": "pytest output",
  "sha256": "b1946ac92492d2347c6235b4d2611184",
  "mime_type": "text/plain"
}

Recommended kind values:

  • command_output
  • file
  • url
  • message
  • commit
  • log_excerpt
  • screenshot
  • schema_validation

operator_context

Minimum recommended fields:

{
  "channel": "telegram",
  "operator_id": "eric",
  "report_anchor": {
    "present": true,
    "anchor_id": "telegram:msg:12345"
  },
  "reporting_mode": "interactive",
  "silent_task": false,
  "checkpoint_policy_id": "default-5m",
  "watchdog_policy_id": "subagent-forwarding-v1"
}

operator_context.report_anchor.present is critical for enforcing the pre-dispatch report-anchor gate.

Canonical event types

Task lifecycle

  • task_started
  • task_checkpoint_due
  • task_checkpoint_sent
  • task_status_changed
  • task_claimed_complete
  • task_evidence_attached
  • operator_review_requested

Subagent orchestration

  • subagent_spawned
  • subagent_spawn_failed
  • subagent_completed
  • subagent_result_forwarded
  • subagent_result_not_forwarded

Silence / watchdog / escalation

  • silence_timeout
  • watchdog_fired
  • forced_operator_update

Gate and governance failures

  • report_anchor_missing

Event payload definitions

1. task_started

Signals that a governed task started execution.

Required payload fields:

  • task_kind (string)
  • started_by (string)
  • initial_status (string)
  • silent_task (boolean)
  • report_required (boolean)

Recommended payload fields:

  • plan_ref (string)
  • checkpoint_due_at (string, RFC 3339)
  • owner_agent_id (string)

Governance note:

  • If silent_task is true while policy forbids silent launches, this event should be blocked or accompanied by forced_operator_update / policy denial upstream.

2. task_checkpoint_due

Signals that a checkpoint obligation became due.

Required payload fields:

  • checkpoint_type (string)
  • due_at (string, RFC 3339)
  • expected_report_type (string)

Recommended payload fields:

  • grace_period_ms (integer)
  • policy_id (string)

3. task_checkpoint_sent

Signals that a checkpoint report was actually emitted.

Required payload fields:

  • checkpoint_type (string)
  • sent_at (string, RFC 3339)
  • report_type (string)

Recommended payload fields:

  • anchor_id (string)
  • message_ref (string)
  • lateness_ms (integer)

4. task_status_changed

Signals a meaningful workflow state transition.

Required payload fields:

  • from_status (string)
  • to_status (string)
  • reason (string)

Recommended payload fields:

  • status_source (string)
  • blocked (boolean)
  • gate_id (string)

5. task_claimed_complete

Signals that an agent claimed completion.

Required payload fields:

  • claimed_status (string)

Recommended payload fields:

  • verification_state (string)
  • claim_basis (string)
  • pending_review (boolean)

Validation rule:

  • task_id is required by the envelope.
  • payload.claimed_status is required.

Governance note:

  • This event should not imply accepted completion. It records the claim so policy can validate verification and review gates.

6. task_evidence_attached

Signals that evidence was added to support status or completion.

Required payload fields:

  • evidence_count (integer, minimum 1)
  • evidence_role (string)

Validation rule:

  • evidence_refs must contain at least one item.

7. operator_review_requested

Signals that operator review or approval was requested.

Required payload fields:

  • review_reason (string)
  • review_scope (string)

Recommended payload fields:

  • requested_status (string)
  • deadline (string, RFC 3339)

8. subagent_spawned

Signals successful subagent dispatch.

Required payload fields:

  • subagent_id (string)
  • subagent_label (string)
  • dispatch_status (string)
  • report_anchor_required (boolean)
  • report_anchor_present (boolean)

Recommended payload fields:

  • spawn_session_id (string)
  • parent_agent_id (string)
  • task_summary (string)
  • worktree (string)

Governance note:

  • report_anchor_present supports the pre-dispatch report-anchor gate.
  • Adapters may reject dispatch before emitting this event if the gate fails.

9. subagent_spawn_failed

Signals that subagent dispatch failed.

Required payload fields:

  • failure_reason (string)
  • failure_stage (string)
  • immediate_report_required (boolean)

Recommended payload fields:

  • attempted_subagent_label (string)
  • error_code (string)
  • retryable (boolean)

Governance note:

  • This event exists so dispatch failure cannot silently disappear.
  • Policies should require an immediate operator-facing report when this event occurs.

10. subagent_completed

Signals child task completion or termination.

Required payload fields:

  • subagent_id (string)
  • completion_state (string)
  • result_available (boolean)

Recommended payload fields:

  • result_ref (string)
  • completed_at (string, RFC 3339)
  • exit_reason (string)

11. subagent_result_forwarded

Signals that child output was forwarded into the governed reporting path.

Required payload fields:

  • subagent_id (string)
  • forwarded_at (string, RFC 3339)
  • forward_target (string)

Recommended payload fields:

  • source_result_ref (string)
  • forward_message_ref (string)
  • integrity_status (string)

12. subagent_result_not_forwarded

Signals a forwarding integrity failure.

Required payload fields:

  • subagent_id (string)
  • detected_at (string, RFC 3339)
  • reason (string)
  • result_ref (string)

Recommended payload fields:

  • forward_deadline (string, RFC 3339)
  • watchdog_window_ms (integer)
  • operator_notified (boolean)

Governance note:

  • This event is the explicit machine-detectable blackhole symptom for a completed child whose result was not surfaced properly.

13. silence_timeout

Signals that required reporting silence exceeded policy.

Required payload fields:

  • duration_ms (integer, minimum 1)
  • expected_report_type (string)

Recommended payload fields:

  • last_report_at (string, RFC 3339)
  • timeout_policy_id (string)
  • blocking_action (string)

Validation rule:

  • duration_ms and expected_report_type are required.

Governance note:

  • Supports the silent-task launch blocker and overdue checkpoint escalation logic.

14. watchdog_fired

Signals a watchdog policy trigger.

Required payload fields:

  • watchdog_type (string)
  • trigger_reason (string)

Recommended payload fields:

  • triggered_at (string, RFC 3339)
  • policy_id (string)
  • severity (string)

15. report_anchor_missing

Signals that a required reporting anchor was missing before dispatch or required reporting.

Required payload fields:

  • required_for (string)
  • gate_action (string)

Recommended payload fields:

  • missing_anchor_kind (string)
  • attempted_action (string)
  • blocking (boolean)

Governance note:

  • This event enables explicit auditing of the pre-dispatch report-anchor gate.

16. forced_operator_update

Signals that the system forced an operator-visible update because a gate or failure policy required it.

Required payload fields:

  • reason (string)
  • update_channel (string)
  • trigger_event_type (string)

Recommended payload fields:

  • update_ref (string)
  • severity (string)
  • deadline_breached (boolean)

Governance note:

  • Used for immediate disclosure when silent failure or blocked dispatch would otherwise become a blackhole.

Governance gate mapping

Pre-dispatch report-anchor gate

Use:

  • operator_context.report_anchor.present
  • subagent_spawned.payload.report_anchor_present
  • report_anchor_missing

Expected behavior:

  • If an operator-visible anchor is required and absent, dispatch should be blocked or explicitly escalated.

Subagent failure immediate-report gate

Use:

  • subagent_spawn_failed
  • forced_operator_update

Expected behavior:

  • Dispatch failure cannot remain internal-only. A failure should trigger or require immediate reporting.

Silent-task launch blocker

Use:

  • task_started.payload.silent_task
  • silence_timeout
  • forced_operator_update

Expected behavior:

  • Policies may block silent starts or force disclosure when a task enters a no-report state beyond allowed policy.

Result-forwarding integrity gate

Use:

  • subagent_completed
  • subagent_result_forwarded
  • subagent_result_not_forwarded
  • watchdog_fired

Expected behavior:

  • If a child result exists but is not forwarded within policy, governance emits an explicit failure event and escalation path.

Example events

Example: subagent_spawned

{
  "event_id": "1adf4ed4-5b4d-4ce8-9b30-11f6fd9dd001",
  "event_type": "subagent_spawned",
  "runtime": "openclaw",
  "adapter_version": "1.0.0",
  "agent_id": "agent:coder:main",
  "task_id": "task-reporting-governance-2",
  "correlation_id": "corr-rg-2026-05-07-001",
  "timestamp": "2026-05-07T15:40:00+08:00",
  "payload": {
    "subagent_id": "agent:coder:subagent:d42f401a-2497-405b-8eed-1606fb710c8a",
    "subagent_label": "reporting-governance-task2-implementer",
    "dispatch_status": "spawned",
    "report_anchor_required": true,
    "report_anchor_present": true,
    "spawn_session_id": "sess_123",
    "parent_agent_id": "agent:coder:main",
    "task_summary": "Implement Task 2 spec/schema work",
    "worktree": "/home/alice/.openclaw/workspace/.worktrees/reporting-governance-plugin"
  },
  "evidence_refs": [],
  "operator_context": {
    "channel": "telegram",
    "operator_id": "eric",
    "report_anchor": {
      "present": true,
      "anchor_id": "telegram:msg:998877"
    },
    "reporting_mode": "interactive",
    "silent_task": false,
    "checkpoint_policy_id": "default-5m",
    "watchdog_policy_id": "forwarding-v1"
  }
}

Example: subagent_spawn_failed

{
  "event_id": "1adf4ed4-5b4d-4ce8-9b30-11f6fd9dd002",
  "event_type": "subagent_spawn_failed",
  "runtime": "openclaw",
  "adapter_version": "1.0.0",
  "agent_id": "agent:coder:main",
  "task_id": "task-reporting-governance-2",
  "correlation_id": "corr-rg-2026-05-07-001",
  "timestamp": "2026-05-07T15:41:10+08:00",
  "payload": {
    "failure_reason": "sessions_spawn returned transport error",
    "failure_stage": "dispatch",
    "immediate_report_required": true,
    "attempted_subagent_label": "reporting-governance-task2-implementer",
    "error_code": "TRANSPORT_UNAVAILABLE",
    "retryable": true
  },
  "evidence_refs": [
    {
      "kind": "log_excerpt",
      "ref": "logs/spawn-error-2026-05-07.txt",
      "label": "subagent spawn error",
      "mime_type": "text/plain"
    }
  ],
  "operator_context": {
    "channel": "telegram",
    "operator_id": "eric",
    "report_anchor": {
      "present": true,
      "anchor_id": "telegram:msg:998877"
    },
    "reporting_mode": "interactive",
    "silent_task": false,
    "checkpoint_policy_id": "default-5m",
    "watchdog_policy_id": "forwarding-v1"
  }
}

Example: subagent_result_not_forwarded

{
  "event_id": "1adf4ed4-5b4d-4ce8-9b30-11f6fd9dd003",
  "event_type": "subagent_result_not_forwarded",
  "runtime": "openclaw",
  "adapter_version": "1.0.0",
  "agent_id": "agent:coder:main",
  "task_id": "task-reporting-governance-2",
  "correlation_id": "corr-rg-2026-05-07-001",
  "timestamp": "2026-05-07T15:49:30+08:00",
  "payload": {
    "subagent_id": "agent:coder:subagent:d42f401a-2497-405b-8eed-1606fb710c8a",
    "detected_at": "2026-05-07T15:49:30+08:00",
    "reason": "child session completed but no forwarded result was recorded before watchdog deadline",
    "result_ref": "session-result:d42f401a-2497-405b-8eed-1606fb710c8a",
    "forward_deadline": "2026-05-07T15:48:00+08:00",
    "watchdog_window_ms": 90000,
    "operator_notified": true
  },
  "evidence_refs": [
    {
      "kind": "message",
      "ref": "telegram:msg:998877",
      "label": "latest operator checkpoint",
      "mime_type": "text/plain"
    }
  ],
  "operator_context": {
    "channel": "telegram",
    "operator_id": "eric",
    "report_anchor": {
      "present": true,
      "anchor_id": "telegram:msg:998877"
    },
    "reporting_mode": "interactive",
    "silent_task": false,
    "checkpoint_policy_id": "default-5m",
    "watchdog_policy_id": "forwarding-v1"
  }
}

Example: silence_timeout

{
  "event_id": "1adf4ed4-5b4d-4ce8-9b30-11f6fd9dd004",
  "event_type": "silence_timeout",
  "runtime": "openclaw",
  "adapter_version": "1.0.0",
  "agent_id": "agent:coder:main",
  "task_id": "task-reporting-governance-2",
  "correlation_id": "corr-rg-2026-05-07-001",
  "timestamp": "2026-05-07T15:50:00+08:00",
  "payload": {
    "duration_ms": 300000,
    "expected_report_type": "task_checkpoint_sent",
    "last_report_at": "2026-05-07T15:45:00+08:00",
    "timeout_policy_id": "default-5m",
    "blocking_action": "force_update"
  },
  "evidence_refs": [],
  "operator_context": {
    "channel": "telegram",
    "operator_id": "eric",
    "report_anchor": {
      "present": true,
      "anchor_id": "telegram:msg:998877"
    },
    "reporting_mode": "interactive",
    "silent_task": false,
    "checkpoint_policy_id": "default-5m",
    "watchdog_policy_id": "forwarding-v1"
  }
}

Example: forced_operator_update

{
  "event_id": "1adf4ed4-5b4d-4ce8-9b30-11f6fd9dd005",
  "event_type": "forced_operator_update",
  "runtime": "openclaw",
  "adapter_version": "1.0.0",
  "agent_id": "agent:coder:main",
  "task_id": "task-reporting-governance-2",
  "correlation_id": "corr-rg-2026-05-07-001",
  "timestamp": "2026-05-07T15:50:05+08:00",
  "payload": {
    "reason": "subagent result forwarding watchdog breached",
    "update_channel": "telegram",
    "trigger_event_type": "subagent_result_not_forwarded",
    "update_ref": "telegram:msg:998899",
    "severity": "high",
    "deadline_breached": true
  },
  "evidence_refs": [
    {
      "kind": "message",
      "ref": "telegram:msg:998899",
      "label": "forced operator update",
      "mime_type": "text/plain"
    }
  ],
  "operator_context": {
    "channel": "telegram",
    "operator_id": "eric",
    "report_anchor": {
      "present": true,
      "anchor_id": "telegram:msg:998877"
    },
    "reporting_mode": "interactive",
    "silent_task": false,
    "checkpoint_policy_id": "default-5m",
    "watchdog_policy_id": "forwarding-v1"
  }
}

Consistency requirements

  • All canonical events use the same envelope schema.
  • Event-specific validation lives in the event catalog schema.
  • Adapters may emit additional fields, but only inside payload or extension-friendly object properties unless future schema revision promotes them.
  • Unknown event_type values must fail validation.
  • Event types representing gate failures are first-class events, not log-only annotations.

Versioning

  • Envelope and event catalog should evolve with explicit schema versioning.
  • Additive payload fields are preferred over breaking top-level envelope changes.
  • New event types should only be added with documentation and example coverage for operator-facing semantics.