Skip to content

v0.2.5

Choose a tag to compare

@MichaelShii MichaelShii released this 29 Sep 11:17
· 164 commits to main since this release

TeamFlow v0.2.5

中文 | English

Release — 「编排可测 + 交付质量可客观判定」版本(19 个新提交 / 49 个文件 / +2484 −719 行,v0.2.4..HEAD 全量对比):① 把 1646 行的 executePipeline 拆成阶段模块、host/core 按职责分目录,并让真实编排行为可以被测试驱动;② 补「接口契约」三层与「跑得起来」要求;③ 新增三条 host 侧客观检查(能否打开 / 接口对不对 / 有没有真动)—— 它们不依赖模型能力,因此对本插件面向的任意模型(含本地小模型)都成立。无破坏性,宿主窗口不变。

Release — "testable orchestration + objectively verifiable delivery" (19 new commits / 49 files / +2484 −719, full v0.2.4..HEAD diff): ① splits the 1646-line executePipeline into stage modules, groups host/core by responsibility, and makes real orchestration behavior testable; ② adds the three-layer interface contract and the "must actually run" requirement; ③ adds three host-side objective checks (does it open / are interfaces consistent / does it actually move) — all independent of model capability, so they hold for any model this plugin is used with, including small local ones. No breaking changes; the host window is unchanged.


中文

升级要点(TL;DR)

  • 无破坏性:宿主窗口不变(>=0.1.7-alpha.1 <0.2.0);journal 格式、任务夹契约、teamflow_* 工具参数全部向后兼容。
  • 升完重启 dsh --profile web 生效(本版改动包含 host 运行时代码)。
  • 新增的 host 侧检查全部只记录、不阻断(warn/info 进 journal 日志),处于观察期,用来积累真实样本。
  • 交付侧多了一处成本:架构蓝图(api 签名)现在也会注入 QA / 验收的上下文,单次约 +1.4k tokens。

为什么做这三件事

都来自实测事故,不是设计偏好:

  1. 编排不可测:executePipeline 单函数 1646 行,dev/qa/acceptance 揉在一起,改一处无法验证「行为没变」。
  2. 交付质量只能靠模型自觉:贪吃蛇那次产出的 main.js 调用了 GameEngine 上不存在的 move()/render(),首帧 TypeError 直接死机,而「文件存在 / 有 export」级别的检查全绿;另一次是把循环判定写反(lastTime - timestamp),不抛异常、控制台干净、画面全黑,QA 三轮全放行。
  3. 约束能不能生效取决于模型:同一个「请在报告里给出命令 + 退出码」的要求,强模型自发就做到了,弱模型三次全部做不到 ⇒ 靠模型自律的门禁只对一部分用户有效。

本次变更

① 编排可测:拆分与分目录

  • executePipeline 1646 → 1159 行:dev / qa / acceptance 三块整体外移到 host/core/stages/,函数体按行切片搬运、一字未改;共享状态装进 PipelineCtx(三兄弟用 import type 反向引类型 ⇒ 运行时无回边、无循环依赖)。
  • host/core 按职责分组:stages/ agent/ workspace/ domain/,pipeline/triage/locale/report 留根。
  • 新增 test/orchestration.test.js:stub 子代理驱动真实 executePipeline,覆盖档位护栏 / 波次调度 / 澄清闸门 / 提测门禁 / 取消 / 终态归一等 17 个场景。

② 交付质量:契约三层 + 跑得起来

  • 接口契约三层:蓝图必须给 api 精确签名 → dev 必须逐字调用、禁止自创成员名 → QA 必须做静态接口一致性核对(不匹配 = P1)。
  • 冒烟运行(0a2):交付必须被证明「主路径产生可观测状态变化」,存在性不是证据;无浏览器时用 DOM/Canvas 桩但必须保留真实定时器语义。
  • 运行证据探针(warn-only):交付含可执行入口时,QA 报告应给出「命令 + 结果」类证据。
  • 措辞修正:明确「不得强行执行不该执行的交付」—— 需编译 / 依赖服务 / 纯库的形态走等价检查。

③ host 侧三条客观检查(与模型能力无关)

检查 判什么 实证
加载检查 真浏览器加载,抓未捕获异常(抓「打开就崩」) 子代理起不了浏览器(受限令牌下 Chromium crashpad 恒失败),这件事只能 host 做
接口核对 解析产物真实导出 vs 跨模块调用点 同一把尺子:事故 run 命中 5 处(engine.move 等),健康 run 0 处
冒烟 有 canvas 却从未绘制 = 空转 事故 run(黑屏)→ no-motion;三个健康交付 → ok,4/4 判定正确

④ 一次公开撤回:浏览器配方

曾基于「本机 headless Chrome 可用」给 QA 写了启动配方(含 --no-sandbox)。用户在 dsh 宿主实测证明:加不加 --no-sandbox 输出逐字节相同,都失败 —— --no-sandbox 关的是 Chromium 自己的沙箱,管不到宿主沙箱对 crashpad 跨进程 OpenProcess 的拒绝。配方已删除,改为写明「agent 沙箱内不可用 + 具体证据 + 不要再试参数组合」。

⑤ 修两个真 bug

  • 两项 host 检查静默空转:误用 root(= options.productRoot) 当文件系统路径,而它工作区模式下恒为 null(连查 5 个 run)⇒ 检查从未执行且 journal 零痕迹。改为经 fsRootOf() 解析,并让每种结局都留痕。
  • 蓝图收不到:stateSliceFor 的角色白名单只有 arch/tech/dev,而 qaPrompt 与 acceptancePrompt 都写着「若注入蓝图则依它核对」⇒ 那两句恒为假。已补 qa/acceptance。

