# Weixin Quoted Text Fail-Closed Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Resolve explicit quoted text safely and fail closed without a model call when Weixin omits the quoted body. **Architecture:** Add pure JS/TS reference-text helpers and one process hook guard to the existing patcher. Keep the patch surface limited to generated `process-message.ts/js`; do not introduce a persistent cache or modify send/monitor/API modules. **Tech Stack:** Python patch generator, TypeScript/JavaScript, Node test harness, pytest. ## Global Constraints - Sub-agents use `gpt-5.3-codex-spark`. - No force push, tag, baseline promotion, credential persistence, recent-message fallback, or approximate text matching. - Existing confirmed image and ordinary text behavior must remain unchanged. --- ### Task 1: Add Quoted Text Resolver With TDD **Files:** - Modify: `tests/test_weixin_image_followup_intent.py` - Modify: `fixes/patch_openclaw_weixin_hermes.py` **Interfaces:** - Produces: `extractHermesReferencedText(items)` and `resolveHermesQuotedTextContext(items, currentText)` in TS and JS helper templates. - [ ] Add a Node-backed failing test with `ref_msg.message_item.type=1` and explicit `text_item.text="被引用的正文"`; assert `reason="quoted_text_resolved"`, `handled=false`, and a prompt containing only delimited quoted/current text. - [ ] Add a Node-backed failing test with `type=0`, quoted ID, no text, and no confirmed image; assert `reason="quoted_text_unavailable"`, `handled=true`, and exact deterministic `replyText`. - [ ] Run `pytest -q tests/test_weixin_image_followup_intent.py -k 'quoted_text'` and record expected RED because the resolver is absent. - [ ] Implement the smallest recursive explicit-text extractor. Accept only known referenced text fields; cap each extracted string at 4000 characters and reject blank values. - [ ] Implement the resolver in both TS and JS templates. Do not read session history, image latest cache, timestamps, or metadata values. - [ ] Re-run the focused tests and record GREEN. - [ ] Commit with `fix(weixin): fail closed on unavailable quoted text`. ### Task 2: Guard The Real Process Hook **Files:** - Modify: `tests/test_weixin_image_followup_intent.py` - Modify: `fixes/patch_openclaw_weixin_hermes.py` **Interfaces:** - Consumes: `resolveHermesQuotedTextContext(items, currentText)`. - Produces: process hook behavior that replies deterministically or replaces only the ordinary text prompt. - [ ] Add a failing JS hook test that stubs the ordinary model dispatch and reply function. For type 0 without text, assert reply called once and model called zero times. - [ ] Add a failing JS hook test for explicit quoted text. Assert model called once with delimited context and no message metadata. - [ ] Add regression assertions for plain text, current image, and exact quoted image. - [ ] Run focused tests and record RED for the missing guard. - [ ] Insert the resolver after reference/image evidence extraction and before ordinary model dispatch. Confirmed image references must bypass the text fail-closed branch. - [ ] Emit structured reason-only diagnostics without message bodies. - [ ] Run focused tests and record GREEN. - [ ] Commit with `fix(weixin): guard quoted text model dispatch`. ### Task 3: Idempotence, Review, And Release **Files:** - Modify: `docs/incidents/WEIXIN_TEXT_IMAGE_CACHE_ISOLATION_20260711.md` - [ ] Run `pytest -q tests/test_weixin_image_followup_intent.py` and require all tests pass. - [ ] Run `python3 -m py_compile fixes/patch_openclaw_weixin_hermes.py tests/test_weixin_image_followup_intent.py`. - [ ] Run `git diff --check`. - [ ] Apply `--process-only` twice to a scratch production-plugin copy and require identical second-run hashes; require slash/channel files unchanged. - [ ] Obtain independent spec and code review. - [ ] Update the incident document with RED/GREEN evidence, main revision, production hashes, rollback directory, and owner live acceptance state. - [ ] Merge by non-force fast-forward from a clean main-based branch, deploy only the two generated process-message files, restart only `openclaw-gateway.service`, and verify service, port 18789, four accounts, zero post-start errors, and unchanged image cache. - [ ] Owner live acceptance: quote a type 0 text message and verify deterministic no-body response; quote a payload that includes explicit text and verify grounded explanation.