docs(phase-06): record 06-06 execution and reverification

This commit is contained in:
肖应宇 2026-04-15 15:43:51 +08:00
parent 3d472761c8
commit ac01d08eb5
3 changed files with 145 additions and 44 deletions

View File

@ -2,12 +2,12 @@
gsd_state_version: 1.0
milestone: v1.0
milestone_name: milestone
status: v1.0 milestone complete
last_updated: "2026-04-15T05:27:38.358Z"
status: Executing Phase 06
last_updated: "2026-04-15T07:35:15.855Z"
progress:
total_phases: 6
completed_phases: 6
total_plans: 10
total_plans: 11
completed_plans: 13
percent: 100
---
@ -19,7 +19,7 @@ progress:
See: .planning/PROJECT.md (updated 2026-04-07)
**Core value:** Keep the frontend visually familiar while preserving and hardening new-system behavior end to end.
**Current focus:** Phase 06 — phase-06
**Current focus:** Phase 06 — 06
## Workflow State

View File

@ -0,0 +1,56 @@
---
phase: 06-
plan: 06
subsystem: backend-middleware
tags: [uploads, mentions, context, gap-closure]
requires:
- phase: 06-05
provides: UAT gap diagnosis and closure plan
provides:
- 过滤 ref_kind=mention避免被识别为本次上传
- UploadsMiddleware 新增 mention 过滤回归测试
affects: [06-UAT, uploads-middleware, thread-context]
tech-stack:
added: []
patterns: [metadata-discriminator, middleware-guard-rail]
key-files:
created:
- .planning/phases/06-/06-06-SUMMARY.md
modified:
- backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py
- backend/tests/test_uploads_middleware_core_logic.py
key-decisions:
- "后端以 ref_kind=mention 作为强判定,明确将 mention 引用排除出 new_files。"
- "保留原有 filename/path/sync 行为,只做最小补丁以降低回归风险。"
requirements-completed: [ATREF-04]
duration: 12min
completed: 2026-04-15
---
# Phase 06 Plan 06: Mention/Upload Misclassification Fix Summary
修复了“提及文件被误判为本次上传文件”的核心问题:`additional_kwargs.files` 中 `ref_kind=mention` 条目现在不会进入 UploadsMiddleware 的 `new_files`
## Accomplishments
- 在 `UploadsMiddleware._files_from_kwargs` 增加判定:`ref_kind == "mention"` 直接跳过。
- 新增两条回归测试:
- 纯 mention 条目应被完全过滤;
- mixed list 中真实 upload 保留、mention 过滤。
## Files Created/Modified
- `.planning/phases/06-/06-06-SUMMARY.md`
- `backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py`
- `backend/tests/test_uploads_middleware_core_logic.py`
## Verification
- 尝试执行:`cd backend && pytest -q tests/test_uploads_middleware_core_logic.py -k "mention or files_from_kwargs"`
- 环境结果:`pytest` 不可用(`python3 -m pytest` 报 `No module named pytest`
## Self-Check: PASSED (code) / PARTIAL (runtime)
- FOUND: mention 过滤逻辑已在 middleware 生效
- FOUND: 单测覆盖已补齐
- BLOCKED: 当前环境缺少 pytest未能本地运行后端测试

View File

@ -1,18 +1,45 @@
---
phase: 06-
verified: 2026-04-15T05:24:24Z
status: verified
score: 8/8 must-haves verified
verified: 2026-04-15T07:42:05Z
status: gaps_found
score: 8/10 must-haves verified
overrides_applied: 0
gaps: []
re_verification:
previous_status: verified
previous_score: 8/8
gaps_closed:
- "提及文件ref_kind=mention发送时不再被识别为本次新上传文件。"
gaps_remaining:
- "Validation/UAT/Requirements 文档闭环未完成,状态与当前实现不一致。"
regressions: []
gaps:
- truth: "Validation 文档的 Wave 0 缺口被关闭或显式替换为可执行命令。"
status: failed
reason: "06-VALIDATION.md 仍包含 pending/未签核项,未体现 06-05/06-06 后的最新验证结果。"
artifacts:
- path: ".planning/phases/06-/06-VALIDATION.md"
issue: "Per-Task 状态仍有 ⚠️/⬜ pendingValidation Sign-Off 全部未勾选Approval 仍为 pending。"
missing:
- "回写 06-05/06-06 最新自动化结果并完成 Validation Sign-Off。"
- truth: "must_haves、requirements-completed、UAT gaps 已形成一致闭环。"
status: failed
reason: "实现已前进,但 UAT/REQUIREMENTS 追踪状态仍停留在 diagnosed/pending文档闭环不一致。"
artifacts:
- path: ".planning/phases/06-/06-UAT.md"
issue: "status 仍为 diagnosed且仍记录“mention 被当作 upload”为 failed。"
- path: ".planning/REQUIREMENTS.md"
issue: "ATREF-01..04 在需求与 Traceability 表中仍为 Pending。"
missing:
- "按当前代码与测试结果更新 06-UAT.md 的 test/gap 状态。"
- "回写 REQUIREMENTS.md 中 ATREF-01..04 的状态(至少 Traceability。"
---
# Phase 6: 在输入框输入@时,可引用已生成文件和已上传附件 Verification Report
**Phase Goal:** 在当前线程聊天输入框中实现 `@` 文件引用artifacts + uploads并通过 `additional_kwargs.files` 稳定提交且具备回归测试。
**Verified:** 2026-04-15T05:24:24Z
**Status:** verified
**Re-verification:** Yes — after 06-05 gap closure
**Verified:** 2026-04-15T07:42:05Z
**Status:** gaps_found
**Re-verification:** Yes — after 06-06 gap closure
## Goal Achievement
@ -20,56 +47,65 @@ gaps: []
| # | Truth | Status | Evidence |
| --- | --- | --- | --- |
| 1 | 输入 `@` 时仅展示当前线程候选并支持连续过滤ATREF-01 | ✓ VERIFIED | `input-box.tsx` 基于 `thread.values.artifacts` + `useUploadedFiles(threadId)` 聚合候选,`findMentionToken` + `mentionQuery` 做过滤。 |
| 2 | 选中后展示可删除 chip而非纯文本 | ✓ VERIFIED | `input-box.tsx` 渲染 `reference-chip`,并支持按钮删除与空输入 `Backspace` 删除最后一项。 |
| 3 | 同名场景显示“文件名+类型+路径尾段”,且上限 10ATREF-02 | ✓ VERIFIED | `MAX_REFERENCES_PER_MESSAGE = 10`;候选与预览均显示 `filename + typeLabel + pathTail`;超过上限提示“单条消息最多引用 10 个文件”。 |
| 4 | 引用通过 `additional_kwargs.files` 提交,不新增并行主结构 | ✓ VERIFIED | `hooks.ts` 提交链路写入 `additional_kwargs: { files: filesForSubmit }`。 |
| 5 | 引用提交带来源元信息且兼容既有渲染链路ATREF-03 | ✓ VERIFIED | `FileInMessage` 保留 `ref_kind/ref_source` 可选字段,消息渲染链路保持兼容。 |
| 6 | 失效引用软剔除并继续发送文本ATREF-03 | ✓ VERIFIED | `buildFilesForSubmit` 丢弃 `stale``hooks.ts` toast 后继续发送。 |
| 7 | 回归测试覆盖候选/chip/上限/软失败ATREF-04 | ✓ VERIFIED | `DF-INPUT-007/008/009` 重新验证通过008 不再永久跳过。 |
| 8 | 存在 style/logic/tests/docs 提交分组计划ATREF-04 | ✓ VERIFIED | `06-COMMIT-GUIDE.md` 保持 `style -> logic -> tests -> docs` 分组约束。 |
| 1 | `@` 仅展示当前线程候选并支持过滤ATREF-01 | ✓ VERIFIED | `input-box.tsx` 使用 `thread.values.artifacts` + `useUploadedFiles(threadId)` 聚合,`findMentionToken`+`mentionQuery` 过滤。 |
| 2 | 选中候选后显示可删除引用 chipATREF-02 | ✓ VERIFIED | [input-box.tsx](/home/mt/Project/deerflow2/frontend/src/components/workspace/input-box.tsx:562) 渲染 `reference-inline-preview/reference-chip`,并支持 remove。 |
| 3 | 同名去歧义“文件名+类型+路径尾段”且上限 10ATREF-02 | ✓ VERIFIED | [input-box.tsx](/home/mt/Project/deerflow2/frontend/src/components/workspace/input-box.tsx:568) 展示 type+pathTail[input-box.tsx](/home/mt/Project/deerflow2/frontend/src/components/workspace/input-box.tsx:348) 限制第 11 个并 toast。 |
| 4 | 引用通过 `additional_kwargs.files` 单一 envelope 提交ATREF-03 | ✓ VERIFIED | [hooks.ts](/home/mt/Project/deerflow2/frontend/src/core/threads/hooks.ts:610) 提交 `additional_kwargs: { files }`[submit-files.ts](/home/mt/Project/deerflow2/frontend/src/core/threads/submit-files.ts:82) 写入 `ref_kind/ref_source`。 |
| 5 | stale 引用软剔除且文本继续发送ATREF-03 | ✓ VERIFIED | [submit-files.ts](/home/mt/Project/deerflow2/frontend/src/core/threads/submit-files.ts:73) 跳过 stale[hooks.ts](/home/mt/Project/deerflow2/frontend/src/core/threads/hooks.ts:596) 仅 toast 后继续 submit。 |
| 6 | **06-06**mention 不被识别为新上传文件 | ✓ VERIFIED | [uploads_middleware.py](/home/mt/Project/deerflow2/backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py:172) `ref_kind=="mention"` 直接跳过。 |
| 7 | `<uploaded_files>` new_files 仅包含真实上传 | ✓ VERIFIED | `_files_from_kwargs` 过滤 mention 后才进入 `new_files`;回归测试 [test_uploads_middleware_core_logic.py](/home/mt/Project/deerflow2/backend/tests/test_uploads_middleware_core_logic.py:146) 与 [test_uploads_middleware_core_logic.py](/home/mt/Project/deerflow2/backend/tests/test_uploads_middleware_core_logic.py:162)。 |
| 8 | ATREF-04 自动化回归可执行(单测+E2E | ✓ VERIFIED | `node --test hooks.test.ts` 4 通过;`pnpm test:e2e --grep DF-INPUT-007/008/009` 3 通过;`uv run pytest -k \"mention or files_from_kwargs\"` 2 通过。 |
| 9 | Validation 的 Wave 0 闭环完成 | ✗ FAILED | [06-VALIDATION.md](/home/mt/Project/deerflow2/.planning/phases/06-/06-VALIDATION.md:45) 仍有 `pending`[06-VALIDATION.md](/home/mt/Project/deerflow2/.planning/phases/06-/06-VALIDATION.md:68) Sign-Off 未完成。 |
| 10 | must_haves / requirements-completed / UAT gaps 闭环一致 | ✗ FAILED | [06-UAT.md](/home/mt/Project/deerflow2/.planning/phases/06-/06-UAT.md:2) 仍 `diagnosed` 且 mention 误判仍记 failed[REQUIREMENTS.md](/home/mt/Project/deerflow2/.planning/REQUIREMENTS.md:72) `ATREF-01..04` 仍 Pending。 |
**Score:** 8/8 truths verified
**Score:** 8/10 truths verified
### Required Artifacts
| Artifact | Expected | Status | Details |
| --- | --- | --- | --- |
| `frontend/src/components/workspace/input-box.tsx` | `@` 候选、过滤、chip、键盘交互、上限 10 | ✓ VERIFIED | 使用 `DropdownMenu` 候选层,包含类型/路径去歧义显示。 |
| `frontend/src/core/threads/hooks.ts` | 统一提交 `additional_kwargs.files` | ✓ VERIFIED | `filesForSubmit` 汇总后进入提交 envelope。 |
| `frontend/src/core/threads/submit-files.ts` | uploads/references 合并与 artifact 物化 | ✓ VERIFIED | `materializeArtifactReferences` + `buildFilesForSubmit` 正常工作。 |
| `frontend/src/core/messages/utils.ts` | `FileInMessage` 扩展兼容 | ✓ VERIFIED | 字段扩展为可选,未破坏旧数据。 |
| `frontend/src/core/threads/hooks.test.ts` | 提交流程与软失败单测 | ✓ VERIFIED | 4 条测试通过。 |
| `frontend/tests/e2e/input-and-compose.spec.ts` | `@` 引用 E2E 回归 | ✓ VERIFIED | `DF-INPUT-007/008/009` 全部通过。 |
| `.planning/phases/06-/06-COMMIT-GUIDE.md` | 分组提交计划 | ✓ VERIFIED | 分组与执行顺序清晰。 |
| `backend/packages/harness/deerflow/agents/middlewares/uploads_middleware.py` | mention 与 upload 语义分离 | ✓ VERIFIED | `_files_from_kwargs` 过滤 `ref_kind=mention`。 |
| `backend/tests/test_uploads_middleware_core_logic.py` | mention 过滤回归测试 | ✓ VERIFIED | 新增 mention-only / mixed-list 两条测试。 |
| `frontend/src/components/workspace/input-box.tsx` | 候选、chip、上限、去歧义 | ✓ VERIFIED | UI 合同字段和 testid 都在位。 |
| `frontend/src/core/threads/hooks.ts` | 单一 files envelope + soft-fail | ✓ VERIFIED | 两条提交流程都接入 `buildFilesForSubmit`。 |
| `.planning/phases/06-/06-VALIDATION.md` | 与当前验证状态一致 | ⚠️ PARTIAL | 文档仍有 pending/未签核项。 |
| `.planning/phases/06-/06-UAT.md` | gap closure 已回写 | ✗ FAILED | 仍停留在旧诊断结果。 |
### Key Link Verification
| From | To | Via | Status | Details |
| --- | --- | --- | --- | --- |
| `input-box.tsx` | `uploads/hooks.ts` | `useUploadedFiles(threadId)` | ✓ WIRED | 候选来源连接正常。 |
| `input-box.tsx` | `thread.values.artifacts` | thread artifacts 候选源 | ✓ WIRED | 直接读取。 |
| `input-box.tsx` | `hooks.ts` | `PromptInputMessage.references` | ✓ WIRED | `handleSubmit` 将 references 合并后提交。 |
| `hooks.ts` | `submit-files.ts` | `buildFilesForSubmit/materializeArtifactReferences` | ✓ WIRED | 提交前标准化已接入。 |
| `hooks.ts` | `additional_kwargs.files` | 提交 envelope | ✓ WIRED | 主链路输出一致。 |
| `input-box.tsx` | `dropdown-menu.tsx` | Dropdown 候选面板 | ✓ WIRED | 使用 `DropdownMenuContent/Item`。 |
| `input-box.tsx` | `hooks.ts` | `PromptInputMessage.references` | ✓ WIRED | `onSubmit` 注入 `references` 并发送。 |
| `hooks.ts` | `submit-files.ts` | `buildFilesForSubmit/materializeArtifactReferences` | ✓ WIRED | 提交前统一归一化并构建 files。 |
| `submit-files.ts` | `uploads_middleware.py` | `additional_kwargs.files[*].ref_kind/ref_source` | ✓ WIRED | 前端写 `ref_kind=mention`,后端读取并过滤 mention。 |
| `uploads_middleware.py` | agent context | `<uploaded_files>` 注入 | ✓ WIRED | `new_files` 过滤后再注入内容。 |
| `06-UAT.md` | 06-05/06-06 实现结果 | gap 状态回写 | ✗ NOT_WIRED | 文档未更新到最新实现。 |
### Data-Flow Trace (Level 4)
| Artifact | Data Variable | Source | Produces Real Data | Status |
| --- | --- | --- | --- | --- |
| `hooks.ts` | `filesForSubmit` | `buildFilesForSubmit(uploadedFileInfo, normalizedReferences)` | Yes | ✓ FLOWING |
| `submit-files.ts` | `referenceFiles[*].ref_kind/ref_source` | `message.references`(含 artifact materialization | Yes | ✓ FLOWING |
| `uploads_middleware.py` | `new_files` | `message.additional_kwargs.files` | Yes过滤 mention仅保留真实 upload | ✓ FLOWING |
### Behavioral Spot-Checks
| Behavior | Command | Result | Status |
| --- | --- | --- | --- |
| 提交构建与软失败单测 | `cd frontend && node --test src/core/threads/hooks.test.ts` | 4 passed, 0 failed | ✓ PASS |
| 类型检查 | `cd frontend && pnpm -s typecheck` | exit 0 | ✓ PASS |
| 引用回归 E2E | `cd frontend && pnpm -s test:e2e --grep "DF-INPUT-007|DF-INPUT-008|DF-INPUT-009"` | 3 passed | ✓ PASS |
| 引用构建与软失败单测 | `cd frontend && node --test src/core/threads/hooks.test.ts` | 4 passed, 0 failed | ✓ PASS |
| `@` 引用 E2E 主链路 | `cd frontend && pnpm -s test:e2e --grep "DF-INPUT-007|DF-INPUT-008|DF-INPUT-009"` | 3 passed | ✓ PASS |
| mention 过滤后端回归 | `cd backend && uv run pytest -q tests/test_uploads_middleware_core_logic.py -k "mention or files_from_kwargs"` | 2 passed | ✓ PASS |
| 直接 `pytest` 入口可用性 | `cd backend && python3 -m pytest -q ...` | `No module named pytest` | ? SKIP需使用 `uv run` |
### Requirements Coverage
| Requirement | Source Plan | Description | Status | Evidence |
| --- | --- | --- | --- | --- |
| ATREF-01 | 06-02, 06-05 | `@` 仅显示当前线程候选并支持过滤 | ✓ SATISFIED | 候选来源与过滤行为已验证。 |
| ATREF-02 | 06-02, 06-05 | chip 展示 + 同名去歧义(文件名+类型+路径尾段)+ 上限 10 | ✓ SATISFIED | 代码常量/文案/E2E 断言已统一为 10。 |
| ATREF-03 | 06-01, 06-05 | `additional_kwargs.files` 提交 + 元信息 + stale 软剔除 | ✓ SATISFIED | hooks + submit-files + 单测通过。 |
| ATREF-04 | 06-03, 06-05 | 单测+E2E 回归 + 提交分组计划 | ✓ SATISFIED | 关键 E2E 用例稳定通过,分组文档完整。 |
| ATREF-01 | 06-02, 06-05 | `@` 候选限定当前线程并可过滤 | ✓ SATISFIED | 代码链路 + DF-INPUT-007 通过。 |
| ATREF-02 | 06-02, 06-05 | chip 展示 + 去歧义 + 上限 10 | ✓ SATISFIED | 输入框合同与 DF-INPUT-009 通过。 |
| ATREF-03 | 06-01, 06-05 | `additional_kwargs.files` 提交 + stale 软剔除 | ✓ SATISFIED | hooks/submit-files + hooks.test 通过。 |
| ATREF-04 | 06-03, 06-05, 06-06 | 自动化回归 + 提交分组计划 | ✓ SATISFIED | E2E/单测/后端回归 + COMMIT-GUIDE。 |
Orphaned requirements for Phase 6: None.
@ -77,13 +113,22 @@ Orphaned requirements for Phase 6: None.
| File | Line | Pattern | Severity | Impact |
| --- | --- | --- | --- | --- |
| `frontend/src/components/workspace/input-box.tsx` | 745 | `TODO` connector 占位注释 | Info | 与 Phase 6 验证目标无阻断关系。 |
| `frontend/src/components/workspace/input-box.tsx` | 745 | TODO 注释 | Info | 与 Phase 6 核心目标无阻断。 |
| `frontend/src/components/workspace/input-box.tsx` | 1128 | TODO 注释 | Info | 与 mention/upload 链路无直接关系。 |
### Human Verification Required
### 1. 候选面板视觉锚定
**Test:** 在真实页面滚动和不同窗口宽度下,输入 `@` 观察候选面板是否“紧贴输入框上方”。
**Expected:** 面板稳定贴近输入框上边缘,不出现明显漂移。
**Why human:** 这是视觉/交互感知问题,自动化命中无法覆盖所有布局场景。
### Gaps Summary
No unresolved verification gaps in Phase 6.
代码与自动化层面06-06 新增 gapmention 被当作 upload已关闭且回归测试通过。当前阻塞来自**文档闭环**`06-VALIDATION.md`、`06-UAT.md`、`REQUIREMENTS.md` 未同步到最新验证状态导致“must_haves / requirements-completed / UAT gaps”三者不一致。
---
_Verified: 2026-04-15T05:24:24Z_
_Verifier: Codex (re-verified with current workspace state)_
_Verified: 2026-04-15T07:42:05Z_
_Verifier: Codex (gsd-verifier)_