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-recalladapter 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.mjssrc/config/defaults.mjssrc/continuity/evaluator.mjssrc/continuity/receipt-validator.mjssrc/continuity/receipt-store.mjssrc/adapters/force-recall.mjssrc/index.mjs
src/index.mjs currently re-exports:
defaultConfigcloneDefaultConfig()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:
- run long-task preflight / gate lock / auto-chain planner
- dynamically load
plugins/continuity/src/index.mjs - call
runForceRecallContinuityAdapter({ wrapperResult, autoChainPlanResult, config }) - 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:
planIdcurrentTasknextDerivedActiondispatchedAtdispatchRunIdchildSessionKeyreplyClosureState
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
- Copy
plugins/continuityinto your workspace. - Ensure
hooks/force-recall/handler.tsloadsplugins/continuity/src/index.mjs. - Adjust the continuity config as needed, especially:
planMatcherslegalTerminalStatesreceiptDiradapter.forceRecall.injectBlockLabel
- If your dispatch flow creates child runs/sessions, persist a real receipt.
- Run the smoke test and the force-recall preflight test.
- 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
nextDerivedActionsubtype. - The documented install path assumes the existing
force-recallpreflight 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, andpending_verification - The evaluator preserves current behavior, including
missing_dispatch_receiptandmissing_auto_next_dispatch - The adapter mirrors the continuity input mapping used by
hooks/force-recall/handler.ts HOOK.mddescribes the plugin/hook adapter contract boundary, not the full installation guide
Chinese documentation
See README.zh-TW.md for the Traditional Chinese version.