# 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 ## Package skeleton ```text 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. Practical migration rule: - 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: ```text 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(...)` - 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. binding contract translates profile-declared script/artifact roots into concrete repo/runtime paths 4. adapter runtime binding can be instantiated from that contract in tests 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. ## Current reference composition The current reference composition is the OpenClaw watchdog chain: ```text watchdog -> queue -> dispatcher -> bridge -> sender binding -> acked|blocked|pending_external_send ``` ## 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` 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. 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**, 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, and a minimal package profile artifact/binding slice, but the remaining enforcement surface is still intentionally honest about adapter gaps.