fix: preserve WeChat attachment task context

This commit is contained in:
inman committed 2026-08-30 15:41:55 +08:00
1 parent e7aa58a203
commit 2360506607
5 files changed
+219 -17

No files matched your search

@@ -0,0 +1,69 @@
# Task: Fix WeChat attachment task correlation
## Identity
- Task ID: 20260830-wechat-attachment-correlation-9f3a2c
- Mode: Feature
- Branch: codex/20260830-wechat-attachment-correlation-9f3a2c-wechat-attachment-correlation
- Worktree: /Users/inmanx/Documents/lwltAPI-worktrees/20260830-wechat-attachment-correlation-9f3a2c
- Base commit: e7aa58a203f9c05850a3d10e681b8800b856ee12
- Owner: codex
- Status: Ready for Integration
## Scope
- Diagnose the deployed WeChat/AgentBus roster-attachment failure shown at 2026-08-30 15:19.
- Keep an attachment-only WeChat message from entering the ordinary new-task path when the bridge supplied only its text placeholder.
- Use the exact WeChat envelope `Conversation:` value for task correlation when no explicit AgentBus conversation field is present.
- Return safe, actionable attachment-ingress errors instead of collapsing metadata, URL, DNS, download, size, or digest failures into the generic task-processing message.
- Add focused regression coverage and update the active AgentBus transport documentation.
## Intent And Constraints
- Preserve the existing Program-only roster workflow: one `.xls/.xlsx` attachment must become `payload.attachments[]` with a bounded public HTTPS URL before it can resume an `awaiting_attachment` task.
- Do not weaken HTTPS, credential, redirect, DNS, private/reserved-network, size, or SHA-256 checks; absent file bytes must fail closed and leave the original task waiting.
- Do not change parser, operation, Schema, mapping, ERP, Chrome-extension, or release-artifact behavior.
- Do not read local secrets, deploy, restart services, mutate live tasks, access ERP, or send external messages.
- Treat the screenshots as evidence only. The raw production frame and server error code are unavailable, so distinguish the two supported failure branches in logs and user replies instead of asserting one without evidence.
## Plan
1. Add strict parsing for the observed WeChat transport envelope, including its conversation identifier and attachment-only placeholder.
2. Reject placeholder-only attachment messages before `TaskService.ingestMessage`, and surface the safe `InputAttachmentError` reason and code.
3. Add listener tests proving conversation correlation, no accidental task creation, actionable failure text, and unchanged strict-envelope behavior.
4. Update the AgentBus contract/readme, then run targeted and full repository verification.
## Outcome
- Confirmed the failure had two distinct ingress problems before task selection: the strict WeChat transport envelope exposed a `Conversation:` value that was not promoted to the AgentBus frame's conversation key, while an attachment card could arrive as placeholder text without the required `payload.attachments[]` file metadata.
- Added strict envelope parsing that preserves explicit AgentBus `conversation_id` precedence and otherwise uses the observed WeChat `Conversation:` value. A real structured attachment can therefore select the unique `awaiting_attachment` task in the same channel and conversation through the existing `TaskService` path.
- Added a fail-closed guard for `[WeChat attachment: ...]` placeholder-only frames. They now stop before `TaskService.ingestMessage`, do not create a second business task, leave the original roster task waiting, and return an actionable safe message that the file content never reached the platform.
- Preserved all existing attachment download controls. Pre-ingest `InputAttachmentError` failures now return their predefined safe summary and log a bounded error code instead of being collapsed into the generic task-processing failure; URLs, file bytes, and roster values remain absent from replies and logs.
- Updated the active AgentBus transport contract and control-plane README. No parser, Schema, mapping, ERP, Chrome-extension, release artifact, deployment, service process, live task, or external system was changed.
## Verification
- Focused AgentBus listener regression: 14/14 passed, including envelope conversation precedence, placeholder-only fail-closed behavior, zero task-ingestion calls, bounded error logging, and listener teardown.
- `node --run check:repo`: 9/9 passed.
- `node --run check`: passed.
- `node --run test:control-plane`: 128/128 passed.
- `node --run test:legacy`: 248/248 passed.
- `node --run build`: passed.
- `check_project_docs.py`: passed.
- `check_doc_drift.py --task-id 20260830-wechat-attachment-correlation-9f3a2c`: passed.
- `git diff --check`: passed.
## Follow-ups
- The external WeChat bridge must deliver each workbook as one real `payload.attachments[]` entry with the documented name, size/type/hash metadata and a control-plane-reachable public HTTPS URL. Placeholder text alone cannot supply file bytes and is intentionally not converted into an attachment.
- The raw 2026-08-30 production frame and its original server-side exception were not available. After this branch is integrated and deployed under separate authorization, observe the bounded `error_code` to distinguish missing metadata from URL, DNS, download, size, or digest failure without inspecting sensitive payloads.
- Integration, deployment, restart, and a live WeChat retry remain separate authorized actions; this Feature task performs none of them.
## Promotion Candidates
- Target: `.project-docs/20-architecture/data-flow.md` and `.project-docs/40-domain/business-rules.md`.
Proposal: record that a strict WeChat envelope may supply the AgentBus conversation fallback, but a roster attachment exists only when the frame carries a validated `payload.attachments[]` entry; placeholder text must never create a new task and must leave the prior roster task awaiting its file.
Evidence: `control-plane/src/agentbus.ts`, `control-plane/test/agentbus.test.ts`, `control-plane/README.md`, and `agent设计规范/agentbus-reply-contract.md` on this task branch; focused 14/14, control-plane 128/128, and legacy 248/248 tests passed.
Future impact: future bridge or channel adapters must preserve stable conversation identity and send file metadata/URL separately from user-visible attachment placeholder text; operational diagnosis should use bounded attachment error codes rather than payload logging.
Semantic conflicts: none found in active contracts; the proposal makes the existing structured-attachment requirement and task-correlation boundary explicit.
Human confirmation: not required for the rule itself because it preserves the existing fail-closed attachment contract, but Integration mode is required before writing canonical project memory.