# Continuity Plugin MVP Implementation Plan > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** Extract the current approved-plan continuity hard-gate into an installable, configurable, testable OpenClaw plugin MVP with bilingual README guidance, example config, and smoke-test flow. **Architecture:** Keep the MVP small and adapter-first. Move continuity logic out of the current hard-coded scripts into a plugin package with four clear seams: config schema, continuity evaluator, receipt validator/storage helper, and hook adapter. Preserve current behavior first, then wrap it in plugin packaging, plugin docs, and plugin-level tests so the same continuity gate can be installed and configured without patching core workflow logic. **Tech Stack:** Node.js, ESM (`.mjs`/TypeScript where already present), file-backed JSON receipts, OpenClaw hook/plugin conventions, bilingual Markdown docs, script-level test runners. --- ## Implementation Notes for the Engineer - Current behavior already exists in these files and should be treated as the extraction source of truth for MVP parity: - `scripts/approved_plan_continuity_gate.mjs` - `scripts/approved_plan_dispatch_binding.mjs` - `scripts/test_approved_plan_continuity_gate.mjs` - `hooks/force-recall/handler.ts` - `docs/runbooks/approved-plan-continuity.md` - `state/approved-plan-continuity/README.md` - The workspace currently has an empty top-level `plugins/` directory, so the plan assumes creating a dedicated plugin package there instead of mixing plugin code back into `scripts/`. - Do not widen scope into a generalized workflow engine. MVP means: preserve today’s continuity decision model, make it pluggable/configurable, document installation, and prove it with tests and a smoke path. - Prefer pure functions for evaluator/validator pieces so they can be tested without spawning hooks. - Treat current hard-gate scripts as compatibility fixtures during migration. Only remove or thin them after plugin parity is verified. ## Proposed MVP Package Layout ```text plugins/continuity/ README.md README.zh-TW.md package.json HOOK.md examples/ openclaw.continuity.example.json approved-plan-receipt.example.json src/ index.mjs config/ schema.mjs defaults.mjs continuity/ evaluator.mjs receipt-validator.mjs receipt-store.mjs types.md adapters/ force-recall.mjs script-bridge.mjs test/ continuity.evaluator.test.mjs continuity.receipt-validator.test.mjs continuity.plugin.test.mjs continuity.smoke.test.mjs ``` If the repo’s actual plugin loader requires a different manifest filename or entrypoint shape, adapt the filenames but keep the same responsibilities and test coverage. ## Acceptance Target The MVP is acceptable only when all of the following are true: 1. Continuity rules are configurable through a plugin config schema instead of only hard-coded constants. 2. The evaluator can be imported and tested as a standalone module. 3. Receipt validation is separated from gate decision logic. 4. A hook adapter can call the plugin and inject the same kind of hard-gate behavior now implemented in `hooks/force-recall/handler.ts`. 5. The plugin ships with bilingual install/apply documentation. 6. The repo contains example config and at least one repeatable smoke test command. 7. Existing current-script behavior is either preserved through bridge wrappers or explicitly mapped in the README migration section. --- ### Task 1: Capture current continuity behavior as extraction baseline **Files:** - Review: `scripts/approved_plan_continuity_gate.mjs` - Review: `scripts/approved_plan_dispatch_binding.mjs` - Review: `scripts/test_approved_plan_continuity_gate.mjs` - Review: `hooks/force-recall/handler.ts` - Review: `docs/runbooks/approved-plan-continuity.md` **Step 1: Create a baseline notes section in the plan worklog** - Write down the exact current responsibilities: - legal terminal states - minimum dispatch receipt fields - receipt filename convention - how `force-recall` currently invokes continuity - which behaviors are already covered by tests **Step 2: Verify nothing was guessed** Run: ```bash rg -n "waiting_user|blocked|pending_verification|dispatchReceipt|nextDerivedAction|approved_plan_continuity" \ scripts/approved_plan_continuity_gate.mjs \ scripts/approved_plan_dispatch_binding.mjs \ scripts/test_approved_plan_continuity_gate.mjs \ hooks/force-recall/handler.ts \ docs/runbooks/approved-plan-continuity.md ``` Expected: matching lines confirm all baseline rules come from checked-in files **Step 3: Commit baseline notes** ```bash git add docs/plans/2026-04-24-continuity-plugin-mvp.md git commit -m "docs: capture continuity plugin extraction baseline" ``` ### Task 1 Baseline Worklog (captured 2026-04-24) #### Reviewed source-of-truth files - `scripts/approved_plan_continuity_gate.mjs` - `scripts/approved_plan_dispatch_binding.mjs` - `scripts/test_approved_plan_continuity_gate.mjs` - `scripts/test_force_recall_long_task_preflight.mjs` - `hooks/force-recall/handler.ts` - `docs/runbooks/approved-plan-continuity.md` #### Current responsibilities baseline - `scripts/approved_plan_continuity_gate.mjs` - Reads JSON input from `--input ` and emits one JSON envelope to stdout. - Evaluates approved-plan continuity only when: - `taskState === 'complete'` - a next action is known via `nextDerivedAction ?? derivedAction` - no valid `dispatchReceipt` is present - `replyClosureState` is not one of the legal terminal states. - Hard-coded legal terminal states today are exactly: - `waiting_user` - `blocked` - `pending_verification` - Current failure output is: - `ok: false` - `status: 'continuity_failure'` - `verdict: 'continuity_failure'` - `reason: 'missing_dispatch_receipt'` - Current pass output is: - `ok: true` - `status: 'pass'` - `verdict: 'pass'` - Always stamps `gate: 'approved_plan_continuity'` in the response envelope. - Current receipt validation inside the gate is intentionally narrow: it only requires `planId`, `currentTask`, object-shaped `nextDerivedAction`, and `dispatchedAt` to treat `dispatchReceipt` as valid. - `scripts/approved_plan_dispatch_binding.mjs` - Reads JSON input from `--input ` and optional `--receipt-dir` override. - Default receipt dir is `state/approved-plan-continuity` resolved from `process.cwd()`. - Builds a receipt from: - `planId` - `currentTask` - `nextDerivedAction ?? derivedAction` - `dispatchedAt` - `dispatchRunId` - `childSessionKey` - `replyClosureState` - Validates presence of all seven fields above before writing. - Adds filesystem-safety checks by slugifying `planId` and `dispatchRunId`; missing/unsafe values are reported as `planId_filesystem_safe` / `dispatchRunId_filesystem_safe`. - On success writes `receipt--.json` under the receipt dir and returns: - `ok: true` - `status: 'receipt_written'` - `binding: 'approved_plan_dispatch'` - `receiptPath` - `receipt` - On validation failure returns: - `ok: false` - `status: 'missing_required_receipt_fields'` - `binding: 'approved_plan_dispatch'` - `missing: string[]` - `receiptPath: null` - `hooks/force-recall/handler.ts` - Runs continuity as a hook-time adapter, not a pure module yet. - Continuity input is assembled by `buildApprovedPlanContinuityInput(wrapperResult, autoChainPlanResult)`. - Hook mapping behavior today: - source next action = `wrapperResult.nextDerivedAction ?? wrapperResult.derivedAction ?? plannerDerivedAction` - `plannerDerivedAction` is synthesized from auto-chain planner output when `derivedAction !== 'none'` - if no next action exists, continuity gate is skipped (`null`) - `replyClosureState` defaults to: - `wrapperResult.replyClosureState`, else - `'waiting_user'` when `wrapperResult.handoff?.mode === 'button_path'`, else - `'completed'` - `dispatchReceipt` is passed through from `wrapperResult.dispatchReceipt ?? null` - `taskState` defaults to `wrapperResult.taskState ?? (plannerDerivedAction ? 'complete' : null)` - The hook executes `scripts/approved_plan_continuity_gate.mjs` via JSON-script indirection, then renders a prompt block. #### Minimal receipt contract baseline - Receipt fields documented/runbook + dispatch binding currently agree on the following MVP minimum shape: - `planId` - `currentTask` - `nextDerivedAction` - `dispatchedAt` - `dispatchRunId` - `childSessionKey` - `replyClosureState` - Important parity note: the gate currently enforces only a smaller subset for pass/fail (`planId`, `currentTask`, object `nextDerivedAction`, `dispatchedAt`), while dispatch binding enforces the full seven-field receipt contract before persisting. - Extraction must preserve this mismatch unless explicitly changed in a later task. #### Receipt filename / storage convention baseline - Receipt directory default: `state/approved-plan-continuity` - Receipt filename pattern: `receipt--.json` - Safe segments are produced by lowercasing, trimming, replacing non `[a-z0-9._-]` runs with `-`, trimming edge dashes, and collapsing repeated dashes. #### Hook block shape baseline - The continuity block currently injected by `hooks/force-recall/handler.ts` is: ```text [APPROVED_PLAN_CONTINUITY_GATE] status= verdict= reason= - HARD_GATE: Do not close out this reply as normal completion. - HARD_GATE: Route back to continuity failure until a real next dispatch receipt exists, unless closure state is waiting_user, blocked, or pending_verification. [/APPROVED_PLAN_CONTINUITY_GATE] ``` - `reason=` is only included when present. - The two `HARD_GATE` lines are only added when `result.ok === false`. - The block is omitted entirely when no continuity input can be constructed. #### Current input / output envelopes - Continuity gate script envelope: - input: JSON file path via `--input`; optional `--compact` - output keys: `ok`, `status`, `verdict`, `reason?`, `gate`, `compact`, `inputPath`, `input` - Dispatch binding script envelope: - input: JSON file path via `--input`; optional `--receipt-dir`; optional `--compact` - output keys on success: `ok`, `status`, `binding`, `compact`, `inputPath`, `receipt`, `receiptPath`, `input` - output keys on failure: same envelope plus `missing`, with `receiptPath: null` #### Test coverage baseline already present - `scripts/test_approved_plan_continuity_gate.mjs` covers: - JSON envelope skeleton / gate label - fail when `taskState=complete` + known next action + no valid dispatch receipt + non-legal closure - fail when planner uses `derivedAction` without bound receipt - fail when `dispatchReceipt` is fake non-null object without minimum fields - pass when valid dispatch receipt exists - pass when `derivedAction` has bound dispatch receipt - pass for legal closure states `waiting_user`, `blocked`, `pending_verification` - `scripts/test_force_recall_long_task_preflight.mjs` covers continuity integration in hook preflight: - continuity block is emitted in pass-path plumbing - dry-run auto-chain dispatch alone still yields `status=continuity_failure` - hook block must surface `verdict=continuity_failure` and `reason=missing_dispatch_receipt` - hook guidance must route back to continuity failure until a real receipt exists #### Known limitations / extraction constraints - Continuity rules are hard-coded in scripts and hook glue; there is no plugin config surface yet. - Hook integration shells out through script execution instead of importing a shared evaluator. - Receipt validation logic is split: - gate pass/fail uses a smaller inline validator - receipt persistence uses a fuller required-field validator - Current gate treats any object-shaped `nextDerivedAction` as sufficient inside a receipt; action schema is not validated further. - Current gate does not read receipts from disk by convention; it only validates the in-memory `dispatchReceipt` payload passed into it. - Hook-generated `plannerDerivedAction` is dry-run planner intent, not proof of real dispatch; continuity intentionally still fails until a real receipt is attached. ### Task 2: Create plugin package skeleton **Files:** - Create: `plugins/continuity/package.json` - Create: `plugins/continuity/README.md` - Create: `plugins/continuity/README.zh-TW.md` - Create: `plugins/continuity/HOOK.md` - Create: `plugins/continuity/src/index.mjs` **Step 1: Create the directory tree only** Run: ```bash mkdir -p plugins/continuity/src plugins/continuity/src/config plugins/continuity/src/continuity plugins/continuity/src/adapters plugins/continuity/examples plugins/continuity/test ``` Expected: directories exist **Step 2: Add minimal package metadata and placeholder entrypoint** - `package.json` should declare the plugin name, version, ESM type, and test script. - `src/index.mjs` should export placeholders for: - config schema/defaults - evaluator - receipt validator - hook adapter factory **Step 3: Verify files exist** Run: ```bash test -f plugins/continuity/package.json \ && test -f plugins/continuity/src/index.mjs \ && test -f plugins/continuity/README.md \ && test -f plugins/continuity/README.zh-TW.md \ && echo OK ``` Expected: `OK` **Step 4: Commit** ```bash git add plugins/continuity git commit -m "chore: add continuity plugin package skeleton" ``` ### Task 3: Define plugin config schema contract **Files:** - Create: `plugins/continuity/src/config/schema.mjs` - Create: `plugins/continuity/src/config/defaults.mjs` - Create: `plugins/continuity/examples/openclaw.continuity.example.json` - Modify: `plugins/continuity/README.md` - Modify: `plugins/continuity/README.zh-TW.md` **Step 1: Write the config keys before implementation code** Define exact keys for MVP, for example: - `enabled` - `planMatchers` - `legalTerminalStates` - `receiptDir` - `requireRealDispatchReceipt` - `allowReplyClosureWithoutDispatch` - `debug` - `adapter.forceRecall.enabled` - `adapter.forceRecall.injectBlockLabel` **Step 2: Add schema/default exports** - `schema.mjs` should export the allowed key list, required types, and validation helper contract. - `defaults.mjs` should export a concrete defaults object aligned with today’s behavior. **Step 3: Add example config** - Put a fully populated example JSON under `plugins/continuity/examples/openclaw.continuity.example.json`. **Step 4: Verify example config matches schema keys** Run: ```bash node -e "import('./plugins/continuity/src/config/defaults.mjs').then(m=>console.log(Object.keys(m.defaultConfig||m.defaults||{})))" ``` Expected: prints the default key list without runtime error **Step 5: Commit** ```bash git add plugins/continuity/src/config plugins/continuity/examples/openclaw.continuity.example.json plugins/continuity/README.md plugins/continuity/README.zh-TW.md git commit -m "feat: define continuity plugin config schema and defaults" ``` ### Task 4: Write failing tests for config validation **Files:** - Create: `plugins/continuity/test/continuity.config.test.mjs` - Test: `plugins/continuity/src/config/schema.mjs` **Step 1: Write fail-first tests for valid config** Cover: - accepts default config - accepts custom receipt directory - accepts custom legal terminal states list **Step 2: Write fail-first tests for invalid config** Cover: - rejects non-array `legalTerminalStates` - rejects empty `receiptDir` - rejects unknown terminal state type entries - rejects disabled adapter object shape if malformed **Step 3: Run tests to verify failure** Run: ```bash node plugins/continuity/test/continuity.config.test.mjs ``` Expected: FAIL because validator behavior is not fully implemented yet **Step 4: Commit** ```bash git add plugins/continuity/test/continuity.config.test.mjs git commit -m "test: add fail-first continuity plugin config validation tests" ``` ### Task 5: Implement minimal config validator **Files:** - Modify: `plugins/continuity/src/config/schema.mjs` - Modify: `plugins/continuity/src/config/defaults.mjs` - Modify: `plugins/continuity/test/continuity.config.test.mjs` **Step 1: Implement the smallest validator that passes the tests** - Normalize missing fields from defaults. - Reject malformed fields with explicit error codes/messages. - Preserve current terminal states: `waiting_user`, `blocked`, `pending_verification`. **Step 2: Run tests** Run: ```bash node plugins/continuity/test/continuity.config.test.mjs ``` Expected: PASS **Step 3: Commit** ```bash git add plugins/continuity/src/config/schema.mjs plugins/continuity/src/config/defaults.mjs plugins/continuity/test/continuity.config.test.mjs git commit -m "feat: validate continuity plugin config" ``` ### Task 6: Extract receipt validator contract **Files:** - Create: `plugins/continuity/src/continuity/receipt-validator.mjs` - Create: `plugins/continuity/src/continuity/types.md` - Modify: `plugins/continuity/README.md` - Modify: `plugins/continuity/README.zh-TW.md` **Step 1: Document the receipt shape in one place** Define these fields as the MVP minimum: - `planId` - `currentTask` - `nextDerivedAction` - `dispatchedAt` - `dispatchRunId` - `childSessionKey` - `replyClosureState` **Step 2: Export validator API shape** - `validateReceipt(receipt)` returns `{ ok, errors, normalizedReceipt }` - `isValidReceipt(receipt)` returns boolean **Step 3: Verify file exists and exports load** Run: ```bash node -e "import('./plugins/continuity/src/continuity/receipt-validator.mjs').then(m=>console.log(Object.keys(m).sort().join(',')))" ``` Expected: export list includes validator functions **Step 4: Commit** ```bash git add plugins/continuity/src/continuity/receipt-validator.mjs plugins/continuity/src/continuity/types.md plugins/continuity/README.md plugins/continuity/README.zh-TW.md git commit -m "chore: define continuity receipt validator contract" ``` ### Task 7: Write failing tests for receipt validator **Files:** - Create: `plugins/continuity/test/continuity.receipt-validator.test.mjs` - Test: `plugins/continuity/src/continuity/receipt-validator.mjs` **Step 1: Write success-path tests** Cover: - valid receipt with all minimum fields passes - filesystem-safe IDs are accepted **Step 2: Write failure-path tests** Cover: - missing `planId` - missing `dispatchRunId` - non-object `nextDerivedAction` - empty `childSessionKey` - fake non-null receipt object fails **Step 3: Run tests to verify failure** Run: ```bash node plugins/continuity/test/continuity.receipt-validator.test.mjs ``` Expected: FAIL **Step 4: Commit** ```bash git add plugins/continuity/test/continuity.receipt-validator.test.mjs git commit -m "test: add fail-first continuity receipt validator tests" ``` ### Task 8: Implement receipt validator **Files:** - Modify: `plugins/continuity/src/continuity/receipt-validator.mjs` - Modify: `plugins/continuity/test/continuity.receipt-validator.test.mjs` **Step 1: Implement field validation and normalization** - Reuse current minimum field expectations from `scripts/approved_plan_dispatch_binding.mjs` and `scripts/approved_plan_continuity_gate.mjs`. - Keep validation separate from file I/O. **Step 2: Run tests** Run: ```bash node plugins/continuity/test/continuity.receipt-validator.test.mjs ``` Expected: PASS **Step 3: Commit** ```bash git add plugins/continuity/src/continuity/receipt-validator.mjs plugins/continuity/test/continuity.receipt-validator.test.mjs git commit -m "feat: implement continuity receipt validator" ``` ### Task 9: Extract receipt store helper **Files:** - Create: `plugins/continuity/src/continuity/receipt-store.mjs` - Modify: `plugins/continuity/examples/approved-plan-receipt.example.json` - Modify: `plugins/continuity/README.md` - Modify: `plugins/continuity/README.zh-TW.md` **Step 1: Create the example receipt JSON** - Add a real-looking valid receipt example matching the documented minimum shape. **Step 2: Implement file naming helpers only** Export small functions for: - slugifying `planId` - slugifying `dispatchRunId` - building `receipt--.json` - resolving the receipt path from config **Step 3: Verify helper exports load** Run: ```bash node -e "import('./plugins/continuity/src/continuity/receipt-store.mjs').then(m=>console.log(Object.keys(m).sort().join(',')))" ``` Expected: helper export names print successfully **Step 4: Commit** ```bash git add plugins/continuity/src/continuity/receipt-store.mjs plugins/continuity/examples/approved-plan-receipt.example.json plugins/continuity/README.md plugins/continuity/README.zh-TW.md git commit -m "chore: add continuity receipt store helpers and examples" ``` ### Task 10: Write failing tests for receipt store behavior **Files:** - Create: `plugins/continuity/test/continuity.receipt-store.test.mjs` - Test: `plugins/continuity/src/continuity/receipt-store.mjs` **Step 1: Write tests for path generation** Cover: - builds correct filename from safe IDs - normalizes unsafe characters - resolves receipt path inside configured receipt dir **Step 2: Write tests for write/read round-trip** Cover: - writes validated receipt JSON - reads back same logical payload - rejects invalid receipt before write **Step 3: Run tests to verify failure** Run: ```bash node plugins/continuity/test/continuity.receipt-store.test.mjs ``` Expected: FAIL until read/write helpers exist **Step 4: Commit** ```bash git add plugins/continuity/test/continuity.receipt-store.test.mjs git commit -m "test: add fail-first continuity receipt store tests" ``` ### Task 11: Implement receipt store helpers **Files:** - Modify: `plugins/continuity/src/continuity/receipt-store.mjs` - Modify: `plugins/continuity/test/continuity.receipt-store.test.mjs` **Step 1: Implement the minimum store API** Export functions for: - `buildReceiptFilename` - `resolveReceiptPath` - `writeReceipt` - `readReceipt` **Step 2: Run tests** Run: ```bash node plugins/continuity/test/continuity.receipt-store.test.mjs ``` Expected: PASS **Step 3: Commit** ```bash git add plugins/continuity/src/continuity/receipt-store.mjs plugins/continuity/test/continuity.receipt-store.test.mjs git commit -m "feat: implement continuity receipt store helpers" ``` ### Task 12: Extract continuity evaluator contract **Files:** - Create: `plugins/continuity/src/continuity/evaluator.mjs` - Modify: `plugins/continuity/src/index.mjs` - Modify: `plugins/continuity/README.md` - Modify: `plugins/continuity/README.zh-TW.md` **Step 1: Define evaluator input/output shape** Input should support: - `taskState` - `nextDerivedAction` - `derivedAction` - `replyClosureState` - `dispatchReceipt` - config override for legal terminal states Output should support: - `ok` - `status` - `verdict` - `reason` - `gate` **Step 2: Stub the evaluator exports** - `evaluateContinuity(payload, config)` - `buildContinuityGateBlock(result, config)` **Step 3: Verify exports load** Run: ```bash node -e "import('./plugins/continuity/src/continuity/evaluator.mjs').then(m=>console.log(Object.keys(m).sort().join(',')))" ``` Expected: export list prints successfully **Step 4: Commit** ```bash git add plugins/continuity/src/continuity/evaluator.mjs plugins/continuity/src/index.mjs plugins/continuity/README.md plugins/continuity/README.zh-TW.md git commit -m "chore: define continuity evaluator contract" ``` ### Task 13: Write failing tests for continuity evaluator parity **Files:** - Create: `plugins/continuity/test/continuity.evaluator.test.mjs` - Test: `plugins/continuity/src/continuity/evaluator.mjs` - Reference: `scripts/test_approved_plan_continuity_gate.mjs` **Step 1: Port the current continuity gate cases into plugin tests** Cover at least: - fail when task complete + next action known + no dispatch receipt + closure not legal - fail when planner returns `derivedAction` without bound dispatch receipt - fail when fake non-null receipt object is supplied - pass when valid dispatch receipt exists - pass when closure is `waiting_user` - pass when closure is `blocked` - pass when closure is `pending_verification` **Step 2: Add one plugin-specific config override case** - custom legal terminal states list works **Step 3: Run tests to verify failure** Run: ```bash node plugins/continuity/test/continuity.evaluator.test.mjs ``` Expected: FAIL **Step 4: Commit** ```bash git add plugins/continuity/test/continuity.evaluator.test.mjs git commit -m "test: add fail-first continuity evaluator parity tests" ``` ### Task 14: Implement continuity evaluator **Files:** - Modify: `plugins/continuity/src/continuity/evaluator.mjs` - Modify: `plugins/continuity/src/continuity/receipt-validator.mjs` - Modify: `plugins/continuity/test/continuity.evaluator.test.mjs` **Step 1: Implement the smallest evaluator that matches current behavior** - Reuse receipt validator instead of inline checks. - Preserve current failure reason: `missing_dispatch_receipt`. - Preserve current legal closure state behavior. **Step 2: Run tests** Run: ```bash node plugins/continuity/test/continuity.evaluator.test.mjs ``` Expected: PASS **Step 3: Commit** ```bash git add plugins/continuity/src/continuity/evaluator.mjs plugins/continuity/src/continuity/receipt-validator.mjs plugins/continuity/test/continuity.evaluator.test.mjs git commit -m "feat: implement continuity evaluator" ``` ### Task 15: Add script bridge for backward compatibility **Files:** - Create: `plugins/continuity/src/adapters/script-bridge.mjs` - Modify: `scripts/approved_plan_continuity_gate.mjs` - Modify: `scripts/approved_plan_dispatch_binding.mjs` **Step 1: Write failing bridge tests first** - The old scripts should still produce compatible JSON envelopes by delegating to plugin modules. **Step 2: Implement thin bridge wiring** - Keep CLI parsing in scripts if easiest. - Move decision logic to plugin modules. **Step 3: Run existing script tests** Run: ```bash node scripts/test_approved_plan_continuity_gate.mjs ``` Expected: PASS with plugin-backed logic **Step 4: Commit** ```bash git add plugins/continuity/src/adapters/script-bridge.mjs scripts/approved_plan_continuity_gate.mjs scripts/approved_plan_dispatch_binding.mjs git commit -m "refactor: bridge legacy continuity scripts to plugin modules" ``` ### Task 16: Extract hook adapter contract **Files:** - Create: `plugins/continuity/src/adapters/force-recall.mjs` - Modify: `plugins/continuity/HOOK.md` - Modify: `plugins/continuity/src/index.mjs` **Step 1: Define hook adapter responsibilities** The adapter should: - accept hook context and plugin config - build continuity input from hook state - call the evaluator - return a prompt block or structured gate result - avoid duplicating evaluator rules **Step 2: Stub the factory export** Export something like: - `createForceRecallContinuityAdapter(config)` - `runForceRecallContinuityAdapter(ctx, config)` **Step 3: Verify exports load** Run: ```bash node -e "import('./plugins/continuity/src/adapters/force-recall.mjs').then(m=>console.log(Object.keys(m).sort().join(',')))" ``` Expected: export names print successfully **Step 4: Commit** ```bash git add plugins/continuity/src/adapters/force-recall.mjs plugins/continuity/HOOK.md plugins/continuity/src/index.mjs git commit -m "chore: define force-recall continuity adapter contract" ``` ### Task 17: Write failing tests for hook adapter **Files:** - Create: `plugins/continuity/test/continuity.plugin.test.mjs` - Test: `plugins/continuity/src/adapters/force-recall.mjs` - Reference: `hooks/force-recall/handler.ts` **Step 1: Write success-path adapter tests** Cover: - returns no block when no approved-plan continuity context exists - returns pass block when receipt is valid **Step 2: Write fail-path adapter tests** Cover: - returns hard-gate block when continuity fails - includes expected gate label and reason - honors config override for block label/debug mode **Step 3: Run tests to verify failure** Run: ```bash node plugins/continuity/test/continuity.plugin.test.mjs ``` Expected: FAIL **Step 4: Commit** ```bash git add plugins/continuity/test/continuity.plugin.test.mjs git commit -m "test: add fail-first continuity hook adapter tests" ``` ### Task 18: Implement hook adapter **Files:** - Modify: `plugins/continuity/src/adapters/force-recall.mjs` - Modify: `plugins/continuity/src/continuity/evaluator.mjs` - Modify: `plugins/continuity/test/continuity.plugin.test.mjs` **Step 1: Implement adapter logic with minimal hook assumptions** - Build gate input from hook payload. - Delegate decisions to evaluator. - Build the hard-gate block string in one place. **Step 2: Run tests** Run: ```bash node plugins/continuity/test/continuity.plugin.test.mjs ``` Expected: PASS **Step 3: Commit** ```bash git add plugins/continuity/src/adapters/force-recall.mjs plugins/continuity/src/continuity/evaluator.mjs plugins/continuity/test/continuity.plugin.test.mjs git commit -m "feat: implement continuity force-recall adapter" ``` ### Task 19: Wire `force-recall` hook to the plugin adapter **Files:** - Modify: `hooks/force-recall/handler.ts` - Test: `scripts/test_force_recall_long_task_preflight.mjs` - Reference: `plugins/continuity/src/adapters/force-recall.mjs` **Step 1: Write the smallest integration change** - Replace inline continuity-specific logic in `handler.ts` with plugin adapter invocation. - Keep unrelated long-task governor behavior unchanged. **Step 2: Run targeted verification** Run: ```bash node scripts/test_approved_plan_continuity_gate.mjs node scripts/test_force_recall_long_task_preflight.mjs node --check hooks/force-recall/handler.ts ``` Expected: PASS **Step 3: Commit** ```bash git add hooks/force-recall/handler.ts git commit -m "refactor: route force-recall continuity gate through plugin adapter" ``` ### Task 20: Add plugin-level smoke test **Files:** - Create: `plugins/continuity/test/continuity.smoke.test.mjs` - Modify: `plugins/continuity/package.json` - Modify: `plugins/continuity/examples/openclaw.continuity.example.json` **Step 1: Write a smoke test that exercises the public plugin path** Smoke path should: - load config - validate config - validate receipt - evaluate a failing continuity payload - evaluate a passing payload with valid receipt **Step 2: Run the smoke test** Run: ```bash node plugins/continuity/test/continuity.smoke.test.mjs ``` Expected: PASS **Step 3: Expose a package script** Add package script, for example: ```json { "scripts": { "test": "node test/continuity.config.test.mjs && node test/continuity.receipt-validator.test.mjs && node test/continuity.receipt-store.test.mjs && node test/continuity.evaluator.test.mjs && node test/continuity.plugin.test.mjs && node test/continuity.smoke.test.mjs" } } ``` **Step 4: Verify package test command** Run: ```bash cd plugins/continuity && npm test ``` Expected: PASS **Step 5: Commit** ```bash git add plugins/continuity/package.json plugins/continuity/test/continuity.smoke.test.mjs plugins/continuity/examples/openclaw.continuity.example.json git commit -m "test: add continuity plugin smoke test and package test script" ``` ### Task 21: Write bilingual README installation/apply instructions **Files:** - Modify: `plugins/continuity/README.md` - Modify: `plugins/continuity/README.zh-TW.md` - Reference: `plugins/continuity/HOOK.md` - Reference: `plugins/continuity/examples/openclaw.continuity.example.json` **Step 1: Add English README sections** Include: - what problem the plugin solves - MVP scope/non-goals - install location and package layout - config reference table/list - example config snippet - receipt format summary - hook adapter usage - smoke test command - migration note from hard-coded scripts **Step 2: Add Traditional Chinese README sections with parity** Include the same sections as the English README. **Step 3: Verify both READMEs mention the same critical commands** Run: ```bash rg -n "npm test|openclaw|receiptDir|waiting_user|pending_verification|blocked" plugins/continuity/README.md plugins/continuity/README.zh-TW.md ``` Expected: both files contain the same core operational terms **Step 4: Commit** ```bash git add plugins/continuity/README.md plugins/continuity/README.zh-TW.md plugins/continuity/HOOK.md git commit -m "docs: add bilingual continuity plugin installation and usage guides" ``` ### Task 22: Add example application note for root workspace config **Files:** - Modify: `plugins/continuity/README.md` - Modify: `plugins/continuity/README.zh-TW.md` - Optional Create: `docs/runbooks/continuity-plugin-apply.md` **Step 1: Document how to apply the plugin in a real OpenClaw workspace** Show a concrete example of: - where the plugin folder lives - how config points at `state/approved-plan-continuity` - how `force-recall` should load/use the adapter **Step 2: Add a do-not-do list** Explicitly warn against: - changing core continuity rules during extraction - using fake dispatch receipts for pass-through - removing current scripts before parity tests pass **Step 3: Verify paths are exact** Run: ```bash test -d plugins/continuity && test -d state/approved-plan-continuity && test -f hooks/force-recall/handler.ts && echo OK ``` Expected: `OK` **Step 4: Commit** ```bash git add plugins/continuity/README.md plugins/continuity/README.zh-TW.md docs/runbooks/continuity-plugin-apply.md git commit -m "docs: add continuity plugin apply guidance for workspace integration" ``` ### Task 23: Run full verification suite **Files:** - Test: `plugins/continuity/test/*.mjs` - Test: `scripts/test_approved_plan_continuity_gate.mjs` - Test: `scripts/test_force_recall_long_task_preflight.mjs` - Check: `hooks/force-recall/handler.ts` **Step 1: Run plugin package tests** Run: ```bash cd plugins/continuity && npm test ``` Expected: PASS **Step 2: Run compatibility tests from repo root** Run: ```bash node scripts/test_approved_plan_continuity_gate.mjs node scripts/test_force_recall_long_task_preflight.mjs node --check hooks/force-recall/handler.ts ``` Expected: PASS **Step 3: Record exact verification results in the plan tail or PR notes** - Copy exact commands - Copy PASS summary counts - Note any skipped tests **Step 4: Commit** ```bash git add plugins/continuity hooks/force-recall/handler.ts scripts/approved_plan_continuity_gate.mjs scripts/approved_plan_dispatch_binding.mjs docs/plans/2026-04-24-continuity-plugin-mvp.md git commit -m "chore: verify continuity plugin MVP end-to-end" ``` ### Task 24: Final acceptance checklist and handoff **Files:** - Modify: `docs/plans/2026-04-24-continuity-plugin-mvp.md` - Review: `plugins/continuity/README.md` - Review: `plugins/continuity/README.zh-TW.md` **Step 1: Add a checked acceptance checklist to the bottom of the plan** Include: - config schema implemented - evaluator extracted - receipt validator extracted - hook adapter wired - plugin-level tests passing - bilingual README complete - example config present - smoke test present - compatibility path preserved **Step 2: Mark remaining risks explicitly** List at least: - plugin loader assumptions may differ from current repo conventions - current repo lacks an existing continuity plugin precedent - future non-`force-recall` adapters are out of MVP scope **Step 3: Leave status as pending verification, not complete** - Follow the workspace rule that implementation is not “done” until verified by the owner flow. **Step 4: Commit** ```bash git add docs/plans/2026-04-24-continuity-plugin-mvp.md git commit -m "docs: finalize continuity plugin MVP implementation plan" ``` --- ## MVP Validation Checklist - [ ] `plugins/continuity/` package exists with entrypoint, docs, examples, and tests - [ ] Config schema/defaults exist and are test-covered - [ ] Receipt validator exists and is test-covered - [ ] Receipt store helpers exist and are test-covered - [ ] Continuity evaluator exists and matches current hard-gate behavior - [ ] Legacy scripts bridge to plugin logic or are otherwise compatibility-covered - [ ] `hooks/force-recall/handler.ts` consumes plugin adapter instead of continuity-specific inline logic - [ ] English README explains install/config/test/migration - [ ] Traditional Chinese README explains install/config/test/migration - [ ] Example config and example receipt are checked in - [ ] Smoke test passes - [ ] Existing continuity and force-recall tests still pass ## Risks / Open Questions 1. The repo currently has an empty `plugins/` directory, so actual OpenClaw plugin manifest/loading conventions may need one discovery slice before implementation. 2. `hooks/force-recall/handler.ts` currently mixes several long-task concerns; extracting only continuity logic must avoid accidental behavior drift in unrelated gate-lock/auto-chain code. 3. Current script tests cover continuity decisions but not yet the full plugin install path, so smoke coverage is mandatory for MVP credibility. 4. The bilingual README must stay behaviorally aligned with actual example config and commands; drift here would make the plugin “documented” but not really adoptable. Plan complete and saved to `docs/plans/2026-04-24-continuity-plugin-mvp.md`. Two execution options: **1. Subagent-Driven (this session)** - I dispatch fresh subagent per task, review between tasks, fast iteration **2. Parallel Session (separate)** - Open new session with executing-plans, batch execution with checkpoints **Which approach?** **If Subagent-Driven chosen:** - **REQUIRED SUB-SKILL:** Use superpowers:subagent-driven-development - Stay in this session - Fresh subagent per task + code review **If Parallel Session chosen:** - Guide them to open new session in worktree - **REQUIRED SUB-SKILL:** New session uses superpowers:executing-plans