docs(test): 记录受控投影项目绑定的回归
短测、vet 与架构边界已通过。dev 浏览器链路尚未重载本提交,报告记为未运行。
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
---
|
||||
title: "修复调研报告受控投影断链"
|
||||
task_id: controlled-projection-project-binding-2026-09-28
|
||||
status: in_progress
|
||||
created: 2026-09-28
|
||||
updated: 2026-09-28
|
||||
owner: Cursor
|
||||
task_type: fix
|
||||
policy_revision: "AGENTS.md + agent-worktree-workflow @ 2026-09-21"
|
||||
branch: fix/controlled-projection-project-binding-2026-09-28
|
||||
worktree: .worktrees/controlled-projection-project-binding-2026-09-28
|
||||
base_dev_sha: "5d762fb2061113285ee21219471baaf11cb2d770"
|
||||
write_scope:
|
||||
- internal/server
|
||||
- internal/coordinator
|
||||
- internal/bizdev
|
||||
- .doc/ops/CURRENT.md
|
||||
- .doc/ops/short-term/2026-09-28-controlled-projection-project-binding.md
|
||||
- .doc/test-reports/2026-09-28-controlled-projection-project-binding-test-report.md
|
||||
mutex: controlled-projection-binding
|
||||
review_state: pending
|
||||
integration_state: branch_only
|
||||
deployment: not_loaded
|
||||
cleanup: pending
|
||||
remote_sync: not_requested
|
||||
---
|
||||
|
||||
# 修复调研报告受控投影断链
|
||||
|
||||
## 用户目标与授权
|
||||
|
||||
用户在项目会话里让助手编制调研报告。助手回复已生成并保存(含耗时与基准假设),刷新文档页仍是模板骨架。授权范围是修复受控投影断链:回填项目绑定、会话可追溯、无绑定时失败关闭、回复与账本状态一致。不改前端骨架回退,不删除工作区,不晋升环境,不 push。
|
||||
|
||||
## 检索
|
||||
|
||||
- 问题台账未另开新条;本任务记录根因与修复。catalog overlap 探测为 none。登记时未带 mutex/intent,避免与持有全仓范围 `.` 的夜间推进任务发生 same_scope 拒绝。
|
||||
- 经验闭环:本轮采纳「回复口径必须跟受控账本,而不是跟小队成功」。
|
||||
|
||||
## 根因
|
||||
|
||||
聊天入口只 `SetProjectID` 做访问校验,`UserCtx.Project.ID` 一直为空。协调器 `handleTriggerTask` 用后者解析 projectID,得到 0。`canonicalDocID` 因此返回空串,bizdev 整段跳过 docgov/docrevision 投影。`output.md` 只落在隔离工作区,回复仍写「正文已保存」。
|
||||
|
||||
证据工作区:`research_1790576535990100562`(project_id=0、session_id 空、completed)。`doc_proj6024_bd_research` 在 07:06 带绑定重跑前只有模板快照。随后 `research_1790584772615062606`(失败)和 `research_1790585141260333084`(completed)仍是 project_id=0。
|
||||
|
||||
## 修复
|
||||
|
||||
提交 `f8730791`:
|
||||
|
||||
- `bindSessionProjectContext`:`enrichSessionWorkflowStage` 在项目已授权且上下文项目 ID 为空时回填。已有绑定不覆盖。
|
||||
- `handleTriggerTask` / `handleTriggerAdhocTask` 把 `ChatSessionID` 写入 `TaskRunRequest.SessionID`。
|
||||
- 受控目录任务(目录键与 `rd_*`)在 `ProjectID <= 0` 时返回「会话未绑定项目,受控交付物无法入账」,不建孤儿工作区。未知自由任务不在此列。
|
||||
- 完成回复只在 `DocRecord` 有文档 ID 时称已写入受控文档;否则说明交付物在工作区、尚未入账。`CompletionSummary` 对受控键同样区分。
|
||||
|
||||
## 数据
|
||||
|
||||
`doc_proj6024_bd_research` 已由 07:06 带绑定重跑入账,不做数据修复。
|
||||
|
||||
孤儿工作区只登记、不删除:
|
||||
|
||||
| 路径 | cleanup | 原因 |
|
||||
|---|---|---|
|
||||
| `data/dev/workspaces/bizdev/research_1790576535990100562` | pending | project_id=0 的已完成调研,正文未入账 |
|
||||
| `data/dev/workspaces/bizdev/research_1790585141260333084` | pending | 修复前再次以 project_id=0 完成 |
|
||||
|
||||
cleanup_owner:本任务。复查触发:合入 local dev 并确认新会话不再产生 project_id=0 的受控工作区之后,由独立维护者决定是否归档。
|
||||
|
||||
## 验证
|
||||
|
||||
见 [测试报告](../../test-reports/2026-09-28-controlled-projection-project-binding-test-report.md)。
|
||||
|
||||
## 五态
|
||||
|
||||
| 字段 | 值 |
|
||||
|---|---|
|
||||
| review_state | pending |
|
||||
| integration_state | branch_only |
|
||||
| deployment | not_loaded(运行中的 dev 二进制早于本提交) |
|
||||
| cleanup | pending |
|
||||
| remote_sync | not_requested |
|
||||
@@ -0,0 +1,103 @@
|
||||
# 调研报告受控投影项目绑定 测试报告
|
||||
|
||||
## 一、 测试背景 (Background)
|
||||
|
||||
项目会话里触发调研报告后,助手称正文已保存,刷新文档页仍显示模板骨架。根因是会话授权项目 ID 没有回填到协调器读取的 `UserCtx.Project.ID`,受控投影被跳过。任务记录见 [短文](../ops/short-term/2026-09-28-controlled-projection-project-binding.md)。
|
||||
|
||||
## 二、 测试目标 (Test Objectives)
|
||||
|
||||
- 已授权会话在派发前把项目 ID 写入协调器上下文,且不覆盖已有绑定。
|
||||
- 协调器触发任务时 `TaskRunRequest` 带上项目 ID 与 `SessionID`。
|
||||
- 受控任务键在 `ProjectID <= 0` 时失败关闭,不建工作区。
|
||||
- 完成回复在没有受控账本记录时不称「正文已保存」。
|
||||
- 既有阶段编排、异步 run 与流式任务在带上项目 ID 后仍能完成。
|
||||
|
||||
## 三、 测试方案与环境 (Test Plan & Environment)
|
||||
|
||||
- OS:Linux。工作树:`.worktrees/controlled-projection-project-binding-2026-09-28`。
|
||||
- 基线 `5d762fb2061113285ee21219471baaf11cb2d770`。被测提交 `f8730791b9a0a9d4ac67586f622acb6afaf43f10`。
|
||||
- 层级:Go 接口短测、`go vet ./...`、架构边界 `arch-check --mode block`。
|
||||
- 产品 PI 浏览器链路依赖已加载本提交的 dev 进程。本报告记录短测时,运行中的 `bin/agent-server` 仍是合入前的主目录制品。
|
||||
|
||||
## 四、 预期结果 (Expected Results)
|
||||
|
||||
- `bindSessionProjectContext` 把空项目 ID 填成会话项目;已有值保持不变;未授权项目不回填。
|
||||
- 同步触发 research 时请求的 `ProjectID` 与 `SessionID` 与上下文一致。
|
||||
- `intake` / `research` 在项目 ID 为 0 时返回 `ErrUnboundControlledProject`,`DocRecord` 为空。
|
||||
- 无 `DocRecord` 的完成回复包含「尚未写入受控文档账本」,且不含「正文已保存」。
|
||||
- `go vet ./...` 无输出;三包 `go test -short` 通过;架构边界通过。
|
||||
|
||||
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
|
||||
|
||||
### 用例 1:项目绑定回填
|
||||
|
||||
- 输入:`go test -count=1 -short -timeout 180s ./internal/server/ -run TestBindSessionProjectContext`(含在用例 4 的整包短测中)。
|
||||
- 实际输出:`internal/server` 整包 `ok`,20.400s。用例覆盖回填 6024、保留已有 `"9"`、`SetProjectID(0)` 时不写入。
|
||||
- 判定:PASS
|
||||
- 耗时:见整包短测
|
||||
|
||||
### 用例 2:触发请求携带项目与会话
|
||||
|
||||
- 输入:`go test -count=1 -short ./internal/coordinator/ -run 'TestSyncTriggerTask|TestFormatTriggerTaskReply'`
|
||||
- 实际输出:`internal/coordinator` 整包 `ok`,0.015s。`TestSyncTriggerTask_EnablesAutoRepair` 断言 `ProjectID==9` 且 `SessionID==sess-research`。
|
||||
- 判定:PASS
|
||||
|
||||
### 用例 3:无项目绑定失败关闭,回复不声称入账
|
||||
|
||||
- 输入:`go test -count=1 -short ./internal/bizdev/ -run 'TestExecuteTask|TestTaskRunResult_'`
|
||||
- 实际输出:`internal/bizdev` 整包 `ok`,0.180s。受控键无项目时 `errors.Is` 为 `ErrUnboundControlledProject`。无账本的完成摘要包含「尚未写入受控文档账本」。未绑定项目的同步触发回复为该错误原文,状态 `StatusRejected`。
|
||||
- 判定:PASS
|
||||
|
||||
### 用例 4:三包短测、vet、架构边界
|
||||
|
||||
- 输入:
|
||||
|
||||
```text
|
||||
gofmt -w internal/server/task_run_observer_test.go
|
||||
go test -count=1 -short -timeout 180s ./internal/bizdev/ ./internal/coordinator/ ./internal/server/
|
||||
go vet ./...
|
||||
./scripts/arch-check.sh --mode block
|
||||
```
|
||||
|
||||
- 实际输出:
|
||||
|
||||
```text
|
||||
ok chat-agent-system/internal/bizdev 0.180s
|
||||
ok chat-agent-system/internal/coordinator 0.015s
|
||||
ok chat-agent-system/internal/server 20.400s
|
||||
VET:0
|
||||
arch-check mode=block
|
||||
ok chat-agent-system/internal/archtest 0.194s
|
||||
ok chat-agent-system/internal/archtest 0.191s
|
||||
arch-check block: production gate passed
|
||||
ARCH:0
|
||||
```
|
||||
|
||||
- 判定:PASS
|
||||
- 耗时:三包短测约 23s;vet 与架构检查约 2s。工作目录为任务 worktree。
|
||||
|
||||
说明:`TestTaskRun_DisconnectDoesNotCancelWorker` 曾因 worker 用 `RunRecord.ProjectID` 覆盖请求而失败。测试记录改为 `ProjectID: 1` 后通过。这与线上异步 run 以记录中的项目 ID 为准一致。
|
||||
|
||||
### 用例 5:dev 真实 PI 浏览器链路
|
||||
|
||||
- 输入:在已加载 `f8730791` 的项目会话中对话触发调研报告,核对 `workspace.json` 的 `project_id`、`document_versions` 的 agent_squad 提交,以及刷新后的文档正文。
|
||||
- 实际输出:未运行。当前 dev 的 `bin/agent-server` 早于本提交,主目录 `dev` 尚未合入该提交。
|
||||
- 判定:未运行
|
||||
- 风险:短测证明绑定与失败关闭,不能代替刷新后文档页看到正文。
|
||||
|
||||
## 六、 自动化测试套件汇总 (Test Suite Execution)
|
||||
|
||||
| 检查 | 结果 |
|
||||
|---|---|
|
||||
| `go test -short` `internal/bizdev` `internal/coordinator` `internal/server` | PASS |
|
||||
| `go vet ./...` | PASS |
|
||||
| `./scripts/arch-check.sh --mode block` | PASS |
|
||||
| 产品 PI 浏览器 | 未运行 |
|
||||
|
||||
未跑全仓 `go test -short ./...`。本改动的包与架构门禁已覆盖计划中的回归范围。
|
||||
|
||||
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
|
||||
|
||||
授权内的代码与短测达到任务分支可审终点。合入 local dev 并重载 `agent-server` 之后,仍须用真实 PI 在项目会话触发调研报告,确认工作区 `project_id` 非 0、账本出现 agent_squad 版本,刷新文档页不再只剩模板骨架。
|
||||
|
||||
孤儿工作区 `research_1790576535990100562`、`research_1790585141260333084` 保持 cleanup=pending,不删除。`doc_proj6024_bd_research` 已有带绑定重跑入账,无额外数据修复。
|
||||
Reference in New Issue
Block a user