Files
reporting-governance-plugin/plugins/continuity

Continuity Plugin (MVP)

中文版:README.zh-TW.md

This package extracts the current approved-plan continuity hard gate into a small installable, testable OpenClaw plugin MVP.

The goal is not to reinvent workflow policy. The goal is to package the existing continuity evaluator, receipt contract, and force-recall adapter so other OpenClaw workspaces can reuse the same minimum integration.

What this MVP currently provides

  • continuity config validation
  • dispatch receipt contract validation
  • receipt file writing
  • approved-plan continuity gate evaluation
  • prompt block generation for the continuity gate
  • a force-recall adapter that maps hook wrapper/planner output into continuity input

Install location

Recommended location inside an OpenClaw workspace:

<workspace>/plugins/continuity

With the current MVP integration, the related files normally look like this:

<workspace>/
  hooks/
    force-recall/
      handler.ts
      HOOK.md
  plugins/
    continuity/
      README.zh-TW.md
      README.md
      HOOK.md
      package.json
      examples/
      src/
      test/
  scripts/
    test_force_recall_long_task_preflight.mjs

Directory structure

plugins/continuity/
  README.zh-TW.md
  README.md
  HOOK.md
  package.json
  examples/
    approved-plan-receipt.example.json
    openclaw.continuity.example.json
  src/
    index.mjs
    adapters/
      force-recall.mjs
    config/
      defaults.mjs
      schema.mjs
    continuity/
      evaluator.mjs
      receipt-store.mjs
      receipt-validator.mjs
      types.md
  test/
    continuity.config.test.mjs
    continuity.evaluator.test.mjs
    continuity.plugin.test.mjs
    continuity.receipt-store.test.mjs
    continuity.receipt-validator.test.mjs
    continuity.smoke.test.mjs

Public surface

  • src/config/schema.mjs
  • src/config/defaults.mjs
  • src/continuity/evaluator.mjs
  • src/continuity/receipt-validator.mjs
  • src/continuity/receipt-store.mjs
  • src/adapters/force-recall.mjs
  • src/index.mjs

src/index.mjs currently re-exports:

  • defaultConfig
  • cloneDefaultConfig()
  • validateContinuityConfig() / normalizeContinuityConfig()
  • evaluateContinuity() / buildContinuityGateBlock()
  • validateReceipt() / isValidReceipt()
  • slugifyReceiptSegment() / buildReceiptFilename() / writeReceipt()
  • buildApprovedPlanContinuityInput()
  • createForceRecallContinuityAdapter() / runForceRecallContinuityAdapter()

Example config

Start from examples/openclaw.continuity.example.json:

{
  "enabled": true,
  "planMatchers": ["approved-plan"],
  "legalTerminalStates": [
    "waiting_user",
    "blocked",
    "pending_verification"
  ],
  "receiptDir": "state/approved-plan-continuity",
  "requireRealDispatchReceipt": true,
  "allowReplyClosureWithoutDispatch": false,
  "debug": false,
  "adapter": {
    "forceRecall": {
      "enabled": true,
      "injectBlockLabel": "APPROVED_PLAN_CONTINUITY_GATE"
    }
  }
}

Defaults are defined in src/config/defaults.mjs.

Hook integration

The primary MVP integration point is hooks/force-recall/handler.ts.

The current hook path is:

  1. run long-task preflight / gate lock / auto-chain planner
  2. dynamically load plugins/continuity/src/index.mjs
  3. call runForceRecallContinuityAdapter({ wrapperResult, autoChainPlanResult, config })
  4. prepend the returned block into bodyForAgent

The handler already contains the plugin path integration points. The key symbols are:

  • runForceRecallContinuityAdapter
  • [APPROVED_PLAN_CONTINUITY_GATE]

Minimal integration example:

import plugin from './plugins/continuity/src/index.mjs';

const out = plugin.runForceRecallContinuityAdapter({
  config: plugin.defaultConfig,
  wrapperResult,
  autoChainPlanResult,
});

if (out?.block) {
  context.bodyForAgent = `${out.block}\n${context.bodyForAgent}`;
}

If you want a custom injected block label, override adapter.forceRecall.injectBlockLabel.

Receipt contract

Minimum receipt shape:

  • planId
  • currentTask
  • nextDerivedAction
  • dispatchedAt
  • dispatchRunId
  • childSessionKey
  • replyClosureState

Example from examples/approved-plan-receipt.example.json:

{
  "planId": "example-plan",
  "currentTask": "task-01",
  "nextDerivedAction": {
    "kind": "delegate",
    "target": "subagent",
    "task": "placeholder"
  },
  "dispatchedAt": "2026-04-24T16:43:00+08:00",
  "dispatchRunId": "example-run",
  "childSessionKey": "session-placeholder",
  "replyClosureState": "pending_verification"
}

To persist a receipt:

import { writeReceipt } from './src/index.mjs';

await writeReceipt({
  receiptDir: 'state/approved-plan-continuity',
  receipt,
});

Smoke test / verification

At minimum, run:

cd plugins/continuity
npm test

cd /path/to/workspace
node scripts/test_force_recall_long_task_preflight.mjs
node --check hooks/force-recall/handler.ts

For a minimal plugin-only check, you can also run:

cd plugins/continuity
node test/continuity.smoke.test.mjs

Install and apply steps for another OpenClaw workspace

  1. Copy plugins/continuity into your workspace.
  2. Ensure hooks/force-recall/handler.ts loads plugins/continuity/src/index.mjs.
  3. Adjust the continuity config as needed, especially:
    • planMatchers
    • legalTerminalStates
    • receiptDir
    • adapter.forceRecall.injectBlockLabel
  4. If your dispatch flow creates child runs/sessions, persist a real receipt.
  5. Run the smoke test and the force-recall preflight test.
  6. Confirm the agent prompt contains the continuity gate block and that dry-run dispatch alone does not pass the gate.

Current limitations

  • This is an MVP extraction of the approved-plan continuity hard gate, not a general workflow engine.
  • The main adapter is force-recall; the package is not yet generalized into a multi-hook / multi-event integration layer.
  • Config is still passed as module defaults plus caller input; there is not yet a full OpenClaw plugin installer/registration guide.
  • The receipt store only writes files; it does not manage retention, cleanup, or indexing.
  • The receipt validator checks the minimum contract only; it does not deeply validate every nextDerivedAction subtype.
  • The documented install path assumes the existing force-recall preflight chain; if your workspace does not use that chain, you still need your own glue code.

Notes

  • Default legal terminal states are waiting_user, blocked, and pending_verification
  • The evaluator preserves current behavior, including missing_dispatch_receipt and missing_auto_next_dispatch
  • The adapter mirrors the continuity input mapping used by hooks/force-recall/handler.ts
  • HOOK.md describes the plugin/hook adapter contract boundary, not the full installation guide

Chinese documentation

See README.zh-TW.md for the Traditional Chinese version.