diff --git a/docs/architecture/agent-reporting-governance-plugin.md b/docs/architecture/agent-reporting-governance-plugin.md index da778f2..be6cd55 100644 --- a/docs/architecture/agent-reporting-governance-plugin.md +++ b/docs/architecture/agent-reporting-governance-plugin.md @@ -150,6 +150,40 @@ The design stance is: - **explicit labels over ambiguous proxy language** - **governed completion over self-declared completion** +## Current architecture trajectory + +The product definition is now backed by a concrete runtime-integration direction: + +- canonical governance contracts are defined in the event, evidence, decision, and policy-pack specs +- runtime portability is carried by an explicit adapter interface +- the completed watchdog auto-notify chain is treated as the first reference adapter composition rather than as standalone repair glue + +In practice, the current reference composition is: + +```text +watchdog runner + -> canonical event + -> operator notification queue + -> dispatcher spool handoff + -> bridge supervisor + -> sender binding + -> acked | blocked | pending_external_send receipt +``` + +This matters architecturally because it proves the plugin can: + +- turn elapsed-time governance failure into canonical machine-readable events +- route required operator-visible follow-up across runtime boundaries +- preserve honest delivery semantics instead of collapsing `dispatched` into false success +- provide a migration path from repo scripts toward package-level adapters and deployment profiles + +The mainline next step is therefore not “more watchdog patching,” but formalizing this runtime composition inside the plugin’s adapter and capability model so future package extraction has a stable target. + +Primary follow-on specs: + +- `docs/specs/reporting-governance-adapter-interface.md` +- `schemas/reporting-governance/adapter-capabilities.schema.json` + ## Summary The Agent Reporting Governance Plugin is a portable enforcement layer for trustworthy agent reporting. It exists because prompts alone cannot reliably prevent missing reports, late reports, fake progress, skipped checkpoints, unverified completion claims, dropped subagent results, or mislabeled placeholder/proxy reporting. diff --git a/docs/specs/reporting-governance-adapter-interface.md b/docs/specs/reporting-governance-adapter-interface.md new file mode 100644 index 0000000..d70268c --- /dev/null +++ b/docs/specs/reporting-governance-adapter-interface.md @@ -0,0 +1,691 @@ +# Reporting Governance Adapter Interface + +## Purpose + +This document defines the adapter contract for the reporting-governance plugin. It is the missing mainline bridge between: + +- the canonical governance model already defined in the event, evidence, decision, and policy-pack specs +- real runtime integrations that must observe activity, evaluate policy, and produce honest operator-visible outcomes +- the now-proven watchdog auto-notify chain (`runner -> queue -> dispatcher -> bridge -> sender -> ack|blocked|pending`) + +The goal is to move the plugin from concept-plus-scripts into a packageable integration surface. + +## Why this spec exists now + +The plugin already has strong mainline specifications for: + +- product definition +- event model +- evidence model +- decision model +- policy packs + +Separately, the repo now also has real runtime infrastructure for anti-blackhole reporting: + +- long-task watchdog runner +- canonical `watchdog_fired` event emission +- operator notification queue +- dispatcher spool handoff +- bridge supervisor +- sender binding +- single-entry orchestrator +- cron-installed auto-notify path +- live acked execution evidence + +Without an adapter interface, those runtime pieces remain implementation islands. This spec makes them first-class plugin architecture rather than incidental scripts. + +## Scope + +This document defines: + +1. adapter responsibilities +2. adapter lifecycle stages +3. canonical input/output contracts +4. capability declaration requirements +5. runtime integration seams for watchdog / queue / dispatcher / bridge / sender / orchestrator +6. minimum package structure expectations for a deployable plugin implementation + +This document does **not** define: + +- one mandatory runtime vendor +- one mandatory transport +- one mandatory storage backend +- one mandatory implementation language +- detailed internal APIs for every package module + +## Design stance + +The adapter layer is where runtime-specific reality gets normalized into portable governance behavior. + +Design priorities: + +- **canonical in, canonical out** +- **honest delivery semantics** +- **explicit capability declaration** +- **policy-driven enforcement** +- **file/runtime/transport boundaries must stay auditable** +- **watchdog escalation must be integrable, not bolted on** + +Most importantly, the adapter must never claim more than the runtime can actually prove. + +## Adapter role in the plugin architecture + +The reporting-governance plugin should be understood as five layers: + +1. **Runtime observation layer** + Captures runtime-native facts such as task start, checkpoint due, subagent completion, watchdog overdue, or outgoing message attempt. + +2. **Adapter normalization layer** + Converts runtime-native facts into canonical events, evidence items, and governance evaluation inputs. + +3. **Policy evaluation layer** + Applies policy packs to canonical facts and emits canonical decisions. + +4. **Enforcement / delivery layer** + Executes required actions such as block, rewrite, force checkpoint, notify operator, or mark pending verification. + +5. **Audit / receipt layer** + Persists enough traceability to prove what was observed, decided, attempted, delivered, blocked, or left pending. + +The adapter owns layers 1, 2, and the runtime-facing part of layer 4. + +## Core adapter responsibilities + +Every adapter implementation MUST support these responsibilities, either directly or by explicitly declaring capability gaps. + +### 1. Observe runtime activity + +The adapter must be able to ingest or derive runtime-native signals such as: + +- task lifecycle events +- checkpoint/report attempts +- subagent spawn/completion/failure states +- watchdog timer breaches +- outgoing operator-notice attempts +- delivery receipts or delivery failures + +### 2. Emit canonical events + +The adapter must translate observed runtime signals into the canonical event envelope defined in: + +- `docs/specs/reporting-governance-event-model.md` +- `schemas/reporting-governance/event-envelope.schema.json` +- `schemas/reporting-governance/events.schema.json` + +### 3. Preserve or synthesize evidence + +The adapter must attach or reference evidence strong enough to support governance decisions, especially for: + +- progress claims +- completion claims +- forced checkpoints +- forwarding integrity +- watchdog-triggered escalation +- actual operator-notice delivery vs mere handoff + +### 4. Evaluate and enforce governance decisions + +The adapter must be able to invoke policy evaluation and then carry out runtime-appropriate enforcement actions such as: + +- block dispatch +- block status transition +- rewrite or annotate outgoing reports +- force an operator-visible checkpoint +- request review +- downgrade status +- escalate severity + +### 5. Produce auditable receipts + +The adapter must preserve enough artifacts to reconstruct: + +- what happened +- what policy fired +- what action was attempted +- whether operator-visible delivery actually occurred +- where the runtime boundary stopped + +### 6. Declare capabilities honestly + +The adapter must publish a machine-readable capability descriptor using: + +- `schemas/reporting-governance/adapter-capabilities.schema.json` + +This is mandatory because the plugin cannot safely assume every runtime can: + +- block before dispatch +- rewrite outgoing text +- send notifications directly +- prove message delivery +- schedule watchdogs +- write receipts +- recover dropped child results + +## Canonical adapter lifecycle + +An adapter integrates the plugin through the following lifecycle. + +### Stage A: Observe + +Input sources may include: + +- hook callbacks +- runtime logs +- task/session state files +- queue items +- cron / scheduler invocations +- explicit CLI entrypoints +- outbound message wrappers + +Output of this stage: + +- runtime-native observation records + +### Stage B: Normalize + +The adapter converts runtime-native observations into canonical objects: + +- event envelope +- evidence item(s) +- evaluation context facts + +Output of this stage: + +- canonical event(s) +- canonical evidence ref(s) +- policy-evaluable context + +### Stage C: Evaluate + +The adapter invokes the policy layer against canonical inputs. + +Output of this stage: + +- canonical decision object +- required actions +- operator notice requirement, if any + +### Stage D: Enforce + +The adapter performs the required actions using runtime-specific mechanisms. + +Possible outputs: + +- blocked transition +- rewritten message +- emitted queue item +- emitted spool artifact +- sent operator notice +- pending placeholder +- escalation receipt + +### Stage E: Record + +The adapter records: + +- emitted canonical events +- evidence references +- delivery or non-delivery receipts +- action results +- capability-aware audit notes + +## Adapter surfaces + +An implementation may expose one or more of the following surfaces. + +### 1. Hook adapter + +Used when the runtime can intercept actions before they complete. + +Typical uses: + +- block silent task launch +- block completion claim without evidence +- rewrite placeholder messaging +- require report anchor before subagent dispatch + +### 2. Watchdog adapter + +Used when policy must be checked on elapsed time or missing follow-up rather than only inline actions. + +Typical uses: + +- missed checkpoint detection +- subagent result not forwarded +- long-task overdue escalation +- promised follow-up not delivered + +### 3. Queue / dispatch adapter + +Used when policy requires an operator-visible notice but direct send is not embedded in the local runtime. + +Typical uses: + +- emit `notify_operator` queue items +- produce spool / handoff artifact +- preserve delivery truthfulness across runtime boundaries + +### 4. Sender / bridge adapter + +Used when a privileged or upper runtime actually performs the operator-visible delivery. + +Typical uses: + +- invoke `message.send` or equivalent +- write `acked` / `blocked` / `pending_external_send` receipts +- preserve exact evidence of send outcome + +### 5. Orchestrator adapter + +Used when several adapter surfaces must be run in a deterministic chain. + +Typical uses: + +- single-entry watchdog auto-notify execution +- cron or scheduler integration +- repeatable end-to-end runtime closure + +## Runtime truth model + +The adapter interface adopts a strict truth model for operator notifications. + +### Delivery states + +At minimum, adapters must distinguish: + +- `prepared` — a notice requirement exists, but no queue/handoff has been created yet +- `queued` — a queue item exists for future delivery +- `dispatched` — a handoff/spool artifact exists and a downstream runtime may now deliver it +- `pending_external_send` — the chain reached the bridge boundary honestly, but real send is not proven +- `acked` — an upper sender path proved success and the queue/receipt writeback completed +- `blocked` — the adapter or upper runtime determined safe delivery could not proceed + +### Hard rule + +`dispatched` is **not** `acked`. +`pending_external_send` is **not** `acked`. +A local script writing a handoff artifact is **not** proof that a human-visible message was delivered. + +This truth model is the main way the recent watchdog chain gets reabsorbed into the plugin architecture without regressing into fake reporting. + +## Required adapter inputs + +An adapter invocation SHOULD accept or derive the following logical inputs. + +| Field | Required | Notes | +| --- | --- | --- | +| `runtime` | yes | Runtime identity such as `openclaw`. | +| `adapter_id` | yes | Stable adapter identifier. | +| `adapter_version` | yes | Version of the adapter implementation. | +| `task_id` | yes for governed task flow | Required for canonical events. | +| `correlation_id` | yes for governed task flow | Required for cross-event linkage. | +| `event_source` | yes | Hook, watchdog, queue, bridge, cron, etc. | +| `observed_at` | yes | Observation timestamp. | +| `payload` | yes | Runtime-native observation payload. | +| `operator_context` | recommended | Channel, target, report anchor, reporting mode, policy IDs. | +| `evidence_refs` | recommended | Artifact refs from runtime or synthesized receipts. | +| `capabilities` | yes | Adapter capability descriptor or profile binding. | + +## Required adapter outputs + +An adapter stage SHOULD produce some subset of the following outputs, depending on surface. + +| Output | Required when | Notes | +| --- | --- | --- | +| canonical event | always for governed observations | Must use canonical envelope. | +| canonical evidence item | when claims, escalation, or delivery truth need proof | May be referenced by event. | +| canonical decision | when policy evaluation is run | Must align to decision model. | +| enforcement result | when an action is attempted | Blocked, rewritten, queued, acked, etc. | +| receipt artifact | when handoff/delivery/escalation state changes | Needed for audit and watchdog closure. | +| operator notice artifact | when a visible notice is required | May be queue, message, or send receipt. | + +## Capability model + +Each adapter MUST declare its capabilities in a machine-readable document validated by: + +- `schemas/reporting-governance/adapter-capabilities.schema.json` + +Capabilities exist so policy/runtime wiring can answer questions like: + +- Can this adapter block before a subagent spawn? +- Can it rewrite outgoing reports? +- Can it schedule or evaluate watchdogs? +- Can it emit queue items but not send directly? +- Can it prove delivery with ack receipts? +- Can it correlate sender receipts back to task and policy IDs? +- Can it recover or inspect child-result state for forwarding integrity? + +## Capability domains + +### Identity and compatibility + +The adapter descriptor must declare: + +- adapter ID +- version +- runtime target +- supported plugin spec version(s) + +### Ingestion capabilities + +Whether the adapter can observe: + +- task lifecycle +- subagent lifecycle +- checkpoint obligations +- outgoing report attempts +- watchdog state +- queue/spool/receipt state + +### Enforcement capabilities + +Whether the adapter can: + +- block transitions +- rewrite outgoing text +- annotate placeholders +- force visible checkpoints +- request review +- downgrade status +- escalate + +### Notification-path capabilities + +Whether the adapter can: + +- create queue items +- create spool/handoff artifacts +- invoke a sender binding +- send directly +- write ack/block/pending receipts +- prove final delivery + +### Watchdog capabilities + +Whether the adapter can: + +- start or install watchdogs +- evaluate overdue rules +- emit `watchdog_fired` +- convert watchdog trigger into operator-visible recovery path +- close watchdog alerts once send outcome is known + +### Storage/audit capabilities + +Whether the adapter can: + +- persist canonical events +- persist evidence items +- persist decision outputs +- persist receipts +- retain original attempted messages when rewrite occurs + +## Mapping the completed watchdog chain into the adapter model + +The newly completed watchdog chain should now be treated as a reference runtime adapter composition rather than a side implementation. + +### Reference chain + +```text +watchdog runner + -> canonical watchdog event + -> operator notification queue + -> dispatcher spool handoff + -> bridge supervisor + -> sender binding + -> acked | blocked | pending_external_send receipt +``` + +### Plugin-mainline interpretation + +This chain maps to adapter responsibilities as follows: + +| Existing runtime piece | Adapter role in mainline design | +| --- | --- | +| `scripts/long_task_watchdog.mjs` | watchdog adapter: observes overdue state, emits canonical `watchdog_fired`, seeds operator notice path | +| `state/long-task-watchdog/*.json` | evidence storage for watchdog-triggered runtime artifacts | +| `state/long-task-watchdog-events/*.json` | canonical event store for watchdog-originated governance events | +| `state/operator-notify-queue/*.json` | queue adapter output representing required operator notice not yet delivered | +| `scripts/operator_notify_dispatcher.mjs` | dispatch adapter converting queue intent into auditable spool/handoff artifact | +| `state/operator-notify-dispatch-spool/*.json` | runtime handoff proof between local governance and upper send runtime | +| `scripts/operator_notify_bridge_supervisor.mjs` | bridge adapter consuming spool, invoking sender boundary, and writing honest status receipts | +| `scripts/operator_notify_sender_binding.mjs` | sender-binding adapter that maps upper runtime send contract into canonical send outcome states | +| `state/operator-notify-bridge-receipts/*.json` | receipt/audit layer for final bridge outcome | +| `scripts/watchdog_auto_notify_orchestrator.mjs` | orchestrator adapter composing the chain into one deterministic runtime path | +| cron installer / wrapper | deployment binding for scheduled adapter execution | + +### Why this matters + +Before this spec, the chain could be read as “helper scripts around a watchdog.” +After this spec, the chain becomes: + +- the first concrete adapter composition for the plugin +- the runtime reference design for forced operator-notice enforcement +- the proof that policy decisions can survive a multi-hop runtime boundary without lying about delivery + +## Adapter composition patterns + +The plugin should support at least these composition patterns. + +### Pattern 1: Inline enforcement adapter + +Use when the runtime can intercept actions before they occur. + +Example: +- pre-dispatch report-anchor gate +- verified-completion-only gate + +### Pattern 2: Deferred operator-notice adapter + +Use when the runtime can decide a notice is required but cannot itself safely prove final send. + +Example: +- local policy emits queue item +- upper runtime later sends notice and acks it + +This is the current watchdog auto-notify chain. + +### Pattern 3: Full-stack runtime adapter + +Use when one runtime can observe, decide, send, and receipt all in one trusted boundary. + +Example: +- future integrated runtime with direct hook + send + receipt APIs + +### Pattern 4: Hybrid adapter pack + +Use when one plugin deployment combines: + +- inline hook enforcement for task/report claims +- scheduled watchdog enforcement for missed follow-up +- queue/bridge sender path for operator notifications + +This is the most realistic mainline target for the reporting-governance plugin. + +## Minimum package structure target + +This spec does not force an exact repository layout, but the next mainline implementation should converge toward a package structure similar to: + +```text +plugins/reporting-governance/ + src/ + core/ + event-normalizer.* + evidence-builder.* + policy-evaluator.* + decision-runner.* + adapters/ + hook-adapter.* + watchdog-adapter.* + queue-adapter.* + bridge-adapter.* + sender-binding-adapter.* + orchestrator-adapter.* + capabilities/ + default-openclaw-watchdog.json + storage/ + event-store.* + evidence-store.* + receipt-store.* + index.* + docs/ + examples/ +``` + +### Mainline integration direction + +The current scripts do not need to disappear immediately. +They should instead be treated as: + +- first reference adapters +- migration bridge for package extraction +- executable fixtures proving the adapter contract before full packaging + +## Required invariants + +All adapter implementations MUST preserve the following invariants. + +### Invariant 1: Canonical event compatibility + +If the adapter claims event emission support, emitted events must validate against the canonical event schemas. + +### Invariant 2: Honest operator-notice state + +The adapter must never collapse queue/spool/send states into false success. + +### Invariant 3: Correlation continuity + +The adapter must preserve `task_id` and `correlation_id` across watchdog, queue, spool, send, and receipt artifacts wherever possible. + +### Invariant 4: Evidence traceability + +If the adapter emits a force-checkpoint or watchdog-driven escalation, it must preserve evidence refs sufficient for later audit. + +### Invariant 5: Capability-aware enforcement + +If a policy requires an action the adapter cannot perform, the adapter must: + +- declare the gap in capabilities +- emit a safe fallback such as queueing, blocking, or escalation +- avoid pretending the missing capability exists + +## Watchdog-specific integration requirements + +Because watchdog enforcement is now a validated mainline feature, adapters that claim watchdog support MUST address the following. + +### 1. Trigger normalization + +A watchdog trigger must be representable as canonical `watchdog_fired` and/or related escalation events. + +### 2. Operator-notice linkage + +A watchdog trigger that requires visible follow-up must link to a concrete notice path: + +- direct send +- queue item +- forced placeholder / visible checkpoint +- explicit blocked state + +### 3. End-state closure + +A watchdog path is not complete just because the trigger fired. +It should close only when the adapter can classify the notice path as: + +- `acked` +- `blocked` +- `pending_external_send` + +### 4. Policy-aware receipts + +Receipts should retain: + +- `policy_id` +- trigger event type +- `task_id` +- `correlation_id` +- evidence refs +- sender outcome + +The current watchdog queue/spool/bridge implementation already demonstrates most of this and should be treated as baseline behavior. + +## OpenClaw reference adapter profile + +Based on the completed work in this repo, the first reference profile is: + +- runtime: `openclaw` +- observe via scripts + file state + cron + runtime artifacts +- canonical event emission supported +- queue-backed operator-notice path supported +- bridge/sender boundary supported +- honest `acked|blocked|pending_external_send` distinction supported +- direct privileged send support is optional and capability-dependent + +This profile should be published as a capabilities descriptor, not just implied by repo docs. + +## Verification expectations + +Any adapter implementation should be verified at three levels. + +### Level 1: Schema validation + +Validate: + +- canonical event outputs +- canonical evidence outputs +- canonical decision outputs +- capability descriptor outputs + +### Level 2: Surface-level behavior tests + +Verify each adapter surface independently. + +Examples: + +- watchdog emits `watchdog_fired` +- dispatcher produces spool and marks `dispatched` +- bridge writes `pending_external_send` in dry-run +- sender binding `sent` leads to queue `acked` +- sender binding `blocked` leads to queue `blocked` + +### Level 3: End-to-end composition tests + +Verify orchestrated chain behavior. + +For example: + +- runner -> queue -> dispatcher -> bridge -> sender -> `acked` +- runner -> queue -> dispatcher -> bridge -> `pending_external_send` +- runner -> queue -> dispatcher -> bridge -> `blocked` + +## Roadmap impact + +This spec is the next high-value mainline step because it turns the product from: + +- conceptual governance docs +- plus separate runtime repair scripts + +into: + +- a plugin with explicit adapter seams +- declared runtime capabilities +- a concrete migration target for package structure +- a validated reference runtime composition + +Suggested mainline next steps after this document: + +1. define default OpenClaw adapter capability profile JSON using the new schema +2. extract current runtime scripts behind named adapter modules +3. add adapter-level schema validation tests +4. define deployment profile format once adapter composition is stable + +## Summary + +The adapter interface is the missing contract that reconnects the proven watchdog auto-notify chain back into the reporting-governance plugin mainline. + +It makes the following explicit: + +- adapters are first-class plugin architecture +- watchdog/queue/dispatcher/bridge/sender/orchestrator are valid adapter surfaces, not side scripts +- operator notification must remain truthful across runtime boundaries +- capabilities must be declared, not assumed +- package structure can now evolve around a real integration contract diff --git a/schemas/reporting-governance/adapter-capabilities.schema.json b/schemas/reporting-governance/adapter-capabilities.schema.json new file mode 100644 index 0000000..e7875b8 --- /dev/null +++ b/schemas/reporting-governance/adapter-capabilities.schema.json @@ -0,0 +1,391 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://cowbay.org/schemas/reporting-governance/adapter-capabilities.schema.json", + "title": "Reporting Governance Adapter Capabilities", + "description": "Machine-readable capability descriptor for reporting-governance runtime adapters.", + "type": "object", + "additionalProperties": false, + "required": [ + "apiVersion", + "kind", + "metadata", + "runtime", + "compatibility", + "capabilities" + ], + "properties": { + "apiVersion": { + "type": "string", + "const": "reporting-governance/v1alpha1" + }, + "kind": { + "type": "string", + "const": "AdapterCapabilities" + }, + "metadata": { + "$ref": "#/$defs/metadata" + }, + "runtime": { + "$ref": "#/$defs/runtime" + }, + "compatibility": { + "$ref": "#/$defs/compatibility" + }, + "capabilities": { + "$ref": "#/$defs/capabilities" + }, + "defaults": { + "$ref": "#/$defs/defaults" + }, + "notes": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + } + }, + "$defs": { + "nonEmptyString": { + "type": "string", + "minLength": 1 + }, + "stringArray": { + "type": "array", + "items": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "metadata": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "title", + "version" + ], + "properties": { + "id": { + "$ref": "#/$defs/nonEmptyString" + }, + "title": { + "$ref": "#/$defs/nonEmptyString" + }, + "version": { + "$ref": "#/$defs/nonEmptyString" + }, + "owner": { + "$ref": "#/$defs/nonEmptyString" + }, + "summary": { + "$ref": "#/$defs/nonEmptyString" + }, + "tags": { + "$ref": "#/$defs/stringArray" + } + } + }, + "runtime": { + "type": "object", + "additionalProperties": false, + "required": [ + "name", + "mode" + ], + "properties": { + "name": { + "$ref": "#/$defs/nonEmptyString" + }, + "mode": { + "type": "string", + "enum": [ + "hook", + "watchdog", + "queue", + "bridge", + "sender_binding", + "orchestrator", + "hybrid" + ] + }, + "surfaces": { + "type": "array", + "minItems": 1, + "items": { + "type": "string", + "enum": [ + "hook", + "watchdog", + "queue", + "dispatcher", + "bridge", + "sender_binding", + "orchestrator", + "scheduler", + "storage" + ] + }, + "uniqueItems": true + }, + "entrypoint": { + "$ref": "#/$defs/nonEmptyString" + } + } + }, + "compatibility": { + "type": "object", + "additionalProperties": false, + "required": [ + "plugin_spec_versions" + ], + "properties": { + "plugin_spec_versions": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/nonEmptyString" + } + }, + "event_schema": { + "$ref": "#/$defs/nonEmptyString" + }, + "evidence_schema": { + "$ref": "#/$defs/nonEmptyString" + }, + "decision_schema": { + "$ref": "#/$defs/nonEmptyString" + }, + "capabilities_schema": { + "$ref": "#/$defs/nonEmptyString" + } + } + }, + "supportLevel": { + "type": "string", + "enum": [ + "none", + "partial", + "full" + ] + }, + "truthState": { + "type": "string", + "enum": [ + "prepared", + "queued", + "dispatched", + "pending_external_send", + "acked", + "blocked" + ] + }, + "ioSupport": { + "type": "object", + "additionalProperties": false, + "required": [ + "supported" + ], + "properties": { + "supported": { + "type": "boolean" + }, + "level": { + "$ref": "#/$defs/supportLevel" + }, + "notes": { + "$ref": "#/$defs/stringArray" + } + } + }, + "truthModel": { + "type": "object", + "additionalProperties": false, + "required": [ + "delivery_states", + "ack_requires_proven_send" + ], + "properties": { + "delivery_states": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/truthState" + }, + "uniqueItems": true + }, + "ack_requires_proven_send": { + "type": "boolean" + }, + "pending_external_send_supported": { + "type": "boolean" + } + } + }, + "observationCapabilities": { + "type": "object", + "additionalProperties": false, + "required": [ + "task_lifecycle", + "subagent_lifecycle", + "checkpoint_obligations", + "outgoing_report_attempts", + "watchdog_state", + "queue_spool_receipts" + ], + "properties": { + "task_lifecycle": { "$ref": "#/$defs/ioSupport" }, + "subagent_lifecycle": { "$ref": "#/$defs/ioSupport" }, + "checkpoint_obligations": { "$ref": "#/$defs/ioSupport" }, + "outgoing_report_attempts": { "$ref": "#/$defs/ioSupport" }, + "watchdog_state": { "$ref": "#/$defs/ioSupport" }, + "queue_spool_receipts": { "$ref": "#/$defs/ioSupport" } + } + }, + "normalizationCapabilities": { + "type": "object", + "additionalProperties": false, + "required": [ + "canonical_events", + "canonical_evidence", + "decision_inputs", + "correlation_propagation" + ], + "properties": { + "canonical_events": { "$ref": "#/$defs/ioSupport" }, + "canonical_evidence": { "$ref": "#/$defs/ioSupport" }, + "decision_inputs": { "$ref": "#/$defs/ioSupport" }, + "correlation_propagation": { "$ref": "#/$defs/ioSupport" } + } + }, + "enforcementCapabilities": { + "type": "object", + "additionalProperties": false, + "required": [ + "block_transition", + "rewrite_message", + "annotate_placeholder", + "force_checkpoint", + "request_review", + "downgrade_status", + "escalate" + ], + "properties": { + "block_transition": { "$ref": "#/$defs/ioSupport" }, + "rewrite_message": { "$ref": "#/$defs/ioSupport" }, + "annotate_placeholder": { "$ref": "#/$defs/ioSupport" }, + "force_checkpoint": { "$ref": "#/$defs/ioSupport" }, + "request_review": { "$ref": "#/$defs/ioSupport" }, + "downgrade_status": { "$ref": "#/$defs/ioSupport" }, + "escalate": { "$ref": "#/$defs/ioSupport" } + } + }, + "notificationCapabilities": { + "type": "object", + "additionalProperties": false, + "required": [ + "queue_items", + "spool_handoff", + "sender_binding", + "direct_send", + "receipts", + "final_delivery_proof", + "truth_model" + ], + "properties": { + "queue_items": { "$ref": "#/$defs/ioSupport" }, + "spool_handoff": { "$ref": "#/$defs/ioSupport" }, + "sender_binding": { "$ref": "#/$defs/ioSupport" }, + "direct_send": { "$ref": "#/$defs/ioSupport" }, + "receipts": { "$ref": "#/$defs/ioSupport" }, + "final_delivery_proof": { "$ref": "#/$defs/ioSupport" }, + "truth_model": { "$ref": "#/$defs/truthModel" } + } + }, + "watchdogCapabilities": { + "type": "object", + "additionalProperties": false, + "required": [ + "scheduler_installation", + "watchdog_evaluation", + "watchdog_event_emission", + "operator_recovery_path", + "watchdog_closure" + ], + "properties": { + "scheduler_installation": { "$ref": "#/$defs/ioSupport" }, + "watchdog_evaluation": { "$ref": "#/$defs/ioSupport" }, + "watchdog_event_emission": { "$ref": "#/$defs/ioSupport" }, + "operator_recovery_path": { "$ref": "#/$defs/ioSupport" }, + "watchdog_closure": { "$ref": "#/$defs/ioSupport" } + } + }, + "storageCapabilities": { + "type": "object", + "additionalProperties": false, + "required": [ + "persist_events", + "persist_evidence", + "persist_decisions", + "persist_receipts", + "preserve_original_attempted_message" + ], + "properties": { + "persist_events": { "$ref": "#/$defs/ioSupport" }, + "persist_evidence": { "$ref": "#/$defs/ioSupport" }, + "persist_decisions": { "$ref": "#/$defs/ioSupport" }, + "persist_receipts": { "$ref": "#/$defs/ioSupport" }, + "preserve_original_attempted_message": { "$ref": "#/$defs/ioSupport" } + } + }, + "capabilities": { + "type": "object", + "additionalProperties": false, + "required": [ + "observation", + "normalization", + "enforcement", + "notification_path", + "watchdog", + "storage" + ], + "properties": { + "observation": { + "$ref": "#/$defs/observationCapabilities" + }, + "normalization": { + "$ref": "#/$defs/normalizationCapabilities" + }, + "enforcement": { + "$ref": "#/$defs/enforcementCapabilities" + }, + "notification_path": { + "$ref": "#/$defs/notificationCapabilities" + }, + "watchdog": { + "$ref": "#/$defs/watchdogCapabilities" + }, + "storage": { + "$ref": "#/$defs/storageCapabilities" + } + } + }, + "defaults": { + "type": "object", + "additionalProperties": false, + "properties": { + "reporting_mode": { + "$ref": "#/$defs/nonEmptyString" + }, + "channel": { + "$ref": "#/$defs/nonEmptyString" + }, + "policy_ids": { + "$ref": "#/$defs/stringArray" + }, + "watchdog_policy_id": { + "$ref": "#/$defs/nonEmptyString" + } + } + } + } +}