docs(06): create phase plan
This commit is contained in:
parent
fc10d047f6
commit
f8f6401842
|
|
@ -30,6 +30,13 @@
|
|||
- [ ] **TEST-02**: Recovery changes are committed in separable concern groups (style vs logic vs tests)
|
||||
- [ ] **TEST-03**: Critical conflict files have before/after verification notes for reviewer auditing
|
||||
|
||||
### Input @ File References (Phase 6)
|
||||
|
||||
- [ ] **ATREF-01**: 输入框输入 `@` 时仅展示当前线程(artifacts + uploads)候选,且支持连续输入过滤
|
||||
- [ ] **ATREF-02**: 选中文件后以可删除 chip 展示,并在同名场景显示“文件名 + 类型 + 路径尾段”,引用上限 10
|
||||
- [ ] **ATREF-03**: 引用文件复用 `additional_kwargs.files` 提交,含来源元信息;失效引用软剔除并不阻断消息发送
|
||||
- [ ] **ATREF-04**: 引用能力具备自动化回归验证(单测 + E2E)及按 style/logic/tests/docs 的提交分组计划
|
||||
|
||||
## v2 Requirements
|
||||
|
||||
### Tooling Improvements
|
||||
|
|
@ -62,10 +69,14 @@
|
|||
| TEST-01 | Phase 5 | Pending |
|
||||
| TEST-02 | Phase 5 | Pending |
|
||||
| TEST-03 | Phase 5 | Pending |
|
||||
| ATREF-01 | Phase 6 | Pending |
|
||||
| ATREF-02 | Phase 6 | Pending |
|
||||
| ATREF-03 | Phase 6 | Pending |
|
||||
| ATREF-04 | Phase 6 | Pending |
|
||||
|
||||
**Coverage:**
|
||||
- v1 requirements: 13 total
|
||||
- Mapped to phases: 13
|
||||
- v1 requirements: 17 total
|
||||
- Mapped to phases: 17
|
||||
- Unmapped: 0
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -53,5 +53,17 @@
|
|||
- Split commits into style / logic / tests concern buckets
|
||||
- Attach reviewer-oriented verification notes for high-risk files
|
||||
|
||||
### Phase 6: 在输入框输入@时,可引用已生成文件和已上传附件
|
||||
|
||||
**Goal:** 在当前线程聊天输入框中实现 `@` 文件引用(artifacts + uploads),并通过 `additional_kwargs.files` 稳定提交且具备回归测试。
|
||||
**Requirements**: ATREF-01, ATREF-02, ATREF-03, ATREF-04
|
||||
**Depends on:** Phase 5
|
||||
**Plans:** 3 plans
|
||||
|
||||
Plans:
|
||||
- [ ] 06-01-PLAN.md — 锁定引用提交契约与软失败链路(additional_kwargs.files)
|
||||
- [ ] 06-02-PLAN.md — 实现 @ 候选 dropdown、chip 交互与上限控制
|
||||
- [ ] 06-03-PLAN.md — 补齐自动化验证并产出 style/logic/tests/docs 提交分组计划
|
||||
|
||||
---
|
||||
*Next command:* `/gsd-plan-phase 1`
|
||||
|
|
|
|||
|
|
@ -0,0 +1,178 @@
|
|||
---
|
||||
phase: 06-
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- frontend/src/core/messages/utils.ts
|
||||
- frontend/src/components/ai-elements/prompt-input.tsx
|
||||
- frontend/src/core/threads/hooks.ts
|
||||
- frontend/src/core/threads/hooks.test.ts
|
||||
autonomous: true
|
||||
requirements:
|
||||
- ATREF-03
|
||||
must_haves:
|
||||
truths:
|
||||
- "用户发送带文件引用的消息后,消息体仍通过 additional_kwargs.files 传输,不新增并行主结构。"
|
||||
- "引用文件在提交结构中可区分来源与类型,且不破坏现有文件渲染链路。"
|
||||
- "引用项失效时会被自动剔除并提示,但文本消息仍可发送。"
|
||||
artifacts:
|
||||
- path: "frontend/src/core/messages/utils.ts"
|
||||
provides: "FileInMessage 扩展字段(引用来源/类型)与兼容解析"
|
||||
- path: "frontend/src/components/ai-elements/prompt-input.tsx"
|
||||
provides: "PromptInputMessage 新增引用文件字段契约"
|
||||
- path: "frontend/src/core/threads/hooks.ts"
|
||||
provides: "上传文件与引用文件合并提交到 additional_kwargs.files"
|
||||
- path: "frontend/src/core/threads/hooks.test.ts"
|
||||
provides: "提交结构与软失败行为的单元测试"
|
||||
key_links:
|
||||
- from: "frontend/src/components/ai-elements/prompt-input.tsx"
|
||||
to: "frontend/src/core/threads/hooks.ts"
|
||||
via: "PromptInputMessage.references"
|
||||
pattern: "references"
|
||||
- from: "frontend/src/core/threads/hooks.ts"
|
||||
to: "frontend/src/core/messages/utils.ts"
|
||||
via: "FileInMessage 扩展字段"
|
||||
pattern: "additional_kwargs:\\s*\\{\\s*files"
|
||||
---
|
||||
|
||||
<objective>
|
||||
先定义并落地“引用文件提交契约”,确保 Phase 6 的数据链路稳定可回归。
|
||||
|
||||
Purpose: 把最难回滚的协议与提交流程先锁定,避免后续 UI 实现完成后才发现协议不兼容。
|
||||
Output: 扩展后的消息类型、提交流程、以及针对合并/软失败的自动化测试。
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@/home/mt/.codex/get-shit-done/workflows/execute-plan.md
|
||||
@/home/mt/.codex/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/phases/06-/06-CONTEXT.md
|
||||
@.planning/phases/06-/06-RESEARCH.md
|
||||
@.planning/phases/06-/06-VALIDATION.md
|
||||
@frontend/src/components/ai-elements/prompt-input.tsx
|
||||
@frontend/src/core/messages/utils.ts
|
||||
@frontend/src/core/threads/hooks.ts
|
||||
@frontend/src/core/threads/hooks.test.ts
|
||||
</context>
|
||||
|
||||
<interfaces>
|
||||
From `frontend/src/components/ai-elements/prompt-input.tsx`:
|
||||
```typescript
|
||||
export type PromptInputMessage = {
|
||||
text: string;
|
||||
files?: FileUIPart[];
|
||||
};
|
||||
```
|
||||
|
||||
From `frontend/src/core/messages/utils.ts`:
|
||||
```typescript
|
||||
export interface FileInMessage {
|
||||
filename: string;
|
||||
size: number;
|
||||
path?: string;
|
||||
status?: "uploading" | "uploaded";
|
||||
}
|
||||
```
|
||||
|
||||
From `frontend/src/core/threads/hooks.ts`:
|
||||
```typescript
|
||||
const filesForSubmit: FileInMessage[] = uploadedFileInfo.map(...)
|
||||
await thread.submit({
|
||||
messages: [{ type: "human", additional_kwargs: { files: filesForSubmit } }],
|
||||
});
|
||||
```
|
||||
</interfaces>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 1: 扩展引用文件契约并写 RED 测试</name>
|
||||
<files>frontend/src/core/messages/utils.ts, frontend/src/components/ai-elements/prompt-input.tsx, frontend/src/core/threads/hooks.test.ts</files>
|
||||
<read_first>
|
||||
- frontend/src/core/messages/utils.ts
|
||||
- frontend/src/components/ai-elements/prompt-input.tsx
|
||||
- frontend/src/core/threads/hooks.test.ts
|
||||
- .planning/phases/06-/06-CONTEXT.md
|
||||
</read_first>
|
||||
<behavior>
|
||||
- Test 1: `PromptInputMessage` 支持 `references` 字段,类型可表达 `artifact|upload` 来源(per D-06)。
|
||||
- Test 2: `FileInMessage` 支持可选 `ref_kind/ref_source` 元数据且旧字段保持可用(per D-05, D-06)。
|
||||
</behavior>
|
||||
<action>在 `PromptInputMessage` 新增 `references` 数组字段;在 `FileInMessage` 增加 `ref_kind: "mention"` 与 `ref_source: "artifact" | "upload"` 可选字段;先在 `hooks.test.ts` 新增失败用例,断言提交 payload 含 `additional_kwargs.files[*].ref_kind/ref_source` 且不删除已有 `filename/size/path/status` 字段(按 D-05、D-06)。</action>
|
||||
<acceptance_criteria>
|
||||
- `rg -n "references\\?:" frontend/src/components/ai-elements/prompt-input.tsx` 返回至少 1 行。
|
||||
- `rg -n "ref_kind|ref_source" frontend/src/core/messages/utils.ts` 返回至少 2 行。
|
||||
- 新增测试在实现前失败(RED),失败信息包含 `ref_kind` 或 `ref_source` 字样。
|
||||
</acceptance_criteria>
|
||||
<verify>
|
||||
<automated>cd frontend && node --test src/core/threads/hooks.test.ts</automated>
|
||||
</verify>
|
||||
<done>类型契约完成并有可复现的失败测试,明确约束提交结构。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 2: 在线程提交链路合并上传文件与引用文件并实现软失败</name>
|
||||
<files>frontend/src/core/threads/hooks.ts, frontend/src/core/threads/hooks.test.ts</files>
|
||||
<read_first>
|
||||
- frontend/src/core/threads/hooks.ts
|
||||
- frontend/src/core/threads/hooks.test.ts
|
||||
- frontend/src/core/uploads/api.ts
|
||||
- .planning/phases/06-/06-CONTEXT.md
|
||||
- .planning/phases/06-/06-RESEARCH.md
|
||||
</read_first>
|
||||
<behavior>
|
||||
- Test 1: 上传文件 + 引用文件会统一写入 `additional_kwargs.files`,且上传文件不被覆盖(per D-05)。
|
||||
- Test 2: 引用失效时仅剔除失效项并 toast,文本仍会继续提交(per D-07)。
|
||||
</behavior>
|
||||
<action>在 `sendMessage` 中新增引用文件合并逻辑:`uploadedFileInfo` 先转 `FileInMessage`,再追加 `message.references`(保留 `ref_kind/ref_source`);提交前根据传入的有效引用列表进行二次过滤,失效项通过 `toast.error("部分引用已失效,已自动移除")` 提示并继续 `thread.submit`;禁止创建 `mentions` 等并行结构(按 D-05、D-07)。</action>
|
||||
<acceptance_criteria>
|
||||
- `rg -n "additional_kwargs:\\s*\\{\\s*files" frontend/src/core/threads/hooks.ts` 命中提交代码。
|
||||
- `rg -n "ref_kind|ref_source" frontend/src/core/threads/hooks.ts` 命中引用元信息写入。
|
||||
- `rg -n "已自动移除|stale" frontend/src/core/threads/hooks.ts` 命中软失败分支。
|
||||
</acceptance_criteria>
|
||||
<verify>
|
||||
<automated>cd frontend && node --test src/core/threads/hooks.test.ts</automated>
|
||||
</verify>
|
||||
<done>提交链路兼容 uploads + references,软失败生效且单测通过。</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| input-box→thread submit API | 用户可控输入跨越到后端提交 envelope |
|
||||
| thread artifacts/uploads→引用元信息 | 候选文件元数据进入消息体 |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-06-01-01 | T | `frontend/src/core/threads/hooks.ts` | mitigate | 仅接受候选池中引用并在提交前二次过滤,拒绝自由路径注入(ASVS V5)。 |
|
||||
| T-06-01-02 | I | `additional_kwargs.files` | mitigate | 强制 thread 范围来源,不引入全局检索,避免跨线程信息泄露(ASVS V4)。 |
|
||||
| T-06-01-03 | D | `sendMessage` 合并逻辑 | mitigate | 失效引用软剔除并继续提交,避免单点失败阻断消息发送。 |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
- `cd frontend && node --test src/core/threads/hooks.test.ts`
|
||||
- `cd frontend && pnpm -s typecheck`
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- `additional_kwargs.files` 成为上传与引用的唯一提交结构。
|
||||
- 引用元信息可被编码且不影响既有文件渲染。
|
||||
- 失效引用不会导致整条消息发送失败。
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/06-/06-01-SUMMARY.md`
|
||||
</output>
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
---
|
||||
phase: 06-
|
||||
plan: 02
|
||||
type: execute
|
||||
wave: 2
|
||||
depends_on:
|
||||
- 06-01
|
||||
files_modified:
|
||||
- frontend/src/components/workspace/input-box.tsx
|
||||
- frontend/src/components/ai-elements/prompt-input.tsx
|
||||
- frontend/src/core/uploads/hooks.ts
|
||||
- frontend/src/components/ui/dropdown-menu.tsx
|
||||
autonomous: true
|
||||
requirements:
|
||||
- ATREF-01
|
||||
- ATREF-02
|
||||
must_haves:
|
||||
truths:
|
||||
- "用户在输入框输入 @ 后可立即看到当前线程文件候选,并可继续输入过滤。"
|
||||
- "用户选择候选后在输入区看到可删除 chip,而不是纯文本 @文件名。"
|
||||
- "同名文件可通过类型徽标和路径尾段区分,且超过 10 个引用会被阻止。"
|
||||
artifacts:
|
||||
- path: "frontend/src/components/workspace/input-box.tsx"
|
||||
provides: "@候选收集、过滤、dropdown 展示、chip 管理"
|
||||
- path: "frontend/src/components/ai-elements/prompt-input.tsx"
|
||||
provides: "textarea 键盘事件和 chip 删除协同"
|
||||
key_links:
|
||||
- from: "frontend/src/components/workspace/input-box.tsx"
|
||||
to: "frontend/src/core/uploads/hooks.ts"
|
||||
via: "useUploadedFiles(threadId)"
|
||||
pattern: "useUploadedFiles"
|
||||
- from: "frontend/src/components/workspace/input-box.tsx"
|
||||
to: "frontend/src/components/ui/dropdown-menu.tsx"
|
||||
via: "DropdownMenu 候选面板"
|
||||
pattern: "DropdownMenuContent"
|
||||
---
|
||||
|
||||
<objective>
|
||||
实现输入态 `@` 引用交互,覆盖候选展示、过滤、选择、chip、上限与键盘操作。
|
||||
|
||||
Purpose: 把 D-01/D-02/D-03/D-04/D-08/D-09 直接转成可见交互,且不突破线程边界。
|
||||
Output: 输入框引用交互闭环(dropdown + chip + 限制策略)。
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@/home/mt/.codex/get-shit-done/workflows/execute-plan.md
|
||||
@/home/mt/.codex/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/phases/06-/06-CONTEXT.md
|
||||
@.planning/phases/06-/06-RESEARCH.md
|
||||
@frontend/src/components/workspace/input-box.tsx
|
||||
@frontend/src/components/ai-elements/prompt-input.tsx
|
||||
@frontend/src/core/uploads/hooks.ts
|
||||
@frontend/src/components/workspace/chats/chat-box.tsx
|
||||
@frontend/src/components/ui/dropdown-menu.tsx
|
||||
</context>
|
||||
|
||||
<interfaces>
|
||||
From `frontend/src/core/uploads/hooks.ts`:
|
||||
```typescript
|
||||
export function useUploadedFiles(threadId: string)
|
||||
```
|
||||
|
||||
From `frontend/src/components/ui/dropdown-menu.tsx`:
|
||||
```typescript
|
||||
export {
|
||||
DropdownMenu,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem
|
||||
}
|
||||
```
|
||||
|
||||
From `frontend/src/components/workspace/chats/chat-box.tsx`:
|
||||
```typescript
|
||||
const { thread } = useThread();
|
||||
// artifacts 来源:thread.values.artifacts
|
||||
```
|
||||
</interfaces>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: 构建 thread-scoped @ 候选聚合与 dropdown 触发过滤</name>
|
||||
<files>frontend/src/components/workspace/input-box.tsx, frontend/src/core/uploads/hooks.ts</files>
|
||||
<read_first>
|
||||
- frontend/src/components/workspace/input-box.tsx
|
||||
- frontend/src/components/workspace/chats/chat-box.tsx
|
||||
- frontend/src/core/uploads/hooks.ts
|
||||
- frontend/src/components/ui/dropdown-menu.tsx
|
||||
- .planning/phases/06-/06-CONTEXT.md
|
||||
</read_first>
|
||||
<action>在 `InputBox` 增加 `referenceCandidates` 与 `mentionQuery` 状态;候选源固定为当前 `threadId` 的 `artifacts + uploads`(按 D-01);检测 textarea 输入中最后一个 `@` token:输入 `@` 立即打开 dropdown(按 D-02),继续输入做前缀过滤;候选项渲染包含“文件名 + 类型徽标 + 路径尾段”(按 D-04);面板必须使用 `DropdownMenu*` 组件(按 D-09),禁止自定义绝对定位浮层。</action>
|
||||
<acceptance_criteria>
|
||||
- `rg -n "useUploadedFiles\\(" frontend/src/components/workspace/input-box.tsx` 命中候选上传源。
|
||||
- `rg -n "thread\\.values\\.artifacts|artifacts" frontend/src/components/workspace/input-box.tsx` 命中 artifact 源。
|
||||
- `rg -n "DropdownMenu|DropdownMenuContent|DropdownMenuItem" frontend/src/components/workspace/input-box.tsx` 命中 dropdown 实现。
|
||||
- `rg -n "mentionQuery|@\"|lastIndexOf\\(\"@\"" frontend/src/components/workspace/input-box.tsx` 命中触发过滤逻辑。
|
||||
</acceptance_criteria>
|
||||
<verify>
|
||||
<automated>cd frontend && pnpm -s typecheck</automated>
|
||||
</verify>
|
||||
<done>输入 `@` 可见 thread 内候选,过滤生效,且候选 UI 满足去歧义展示。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: 实现 chip 选择/删除、上限控制与键盘行为</name>
|
||||
<files>frontend/src/components/workspace/input-box.tsx, frontend/src/components/ai-elements/prompt-input.tsx</files>
|
||||
<read_first>
|
||||
- frontend/src/components/workspace/input-box.tsx
|
||||
- frontend/src/components/ai-elements/prompt-input.tsx
|
||||
- .planning/phases/06-/06-CONTEXT.md
|
||||
- .planning/phases/06-/06-RESEARCH.md
|
||||
</read_first>
|
||||
<action>选中候选后写入 `references` 状态并在输入区展示可删除 chip(按 D-03),不把引用作为纯文本提交;按 `source+path` 去重;引用数量达到 10 时用 `toast.error` 提示并阻止新增(按 D-08);实现键盘交互:`ArrowUp/ArrowDown` 切换候选、`Enter` 选中、`Escape` 关闭、空输入时 `Backspace` 删除最后一个 chip;与 IME 组合输入状态兼容(`isComposing` 时不触发选择提交)。</action>
|
||||
<acceptance_criteria>
|
||||
- `rg -n "references|chip|Tag" frontend/src/components/workspace/input-box.tsx` 命中 chip 渲染与状态。
|
||||
- `rg -n "10|MAX_.*REFERENCE|超限|toast\\.error" frontend/src/components/workspace/input-box.tsx` 命中上限控制。
|
||||
- `rg -n "ArrowDown|ArrowUp|Escape|Backspace|isComposing" frontend/src/components/workspace/input-box.tsx frontend/src/components/ai-elements/prompt-input.tsx` 命中键盘实现。
|
||||
</acceptance_criteria>
|
||||
<verify>
|
||||
<automated>cd frontend && pnpm -s typecheck</automated>
|
||||
</verify>
|
||||
<done>chip 交互、上限、键盘行为与 IME 保护均实现并可编译。</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| textarea 输入→候选匹配 | 用户输入内容驱动候选过滤 |
|
||||
| 候选列表→引用状态 | 可展示文件元数据进入可提交状态 |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-06-02-01 | I | `input-box.tsx` 候选聚合 | mitigate | 候选严格绑定当前 `threadId` 的 artifacts/uploads,禁止全局池(ASVS V4,per D-01)。 |
|
||||
| T-06-02-02 | T | `@` 查询与选择 | mitigate | 选择仅可来自候选对象,提交不信任自由文本路径(ASVS V5)。 |
|
||||
| T-06-02-03 | D | 引用数量控制 | mitigate | 强制 10 个上限并阻止继续添加,降低前端/提交膨胀风险(per D-08)。 |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
- `cd frontend && pnpm -s typecheck`
|
||||
- `cd frontend && pnpm -s lint -- src/components/workspace/input-box.tsx src/components/ai-elements/prompt-input.tsx`
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- `@` 触发、过滤、选择、关闭行为完整可用。
|
||||
- 引用展示为 chip,支持删除、去重、键盘操作。
|
||||
- 候选来源与组件实现满足 D-01/D-09 的硬约束。
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/06-/06-02-SUMMARY.md`
|
||||
</output>
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
---
|
||||
phase: 06-
|
||||
plan: 03
|
||||
type: execute
|
||||
wave: 3
|
||||
depends_on:
|
||||
- 06-01
|
||||
- 06-02
|
||||
files_modified:
|
||||
- frontend/tests/e2e/input-and-compose.spec.ts
|
||||
- frontend/tests/e2e/support/chat-helpers.ts
|
||||
- frontend/src/core/threads/hooks.test.ts
|
||||
- .planning/phases/06-/06-VALIDATION.md
|
||||
- .planning/phases/06-/06-COMMIT-PLAN.md
|
||||
autonomous: true
|
||||
requirements:
|
||||
- ATREF-04
|
||||
must_haves:
|
||||
truths:
|
||||
- "@ 引用主流程有自动化测试覆盖(候选、chip、上限、软失败)。"
|
||||
- "Phase 6 提交分组按 style / logic / tests / docs 顺序可直接执行。"
|
||||
- "Validation 文档的 Wave 0 缺口被关闭或显式替换为可执行命令。"
|
||||
artifacts:
|
||||
- path: "frontend/tests/e2e/input-and-compose.spec.ts"
|
||||
provides: "@ 引用交互 E2E 回归"
|
||||
- path: "frontend/src/core/threads/hooks.test.ts"
|
||||
provides: "提交 envelope 与软失败单测"
|
||||
- path: ".planning/phases/06-/06-COMMIT-PLAN.md"
|
||||
provides: "按关注点提交分组与执行顺序"
|
||||
key_links:
|
||||
- from: "frontend/tests/e2e/input-and-compose.spec.ts"
|
||||
to: "frontend/src/components/workspace/input-box.tsx"
|
||||
via: "@ 引用交互断言"
|
||||
pattern: "@引用|chip|失效引用|上限"
|
||||
- from: ".planning/phases/06-/06-COMMIT-PLAN.md"
|
||||
to: "git history"
|
||||
via: "concern-based commit order"
|
||||
pattern: "style -> logic -> tests -> docs"
|
||||
---
|
||||
|
||||
<objective>
|
||||
补齐 Phase 6 的自动化验证与提交卫生,使本阶段可审计、可回归、可合并。
|
||||
|
||||
Purpose: 避免“功能上线但无测试与提交策略”的交付风险。
|
||||
Output: E2E/单测、更新后的验证矩阵、以及可执行的 commit 分组计划。
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@/home/mt/.codex/get-shit-done/workflows/execute-plan.md
|
||||
@/home/mt/.codex/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/phases/06-/06-VALIDATION.md
|
||||
@.planning/phases/06-/06-CONTEXT.md
|
||||
@frontend/tests/e2e/input-and-compose.spec.ts
|
||||
@frontend/tests/e2e/support/chat-helpers.ts
|
||||
@frontend/src/core/threads/hooks.test.ts
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
<name>Task 1: 增加 @ 引用 E2E 与 hooks 单测覆盖 D-01~D-08</name>
|
||||
<files>frontend/tests/e2e/input-and-compose.spec.ts, frontend/tests/e2e/support/chat-helpers.ts, frontend/src/core/threads/hooks.test.ts</files>
|
||||
<read_first>
|
||||
- frontend/tests/e2e/input-and-compose.spec.ts
|
||||
- frontend/tests/e2e/support/chat-helpers.ts
|
||||
- frontend/src/core/threads/hooks.test.ts
|
||||
- .planning/phases/06-/06-VALIDATION.md
|
||||
- .planning/phases/06-/06-CONTEXT.md
|
||||
</read_first>
|
||||
<behavior>
|
||||
- Test 1: 输入 `@` 后只展示当前线程候选并可过滤(per D-01, D-02)。
|
||||
- Test 2: 选择候选后显示 chip,超过 10 个不可继续添加(per D-03, D-08)。
|
||||
- Test 3: 失效引用被剔除且发送不阻断(per D-07)。
|
||||
</behavior>
|
||||
<action>在 `input-and-compose.spec.ts` 增加 `@引用` 场景用例(可用 `test.describe("聊天工作台 / @引用文件")` 分组);必要时在 `chat-helpers.ts` 增加 thread 内 artifact/upload fixture 探测辅助;在 `hooks.test.ts` 增加引用元信息提交与失效软失败断言。若环境依赖不足,使用 `testInfo.skip` 并写明原因字符串,不允许静默跳过。</action>
|
||||
<acceptance_criteria>
|
||||
- `rg -n "@引用文件|chip|失效引用|上限" frontend/tests/e2e/input-and-compose.spec.ts` 命中新增场景。
|
||||
- `rg -n "ref_kind|ref_source|soft|stale|继续提交" frontend/src/core/threads/hooks.test.ts` 命中新增断言。
|
||||
- 新增/修改测试命令可执行且输出包含 pass 或 explainable skip。
|
||||
</acceptance_criteria>
|
||||
<verify>
|
||||
<automated>cd frontend && pnpm -s test:e2e -- input-and-compose.spec.ts && node --test src/core/threads/hooks.test.ts</automated>
|
||||
</verify>
|
||||
<done>自动化覆盖 D-01~D-08 的关键行为,并保留可解释 skip 机制。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: 更新验证矩阵并关闭 Wave 0 缺口</name>
|
||||
<files>.planning/phases/06-/06-VALIDATION.md</files>
|
||||
<read_first>
|
||||
- .planning/phases/06-/06-VALIDATION.md
|
||||
- .planning/phases/06-/06-RESEARCH.md
|
||||
- .planning/phases/06-/06-CONTEXT.md
|
||||
</read_first>
|
||||
<action>把 `06-VALIDATION.md` 中 Wave 0 缺口替换为本阶段已落地的真实测试文件与命令;将 `nyquist_compliant` 更新为 `true`(前提是所有任务都具备自动化验证命令);在 Per-Task Verification Map 中加入 D-01~D-09 对应条目与 threat 引用。</action>
|
||||
<acceptance_criteria>
|
||||
- `rg -n "nyquist_compliant:\\s*true" .planning/phases/06-/06-VALIDATION.md` 命中。
|
||||
- `rg -n "D-0[1-9]|ATREF" .planning/phases/06-/06-VALIDATION.md` 命中需求映射。
|
||||
- `rg -n "Wave 0" .planning/phases/06-/06-VALIDATION.md` 不再包含未完成占位项。
|
||||
</acceptance_criteria>
|
||||
<verify>
|
||||
<automated>cd /home/mt/Project/deerflow2 && rg -n "nyquist_compliant:\\s*true|D-0[1-9]|ATREF" .planning/phases/06-/06-VALIDATION.md</automated>
|
||||
</verify>
|
||||
<done>验证策略与实现状态一致,且 Nyquist 检查可通过。</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: 产出 Phase 6 Git 提交分组计划(style/logic/tests/docs)</name>
|
||||
<files>.planning/phases/06-/06-COMMIT-PLAN.md</files>
|
||||
<read_first>
|
||||
- .planning/phases/05-test-hardening-and-commit-hygiene/05-SUMMARY.md
|
||||
- .planning/phases/06-/06-01-PLAN.md
|
||||
- .planning/phases/06-/06-02-PLAN.md
|
||||
- .planning/phases/06-/06-VALIDATION.md
|
||||
</read_first>
|
||||
<action>新增 `06-COMMIT-PLAN.md`,明确提交顺序与分组:`1) style`(仅样式/展示类变更,如 chip 外观、dropdown 样式类),`2) logic`(候选聚合、提交结构、软失败逻辑),`3) tests`(hooks/e2e 用例与 helper),`4) docs`(VALIDATION/SUMMARY/ROADMAP 更新);每组列出建议 `git add` 文件清单与规范 commit message 模板,禁止跨组混提。</action>
|
||||
<acceptance_criteria>
|
||||
- `06-COMMIT-PLAN.md` 包含固定顺序文本 `style -> logic -> tests -> docs`。
|
||||
- 文档内每个分组都有文件清单与 commit message 示例。
|
||||
- 文档包含“禁止跨组混提”规则。
|
||||
</acceptance_criteria>
|
||||
<verify>
|
||||
<automated>cd /home/mt/Project/deerflow2 && rg -n "style -> logic -> tests -> docs|禁止跨组混提|commit message" .planning/phases/06-/06-COMMIT-PLAN.md</automated>
|
||||
</verify>
|
||||
<done>提交卫生方案可直接执行,满足用户的分组与顺序约束。</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| test fixtures→真实线程环境 | 自动化测试依赖 thread fixtures 与后端可用性 |
|
||||
| commit grouping doc→实际提交动作 | 文档规范需要转化为可执行提交步骤 |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-06-03-01 | R | `06-COMMIT-PLAN.md` | mitigate | 提供固定顺序与文件清单,确保提交可追踪与可审计。 |
|
||||
| T-06-03-02 | D | E2E 测试执行 | mitigate | 环境不足时显式 skip 并给原因,避免反复失败阻塞整个阶段。 |
|
||||
| T-06-03-03 | T | 验证矩阵 | mitigate | 将验证命令与需求映射写死到 VALIDATION,避免后续手工偏离。 |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
- `cd frontend && pnpm -s test:e2e -- input-and-compose.spec.ts`
|
||||
- `cd frontend && node --test src/core/threads/hooks.test.ts`
|
||||
- `cd /home/mt/Project/deerflow2 && rg -n "style -> logic -> tests -> docs" .planning/phases/06-/06-COMMIT-PLAN.md`
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Phase 6 关键行为有自动化回归(单测 + E2E)。
|
||||
- 验证文档与代码状态一致,不留 Wave 0 未闭合缺口。
|
||||
- Git 提交计划明确 style/logic/tests/docs 分组与执行顺序。
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/06-/06-03-SUMMARY.md`
|
||||
</output>
|
||||
Loading…
Reference in New Issue