Files
aios/docs/superpowers/plans/2026-07-12-weixin-quoted-text-failclosed.md
T

4.5 KiB

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.