diff --git a/docs/specs/reporting-governance-policy-packs.md b/docs/specs/reporting-governance-policy-packs.md new file mode 100644 index 0000000..1d37134 --- /dev/null +++ b/docs/specs/reporting-governance-policy-packs.md @@ -0,0 +1,436 @@ +# Reporting Governance Policy Packs + +## Purpose + +This document defines the MVP policy-pack format for the reporting-governance plugin and specifies the first four reusable packs: + +- `no-silence` +- `no-fake-progress` +- `verified-completion-only` +- `mandatory-checkpoint-structure` + +These packs convert reporting expectations into portable policy artifacts that can be versioned, reviewed, pinned, and enforced across runtimes. + +They are designed to align with: + +- `docs/specs/reporting-governance-event-model.md` +- `docs/specs/reporting-governance-evidence-model.md` +- `docs/specs/reporting-governance-decision-model.md` + +## Design goals + +The MVP policy-pack system should: + +- express reporting rules as versioned artifacts instead of prompt folklore +- map canonical events plus evidence into canonical decisions +- make operator-visible follow-up obligations explicit +- preserve auditability when progress or completion claims are rewritten, blocked, or downgraded +- capture the concrete failure modes observed today: + - result arrived but no operator-visible follow-up + - promised follow-up not delivered + - next-step claim without evidence + +## Policy-pack scope + +A policy pack is a deployable bundle of one or more governance rules focused on a single reporting risk area. + +For MVP, each pack is a single `policy.yaml` file living at: + +- `policy-packs//policy.yaml` + +Future versions may allow multiple rule files, shared templates, profile overlays, or environment-specific wiring. MVP intentionally keeps the artifact simple. + +## Canonical policy-pack structure + +Every policy pack should use the following top-level shape. + +```yaml +apiVersion: reporting-governance/v1alpha1 +kind: PolicyPack +metadata: + id: no-silence + title: No Silence + version: 1.0.0 + summary: >- + Prevent missed checkpoints, invisible subagent handoffs, and silent task execution. + owner: reporting-governance-plugin + severity_default: high + applies_to: + runtimes: [openclaw] + task_modes: [interactive, silent] + tags: [reporting, checkpoints, anti-blackhole] + +spec: + evaluation_mode: any_rule_match + rules: + - id: no-silence.missed-checkpoint + title: Missed checkpoint requires immediate visible recovery + triggers: + event_types: [task_checkpoint_due, silence_timeout] + conditions: + all: + - fact: checkpoint.is_overdue + equals: true + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 1 + decision_output: + decision: force_checkpoint + severity: high + suggested_status: in_progress + operator_message_templates: + checkpoint_forced: >- + Required update: this task exceeded its reporting window... +``` + +## Top-level fields + +### `apiVersion` +Stable format version for the policy artifact. + +### `kind` +Must be `PolicyPack` for MVP. + +### `metadata` +Describes the pack as a versioned operational artifact. + +Required metadata fields: + +| Field | Type | Notes | +| --- | --- | --- | +| `id` | string | Stable pack identifier. | +| `title` | string | Human-readable pack name. | +| `version` | string | Semantic or release version. | +| `summary` | string | Short operator/reviewer summary. | +| `owner` | string | Responsible component or team. | +| `severity_default` | string | Default severity when a rule does not override it. | +| `applies_to` | object | Runtime/workflow applicability. | +| `tags` | array | Search and grouping labels. | + +Recommended `applies_to` fields: + +- `runtimes` +- `task_modes` +- `workflow_shapes` +- `channels` + +### `spec` +Contains evaluation behavior and rule definitions. + +Required spec fields: + +| Field | Type | Notes | +| --- | --- | --- | +| `evaluation_mode` | string | MVP values: `any_rule_match` or `first_match`. | +| `rules` | array | One or more policy rules. | + +## Rule structure + +Each rule should use the following shape. + +| Field | Type | Required | Notes | +| --- | --- | --- | --- | +| `id` | string | yes | Stable rule identifier used as `policy_id` in decisions. | +| `title` | string | yes | Human-readable rule title. | +| `intent` | string | yes | Short explanation of the behavior being governed. | +| `triggers` | object | yes | Canonical event types or derived trigger states. | +| `conditions` | object | yes | Boolean logic over event, evidence, decision, or task facts. | +| `evidence_requirements` | object | yes | Minimum evidence required for the governed claim or checkpoint. | +| `decision_output` | object | yes | Canonical decision-model output template. | +| `operator_message_templates` | object | yes | Operator-facing message templates for forced notices, rewrites, and review requests. | +| `notes` | array | no | Design notes, caveats, or alignment comments. | + +## `triggers` + +`triggers` identifies when a rule should evaluate. + +Recommended fields: + +| Field | Type | Notes | +| --- | --- | --- | +| `event_types` | array | Canonical event types from the event model. | +| `derived_signals` | array | Normalized evaluator signals such as `checkpoint_overdue`. | +| `claim_types` | array | Claim categories such as `progress`, `completion`, `verified_completion`. | + +Example: + +```yaml +triggers: + event_types: [task_claimed_complete] + claim_types: [completion, verified_completion] +``` + +## `conditions` + +`conditions` describes what must be true for the rule to fire. + +MVP uses structured boolean groups: + +- `all` +- `any` +- `not` + +Each leaf condition references a normalized evaluator fact, for example: + +- `checkpoint.is_overdue` +- `checkpoint.externalized_path_valid` +- `forwarding.result_available_without_visible_followup` +- `evidence.new_items_since_last_checkpoint` +- `evidence.completion_min_quality` +- `claim.promised_followup_due` +- `claim.next_step_has_supporting_evidence` +- `message.has_required_checkpoint_fields` + +Common comparators: + +- `equals` +- `not_equals` +- `greater_than` +- `less_than` +- `in` +- `contains` + +## `evidence_requirements` + +`evidence_requirements` connects the pack to the canonical evidence model. + +Recommended fields: + +| Field | Type | Notes | +| --- | --- | --- | +| `progress.min_new_items_since_last_checkpoint` | integer | Minimum new evidence items for progress-bearing reports. | +| `progress.allowed_quality_floor` | string | Minimum evidence quality allowed for progress claims. | +| `completion.min_quality` | string | Minimum quality for completion claims, usually `moderate`. | +| `verified_completion.min_quality` | string | Minimum quality for verified completion, usually `strong`. | +| `must_reference_event_types` | array | Event types that must be cited in operator-visible notices. | +| `must_reference_evidence_classes` | array | Evidence classes required for the claim path. | + +Semantics: + +- Progress claims must respect the evidence model requirement for at least one **new** evidence item since the previous checkpoint. +- Completion claims must meet the evidence model threshold of at least `moderate` support. +- Verified completion claims must meet the evidence model threshold of at least `strong` support. +- Some policies require operator-visible disclosure even when the evidence is runtime-derived rather than user-facing. + +## `decision_output` + +`decision_output` must map to the canonical decision model. + +Required fields: + +| Field | Type | Notes | +| --- | --- | --- | +| `decision` | string | Canonical decision value such as `block`, `force_checkpoint`, `downgrade_status`, `annotate_placeholder`, `require_review`. | +| `severity` | string | Canonical severity. | +| `reason` | string | Stable rationale template. | +| `suggested_status` | string or null | Recommended workflow status. | +| `required_actions` | array | Canonical required actions. | +| `operator_notice` | object | Operator-visible notice requirements. | + +Rule-specific variable interpolation is allowed in messages and reasons, but the resulting decision must still be expressible in the decision model defined in `docs/specs/reporting-governance-decision-model.md`. + +## `operator_message_templates` + +Each rule must provide operator-facing templates so the runtime does not have to improvise compliance language. + +Recommended template keys: + +- `checkpoint_forced` +- `placeholder_rewrite` +- `review_required` +- `status_downgraded` +- `blocked` + +Template goals: + +- clearly distinguish provisional vs verified states +- disclose when evidence is missing, repeated, or ambiguous +- reference required events or artifacts when the decision model says `must_reference` +- make follow-up obligations explicit + +## Alignment with event, evidence, and decision models + +### Event model alignment + +Policy packs must trigger from canonical events and derived facts built from them. + +Important event-model mappings for MVP packs: + +- `task_checkpoint_due` +- `task_checkpoint_sent` +- `task_claimed_complete` +- `subagent_completed` +- `subagent_result_forwarded` +- `subagent_result_not_forwarded` +- `silence_timeout` +- `forced_operator_update` +- `operator_review_requested` + +### Evidence model alignment + +Policy packs must interpret evidence using the evidence model’s classes and quality levels. + +Important evidence concepts for MVP packs: + +- no new evidence since last checkpoint +- narrative-only or reminder-only updates count as `none` +- next-step claims should cite new `decision_record`, `tool_output`, `file_change`, `runtime_artifact`, or other supported evidence when they assert concrete advancement +- completion claims require `moderate+` +- verified completion claims require `strong+` + +### Decision model alignment + +Policy packs must emit decisions from the canonical decision vocabulary. + +Important decision patterns for MVP: + +- `force_checkpoint` for missed checkpoint and dropped visible follow-up +- `annotate_placeholder` for status reports that would otherwise overstate progress +- `downgrade_status` for unsupported completion claims +- `require_review` for ambiguous completion evidence or borderline acceptance cases +- `block` when a required report structure or hard prerequisite is absent + +## MVP policy packs + +### 1. No Silence + +Purpose: +- prevent missed checkpoints from becoming blackholes +- prevent child-result arrival from remaining invisible to the operator +- prevent “silent” tasks unless a valid externalized checkpoint path exists + +Required failure modes covered: +- missed checkpoint +- subagent result not forwarded +- silent task without valid externalized checkpoint path +- result arrived but no operator-visible follow-up +- promised follow-up not delivered + +Typical decisions: +- `force_checkpoint` +- `block` +- `escalate` for repeated or critical cases + +### 2. No Fake Progress + +Purpose: +- prevent narrative activity from being treated as real progress +- require new evidence for progress-bearing checkpoints +- stop reminder-only or repeated status-only updates from being framed as advancement + +Required failure modes covered: +- no new evidence since last checkpoint +- repeated status-only updates +- reminder-only activity presented as progress +- next-step claim without evidence +- promised follow-up not delivered when the promised next update never gains evidence + +Typical decisions: +- `annotate_placeholder` +- `rewrite` +- `force_checkpoint` when silence risk is also active + +### 3. Verified Completion Only + +Purpose: +- prevent unsupported completion from being treated as accepted completion +- automatically downgrade unsupported completion to `pending_verification` +- route ambiguous completion to operator review + +Required failure modes covered: +- no completion without required evidence +- auto-downgrade to `pending_verification` +- operator review path when completion is ambiguous +- next-step or closure claim unsupported by evidence + +Typical decisions: +- `downgrade_status` +- `require_review` +- `block` for hard invalid completion attempts + +### 4. Mandatory Checkpoint Structure + +Purpose: +- require reports to include a stable operator-usable structure +- ensure that every checkpoint answers the core managerial questions +- prevent reports that look active but omit actionable next-state information + +Required structure equivalents: +- current status +- completed this segment +- next step +- next report condition +- whether operator intervention is needed + +Typical decisions: +- `rewrite` +- `block` +- `force_checkpoint` when missing structure would otherwise hide the actual task state + +## Evaluator guidance + +### Rule ordering + +Recommended MVP evaluation order: + +1. `no-silence` +2. `mandatory-checkpoint-structure` +3. `no-fake-progress` +4. `verified-completion-only` + +Rationale: +- visibility failures should be corrected first +- then the structure of the operator-visible report +- then truthfulness of progress wording +- then closure and acceptance semantics + +### Multiple matches + +If multiple rules match, the evaluator should prefer the most safety-preserving outcome. + +Recommended precedence when conflicts occur: + +1. `escalate` +2. `block` +3. `force_checkpoint` +4. `downgrade_status` +5. `require_review` +6. `rewrite` +7. `annotate_placeholder` +8. `allow` + +If one rule requires an operator-visible notice and another does not, the safer behavior is to preserve the notice requirement. + +### Audit trail + +When a rule rewrites, annotates, blocks, or downgrades a claim, the runtime should preserve: + +- original attempted message or claim text +- triggering event IDs when available +- attached or missing evidence summary +- resulting canonical decision object +- operator-visible message actually sent + +## Future evolution + +Potential future extensions include: + +- multi-file packs with shared templates +- environment/profile overlays +- schema-backed pack validation +- rule suppression windows for approved maintenance flows +- pack composition and inheritance +- rule telemetry for false-positive tuning + +## Summary + +The MVP policy-pack model gives the reporting-governance plugin a portable enforcement surface. It standardizes how reporting rules are declared, how they consume canonical events and evidence, and how they produce operator-visible decisions. + +The four initial packs focus on the observed operational failure modes that matter most: + +- silence +- fake progress +- unsupported completion +- structurally incomplete checkpoints + +Together, they provide a practical first layer of governance that is explicit, reviewable, and aligned with the event, evidence, and decision models. diff --git a/policy-packs/mandatory-checkpoint-structure/policy.yaml b/policy-packs/mandatory-checkpoint-structure/policy.yaml new file mode 100644 index 0000000..4adae2f --- /dev/null +++ b/policy-packs/mandatory-checkpoint-structure/policy.yaml @@ -0,0 +1,212 @@ +apiVersion: reporting-governance/v1alpha1 +kind: PolicyPack +metadata: + id: mandatory-checkpoint-structure + title: Mandatory Checkpoint Structure + version: 1.0.0 + summary: >- + Require checkpoint reports to include the minimum operator-usable structure + for status, completed work, next step, next reporting condition, and intervention need. + owner: reporting-governance-plugin + severity_default: medium + applies_to: + runtimes: [openclaw] + task_modes: [interactive, silent] + workflow_shapes: [single-agent, parent-child] + channels: [telegram] + tags: [reporting, structure, checkpoints, operator-ux] +spec: + evaluation_mode: any_rule_match + rules: + - id: mandatory-checkpoint-structure.required-fields-missing + title: Checkpoint must include the required operator fields + intent: >- + Ensure every checkpoint answers the minimum managerial questions the + operator needs to supervise the task. + triggers: + event_types: [task_checkpoint_sent, forced_operator_update] + claim_types: [progress] + conditions: + any: + - fact: message.current_status_present + equals: false + - fact: message.completed_this_segment_present + equals: false + - fact: message.next_step_present + equals: false + - fact: message.next_report_condition_present + equals: false + - fact: message.operator_intervention_needed_present + equals: false + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 0 + decision_output: + decision: rewrite + severity: medium + reason: >- + checkpoint omitted one or more required operator-usable fields + suggested_status: in_progress + required_actions: + - action: rewrite_message + target: outgoing_report + mandatory: true + details: + mode: inject_missing_checkpoint_fields + - action: append_audit_note + target: task_record + mandatory: true + details: + note: missing checkpoint fields were normalized by governance + operator_notice: + required: false + channel: telegram + urgency: low + message: null + must_reference: [] + deadline: null + operator_message_templates: + placeholder_rewrite: >- + Structured checkpoint required: + - Current status: {{current_status_or_unknown}} + - Completed this segment: {{completed_this_segment_or_none}} + - Next step: {{next_step_or_unspecified}} + - Next report condition: {{next_report_condition_or_missing}} + - Operator intervention needed: {{operator_intervention_needed_or_unknown}} + + - id: mandatory-checkpoint-structure.next-step-and-report-condition-coupled + title: Next step must be paired with the next reporting condition + intent: >- + Prevent checkpoints from naming a next action without saying when or why + the operator should expect the next update. + triggers: + event_types: [task_checkpoint_sent] + claim_types: [progress] + conditions: + all: + - fact: message.next_step_present + equals: true + - fact: message.next_report_condition_present + equals: false + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 0 + decision_output: + decision: rewrite + severity: medium + reason: >- + next step was stated without the next reporting condition + suggested_status: in_progress + required_actions: + - action: rewrite_message + target: outgoing_report + mandatory: true + details: + mode: append_next_report_condition_prompt + - action: append_audit_note + target: task_record + mandatory: true + details: + note: next-step-only checkpoint normalized to include follow-up condition + operator_notice: + required: false + channel: telegram + urgency: low + message: null + must_reference: [] + deadline: null + operator_message_templates: + placeholder_rewrite: >- + Next step recorded, but the next report condition was missing. The + checkpoint must say when the next update will be sent or what event will trigger it. + + - id: mandatory-checkpoint-structure.operator-intervention-explicit + title: Checkpoint must explicitly say whether operator intervention is needed + intent: >- + Prevent reports that leave the operator unsure whether action or waiting + is required. + triggers: + event_types: [task_checkpoint_sent, operator_review_requested, forced_operator_update] + claim_types: [progress, completion] + conditions: + all: + - fact: message.operator_intervention_needed_present + equals: false + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 0 + decision_output: + decision: rewrite + severity: medium + reason: >- + checkpoint did not explicitly state whether operator intervention is needed + suggested_status: in_progress + required_actions: + - action: rewrite_message + target: outgoing_report + mandatory: true + details: + mode: append_operator_intervention_field + operator_notice: + required: false + channel: telegram + urgency: low + message: null + must_reference: [] + deadline: null + operator_message_templates: + placeholder_rewrite: >- + Operator intervention field required: explicitly say either "no + operator action needed now" or describe the exact intervention required. + + - id: mandatory-checkpoint-structure.block-empty-checkpoint + title: Empty or nearly empty checkpoints must not pass as compliant reports + intent: >- + Block reports that lack enough structure to function as real + supervision checkpoints. + triggers: + event_types: [task_checkpoint_sent, forced_operator_update] + claim_types: [progress] + conditions: + all: + - fact: message.required_checkpoint_field_count_present + less_than: 2 + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 0 + decision_output: + decision: block + severity: high + reason: >- + checkpoint was too structurally incomplete to count as a compliant report + suggested_status: blocked + required_actions: + - action: block_transition + target: outgoing_report + mandatory: true + details: + blocked_action: send_incomplete_checkpoint + - action: notify_operator + target: operator_channel + mandatory: true + details: + kind: malformed_checkpoint + - action: append_audit_note + target: task_record + mandatory: true + details: + note: empty checkpoint blocked before dispatch + operator_notice: + required: true + channel: telegram + urgency: medium + message: >- + A checkpoint was blocked because it omitted most required structure + and could not function as a real operator update. + must_reference: [] + deadline: immediate + operator_message_templates: + blocked: >- + Blocked: this checkpoint is too incomplete to send. It must include at + least current status, completed this segment, next step, next report + condition, and whether operator intervention is needed. diff --git a/policy-packs/no-fake-progress/policy.yaml b/policy-packs/no-fake-progress/policy.yaml new file mode 100644 index 0000000..1ddf741 --- /dev/null +++ b/policy-packs/no-fake-progress/policy.yaml @@ -0,0 +1,216 @@ +apiVersion: reporting-governance/v1alpha1 +kind: PolicyPack +metadata: + id: no-fake-progress + title: No Fake Progress + version: 1.0.0 + summary: >- + Prevent status language, reminders, or unsupported next-step claims from + being treated as real progress without new evidence. + owner: reporting-governance-plugin + severity_default: medium + applies_to: + runtimes: [openclaw] + task_modes: [interactive, silent] + workflow_shapes: [single-agent, parent-child] + channels: [telegram] + tags: [reporting, evidence, anti-fake-progress] +spec: + evaluation_mode: any_rule_match + rules: + - id: no-fake-progress.no-new-evidence + title: Progress-bearing checkpoint requires new evidence + intent: >- + Prevent narrative-only progress reports from satisfying checkpoint + obligations when nothing new has been attached since the last report. + triggers: + event_types: [task_checkpoint_sent, task_status_changed] + derived_signals: [checkpoint_progress_claim] + claim_types: [progress] + conditions: + all: + - fact: claim.is_progress_bearing + equals: true + - fact: evidence.new_items_since_last_checkpoint + equals: 0 + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 1 + allowed_quality_floor: weak + must_reference_evidence_classes: [tool_output, file_change, decision_record, runtime_artifact] + decision_output: + decision: annotate_placeholder + severity: medium + reason: >- + checkpoint contains no new evidence and cannot count as substantive progress + suggested_status: in_progress + required_actions: + - action: rewrite_message + target: outgoing_report + mandatory: true + details: + mode: replace_with_placeholder + - action: append_audit_note + target: task_record + mandatory: true + details: + note: original progress wording preserved for audit; no new evidence was attached + operator_notice: + required: true + channel: telegram + urgency: medium + message: >- + Progress update was rewritten as a placeholder because no new + evidence was attached since the previous checkpoint. + must_reference: [] + deadline: null + operator_message_templates: + placeholder_rewrite: >- + Progress update: work is still in progress, but no new auditable + artifact was attached since the previous checkpoint. The next update + must include new evidence such as tool output, a file change, or a + decision record. + + - id: no-fake-progress.repeated-status-only + title: Repeated status-only updates must not be framed as advancement + intent: >- + Distinguish liveness or continuity from actual task advancement. + triggers: + event_types: [task_checkpoint_sent, forced_operator_update] + derived_signals: [repeated_status_only_update] + claim_types: [progress] + conditions: + all: + - fact: message.status_only + equals: true + - fact: message.substantive_delta_from_previous + equals: false + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 1 + allowed_quality_floor: weak + decision_output: + decision: rewrite + severity: medium + reason: >- + repeated status-only update was presented as progress without a new substantive delta + suggested_status: in_progress + required_actions: + - action: rewrite_message + target: outgoing_report + mandatory: true + details: + mode: reframe_as_continuity_update + - action: append_audit_note + target: task_record + mandatory: true + details: + note: repeated status-only update reframed to avoid fake progress + operator_notice: + required: false + channel: telegram + urgency: low + message: null + must_reference: [] + deadline: null + operator_message_templates: + placeholder_rewrite: >- + Continuity update only: task status remains unchanged since the last + checkpoint. No new progress artifact has been attached yet. + + - id: no-fake-progress.reminder-presented-as-progress + title: Reminder-only activity must not count as progress + intent: >- + Prevent nudges, reminders, or waiting-state management from being + presented as actual task advancement unless new evidence accompanies them. + triggers: + event_types: [task_checkpoint_sent, operator_review_requested] + derived_signals: [reminder_only_activity] + claim_types: [progress] + conditions: + all: + - fact: activity.kind + equals: reminder_only + - fact: evidence.new_items_since_last_checkpoint + equals: 0 + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 1 + allowed_quality_floor: weak + decision_output: + decision: rewrite + severity: medium + reason: >- + reminder-only activity was presented as task progress without supporting evidence + suggested_status: in_progress + required_actions: + - action: rewrite_message + target: outgoing_report + mandatory: true + details: + mode: reframe_as_non_progress_update + - action: append_audit_note + target: task_record + mandatory: true + details: + note: reminder-only activity cannot satisfy progress reporting on its own + operator_notice: + required: false + channel: telegram + urgency: low + message: null + must_reference: [] + deadline: null + operator_message_templates: + placeholder_rewrite: >- + Non-progress update: reminder or follow-up activity occurred, but no + new task evidence was attached. This does not count as substantive progress. + + - id: no-fake-progress.next-step-claim-without-evidence + title: Concrete next-step claims need supporting evidence or explicit uncertainty + intent: >- + Prevent unsupported claims about what was prepared, queued, or made ready + for the next segment of work. + triggers: + event_types: [task_checkpoint_sent, task_status_changed] + derived_signals: [next_step_asserted] + claim_types: [progress] + conditions: + all: + - fact: claim.next_step_asserted + equals: true + - fact: claim.next_step_has_supporting_evidence + equals: false + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 1 + allowed_quality_floor: weak + must_reference_evidence_classes: [decision_record, tool_output, file_change, runtime_artifact] + decision_output: + decision: annotate_placeholder + severity: medium + reason: >- + next-step claim was stated without evidence showing the prerequisite work or decision basis + suggested_status: in_progress + required_actions: + - action: rewrite_message + target: outgoing_report + mandatory: true + details: + mode: qualify_next_step_claim + - action: append_audit_note + target: task_record + mandatory: true + details: + note: unsupported next-step assertion qualified by governance + operator_notice: + required: false + channel: telegram + urgency: low + message: null + must_reference: [] + deadline: null + operator_message_templates: + placeholder_rewrite: >- + Next step is proposed, not yet evidenced. Before it can be reported as + prepared or ready, the task needs a supporting artifact or decision record. diff --git a/policy-packs/no-silence/policy.yaml b/policy-packs/no-silence/policy.yaml new file mode 100644 index 0000000..587db44 --- /dev/null +++ b/policy-packs/no-silence/policy.yaml @@ -0,0 +1,253 @@ +apiVersion: reporting-governance/v1alpha1 +kind: PolicyPack +metadata: + id: no-silence + title: No Silence + version: 1.0.0 + summary: >- + Prevent missed checkpoints, invisible child-result handoffs, and silent task + execution unless a valid externalized checkpoint path exists. + owner: reporting-governance-plugin + severity_default: high + applies_to: + runtimes: [openclaw] + task_modes: [interactive, silent] + workflow_shapes: [single-agent, parent-child] + channels: [telegram] + tags: [reporting, anti-blackhole, checkpoints, forwarding] +spec: + evaluation_mode: any_rule_match + rules: + - id: no-silence.missed-checkpoint + title: Missed checkpoint requires immediate visible recovery + intent: >- + Prevent overdue reporting obligations from becoming invisible work. + triggers: + event_types: [task_checkpoint_due, silence_timeout] + derived_signals: [checkpoint_overdue] + claim_types: [progress] + conditions: + all: + - fact: checkpoint.is_overdue + equals: true + - fact: checkpoint.operator_visible_update_sent + equals: false + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 1 + allowed_quality_floor: weak + must_reference_event_types: [silence_timeout] + decision_output: + decision: force_checkpoint + severity: high + reason: >- + required checkpoint became overdue without an operator-visible update + suggested_status: in_progress + required_actions: + - action: notify_operator + target: operator_channel + mandatory: true + details: + kind: forced_checkpoint + - action: emit_event + target: event_stream + mandatory: true + details: + event_type: forced_operator_update + - action: append_audit_note + target: task_record + mandatory: true + details: + note: checkpoint silence breach recovered through forced operator update + operator_notice: + required: true + channel: telegram + urgency: high + message: >- + Required update: this task exceeded its reporting window and an + immediate checkpoint is now required. + must_reference: [silence_timeout] + deadline: immediate + operator_message_templates: + checkpoint_forced: >- + Required update: this task exceeded the allowed reporting window. + Current state is being reconciled now, and a substantive follow-up + must be sent immediately. + + - id: no-silence.subagent-result-not-forwarded + title: Child result must not disappear between completion and operator follow-up + intent: >- + Catch the exact failure mode where a child result exists but no + operator-visible forwarding step occurred in time. + triggers: + event_types: [subagent_completed, subagent_result_not_forwarded, watchdog_fired] + derived_signals: [result_available_without_visible_followup] + claim_types: [progress, completion] + conditions: + all: + - fact: forwarding.result_available + equals: true + - fact: forwarding.operator_visible_followup_present + equals: false + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 1 + allowed_quality_floor: weak + must_reference_event_types: + [subagent_completed, subagent_result_not_forwarded] + must_reference_evidence_classes: [runtime_artifact, operator_message] + decision_output: + decision: force_checkpoint + severity: critical + reason: >- + child result was available but no operator-visible forwarding record + was produced before the watchdog deadline + suggested_status: pending_verification + required_actions: + - action: notify_operator + target: operator_channel + mandatory: true + details: + kind: missing_forwarded_result + - action: emit_event + target: event_stream + mandatory: true + details: + event_type: subagent_result_not_forwarded + - action: record_placeholder + target: outgoing_report + mandatory: true + details: + label: result_received_forwarding_pending + - action: append_audit_note + target: task_record + mandatory: true + details: + note: child result existed before visible follow-up; forced checkpoint issued + operator_notice: + required: true + channel: telegram + urgency: critical + message: >- + Child result was received but not forwarded visibly in time. + Immediate checkpoint issued and operator-visible follow-up is now + mandatory. + must_reference: [subagent_completed, subagent_result_not_forwarded] + deadline: immediate + operator_message_templates: + checkpoint_forced: >- + Checkpoint: a child task result has been received, but the required + operator-visible forwarding step was missed. Governance is surfacing + this immediately and preserving the result for follow-up. + placeholder_rewrite: >- + Placeholder only: child result exists, but the verified forwarding + summary is still pending. + + - id: no-silence.silent-task-without-externalized-path + title: Silent task requires a valid externalized checkpoint path + intent: >- + Block silent execution when there is no approved way to externalize + checkpoints or completion notices. + triggers: + event_types: [task_started] + derived_signals: [silent_task_launch] + conditions: + all: + - fact: task.silent_mode_requested + equals: true + - fact: checkpoint.externalized_path_valid + equals: false + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 0 + must_reference_event_types: [task_started] + decision_output: + decision: block + severity: high + reason: >- + silent task execution was requested without a valid externalized + checkpoint path + suggested_status: blocked + required_actions: + - action: block_transition + target: status_transition + mandatory: true + details: + blocked_action: task_start + - action: notify_operator + target: operator_channel + mandatory: true + details: + kind: silent_task_blocked + - action: append_audit_note + target: task_record + mandatory: true + details: + note: silent task blocked because no compliant external checkpoint path exists + operator_notice: + required: true + channel: telegram + urgency: high + message: >- + Silent task launch was blocked because no valid externalized + checkpoint path was available. + must_reference: [task_started] + deadline: immediate + operator_message_templates: + blocked: >- + Blocked: this task cannot run silently because there is no valid + externalized checkpoint path for operator-visible reporting. + + - id: no-silence.promised-followup-not-delivered + title: Promised follow-up must either arrive or be surfaced as a failure + intent: >- + Prevent agents from promising a near-term follow-up and then going dark. + triggers: + event_types: [task_checkpoint_sent, silence_timeout, forced_operator_update] + derived_signals: [followup_deadline_breached] + claim_types: [progress] + conditions: + all: + - fact: claim.promised_followup_due + equals: true + - fact: claim.promised_followup_delivered + equals: false + evidence_requirements: + progress: + min_new_items_since_last_checkpoint: 0 + must_reference_event_types: [forced_operator_update] + decision_output: + decision: force_checkpoint + severity: high + reason: >- + an explicit follow-up promise was not delivered by its own reporting condition + suggested_status: in_progress + required_actions: + - action: notify_operator + target: operator_channel + mandatory: true + details: + kind: missed_promised_followup + - action: emit_event + target: event_stream + mandatory: true + details: + event_type: forced_operator_update + - action: append_audit_note + target: task_record + mandatory: true + details: + note: promised follow-up breached and was surfaced as a governance failure + operator_notice: + required: true + channel: telegram + urgency: high + message: >- + A promised follow-up was not delivered on time. Governance is + issuing an immediate recovery checkpoint. + must_reference: [forced_operator_update] + deadline: immediate + operator_message_templates: + checkpoint_forced: >- + Required update: a previously promised follow-up did not arrive on + time. This recovery checkpoint is being sent to avoid silent drift. diff --git a/policy-packs/verified-completion-only/policy.yaml b/policy-packs/verified-completion-only/policy.yaml new file mode 100644 index 0000000..680ac25 --- /dev/null +++ b/policy-packs/verified-completion-only/policy.yaml @@ -0,0 +1,171 @@ +apiVersion: reporting-governance/v1alpha1 +kind: PolicyPack +metadata: + id: verified-completion-only + title: Verified Completion Only + version: 1.0.0 + summary: >- + Prevent completion from being accepted without the evidence and review state + required by the governance evidence and decision models. + owner: reporting-governance-plugin + severity_default: high + applies_to: + runtimes: [openclaw] + task_modes: [interactive, silent] + workflow_shapes: [single-agent, parent-child] + channels: [telegram] + tags: [reporting, completion, verification, review] +spec: + evaluation_mode: any_rule_match + rules: + - id: verified-completion-only.completion-without-required-evidence + title: Completion claim below moderate evidence threshold is invalid + intent: >- + Enforce the evidence-model baseline that completion requires at least + moderate auditable support. + triggers: + event_types: [task_claimed_complete] + claim_types: [completion] + conditions: + all: + - fact: claim.completion_asserted + equals: true + - fact: evidence.completion_min_quality + less_than: moderate + evidence_requirements: + completion: + min_quality: moderate + must_reference_evidence_classes: [verification_output, file_change, tool_output, decision_record] + decision_output: + decision: downgrade_status + severity: high + reason: >- + completion was claimed without sufficient auditable evidence + suggested_status: pending_verification + required_actions: + - action: set_status + target: status_transition + mandatory: true + details: + from: completed + to: pending_verification + - action: request_review + target: review_queue + mandatory: true + details: + review_scope: completion_evidence + - action: append_audit_note + target: task_record + mandatory: true + details: + note: original completion claim preserved; downgraded by governance due to insufficient evidence + operator_notice: + required: true + channel: telegram + urgency: high + message: >- + Completion claim was downgraded to pending verification because + sufficient evidence was not attached. + must_reference: [] + deadline: null + operator_message_templates: + status_downgraded: >- + Completion claim received, but the task remains pending verification + until auditable evidence is attached. + + - id: verified-completion-only.verified-completion-without-strong-evidence + title: Verified completion requires strong evidence + intent: >- + Enforce the stronger threshold for reports that claim verified or fully + accepted completion. + triggers: + event_types: [task_claimed_complete] + claim_types: [verified_completion] + conditions: + all: + - fact: claim.verified_completion_asserted + equals: true + - fact: evidence.verified_completion_min_quality + less_than: strong + evidence_requirements: + verified_completion: + min_quality: strong + must_reference_evidence_classes: [verification_output, decision_record] + decision_output: + decision: require_review + severity: high + reason: >- + verified completion was asserted without strong enough supporting evidence + suggested_status: pending_verification + required_actions: + - action: request_review + target: review_queue + mandatory: true + details: + review_scope: verified_completion + - action: append_audit_note + target: task_record + mandatory: true + details: + note: verified completion wording retained for audit but requires review before acceptance + operator_notice: + required: true + channel: telegram + urgency: high + message: >- + Verified completion was claimed, but the evidence does not yet meet + the strong threshold required for acceptance. + must_reference: [] + deadline: null + operator_message_templates: + review_required: >- + Review required: completion may be real, but the current evidence does + not yet justify a verified-completion label. + + - id: verified-completion-only.ambiguous-completion-review-path + title: Ambiguous completion must be routed to operator review + intent: >- + Provide a conservative review path when completion evidence exists but + remains mixed, incomplete, or interpretation-dependent. + triggers: + event_types: [task_claimed_complete, operator_review_requested] + claim_types: [completion] + conditions: + all: + - fact: claim.completion_asserted + equals: true + - fact: evidence.completion_is_ambiguous + equals: true + evidence_requirements: + completion: + min_quality: moderate + decision_output: + decision: require_review + severity: medium + reason: >- + completion evidence is present but ambiguous and should not be auto-accepted + suggested_status: awaiting_review + required_actions: + - action: request_review + target: review_queue + mandatory: true + details: + review_scope: ambiguous_completion + - action: notify_operator + target: operator_channel + mandatory: true + details: + kind: ambiguous_completion_review + operator_notice: + required: true + channel: telegram + urgency: medium + message: >- + Completion evidence exists but is ambiguous. Operator review is + required before the task can be treated as complete. + must_reference: [] + deadline: null + operator_message_templates: + review_required: >- + Completion evidence is present, but acceptance is ambiguous. This task + is being routed for operator review rather than treated as complete.