Files
reporting-governance-plugin/plugins/reporting-governance

Reporting Governance Plugin

This package is the emerging package boundary for the reporting-governance mainline.

Current purpose:

  • give the plugin a real package home
  • publish capability descriptors as package artifacts
  • fix boundaries between core/, adapters/, storage/, and reference implementations
  • prepare the next implementation round for evaluator / decision-runner extraction
  • provide a minimal package-level policy evaluator and decision runner skeleton that can be verified in isolation
  • add one minimal package-owned deployment profile artifact / loader / binding contract slice that is executable in tests
  • let profile artifacts drive one real orchestrator adapter entrypoint instead of staying test-only

Package skeleton

plugins/reporting-governance/
  package.json
  README.md
  capabilities/
  profiles/
  docs/
  examples/
  src/
    core/
      index.mjs
      policy-evaluator.mjs
      decision-runner.mjs
      execute-governance-contract.mjs
    adapters/
    storage/
    reference/
    index.mjs
  test/

Boundary rules

src/core/

Runtime-agnostic governance logic:

  • canonical event normalization
  • evidence building
  • policy evaluation
  • decision running
  • capability/profile compatibility

src/adapters/

Runtime-facing adapter modules:

  • watchdog adapter
  • dispatcher adapter
  • bridge adapter
  • sender-binding adapter
  • orchestrator adapter

These may initially wrap existing repo scripts while extraction is still in progress.

src/storage/

Durable I/O contracts for governance artifacts:

  • events
  • evidence
  • queue items
  • spool artifacts
  • receipts
  • decision/profile/package artifacts
  • future decisions / audit manifests

src/reference/

Reference runtime compositions and migration notes.

The watchdog reference runtime composition belongs here, as a reference implementation for OpenClaw rather than as package core logic.

Public surface and compatibility

Current public package surface is intentionally narrow:

  • root export: @openclaw/plugin-reporting-governance
  • adapter exports:
    • @openclaw/plugin-reporting-governance/adapters
    • @openclaw/plugin-reporting-governance/adapters/watchdog
    • @openclaw/plugin-reporting-governance/adapters/dispatcher
    • @openclaw/plugin-reporting-governance/adapters/bridge-supervisor
    • @openclaw/plugin-reporting-governance/adapters/sender-binding
    • @openclaw/plugin-reporting-governance/adapters/orchestrator

What is currently exposed from the root export:

  • evaluatePolicyPack(...)
  • evaluatePolicies(...)
  • planDecisionExecution(...)
  • executeGovernanceContract(...)
  • package metadata helpers such as packageName
  • package-owned adapter entrypoints and runWatchdogChain(...)

Compatibility posture for this slice:

  • 0.1.0-mainline should be treated as pre-1.0, surface-tightening phase.
  • Deep imports into src/ are not supported API even if files exist in-repo.
  • Tests now explicitly enforce that private paths like src/adapters/runtime-binding.mjs stay outside exports.
  • Adding a symbol to a file under src/ does not mean it is public unless wired through package exports.
  • Future tightening of root/adapters exports may still be a breaking change until a stable 1.0 surface is declared.

Compatibility envelope vs legacy compatibility mode

This slice now makes the boundary explicit:

  • compatibility envelope present = caller provides a deployment profile and/or package version pin, so runCompatibilityPreflight(...) must enforce canonical schema paths, declared plugin compatibility, required expectations, and action support fail-closed.
  • legacy compatibility mode = caller omits profile + package version entirely, so preflight keeps old call sites alive, records the missing version pin as a note, and does not fail only because descriptor schema/version metadata drifted.

Hard rule:

  • legacy mode is a caller-compatibility concession, not a relaxed truth model.
  • once any profile/package compatibility envelope is supplied, schema mismatch becomes blocking again.

Practical migration rule:

  • new integrations should always send a profile artifact or package version pin.
  • old integrations may temporarily call without one, but should treat returned notes as migration debt.
  • depend on package root exports or declared adapter subpaths only
  • do not couple runtime integrations to repo-private file paths
  • treat capability descriptors and schemas as package artifacts, but not as guaranteed JS import entrypoints unless exported later

