dsh-plugin-teamflow 0.1.0 → 0.1.1

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/README.en.md ADDED
@@ -0,0 +1,137 @@
1
+ # dsh-plugin-teamflow
2
+
3
+ [中文](./README.md) | English
4
+
5
+ TeamFlow team R&D pipeline — a distributable DeepSeek Harness plugin (install via `dsh plugin --profile web add`).
6
+
7
+ Turns "one-line user requirement → real R&D team multi-agent pipeline" into a host-level capability:
8
+
9
+ ```
10
+ requirement → PRD (based on existing patterns / product memory, archived to prevent bloat)
11
+ → (UI redesign) UI/UX design
12
+ → (new project) architect plans and scaffolds + AGENTS.md
13
+ → senior full-stack engineer tech spec (aligned with dispatched tasks)
14
+ → parallel dev when tasks are splittable
15
+ → QA functional testing (structured defects → register bugs)
16
+ → product acceptance (update product memory)
17
+ ```
18
+
19
+ ## Core Features
20
+
21
+ - **Anti-fake-delivery**: ① Substantive validation — outputs containing rejection phrases ("I cannot complete", etc.) or below the per-stage length floor are treated as undelivered and routed to retry / human intervention; ② Token circuit breaker — a single stage accumulating 60k budget stops retries; ③ Context-exhaustion failures are not retried (retrying the same prompt likely reproduces); ④ Product-level concurrency lock — only one active pipeline per product at a time, preventing requirement state from stepping on itself; ⑤ Memory trimming — timeline summarization + in-memory stage output removal (kept on disk, reloaded in full on resume).
22
+ - **Auto completion report to main thread**: when a pipeline ends (success / failure / cancel / interrupt), it automatically delivers a summary (status / stage stats / total token / backlog / next-step guidance) to the initiating session's Agent — wakes on idle (followup), injects next-step context when busy (inject), using the same mechanism as DSH's background-task notifications (tool-jobs mode, but independently implemented and not dependent on the web-disabled tool-jobs). The user need not watch the panel; the model relays the result or continues per guidance (claim defects / transition / resume from checkpoint).
23
+ - **Resume from checkpoint**: every stage checkpoint persists to `$DSH_HOME/teamflow/runs/<runId>.json` (LangGraph checkpointer semantics); after a process crash / restart it is auto-marked `interrupted`, and `teamflow_resume` / the panel's "↻ resume from checkpoint" continues from the first unfinished stage (skipping completed stages, reusing full stage outputs).
24
+ - **Backlog persistence (workspace-isolated since v0.1.0)** under `$DSH_HOME/teamflow/<workspace>/backlog/` as `requirements.json` / `tasks.json` / `bugs.json`, surviving restarts; backlog is isolated per "workspace (project)" — one workspace is one product line, and different workspaces each see their own Team Workspace.
25
+ - **Single-task model (v0.1.0)**: one requirement = one rotating task card (no longer split by role); the task card records `devAssign` / `qaAssign` / acceptor, with state rotation: todo → developing → to-test → testing → to-accept → accepted | bounced | needs-human; the delivered frontend page also shows each role's **real token usage** spent on that task.
26
+ - **Artifact consolidation (v0.1.0)**: pipeline docs (PRD / design / architecture / tech spec / QA / memory / history) all consolidate into `docs/teamflow/`, command run logs into `logs/teamflow/<runId>/`, so the host `docs/<role>/` and project root are no longer polluted by TeamFlow; the host-side run log likewise lands in `<workspace>/logs/teamflow/<runId>.log`.
27
+ - **State machine + event log**: requirement (initiated → in-progress → to-accept → accepted), task (todo → developing → to-test → testing → to-accept → done | bounced | needs-human), defect (to-claim → in-progress → fixed-to-verify → closed).
28
+ - **Bounce-back threshold**: 2 consecutive Agent failures in a single stage auto-retry; still failing → `needs-human`, requiring human intervention.
29
+ - **Concurrency pool**: dev tasks run in parallel by `maxConcurrency` (default 3, max 8).
30
+ - **QA defect registration**: the QA report outputs in a fixed table → auto-parsed into bugs entering the backlog.
31
+ - **Token metering (official semantics)**: each stage records `usage` = **cache-miss input / cache-hit input / write-cache / output + call count** (accumulated per event by the sub-agent session) + **cache hit rate** (cacheRead / (input + cacheRead)). Workspace cards / task cards / completion reports all display in this basis — model-agnostic and consistent with the official bill.
32
+ - **lite mode (v0.1.0)**: lightweight micro-features — `teamflow_start(lite:true)` skips the standalone tech-spec doc stage (PRD is the contract) and goes straight **PRD → dev → QA → acceptance**; with `needDesign:true` it **keeps the UI/UX design stage**. Measured ~64% time / ~88% token savings vs the full 7-stage run.
33
+ - **Token circuit breaker**: when a stage's official total consumption (input + cacheRead + cacheWrite + output accumulated) exceeds `STAGE_TOKEN_BUDGET` (default 60k), retries stop and human intervention is required.
34
+ - **🏭 Team Workspace (Web tab)**: a session-header tab alongside chat / trace, containing:
35
+ - Pipeline graph (stage swimlanes + node cards: status / duration / token / sub-agent session, 2s live refresh)
36
+ - **Backlog drag-drop kanban** (requirement / task / defect three status swimlanes, cards dragged to transition, native HTML5 DnD zero-dep)
37
+ - Cost center (per-stage token + total + runtime)
38
+ - Human-intervention center (needs-human items aggregated + one-click terminal state)
39
+ - History run switching + product switching
40
+
41
+ ## AGENTS.md minimal-invasion principle (important)
42
+
43
+ AGENTS.md is unconditionally injected into every session by the harness; it is **team assets**. TeamFlow follows separation of concerns:
44
+
45
+ - **AGENTS.md holds only the stable consensus layer**: team role flows, engineering conventions, doc index, and the `<!-- teamflow:begin/end -->` managed region (pointers only).
46
+ - **Product memory / todos go in a separate live doc** `docs/teamflow/memory.md` (read on demand, not injected every session → saves token).
47
+ - **Onboarding existing projects**: if AGENTS.md already exists → never rewrite / reorder / overwrite; only append a managed block at the end (if none); the team's original conventions are left untouched line by line.
48
+ - **Clean exit**: after a team stops using TeamFlow, deleting the managed block and `docs/teamflow/` fully restores it, with no ledger left in AGENTS.md.
49
+
50
+ ## Architecture (stage 3)
51
+
52
+ ```
53
+ web profile host composition
54
+ ├── teamflow-host (dsh-plugin-teamflow/host) Cordis service `teamflow`
55
+ │ └── TeamflowService extends TypertRemoteService
56
+ │ ├── ctx.typert.register(strict descriptors) ← 7 Remote methods
57
+ │ ├── ctx.tools.register(teamflow_*) ← 6 model tools
58
+ │ └── node:fs → $DSH_HOME/teamflow/...
59
+ └── teamflow-client (dsh-plugin-teamflow/client, auto-scanned) ← package.json declares dsh.client,
60
+ └── ctx.remote.$mount(TEAMFLOW_REMOTE_CONTRIBUTION) no patch line needed, clientModules auto-registers
61
+ └── conversation.view tab "🏭 Team Workspace"
62
+ ```
63
+
64
+ **Why not the @Remote decorator**: host plugins are distributed as plain JS to avoid decorator syntax / TS compilation requirements; `ctx.typert.register` registers strict descriptors (`descriptors.js` pure data, shared by host/client, keeping endpoint and wire parameters consistent).
65
+
66
+ **Why a host-level plugin (not a dynamic plugin)**: dynamic (in-session) plugins run in a restricted sandbox whose `fs` is hard-limited to the runtime root and cannot write to `$DSH_HOME` or the session workspace (observed `file access denied under workspace-write mode`). Only a formal plugin inside the host composition has real Node `fs`, able to land backlog in `$DSH_HOME`, and the client can register an independent tab.
67
+
68
+ ## Directory structure
69
+
70
+ ```
71
+ dsh-plugin-teamflow/
72
+ package.json # dsh.bundle.patch + dsh.client declarations; exports point to lib/ build output
73
+ cordis.patch.yml # insert block; entry name uses package root (so clientModules can scan dsh.client)
74
+ tsdown.config.ts # client build (ModuleLoader bundle → lib/client.js)
75
+ tsdown.host.config.ts # host/store/descriptors build (ESM → lib/*.mjs)
76
+ descriptors.ts # Remote descriptors (pure data, shared by host/client)
77
+ store.ts # persistence layer: atomic write / backup / corruption self-heal + journal serialize / load (independently testable)
78
+ host/index.ts # TeamflowService (TS; built to lib/host.mjs for the host to load)
79
+ client/index.tsx # Team Workspace (TSX; built to lib/client.js)
80
+ test/smoke.js # dependency-free smoke test (descriptors / structure / security hardening)
81
+ test/journal.test.js # journal behavior test (runs store.ts source directly)
82
+ ```
83
+
84
+ **TypeScript note**: the whole repo is TS/TSX. The host **must be built** (cannot rely on Node strip-types to run directly) — Node 22's type stripping does not apply to files under `node_modules` ("unsupported for files under node_modules"), while the host composition loads plugins from `profile/node_modules`. Consistent with the DSH ecosystem (the `@deepseek-ai/dsh-*` host packages' exports all point to lib/*.js). After changing source, run `pnpm bundle` to rebuild and sync the profile copy's `lib/`.
85
+
86
+ ## Install (for users)
87
+
88
+ ```bash
89
+ # Install from npm (after publish)
90
+ dsh plugin --profile web add dsh-plugin-teamflow
91
+
92
+ # Or local directory install (during development)
93
+ dsh plugin --profile web add file:./plugins/dsh-plugin-teamflow
94
+ ```
95
+
96
+ After install, **restart** `dsh --profile web` for the host `teamflow-host` to take effect:
97
+ - The model side gains 11 `teamflow_*` tools: `start / triage / status / backlog / claim / update / assign / cancel / resume / pause / resume_session`;
98
+ - The browser session header shows the "🏭 Team Workspace" tab;
99
+ - Backlog is written to `$DSH_HOME/teamflow/<product>/backlog/*.json`.
100
+
101
+ > Note: `@deepseek-ai/*` are host-private packages; running requires the DeepSeek Harness (dsh) host environment; this package is neither published standalone nor runnable alone.
102
+
103
+ ## Development & verification
104
+
105
+ ```bash
106
+ npm test # smoke (descriptors / structure / security) + journal (resume behavior)
107
+ npm run typecheck # tsc --noEmit type check (same as VSCode, no drift)
108
+ node --check lib/host.mjs lib/client.js lib/store.mjs lib/descriptors.mjs
109
+ npm run bundle # build client (tsdown → lib/client.js, __ModuleLoader__.load registers)
110
+ ```
111
+
112
+ **Type resolution note**: `@deepseek-ai/dsh-*` are host-private packages (not on the public registry, injected by the dsh profile at runtime); types come from the locally installed host copy at `~/.dsh/profiles/node_modules/@deepseek-ai/*` — `tsconfig.json`'s `paths` already maps them (change the username in the path when moving across machines). The build (tsdown) does not depend on this mapping: the host build keeps `@deepseek-ai/*` external, and the client does not reference host packages.
113
+
114
+ Effective chain after changing code (recommended): `node deploy.mjs` (build + test + sync profile copy + detect running web and prompt restart) → restart `dsh --profile web`. Backup chain: `npm run bundle` → update profile copy (`pnpm update dsh-plugin-teamflow`, under `~/.dsh/profiles/web/`; if "Already up to date", first delete `node_modules/dsh-plugin-teamflow` then update) → restart `dsh --profile web`.
115
+
116
+ **⚠ Effectiveness prerequisite (easy to trip)**: the running web loads the host from the **profile deployment copy** (`~/.dsh/profiles/web/node_modules/dsh-plugin-teamflow/lib/`), not the source `plugins/.../lib/`. Building only the source does not take effect in the profile; you must deploy-sync + restart the process, otherwise old logic runs (e.g. the lite flag is silently ignored).
117
+
118
+ Note: `lib/` is excluded by `.gitignore`, but not by `.npmignore` — both `file:` install and npm publish must carry the build output (`exports["./client"]` points to `./lib/client.js`).
119
+
120
+ ## Contract quick reference
121
+
122
+ | Tool / Remote | Purpose |
123
+ |---|---|
124
+ | `teamflow_start` / `teamflow.start(sessionId, requirement, options)` | Start the pipeline |
125
+ | `teamflow_status` / `teamflow.list()` + `teamflow.snapshot(runId)` | Query run progress (stage / status / token / log / needs-human?) |
126
+ | `teamflow_backlog` / `teamflow.backlog(product)` | View backlog (+ persistence path) |
127
+ | `teamflow_claim` | Claim a task or defect |
128
+ | `teamflow_update` / `teamflow.backlogUpdate(kind, id, to, product, reason)` | Manually transition state (handle needs-human) |
129
+ | `teamflow_cancel` / `teamflow.cancel(runId)` | Cancel a run |
130
+ | `teamflow_resume` / `teamflow.resume(runId, sessionId)` | Resume from checkpoint (rerun from first unfinished stage) |
131
+ | `teamflow_triage` | Requirement triage preview (start auto-triages by default; use only to pre-assess / force a mode) |
132
+ | `teamflow_assign` | Assign owner of a task / defect (separate from claim: claim only changes state) |
133
+ | `teamflow_pause` / `teamflow_resume_session` | Pause / resume teamflow triggering for the current session (session-level, auto-reset on new session) |
134
+
135
+ ## License
136
+
137
+ MIT — see [LICENSE](./LICENSE).
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # dsh-plugin-teamflow
2
2
 
3
+ 中文 | [English](./README.en.md)
4
+
3
5
  TeamFlow 团队研发流水线 —— DeepSeek Harness 可分发插件(`dsh plugin --profile web add` 安装)。
4
6
 
5
7
  把「用户一句话需求 → 真实研发团队多 Agent 流水线」做成宿主级能力:
@@ -46,17 +48,6 @@ AGENTS.md 会被 harness 无条件注入每个会话,是**团队资产**。Tea
46
48
  - **已有项目接入**:检测到 AGENTS.md 已存在 → 绝不重写/重排/覆盖,仅在文末追加托管块(若没有);团队原有约定一行不动。
47
49
  - **退出干净**:团队停用 TeamFlow 后,删除托管块与 `docs/teamflow/` 即完全复原,AGENTS.md 无残留账本。
48
50
 
49
- ## 架构决策记录(ADR)
50
-
51
- 关键设计决策独立存档于 `docs/adr/`,README 只留索引:
52
-
53
- - [ADR-0001 断点续跑自研 journal,不引入 LangGraph](docs/adr/0001-self-hosted-journal-vs-langgraph.md)
54
- - [ADR-0002 AGENTS.md 最小侵入(共识层/运营数据分离)](docs/adr/0002-agents-md-minimal-invasion.md)
55
- - [ADR-0003 部署生效契约 + token 计量口径(真实累计/当量/观测线)](docs/adr/0003-release-deploy-and-token-metering.md)
56
- - [ADR-0004 需求分诊路由 + 共享状态分层(full/lite/tech + context bundle)](docs/adr/0004-triage-and-shared-state.md)
57
-
58
- 新增决策时:`docs/adr/NNNN-<kebab-name>.md`(背景/决策/理由/影响/触发信号),并在本索引追加一行。
59
-
60
51
  ## 架构(阶段 3)
61
52
 
62
53
  ```
@@ -92,7 +83,6 @@ dsh-plugin-teamflow/
92
83
  store.ts # 持久化层:原子写/备份/损坏自愈 + journal 序列化/加载(可独立测试)
93
84
  host/index.ts # TeamflowService(TS;构建为 lib/host.mjs 供宿主加载)
94
85
  client/index.tsx # 团队工作台(TSX;构建为 lib/client.js)
95
- docs/adr/ # 架构决策记录(ADR-0001/0002…)
96
86
  test/smoke.js # 无依赖 smoke 测试(描述符/模块结构/安全加固)
97
87
  test/journal.test.js # journal 行为测试(直跑 store.ts 源码)
98
88
  ```
@@ -114,6 +104,8 @@ dsh plugin --profile web add file:./plugins/dsh-plugin-teamflow
114
104
  - 浏览器侧会话头部出现「🏭 团队工作台」tab;
115
105
  - backlog 写入 `$DSH_HOME/teamflow/<product>/backlog/*.json`。
116
106
 
107
+ > 注意:`@deepseek-ai/*` 为宿主私有包,运行需 DeepSeek Harness(dsh)宿主环境;本包不发布也无法独立运行。
108
+
117
109
  ## 开发与验证
118
110
 
119
111
  ```bash
@@ -131,24 +123,11 @@ npm run bundle # 构建 client(tsdown → lib/client.js,__ModuleLoa
131
123
  改完代码的生效链路(推荐):`node deploy.mjs`(构建 + 测试 + 同步 profile 副本 + 检测运行中 web 并提示重启)→ 重启 `dsh --profile web`。
132
124
  改完代码的生效链路(备用):`npm run bundle` → profile 副本更新(`pnpm update dsh-plugin-teamflow`,在 `~/.dsh/profiles/web/` 下,若 Already up to date 先删 `node_modules/dsh-plugin-teamflow` 再 update)→ 重启 `dsh --profile web`。
133
125
 
134
- **⚠ 生效前提(易踩坑,详见 ADR-0003)**:运行中的 web **从 profile 部署副本**(`~/.dsh/profiles/web/node_modules/dsh-plugin-teamflow/lib/`)加载 host,不是源码 `plugins/.../lib/`。只构建源码不在 profile 生效;必须 deploy 同步 + 重启进程,否则跑旧逻辑(如 lite 参数被静默忽略)。
126
+ **⚠ 生效前提(易踩坑)**:运行中的 web **从 profile 部署副本**(`~/.dsh/profiles/web/node_modules/dsh-plugin-teamflow/lib/`)加载 host,不是源码 `plugins/.../lib/`。只构建源码不在 profile 生效;必须 deploy 同步 + 重启进程,否则跑旧逻辑(如 lite 参数被静默忽略)。
135
127
 
136
128
  注意:`lib/` 被 `.gitignore` 排除,但 `.npmignore` 不排除——`file:` 安装与 npm 发布
137
129
  都必须带上构建产物(`exports["./client"]` 指向 `./lib/client.js`)。
138
130
 
139
- ## 发布
140
-
141
- ```bash
142
- # 1) 升版本号(package.json 的 version,遵循 semver)
143
- # 2) 构建产物(lib/ 已被 .gitignore 排除,但靠 package.json 的 files 白名单随包发布)
144
- pnpm bundle # 或 npx tsdown && npx tsdown -c tsdown.host.config.ts
145
- # 3) 跑测试 + 发布(prepublishOnly 会自动 build + test,可跳过手动 build)
146
- npm login
147
- npm publish # 仅发布 files 白名单内的 lib / cordis.patch.yml / README.md / AGENTS.md / docs/adr
148
- ```
149
-
150
- > 注意:`@deepseek-ai/*` 为宿主私有包,运行需 DeepSeek Harness(dsh)宿主环境;本包不发布也无法独立运行。
151
-
152
131
  ## 契约速览
153
132
 
154
133
  | 工具 / Remote | 作用 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-teamflow",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "TeamFlow 团队研发流水线(TypeScript):需求→PRD→设计→架构→技术方案→并行开发→QA→验收;backlog 持久化 + 断点续跑 + 完成汇报 + 防假交付;Web 团队工作台(conversation.view tab + 拖拽看板)",
5
5
  "type": "module",
6
6
  "main": "./lib/host.mjs",
@@ -42,9 +42,7 @@
42
42
  "files": [
43
43
  "lib",
44
44
  "cordis.patch.yml",
45
- "README.md",
46
- "AGENTS.md",
47
- "docs/adr"
45
+ "README.md"
48
46
  ],
49
47
  "dependencies": {
50
48
  "react": "^18.2.0"
@@ -64,5 +62,9 @@
64
62
  "@deepseek-ai/dsh-tools": "*",
65
63
  "@deepseek-ai/dsh-typert-protocol": "*"
66
64
  },
67
- "license": "MIT"
65
+ "license": "MIT",
66
+ "repository": {
67
+ "type": "git",
68
+ "url": "https://github.com/MichaelShii/dsh-plugin-teamflow.git"
69
+ }
68
70
  }
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 §影响)。
@@ -1,67 +0,0 @@
1
- # ADR-0006:流水线「认知前置 + 架构落地」重构(质量优先于 token)
2
-
3
- - 状态:已接受(Accepted)
4
- - 日期:2026-08(v0.1.0)
5
- - 关联:`host/core/sanity.ts`(新)、`host/core/pipeline.ts`、`host/core/state.ts`、`host/core/triage.ts`、`host/util.ts`、`host/prompts/index.ts`、`store.ts`
6
-
7
- ## 背景
8
-
9
- 对同一持久化需求的 A/B 实测(见 `docs/benchmarks/pipeline-vs-native.md`)暴露根本问题:
10
- - **功能等价 ≠ 代码质量等价**。流水线 dev 输出 game.js/audio.js 两套几乎重复的 safeStorage 适配器、键名分散;原生 DSH 输出独立 storage.js + PERSIST_DEFS 单一事实来源 + verify-storage 专测。
11
- - 根因不是「流水线 vs 原生」,而是流水线**跳过了「建全局认知 → 架构决策」**:TOKEN_HYGIENE 让 dev「只读任务内文件」,state 只传"结论摘要"不传"架构蓝图" → dev 在无全局视野、无设计引导下散落实现。
12
-
13
- 原生工作流实证(`docs/benchmarks/native-workflow.md`):原生高质量 = 环境探索 → 全局 READ → **Design Decision** → 基线验证 → 实现,**次序不可跳过**。而流水线为省 token 压掉了这个自然涌现。
14
-
15
- DSH 无内置"认知构建"机制(standard preset persona 只有一句身份;仅 plan-mode 有 "Explore first")。所以流水线**必须显式化**这套认知流程,不能指望模型自觉。
16
-
17
- ## 决策
18
-
19
- ### 三情况协议(认知传递的总原则)
20
- - 情况一(全新会话 0 认知):读索引减量 + 定向精读,建认知。
21
- - 情况二(续会话):**默认认知已过期**(多人/场外提交/非流水线改动)→ 先状态核对再复用。
22
- - 情况三(新会话处理新需求):共用 state/记忆减量 + 轻量核对现状。
23
- - 核心:**认知资产可复用"减量",但永不能替代"对代码库当前真实状态的核对"**。
24
-
25
- ### M0 状态核对(`core/sanity.ts`)
26
- - `executePipeline` 开头(PRD 前)host 侧直接跑 `git branch/status/log`,产出 `externalDiffs` 摘要。
27
- - 注入所有后续阶段 prompt(经 `state.__runCtx.sanity`,`stateSliceFor` 统一渲染)。
28
- - 持久化到 `journal.sanity`(审计)。失败优雅降级为"无法核对",不阻断流程。
29
-
30
- ### M1 架构阶段全模式启用
31
- - `lite/tech/patch` 不再跳过技术/架构阶段——改为**轻量架构蓝图**(`architectPrompt`,只产蓝图 JSON,不写文档);`full/medium` 由 `techPrompt` 产蓝图 + 完整文档。
32
- - `architectPrompt` 明确**允许整文件 read 关键源文件**(豁免 TOKEN_HYGIENE「别整读」——架构决策需要全局视野),先读状态核对,再建全局认知,最后输出结构化蓝图。
33
- - 架构蓝图 = `<!-- blueprint -->{json}<!-- /blueprint -->` 块,host 用 `extractBlueprint` 解析,`render` 注入 `state.__runCtx.blueprint`。
34
-
35
- ### M2 dev 继承蓝图 + 自动拆任务
36
- - `devPrompt` 注入架构蓝图,契约升级为"按蓝图在既有架构上实现",允许小范围核实(不整读)。
37
- - dev 任务来源优先级:**蓝图 tasks(架构师自动拆,按文件边界)> 调用方 tasks > 整体开发**。
38
- - 冲突检测:蓝图任务 files 有交集 → 合并(保证并发不写同一文件);无交集才并行。
39
-
40
- ### M3 质量门禁
41
- - QA/验收 prompt 加「架构核验」:核对是否遵循蓝图、有无重复实现/适配器漂移/该抽象未抽象。
42
- - `parseAcceptanceVerdict` 扩展:命中架构打回信号(架构返工/重复实现/偏离蓝图/该拆未拆/该抽象未抽象/破坏既有结构)→ `rework`,即使结论行写"通过"。
43
- - 验收不再是"verify 全绿即通过";架构偏离 → 有条件通过(返工)或打回。
44
-
45
- ### triage 配套
46
- - SIGNALS 增架构性词(持久化/localStorage/存储/独立模块/抽象/跨模块等)。
47
- - 架构护栏:命中架构性信号且判 lite/tech/patch → **强制 medium**(必须有架构阶段)。
48
- - TRIAGE_PROMPT 增第 5 条架构判据。
49
-
50
- ## 理由(质量优先于 token)
51
-
52
- - **代码质量是生产底线**:不能为省 token 放弃架构。省 token 的正确方式是把建认知+出设计做成**一次共享**(tech→蓝图→dev 继承),而不是让每个 dev 各读一遍(重复)或都不读(没认知)。
53
- - 让「架构阶段」全模式存在,是把原生工作流最值钱的「全局读 → Design Decision」固化成一个真实阶段 + 一种共享数据(蓝图)。
54
- - 验收加架构门禁,把"防重复/防散落"变成可判定的门禁,而非靠各 agent 自觉。
55
-
56
- ## 影响
57
-
58
- - lite 语义变化:仍跑轻量架构阶段(产蓝图不写文档);triage 对架构性需求强升 medium。
59
- - dev 任务可能被蓝图自动拆解(架构性需求不再退化为"整体开发"单任务)。
60
- - 验收更严格:架构偏离会打回(首次可能增多返工,但这是质量投入)。
61
- - `journal.sanity`/`journal.blueprint` 新增字段;`state.__runCtx` 为运行时注入(不持久化)。
62
-
63
- ## 后续
64
-
65
- - 用「持久化」类需求重跑,验证:M0 状态核对注入、M1 蓝图产出、M2 dev 按蓝图拆任务、M3 验收架构核验效果。
66
- - full/medium 阶段集差异执行仍待做(ADR-0004 §影响)。
67
- - 认知传递的更深层(如共享向量/结构化知识)依赖 DSH 未来能力,当前用"蓝图 + 状态核对"显式化已覆盖根因。
@@ -1,65 +0,0 @@
1
- # ADR-0007:QA 发现缺陷 → 打回开发修复 → 复验 → 干净才验收(有界循环 + 人工兜底)
2
-
3
- - 状态:已接受(Accepted)
4
- - 日期:2026-08(v0.1.0)
5
- - 关联:`host/core/pipeline.ts`、`host/core/backlog.ts`、`host/constants.ts`、`host/prompts/index.ts`、`test/smoke.js`
6
-
7
- ## 背景
8
-
9
- 对照实验 run `tf-mt317a5e-0iwvuy`(干净分支 feat/persistence-localStorage2,tech 档)实测暴露两个流程缺陷:
10
-
11
- 1. **QA 发现的缺陷没有被解析**。QA 报告缺陷行按 markdown 加粗写严重级(`| BUG-P1-1 | **P1** | …`),
12
- `parseDefects` 旧正则是 `(P[0-3])\s*\|`,要求严重级后**紧跟管道符** → `**P1**` 匹配失败 → 缺陷 0 条。
13
- 于是日志记录「QA 未发现 P0/P1/P2 缺陷(未登记 Bug)」,任务静默进入 `pending-acceptance`。
14
- 2. **没有 QA→开发 打回闭环**。即使解析出缺陷,旧逻辑也只是登记 bug 后照样进产品验收;
15
- QA 的负向结论要等到验收(PM)再拦一次(本次是资深 PM 源码复核拦下的),
16
- 既浪费一次验收调用,也让「QA 报告已给出可执行缺陷」的事实被流程白白放过。
17
-
18
- 用户反馈明确要求:QA 发现缺陷 → **打回开发确认是否属实 → 属实则直接修复 → 复验 QA →
19
- QA 干净才到产品最终验收**;该循环需**限制轮次上限**(防无限循环),超限才转人工介入。
20
-
21
- ## 决策
22
-
23
- ### 1. 修复缺陷解析(`backlog.ts` `parseDefects`)
24
- - 改为按管道单元格解析:容忍 markdown 加粗(`**P1**`)、反引号、行首 `|` 偏移;不再要求固定列数。
25
- - 只认「三要素齐全(id / P0-P3 严重级 / 模块)+ 非表头 + 非 OBS」的行 → 真实缺陷(含 `**P1**`)必被解析。
26
- - 语义保持不变:P0/P1/P2 = 阻断缺陷;P3 = 观察项(非阻断)。
27
-
28
- ### 2. QA→开发→复验 有界闭环(`pipeline.ts`)
29
- - QA 阶段改为 `do…while` 循环,最多 `1 + QA_REWORK_LIMIT` 轮:
30
- - 第一轮:常规 QA(label「QA 测试工程师 · 功能测试」)。
31
- - 解析缺陷 → 阻断缺陷(P0-P2)> 0:
32
- - 未超上限 → `advanceTask('rework')`,启动开发修复子代理(新 prompt `qaFixPrompt`,
33
- 指令「**先确认缺陷是否属实 → 属实在既有架构上修复 → 交还复验**」,防"修错/臆造/无视误报")。
34
- - 修复摘要拼接进下一轮 QA 的开发结果上下文 → 复验(label「QA 复验 · 第N轮修复后」)。
35
- - 复验无阻断缺陷 → `verifyReqBugs` 关单 + `advanceTask('pending-acceptance')` → 进入产品验收。
36
- - **QA 干净是进产品验收的充分条件**:验收块由 `if (!qaBlocked)` 门控;QA 不干净绝不自动跑验收,
37
- 杜绝「QA 报告已列缺陷 → 还进验收 → 验收再打回」的浪费。
38
-
39
- ### 3. 轮次上限 + 人工兜底(`constants.ts` / `pipeline.ts`)
40
- - `QA_REWORK_LIMIT = 2`:最多 2 轮「打回开发修复 + 复验」;配合首轮共 3 次 QA 执行,防无限循环。
41
- - 超限 → `qaBlocked = true`:task/req 置 `needs-human`、`humanIntervention = true`、
42
- 日志明示「超出复验上限,需人工介入」,跳过产品验收,流水线以需人工收尾。
43
-
44
- ### 4. 缺陷单幂等 + 关单(`backlog.ts`)
45
- - `syncQaDefects`:按 `reqId + defectId` 幂等登记(多轮复验同一缺陷不重复建卡,只刷新严重级/状态)。
46
- - `verifyReqBugs`:QA 复验通过 / 验收通过时,关闭该需求全部 open 的 P0-P2 缺陷(P3 观察项保留)。
47
- - 验收通过分支复用 `verifyReqBugs`(原「存在未关闭缺陷 → pending-acceptance」逻辑中避免遗留僵尸 open 单)。
48
-
49
- ## 理由
50
-
51
- - **QA 是第一质量门禁**:它的负向结论应当驱动最近的正向反馈环(开发修复),而不是被推给下一阶段的验收。
52
- - **有界性是必须的**:无限复议 = 无限 token 烧毁 + 任务无终止;上限处转人工,让"工具化复盘"让位于"人的判断"。
53
- - 与 ADR-0006 一脉相承:M3 门禁管"验收拦截",本 ADR 管"QA 打回后快速自愈",两处都不可省。
54
-
55
- ## 影响
56
-
57
- - QA 阶段可能多次执行(最多 3 轮),token/调用数上升是**可预期成本**,换取「缺陷在 QA 内闭环」。
58
- - `advanceTask('rework')` 现用于 QA 打回(此前仅验收 rework 用);任务卡状态机本就含 `rework`,无需扩展。
59
- - `parseDefects` 行为收紧:表头/观察项/非管道行不再可能被误认作缺陷。
60
- - run 日志可见「QA 打回开发修复(第 N/N+1 轮)」「QA 复验通过(第 N 轮修复后)」等新阶段轨迹。
61
-
62
- ## 后续
63
-
64
- - 用「持久化修复」类需求实测一条完整打回链:QA 报 P1 → 开发修复 → 复验通过 → 验收 ✅,验证闭环行为与 token 成本。
65
- - 观察超限打回(needs-human)的人工介入路径是否顺畅(`teamflow_update`/认领后重跑)。
@@ -1,103 +0,0 @@
1
- # ADR-0008:文档层重构——活文档版本制 → 任务夹收口制(日期+需求+slug,历史不可变)
2
-
3
- - 状态:已接受(Accepted)
4
- - 日期:2026-08(v0.1.0)
5
- - 关联:`host/core/pipeline.ts`、`host/core/triage.ts`、`host/core/state.ts`、`host/core/backlog.ts`、`host/core/sanity.ts`、`host/prompts/index.ts`、`host/constants.ts`、`store.ts`、client 展示层、全部 smoke 断言
6
-
7
- ## 背景
8
-
9
- 现行文档层是「活文档 + 版本切片」模型:PRD/TECHNICAL/QA 等固定在 `docs/teamflow/{prd,technical,qa}/` 单一路径,
10
- 每次迭代先 mv 旧版到 `history/v<旧版本号>/` 再写新版,靠 prompt 纪律约束模型执行。实测暴露四类结构性缺陷:
11
-
12
- 1. **双归档升版**(实锤 tetris):阶段重试或断点续跑重入 PRD 阶段时,把自己上次的产物当「旧版」再归档一次,
13
- 版本号凭空 +1——已用「防双归档」prompt 补丁缓解,但补丁是概率性的。
14
- 2. **memory.md 段落堆积**(实锤 8 段「当前迭代记忆」并存):「更新记忆」语义模糊导致追加而非替换,
15
- 多段自称"当前",版本互相矛盾——同样只能靠 prompt 补丁。
16
- 3. **全局串行版本假设脆弱**:v2.* 隐含"所有变更排一条时间线"。多人并行、场外改动(不走流水线的功能)、
17
- 多分支开发任一发生,版本号即失真。tetris 三模块代码头 2.3.0/2.3.0/2.6.0 与文档 v2.9 三方漂移即实证。
18
- 4. **并行分支合并冲突**:两个分支各自迭代必然改同一份 PRD.md 的同区域(修订表/AC 清单)+ 同一份 memory.md
19
- ——文档层合并冲突在活文档模型下是结构必然而非偶然。
20
-
21
- 根因判断:**版本号是隐含全局锁的共享可变状态;归档是依赖模型自觉的写时动作**。两者都违背
22
- 「结构保证优于提示词恳求」原则(与 ADR-0007 同一哲学)。
23
-
24
- ## 决策
25
-
26
- ### 1. 任务夹 = 需求级档案单元
27
-
28
- ```
29
- docs/teamflow/
30
- ├── 20260825-r8-wallkick-toggle/ ← 任务夹(建后不可变;阶段重试/断点续跑复用同夹)
31
- │ ├── meta.json ← host 写:{reqId,runId,title,slug,mode,createdAt} 静态标识卡(建夹即定;status/endedAt 权威在 runs/<runId>.json journal,不落 meta——终态回写已废:避免「提交后再脏」与 run 误判时快照过时)
32
- │ ├── PRD.md ← 模型写:meta 头 + 基线声明/取代声明 + 本地 AC 编号(AC-1..n)
33
- │ ├── DESIGN.md / TECHNICAL.md ← 按档位出现(needDesign/非 lite),不再归档
34
- │ ├── QA-REPORT.md
35
- │ └── ACCEPTANCE.md ← 验收报告进夹(废除独立 acceptance/ 目录)
36
- ├── memory.md ← 收窄为产品约定层(技术栈/团队规矩),低频幂等更新
37
- └── (SUMMARY.md 废除:由 host 扫描各夹 meta.json 聚合,工作台渲染)
38
- ```
39
-
40
- - 命名 `<yyyyMMdd>-r<N>[-<slug>]`:日期=需求创建日;`r<N>` 为 reqId 序号(防撞兜底,triage 无 slug 时退化
41
- 为 `20260825-r9/`);slug 由 triage 新增输出(正则 `[a-z0-9-]{3,24}` 校验,非法降级)。
42
- - **身份 = reqId**:夹名在建夹时刻固定并持久化到 `journal.runDocs`;重试、续跑、隔天重跑一律复用同夹
43
- ——幂等性由「夹已存在直接复用」的结构规则保证,不再依赖模型自觉。
44
-
45
- ### 2. 共享写点清零策略
46
-
47
- | 旧共享写点 | 新方案 |
48
- |---|---|
49
- | prd/PRD.md(每分支必改) | 各分支写各的任务夹,路径不相交 |
50
- | memory.md 当前迭代段落 | 「当前迭代」制度废除——迭代细节天然在夹内;memory 收窄为约定层 |
51
- | SUMMARY.md 登记表 | 废除静态文件:host 扫描 meta.json 聚合,工作台按需渲染 |
52
-
53
- memory.md 仅在真正新增团队约定时追加一行(幂等:同主题替换),写入频率从每迭代一次降到偶发。
54
-
55
- ### 3. 回归基线:局部编号 + 显式指针 + 硬保障在代码层
56
-
57
- - AC 编号回归需求本体(夹内 AC-1..n),废除全局账本(中央登记表会重新引入共享写点)。
58
- - 新 PRD 头部两行声明:
59
- - `基线依赖:<其他任务夹名列表>(其既定行为不得回退)`
60
- - `取代:<某夹>#AC-n(语义变更说明)`——历史夹永不改动;查最新真相 = 按日期倒序找最后一条取代链。
61
- - 回归的硬保障仍是项目 verify-* 可执行套件(本就不依赖文档编号);QA 阶段照旧全量运行。
62
-
63
- ### 4. host/model 职责切分:结构归 host,内容归 model
64
-
65
- - host:建夹、命名、meta.json 静态标识卡(建夹一次写入,无终态回写)、journal.runDocs/state.__runCtx 注入;动态状态(status/endedAt)唯一权威 = runs/<runId>.json,目录聚合扫描时以 journal 为准。
66
- - model:只写自己夹内的产物文件;对索引零写入权。PRD 头部输出一行机器可读 meta
67
- (`<!-- meta: summary="…" -->`)供未来聚合使用(YAGNI:本轮不做解析消费)。
68
-
69
- ### 5. 代码头 VERSION 解耦
70
-
71
- devPrompt 明确:模块头部 VERSION 是发布版本,仅对外发版时升位;流水线迭代不碰。
72
- (修复 game.js 2.3.0 型漂移的再发——迭代计数器不得误植进代码。)
73
-
74
- ### 6. 存量过渡:零迁移
75
-
76
- 旧 `prd/`、`technical/`、`history/`、既有 SUMMARY.md 原样留存(历史可追溯性不受影响);
77
- 新需求自然落新夹。项目侧 verify 脚本的文档路径断言由项目自行调整(不在插件范围)。
78
-
79
- ## 理由
80
-
81
- - **结构消灭 bug 类别**:双归档/版本虚增/memory 堆积的全部前提是「固定路径上的覆盖式写入」;
82
- 任务夹让该前提取消,prompt 补丁(防双归档条款等)随之整体删除而非叠加。
83
- - **容忍乱序与旁路**:日期命名不假设任何全局顺序;场外改动、多分支、多团队并行都不再使任何计数器失真。
84
- - **审计单元对齐心智**:「一个需求的所有产物在一个文件夹」与 backlog req/task、journal run 天然一一对应;
85
- review/回滚/交接以文件夹为单位。
86
- - **已有先例**:`logs/teamflow/<runId>/` 早已是 per-run 收口模式,docs 对齐反而统一。
87
- - **resume 不受影响**:断点续跑的产物重建走 journal stage.output 全文,不依赖文档路径——改造影响面收敛在
88
- prompt 注入与展示层。
89
-
90
- ## 影响
91
-
92
- - 全部 10 个 prompt 的路径注入改为 `TF_RUN_DOCS`(本任务夹)+ `TF_PRODUCT_DOCS`(memory 层)两个变量。
93
- - triage 输出协议扩展 `slug` 字段(向后兼容:缺省为空)。
94
- - state.json `product.currentVersion` 废弃,改记 `lastRunFolder`。
95
- - client 文档引用路径跟随 journal.runDocs;目录浏览器不做(YAGNI)。
96
- - smoke 断言大改:删除版本切片/mv 归档/防双归档族断言,新增 runDocs 注入/meta.json/命名格式断言。
97
- - 单 commit 可整体回滚;运行中流水线不受影响,重启宿主生效。
98
-
99
- ## 后续
100
-
101
- - 用下一条真实需求实测完整生命周期:建夹命名 → 各阶段产物落位 → 续跑复用同夹 → 验收后由 runs/<runId>.json 反映终态。
102
- - 观察两分支并行迭代的真实合并场景,确认文档层零冲突。
103
- - 工作台聚合视图(扫 meta.json 渲染产品时间线)作为后续增强候选,本轮不做。