dsh-plugin-teamflow 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/host.mjs CHANGED
@@ -3293,10 +3293,14 @@ const simpleRender = (args, value) => [{
3293
3293
  text: JSON.stringify(value, null, 2).slice(0, 4e3)
3294
3294
  }];
3295
3295
  function registerTools(ctx) {
3296
- const T = (tool) => ctx.tools.register({
3297
- ...tool,
3298
- parameters: parameterSchemaSpecToJsonSchema(tool.parameters)
3299
- });
3296
+ let registeredCount = 0;
3297
+ const T = (tool) => {
3298
+ registeredCount++;
3299
+ return ctx.tools.register({
3300
+ ...tool,
3301
+ parameters: parameterSchemaSpecToJsonSchema(tool.parameters)
3302
+ });
3303
+ };
3300
3304
  T({
3301
3305
  name: "teamflow_start",
3302
3306
  description: "Start the team R&D pipeline (background async): runs the stages per team config (PRD→design→tech→dev→QA→acceptance). Specify teamId (matches teams.json) or pick a team via the UI \"+\" button first so messages auto-match. Stage failures auto-retry; beyond threshold → rework/human intervention; per-stage token usage recorded. NOTE: after calling, the implementation work is done by pipeline subagents — the main thread MUST NOT write code or run verifications for it. requirement must be a faithful transcription of the user's words; do not invent file paths / tech claims without code verification (downstream stages build the PRD from it).",
@@ -3734,6 +3738,7 @@ function registerTools(ctx) {
3734
3738
  return resumeRun(args && typeof args.runId === "string" ? args.runId : null, parent.session.id);
3735
3739
  }
3736
3740
  });
3741
+ return registeredCount;
3737
3742
  }
3738
3743
  /** 会话级暂停标记:pausedSessions.has(sessionId) → 该会话的 teamflow_start 被拦截。 */
3739
3744
  const pausedSessions = /* @__PURE__ */ new Set();
@@ -3798,8 +3803,8 @@ var TeamflowService = class extends TypertRemoteService {
3798
3803
  },
3799
3804
  invocations: TEAMFLOW_DESCRIPTORS
3800
3805
  });
3801
- registerTools(ctx);
3802
- console.log(`[teamflow] host 就绪:backlog 根 ${teamflowRoot()},Remote ${TEAMFLOW_DESCRIPTORS.length} 个,工具 8 个${interruptedCount > 0 ? `,⚠ 发现 ${interruptedCount} 条中断的流水线(可用 teamflow_resume 从断点重跑)` : ""}`);
3806
+ const modelTools = registerTools(ctx);
3807
+ console.log(`[teamflow] host 就绪:backlog 根 ${teamflowRoot()},Remote ${TEAMFLOW_DESCRIPTORS.length} 个,工具 ${modelTools} 个${interruptedCount > 0 ? `,⚠ 发现 ${interruptedCount} 条中断的流水线(可用 teamflow_resume 从断点重跑)` : ""}`);
3803
3808
  }
