21 KiB
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_firedevent 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:
- adapter responsibilities
- adapter lifecycle stages
- canonical input/output contracts
- capability declaration requirements
- runtime integration seams for watchdog / queue / dispatcher / bridge / sender / orchestrator
- 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:
-
Runtime observation layer Captures runtime-native facts such as task start, checkpoint due, subagent completion, watchdog overdue, or outgoing message attempt.
-
Adapter normalization layer Converts runtime-native facts into canonical events, evidence items, and governance evaluation inputs.
-
Policy evaluation layer Applies policy packs to canonical facts and emits canonical decisions.
-
Enforcement / delivery layer Executes required actions such as block, rewrite, force checkpoint, notify operator, or mark pending verification.
-
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.mdschemas/reporting-governance/event-envelope.schema.jsonschemas/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_operatorqueue 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.sendor equivalent - write
acked/blocked/pending_external_sendreceipts - 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 yetqueued— a queue item exists for future deliverydispatched— a handoff/spool artifact exists and a downstream runtime may now deliver itpending_external_send— the chain reached the bridge boundary honestly, but real send is not provenacked— an upper sender path proved success and the queue/receipt writeback completedblocked— 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
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:
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:
ackedblockedpending_external_send
4. Policy-aware receipts
Receipts should retain:
policy_id- trigger event type
task_idcorrelation_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_senddistinction 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_sendin dry-run - sender binding
sentleads to queueacked - sender binding
blockedleads to queueblocked
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:
- define default OpenClaw adapter capability profile JSON using the new schema
- extract current runtime scripts behind named adapter modules
- add adapter-level schema validation tests
- 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