Commit babc58d36b57c5a0b82345836f7d6e4552d89422

Authored by graphlemon
1 parent 0d7a045a

graphlemon: brd artifact for task 773a7a08-b295-4ba3-b506-196a21403d8b

.graphlemon/runs/773a7a08-b295-4ba3-b506-196a21403d8b/brd.md 0 → 100644
  1 +# BRD:修复"Planner 产出总览"面板文件/代码列表点击无反应的 Bug
  2 +
  3 +> 依据 SOUL.md §16,本 Agent 不直接改写 `task.status`,仅产出本 BRD Artifact 供 `c_org_node_trigger`/`c_org_loop_route` 判定流转。以下事实均来自对当前代码(非文档)的直接读取:`frontend/app.js`、`frontend/style.css`、`frontend/test_graph_console_smoke.js`、`src/artifact_query.py`、`src/artifact_write.py`、`src/backend_server.py`、`docs/sdd/02-V-界面与交互.md`。
  4 +
  5 +## 0. 文档信息
  6 +
  7 +- 触发来源:用户报告的可复现 UI Bug + 用户已给出的确认根因(本 BRD 对根因做了独立交叉验证,见 1.2)。
  8 +- 覆盖实体/接口:V=`v_graph_console`(`#/graph`,"Planner 产出总览"面板,2026-08-03 加入,无独立 SDD 文档条目,`docs/sdd/02-V-界面与交互.md`未记录此面板——见 1.3 的文档缺口说明)复用 V=`v_artifact_browser`(`docs/sdd/02-V-界面与交互.md` §2.8);C=`c_artifact_get`(`GET /api/artifacts/:artifact_id`,`src/artifact_query.py:49-71`,本次**不修改**。
  9 +- 类型:Bug 修复(交互缺陷,根因单一),非新特性、非重新设计。
  10 +- 风险等级:低(纯前端 `frontend/app.js` 改动,无权限/支付/数据不可逆变更;无需触碰后端 API 或数据库 schema)。
  11 +- 状态机备注:本文档为 `task` 生命周期中 `planning_brd_prd_sdd` 阶段产出的 BRD Artifact,不代表任务已完成;状态流转由 `c_org_node_trigger`/`c_org_loop_route` 依据 BRD/PRD/SDD/Benchmark 判定。
  12 +
  13 +## 1. 背景与问题陈述
  14 +
  15 +### 1.1 用户可观察的症状
  16 +
  17 +控制台 Graph 页面(`#/graph`)"Planner 产出总览"面板中,"文档列表(brd/prd/sdd/benchmark)"和"代码列表(code_diff/test_report)"两个子列表里的每一项,点击后没有任何反应——用户预期点击后能跳转到该 artifact 的详情/内容页面,实际什么都不发生。
  18 +
  19 +### 1.2 根因(已通过直接读取生产代码交叉验证,非仅采信用户描述)
  20 +
  21 +- `renderArtifactSummaryList()`(`frontend/app.js:1344-1351`)目前渲染出的每个 `<li>` 只包含两个 `<span>` 文本节点,**没有任何 `data-*` 属性,也没有绑定任何点击行为**。已确认用户给出的根因描述准确无误。
  22 +- 对照组:同一挂载函数 `mountArtifactsOverviewPanel()`(1359-1400 行)里的"Graph 运行历史"列表(`gc_runs_list`)已正确实现"数据带 id + 点击跳转"模式(`data-run-task-id` + `querySelectorAll`/`addEventListener` 绑定),证明面板内已有可复用实现模式,问题范围严格限定在 `renderArtifactSummaryList()` 及其调用方。
  23 +- 数据侧确认:`list_artifacts()`(`src/artifact_query.py:22-46`)返回对象已带 `artifact_id`(不含 `/`,可安全嵌入 URL hash)。
  24 +- 已有可复用跳转机制:`v_artifact_browser`(`#/artifacts`,`frontend/app.js:1560-1654`)已完整实现"选中 artifact → 拉取 `GET /api/artifacts/:artifact_id` → 展示血缘链 + 内容预览",工作正常,不应重建并行逻辑。
  25 +- 路由层现状:`render()`(77-132 行)只支持精确匹配表和两个正则动态路由(`TASK_DETAIL_RE`/`SKILL_AUDIT_RE`),`#/artifacts` 目前没有携带具体 id 的动态子路由。
  26 +
  27 +### 1.3 相关文档缺口(供 Validator 知悉,非本次修复范围)
  28 +
  29 +"Planner 产出总览"面板未被 `docs/sdd/02-V-界面与交互.md`/`docs/development-plan.md` 记录(与 CLAUDE.md "Status" 一节所述现象一致)。本 BRD 以代码本身为事实来源,不在本次范围内补写缺失文档。
  30 +
  31 +## 2. 目标与非目标
  32 +
  33 +### 2.1 目标
  34 +- **G1**:文档/代码列表每项带真实 `artifact_id`,点击可跳转,视觉提示与"Graph 运行历史"一致。
  35 +- **G2**:跳转后精确展示被点击 artifact 的真实内容(复用 `v_artifact_browser` 预览面板),不是空白/默认最新一条。
  36 +- **G3**:两个"查看全部"链接继续跳到未过滤 `#/artifacts`,行为不变。
  37 +- **G4**:不重新实现内容展示逻辑,只接入既有机制。
  38 +
  39 +### 2.2 非目标
  40 +不修改 `src/artifact_query.py`/后端 API;不修改 `showPreview()` 内部逻辑;不改变"查看全部"行为或补充过滤参数;不处理"任务列表"子块点击(范围外,记录为后续跟进项);不改动"Graph 运行历史"现有实现;不引入新依赖/构建步骤。
  41 +
  42 +## 3. 事实 / 设计决策 / 假设 / 未知
  43 +
  44 +### 3.1 已知事实
  45 +- `renderArtifactSummaryList()` 无 `data-*`/事件绑定;`artifacts` 已含 `artifact_id`(UUID,`src/artifact_write.py:68`)。
  46 +- `render()` 无查询字符串解析能力;`#/tasks/:id`、`#/skills/:id/audit` 是"列表+id 动态子路由"的两个成熟先例。
  47 +- `mountArtifactBrowser()` 的 `refreshList()`(1638-1642 行)已有"若 `selectedArtifactId` 存在则 `showPreview()`,否则默认第一条"逻辑,可直接复用于"外部带初始 id 进入"场景。
  48 +- `.artifact-list li` 已有 `cursor:pointer`/`:hover`/`.active` 样式;`.simple-list li` 没有。
  49 +- `frontend/test_graph_console_smoke.js` 现有 fixture(116-120 行)不含 `artifact_id`,若不同步更新会造成"测试通过但未测到关键改动"的假阳性。
  50 +
  51 +### 3.2 设计决策
  52 +- **D1**:新增动态路由 `#/artifacts/:artifact_id`(沿用既有正则动态路由模式),不引入查询字符串解析。
  53 +- **D2**:`mountArtifactBrowser()` 新增可选形参 `artifactId`,有值时预置 `selectedArtifactId`,复用既有"保持选中项"逻辑触发 `showPreview()`。
  54 +- **D3**:`renderArtifactSummaryList()` 输出 `data-artifact-id` + 可点击视觉提示;事件绑定放在 `mountArtifactsOverviewPanel()` 里 `innerHTML` 赋值之后,与 `gc_runs_list` 现有模式一致(不用内联 `onclick`)。
  55 +- **D4**:跳转 URL 对 `artifact_id` 做 `encodeURIComponent()`,与 `showPreview()` 现有写法一致。
  56 +
  57 +### 3.3 待验证假设
  58 +无实质性待验证假设,根因/数据/可复用机制/路由边界均已通过读代码确认。
  59 +
  60 +### 3.4 阻塞性未知
  61 +无。可直接进入开发。
  62 +
  63 +## 4. 范围
  64 +
  65 +### 4.1 范围内文件
  66 +- `frontend/app.js`:`renderArtifactSummaryList()`、`mountArtifactsOverviewPanel()`、`routes`/动态路由区(新增 `ARTIFACT_DETAIL_RE`)、`mountArtifactBrowser()`(新增可选形参)。
  67 +- `frontend/test_graph_console_smoke.js`:更新 fixture + 断言。
  68 +- `frontend/style.css`(视实现选择,非必须)。
  69 +
  70 +### 4.2 明确排除
  71 +`src/artifact_query.py`、`src/backend_server.py`、`src/artifact_write.py`;`showPreview()` 内部逻辑;"查看全部"行为;"任务列表"点击;"Graph 运行历史"现有实现;后端测试套件(应保持全绿但无需新增用例)。
  72 +
  73 +## 5. 验收标准
  74 +
  75 +### 5.1 自动化测试证据
  76 +- `node frontend/test_graph_console_smoke.js`:fixture 含 `artifact_id`,断言输出含精确匹配的 `data-artifact-id`;"查看全部"仍渲染为无 id/无查询参数的普通链接;现有断言全部继续通过。
  77 +- `python3 -m unittest discover -s src` 全量通过(回归基线,未改后端代码)。
  78 +
  79 +### 5.2 真实浏览器验证证据(人工,本仓库前端既有约定)
  80 +1. `#/graph` 面板列表项呈现可点击视觉提示。
  81 +2. 点击文档列表项,hash 变为 `#/artifacts/<真实 artifact_id>`,切换到 Artifact 浏览器。
  82 +3. 预览面板精确展示被点击 artifact 的真实内容,对应 `<li>` 呈现 `.active` 高亮。
  83 +4. 代码列表(`code_diff`/`test_report`)重复验证。
  84 +5. 两个"查看全部"仍跳到未过滤 `#/artifacts`。
  85 +6. 直接在地址栏输入 `#/artifacts/<id>` 能独立正确加载(不依赖前置点击状态)。
  86 +
  87 +### 5.3 边界场景证据
  88 +磁盘文件缺失时预览面板展示"(文件不可用)"文案(既有逻辑),不崩溃。
  89 +
  90 +## 6. 风险与依赖
  91 +- R1(低):`mountArtifactBrowser` 新增可选形参需保证 `artifactId` 为 `undefined` 时默认行为逐字节不变。
  92 +- R2(低):fixture 更新遗漏 `artifact_id` 会造成假阳性测试,需人工确认断言做了精确值匹配。
  93 +- R3(可忽略):D4 已给出防御性 encode 写法。
  94 +- 依赖:无外部依赖,无环;复用组件均已验证可工作。
  95 +
  96 +## 7. 可追溯性矩阵
  97 +
  98 +| 原始要求 | 责任范围 | 验收锚点 |
  99 +|---|---|---|
  100 +| 每项加真实 `artifact_id` + 点击跳转 | `renderArtifactSummaryList()` + `mountArtifactsOverviewPanel()` 绑定 | 5.1 + 5.2.1/5.2.2 |
  101 +| 跳转需定位到具体 artifact 详情视图 | 新增 `#/artifacts/:artifact_id` 路由(D1)+ 预置 `selectedArtifactId`(D2) | 5.2.2/5.2.6 |
  102 +| 跳转后展示真实内容,非空白/默认全量 | 复用既有 `showPreview`/`selectedArtifactId` 逻辑 | 5.2.3/5.2.4 + 5.3 |
  103 +| "查看全部"行为不变 | 不改动现有 `<a>` 标签 | 5.1 + 5.2.5 |
  104 +| 复用现有内容预览机制,不重建 | D1-D4 均基于复用 | 4.2 + 2.1 G4 |
  105 +| 不修改 `c_artifact_get`/`v_artifact_browser` 本身 | 4.2 排除后端与预览内部实现 | 4.2 |
  106 +
  107 +## 8. PL 自审
  108 +- [x] 根因有明确代码来源(1.2)
  109 +- [x] 事实/决策/假设/未知已分列(第 3 节)
  110 +- [x] 范围清晰,显式排除相邻蔓延项(2.2、4.2)
  111 +- [x] 验收标准可测试、描述可观察结果(5.1/5.2)
  112 +- [x] 已识别"测试通不到真改动"的假阳性风险(3.1、R2)
  113 +- [x] 依赖无环(第 6 节)
  114 +- [x] 原始要求均在追溯矩阵中有责任方与验收锚点(第 7 节)
  115 +- [x] 无需更深调查,风险等级低,可直接进入开发
  116 +
  117 +**判定:可以流转到开发(Code Agent)**,无阻塞性未知,范围与验收标准明确。后续 SDD 应给出 `ARTIFACT_DETAIL_RE` 具体正则、函数签名与 CSS class 命名,BRD 本身不预锁实现细节。
0 118 \ No newline at end of file
... ...