Current reference composition

The current reference composition is the OpenClaw watchdog chain:

watchdog -> queue -> dispatcher -> bridge -> sender binding -> acked|blocked|pending_external_send

Package-home documentation:

  • src/reference/openclaw-watchdog-chain.md
  • capabilities/openclaw-watchdog-reference.json
  • profiles/strict-manager-mode.profile.json

Mainline background specs remain in:

  • docs/specs/reporting-governance-capability-descriptor.md
  • docs/specs/reporting-governance-adapter-interface.md
  • docs/specs/reporting-governance-deployment-model.md

Minimal profile artifact / loader / binding contract slice

This round adds one small but real package artifact path:

  • package artifact: profiles/strict-manager-mode.profile.json
  • loader: src/storage/profile-artifact.mjs#loadDeploymentProfileArtifact(...)
  • validator: src/storage/profile-artifact.mjs#validateDeploymentProfileArtifact(...)
  • binding contract: src/storage/profile-artifact.mjs#createDeploymentBindingContract(...)

What this slice does:

  1. package ships a profile artifact snapshot under package boundary
  2. loader resolves that artifact from package-local path
  3. validator fail-closes minimal boundary drift on kind, apiVersion, spec.bindings.entrypoint, scripts, artifact_roots, and spec.package.pluginVersion
  4. binding contract translates profile-declared script/artifact roots into concrete repo/runtime paths
  5. adapter runtime binding can be instantiated from that contract in tests
  6. orchestrator adapter can now bootstrap from package profile artifact input directly

What this slice does not claim yet:

  • full profile schema validation pipeline
  • automatic YAML -> artifact generation
  • generalized multi-profile packaging
  • production deployment installer

It is intentionally the smallest verifiable step that proves package profile artifacts are executable inputs rather than documentation only.

Minimal evaluator / decision runner now included

The current package now includes a small but runnable core/ implementation:

  • src/core/policy-evaluator.mjs
  • src/core/decision-runner.mjs
  • src/core/execute-governance-contract.mjs
  • src/core/index.mjs

Current package-core responsibilities:

  • normalize evaluator facts from canonical event payload + evidence + local context
  • match policy-pack rules by trigger and structured conditions
  • produce canonical decision-model shaped decision objects
  • choose the highest-precedence decision when multiple rules match
  • convert a canonical decision into an execution plan, enforcement intent, and receipt skeleton
  • truthfully degrade unsupported enforcement paths based on the capability descriptor
  • provide one minimal contract path from capability descriptor -> policy decision -> execution planning
  • surface deployment binding metadata when caller passes a validated profile artifact

Still runtime-adapter responsibility at this stage:

  • intercepting real outgoing messages or status transitions inline
  • actually sending operator notices
  • acking final delivery to external channels
  • persisting decisions/receipts into a production decision store
  • installing schedulers / watchdog loops / bridge sender bindings

This means core/ now owns evaluation and planning semantics, while adapters still own actual enforcement side effects.

Minimal end-to-end contract slice now included

This slice now has one small but testable contract path:

  1. capability descriptor advertises real enforcement support
  2. policy evaluator emits a canonical decision from event/evidence/context
  3. decision runner converts that decision into execution planning
  4. validated profile artifact can supply deployment binding metadata
  5. orchestrator adapter can consume profile artifact bindings and run one real runtime layer
  6. the result declares:
    • adapter-dispatch actions required
    • package-core actions possible locally
    • blocked mandatory actions when capability support is missing
    • truthful delivery / receipt state

This is intentionally planning-level end-to-end plus one adapter bootstrap layer, not full live inline interception. It proves contract alignment without pretending all runtime enforcement is already extracted.

Not yet included

This package still does not claim full implementation of:

  • generalized event normalization modules
  • generalized evidence builder modules
  • production decision persistence
  • complete rewrite / placeholder / review / status-downgrade adapter execution
  • non-watchdog full runtime governance interception

It now provides the first package-mainline evaluator / decision-runner core, a compatibility-envelope boundary, a minimal package profile artifact/binding slice, and one profile-driven orchestrator path, but the remaining enforcement surface is still intentionally honest about adapter gaps.