# Reporting Governance Plugin > 中文在前,English below. > This package is the current package home for the reporting-governance mainline. ## 中文說明 ### 這個 package 是做什麼的? `@openclaw/plugin-reporting-governance` 的目標,是把「代理是否有按規則回報、是否在卡住時誠實升級、通知是否真的送達」這些治理要求,逐步整理成: - 可安裝的 package 邊界 - 可驗證的 capability / profile / schema artifacts - 可執行的 adapter entrypoints - 可測試的 governance core slice 目前最成熟、也最能直接展示價值的路徑,是 **OpenClaw watchdog reference chain**: ```text watchdog -> queue -> dispatcher -> bridge -> sender binding -> acked|blocked|pending_external_send ``` 白話講: 這個 package 目前最擅長的是把「長任務太久沒回報」這種治理問題,轉成一條有事件、有 handoff、有 receipt、而且不會假裝成功的通知鏈。 ### 目前誠實狀態 #### 已經有、而且有測試支持的部分 - package boundary 已建立: - `src/core/` - `src/adapters/` - `src/storage/` - `profiles/` - `capabilities/` - `schemas/` - 最小 runnable governance core 已存在: - `evaluatePolicyPack(...)` - `evaluatePolicies(...)` - `planDecisionExecution(...)` - `executeGovernanceContract(...)` - `executeRuntimeIntegratedGovernance(...)` - `runCompatibilityPreflight(...)` - OpenClaw watchdog reference composition 已可執行 - package-owned deployment profile artifact 已存在且可 loader/validator 驗證 - capability descriptor 已存在且與目前 reference runtime 對齊 - package tarball / clean-consumer install / public exports smoke tests 已存在 #### 還沒完成、不能誇大的部分 - 版本仍是 `0.1.0-mainline`,屬於 **pre-1.0 surface-tightening phase** - 還不是完整通用的 reporting-governance framework - 還沒把所有治理行為都做成通用 inline enforcement - adapter 仍有一部分是對既有 repo scripts 的收斂與包裝 - `src/` 裡有檔案,不代表那些路徑都是公開 API ### 現在最實用的驗證方式 #### 1. 跑 smoke ```bash npm run smoke ``` 預期: - 成功輸出 JSON - `ok: true` - 會顯示 orchestrator 執行順序 - 若 sender 未配置,結果應誠實停在 pending 類狀態 #### 2. 跑測試 ```bash npm test ``` 目前測試覆蓋重點包含: - package structure - descriptor / export boundary - policy evaluator / decision runner - compatibility preflight - profile artifact / profile generator - runtime-integrated slice - watchdog chain integration - orchestrator execution - packed consumer install smoke #### 3. 看目前最重要的 artifact / 文件 - `capabilities/openclaw-watchdog-reference.json` - `profiles/strict-manager-mode.profile.json` - `src/reference/openclaw-watchdog-chain.md` ### 安裝 / 使用建議(依目前成熟度) #### 當作 package 開發與驗證目標 在 repo root 或 package 目錄中: ```bash npm --prefix plugins/reporting-governance install npm --prefix plugins/reporting-governance test npm --prefix plugins/reporting-governance run smoke ``` #### 當作程式依賴使用 優先只依賴: - root export:`@openclaw/plugin-reporting-governance` - 已宣告的 adapter subpaths: - `@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` 不要把 repo 內 `src/...` 深層檔案路徑當成穩定公開 API。 #### 當作 runtime slice 使用 目前最合適的心態是: - 把它當成 **OpenClaw reference runtime composition** - 把它當成 **可驗證的 MVP package slice** - 不要把它當成「所有治理功能都已完成的 production product」 --- ## English ### What is this package for? `@openclaw/plugin-reporting-governance` is turning reporting-governance requirements into: - a real package boundary, - package-owned schemas / capabilities / deployment profiles, - executable adapter entrypoints, - and a testable governance core slice. The most concrete implemented path today is the **OpenClaw watchdog reference chain**: ```text watchdog -> queue -> dispatcher -> bridge -> sender binding -> acked|blocked|pending_external_send ``` In plain language: this package currently focuses on making overdue-reporting recovery auditable, testable, and honest about delivery truth. ### Honest status What is already real and tested: - package boundary under `plugins/reporting-governance/` - minimal runnable governance core - executable OpenClaw watchdog reference composition - package-owned deployment profile artifact - capability descriptor aligned to the current reference runtime - tarball/install/export smoke coverage What is not complete yet: - still **pre-1.0** (`0.1.0-mainline`) - not yet a fully generalized reporting-governance framework - not all governance behaviors are wired into general inline enforcement - some adapters still wrap existing repo scripts during MVP extraction - files under `src/` are not automatically public API ### Quick verification Run smoke: ```bash npm run smoke ``` Run tests: ```bash npm test ``` ### Practical install/use guidance Use public exports only: - `@openclaw/plugin-reporting-governance` - `@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` Do not treat deep `src/...` imports as stable API. --- ## Package skeleton ```text plugins/reporting-governance/ package.json README.md capabilities/ profiles/ profiles-src/ schemas/ scripts/ docs/ examples/ src/ core/ index.mjs policy-evaluator.mjs decision-runner.mjs execute-governance-contract.mjs runtime-integrated.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` `@openclaw/plugin-reporting-governance/adapters` 目前只代表 **runtime adapter entrypoints**。 `createRuntimeBinding(...)`、`loadDeploymentProfileArtifact(...)`、`createDeploymentBindingContract(...)` 不再掛在 `./adapters` barrel;前者仍由 root export 提供,後兩者屬於 storage/profile artifact slice。 目前 `storage` / `profile-artifact` 也**不是公開 subpath**;若要使用其能力,請以 root export / 已宣告 exports 為準,不要 deep import `src/storage/*`。 What is currently exposed from the root export: - `evaluatePolicyPack(...)` - `evaluatePolicies(...)` - `planDecisionExecution(...)` - `executeGovernanceContract(...)` - `executeRuntimeIntegratedGovernance(...)` - 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: ```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(...)` - 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. validator rejects `artifact_roots` absolute paths, lexical escapes, and symlink escapes that resolve outside repo realpath boundary 6. adapter runtime binding can be instantiated from that contract in tests 7. orchestrator adapter can now bootstrap from package profile artifact input directly 8. `queueItems` now has two checks: load-time artifact validation and orchestrator use-time realpath recheck before runtime consumption 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/runtime-integrated.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 - optionally hand that deployment binding into the orchestrator adapter when caller explicitly supplies runtime execution inputs 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. runtime-integrated helper can take that binding and route it into the orchestrator adapter 6. orchestrator adapter consumes the same binding and runs one real runtime layer 7. the result declares: - adapter-dispatch actions required - package-core actions possible locally - blocked mandatory actions when capability support is missing - truthful delivery / receipt state - runtime execution result when explicitly requested Current runtime contract in this repo is intentionally narrower than a future generalized aggregation model: - **single notice settlement path only** - one governance-triggered operator notice route is evaluated as one truth boundary - overall truth state may promote to `acked` only when the observed terminal outcome set for that single path is fully acked - mixed observed outcomes such as `acked + pending` or `acked + blocked` must stay non-`acked` - this slice does **not** yet claim generalized multi-notice aggregation, fan-in settlement, or cross-notice quorum semantics 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. What this means for implementers right now: - treat `dispatched` / `pending_external_send` / `blocked` as honest end states unless the single notice path reaches sender-backed ack proof - do not collapse partial success into overall `acked` - if future work introduces multiple notice paths, that must land as a separate runtime-contract slice with its own tests ## 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 - full audit-export packaging - production-ready installer flow