Progress tracking now lives in a separate project. Drop the server, docs, and module-boundary entries without restoring engineering-dashboard. Co-authored-by: Cursor <cursoragent@cursor.com>
17 KiB
17 KiB
title, status, created, updated, severity
| title | status | created | updated | severity |
|---|---|---|---|---|
| 系统全面体检:任务收口、缺陷与未启用功能审计 | done | 2026-09-17 | 2026-09-17 | high |
系统全面体检(2026-09-17)
范围:① 规划未实现 / 需变更 / 实施中任务;② 现存与潜在 bug;③ 已实现但未启用或未测试的功能。 方法:文档 SSOT 盘点(CURRENT / FEATURE-MATRIX / gap-matrix / short-term / long-term / backlog / ADR / handoff)+ Go 全量 vet/build/test + 前端 test/build + 特性开关与环境配置交叉核对。只读审计,未实施任何修改。 基线验证:
go vet ./...与go build ./...全绿;go test -short -count=1 ./...62 包全 ok;webnpm test(380+32)与 build 通过。
一、任务状态盘点
1.1 实施中(in_progress)
| # | 任务 | 位置 | 剩余工作 |
|---|---|---|---|
| T1 | partial/deferred 全量收口总控 | .doc/ops/short-term/2026-09-16-partial-deferred-completion.md(owner Cline) |
W5(SWBOOT-10 真实现 + 真实 PI + UI 二次验收)、W6(FAV shadow→live 放量)、W7(D7 按 ADR 整改,待合规签字)、逐行升 done |
| T2 | Control Center 个人中控台 | 2026-09-19 已移出本仓库 | 进度管理改由独立项目承担;本仓库不再保留该模块 |
| T3 | 纯软件项目自举 W5b | .doc/ops/long-term/2026-09-14-software-project-bootstrap-implementation.md |
SWBOOT-10 受控执行器(真 patch/merge)未启动,需独立安全评审,当前 fail-closed stub |
1.2 已规划未开始
| # | 任务 | 位置 |
|---|---|---|
| T4 | 首次加载性能 U1/U3–U7 | .doc/remediation/2026-09-17-initial-load-performance-plan.md(仅 U2 done:主 JS 传输 2.82 MB→~624 KB) |
| T5 | 选择性模块解耦 M4–M6 | .doc/ops/long-term/2026-09-14-selective-module-decoupling.md(planned,owner=TBD) |
| T6 | 产品 backlog:B5 报价复核、A5/A6 小队降级与 trace、A7 中文注释迁移、D5 KB 按环境隔离评估 | .doc/backlog/chat-agent-p6-backlog.md(均无任务文件) |
| T7 | TestReconcile_LegacyRepair_PG 工程测试债 |
gap-matrix DOC-CONTENT-CANONICAL-HASH-DRIFT 行(需隔离 PG,本机无) |
| T8 | IAM 收尾开放项:410 退役产品拍板、R13 全量清单勾选 | handoff 2026-09-16-phase3-leftover-closeout.md |
1.3 部分完成(partial,剩余关闭条件)
| 行 | 剩余关闭条件 |
|---|---|
| 纯软件项目自举 | SWBOOT-10 非 stub(W5b)+ 真实 PI 全链路 + UI 二次验收 |
| FAV | W6 shadow 已合;live 未放量(staging→artifact→publication 各 ≥7 天观察窗) |
| Control Center | 2026-09-19 已移出本仓库,不再作为本仓库关闭条件 |
| 首次加载性能 | U1/U3–U7 |
| 文档可靠性试点 | M1 结论「停止扩面」;M2(U5–U12)明确禁止开工,真实 PI/浏览器验收未勾 |
1.4 deferred 待决策
- D7 对话数据治理:ADR
2026-09-17-d7-chat-data-retention.md仍pending-compliance-signoff;W7 盘点未发现违规;签字前禁止物理删除。 SEMANTIC_SUMMARY_REPLACE:决策默认不启用;启用须另开授权 + fail-closed 灰度。MULTI_INTENT_PLAN_TIER升 confirm:W4 证据闭环,升级需独立授权;永不默认 full。
1.5 文档漂移 / 矛盾(文档债)
| # | 漂移 | 涉及文件 |
|---|---|---|
| D-1 | PU8 四份契约文件仍 status: in_progress,但 U9–U12 已升 done、报告已归档 |
.doc/ops/long-term/2026-09-16-pu8-u9/u10/u11/u12-*.md |
| D-2 | ADR modular-monolith-decoupling 仍「提议,等待用户确认」,但 Phase 1/2 已落地并被当作已确认结论引用 | .doc/adr/2026-09-14-modular-monolith-decoupling.md |
| D-3 | audit/INDEX.md 与 remediation/INDEX.md 末行称首次加载性能「方案未实施」,与 U2 已验收矛盾 | 两个 INDEX.md(本审计已顺手修正为准确表述) |
| D-4 | handoff 2026-09-15-conversation-intent-dual-tab.md 的「未完成」已被后续 PASS 覆盖但未回标 |
该 handoff |
| D-5 | backlog D3/D7 条目与 W2 done、W7/ADR 草案并存,backlog 未同步 | .doc/backlog/chat-agent-p6-backlog.md |
| D-6 | PROJECT.md §9「剩余 blocker」表述与 gap-matrix「门禁已签、production_ready=yes」口径冲突 | PROJECT.md |
二、Bug 清单
2.1 确认 bug(有明确证据)
后端
| ID | 描述 | 证据 | 严重度 |
|---|---|---|---|
| B-1 | SSE 聊天流被全局 WriteTimeout=120s 强杀:server.go:350 的 WriteTimeout 是绝对期限;handleChatStream(sse.go:129)从不调用 extendSSEWriteDeadline、无心跳,该机制只接到了 run-events 订阅端点。任何 >120s 的聊天回合(长 PI 推演常见)必断流 |
internal/server/server.go:350、internal/server/sse.go:46-64,129 |
high |
| B-2 | POST /tasks/run/stream 同样无 deadline 延长/心跳,且断线后无法续订:sse.go:390 写死 Subscribe(created.RunID, 0),不接受 after_seq |
internal/server/sse.go:305-424,390 |
high |
| B-3 | handleRunTaskStream 静默吞 JSON 解析错误:_ = json.NewDecoder(r.Body).Decode(&req),畸形 body 以空请求走默认 TaskKey="intake",可能误启动 intake 任务 |
internal/server/sse.go:315,362-364 |
medium |
| B-4 | handleRunTaskStream Flush 200 SSE 头之后才做会失败的操作(CreateAndStart/Subscribe),失败时往 SSE 流里写 JSON 错误体;同文件 chat 路径明确「授权必须在 Flush 前」,task 路径未对齐 |
internal/server/sse.go:355-360,383-393 |
medium |
前端
| ID | 描述 | 证据 | 严重度 |
|---|---|---|---|
| B-5 | 会话窗口缓存 key 不一致:读/初次写带 userId 前缀,但 loadOlder/loadFullDay/jumpToDate/loadDayForAnchor/appendLiveMessage 等 7 处后续写入不带前缀 → 刷新/切会话恢复到旧窗口;且 LRU 驱逐只用无前缀 key,带前缀缓存永不驱逐,localStorage 只增不减 |
web/src/hooks/useChatWindow.ts:84,100,136,235,271,315,365,416,439,471、web/src/data/storage.ts:164-176 |
high |
| B-6 | mount 时 IndexedDB 恢复用陈旧快照整体覆盖 deliverables:捕获 mount 闭包、非函数式 set,resolve 前新增的 deliverable 被静默丢弃(旁边已有 deliverablesRef 未用) |
web/src/App.tsx:326-336 |
medium |
| B-7 | useTaskRunStream 返回伪 ref(每渲染新建对象、快照值非 live),且全仓库无消费方——误导性 API |
web/src/hooks/useTaskRunStream.ts:96 |
low |
2.2 高风险隐患
| ID | 描述 | 证据 |
|---|---|---|
| R-1 | 聊天会话无归属校验:getOrCreateSession 仅凭客户端传入 session_id 返回既有内存会话,随后直接覆盖 sess.UserID;非项目会话(ProjectID==0)无任何授权关卡,内存 Messages/Facts 可进入他人 Prompt 与 SSE。缓解:session ID 为纳秒时间戳不易猜 |
internal/server/server.go:394-415、handlers.go:181、sse.go:187、stage_access_helpers.go:251-253 |
| R-2 | 18 个非测试文件 rows.Next() 循环后未查 rows.Err(),中途断连静默截断结果集(ctxmgr 历史/窗口/搜索、docgov engine、freedoc、storage/cas、cmd/document-content-reconcile 漏检会让 reconcile 漏报文档) |
如 internal/ctxmgr/chat_history.go、internal/docgov/engine.go、cmd/document-content-reconcile/main.go:82 |
| R-3 | 事件 dispatcher Handlers map 写持锁、读不持锁(当前仅启动期注册则良性,动态注册即 race) |
internal/events/worker.go:87,154,234 |
| R-4 | memTurns 全局幂等表只增不删且跨实例共享,长期运行内存缓增、测试间可能串扰 |
internal/ctxmgr/chat_turns.go:169 |
| R-5 | internal/docrevision/pg_store.go:68-208 十余处 _ = json.Unmarshal(...),账本 JSONB 损坏时静默零值化 |
同左 |
| R-6 | 后台 ticker goroutine 无关停通道(通知提醒、vault Drain 错误被丢弃、bizdev 心跳用 context.Background()),Shutdown 未覆盖 |
notification_reminder_loop.go:15、vault.go:63、bizdev/service.go:682 |
| R-7 | SSE 重连对 401/404 无 fail-fast:任何错误一律退避重连 40 次(~3 分钟)期间 UI 一直 thinking;streamChat 对畸形 data 帧直接抛错中断整条流 |
web/src/api/taskRuns.ts:108-140、api/chatStream.ts:122 |
| R-8 | 组件卸载/登出不 abort 任务流,在途 SSE 继续写 localStorage | web/src/App.tsx:595,2804 |
2.3 环境 / 配置缺陷
| ID | 描述 | 证据 | 严重度 |
|---|---|---|---|
| E-1 | main 环境 app ENV=prod 与 events ENV=main 不一致:事件信封以 Environment="prod" 写入,而 event_consumer_modes 只种子 dev/test/main 三行 → app 侧 WriterLive("prod") 恒 false(in-process 直连不退出),events worker 按 'main' 判定 → main 存在双写或 durable 管道空转风险(取决于 main 行 mode)。dev/test 两服务 ENV 一致,无此问题 |
docker-compose.main.yml:90,160、internal/app/docflow/commands.go:276、goose/00040:55-59、internal/events/dispatcher.go:308-313 |
critical(main 专属) |
| E-2 | main schema 落后两版(47 vs dev 49):00048 给 projects 加 13 列,当前 HEAD 代码直接 SELECT/INSERT 这些列;00049 建 system_settings。若把 dev HEAD 镜像升 main 而不先跑迁移,项目工作流查询/系统设置 API 直接 SQL 报错。main 晋升顺序必须 events(跑迁移)先于 app | goose/00048、goose/00049、internal/projectworkflow/store.go:76,113 |
high(晋升窗口) |
| E-3 | MULTI_INTENT_PLAN_TIER 未在任何 compose environment 声明(configs/.env 设了也传不进容器);test/main 连 U9–U12 flag 都未声明 → 容器内锁死 legacy,授权升级时需先改 compose |
docker-compose.*.yml |
medium |
| E-4 | CURSOR_RUNNER_URL 三环境 compose 都注入但代码零读取;cursor-agent 容器是 alpine 占位,cursor-cli 后端容器部署不可达 |
docker-compose.*.yml |
low |
| E-5 | ENABLE_DEV_IMPORT 不在任何 compose/.env.example;且判断把 cfg.Env=="" 也算 dev——配置缺失时导入门禁自动放开 |
internal/server/chat_window_api.go:171 |
medium |
| E-6 | SEED_DEMO_USERS 仅 test compose 显式 false;dev 依赖默认播种(demo 密码 123456),main 靠代码 Env!="dev/test" 兜底,主 compose 未显式关闭 |
docker-compose.test.yml:91、internal/auth/bootstrap.go:67-116 |
low |
| E-7 | INTENT_V2_DECISION_TIER 非法值回退 query(激进),与 MULTI_INTENT_PLAN_TIER 回退 legacy(保守)策略不一致 |
internal/intent/flags.go:47-64 |
low |
| E-8 | publisher_gate_test.go:16 读 FAV_PUBLISHER_ENABLE(少 D),与正式变量名不符,该测试门永远走默认分支 |
internal/artifactvault/publisher_gate_test.go:16 |
low |
| E-9 | main compose 的 system-db initdb 只挂 00001_baseline.sql,与 dev/test 不一致;新建卷时初始脚本漂移(依赖 events 启动迁移补齐) | docker-compose.main.yml:23 |
low |
三、已实现但未启用 / 未测试的功能
3.1 特性开关封存(实现完整,全环境 off)
| 功能 | 实现位置 | 状态与门禁 |
|---|---|---|
| FAV 事件订阅者 | internal/app/fav/subscriber.go |
三重硬门禁:cmd/events 刻意不注册、registry fail-closed、SetMode 拒绝非 off;仅 ObserveShadow 可达 |
| FAV 发布器 | internal/server/vault.go:18-67 |
FAV_PUBLISHER_ENABLED=false 三环境显式;且 VAULT_* 三变量 compose 全未声明,容器内即使开 flag 也会静默 return(E-类:实际不可误开,属设计内封存) |
| FAV 降级读 | internal/docquery/service.go:70 |
FAV_DEGRADED_READ=false 红线保持 |
| 多意图 PlanTier shadow/auto_read/confirm | internal/app/intentflow/turn.go |
容器内锁死 legacy(见 E-3) |
| U9–U12 扩面 | intentflow/expansion.go、mux.go |
全 false;dev compose 已声明可调,test/main 未声明 |
| 意图 V2 shadow/decision | internal/intent/shadow_v2.go、v2_decision.go |
三环境显式 false |
| 语义摘要 shadow | internal/ctxmgr/semantic_summary.go:216 |
默认 off,且仅 AGENT_BACKEND=pi-agent 时挂载 |
| PI change-report 叙事 | internal/docrevision/narrative.go:68 |
默认 off,仅确定性 fallback(不得冒充完整 PI) |
| artifact-vault CLI | cmd/artifact-vault/main.go |
未部署 stub |
| eventmode cutover CLI | cmd/eventmode/main.go |
硬门禁仅 dev 可用(internal/events/cutover.go:13) |
3.2 死代码 / 机制先行无消费方
| # | 项 | 位置 |
|---|---|---|
| X-1 | SEMANTIC_FALLBACK_ENABLED 死 flag:无任何业务消费方,仅 sysadmin 展示;三环境 compose 都在设一个没用的变量 |
internal/intent/flags.go:43、internal/app/app.go:285 |
| X-2 | SEMANTIC_SUMMARY_REPLACE 读取后 _= 显式丢弃,刻意永久未接线 |
internal/ctxmgr/semantic_summary.go:257 |
| X-3 | goose 00048 三张新表 project_source_bindings/repo_path_allowlist/project_type_workflows 无代码消费方(swboot 目录硬编码内存版,RepoAllowlist 为 stub) |
internal/swboot/catalog.go:92,118、repo_allowlist.go |
| X-4 | system_settings 白名单 6 键全部无业务消费方——可写不生效,纯机制先行 |
internal/sysadmin/settings.go:57-66 |
| X-5 | 前端死组件:DocumentNotificationList.tsx(含已读回写,功能完整无挂载点)、WorkflowPrerequisiteBanner.tsx、user/SettingsModal.tsx(已被 UserSettingsModal 取代);死 API:api/projectWorkflow.ts:71 activateWorkflow;data/storage.ts:141 saveMessages deprecated no-op |
web/src 各文件 |
| X-6 | useTaskRunStream 伪 ref(同 B-7) |
— |
3.3 测试盲区
| # | 盲区 | 说明 |
|---|---|---|
| S-1 | TestReconcile_LegacyRepair_PG 从未执行 |
要求隔离 PG 且硬拒绝 5433/5434/5435;canonical-hash 修复链路零自动化验证(gap-matrix 已记测试债) |
| S-2 | 两个「永久跳过」 | taskstream_test.go:189(功能已删,测试成死代码应删除);plan_owner_test.go:125(重定向跳过) |
| S-3 | 无测试的 cmd 入口 | cmd/server、cmd/events、cmd/artifact-vault、cmd/dataset、cmd/eventmode、cmd/recategorize、cmd/document-revision-backfill(仅 bizdev-cli、document-content-reconcile 有);internal/observability、internal/workflow 无测试文件 |
| S-4 | E2E 默认全不跑:web/e2e 9 个 spec 全部被环境门禁(RUN_UI_ACCEPTANCE=1/DOCREV_E2E_BASE_URL/INTENT_DUAL_TAB=1),默认 playwright test 实跑 0 用例;test:ui-acceptance script 只覆盖 1 个 spec,其余 8 个无 script 入口 |
web/e2e/、web/package.json:11 |
| S-5 | 409 信封处理只覆盖部分消费方:projectMembers、freeformDoc、createTaskRun、chatSessions upsert 等 409 只能裸报错(与 FEATURE-MATRIX hardening backlog 一致) | web/src/api/projectMembers.ts、freeformDoc.ts:177、taskRuns.ts、chatSessions.ts |
| S-6 | 前端 bundle 大 chunk 未分割(mermaid/katex/xlsx/docx 各成 >500 kB chunk,已有 precompress 缓解) | vite build 警告 |
四、结论与优先级
总体判断:发布门禁与 FEATURE-MATRIX 的 done/partial/deferred 口径与代码实况基本一致,未发现「stub 冒充验收」类违规;质量门禁(vet/test/build)全绿。主要风险集中在三处:
- E-1(main ENV 不一致 → 双写/空转)是唯一 critical 级发现,且只在 main 环境存在, dev/test 的「healthy」不能证明 main 事件链路正确。
- SSE 120s 断流(B-1/B-2)直接影响长任务可用性,是用户可感知的现存 bug。
- 封存面(FAV/多意图 tier/U9–U12/语义摘要/PI 叙事)实现完整但容器内不可调或硬门禁封存,红线达标,但授权放量时会发现 compose 层缺失(E-3)与若干死接线(X-1/X-2)。
详细整改顺序见 remediation 方案。
关联整改
- Remediation: 2026-09-17-system-health-remediation-plan.md
证据
go vet ./.../go build ./.../go test -short -count=1 ./...(62 包 ok)/cd web && npm test && npm run build:2026-09-17 全绿。- 文中所有
文件:行号引用均为 2026-09-17 dev 分支工作区实测。
开放问题
- E-1 的修复取向(app 改
ENV=mainvs 事件信封/consumer mode 键改用部署名)需架构决策。 - D7 合规签字、
MULTI_INTENT_PLAN_TIER升 confirm、FAV live 放量均需用户显式授权,不在本整改自动范围内。 - configs/.env.dev/.env.test/.env.main 实际文件未读取(含密钥);若偏离 example 模板,E-3/E-4/E-6 结论需复核。