diff --git a/docs/specs/reporting-governance-event-model.md b/docs/specs/reporting-governance-event-model.md new file mode 100644 index 0000000..eccbff3 --- /dev/null +++ b/docs/specs/reporting-governance-event-model.md @@ -0,0 +1,621 @@ +# 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: + +```json +{ + "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: + +```json +{ + "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` + +```json +{ + "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` + +```json +{ + "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` + +```json +{ + "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` + +```json +{ + "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` + +```json +{ + "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. diff --git a/schemas/reporting-governance/event-envelope.schema.json b/schemas/reporting-governance/event-envelope.schema.json new file mode 100644 index 0000000..3241f48 --- /dev/null +++ b/schemas/reporting-governance/event-envelope.schema.json @@ -0,0 +1,169 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://cowbay.org/schemas/reporting-governance/event-envelope.schema.json", + "title": "Reporting Governance Event Envelope", + "description": "Canonical top-level envelope for reporting-governance plugin events.", + "type": "object", + "additionalProperties": false, + "required": [ + "event_id", + "event_type", + "runtime", + "adapter_version", + "agent_id", + "task_id", + "correlation_id", + "timestamp", + "payload", + "evidence_refs", + "operator_context" + ], + "properties": { + "event_id": { + "type": "string", + "minLength": 1, + "description": "Unique event identifier." + }, + "event_type": { + "type": "string", + "enum": [ + "task_started", + "task_checkpoint_due", + "task_checkpoint_sent", + "task_status_changed", + "task_claimed_complete", + "task_evidence_attached", + "subagent_spawned", + "subagent_spawn_failed", + "subagent_completed", + "subagent_result_forwarded", + "subagent_result_not_forwarded", + "silence_timeout", + "watchdog_fired", + "operator_review_requested", + "report_anchor_missing", + "forced_operator_update" + ], + "description": "Canonical reporting-governance event type." + }, + "runtime": { + "type": "string", + "minLength": 1 + }, + "adapter_version": { + "type": "string", + "minLength": 1 + }, + "agent_id": { + "type": "string", + "minLength": 1 + }, + "task_id": { + "type": "string", + "minLength": 1 + }, + "correlation_id": { + "type": "string", + "minLength": 1 + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "payload": { + "type": "object", + "description": "Event-specific payload validated by the event catalog schema." + }, + "evidence_refs": { + "type": "array", + "items": { + "$ref": "#/$defs/evidenceRef" + } + }, + "operator_context": { + "$ref": "#/$defs/operatorContext" + } + }, + "$defs": { + "evidenceRef": { + "type": "object", + "additionalProperties": true, + "required": [ + "kind", + "ref" + ], + "properties": { + "kind": { + "type": "string", + "minLength": 1 + }, + "ref": { + "type": "string", + "minLength": 1 + }, + "label": { + "type": "string" + }, + "sha256": { + "type": "string" + }, + "mime_type": { + "type": "string" + } + } + }, + "reportAnchor": { + "type": "object", + "additionalProperties": true, + "required": [ + "present" + ], + "properties": { + "present": { + "type": "boolean" + }, + "anchor_id": { + "type": "string" + }, + "anchor_kind": { + "type": "string" + } + } + }, + "operatorContext": { + "type": "object", + "additionalProperties": true, + "required": [ + "channel", + "report_anchor", + "reporting_mode", + "silent_task" + ], + "properties": { + "channel": { + "type": "string", + "minLength": 1 + }, + "operator_id": { + "type": "string" + }, + "report_anchor": { + "$ref": "#/$defs/reportAnchor" + }, + "reporting_mode": { + "type": "string", + "minLength": 1 + }, + "silent_task": { + "type": "boolean" + }, + "checkpoint_policy_id": { + "type": "string" + }, + "watchdog_policy_id": { + "type": "string" + } + } + } + } +} diff --git a/schemas/reporting-governance/events.schema.json b/schemas/reporting-governance/events.schema.json new file mode 100644 index 0000000..4d992c5 --- /dev/null +++ b/schemas/reporting-governance/events.schema.json @@ -0,0 +1,453 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://cowbay.org/schemas/reporting-governance/events.schema.json", + "title": "Reporting Governance Events", + "description": "Validation schema for canonical reporting-governance events, including envelope and event-specific payload rules.", + "allOf": [ + { + "$ref": "./event-envelope.schema.json" + }, + { + "oneOf": [ + { + "$ref": "#/$defs/taskStartedEvent" + }, + { + "$ref": "#/$defs/taskCheckpointDueEvent" + }, + { + "$ref": "#/$defs/taskCheckpointSentEvent" + }, + { + "$ref": "#/$defs/taskStatusChangedEvent" + }, + { + "$ref": "#/$defs/taskClaimedCompleteEvent" + }, + { + "$ref": "#/$defs/taskEvidenceAttachedEvent" + }, + { + "$ref": "#/$defs/subagentSpawnedEvent" + }, + { + "$ref": "#/$defs/subagentSpawnFailedEvent" + }, + { + "$ref": "#/$defs/subagentCompletedEvent" + }, + { + "$ref": "#/$defs/subagentResultForwardedEvent" + }, + { + "$ref": "#/$defs/subagentResultNotForwardedEvent" + }, + { + "$ref": "#/$defs/silenceTimeoutEvent" + }, + { + "$ref": "#/$defs/watchdogFiredEvent" + }, + { + "$ref": "#/$defs/operatorReviewRequestedEvent" + }, + { + "$ref": "#/$defs/reportAnchorMissingEvent" + }, + { + "$ref": "#/$defs/forcedOperatorUpdateEvent" + } + ] + } + ], + "$defs": { + "nonEmptyString": { + "type": "string", + "minLength": 1 + }, + "positiveInteger": { + "type": "integer", + "minimum": 1 + }, + "taskStartedPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "task_kind", + "started_by", + "initial_status", + "silent_task", + "report_required" + ], + "properties": { + "task_kind": { "$ref": "#/$defs/nonEmptyString" }, + "started_by": { "$ref": "#/$defs/nonEmptyString" }, + "initial_status": { "$ref": "#/$defs/nonEmptyString" }, + "silent_task": { "type": "boolean" }, + "report_required": { "type": "boolean" }, + "plan_ref": { "type": "string" }, + "checkpoint_due_at": { "type": "string", "format": "date-time" }, + "owner_agent_id": { "type": "string" } + } + }, + "taskCheckpointDuePayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "checkpoint_type", + "due_at", + "expected_report_type" + ], + "properties": { + "checkpoint_type": { "$ref": "#/$defs/nonEmptyString" }, + "due_at": { "type": "string", "format": "date-time" }, + "expected_report_type": { "$ref": "#/$defs/nonEmptyString" }, + "grace_period_ms": { "type": "integer", "minimum": 0 }, + "policy_id": { "type": "string" } + } + }, + "taskCheckpointSentPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "checkpoint_type", + "sent_at", + "report_type" + ], + "properties": { + "checkpoint_type": { "$ref": "#/$defs/nonEmptyString" }, + "sent_at": { "type": "string", "format": "date-time" }, + "report_type": { "$ref": "#/$defs/nonEmptyString" }, + "anchor_id": { "type": "string" }, + "message_ref": { "type": "string" }, + "lateness_ms": { "type": "integer", "minimum": 0 } + } + }, + "taskStatusChangedPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "from_status", + "to_status", + "reason" + ], + "properties": { + "from_status": { "$ref": "#/$defs/nonEmptyString" }, + "to_status": { "$ref": "#/$defs/nonEmptyString" }, + "reason": { "$ref": "#/$defs/nonEmptyString" }, + "status_source": { "type": "string" }, + "blocked": { "type": "boolean" }, + "gate_id": { "type": "string" } + } + }, + "taskClaimedCompletePayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "claimed_status" + ], + "properties": { + "claimed_status": { "$ref": "#/$defs/nonEmptyString" }, + "verification_state": { "type": "string" }, + "claim_basis": { "type": "string" }, + "pending_review": { "type": "boolean" } + } + }, + "taskEvidenceAttachedPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "evidence_count", + "evidence_role" + ], + "properties": { + "evidence_count": { "$ref": "#/$defs/positiveInteger" }, + "evidence_role": { "$ref": "#/$defs/nonEmptyString" } + } + }, + "operatorReviewRequestedPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "review_reason", + "review_scope" + ], + "properties": { + "review_reason": { "$ref": "#/$defs/nonEmptyString" }, + "review_scope": { "$ref": "#/$defs/nonEmptyString" }, + "requested_status": { "type": "string" }, + "deadline": { "type": "string", "format": "date-time" } + } + }, + "subagentSpawnedPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "subagent_id", + "subagent_label", + "dispatch_status", + "report_anchor_required", + "report_anchor_present" + ], + "properties": { + "subagent_id": { "$ref": "#/$defs/nonEmptyString" }, + "subagent_label": { "$ref": "#/$defs/nonEmptyString" }, + "dispatch_status": { "$ref": "#/$defs/nonEmptyString" }, + "report_anchor_required": { "type": "boolean" }, + "report_anchor_present": { "type": "boolean" }, + "spawn_session_id": { "type": "string" }, + "parent_agent_id": { "type": "string" }, + "task_summary": { "type": "string" }, + "worktree": { "type": "string" } + } + }, + "subagentSpawnFailedPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "failure_reason", + "failure_stage", + "immediate_report_required" + ], + "properties": { + "failure_reason": { "$ref": "#/$defs/nonEmptyString" }, + "failure_stage": { "$ref": "#/$defs/nonEmptyString" }, + "immediate_report_required": { "type": "boolean" }, + "attempted_subagent_label": { "type": "string" }, + "error_code": { "type": "string" }, + "retryable": { "type": "boolean" } + } + }, + "subagentCompletedPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "subagent_id", + "completion_state", + "result_available" + ], + "properties": { + "subagent_id": { "$ref": "#/$defs/nonEmptyString" }, + "completion_state": { "$ref": "#/$defs/nonEmptyString" }, + "result_available": { "type": "boolean" }, + "result_ref": { "type": "string" }, + "completed_at": { "type": "string", "format": "date-time" }, + "exit_reason": { "type": "string" } + } + }, + "subagentResultForwardedPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "subagent_id", + "forwarded_at", + "forward_target" + ], + "properties": { + "subagent_id": { "$ref": "#/$defs/nonEmptyString" }, + "forwarded_at": { "type": "string", "format": "date-time" }, + "forward_target": { "$ref": "#/$defs/nonEmptyString" }, + "source_result_ref": { "type": "string" }, + "forward_message_ref": { "type": "string" }, + "integrity_status": { "type": "string" } + } + }, + "subagentResultNotForwardedPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "subagent_id", + "detected_at", + "reason", + "result_ref" + ], + "properties": { + "subagent_id": { "$ref": "#/$defs/nonEmptyString" }, + "detected_at": { "type": "string", "format": "date-time" }, + "reason": { "$ref": "#/$defs/nonEmptyString" }, + "result_ref": { "$ref": "#/$defs/nonEmptyString" }, + "forward_deadline": { "type": "string", "format": "date-time" }, + "watchdog_window_ms": { "$ref": "#/$defs/positiveInteger" }, + "operator_notified": { "type": "boolean" } + } + }, + "silenceTimeoutPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "duration_ms", + "expected_report_type" + ], + "properties": { + "duration_ms": { "$ref": "#/$defs/positiveInteger" }, + "expected_report_type": { "$ref": "#/$defs/nonEmptyString" }, + "last_report_at": { "type": "string", "format": "date-time" }, + "timeout_policy_id": { "type": "string" }, + "blocking_action": { "type": "string" } + } + }, + "watchdogFiredPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "watchdog_type", + "trigger_reason" + ], + "properties": { + "watchdog_type": { "$ref": "#/$defs/nonEmptyString" }, + "trigger_reason": { "$ref": "#/$defs/nonEmptyString" }, + "triggered_at": { "type": "string", "format": "date-time" }, + "policy_id": { "type": "string" }, + "severity": { "type": "string" } + } + }, + "reportAnchorMissingPayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "required_for", + "gate_action" + ], + "properties": { + "required_for": { "$ref": "#/$defs/nonEmptyString" }, + "gate_action": { "$ref": "#/$defs/nonEmptyString" }, + "missing_anchor_kind": { "type": "string" }, + "attempted_action": { "type": "string" }, + "blocking": { "type": "boolean" } + } + }, + "forcedOperatorUpdatePayload": { + "type": "object", + "additionalProperties": true, + "required": [ + "reason", + "update_channel", + "trigger_event_type" + ], + "properties": { + "reason": { "$ref": "#/$defs/nonEmptyString" }, + "update_channel": { "$ref": "#/$defs/nonEmptyString" }, + "trigger_event_type": { "$ref": "#/$defs/nonEmptyString" }, + "update_ref": { "type": "string" }, + "severity": { "type": "string" }, + "deadline_breached": { "type": "boolean" } + } + }, + "taskStartedEvent": { + "type": "object", + "properties": { + "event_type": { "const": "task_started" }, + "payload": { "$ref": "#/$defs/taskStartedPayload" } + } + }, + "taskCheckpointDueEvent": { + "type": "object", + "properties": { + "event_type": { "const": "task_checkpoint_due" }, + "payload": { "$ref": "#/$defs/taskCheckpointDuePayload" } + } + }, + "taskCheckpointSentEvent": { + "type": "object", + "properties": { + "event_type": { "const": "task_checkpoint_sent" }, + "payload": { "$ref": "#/$defs/taskCheckpointSentPayload" } + } + }, + "taskStatusChangedEvent": { + "type": "object", + "properties": { + "event_type": { "const": "task_status_changed" }, + "payload": { "$ref": "#/$defs/taskStatusChangedPayload" } + } + }, + "taskClaimedCompleteEvent": { + "type": "object", + "properties": { + "event_type": { "const": "task_claimed_complete" }, + "payload": { "$ref": "#/$defs/taskClaimedCompletePayload" } + } + }, + "taskEvidenceAttachedEvent": { + "type": "object", + "properties": { + "event_type": { "const": "task_evidence_attached" }, + "payload": { "$ref": "#/$defs/taskEvidenceAttachedPayload" }, + "evidence_refs": { + "type": "array", + "minItems": 1 + } + } + }, + "subagentSpawnedEvent": { + "type": "object", + "properties": { + "event_type": { "const": "subagent_spawned" }, + "payload": { "$ref": "#/$defs/subagentSpawnedPayload" } + } + }, + "subagentSpawnFailedEvent": { + "type": "object", + "properties": { + "event_type": { "const": "subagent_spawn_failed" }, + "payload": { "$ref": "#/$defs/subagentSpawnFailedPayload" } + } + }, + "subagentCompletedEvent": { + "type": "object", + "properties": { + "event_type": { "const": "subagent_completed" }, + "payload": { "$ref": "#/$defs/subagentCompletedPayload" } + } + }, + "subagentResultForwardedEvent": { + "type": "object", + "properties": { + "event_type": { "const": "subagent_result_forwarded" }, + "payload": { "$ref": "#/$defs/subagentResultForwardedPayload" } + } + }, + "subagentResultNotForwardedEvent": { + "type": "object", + "properties": { + "event_type": { "const": "subagent_result_not_forwarded" }, + "payload": { "$ref": "#/$defs/subagentResultNotForwardedPayload" } + } + }, + "silenceTimeoutEvent": { + "type": "object", + "properties": { + "event_type": { "const": "silence_timeout" }, + "payload": { "$ref": "#/$defs/silenceTimeoutPayload" } + } + }, + "watchdogFiredEvent": { + "type": "object", + "properties": { + "event_type": { "const": "watchdog_fired" }, + "payload": { "$ref": "#/$defs/watchdogFiredPayload" } + } + }, + "operatorReviewRequestedEvent": { + "type": "object", + "properties": { + "event_type": { "const": "operator_review_requested" }, + "payload": { "$ref": "#/$defs/operatorReviewRequestedPayload" } + } + }, + "reportAnchorMissingEvent": { + "type": "object", + "properties": { + "event_type": { "const": "report_anchor_missing" }, + "payload": { "$ref": "#/$defs/reportAnchorMissingPayload" } + } + }, + "forcedOperatorUpdateEvent": { + "type": "object", + "properties": { + "event_type": { "const": "forced_operator_update" }, + "payload": { "$ref": "#/$defs/forcedOperatorUpdatePayload" } + } + } + } +}