3804
3809
  ping() {
3805
3810
  return { ok: true };
@@ -4143,5 +4148,3 @@ var TeamflowService = class extends TypertRemoteService {
4143
4148
  };
4144
4149
  //#endregion
4145
4150
  export { TeamflowService, TeamflowService as default };
4146
-
4147
- //# sourceMappingURL=host.mjs.map
package/lib/store.mjs CHANGED
@@ -254,5 +254,3 @@ function loadJournals() {
254
254
  }
255
255
  //#endregion
256
256
  export { STAGE_OUTPUT_CLIP, dshHome, fileFor, journalFile, loadJournals, persistJournal, persistRunLog, productDir, readJson, readJsonAny, runLogFile, runsDir, serializeJournal, slugPath, teamflowRoot, workspaceDir, writeJson, writeText };
257
-
258
- //# sourceMappingURL=store.mjs.map
package/package.json CHANGED
@@ -1,68 +1,97 @@
1
- {
2
- "name": "dsh-plugin-teamflow",
3
- "version": "0.1.0",
4
- "description": "TeamFlow 团队研发流水线(TypeScript):需求→PRD→设计→架构→技术方案→并行开发→QA→验收;backlog 持久化 + 断点续跑 + 完成汇报 + 防假交付;Web 团队工作台(conversation.view tab + 拖拽看板)",
5
- "type": "module",
6
- "main": "./lib/host.mjs",
7
- "exports": {
8
- ".": "./lib/host.mjs",
9
- "./host": "./lib/host.mjs",
10
- "./client": "./lib/client.js",
11
- "./store": "./lib/store.mjs",
12
- "./descriptors": "./lib/descriptors.mjs",
13
- "./package.json": "./package.json"
14
- },
15
- "engines": {
16
- "node": ">=22.18"
17
- },
18
- "dsh": {
19
- "bundle": {
20
- "patch": "./cordis.patch.yml"
21
- },
22
- "client": {
23
- "platform": "web",
24
- "inject": [
25
- "@deepseek-ai/dsh-client-locale",
26
- "@deepseek-ai/dsh-client-runtime",
27
- "@deepseek-ai/dsh-client-ui-conversation"
28
- ],
29
- "immediately": false
30
- }
31
- },
32
- "scripts": {
33
- "bundle": "tsdown && tsdown -c tsdown.host.config.ts",
34
- "bundle:host": "tsdown -c tsdown.host.config.ts",
35
- "bundle:client": "tsdown",
36
- "watch": "tsdown --watch",
37
- "deploy": "node deploy.mjs",
38
- "typecheck": "tsc --noEmit",
39
- "test": "node test/smoke.js && node test/verdict.test.js && node test/stages.test.js && node test/journal.test.js",
40
- "prepublishOnly": "npx tsdown && npx tsdown -c tsdown.host.config.ts && node test/smoke.js && node test/verdict.test.js && node test/stages.test.js && node test/journal.test.js"
41
- },
42
- "files": [
43
- "lib",
44
- "cordis.patch.yml",
45
- "README.md",
46
- "AGENTS.md",
47
- "docs/adr"
48
- ],
49
- "dependencies": {
50
- "react": "^18.2.0"
51
- },
52
- "devDependencies": {
53
- "@types/node": "^26.2.0",
54
- "@types/react": "^18.3.31",
55
- "tsdown": "^0.22.2",
56
- "typescript": "^6.0.3"
57
- },
58
- "peerDependencies": {
59
- "@deepseek-ai/dsh-base": "*",
60
- "@deepseek-ai/dsh-client-locale": "*",
61
- "@deepseek-ai/dsh-client-runtime": "*",
62
- "@deepseek-ai/dsh-client-ui-conversation": "*",
63
- "@deepseek-ai/dsh-llm": "*",
64
- "@deepseek-ai/dsh-tools": "*",
65
- "@deepseek-ai/dsh-typert-protocol": "*"
66
- },
67
- "license": "MIT"
68
- }
1
+ {
2
+ "name": "dsh-plugin-teamflow",
3
+ "version": "0.1.2",
4
+ "description": "TeamFlow 团队研发流水线(TypeScript):需求→PRD→设计→架构→技术方案→并行开发→QA→验收;backlog 持久化 + 断点续跑 + 完成汇报 + 防假交付;Web 团队工作台(conversation.view tab + 拖拽看板)",
5
+ "type": "module",
6
+ "main": "./lib/host.mjs",
7
+ "exports": {
8
+ ".": "./lib/host.mjs",
9
+ "./host": "./lib/host.mjs",
10
+ "./client": "./lib/client.js",
11
+ "./store": "./lib/store.mjs",
12
+ "./descriptors": "./lib/descriptors.mjs",
13
+ "./package.json": "./package.json"
14
+ },
15
+ "engines": {
16
+ "node": ">=22.18"
17
+ },
18
+ "dsh": {
19
+ "bundle": {
20
+ "patch": "./cordis.patch.yml"
21
+ },
22
+ "client": {
23
+ "platform": "web",
24
+ "inject": [
25
+ "@deepseek-ai/dsh-client-locale",
26
+ "@deepseek-ai/dsh-client-runtime",
27
+ "@deepseek-ai/dsh-client-ui-conversation"
28
+ ],
29
+ "immediately": false
30
+ }
31
+ },
32
+ "scripts": {
33
+ "bundle": "tsdown && tsdown -c tsdown.host.config.ts",
34
+ "bundle:host": "tsdown -c tsdown.host.config.ts",
35
+ "bundle:client": "tsdown",
36
+ "watch": "tsdown --watch",
37
+ "deploy": "node deploy.mjs",
38
+ "typecheck": "tsc --noEmit",
39
+ "test": "node test/smoke.js && node test/verdict.test.js && node test/stages.test.js && node test/journal.test.js",
40
+ "prepublishOnly": "npx tsdown && npx tsdown -c tsdown.host.config.ts && node test/smoke.js && node test/verdict.test.js && node test/stages.test.js && node test/journal.test.js"
41
+ },
42
+ "files": [
43
+ "lib",
44
+ "cordis.patch.yml",
45
+ "README.md",
46
+ "README.en.md",
47
+ "CHANGELOG.md"
48
+ ],
49
+ "keywords": [
50
+ "dsh",
51
+ "deepseek-harness",
52
+ "plugin",
53
+ "teamflow",
54
+ "multi-agent",
55
+ "pipeline",
56
+ "agent-team",
57
+ "llm-agent",
58
+ "kanban",
59
+ "coding-agent"
60
+ ],
61
+ "dependencies": {},
62
+ "devDependencies": {
63
+ "@types/node": "^26.2.0",
64
+ "@types/react": "^18.3.31",
65
+ "tsdown": "^0.22.2",
66
+ "typescript": "^6.0.3"
67
+ },
68
+ "peerDependencies": {
69
+ "react": "^18.2.0",
70
+ "@deepseek-ai/dsh-base": "*",
71
+ "@deepseek-ai/dsh-client-locale": "*",
72
+ "@deepseek-ai/dsh-client-runtime": "*",
73
+ "@deepseek-ai/dsh-client-ui-conversation": "*",
74
+ "@deepseek-ai/dsh-llm": "*",
75
+ "@deepseek-ai/dsh-tools": "*",
76
+ "@deepseek-ai/dsh-typert-protocol": "*"
77
+ },
78
+ "peerDependenciesMeta": {
79
+ "@deepseek-ai/dsh-base": { "optional": true },
80
+ "@deepseek-ai/dsh-client-locale": { "optional": true },
81
+ "@deepseek-ai/dsh-client-runtime": { "optional": true },
82
+ "@deepseek-ai/dsh-client-ui-conversation": { "optional": true },
83
+ "@deepseek-ai/dsh-llm": { "optional": true },
84
+ "@deepseek-ai/dsh-tools": { "optional": true },
85
+ "@deepseek-ai/dsh-typert-protocol": { "optional": true },
86
+ "react": { "optional": true }
87
+ },
88
+ "license": "MIT",
89
+ "repository": {
90
+ "type": "git",
91
+ "url": "https://github.com/MichaelShii/dsh-plugin-teamflow.git"
92
+ },
93
+ "homepage": "https://github.com/MichaelShii/dsh-plugin-teamflow",
94
+ "bugs": {
95
+ "url": "https://github.com/MichaelShii/dsh-plugin-teamflow/issues"
96
+ }
97
+ }
package/AGENTS.md DELETED
@@ -1,108 +0,0 @@
1
- # AGENTS.md — TeamFlow 插件开发守则与产品记忆锚点(dsh-plugin-teamflow)
2
-
3
- > **任何加入本插件开发的 Agent(团队成员)必须先通读本文件**,再按 §2 文档索引读取对应文档,
4
- > 不要在未了解现状前自行全量探索代码。
5
- > 维护者:TeamFlow 自身演进(像对待产品一样对待插件工程)。
6
-
7
- ---
8
-
9
- ## 1. 这是什么
10
-
11
- - **产品**:`dsh-plugin-teamflow` —— DeepSeek Harness 可分发插件,把「一句话需求 → 多 Agent 团队研发流水线」做成宿主能力。
12
- - **形态**:host(Cordis service `teamflow`,node 侧)+ client(Web「🏭 团队工作台」tab)+ 模型工具(`teamflow_*`)。
13
- - **运行环境**:web profile 宿主组合真实 Node 进程;`file:` 安装 + 从 profile 副本加载。
14
- - **当前状态**(2026-08 大版本线):
15
- - ✅ **领域化重构完成**:1418 行单文件 → 11 个领域文件(见 §3)
16
- - ✅ **token 官方口径计量**(usage = 输入未命中/命中/写缓存/输出/调用数 + 缓存命中率,ADR-0003)
17
- - ✅ **lite 模式 / mode 5 档 + 模型驱动 triage**(ADR-0004,`teamflow_triage`)
18
- - ✅ **full/medium 阶段集差异执行(ADR-0004 落地)**:`STAGE_POLICY` 五档策略表 + `resolveStages()` 纯函数,pipeline 的 design/scaffold/qa 门控改由表驱动;design/scaffold 全档位按显式 flag 条件化(不吞显式请求),patch 无独立 QA——见 §6
19
-
20
- ## 2. 文档索引(按职责)
21
-
22
- | 职责 | 位置 | 说明 |
23
- |---|---|---|
24
- | **摘要索引** | 本文件 | 先读:现状 / 结构 / 工程约定 / 待办 |
25
- | 使用与架构 | `README.md` | 安装、契约速览、token/lite 说明、ADR 索引 |
26
- | 决策记录 | `docs/adr/0001~0007` | 自研 journal(不引 LangGraph) / AGENTS 最小侵入 / 部署+token 口径 / triage+共享状态 / 需求无效→验收「需求不适用」拦截 / 认知前置+架构落地重构(质量优先) / **QA 打回修复有界闭环(ADR-0007)** |
27
- | 测试 | `test/smoke.js` `test/stages.test.js` `test/verdict.test.js` `test/journal.test.js` | 结构/描述符 smoke + 档位阶段集 + 验收结论 + journal 行为 |
28
-
29
- ## 3. 工程结构(领域划分,单向依赖)
30
-
31
- ```
32
- host/
33
- ├── index.ts # 门面:TeamflowService + 工具注册(teamflow_*) + ACTIVE 注入
34
- ├── types.ts # 公共类型(Journal/BacklogItem/PipelineOptions/PipelineMode…)
35
- ├── constants.ts # 常量/阶段映射/预算(STATUS/PHASE_*/STAGE_TOKEN_BUDGET/MODE…)
36
- ├── util.ts # 通用工具(clip/normalize*/suggest 辅助…)
37
- ├── prompts/index.ts # 全部 Prompt(prd/design/scaffold/tech/dev/qa/acceptance + TRIAGE_PROMPT + 模板)
38
- └── core/
39
- ├── context.ts # 运行期共享状态单例(runtime + runs/inFlight/activeProducts + providerName)
40
- ├── backlog.ts # Backlog 数据层 + storeFor + 缺陷解析 + 立项建卡 + 任务流转 + 视图/流转
41
- ├── metering.ts # token 官方口径计量(accumulate/summary 三桶+calls+命中率)
42
- ├── runner.ts # 子代理执行(runPool/runAgent/withRetry + 重试/熔断)
43
- ├── report.ts # 完成汇总投递(deliverCompletion,官方口径汇报)
44
- ├── pipeline.ts # 编排中枢(executePipeline/start/cancel/resume + MODE 归一;【mode 路由挂载点】)
45
- └── triage.ts # 需求分诊(MODE_REGISTRY 策略表 + 正则预筛 + runTriage 模型驱动)
46
- store.ts # 持久化层(原子写/.bak/损坏自愈 + journal 序列化),独立 lib entry
47
- descriptors.ts # Remote 描述符(host/client 共用,单独 entry)
48
- ```
49
-
50
- **规则**:依赖只允许 `types/constants/util` → `prompts`/`core/*` → `index`(门面);严禁反向/循环。所有 Prompt 文本必须进 `prompts/index.ts`。
51
-
52
- ## 4. 工程约定
53
-
54
- - **构建/验证**(插件目录下):
55
- - `pnpm run typecheck` —— tsc --noEmit(改 type 后必跑)
56
- - `pnpm run bundle` —— tsdown → `lib/`(host.mjs/client.js/store.mjs/descriptors.mjs)
57
- - `pnpm test` —— smoke + journal(smoke 对 host 目录做源码断言:新增/移动函数后要同步指向)
58
- - **部署**:`node deploy.mjs`(构建+测试+同步 profile 副本 + 检测运行 web 提示)→ **重启 `dsh --profile web` 才生效**(易踩坑,ADR-0003)。
59
- - **类型**:全 TS;host 必须构建(`node_modules` 下 strip-types 不生效);`peerDeps`(@deepseek-ai/*) 宿主注入。
60
- - **运行时**:零新增运行时依赖(依赖 `store.ts` 的 `node:fs` 与宿主 `ctx`)。
61
- - **数据**:backlog/journal 持久化于 `$DSH_HOME/teamflow/<product>/`;`stores`/`runs`/`activeProducts` 走 `core/context.ts`(进程单例)。
62
- - **token 口径**(官方口径):stage 记 `usage` = `{ input(未命中), cacheRead(命中), cacheWrite, output, calls }`;billed input = input+cacheRead+cacheWrite,缓存命中率 = cacheRead/(input+cacheRead)。熔断预算用官方总消耗(input+cacheRead+cacheWrite+output 累计)。汇报与工作台卡片均按官方口径展示。
63
-
64
- ## 5. 产品记忆(功能演进)
65
-
66
- > v0.3~v0.13 为发布前的内部迭代记录;对外统一归到首次公开发布版本 **v0.1.0**(见 `CHANGELOG.md`)。下表按时间顺序记录各阶段核心变更。
67
-
68
- | 版本 | 核心变更 |
69
- |---|---|
70
- | v0.3~0.6 | journal 断点续跑(ADR-0001)/ AGENTS 最小侵入(ADR-0002)/ 防假交付(实质校验+熔断)/ 并发池 / QA 缺陷登记 / 完成汇报 |
71
- | v0.8.0 | token 双口径 + 成本观测线 + lite 模式 + 部署契约(ADR-0003/0004) |
72
- | v0.8.x | 领域化重构(11 文件)+ triage 5 档(model 驱动)+ lite/tech/patch 端到端 + 需求无效拦截(ADR-0004/0005 落地) |
73
- | v0.10 | 多团队架构(teams.json)+UI"+团队"触发+workspace 级隔离(UUID)+单任务轮转+dev 子卡+官方口径 token 展示+会话暂停/resume+state.json 预编译索引+版本切片/一次成型纪律+子代理路由跟随主线程 |
74
- | v0.10.1 | **验收结论解析修复**(误报实锤 run tf-msytlok5:验收 ✅ 通过,记忆回写段「SUMMARY.md 结构无需改动」命中旧正则「无需改动」→ 误判 reject 杀整条流水线)。`parseAcceptanceVerdict` 移入 util.ts:只认显式「验收结论/整体结论」行 + 专用「📝 需求不适用」全文命中,正文散文不再朴素子串匹配;verdict.test.js 回归覆盖 |
75
- | v0.10.2 | **执行路径基准**(同一持久化需求 A/B):流水线 38m/164 调用/11.6M billed vs 原生 DSH 27m/115 调用/19.1M billed。流水线省 ~39% token(阶段/子代理上下文隔离),原生快 ~29%(少门禁但单 agent 上下文膨胀);质量等价。**拆分价值在「上下文隔离」而非并行次数**。详见 `docs/benchmarks/pipeline-vs-native.md` |
76
- | v0.11 | **「认知前置 + 架构落地」重构(破坏性,ADR-0006)**:① M0 状态核对(core/sanity.ts,start 跑 git 现状注入各阶段,治"认知过期/场外提交");② M1 架构阶段全模式启用(lite 也跑轻量架构蓝图,architectPrompt/techPrompt 产结构化 JSON 蓝图,state.__runCtx 统一注入);③ M2 dev 继承蓝图 + 按蓝图自动拆任务(devTaskDefs 蓝图优先+文件冲突检测合并);④ M3 质量门禁(QA/验收加架构核验,parseAcceptanceVerdict 识别架构打回);⑤ triage 架构护栏(持久化/存储/独立模块等 → 强升 medium)。质量优先于 token:不砍「建全局认知」;原生工作流基线见 `docs/benchmarks/native-workflow.md` |
77
- | v0.12 | **QA 打回修复闭环(ADR-0007)**:QA 发现 P0-P2 阻断缺陷 → 打回开发确认+修复(qaFixPrompt)→ 复验 QA → 干净才进产品验收;`QA_REWORK_LIMIT=2` 上限防无限循环、超限转 needs-human 人工介入;`parseDefects` 容忍 `**P1**` 加粗严重级(修对照实验 tf-mt317a5e 缺陷漏登记);缺陷卡按 reqId+defectId 幂等登记、复验通过 `verifyReqBugs` 关单(P3 观察项保留)。实证:docs/benchmarks/pipeline-vs-native.md「复核」节 |
78
- | v0.1.0(首次公开发布) | **文档层重构:活文档版本制 → 任务夹收口制(ADR-0008,破坏性)**:每需求一个自包含任务夹 `docs/teamflow/<yyyyMMdd>-r<N>[-<slug>]/`(PRD/TECHNICAL/QA-REPORT/ACCEPTANCE 收口其中),host 建夹命名+meta.json,`journal.runDocs` 固定需求级身份——重试/续跑复用同夹,双归档/版本虚增/memory 堆积三类 bug 结构性消失;SUMMARY.md 废除(扫描 meta 聚合)、memory.md 收窄为约定层;AC 局部编号+基线依赖/取代声明;代码头 VERSION 解耦为发布版本;triage 新增 slug 输出。存量项目零迁移 |
79
-
80
- ## 6. 已知待办
81
-
82
- - 🔜 **用「持久化」类需求重跑验证 ADR-0006**:确认 M0 状态核对注入、M1 蓝图产出(架构阶段不再被 lite 跳过)、M2 dev 按蓝图拆任务、M3 验收架构核验(重复适配器应被打回)全链路生效。
83
- - ✅ **full/medium 阶段集差异执行(ADR-0004 已落地)**:`host/constants.ts` 新增 `STAGE_POLICY`(五档阶段集策略表,单一事实来源)+ `resolveStages()` 纯函数;`pipeline.ts` 的 design/scaffold/qa 门控改由该表驱动(`enabled()`),取代散落 if/else。**design/scaffold 全档位按显式 flag(needDesign/needScaffold)条件化——显式请求永不被档位吞掉(v0.8.1 原则泛化)**;patch 始终无独立 QA;与团队阶段交集裁剪。`test/stages.test.js` 覆盖五档展开。
84
- - **需求有效性前置拦截**(ADR-0005 触发信号):在 PRD/确认单阶段判别"需求与现状不符"即停,避免走完开发/验收。
85
- - **deploy.mjs FILES** 未含 `host/core/**`、`host/util.ts`、`host/constants.ts`、`host/prompts/**` 源码(运行时只看 lib,不影响功能;补上保持 profile 工作副本一致,非阻断)。
86
- - `STAGE_TOKEN_BUDGET=60k` 硬编码 → 可升级为 service Config(熔断阈值可调)。
87
- - smoke.js 的源码断言依赖 host 目录聚合(`#region host-pool`):新增领域文件需同步加入。
88
- - 🔜 **给官方提交 PR(低侵入原则下不自改 DSH)**:`conversation` 服务增加 `setView(viewId)`(复用内部 `store.actions.setView`),使「查看子代理会话」可一键跳转并自动切到「对话」tab;PR 合并前暂用 B 方案(按钮加引导文案:「跳转后请切「对话」tab 查看轨迹」)。
89
- - 🔜 **跨会话跳转子代理(同 PR 范畴)**:DSH 子代理目录按父会话加载,`selectSubagent` 不支持跨父导航。已记录 `journal.ownerSession`(发起会话,下发于 stageDetail),跳转按钮在 ownerSession≠当前会话时**禁用 + title/文案提示**;待官方支持跨父会话导航后再解锁(数据已备好)。
90
-
91
- ## 7. 变更记录(近期)
92
-
93
- - 2026-08-25:**任务夹文档制落地(ADR-0008,破坏性)**——按头脑风暴定稿实施:① **结构**:每需求一个自包含任务夹 `docs/teamflow/<yyyyMMdd>-r<N>[-<slug>]/`(PRD/DESIGN/TECHNICAL/QA-REPORT/ACCEPTANCE 收口其中),host 在 initBacklog 后建夹(mkdir+meta.json)并持久化 `journal.runDocs`——重试/续跑复用同夹,双归档/版本虚增/memory 堆积三类 bug 结构性消失;② **slug**:triage 输出协议新增 `slug` 字段(`[a-z0-9-]{3,24}` 校验,非法/缺失退化为 `<date>-r<N>`);③ **prompt 全改**:TF_DOCS 拆产品层/任务夹两层,`RUN(state)` 读 `state.__runCtx.runDocs`(stateSliceFor 首行注入),删除 VERSION_SLICE_BLOCK 与全部 mv 归档/防双归档话术;PRD 头部三行声明(meta summary/基线依赖/取代)、AC 夹内从 1 编起、修订表废除;④ **SUMMARY.md 废除**(host 扫 meta 聚合,本轮只做注入不做浏览器)、memory.md 收窄为约定层(仅约定变更时幂等更新);⑤ **VERSION 解耦**:代码头是发布版本,迭代不碰;state.currentVersion→lastRunFolder;⑥ smoke 拆旧断言加 3i 断言组。存量项目零迁移。设计文档 docs/adr/0008-task-folder-docs.md。
94
- - 2026-08-24:**主线程停手契约 + 单调用护栏 + 工程动作承接(实锤 run tf-mt3s9ej7/tf-mt5afdch)**——三连修复:① **主线程停手契约**:`teamflow_start` 返回 render/工具描述/TeamFlow 注入三处一致约束「start 后不得自行改代码/跑验证,等完成汇报」(收敛为 `teamflowContextText()` 单一来源)+ `teamflow_status` 运行中带 `reminder`;requirement 参数强制忠实转写用户原话。实证:无踢墙需求主线程 17s 结束回合零工具调用、requirement 一字未改。② **单调用护栏(`core/guard.ts` 新文件)**:进行中退化检测——复读检测(滑动窗口内同一规范化流式片段 ≥12 次)+ 墙钟兜底 25min → `run.dispose()` 中止,outcome=`degenerated`(命名避开 isUnretryable 正则),豁免预算门允许一次干净重试。根因:熔断只在 withRetry「尝试之间」检查,单调用死循环永不返回时够不着(QA 复读 38min 烧 481 万 token 零产出)。设计原则:**进度信号而非配额**——正常阶段间调用数差 9 倍/计费差 11 倍,硬上限必误杀。③ **工程动作承接 + 杂项**:PRD prompt 新增「工程动作承接」(分支/提交类指令必须落「工程约束」小节,实锤「新起一个分支」被整条流水线静默丢弃)、tech 蓝图传递、dev prompt「先执行动作再写码」;`resumeRun` 重置 `journal.humanIntervention`(否则续跑完成汇报误标 ⚠️);7 处阶段失败 throw 收口为 `stageFailError()`(真实次数/末次 outcome/熔断语义)。smoke 增补 3h 断言。④ **文档归档/记忆写入幂等(已被 ADR-0008 结构性取代)**:PRD prompt 版本切片加「防双归档」、memory.md 幂等替换语义、DESIGN/TECHNICAL/QA-REPORT 归档同需求草稿跳过条款——本日全部随版本切片制度一并删除。
95
- - 2026-08-21:**QA 打回修复闭环(ADR-0007)**——对照实验 run tf-mt317a5e 实锤流程双缺口:① `parseDefects` 旧正则要求严重级后紧跟 `|`,QA 报告写 `**P1**`(markdown 加粗)→ 缺陷解析为 0 →「QA 未发现缺陷」日志 + 静默进验收(验收源码复核才拦住 BUG-P1-1);② QA 阶段无「缺陷→打回开发→复验」闭环,缺陷只登记不回流。落地:`parseDefects` 改按管道单元格解析(容忍 `**P1**`/反引号/行首 `|`,只认 id+P0-P3+模块三要素非 OBS 行);`pipeline.ts` QA 改 `do…while` 有界闭环——P0-P2 阻断缺陷 → `advanceTask('rework')` + 开发修复子代理(新 `qaFixPrompt`,指令「先确认属实→修复→交还复验」)→ 复验,干净才 `pending-acceptance` 进产品验收;`QA_REWORK_LIMIT=2` 超限 → task/req needs-human + humanIntervention,跳过验收;验收块 `if (!qaBlocked)` 门控。`backlog.ts` 新增 `syncQaDefects`(按 reqId+defectId 幂等建卡/刷新)+ `verifyReqBugs`(复验/验收通过关 P0-P2 open 单,P3 观察项保留)。smoke 增补 3g 断言,typecheck/bundle/全套测试通过。
96
- - 2026-08-20:**档位阶段集差异执行落地(ADR-0004 待办清理)**——`host/constants.ts` 新增 `STAGE_POLICY` 五档策略表(单一事实来源)+ `resolveStages()` 纯函数;`pipeline.ts` 的 design/scaffold/qa 门控改由 `enabled()`(档位阶段集 × 团队阶段交集)驱动,**取代散落 if/else**。语义关键:**design/scaffold 全档位按显式 flag 条件化(不吞显式请求,v0.8.1 原则泛化)**;patch 始终无独立 QA。初版曾把「medium 去 scaffold」做成结构化排除,审计发现会吞显式 needScaffold/needDesign → 已回正。新增 `test/stages.test.js`(五档展开行为测试,含「显式 flag 不被吞」回归断言),smoke 增补 `3f`,package.json test 链挂上。
97
- - 2026-08-20:**【认知前置 + 架构落地】重构(ADR-0006,破坏性)**——从「持久化需求 A/B 实测」提炼:流水线质量低于原生的根因是跳过「建全局认知 → 架构决策」。落地:M0 状态核对(`core/sanity.ts`,start 跑 git 现状,注入所有阶段);M1 架构阶段全模式启用(lite 轻量蓝图 / full-medium 蓝图+文档,`architectPrompt` 允许整读关键文件,产出 `<!-- blueprint -->` JSON);M2 dev 继承蓝图 + 蓝图自动拆任务(文件冲突检测合并);M3 QA/验收架构核验(`parseAcceptanceVerdict` 识别架构打回 → rework);triage 架构护栏(持久化/存储/独立模块 → 强升 medium)。质量优先于 token:不砍「建全局认知」。
98
- - 2026-08-20:**延迟注入修复**——新会话选团队时 agent 可能尚未加载(懒加载),导致 `agent.inject` 静默失败、模型无团队上下文→不走 teamflow。修复:选团队时若 agent 不可用,存入 `pendingInjections` 队列;在 `start`(流水线启动前)和 `getActiveTeam`(UI 加载时)补发注入。
99
- - 2026-08-20:**TOKEN_HYGIENE v2 + PRD head+tail 切片**——通用 token 治理:文件作用域(只 read 任务目标文件)、禁止重复读(同文件 read ≤1 次)、批量修复(一次修完所有失败再跑,最多 3 轮)、AGENTS.md/SUMMARY.md 已注入无需重读;QA/验收 PRD 内联改 head+tail 组合切片(覆盖头部基线+尾部新增 AC,预算不变)。基于 BGM run 实际数据对比正常会话,只砍"正常会话不会做的操作",零质量损失。
100
- - 2026-08-19:**lite × needDesign 语义修复**:lite 模式不再吞掉显式要求的「UI/UX 设计」——去掉 pipeline 设计阶段闸门里的 `!options.lite`(design 以 `needDesign` 为准启用);lite 仍跳过独立技术方案文档(PRD/变更单即契约)。工具描述/types/triage/README 同步注明「lite + needDesign:true 保留设计阶段」。
101
-
102
- - 2026-08-19:`journal.ownerSession` 溯源(发起会话 id,下发于 stageDetail);跳转子代理按钮增加跨会话判定——ownerSession≠当前会话时禁用并 title/文案提示(DSH 目录按父会话加载、跨父导航待官方 PR)。
103
- - 2026-08-19:PRD/活文档升级改 **mv 归档 + 增量干净文件**(结构上杜绝 edit-in-place):`VERSION_SLICE_BLOCK` 真正接入 PRD prompt;旧版整文件 git mv 到 history/<旧版本>/,新文件只写增量 US/AC + 压缩回归基线(AC 仅编号+一行语义+指针,严禁照抄全文,防 35KB 巨无霸);design/tech/QA 归档话术同步。
104
-
105
- - 2026-08-19:token 计量收敛为官方口径(去除计费当量/上下文压力自定义概念):`usage` = 输入未命中/命中/写缓存/输出/调用数 + 缓存命中率;熔断预算用官方总消耗;工作台卡片/任务卡/汇报均按官方口径展示。
106
- - 2026-08-19:流水线视图重设计 —— 横向蛇形流程(相位从左至右、上下波浪错位 + SVG 弧线连接 + 沿路径流动高亮虚线 + 箭头终点),整块画布默认可拖拽平移 + 滚轮缩放 + 适应/± 控制簇,点阵网格背景与步骤序号徽标提升质感;历史 run 选择器门控到流水线 tab。验收结论解析修复为只认「验收结论」行(parseAcceptanceVerdict,误报实锤 tf-msytlok5)。
107
- - 2026-08-19:阶段卡点击查看详情 —— 悬浮于画布右上的浮层(不挤占画布宽度;画布加高至 560;浮层内原生 wheel stopPropagation,滚轮只滚正文不触发画布缩放),官方口径 usage 全字段 + 阶段性产物全文 +「🎬 跳转子代理会话」(sessions.openSubagent,mode one-shot;按钮带引导文案「跳转后请切「对话」tab 查看轨迹」——DSH 未向第三方暴露切视图接口,待官方 conversation.setView PR 后一键直达);host 新增 stageDetail RPC(读 stage.output 全文);终态 checkpoint 不再删 stage.output(磁盘+内存保留全文,供详情/断点续跑,smoke 断言同步)。
108
- - 2026-08-19:dev 子卡模型(一个需求一张轮转主卡 + 并行 dev 子卡)、assign 与 status 分离(teamflow_assign)、workspace 级隔离(DSH workspace UUID)、UI"+团队"触发 + teamflow_pause/resume、子代理路由跟随主线程、state.json 预编译索引 + 版本切片/一次成型纪律、backlogUpdate 参数对齐修复。
@@ -1,46 +0,0 @@
1
- # ADR-0001:断点续跑自研 journal,不引入 LangGraph
2
-
3
- - 状态:已接受(Accepted)
4
- - 日期:2026-08(v0.1.0)
5
- - 关联:`store.js`(journal 三件套)、`host/index.js`(executePipeline resume)
6
-
7
- ## 背景
8
-
9
- 流水线要跑 10+ 个子代理、30-60 分钟,进程重启后需要可恢复。候选方案:
10
-
11
- 1. 自研 journal checkpoint(`$DSH_HOME/teamflow/runs/<runId>.json`)
12
- 2. 引入 `@langchain/langgraph`(JS 版)做编排 + checkpoint
13
-
14
- ## 决策
15
-
16
- 自研(LangGraph checkpointer 语义的务实子集),不引入 LangGraph。
17
-
18
- ## 理由
19
-
20
- - **LLM 编排不可重放**:LangGraph 的恢复 = 从 checkpoint 重放节点代码产生相同结果,对纯函数节点成立;我们的节点是子代理(LLM 调用),重放 = 重新烧 token 且结果不同。"跳过已完成阶段复用产物"(resume)两种方案都得自己写——checkpoint 的核心价值对我们失效一半。
21
- - **分发风险**:LangGraph JS 开箱持久化 checkpointer 用 `better-sqlite3`(原生模块,Windows 安装可能失败);纯 JS 文件版要么自写 `BaseCheckpointSaver`(回到自研),要么依赖尚不成熟的 node:sqlite 适配。DSH 插件分发要求薄依赖。
22
- - **替换率 ~30%**:子代理编排、token 计量、backlog 落盘、文档归档都是 LangGraph 不管的;它只替换"编排骨架 + checkpoint",而面板/工具/测试已按自研写好。迁移 = 重写 + 回归。
23
- - **状态 schema 化成本**:LangGraph 要求 zod schema + 严格 JSON state;我们的 backlog/journal 自由 JSON 更灵活。
24
-
25
- ## 已对齐的概念(将来迁移概念兼容)
26
-
27
- | LangGraph | TeamFlow |
28
- |---|---|
29
- | thread_id | runId |
30
- | checkpointer | runs/<runId>.json |
31
- | interrupt() | needs-human |
32
- | Command(resume=) | 从断点重跑(teamflow_resume) |
33
- | durable execution | 启动扫描标记 interrupted |
34
-
35
- ## 触发迁移的信号
36
-
37
- - 编排复杂度显著上升(动态分支、`Send` 级扇出、多层循环)
38
- - 需要 time travel / 历史版本重放 / 审计回滚
39
- - 团队拥抱 LangChain 生态(LangSmith、LangGraph Platform)
40
-
41
- ## 若迁移的选型要点
42
-
43
- - checkpointer 用 node:sqlite 适配,不用 better-sqlite3(避免原生编译)
44
- - 子代理调用包成幂等节点:state 带产物缓存 + 节点入口检查缓存,让重放真正跳过
45
- - 锁死 LangGraph 版本
46
- - `store.js` 保留做 backlog——backlog 与 checkpoint 是两层,不冲突
@@ -1,28 +0,0 @@
1
- # ADR-0002:AGENTS.md 最小侵入(共识层 / 运营数据分离)
2
-
3
- - 状态:已接受(Accepted)
4
- - 日期:2026-08(v0.1.0)
5
- - 关联:`host/index.js`(AGENTS_TEMPLATE v2 / MEMORY_TEMPLATE / productCtx 边界约束)
6
-
7
- ## 背景
8
-
9
- 产品经理/验收环节把迭代历史(产品记忆表)、待办清单直接写进产品 `AGENTS.md`。已有项目团队接入时,这是他们的团队资产(被 harness 无条件注入每次会话)。
10
-
11
- ## 决策
12
-
13
- - AGENTS.md 只放**稳定共识层**:团队角色流程、工程约定、文档索引、`<!-- teamflow:begin/end -->` 托管区(仅指针)
14
- - 产品记忆/待办放独立活文档 `docs/teamflow/memory.md`(按需读取)
15
- - 已有项目:检测到 AGENTS.md 已存在 → 绝不重写/重排/覆盖,仅在文末追加托管块(若没有)
16
- - TeamFlow 只维护托管区与 `docs/teamflow/`;停用时删这两处即完全复原
17
-
18
- ## 理由
19
-
20
- - **覆写风险**:已有团队自己的 AGENTS.md 约定会被流水账重排/覆盖,破坏其 agent 体系
21
- - **职责混淆 → token 注入成本**:AGENTS.md 每次会话无条件注入,高频运营数据(每迭代追加)塞进去 = 文档膨胀 × 每次都读
22
- - **退出残留**:团队停用后账本死数据留在 AGENTS.md 继续注入
23
-
24
- ## 影响
25
-
26
- - 新项目脚手架创建"共识层 AGENTS.md + memory.md 骨架"两个文件
27
- - 各环节提示词(PRD/验收)的记忆回写目标改为 memory.md,并明示不得触碰托管区外内容
28
- - 多产品线各自独立 memory.md + backlog,不串味
@@ -1,50 +0,0 @@
1
- # ADR-0003:部署生效契约 + token 计量口径(真实累计 / 当量 / 观测线)
2
-
3
- - 状态:已接受(Accepted)
4
- - 日期:2026-08(v0.1.0)
5
- - 关联:`host/index.ts`(accumulateSessionUsage / costTokensOf / COST_BUDGET_TOKENS / deliverCompletion)、`store.ts`(stage.usage/costTokens/handoff)、`deploy.mjs`
6
-
7
- ## 背景
8
-
9
- 两个被实测锤出的问题:
10
-
11
- 1. **token 口径低估 26 倍**:旧 `stage.tokens` = `tokenMeter.measure(session).totalTokens`,本质是"会话尾声的上下文压力**快照**",不是生命周期累计消耗。真实 API token(含每步上下文重放)需从子代理会话逐事件累计——实测一流水线显示 593k,真实 15.4M(cacheRead 占 95%)。
12
- 2. **改源码不生效**:运行中的 web 从 **profile 部署副本**(`~/.dsh/profiles/web/node_modules/dsh-plugin-teamflow/lib/`)加载 host,不是源码 `plugins/**/lib/`。只构建源码、不 deploy、不重启,改动被静默忽略(lite 参数被旧 host 忽略、汇报仍是旧格式)。
13
-
14
- ## 决策
15
-
16
- ### 1. token 三口径(stage 级)
17
- | 字段 | 含义 | 来源 |
18
- |---|---|---|
19
- | `usage` | **真实累计** `{input, cacheRead, cacheWrite, output, calls}` | `accumulateSessionUsage`:遍历子代理 `session.events` 的 `assistant/message` 事件,按 `turn.step` 去重计调用数 |
20
- | `costTokens` | **计费当量** = `input + cacheWrite + output + cacheRead×0.1` | `costTokensOf`(cache hit 约 input 1/10 价)|
21
- | `tokens` | **上下文压力快照**(原字段,向后兼容)| `tokenMeter.measure(...).totalTokens` |
22
-
23
- - 汇总汇报给双口径:`Token:∑ 当量(in / cacheRead / out · N 调用)· 上下文压力 X`
24
- - 旧的 `tokens` 保留:老 journal / 无 usage 数据时回退显示上下文压力,不破坏 `teamflow_resume`。
25
-
26
- ### 2. 成本观测线(只记录不打断)
27
- - `COST_BUDGET_TOKENS = 250000`(计费当量)。单阶段当量超线 → `journal.logs` 记 `warn`("仅记录,不打断")。
28
- - 定位是**观测工具**(暴露高成本阶段),不是熔断(熔断仍由上下文压力 60k 预算负责)。
29
-
30
- ### 3. 部署生效契约
31
- - 改 host/client 后的**唯一正确链路**:`node deploy.mjs`(构建 + 测试 + 同步 profile 副本)→ **重启 `dsh --profile web`**。
32
- - `deploy.mjs` 结尾检测 3080 是否在监听 + 进程启动时间 → 提示"不重启则仍跑旧逻辑"。
33
- - 源码 `lib/` 构建**不**等于部署;`.npmignore` 排除与否与运行时加载副本无直接关系(运行时只看 profile 副本)。
34
-
35
- ## 理由
36
-
37
- - 快照口径让"上下文压力"被误当成本,误导成本决策;累计口径 + 当量才贴近计费(实测低估 26 倍)。
38
- - cacheRead 重放是真实成本大头,观测它(而非隐藏)才能驱动"共享状态/精读"优化(见 ADR-0004)。
39
- - 部署契约踩坑会浪费大量往返;显式化 + 自动提示防复发。
40
-
41
- ## 影响
42
-
43
- - `deliverCompletion` 汇报行变化(双口径);工作台卡片展示 `costTokens`(当量)+ tooltip 明细。
44
- - `stage.usage/costTokens/handoff` 持久化到 journal(store.ts serializeJournal)。
45
- - 开发循环必须走 deploy 而非"以为构建就生效"。
46
-
47
- ## 触发信号
48
-
49
- - 需要按 provider 真实计费折算(cache 折扣变化/多 provider 差异)→ 当量折算改为可配置。
50
- - 成本观测线需要按产品/阶段差异化 → `COST_BUDGET_TOKENS` 从常量升级为 service 配置。
@@ -1,52 +0,0 @@
1
- # ADR-0004:需求分诊路由 + 共享状态分层(full / lite / tech + Context Bundle)
2
-
3
- - 状态:已接受为设计方向(实现分二期,见「影响」)
4
- - 日期:2026-08(v0.1.0 起规划)
5
- - 关联:`host/index.ts`(lite 已实现)、`docs/adr/0001`(编排仍自研,不引入 LangGraph)、`docs/adr/0003`(token 累计口径)
6
-
7
- ## 背景
8
-
9
- 1. **不是所有需求都该走完整 PRD**(用户反馈):
10
- - 完整新功能 → 产品/技术 leader 评估是否接 → 完整流程;
11
- - 微功能小改动 → 轻量(已由 `lite` 覆盖);
12
- - **技术驱动改造**(架构升级、代码优化、重构、hotfix)→ 产品只需要"知道并同步记忆",不需要完整 PRD:变更单 → 开发 → QA → 上线。
13
- 2. **token 随工程增长呈指数风险**:每个子代理是新会话(零父上下文),各自重新读 AGENTS/SUMMARY/PRD/TECH 全文 → read 重复 + cacheRead 重放(实测占 95%)。痛点 = **共享状态缺失 / 每个"会话"都要重新建立全量认知**。
14
-
15
- ## 决策
16
-
17
- ### 1. 需求分诊路由:三档流水线形态 `mode: full | lite | tech`
18
- | mode | 适用 | 阶段 |
19
- |---|---|---|
20
- | `full`(默认) | 完整新需求 / 跨模块 | 现状 7 段(PM 先评估是否接)|
21
- | `lite`(已实现)| 单模块小功能 / 微增强 | PRD → 开发 → QA → 验收(4 段,跳过 design/tech 文档阶段)|
22
- | `tech`(待实现)| 技术驱动改造 / hotfix | **技术变更单**(非完整 PRD:PM 只做范围评估 + 任务卡 + 记忆同步)→ 开发 → QA → 上线 |
23
-
24
- - 路由时机:调用方(模型)在 `teamflow_start` 前判断需求类型;提供 `lite` 已支持,`tech` 新增;可选提供 `teamflow_triage` 辅助判定(启发式关键词 + 让模型评估),并允许显式传 `mode`。
25
- - `tech` 的关键差异:PRD 环节不产出 `docs/prd/PRD.md` 全文,改为极简「技术变更单」+ `memory.md` 记忆回写(见 ADR-0002 的产品记忆通道),开发按任务卡 + 技术契约实施。
26
-
27
- ### 2. 共享状态分层(回应 LangGraph "shared state" 概念,但不换编排)
28
- 沿 ADR-0001 的结论:编排/checkpoint 继续自研(journal);这里补的是**输入侧状态共享**,目标是"少读、精读、跨流水线复用",不是替换 checkpoint。
29
-
30
- **Context Bundle(产品上下文包,两级落地)**:
31
- - **B 期(prompt 层,低风险快见效)**:host 侧预构建"产品认知切片"(AGENTS 要旨 / 文档索引 / 关键契约摘录),随阶段 prompt 注入;结合 ADR-0003 的 TOKEN_HYGIENE 硬约束 + 超配额 warn,让子代理**不再自行全量重读**公共文档。
32
- - **A 期(state 文件,跨流水线复用)**:产品级 `.teamflow/state.json` 持久化上下文包(由各阶段 contributor 更新:PM→prd 摘要、tech→接口契约、QA→结论),子代理只拿相关 slice;跨流水线复用(无需每个新 run 重建全量认知)→ 直接应对"工程变大 token 指数增长"。
33
-
34
- - 与现有构件的关系:`memory.md`(ADR-0002)是**权威运营记忆**(人工可读);`state.json` 是它的**预编译索引缓存**(机器喂给子代理切片,避免子代理去 parse 文档)。`journal` 仍是 checkpoint(断点续跑),二者不冲突。
35
-
36
- ## 理由
37
-
38
- - 分级路由把流程重量匹配到需求规模,避免"一个微功能套完整瀑布"(实测 lite 省 64% 时间 / 88% token)。
39
- - 共享状态直击 cacheRead 占比 95% 的根因:重复读 + 全量上下文重放;索引化 + 切片注入把"每次新会话重建认知"降为"读一次索引"。
40
- - 不引 LangGraph 本体(ADR-0001 理由仍成立:LLM 节点不可重放、薄依赖、替换率低);只借用其"统一 state + 子图共享"思想,落在自研分层上。
41
-
42
- ## 影响
43
-
44
- - 已交付:`lite`(v0.1.0)。`tech` 路由、`teamflow_triage`、Context Bundle B/A 期为下阶段实现项。
45
- - PRD 提示词按 mode 分流;新增 `mode` 选项 + 分诊工具描述。
46
- - state.json 的构建/失效/并发锁(与现有产品级并发锁共用一个入口)需设计。
47
-
48
- ## 触发信号 / 后续
49
-
50
- - cacheRead 占比仍在 70%+ 且 `COST_BUDGET_TOKENS` 持续触发 → 优先做 Context Bundle A 期。
51
- - 出现"技术驱动改造"类需求反馈 → 优先补 `tech` 路由。
52
- - 需要 time travel / 历史重放 / 强审计 → 才重新评估 LangGraph(见 ADR-0001 触发信号)。
@@ -1,38 +0,0 @@
1
- # ADR-0005:需求无效 → 验收阶段「需求不适用」拦截(不误标 accepted)
2
-
3
- - 状态:已接受(Accepted)
4
- - 日期:2026-08(v0.1.0)
5
- - 关联:`host/core/pipeline.ts`(验收段 accVerdict)、`host/prompts/index.ts`(acceptancePrompt)、`host/core/backlog.ts`
6
-
7
- ## 背景
8
-
9
- 端到端复验「需求与实际不符」场景(如要求删除一个不存在的字符)时暴露:
10
- - **dev 执行纪律生效**:确认单与开发正确指出「需求与现状不符 / 无需改动」,未臆造改动(此前问题已修)。
11
- - 但**验收 agent 把「无缺陷 + 无需改动」判成了「✅ 通过」**,需求被误标 accepted。
12
-
13
- 根因:`acceptancePrompt` 的验收结论只有三档(通过/有条件通过/不通过),缺少"需求本身无效"的语义出口;对「无变更的正确拒绝」模型倾向视为通过。
14
-
15
- ## 决策
16
-
17
- 1. **验收结论新增第四档「📝 需求不适用」**(`acceptancePrompt`):当 PRD/变更单/确认单已指出"需求与现状不符",或开发明确"无需改动(需求站不住/已满足)"时,结论应为「📝 需求不适用」,不得因无缺陷标 ✅ 通过。
18
- 2. **executePipeline 验收段拦截**:验收文本命中 `需求不适用|需求与实际不符|需求站不住|无需改动|无需修改|需求无效` → `accVerdict = 'reject'`:
19
- - acceptance task → `needs-human`
20
- - req → `needs-human`(humanIntervention=true,需人工决定调整或取消需求)
21
- - 流水线中断(throw,journal.status=failed)
22
- - 原 `❌/不通过/需返工 → rework` 路径保留(针对交付未达标的场景)
23
- 3. 需求有效性**前置拦截**(在 PRD/确认单阶段就判别并停)是更彻底的方向,暂不实现(见「触发信号」)。
24
-
25
- ## 理由
26
-
27
- - 「需求无效」与「交付不达标」是两类不同终止:后者可返工(rework),前者应停流水线交人工裁夺(needs-human),混为 accepted 会掩盖需求本身的问题。
28
- - 在验收提示中显式给出该档,模型才有正确归类的词汇;正则捕获让判定确定性可测。
29
-
30
- ## 影响
31
-
32
- - 需求无效 → req/acceptance 卡 `needs-human` + 人工介入横幅出现,团队台明确提示。
33
- - 端到端可用「空需求/需求站不住」场景验证红路径。
34
-
35
- ## 触发信号 / 后续
36
-
37
- - 需求有效性前置到 PRD/确认单阶段(一发现不符即停,省去开发与验收整段):可作为 v0.1.0 增强。
38
- - full/medium 档位阶段集差异化执行仍待做(ADR-0004 §影响)。