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:
- Pre-dispatch report-anchor gate
- Subagent failure immediate-report gate
- Silent-task launch blocker
- 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_idwhile 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_outputfileurlmessagecommitlog_excerptscreenshotschema_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_startedtask_checkpoint_duetask_checkpoint_senttask_status_changedtask_claimed_completetask_evidence_attachedoperator_review_requested
Subagent orchestration
subagent_spawnedsubagent_spawn_failedsubagent_completedsubagent_result_forwardedsubagent_result_not_forwarded
Silence / watchdog / escalation
silence_timeoutwatchdog_firedforced_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_taskistruewhile policy forbids silent launches, this event should be blocked or accompanied byforced_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_idis required by the envelope.payload.claimed_statusis 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_refsmust 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_presentsupports 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_msandexpected_report_typeare 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.presentsubagent_spawned.payload.report_anchor_presentreport_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_failedforced_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_tasksilence_timeoutforced_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_completedsubagent_result_forwardedsubagent_result_not_forwardedwatchdog_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_typevalues 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.