验证

  • 30 个测试套件全绿,断言 2177 条(v0.2.4 为 2013)。
  • tsc 0 错;oxlint --deny-warnings 0 警告 0 错误(73 文件)。
  • CI(ubuntu-latest)全绿;host 冒烟在 Linux 上真跑了(不是环境跳过)。
  • 编排测试对拆分前 / 拆分后两份代码各跑一遍均全绿 ⇒ 锁的是行为而非结构。

已知边界

  • 三条 host 检查纯记录、不参与判定;判据(尤其冒烟的「有 canvas 却零绘制」)需更多真实样本校准后才考虑升级。
  • 冒烟依赖本机 Chromium 可启动;起不来即 skip,绝不因此影响流水线。
  • 接口核对是内部一致性(调用点 vs 产物导出);「蓝图声明 vs 产物实现」的契约一致性尚未覆盖。
  • 缺陷闭环目前只有「整轮干净」的批量核销,没有逐条核销(已知问题,留待后续)。

English

Upgrade notes (TL;DR)

  • No breaking changes: host window unchanged (>=0.1.7-alpha.1 <0.2.0); journal format, task-folder contract and teamflow_* tool arguments all remain backward compatible.
  • Restart dsh --profile web after upgrading (this release touches host runtime code).
  • Every new host-side check is record-only and non-blocking (warn/info in the journal log) — it is in an observation period to collect real samples.
  • One added cost: the architecture blueprint (api signatures) is now also injected into QA / acceptance context, roughly +1.4k tokens per call.

Why these three themes

All trace back to observed failures, not preferences:

  1. Orchestration was untestable: a single 1646-line executePipeline mixing dev/qa/acceptance — there was no way to prove a change preserved behavior.
  2. Delivery quality depended on the model's discipline: a snake game shipped a main.js calling move()/render() that did not exist on GameEngine — instant TypeError, while "file exists / has exports" checks were all green. Another run inverted a loop comparison (lastTime - timestamp): no exception, clean console, black screen, and QA signed off across three rounds.
  3. Whether a constraint works depends on the model: the same "record the command and its exit code" requirement was met spontaneously by a strong model and missed three times out of three by a weak one ⇒ model-discipline gates only work for part of the audience.

Changes

① Testable orchestration

  • executePipeline 1646 → 1159 lines: dev/qa/acceptance moved to host/core/stages/, bodies transferred line-by-line, unmodified; shared state collected into PipelineCtx (the three modules import the type back with import type, so there is no runtime back-edge).
  • host/core grouped by responsibility: stages/ agent/ workspace/ domain/.
  • New test/orchestration.test.js: stub subagents driving the real executePipeline across 17 scenarios.

② Delivery quality: contract + "it must run"

  • Three-layer interface contract: the blueprint must declare exact api signatures → dev must call them verbatim → QA must statically verify cross-module consistency (mismatch = P1).
  • Smoke run (0a2): the delivery must be shown to produce observable state change; existence is not evidence. Without a browser, use DOM/Canvas stubs but keep real timer semantics.
  • Verification-evidence probe (warn-only) and a wording fix: never force-launch something not meant to be launched.

③ Three host-side objective checks (model-independent)

Check What it decides Evidence
Load check real-browser load, captures uncaught errors ("dead on arrival") subagents cannot launch a browser at all (restricted token ⇒ Chromium crashpad always fails)
Interface check real exports vs cross-module call sites same ruler: 5 hits on the incident run (engine.move etc.), 0 on healthy ones
Smoke canvas present but never drawn = inert incident run (black screen) → no-motion; three healthy deliveries → ok — 4/4 correct

④ One public retraction: the browser recipe

A launch recipe (including --no-sandbox) was added for QA based on "headless Chrome works here". The user's probe inside the dsh host proved identical byte-for-byte failure with and without --no-sandbox — that flag disables Chromium's own sandbox, not the host sandbox that denies crashpad's cross-process OpenProcess. The recipe was removed and replaced with "not launchable inside the agent sandbox + concrete evidence + do not retry flag combinations".

⑤ Two real bugs fixed

  • Two host checks were silently no-ops: root (= options.productRoot) was used as a filesystem path, but it is always null in workspace mode (checked across 5 runs) ⇒ the checks never ran and left no trace. Now resolved via fsRootOf(), and every outcome is logged.
  • The blueprint never reached QA/acceptance: stateSliceFor's role whitelist had only arch/tech/dev, while both qaPrompt and acceptancePrompt said "if the injected blueprint JSON is present…" ⇒ those two clauses were always false. qa/acceptance added.

Verification

  • 30 test suites green, 2177 assertions (v0.2.4 had 2013).
  • tsc clean; oxlint --deny-warnings 0 warnings / 0 errors across 73 files.
  • CI (ubuntu-latest) green; the host smoke check actually ran on Linux (not skipped for environment).
  • The orchestration suite passes against both pre-split and post-split code ⇒ it locks behavior, not structure.

Known limits

  • All three host checks are record-only and non-blocking; thresholds (especially "canvas present but zero draws") need more real samples before being promoted.
  • Smoke depends on a launchable local Chromium; otherwise it reports skip and never affects the pipeline.
  • The interface check covers internal consistency (call sites vs exports); contract consistency (blueprint declaration vs implementation) is not covered yet.
  • Defect closure is still all-or-nothing per clean round; per-defect closure is a known gap.