@xulthekl/team-flow 0.62.0 → 0.63.0
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/.claude/always/phase-guard.md +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/marketplace.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/.github/plugin/marketplace.json +2 -2
- package/CHANGELOG.md +39 -0
- package/GEMINI.md +1 -1
- package/INSTALL.md +1 -1
- package/README.md +1 -1
- package/docs/README_en.md +1 -1
- package/docs/decision-points.md +8 -0
- package/docs/team-flow /344/275/277/347/224/250/350/257/264/346/230/216/357/274/210/347/240/224/345/217/221/345/233/242/351/230/237/347/211/210/357/274/211.md" +4 -4
- package/gemini-extension.json +1 -1
- package/hooks/session-start +2 -2
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/scripts/guard/checks/contract-fresh.mjs +48 -4
- package/scripts/guard/checks/gates-probed.mjs +175 -0
- package/scripts/guard/guard.mjs +17 -2
- package/scripts/lib/cmd-state.mjs +4 -0
- package/scripts/lib/state-loader.mjs +12 -0
- package/skills/build-executor/SKILL.md +6 -11
- package/skills/build-executor/references/wave-delivery-selfcheck.md +92 -0
- package/skills/code-reviewer/SKILL.md +4 -0
- package/skills/contract-builder/SKILL.md +21 -0
- package/skills/contract-builder/references/bridging-gate-dry-run.md +89 -0
- package/skills/contract-builder/references/freeze-and-errata.md +81 -0
- package/skills/release-archivist/SKILL.md +9 -0
- package/skills/spec-writer/SKILL.md +3 -0
- package/skills/spec-writer/references/facts-referencing.md +64 -0
- package/skills/workflow-start/SKILL.md +1 -0
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
{
|
|
10
10
|
"name": "team-flow",
|
|
11
11
|
"description": "8-state spec workflow + compound global compounding + architecture-design (4A/DDD) + local HTML prototype + product-level orchestration + bootstrap + e2e + session handoff + workflow feedback + independent business analysis. 28 skills + 17 agents with embedded TDD, SDD, code review, debugging, delta spec sync, and design-system-driven prototyping.",
|
|
12
|
-
"version": "0.
|
|
12
|
+
"version": "0.63.0",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "LT",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "team-flow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.0",
|
|
4
4
|
"description": "Unified workflow plugin: team-flow (spec-driven dev: TDD/SDD/code-review/debugging) + compound-engineering core subset (brainstorm/plan/compound/strategy/ideate/proof, global compounding) + architecture-design (4A+DDD incremental design & global compounding) + prototype (local HTML prototype, zero external deps) + e2e (Playwright E2E, AC-driven) + workflow-orchestrator (product-level workflow orchestration) + workflow-bootstrap (existing project onboarding) + session-handoff (context transfer) + workflow-feedback (issue tracking) + business-analysis (independent requirement/scenario artifact) + design-system (design tokens + component contract + AI primer + showcase) + test-strategy (test strategy design) + project-initialize (new service onboarding) + jarvis (team-flow decision agent, opt-in). 28 skills + 17 agents, one install.",
|
|
5
5
|
"source": "./",
|
|
6
6
|
"author": {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "team-flow",
|
|
3
3
|
"displayName": "team-flow",
|
|
4
4
|
"description": "Unified workflow plugin: team-flow (spec-driven dev: TDD/SDD/code-review/debugging) + compound-engineering core subset (brainstorm/plan/compound/strategy/ideate/proof, global compounding) + architecture-design (4A+DDD incremental design & global compounding) + prototype (local HTML prototype, zero external deps) + e2e (Playwright E2E, AC-driven) + workflow-orchestrator (product-level workflow orchestration) + workflow-bootstrap (existing project onboarding) + session-handoff (context transfer) + workflow-feedback (issue tracking) + business-analysis (independent requirement/scenario artifact) + jarvis (team-flow decision agent, opt-in). 28 skills + 17 agents, one install.",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.63.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "LT",
|
|
8
8
|
"url": "https://github.com/LT"
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Unified workflow plugins and skills for AI coding agents (team-flow: team-flow + compound + architecture-design + prototype).",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.63.0"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "team-flow",
|
|
14
14
|
"description": "Unified workflow with planning artifacts, execution contracts, TDD, review gates, systematic debugging, delta spec sync, architecture-design, independent business analysis, and local HTML prototyping.",
|
|
15
|
-
"version": "0.
|
|
15
|
+
"version": "0.63.0",
|
|
16
16
|
"source": ".",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "LT",
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,45 @@ All notable changes to `team-flow` will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format loosely follows Keep a Changelog.
|
|
6
6
|
|
|
7
|
+
## [0.63.0] - 2026-09-23
|
|
8
|
+
|
|
9
|
+
### Added(sop-flow 效率八项改进 S1–S6 + E1/E2;来源:emp-auth workflow-feedback 20260923-013114,经 308 行独立专家评审定稿)
|
|
10
|
+
|
|
11
|
+
**新增 guard 维度 `gates-probed`(S2,本版本核心代码变更)**
|
|
12
|
+
- 挂 `bridging → approved-for-build`:契约声明的 G 类闸门必须已在主工作区当前态跑过 dry-run(预期 FAIL = RED 基线)并留档 `.superpowers/test-evidence/bridging-gates-red.txt`。
|
|
13
|
+
- 检查五件:evidence 存在 / 首行逐字 `EXPECTED: FAIL (RED baseline)` / `CONTRACT_HASH` **值**新鲜(不用 mtime——契约字节等价重生成或 git 恢复会让 mtime 变新而内容未变)/ 契约 `## Gate Registry` 的 id 逐 id 覆盖 / **段缺失或解析失败 = FAIL(fail-closed)**。
|
|
14
|
+
- **段存在性是硬要求**:缺段与「零闸门」不可区分——v0.13 RC-1 已删除的内容型豁免不得复活。确无闸门须写 `N/A: <理由>`;另有 `gates_probed_skipped` + 理由作可审计豁免(hotfix 走转移表天然豁免,tweak 会继承故必须靠该键放行)。
|
|
15
|
+
- 三处状态管道同步注册(`state-loader` BUILTIN_DEFAULTS + `writeState` + `cmd-state` SETTABLE_FIELDS)——缺一即「回显成功却零写入」(v0.59.0 同型教训)。
|
|
16
|
+
- 把 `design.md` R-7「闸门命令已实测可跑」长期的**文字自证**物化为机械证据。
|
|
17
|
+
|
|
18
|
+
**`executing:closing` 补挂 `contract-fresh`(S3 反查锚)**
|
|
19
|
+
- 原状 closing 的反查走 `execution-plan-ready`(`validatePlan` 比对 plan 内嵌 hash),而该比对可被 `tf execution refresh-hash` 一键刷平(只改 plan JSON、revision 不升),且 `wave_fingerprint` 不含 `artifacts_hash` → 把 gate-affecting 变更伪记为陈述性勘误后可**静默通过**。
|
|
20
|
+
- 新挂载直接比对 `state.artifacts_hash` 与制品实算值,`refresh-hash` 无法清屏。
|
|
21
|
+
- 失败信息按时间点分流(P4 评审补强):冻结前改动可裸 `tf state rebuild`;**冻结后必须走勘误登记/例外 2**,明文禁止用 rebuild 抹平差异。
|
|
22
|
+
|
|
23
|
+
**新增 references**:`contract-builder/references/freeze-and-errata.md`(勘误登记段模板 + 六条冻结例外 + 三分处方表)、`contract-builder/references/bridging-gate-dry-run.md`(Gate Registry 模板 + dry-run 六条硬要求 + Facts Recheck)、`spec-writer/references/facts-referencing.md`(facts 三件套 + 判据四条 + 跨仓结构)、`build-executor/references/wave-delivery-selfcheck.md`(case↔test 对账三层判据 + Gate-Only receipt 协议)。
|
|
24
|
+
|
|
25
|
+
### Changed(纪律写入 6 个 skill)
|
|
26
|
+
|
|
27
|
+
- **S1 事实前置**:制品引用 `facts.json` 键而非裸写数字(基线数字须写成 `<值>(facts:<键>,ts=…)`);bridging 期由 contract-builder 复测一次,差异摘要**并入 DP-3 ask 呈报**(裁决权归 LT,不得由实施方自行解释掉)。强度如实声明:纪律条款,`tf facts probe` 与 WARNING lint 归远期。
|
|
28
|
+
- **S3 冻结纪律**:DP-3 后 planning 四件默认冻结,陈述性订正记入契约 `## Errata Register`;勘误段写入后 **MUST `tf execution refresh-hash`**(否则卡 `execution-plan-ready`,恰复活 revision 回路)。例外 2 判定权**升格至审查侧**(自判错判方向即伪绿出口)。
|
|
29
|
+
- **S4 对账左移**:build-executor 每 wave 产出 `<wave>-case-test-reconciliation.md`;完成门 = 机械层 + 半机械层通过,**断言点层归 code-reviewer,不构成本步条件**(防卡死、防自填假证据)。code-reviewer Step 5b 独立复核权不减免,且新增「根仓 planning 制品 diff 单列」(多仓下子仓 range 看不到根仓 planning 改动)。
|
|
30
|
+
- **S5 攒批与预批复**:同根因发现攒成一次 ask;DP-6 与 roadmap/push 边界并入 closing 确认;**门禁类 DP(dp_3/dp_4)禁超时代答**(二者是 `dp-gate-passed` 数据源)。
|
|
31
|
+
- **S6 环境清单注入**:`.team-flow/environment.md` 存在则全文附入 dispatch prompt,并**追加元指令要求下游继续附入**(子代理不继承 skills,规则否则到不了第二跳)。
|
|
32
|
+
- **E1 tasks checkbox 形态**:spec-writer 校验清单与 contract-builder 的 hotfix tasks 产出路径**双路径**强制 `- [ ]`——同时消掉 closing 死锁与 hash 漂移重签双源头。
|
|
33
|
+
- **E2 receipt 协议**:零代码/纯闸门波次以根仓 planning commit 作 base..head;**若 G4 未执行须先完成其阻塞询问再 publish**,不得静默代替用户选择。
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- `contract-fresh` 失败信息区分「缺 artifacts_hash(状态文件异常)」与「真漂移」,并给出可执行出路——避免 closing 死锁无指示。
|
|
38
|
+
|
|
39
|
+
### 验证
|
|
40
|
+
|
|
41
|
+
- `npm test` 1237/1237(新增 `guard-gates-probed` 15 例 + `guard-closing-contract-fresh` 3 例);`npm run test:e2e` 77/77。
|
|
42
|
+
- **反向验证 ×2**(改门禁后须能证明它有效):移除 `gates-probed` 挂载 → 测试变红 1 项;移除 closing 的 `contract-fresh` → 变红 2 项(含「删 `## Gate Registry` 段必 FAIL」)。
|
|
43
|
+
- P1.5 标准档两轮对抗验证:第一轮 2C+14M+8m、第二轮 2C+6M+1m(**其中 2 个 Critical 是上一轮修复自身引入的**),全部闭合后进 P2;P4 双评审(plugin-validator / skill-reviewer)12 项发现全部修复。
|
|
44
|
+
- 横展同步 3 处维度计数宣称(`guard-dimensions.test.mjs` 覆盖映射 19→20 维 + `test-matrix.md` + 团队版使用说明)。
|
|
45
|
+
|
|
7
46
|
## [0.62.0] - 2026-09-22
|
|
8
47
|
|
|
9
48
|
### Changed(PRD 业务可读性改造:§8.4 形态重写 + 规范与体例解耦 + 模板一致性确认门)
|
package/GEMINI.md
CHANGED
|
@@ -8,7 +8,7 @@ The workflow is self-contained and does not require OpenSpec or Superpowers at r
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
<!-- team-flow-phase-guard-start -->
|
|
11
|
-
# team-flow v0.
|
|
11
|
+
# team-flow v0.63.0 | 阶段: {{state}} | 工作流: {{workflow}}
|
|
12
12
|
当前阶段允许的操作由 workflow-start 路由规则定义。
|
|
13
13
|
禁止跨越 DP gate 进入下一阶段。变更范围以 execution-contract.md 的 Intent Lock 为准。
|
|
14
14
|
<!-- team-flow-phase-guard-end -->
|
package/INSTALL.md
CHANGED
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# team-flow
|
|
2
2
|
|
|
3
|
-
> 当前版本:`v0.
|
|
3
|
+
> 当前版本:`v0.63.0`
|
|
4
4
|
|
|
5
5
|
> 统一插件:**team-flow**(spec 驱动开发)+ **compound-engineering 核心子集**(全局复利)+ **architecture-design**(4A+DDD 增量设计)+ **prototype**(本地 HTML 原型)+ **e2e**(AC 驱动 E2E)+ **workflow-orchestrator**(产品级编排)+ **workflow-bootstrap**(既有项目接入)。一次安装,十三套能力协同(详见下文「十三套能力」)。
|
|
6
6
|
|
package/docs/README_en.md
CHANGED
|
@@ -126,7 +126,7 @@ npm install -g team-flow
|
|
|
126
126
|
|
|
127
127
|
### Version
|
|
128
128
|
|
|
129
|
-
- Current: `v0.
|
|
129
|
+
- Current: `v0.63.0`
|
|
130
130
|
- v0.9.1 highlights: DP-4 execution-mode recommendations, a portable runtime across 17 platforms, and a raw-package smoke with no plugin-root variable.
|
|
131
131
|
- Self-contained — no OpenSpec or Superpowers runtime required
|
|
132
132
|
- Upstream: [Fission-AI/OpenSpec](https://github.com/Fission-AI/OpenSpec), [obra/superpowers](https://github.com/obra/superpowers)
|
package/docs/decision-points.md
CHANGED
|
@@ -131,6 +131,14 @@
|
|
|
131
131
|
|--------|----------|
|
|
132
132
|
| DP-0 + DP-A | `arch_design_decision == skipped` |
|
|
133
133
|
| DP-3 + G4 + DP-4 | 契约已产出且 hash 有效 |
|
|
134
|
+
| **DP-6 + roadmap/push 边界**(v0.63.0 新增) | closing 型变更(须机器门禁全 PASS 才生效) |
|
|
134
135
|
| DP-7 + 代码落地 + G5 | 恒成立 |
|
|
135
136
|
|
|
136
137
|
`arch_design_decision == required` 时 DP-A 必须独立(用户需单独审架构产物)。
|
|
138
|
+
|
|
139
|
+
**v0.63.0 攒批与预批复纪律**(feedback 20260923-013114 S5):
|
|
140
|
+
|
|
141
|
+
- **同根因攒批(MUST)**:同一根因的多个发现攒成**一次** ask,不逐个往返。
|
|
142
|
+
- **批量预批复单**:closing 型变更可一次性列出全部待确认项 + 建议取值 + 理由,由用户一次批复。
|
|
143
|
+
- **⛔ 防伪绿护栏**:**门禁类 DP(`dp_3` / `dp_4`)禁止超时代答**(二者是 `dp-gate-passed` 的门禁数据源,`checks/dp-gate-passed.mjs` 仅映射这两个);**预批复只作用于非门禁确认**;DP-6 预批复为**条件式**。
|
|
144
|
+
- **Rewind 作废**:Rewind 后已发出的预批复自动作废,须重新征询。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# team-flow 使用说明(研发团队版)
|
|
2
2
|
|
|
3
|
-
> 版本锚点:v0.
|
|
3
|
+
> 版本锚点:v0.63.0(28 skills + 17 agents)· 更新日期:2026-09-21
|
|
4
4
|
> 读者:使用 team-flow 做日常研发的工程师。不需要你懂插件内部实现,只需要照着路径走。
|
|
5
5
|
> 配套文档:安装细节见 [INSTALL.md](../INSTALL.md);状态机细节见 [state-machine.md](state-machine.md);决策点细节见 [decision-points.md](decision-points.md);平台差异见 [platform-matrix.md](platform-matrix.md)。
|
|
6
6
|
|
|
@@ -232,15 +232,15 @@ workflow-start 在初始化时自动推断(`tf runtime infer`),你也可
|
|
|
232
232
|
tf runtime guard check <change-dir> <from-state> <to-state> [--workflow full|hotfix|tweak]
|
|
233
233
|
```
|
|
234
234
|
|
|
235
|
-
**full 模式的完整转换矩阵**(
|
|
235
|
+
**full 模式的完整转换矩阵**(20 个维度 + 1 个 workflow 限制维度):
|
|
236
236
|
|
|
237
237
|
| 转换 | 维度 |
|
|
238
238
|
|------|------|
|
|
239
239
|
| exploring→specifying | arch-design、arch-readiness |
|
|
240
240
|
| specifying→bridging | artifacts-exist、schema-valid |
|
|
241
|
-
| bridging→approved-for-build | artifacts-exist、schema-valid、contract-fresh、dp-gate-passed、dp3-approved |
|
|
241
|
+
| bridging→approved-for-build | artifacts-exist、schema-valid、contract-fresh、dp-gate-passed、dp3-approved、**gates-probed**(v0.63.0) |
|
|
242
242
|
| approved-for-build→executing | artifacts-exist、contract-fresh、dp-gate-passed、execution-plan-ready、test-matrix-ready |
|
|
243
|
-
| **executing→closing** | **
|
|
243
|
+
| **executing→closing** | **11 维**:**contract-fresh(v0.63.0)**、tasks-complete、tests-passing、specs-merged、execution-plan-ready、execution-reviews-passed、compound-captured、test-matrix-complete、arch-snapshot、delegation-status、arch-merged |
|
|
244
244
|
| executing↔debugging | debugging 入口无门禁;回 executing 挂 contract-fresh、execution-plan-ready |
|
|
245
245
|
| exploring→bridging / exploring→approved-for-build | 0 维,但**一一对应**:`exploring→bridging` 仅 hotfix 可走、`exploring→approved-for-build` 仅 tweak 可走;full 走或其他组合都直接 FAIL |
|
|
246
246
|
| 7 条回退 + 6 条放弃 | 0 维(回退是合法操作,不需要门禁放行) |
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "team-flow",
|
|
3
3
|
"description": "Unified workflow plugin: team-flow (spec-driven dev) + compound-engineering core subset + architecture-design (4A/DDD) + prototype (local HTML) + business-analysis (independent requirement/scenario artifact) + jarvis (team-flow decision agent, opt-in). 28 skills, one install.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.63.0",
|
|
5
5
|
"contextFileName": "GEMINI.md"
|
|
6
6
|
}
|
package/hooks/session-start
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# v0.
|
|
2
|
+
# v0.63.0: auto-sync CLI version with plugin version
|
|
3
3
|
set -e
|
|
4
4
|
|
|
5
5
|
# ═══════════════════════════════════════════════════════════════
|
|
6
6
|
# Plugin version (update this when releasing new versions)
|
|
7
7
|
# ═══════════════════════════════════════════════════════════════
|
|
8
|
-
PLUGIN_VERSION="0.
|
|
8
|
+
PLUGIN_VERSION="0.63.0"
|
|
9
9
|
|
|
10
10
|
# ═══════════════════════════════════════════════════════════════
|
|
11
11
|
# Step 1: Auto-sync CLI version with plugin version
|
package/llms.txt
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
## Overview
|
|
4
4
|
spec-superflow is a self-contained workflow integration plugin for Claude Code, Cursor, OpenAI Codex CLI/App, GitHub Copilot CLI, Gemini CLI, OpenCode, WorkBuddy, and Trae. It merges spec-driven planning artifacts (proposal, specs, design, tasks) with disciplined execution guardrails (TDD, review gates, controlled handoff) into one unified workflow.
|
|
5
5
|
|
|
6
|
-
Current version: v0.
|
|
6
|
+
Current version: v0.63.0.
|
|
7
7
|
|
|
8
8
|
## Key Documents
|
|
9
9
|
- README.md: Chinese homepage with full usage guide and FAQ
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xulthekl/team-flow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.0",
|
|
4
4
|
"description": "Unified plugin (28 skills + 17 agents) integrating team-flow, compound-engineering, architecture-design, prototype, design-system, workflow-orchestrator, workflow-bootstrap, e2e, session-handoff, workflow-feedback, business-analysis for multi-agent coding tools.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
package/plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "team-flow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.0",
|
|
4
4
|
"description": "Unified workflow plugin: team-flow (spec-driven dev: TDD/SDD/code-review/debugging) + compound-engineering core subset (brainstorm/plan/compound/strategy/ideate/proof, global compounding) + architecture-design (4A+DDD incremental design & global compounding) + prototype (local HTML prototype, zero external deps) + e2e (Playwright E2E, AC-driven) + workflow-orchestrator (product-level workflow orchestration) + workflow-bootstrap (existing project onboarding) + session-handoff (context transfer) + workflow-feedback (issue tracking) + business-analysis (independent requirement/scenario artifact) + design-system (design tokens + component contract + AI primer + showcase) + test-strategy (test strategy design) + project-initialize (new service onboarding) + jarvis (team-flow decision agent, opt-in). 28 skills + 17 agents, one install.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "LT"
|
|
@@ -1,17 +1,61 @@
|
|
|
1
1
|
// scripts/guard/checks/contract-fresh.mjs — check contract staleness via hash comparison
|
|
2
|
+
//
|
|
3
|
+
// v0.63.0(workflow-feedback 20260923-013114 S3):本维度新增挂载到 executing:closing。
|
|
4
|
+
// 动机:S3「DP-3 后 planning 制品冻结」的反查锚——原本 closing 侧反查依赖
|
|
5
|
+
// execution-plan-ready(validatePlan 比对 plan 内嵌的 artifacts_hash/contract_hash),
|
|
6
|
+
// 而该比对可被 `tf execution refresh-hash` 一键刷平(它只改 plan JSON)→ 把 gate-affecting
|
|
7
|
+
// 变更伪记为陈述性勘误后,closing 全维 PASS、wave receipt 亦不失效(wave_fingerprint
|
|
8
|
+
// 不含 artifacts_hash)→ **伪绿静默通过**。本维度直接比对 state.artifacts_hash 与制品实算值,
|
|
9
|
+
// refresh-hash 无法清屏(它不碰 state),故为独立锚。
|
|
10
|
+
//
|
|
11
|
+
// 注意(卡死面):本维度**无 legacy 豁免**(与既有挂载点一致)——存量 change 在 closing
|
|
12
|
+
// 若状态文件缺 artifacts_hash 会被拦。故失败信息必须给出可执行出路(tf state rebuild),
|
|
13
|
+
// 不得让门禁成为无出口的闭门(参照 arch_merge_skipped 的设计原则)。
|
|
14
|
+
import fs from 'node:fs';
|
|
15
|
+
import path from 'node:path';
|
|
2
16
|
import { isContractFresh } from '../../lib/hash.mjs';
|
|
17
|
+
import { readState } from '../../lib/state-loader.mjs';
|
|
18
|
+
|
|
19
|
+
// v0.63.0(P4 评审 L3):裸 rebuild 会重算并覆盖 state.artifacts_hash——若发生在 DP-3 冻结之后,
|
|
20
|
+
// 它就成了与 refresh-hash 并列的「清屏」通道,且不留任何 errata 痕迹。故提示按时间点分流:
|
|
21
|
+
// 冻结前的改动可裸 rebuild;冻结后的改动必须走勘误登记/例外 2,不得用 rebuild 把差异抹平。
|
|
22
|
+
const REBUILD_HINT =
|
|
23
|
+
'If the planning change predates DP-3 approval, re-capture the hash: `tf state rebuild <dir>`. '
|
|
24
|
+
+ 'If it happened AFTER DP-3, the artifacts are FROZEN: record it in the contract `## Errata Register` '
|
|
25
|
+
+ 'under the applicable exception (doc-only corrections), or take the gate-affecting path rebuild->revise '
|
|
26
|
+
+ '(exception 2). Do NOT rebuild past a frozen change — that erases the diff without any errata trace.';
|
|
3
27
|
|
|
4
28
|
/**
|
|
5
29
|
* Compare stored artifacts_hash in .team-flow.yaml against current artifact hashes.
|
|
6
30
|
* Returns { pass, failures[] }.
|
|
7
31
|
*/
|
|
8
32
|
export function checkContractFresh(changeDir) {
|
|
9
|
-
|
|
10
|
-
if (fresh) {
|
|
33
|
+
if (isContractFresh(changeDir)) {
|
|
11
34
|
return { pass: true, failures: [] };
|
|
12
35
|
}
|
|
36
|
+
|
|
37
|
+
// 区分两类失败,给出各自的出路(否则关闭期死锁无指示)。
|
|
38
|
+
let stored = null;
|
|
39
|
+
try {
|
|
40
|
+
const state = readState(changeDir);
|
|
41
|
+
stored = state?.artifacts_hash ?? null;
|
|
42
|
+
} catch {
|
|
43
|
+
stored = null;
|
|
44
|
+
}
|
|
45
|
+
if (!stored || stored === 'null') {
|
|
46
|
+
return {
|
|
47
|
+
pass: false,
|
|
48
|
+
failures: [
|
|
49
|
+
'execution-contract.md freshness cannot be judged: the state file carries no artifacts_hash '
|
|
50
|
+
+ '(hand-written or truncated .team-flow.yaml). Re-capture it: `tf state rebuild <dir>`.',
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
13
55
|
return {
|
|
14
56
|
pass: false,
|
|
15
|
-
failures: [
|
|
57
|
+
failures: [
|
|
58
|
+
`execution-contract.md is stale: artifacts hash mismatch. ${REBUILD_HINT}`,
|
|
59
|
+
],
|
|
16
60
|
};
|
|
17
|
-
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// scripts/guard/checks/gates-probed.mjs — bridging dry-run evidence gate
|
|
2
|
+
//
|
|
3
|
+
// v0.63.0(workflow-feedback 20260923-013114 S2):
|
|
4
|
+
// full workflow 的 bridging→approved-for-build 新增本维度——契约产出的 G 类闸门
|
|
5
|
+
// 必须已在**主工作区当前态**跑过 dry-run(预期 FAIL = RED 基线),原始输出留档。
|
|
6
|
+
// 动机:`design.md` R-7「闸门命令已实测可跑」长期只是**文字自证**;实测中 G1 格式约束、
|
|
7
|
+
// grep shim、dist 误入扫描、desc 文案 vs G2 互斥均在施工中才暴露。
|
|
8
|
+
//
|
|
9
|
+
// **存在性强制(Critical 处置,不得退回内容型豁免)**:
|
|
10
|
+
// 契约缺 `## Gate Registry` 段 / 表解析失败 → **FAIL**,不得落入 N/A 放行。
|
|
11
|
+
// 依据:v0.13 RC-1 已删除「以 contract 内容为键」的豁免——test-gate-exemptions.mjs
|
|
12
|
+
// :7-10 明文记载「无法区分真存量与漏生成,导致零测试通过全部门禁」;既有先例
|
|
13
|
+
// `contractDeclaresTestMatrix` 走的是段存在性硬要求。本 check 复刻该先例。
|
|
14
|
+
//
|
|
15
|
+
// 与 test-matrix-ready(:49 入口门禁)同构:legacy 豁免 + 显式 skip 附理由。
|
|
16
|
+
import fs from 'node:fs';
|
|
17
|
+
import path from 'node:path';
|
|
18
|
+
import { readState } from '../../lib/state-loader.mjs';
|
|
19
|
+
import { computeContractHash } from '../../lib/hash.mjs';
|
|
20
|
+
import { isLegacyChange } from './test-gate-exemptions.mjs';
|
|
21
|
+
|
|
22
|
+
export const EVIDENCE_REL = path.join('.superpowers', 'test-evidence', 'bridging-gates-red.txt');
|
|
23
|
+
const REGISTRY_HEADING = '## Gate Registry';
|
|
24
|
+
const RED_BASELINE_LINE = 'EXPECTED: FAIL (RED baseline)';
|
|
25
|
+
const SKIP_REASON_HINT =
|
|
26
|
+
'gates_probed_skipped=true requires gates_probed_skip_reason — record it: '
|
|
27
|
+
+ "tf state set <dir> gates_probed_skip_reason '<why this change has no gate dry-run>'";
|
|
28
|
+
|
|
29
|
+
/** 提取 '## Gate Registry' 段正文(到下一个同级标题或文件尾)。 */
|
|
30
|
+
export function extractRegistrySection(contractText) {
|
|
31
|
+
const lines = contractText.split(/\r?\n/);
|
|
32
|
+
const start = lines.findIndex((l) => l.trim() === REGISTRY_HEADING);
|
|
33
|
+
if (start === -1) return null;
|
|
34
|
+
const body = [];
|
|
35
|
+
for (let i = start + 1; i < lines.length; i += 1) {
|
|
36
|
+
if (/^##\s/.test(lines[i])) break;
|
|
37
|
+
body.push(lines[i]);
|
|
38
|
+
}
|
|
39
|
+
return body.join('\n');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 解析 Gate Registry 表格的 id 列。
|
|
44
|
+
* 表头固定 `| id | phase | command | expected |`;id 形如 G-1。
|
|
45
|
+
* @returns {string[]} id 列表(去重,出现顺序)
|
|
46
|
+
*/
|
|
47
|
+
export function parseGateIds(sectionBody) {
|
|
48
|
+
const ids = [];
|
|
49
|
+
for (const line of sectionBody.split(/\r?\n/)) {
|
|
50
|
+
if (!line.trim().startsWith('|')) continue;
|
|
51
|
+
const cells = line.split('|').map((c) => c.trim());
|
|
52
|
+
// cells[0] === ''(前导竖线),故首列在 index 1
|
|
53
|
+
const first = cells[1] || '';
|
|
54
|
+
if (!first || /^-+$/.test(first) || first.toLowerCase() === 'id') continue;
|
|
55
|
+
if (!ids.includes(first)) ids.push(first);
|
|
56
|
+
}
|
|
57
|
+
return ids;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** 段内显式声明零闸门 + 理由(形如 `N/A: <理由>`)。 */
|
|
61
|
+
export function declaredNotApplicable(sectionBody) {
|
|
62
|
+
const m = sectionBody.match(/(?:^|\n)\s*(?:N\/A|NA)\s*[::]\s*(.+)/i);
|
|
63
|
+
return m ? m[1].trim() : null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Returns { pass, failures[], reason? }.
|
|
68
|
+
*/
|
|
69
|
+
export function checkGatesProbed(changeDir) {
|
|
70
|
+
const state = readState(changeDir);
|
|
71
|
+
|
|
72
|
+
// Exemption 1:legacy change(v0.32.0 之前初始化,无 schema_version 打戳)。
|
|
73
|
+
if (isLegacyChange(state)) {
|
|
74
|
+
return { pass: true, failures: [], reason: 'legacy change — initialized before v0.32.0' };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Exemption 2:显式 skip(必须附理由)。
|
|
78
|
+
if (state.gates_probed_skipped === 'true') {
|
|
79
|
+
const reason = state.gates_probed_skip_reason;
|
|
80
|
+
if (typeof reason !== 'string' || reason.trim().length === 0) {
|
|
81
|
+
return { pass: false, failures: [SKIP_REASON_HINT] };
|
|
82
|
+
}
|
|
83
|
+
return { pass: true, failures: [], reason: `explicitly skipped: ${reason}` };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// 段存在性硬要求(fail-closed):缺段 / 解析失败一律 FAIL,不得落 N/A。
|
|
87
|
+
const contractPath = path.join(changeDir, 'execution-contract.md');
|
|
88
|
+
if (!fs.existsSync(contractPath)) {
|
|
89
|
+
return { pass: false, failures: ['execution-contract.md is missing — run contract-builder first'] };
|
|
90
|
+
}
|
|
91
|
+
const contractText = fs.readFileSync(contractPath, 'utf-8');
|
|
92
|
+
const section = extractRegistrySection(contractText);
|
|
93
|
+
if (section === null) {
|
|
94
|
+
return {
|
|
95
|
+
pass: false,
|
|
96
|
+
failures: [
|
|
97
|
+
`contract does not declare ${REGISTRY_HEADING} — return to bridging so contract-builder generates it.`,
|
|
98
|
+
'A missing section is NOT a "no gates" declaration: absence of the registry cannot be distinguished '
|
|
99
|
+
+ 'from an omitted registry (v0.13 RC-1 content-key exemption was removed for exactly this reason).',
|
|
100
|
+
'If this change genuinely has no gates, write the section with an explicit "N/A: <reason>" line.',
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const gateIds = parseGateIds(section);
|
|
105
|
+
|
|
106
|
+
// N/A:段存在 + 显式声明零闸门 + 理由(state 键为备用通道)。
|
|
107
|
+
if (gateIds.length === 0) {
|
|
108
|
+
const naReason = declaredNotApplicable(section);
|
|
109
|
+
if (naReason) {
|
|
110
|
+
return { pass: true, failures: [], reason: `not applicable — ${naReason}` };
|
|
111
|
+
}
|
|
112
|
+
if (state.gates_probed_na === 'true') {
|
|
113
|
+
return { pass: true, failures: [], reason: 'not applicable — gates_probed_na set in state' };
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
pass: false,
|
|
117
|
+
failures: [
|
|
118
|
+
`${REGISTRY_HEADING} present but declares no gate id and no "N/A: <reason>" line.`,
|
|
119
|
+
'Either list the gates (| id | phase | command | expected |) or state "N/A: <reason>".',
|
|
120
|
+
],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 正常路径:evidence 文件 + 首行 RED 基线 + hash 值新鲜 + id 全覆盖。
|
|
125
|
+
const evidencePath = path.join(changeDir, EVIDENCE_REL);
|
|
126
|
+
if (!fs.existsSync(evidencePath)) {
|
|
127
|
+
return {
|
|
128
|
+
pass: false,
|
|
129
|
+
failures: [
|
|
130
|
+
`${EVIDENCE_REL} is missing — run the bridging gate dry-run (expect FAIL = RED baseline) `
|
|
131
|
+
+ 'and persist the raw output there.',
|
|
132
|
+
'Required first line: ' + RED_BASELINE_LINE,
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const evidence = fs.readFileSync(evidencePath, 'utf-8');
|
|
137
|
+
const failures = [];
|
|
138
|
+
const evidenceLines = evidence.split(/\r?\n/);
|
|
139
|
+
const firstNonEmpty = evidenceLines.find((l) => l.trim().length > 0) || '';
|
|
140
|
+
if (firstNonEmpty.trim() !== RED_BASELINE_LINE) {
|
|
141
|
+
failures.push(
|
|
142
|
+
`evidence first line must be exactly "${RED_BASELINE_LINE}", got: "${firstNonEmpty.trim().slice(0, 80)}". `
|
|
143
|
+
+ 'A gate that already PASSES means the baseline was not RED — record the expected-FAIL run instead.',
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// 新鲜度 = hash 值比对(非 mtime):
|
|
148
|
+
// refresh-hash / state rebuild 均不重写契约文件,故 mtime 判据只会在「契约字节等价重生成」
|
|
149
|
+
// 或 git 恢复场景下误报;hash 值比对天然免疫。
|
|
150
|
+
const contractHash = computeContractHash(changeDir);
|
|
151
|
+
const hashMatch = evidence.match(/CONTRACT_HASH:\s*(sha256:[0-9a-f]{64})/);
|
|
152
|
+
if (!hashMatch) {
|
|
153
|
+
failures.push(
|
|
154
|
+
'evidence must carry a "CONTRACT_HASH: sha256:<64 hex>" line so freshness is judged by content, not mtime.',
|
|
155
|
+
);
|
|
156
|
+
} else if (contractHash && hashMatch[1] !== contractHash) {
|
|
157
|
+
failures.push(
|
|
158
|
+
`evidence is stale: CONTRACT_HASH ${hashMatch[1].slice(0, 20)}… does not match current contract `
|
|
159
|
+
+ `${String(contractHash).slice(0, 20)}… — re-run the dry-run against the current contract.`,
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const missingIds = gateIds.filter((id) => {
|
|
164
|
+
const esc = id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
165
|
+
return !new RegExp(`(^|[^\\w-])${esc}([^\\w-]|$)`).test(evidence);
|
|
166
|
+
});
|
|
167
|
+
if (missingIds.length > 0) {
|
|
168
|
+
failures.push(
|
|
169
|
+
`evidence does not cover declared gate id(s): ${missingIds.join(', ')} — every id in ${REGISTRY_HEADING} needs a dry-run record.`,
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (failures.length > 0) return { pass: false, failures };
|
|
174
|
+
return { pass: true, failures: [] };
|
|
175
|
+
}
|
package/scripts/guard/guard.mjs
CHANGED
|
@@ -16,6 +16,7 @@ import { checkExecutionReviewsPassed } from './checks/execution-reviews-passed.m
|
|
|
16
16
|
import { checkCompoundCaptured } from './checks/compound-captured.mjs';
|
|
17
17
|
import { checkTestMatrixComplete } from './checks/test-matrix-complete.mjs';
|
|
18
18
|
import { checkTestMatrixReady } from './checks/test-matrix-ready.mjs';
|
|
19
|
+
import { checkGatesProbed } from './checks/gates-probed.mjs';
|
|
19
20
|
import { checkArchReadiness } from './checks/arch-readiness.mjs';
|
|
20
21
|
import { checkArchSnapshot } from './checks/arch-snapshot.mjs';
|
|
21
22
|
import { checkArchMerged } from './checks/arch-merged.mjs';
|
|
@@ -39,7 +40,12 @@ const TRANSITION_CHECKS = {
|
|
|
39
40
|
// 任何能写 dp_3_result 的主体(含夜间替身的 HOLD 落盘)都能让 change 呈现"已批准"假象,
|
|
40
41
|
// 从而在无真实批准的前提下跨过 DP-3 硬门。本维度要求取值以 "approved" 开头
|
|
41
42
|
// (判据实现见 checks/dp3-approved.mjs)。
|
|
42
|
-
|
|
43
|
+
// v0.63.0(workflow-feedback 20260923-013114 S2):**gates-probed 新增**——契约的 G 类闸门
|
|
44
|
+
// 必须在 bridging 期跑过 dry-run(预期 FAIL = RED 基线)并留档,把 design.md R-7 长期存在的
|
|
45
|
+
// 「闸门已实测可跑」文字自证物化为机械证据。检查五件:evidence 存在 / 首行 RED 基线 /
|
|
46
|
+
// CONTRACT_HASH 值新鲜 / 契约 Gate Registry 的 id 逐 id 覆盖 / **段缺失即 FAIL(fail-closed)**。
|
|
47
|
+
// hotfix 走 WORKFLOW_TRANSITION_CHECKS 自有覆盖(下方),tweak 由 skip 回退阀放行。
|
|
48
|
+
'bridging:approved-for-build': ['artifacts-exist', 'schema-valid', 'contract-fresh', 'dp-gate-passed', 'dp3-approved', 'gates-probed'],
|
|
43
49
|
// v0.13 §49:test-matrix-ready 门禁前移——full 模式进入 executing 前强制测试准备度
|
|
44
50
|
//(矩阵存在非空 OR 显式 skip 附理由;legacy 豁免)。hotfix/tweak 沿用 §45.3 豁免,不挂。
|
|
45
51
|
'approved-for-build:executing': ['artifacts-exist', 'contract-fresh', 'dp-gate-passed', 'execution-plan-ready', 'test-matrix-ready'],
|
|
@@ -51,7 +57,15 @@ const TRANSITION_CHECKS = {
|
|
|
51
57
|
// 且 arch-merge 在状态机上无任何锚点(VALID_STATES 无 closed、closing→closed 不存在)。
|
|
52
58
|
// B' 把 arch-merge 前移到本转换**之前**,本维度即其前置条件。
|
|
53
59
|
// hotfix/tweak 沿用既有豁免口径(WORKFLOW_TRANSITION_CHECKS 各自列维度,天然不挂)。
|
|
54
|
-
|
|
60
|
+
// v0.63.0(feedback 20260923-013114 S3):**contract-fresh 新增**——S3「DP-3 后规划制品冻结」
|
|
61
|
+
// 的反查锚。原状 closing 无 contract-fresh,反查实际依赖 execution-plan-ready(validatePlan
|
|
62
|
+
// 比对 plan 内嵌的 artifacts_hash/contract_hash),而该比对可被 `tf execution refresh-hash`
|
|
63
|
+
// 一键刷平(refreshPlanHash 直接改写 plan JSON、revision 不升)→ 把 gate-affecting 变更
|
|
64
|
+
// 伪记为陈述性勘误后,closing 全维 PASS、wave receipt 亦不失效(wave_fingerprint 不含
|
|
65
|
+
// artifacts_hash)→ **伪绿静默通过**。本维度直接比对 state.artifacts_hash 与制品实算值,
|
|
66
|
+
// refresh-hash 无法清屏(它只改 plan JSON,不碰 state)——故为 refresh-hash 之外的独立锚。
|
|
67
|
+
// hotfix/tweak 不挂:二者跳过 spec-writer、无 planning 四件,冻结机制本身 N/A(设计 §3.9)。
|
|
68
|
+
'executing:closing': ['contract-fresh', 'tasks-complete', 'tests-passing', 'specs-merged', 'execution-plan-ready', 'execution-reviews-passed', 'compound-captured', 'test-matrix-complete', 'arch-snapshot', 'delegation-status', 'arch-merged'],
|
|
55
69
|
|
|
56
70
|
// Debugging side-path
|
|
57
71
|
'executing:debugging': [],
|
|
@@ -200,6 +214,7 @@ async function main() {
|
|
|
200
214
|
'compound-captured': (dir) => checkCompoundCaptured(dir),
|
|
201
215
|
'test-matrix-complete': (dir) => checkTestMatrixComplete(dir),
|
|
202
216
|
'test-matrix-ready': (dir) => checkTestMatrixReady(dir),
|
|
217
|
+
'gates-probed': (dir) => checkGatesProbed(dir),
|
|
203
218
|
'arch-readiness': (dir) => checkArchReadiness(dir),
|
|
204
219
|
'arch-snapshot': (dir) => checkArchSnapshot(dir),
|
|
205
220
|
'arch-merged': (dir) => checkArchMerged(dir),
|
|
@@ -45,6 +45,10 @@ const SETTABLE_FIELDS = [
|
|
|
45
45
|
'tasks_skipped', 'tasks_skip_reason',
|
|
46
46
|
// Arch merge gate (v0.53.0 §110.2:arch-merged guard 维度的显式跳过键,须附理由)
|
|
47
47
|
'arch_merge_skipped', 'arch_merge_skip_reason',
|
|
48
|
+
// Bridging gates dry-run gate (v0.63.0;feedback 20260923-013114 S2)
|
|
49
|
+
// 三键必须与 state-loader BUILTIN_DEFAULTS + writeState 序列化分支同步注册,
|
|
50
|
+
// 缺任一环即「回显成功却零写入」(v0.59.0 同型教训,见本文件 :20-24 注释)。
|
|
51
|
+
'gates_probed_skipped', 'gates_probed_skip_reason', 'gates_probed_na',
|
|
48
52
|
];
|
|
49
53
|
|
|
50
54
|
export async function run(args) {
|
|
@@ -83,6 +83,13 @@ const BUILTIN_DEFAULTS = {
|
|
|
83
83
|
// `change:<name>`,若不给跳过键则 guard 永久 FAIL 无出路)。
|
|
84
84
|
arch_merge_skipped: null,
|
|
85
85
|
arch_merge_skip_reason: null,
|
|
86
|
+
// Bridging gates dry-run gate (v0.63.0;feedback 20260923-013114 S2)
|
|
87
|
+
// gates-probed 挂 full 的 bridging→approved-for-build;hotfix 走 WORKFLOW_TRANSITION_CHECKS
|
|
88
|
+
// 自有覆盖自动豁免;**tweak 无该键的覆盖条目 → 回落继承本维度**,故 tweak 必须靠
|
|
89
|
+
// gates_probed_skipped 放行——缺此键则 tweak 硬卡死(三处管道缺一不可)。
|
|
90
|
+
gates_probed_skipped: null,
|
|
91
|
+
gates_probed_skip_reason: null,
|
|
92
|
+
gates_probed_na: null,
|
|
86
93
|
// 注意:schema_version 故意不在 BUILTIN_DEFAULTS 中(v0.13 §48.1)——
|
|
87
94
|
// 它只由 `tf state init` 在 change 创建时打戳,字段缺失本身就是"存量 change"信号。
|
|
88
95
|
};
|
|
@@ -213,6 +220,11 @@ export function writeState(changeDir, state) {
|
|
|
213
220
|
lines.push('# === Arch merge gate (v0.53.0 §110.2) ===');
|
|
214
221
|
lines.push(`arch_merge_skipped: ${state.arch_merge_skipped ?? 'null'}`);
|
|
215
222
|
lines.push(`arch_merge_skip_reason: ${state.arch_merge_skip_reason ?? 'null'}`);
|
|
223
|
+
lines.push('');
|
|
224
|
+
lines.push('# === Bridging gates dry-run gate (v0.63.0) ===');
|
|
225
|
+
lines.push(`gates_probed_skipped: ${state.gates_probed_skipped ?? 'null'}`);
|
|
226
|
+
lines.push(`gates_probed_skip_reason: ${state.gates_probed_skip_reason ?? 'null'}`);
|
|
227
|
+
lines.push(`gates_probed_na: ${state.gates_probed_na ?? 'null'}`);
|
|
216
228
|
|
|
217
229
|
fs.writeFileSync(filePath, lines.join('\n') + '\n', 'utf-8');
|
|
218
230
|
}
|
|
@@ -131,18 +131,9 @@ For full/hotfix by default. Execute waves as dispatched by workflow-start.
|
|
|
131
131
|
1. Read the current plan with `tf execution show <change-dir> --json`; only waves shown with `current: true` and `eligible: true` may start. A `retryable: true` wave may only be repaired and re-reviewed; do not dispatch its dependents until its replacement receipt is `pass`. The CLI encodes dependencies in `--wave <id>:<strategy>:<tasks>[:<depends-on,...>]` and rejects a review receipt for a wave whose prerequisites lack current `pass` receipts.
|
|
132
132
|
2. A `parallel` wave may dispatch independent tasks simultaneously only when the platform supports concurrent dispatch. If it does not, disclose the unavailable capability and execute the same wave one task at a time without changing its stored strategy.
|
|
133
133
|
3. A `serial` wave dispatches one task at a time in listed order.
|
|
134
|
-
4.
|
|
134
|
+
4. **case↔test 对账(v0.63.0;feedback 20260923-013114 S4,MUST,不过不许报完成)**:产出 `.superpowers/test-evidence/<wave>-case-test-reconciliation.md`——口径见下方 `### Wave Case↔Test Reconciliation (v0.63.0)
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
Notify with:
|
|
139
|
-
- Wave ID
|
|
140
|
-
- Worktree path
|
|
141
|
-
- Branch
|
|
142
|
-
- Repositories and commit SHAs (base + head)
|
|
143
|
-
- Summary of changes
|
|
144
|
-
5. **Do not** attempt to dispatch code-reviewer or write review receipts — that is workflow-start's responsibility.
|
|
145
|
-
6. Critical/Important findings require a `fail` receipt, a focused repair, re-review, then a replacement `pass` receipt. Never advance or close with a missing or failed receipt.
|
|
136
|
+
**交付自检(MUST,不过不许报完成)**:每个 wave 完成时产出 `.superpowers/test-evidence/<wave>-case-test-reconciliation.md`(case id → 测试文件 → 方法名 → 断言点)。**完成门 = 机械层(case_id↔文件)+ 半机械层(方法名)通过即放行**;**断言点层归 code-reviewer Step 5b,不构成本步条件**(防卡死、防自填假证据)。不进 receipt JSON / 不进 test-matrix hash / 不新增 guard 维度。三层判据表、无脚本降级模板、N/A 落盘、升级路径与复用评估见 `references/wave-delivery-selfcheck.md`。
|
|
146
137
|
|
|
147
138
|
### Wave Verify: Actual Test Count (v0.43.1)
|
|
148
139
|
|
|
@@ -152,6 +143,10 @@ For full/hotfix by default. Execute waves as dispatched by workflow-start.
|
|
|
152
143
|
2. 对照 test-matrix 当前 wave 覆盖的用例数(**分母排除 `test_tier=e2e`**——E2E case 由 Playwright 执行,不进入 `mvn test`/`npm test` 的 `Tests run: N`,口径与 code-reviewer Step 5b / release-archivist Step 2b 一致):实际执行数明显低于预期(< 70%)→ **警告 + 调查**(@Nested 静默跳过、测试未被发现、编译期跳过等),未查明前不得报告 "N tests pass"。
|
|
153
144
|
3. 报告引用实际执行数(按 runner 的计数口径),而非 BUILD SUCCESS 或编译通过数量。
|
|
154
145
|
|
|
146
|
+
### Gate-Only Wave Receipt Protocol (v0.63.0)
|
|
147
|
+
|
|
148
|
+
**零代码/纯闸门波次**的 receipt 范围:以根仓 planning commit(`tf publish --changes` 产物)作 base..head(`base` = 其父提交、`head` = 该 commit 本身)。**⚠️ 执行者 = workflow-start**(本 agent 不得自行写 receipt)。**若 G4 尚未执行:先按 G4 纪律完成 AskUserQuestion → 再 publish → 再建 receipt**,不得静默代替用户选择。**⛔ 有代码的波次不得借用。** 细则见 `references/wave-delivery-selfcheck.md`。
|
|
149
|
+
|
|
155
150
|
### Per-Task Loop
|
|
156
151
|
1. **Dispatch implementer**: Load the template with `tf runtime asset read skills/build-executor/implementer-prompt.md`. Extract task brief with `scripts/task-brief PLAN_FILE N`. Include: where task fits, brief path, interfaces from prior tasks, report file path.
|
|
157
152
|
2. **Handle response**: DONE → generate review package + dispatch reviewer. DONE_WITH_CONCERNS → assess. NEEDS_CONTEXT → provide context. BLOCKED → re-dispatch with better model or escalate.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# 波次交付自检(v0.63.0;feedback 20260923-013114 S4 + E2)
|
|
2
|
+
|
|
3
|
+
本文件承载 build-executor SKILL 中两个「每次波次都要执行」的流程细节。SKILL 保留 MUST 与指针,细则在此。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 一、case↔test 对账(S4)
|
|
8
|
+
|
|
9
|
+
**来源**:v2-C2 实测——矩阵↔测试两份手写文本漂移(I-1 测试缺矩阵 expected 子断言 / M-1 方法名漂移 /
|
|
10
|
+
M-2 expected 与实测矛盾)**全部在 code-reviewer 才抓出**,引发修复 + 复审一整轮。本步把「事后抓漂移」前移为「交付自检」。
|
|
11
|
+
|
|
12
|
+
**产出**:`.superpowers/test-evidence/<wave>-case-test-reconciliation.md`,本 wave 覆盖的每个矩阵 case 一行:
|
|
13
|
+
|
|
14
|
+
```markdown
|
|
15
|
+
| case_id | 测试文件 | 方法名 | 断言点 | 备注 |
|
|
16
|
+
|---|---|---|---|---|
|
|
17
|
+
| Svc-create-001 | src/test/java/.../XxxServiceTest.java | shouldCreate_whenValid() | assertThat(status).isEqualTo(...) | — |
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### 三层判据(按可判定性分层,不搞一刀切)
|
|
21
|
+
|
|
22
|
+
| 层 | 判据 | 谁判 | 是否构成本步完成条件 |
|
|
23
|
+
|---|---|---|---|
|
|
24
|
+
| `case_id` ↔ 测试文件 | **机械**——矩阵 12 列格式本就含 `test_file` / `test_method_name` 列 | 脚本比对 | **是** |
|
|
25
|
+
| 方法名 | **半机械**——可 grep 校验;矩阵一行对多测试时须在备注注明拆分;`@ParameterizedTest` 一方法对多 case 时 grep 仍命中文件,case↔参数行语义归审查侧 | 脚本提示 + 人工确认 | **是** |
|
|
26
|
+
| 断言点 | **审查侧**——语义对应,机器不可判 | code-reviewer Step 5b | **否**——归审查侧,**不构成本步的完成条件**,本步不得因它卡住或自证 |
|
|
27
|
+
|
|
28
|
+
> **完成门(防卡死/防造假)**:**机械层 + 半机械层两层通过 → 本步放行**(可进入下一步通知 wave 完成)。
|
|
29
|
+
> 断言点层由 code-reviewer 独立复核,实施方**不需要也不得**为其自证——否则会逼出「自填断言点」的假自证。
|
|
30
|
+
|
|
31
|
+
### 硬边界(MUST NOT 越界)
|
|
32
|
+
|
|
33
|
+
- **不进 receipt JSON**(`execution-plan.mjs` 的 `savedReceipt` 字段白名单会静默丢弃);
|
|
34
|
+
- **不进 test-matrix hash**(`hash.mjs computeTestMatrixHash` 防自循环设计);
|
|
35
|
+
- **不新增 guard 维度**——走「evidence 文件 + 报告引用」的既有哲学。
|
|
36
|
+
|
|
37
|
+
**反向回填限缩**:允许**仅方法名**从测试回同步矩阵;**expected 禁止由测试反生成**(防 oracle 循环)。
|
|
38
|
+
|
|
39
|
+
### N/A 与无脚本降级
|
|
40
|
+
|
|
41
|
+
- **N/A 落盘位置**:无矩阵的 change(hotfix/tweak,legacy 豁免)→ 在**同一 evidence 文件**内写
|
|
42
|
+
`N/A: <理由>`(文件仍须存在,保持「有产物可查」的一致性),**不得**静默跳过。
|
|
43
|
+
- **机械层脚本不存在时**(team-flow 不内置,脚本由项目侧提供):降级为人工执行同口径比对——
|
|
44
|
+
```bash
|
|
45
|
+
# 矩阵 test_file 列 → 文件存在性
|
|
46
|
+
command grep -nE '^\|' test-matrix.md | … # 逐行取 case_id / test_file
|
|
47
|
+
test -s <test_file> # 存在且非空
|
|
48
|
+
# test_method_name 列 → 源文件内 grep
|
|
49
|
+
command grep -rn "<method_name>" <test_file>
|
|
50
|
+
```
|
|
51
|
+
**原始输出先落文件**再计数(判据四条),并在对账表末尾注明「机械层为人工降级执行」。
|
|
52
|
+
- **升级**:对账反复不过(≥2 轮)→ 根因属纯文本订正走 doc-only 收口波次;**根因属矩阵 expected/方法名本身错**
|
|
53
|
+
→ 走契约勘误的 gate-affecting 通道(rebuild→revise),**不得**以 doc-only 绕过。
|
|
54
|
+
|
|
55
|
+
**复用评估(已做,勿重复)**:glaf4-dev 的 case 级对账实现
|
|
56
|
+
(`glaf4-dev/0.6.2/scripts/gates/spring_contract_check.py`——case_id ↔ 测试方法「恰一个」匹配 + fail-closed 报告结构)
|
|
57
|
+
**算法与报告形态可借鉴,实现不可直接复用**:其硬绑 Java/Spring(`.java` 后缀、surefire 报告),
|
|
58
|
+
而 team-flow 的 change 跨 JS/Java/Kotlin 多栈,须泛化重写。
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 二、Gate-Only 波次 receipt 协议(E2)
|
|
63
|
+
|
|
64
|
+
> **执行者 = workflow-start,不是本 agent。** receipt 由 workflow-start 组装并写入
|
|
65
|
+
> (见 SKILL `### Planned-Wave Loop` 第 6 条:build-executor **不得**自行 dispatch reviewer 或写 receipt)。
|
|
66
|
+
> 本文件记录该协议,**供 workflow-start 在组装 `--base/--head` 时遵循**;build-executor 只需在报告中提供
|
|
67
|
+
> 「本波次无代码提交」这一事实,**不自行构造范围**。
|
|
68
|
+
|
|
69
|
+
**现状**:`tf execution review` 的 `validateResolvedRange` 拒绝 `base == head`(**防伪设计,非缺陷**)——
|
|
70
|
+
但纯闸门/制品型波次**没有代码提交**,每次都要人肉发明一个范围(v2-C1 wave4 与 v2-C2 w3 已重复 ≥2 次)。
|
|
71
|
+
|
|
72
|
+
**固化协议**:纯闸门 / 零代码波次,以**根仓 planning commit**(`tf publish --changes` 的产物)作 receipt 范围:
|
|
73
|
+
|
|
74
|
+
| 项 | 取值 |
|
|
75
|
+
|---|---|
|
|
76
|
+
| `base` | planning commit 的**父提交** |
|
|
77
|
+
| `head` | planning commit **本身** |
|
|
78
|
+
|
|
79
|
+
**若该波次的 G4(阶段产物同步门禁点,§68.2)尚未执行**:G4 本身是一个**阻塞 AskUserQuestion**
|
|
80
|
+
(A 提交并推送 / B 仅提交不推送 / C 暂不同步),**不得静默代替用户选择**。故此处不是「选 C 直接补 publish」,
|
|
81
|
+
而是:
|
|
82
|
+
|
|
83
|
+
1. **按 G4 纪律完成询问**(本场景通常倾向 B「仅提交不推送」——planning commit 只需落地为 receipt 基线,未必需要推送);
|
|
84
|
+
2. 用户批复后,按其选择执行 `tf publish --changes`;
|
|
85
|
+
3. **再**以该 commit 组装 receipt 的 base..head。
|
|
86
|
+
|
|
87
|
+
> 若跳过询问静默执行,等于替用户决定了 G4 的结果——**收据先于闸门 = 伪绿方向**。
|
|
88
|
+
> 反过来把 G4 延到下一波次同样脱节。所以唯一正确顺序是「先问 → 再 publish → 再建 receipt」。
|
|
89
|
+
|
|
90
|
+
- **⛔ 有代码的波次不得借用本协议**——它不是放宽范围校验的口子,只为消掉「每次重新发明」的浪费。
|
|
91
|
+
- **命名空间提示**:本协议的 `G4` 属**团队同步点编号 G1–G5**;契约 `## Gate Registry` 里的 `G-1`/`G-2`
|
|
92
|
+
是**命令型质量闸门**编号——**两套编号互不相干**,不要混用。
|
|
@@ -107,6 +107,8 @@ Run `tf solutions inject --phase review --limit 15` (never blocks on failure)
|
|
|
107
107
|
3. Read `design.md` to understand architectural decisions
|
|
108
108
|
4. Get the list of changed files: `git diff --name-only BASE..HEAD` or from the change directory
|
|
109
109
|
|
|
110
|
+
5. **根仓 planning 制品 diff 单列(v0.63.0;S3 例外 2 判定,MUST)**:多仓场景下 `BASE..HEAD` 解析到**子仓**,而 planning 四件在**根仓** `changes/<change-name>/`——子仓 diff 里**看不到它们是否被改**。故须额外单列 `proposal.md` / `specs/` / `design.md` / `tasks.md` / `execution-contract.md` 的 diff(相对 DP-3 批准时点)。**基线获取**:优先取 G4 publish 产生的 planning commit;无则 `git log --format=%H --before='<dp_3_timestamp>' -- <paths>` 取最后提交;仍无(未跟踪文件)则以 `state.artifacts_hash` 不匹配为触发信号,diff 工作区 vs HEAD 并在报告注明「基线降级」。判定:有改动 + 已登记 `## Errata Register` 且判定依据成立 → 通过;有改动 + 未登记,或实为 gate-affecting(矩阵 `expected`/方法名、闸门基线数字、`## Test Matrix` 段)→ **Critical finding**(`frozen-artifact-modified`)。**不采信实施方对「陈述性」的自判**——判定权在本步。
|
|
111
|
+
|
|
110
112
|
### Step 1b: File Existence Check (前置, v0.43.1)
|
|
111
113
|
|
|
112
114
|
在 spec-compliance 之前校验 tasks.md 声明的文件是否实际落地(设计增强方案 v0.18 §75,来源:workflow-feedback 2026-08-06——build-executor 标记 Task 完成但文件未创建,审查未发现直到 closing):
|
|
@@ -160,6 +162,8 @@ Check for:
|
|
|
160
162
|
|
|
161
163
|
If `test-matrix.md` exists in the change directory, audit the implementation against it:
|
|
162
164
|
|
|
165
|
+
> **与 build-executor 对账表的关系(v0.63.0,S4)**:build-executor 的 `.superpowers/test-evidence/<wave>-case-test-reconciliation.md` 是**交付自检**(左移)。**本步独立复核权不减免**(审查侧不采信实施方自查);对账表可作交叉线索,但**不得**以它「已过」替代逐 case 核验。两者是「左移 + 复核」两条路径,非重复劳动。
|
|
166
|
+
|
|
163
167
|
1. **Case-by-case verification**: For each case in the matrix:
|
|
164
168
|
- Check if the test implementation exists (`test_file` + `test_method_name` match)
|
|
165
169
|
- Verify assertions match the matrix's `expected` output
|
|
@@ -36,6 +36,10 @@ Before finalizing:
|
|
|
36
36
|
|
|
37
37
|
Must make obvious: approved behavior, out-of-scope, constraints, batches, test obligations, review gates, and conditions that force a rewind to planning. Prefer compression over repeating planning details.
|
|
38
38
|
|
|
39
|
+
**`## Errata Register`(勘误登记段,v0.63.0 新增)**:DP-3 批准后 planning 四件默认**冻结**,陈述性订正改记入契约的 `## Errata Register` 段(不改 planning 原文),以减少 `artifacts_hash` 漂移 → rebuild → revise 回路。段模板、六条冻结例外、三分处方表(matrix→rebuild / 契约段→refresh-hash / wave→revise)、**勘误写入后 MUST `tf execution refresh-hash`** 的操作序、以及例外 2 的判定升格与呈报纪律——**详见 `references/freeze-and-errata.md`(MUST 按该文件执行)**。
|
|
40
|
+
|
|
41
|
+
**`## Gate Registry`(闸门登记段,v0.63.0 新增,MUST)**:列 `| id | phase | command | expected |`,声明本 change 全部 G 类闸门(`id` 形如 `G-1`),`gates-probed` 门禁按此逐 id 核对 dry-run 留档。**段存在性是硬要求**——缺段/解析失败 = FAIL(缺段与「零闸门」不可区分,v0.13 RC-1 内容型豁免已删除);确无闸门写 `N/A: <理由>` 一行。`G-<n>`(命令型闸门)与团队同步点 G1–G5 是两套编号。模板与判定规则见 `references/bridging-gate-dry-run.md`。
|
|
42
|
+
|
|
39
43
|
## UI UX Delta Prototype Reference (v0.37.0 §68.5)
|
|
40
44
|
|
|
41
45
|
When the change involves UI (design.md has a `## UI Contract` section), the execution-contract's `## UX 增量` section (consumed by `tf prototype-sync`) must **state the prototype version worktree path** in its first line:
|
|
@@ -181,6 +185,8 @@ Still requires DP-3 approval.
|
|
|
181
185
|
|
|
182
186
|
**`tasks.md` 归属(v0.22 §85)**:hotfix/tweak 默认跳过(上条),但若该 change 确实需要任务记录,`tasks.md` 由本 skill 一并产出——归属 contract-builder(本 skill 已有 `tasks.md → Execution Batches` 的 Artifact Mapping,反向生成成本最低);任务文本不再经 spec-writer(hotfix/tweak 已跳过它)。
|
|
183
187
|
|
|
188
|
+
**该路径同样强制 `- [ ]` 形态(v0.63.0;feedback 20260923-013114 E1 横展)**:本 skill 产出的 `tasks.md`,**任务行 MUST 为 `- [ ]` checkbox 形态**——与 `spec-writer` 校验清单同口径,**hotfix/tweak 路径不因轻量而豁免**(否则零 checkbox → `tasks-complete` closing 死锁原样复现,且事后补勾选同样触发 `artifacts_hash` 漂移)。
|
|
189
|
+
|
|
184
190
|
## Guardrails
|
|
185
191
|
|
|
186
192
|
- **状态字段禁写(v0.30.0;v0.22 §85 澄清写入白名单)**:仅写本 skill 的 `dp_3_*` 决策字段,以及本 skill 职责内的门禁豁免键——`test_matrix_skipped` / `test_matrix_skip_reason`(v0.13 §50)、`tasks_skipped` / `tasks_skip_reason`(v0.22 §85);**MUST NOT** 修改 `state`/`workflow` 核心字段——状态转换由主代理经 `tf state transition` 执行。`tf state init` 只创建状态文件,不改 `state` 值(来源:workflow-feedback 2026-08-01)。
|
|
@@ -192,6 +198,21 @@ Still requires DP-3 approval.
|
|
|
192
198
|
|
|
193
199
|
## Post-Generation
|
|
194
200
|
|
|
201
|
+
### 契约 post-generation 两动作(v0.63.0,MUST,均在 `tf state init` 之前)
|
|
202
|
+
|
|
203
|
+
**① Facts Recheck**:对 `facts.json` 中契约将引用的键复测一次(防 specifying→bridging 漂移),差异写 `facts.bridging_recheck`。
|
|
204
|
+
**位置**:契约初稿完成后、dry-run 之前(复测可能改变闸门 `expected` 基线数字,草稿态回写成本最低)。
|
|
205
|
+
**差异(含超口径项)MUST 并入 DP-3 批准 ask 呈报**,裁决权归 LT——不得由实施方自行解释掉(错判即伪绿)。
|
|
206
|
+
|
|
207
|
+
**② Bridging Gate Dry-Run**:对每个 **pre-build** 闸门在主工作区当前态跑一次(预期 FAIL = RED 基线),落
|
|
208
|
+
`.superpowers/test-evidence/bridging-gates-red.txt`。硬要求:首行逐字 `EXPECTED: FAIL (RED baseline)` /
|
|
209
|
+
必须含 `CONTRACT_HASH: sha256:…` 行(新鲜度按**内容**判,不用 mtime)/ 每个注册 id 一个 `[G-<id>]` 分节 /
|
|
210
|
+
原始输出先落文件 / 多仓逐仓分节 cwd / `post-build` 闸门只做语法可执行性 probe。
|
|
211
|
+
若某闸门意外 PASS → 复核契约声明(它不是有效基线),不要改 evidence。
|
|
212
|
+
**Rewind 或契约重生成后 evidence 失效,须重跑。**
|
|
213
|
+
|
|
214
|
+
> 两动作的完整模板与理由见 `references/bridging-gate-dry-run.md`。
|
|
215
|
+
|
|
195
216
|
Run `tf state init <change-dir>` to create `.team-flow.yaml` with hashes.
|
|
196
217
|
|
|
197
218
|
For hotfix, after writing the minimal contract, run `tf state init <change-dir>` or `tf state rebuild <change-dir>` so `contract_hash` is recorded. DP-3 remains mandatory before build.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# bridging 闸门登记与 dry-run 留档(v0.63.0;feedback 20260923-013114 S2 + S1 复测)
|
|
2
|
+
|
|
3
|
+
本文件承载契约 post-generation 的两个动作细则。SKILL 保留 MUST 与指针,细则在此。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 一、`## Gate Registry`(闸门登记段,MUST)
|
|
8
|
+
|
|
9
|
+
声明本 change 的全部 G 类闸门,`gates-probed` 门禁按此逐 id 核对 dry-run 留档。列固定为 `| id | phase | command | expected |`:
|
|
10
|
+
|
|
11
|
+
```markdown
|
|
12
|
+
## Gate Registry
|
|
13
|
+
|
|
14
|
+
| id | phase | command | expected |
|
|
15
|
+
|----|-------|---------|----------|
|
|
16
|
+
| G-1 | pre-build | `npx eslint src/` | 0 errors |
|
|
17
|
+
| G-2 | pre-build | `npm run test:unit -- --coverage` | covered 132 |
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
- `id` 形如 `G-1`/`G-2`,须与契约内各闸门小节**一一对应**(审查侧会核对)。
|
|
21
|
+
- **`G-<n>` 是命令型质量闸门编号**,与团队同步点编号 **G1–G5**(§68.2 等)是**两套命名空间**,勿混用。
|
|
22
|
+
- `phase: post-build` 类闸门同样登记,其 dry-run 只做**语法/路径可执行性 probe**(不预跑结果)。
|
|
23
|
+
- 契约改动(含勘误段)后须**重跑 dry-run**(evidence 的 `CONTRACT_HASH` 比对会判陈旧)。
|
|
24
|
+
|
|
25
|
+
### 段存在性是硬要求(fail-closed)
|
|
26
|
+
|
|
27
|
+
**缺段 = `gates-probed` FAIL**——缺段与「零闸门」不可区分,v0.13 RC-1 的内容型豁免已删除。
|
|
28
|
+
|
|
29
|
+
> **workflow 限定**:本维度只挂 **full** 的 `bridging→approved-for-build`。**hotfix** 走 `WORKFLOW_TRANSITION_CHECKS` 自有覆盖、**天然不挂本维度**(无需注册该段);**tweak** 会回落继承本维度,须靠 `gates_probed_skipped` + 理由放行。
|
|
30
|
+
|
|
31
|
+
**两种「无闸门」表达的判定规则**:
|
|
32
|
+
|
|
33
|
+
| 情形 | 写法 | 结果 |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| 确无 G 类闸门 | 段存在 + `N/A: <理由>` 一行 | PASS(N/A 记录) |
|
|
36
|
+
| 临时豁免(不想写段) | `tf state set <dir> gates_probed_skipped true` + `gates_probed_skip_reason '<理由>'` | PASS(可审计豁免) |
|
|
37
|
+
| 忘写段 / 表解析失败 | — | **FAIL**(不得落 N/A) |
|
|
38
|
+
|
|
39
|
+
> 优先用**段内 `N/A: <理由>`**(理由随契约入库、随 hash 冻结);state 键是备用通道,仅在段写法不便时使用。
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 二、Bridging Gate Dry-Run(MUST,在 `tf state init` 之前)
|
|
44
|
+
|
|
45
|
+
契约产出后,对 `## Gate Registry` 声明的每个 **pre-build** 闸门,在**主工作区当前态**跑一次
|
|
46
|
+
——此时实现尚未开始,**预期结果是 FAIL**,这个 FAIL 就是 RED 基线(与 TDD 的红证据同源)。
|
|
47
|
+
|
|
48
|
+
**产出**:`.superpowers/test-evidence/bridging-gates-red.txt`
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
EXPECTED: FAIL (RED baseline)
|
|
52
|
+
CONTRACT_HASH: sha256:<64 位十六进制>
|
|
53
|
+
|
|
54
|
+
[G-1] npx eslint src/
|
|
55
|
+
<闸门原始输出,不得摘要或改写>
|
|
56
|
+
exit=1
|
|
57
|
+
|
|
58
|
+
[G-2] npm run test:unit -- --coverage
|
|
59
|
+
<闸门原始输出>
|
|
60
|
+
exit=1
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**六条硬要求**:
|
|
64
|
+
|
|
65
|
+
1. **首行逐字** `EXPECTED: FAIL (RED baseline)`;
|
|
66
|
+
2. **必须有 `CONTRACT_HASH: sha256:…` 行**,取当前 `execution-contract.md` 的 hash——新鲜度按**内容**判(不用 mtime:契约字节等价重生成、或 git 恢复会让 mtime 变新而内容未变,会误卡);
|
|
67
|
+
3. **每个注册 id 都要有 `[G-<id>]` 分节**——缺 id 会被门禁点出;
|
|
68
|
+
4. **原始输出先落文件**再写本 evidence(不写管道中间结果);
|
|
69
|
+
5. **多仓**:逐仓声明执行 cwd,evidence 内逐仓分节;
|
|
70
|
+
6. **`phase: post-build` 的闸门**只做语法/路径可执行性 probe,不预跑结果。
|
|
71
|
+
|
|
72
|
+
> 本步把 `design.md` R-7「闸门命令已实测可跑」的文字自证物化为机械证据。
|
|
73
|
+
> 若某闸门在此步**意外 PASS**,说明它不是有效基线(已实现/已满足),须复核契约声明而非改 evidence。
|
|
74
|
+
> **Rewind 或契约重生成后,既存 evidence 失效**,须重跑(`CONTRACT_HASH` 比对可兜底,但纪律须遵守)。
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 三、Facts Recheck(MUST,在 dry-run 之前)
|
|
79
|
+
|
|
80
|
+
对 `<change-dir>/.superpowers/facts.json` 中**契约将要引用的键**复测一次(防 specifying→bridging 期间漂移),
|
|
81
|
+
差异写入 `facts.bridging_recheck` 段。
|
|
82
|
+
|
|
83
|
+
**位置说明(避免与 §3.1 的「生成前」表述混淆)**:复测动作在**契约初稿完成后、dry-run 之前**执行——
|
|
84
|
+
因为复测结果可能改变契约为闸门声明的基线数字(`expected` 列),此时契约尚在草稿态、回写成本最低。
|
|
85
|
+
**DP-3 批准 ask 必须晚于本复测**(差异摘要要并入那次 ask)。
|
|
86
|
+
|
|
87
|
+
**差异呈报(MUST)**:差异摘要(含**超出口径声明**的项)**并入 DP-3 批准 ask 一并呈报**,裁决权归 LT。
|
|
88
|
+
**不得**由实施方(含主会话)自行解释掉——错判方向即伪绿(把超口径差异解释为「口径问题」→ 闸门基线数字错)。
|
|
89
|
+
无法在声明口径内解释的差异 → 触发**契约侧重签判断**,不要带着已知漂移进入执行。
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# 规划制品冻结与契约勘误登记(v0.63.0;feedback 20260923-013114 S3)
|
|
2
|
+
|
|
3
|
+
> **来源**:v2-C2(跨 4 仓命名统一,生产逻辑实改 ≈1 if + 1 enum + 3 文案)三轮 dispatch 实证——规划制品数字靠抄写而非实测,
|
|
4
|
+
> 过期声明 6 处 + 派生描述 4 处 + tasks 测试计数 3 处 + 契约/矩阵计数 3 处,每轮订正触发 `artifacts_hash` 漂移 →
|
|
5
|
+
> `contract-fresh` 失败 → rebuild → plan revise(`.team-flow.yaml:7 revision: 3` 三次重签全可定位)。
|
|
6
|
+
|
|
7
|
+
## 1. 冻结规则
|
|
8
|
+
|
|
9
|
+
DP-3 批准后,**planning 四件(proposal.md / specs/ / design.md / tasks.md)默认冻结**。
|
|
10
|
+
|
|
11
|
+
陈述性订正**不再改 planning 原文**,改记入 `execution-contract.md` 的 **`## Errata Register`(勘误登记段)**。
|
|
12
|
+
|
|
13
|
+
## 2. 勘误登记段模板
|
|
14
|
+
|
|
15
|
+
追加到契约的固定段名与字段:
|
|
16
|
+
|
|
17
|
+
```markdown
|
|
18
|
+
## Errata Register
|
|
19
|
+
|
|
20
|
+
| 日期 | 原文(planning 制品:位置) | 订正后 | 例外条款 | 授权人 | 留痕 |
|
|
21
|
+
|------|--------------------------|--------|---------|--------|------|
|
|
22
|
+
| 2026-09-22 | design.md §Risks 第 3 条 | 基线 115 → 132 | 例外 1(作者裁决) | LT | dp_3_result |
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- **留痕要求**:每行必须有 `例外条款` 与 `授权人`;订正前原文须可追溯(引用制品位置,必要时附原句)。
|
|
26
|
+
- 勘误段**入 `contract_hash`**(契约全文入 hash),故写入后必须按下节操作序处理。
|
|
27
|
+
|
|
28
|
+
## 3. 操作序(MUST)
|
|
29
|
+
|
|
30
|
+
> **勘误段写入后 MUST 执行 `tf execution refresh-hash`。**
|
|
31
|
+
>
|
|
32
|
+
> **理由**:写契约 = 改 `contract_hash`;不 refresh 会卡 `execution-plan-ready`(该维度挂 `executing:closing` 与 `debugging:executing`)——**恰复活了本机制要消除的 revision 回路**。
|
|
33
|
+
> **先例**:`references/glaf4-delegation.md`(契约改 hash → 必须先 refresh-hash)。
|
|
34
|
+
|
|
35
|
+
## 4. 三分处方表(禁止混用)
|
|
36
|
+
|
|
37
|
+
| 变更对象 | 处方 | 说明 |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| `test-matrix.md` 段 | `tf state rebuild` | 矩阵 hash 独立(`hash.mjs computeTestMatrixHash`) |
|
|
40
|
+
| 契约段(含 `## Errata Register`) | `tf execution refresh-hash` | 只动 plan 内嵌的 `contract_hash`,不碰 state |
|
|
41
|
+
| wave / 执行模式变更 | plan revise | 结构性变更,走重规划 |
|
|
42
|
+
|
|
43
|
+
**rebuild 与勘误段的存续顺序**:`tf state rebuild` 会重建契约 → **勘误段随旧契约丢失**,须在 rebuild 后将勘误段**回填**(回填内容以 `dp_N_result` + 审查报告为源)。
|
|
44
|
+
|
|
45
|
+
## 5. 冻结例外(六条,均须留痕)
|
|
46
|
+
|
|
47
|
+
| # | 例外 | 处置 |
|
|
48
|
+
|---|------|------|
|
|
49
|
+
| 1 | **作者级裁决落地**(LT/业务作者定稿变更,如 C2-CONFLICT-001 desc1) | 按契约裁决记录 + 订正前原文留痕;**若触及 gate-affecting → 回归例外 2** |
|
|
50
|
+
| 2 | **gate-affecting 勘误必改**(矩阵 expected/方法名、闸门基线数字、契约 Test Matrix 段) | 触发 rebuild → revise |
|
|
51
|
+
| 3 | **checkbox 勾选回写**(进度位) | **显式豁免**——`hash.mjs normalizeCheckboxes` 已归一化,不属冻结对象(否则与 v0.49.0 修复自相矛盾) |
|
|
52
|
+
| 4 | **显式 Rewind 后的修改**(scope→re-specify、contract→re-bridge) | 冻结**不豁免** Rewind |
|
|
53
|
+
| 5 | **Review Findings 分轨文本订正**(M-1/M-2 类纯文本缺陷) | 经 doc-only 授权、收口波次落地,与代码修复分轨 |
|
|
54
|
+
| 6 | **LT 书面授权兜底** | 须写入 `dp_N_result` 或契约勘误段 |
|
|
55
|
+
|
|
56
|
+
**例外授权升级序**:例外 6 **不可与其他例外叠加降级**——不得以「LT 曾授权例外 6」为由豁免例外 2 的判定复核;例外 1 如触及 gate-affecting,**回归例外 2** 处理。
|
|
57
|
+
|
|
58
|
+
## 6. 非例外(禁止)
|
|
59
|
+
|
|
60
|
+
- 无新证据的措辞美化
|
|
61
|
+
- 把陈述性订正**伪装**成 gate-affecting(或其反向:把 gate-affecting 记成陈述性)
|
|
62
|
+
- 绕过 Rewind 改 brief 级范围
|
|
63
|
+
|
|
64
|
+
## 7. 例外 2 的判定与呈报(防伪绿关键)
|
|
65
|
+
|
|
66
|
+
**判定权升格**:实施方仅**提议**,**判定由审查侧复核**(code-reviewer)+ closing 侧反查。**自判错判的方向恰是伪绿出口**。
|
|
67
|
+
|
|
68
|
+
**呈报纪律(MUST)**:
|
|
69
|
+
|
|
70
|
+
1. 「例外 2 提议 + 判定依据 + `## Errata Register` 摘要」**并入 wave review prompt**;
|
|
71
|
+
2. **根仓 planning 制品 diff 单列进审查范围**——多仓场景下 wave `base..head` 的 git range 解析到**子仓**,而 planning 制品在**根仓**,子仓 diff 里看不到它们被改;
|
|
72
|
+
3. **未在 DP-3 摘要中呈报的差异,不得执行 `tf execution refresh-hash`**(该命令是唯一能把「改过 planning」从 `validatePlan` 比对中抹掉的操作)。
|
|
73
|
+
|
|
74
|
+
**closing 侧反查锚(v0.63.0 新增)**:`executing:closing` 维度已补挂 `contract-fresh`——它比对 `state.artifacts_hash` 与制品实算值,**`refresh-hash` 无法清屏**(后者只改 plan JSON)。
|
|
75
|
+
|
|
76
|
+
## 8. 机械强度如实声明
|
|
77
|
+
|
|
78
|
+
v0.63.0 **不加专用冻结 guard 维度**。本期 = 本文件纪律 + Staleness advisory + `contract-fresh`(含 closing 新挂)+ `executing:closing` 反查三者合成。
|
|
79
|
+
**硬门禁**(DP-3 写 planning 快照 hash + closing 快照比对)归**远期上游 PR**。
|
|
80
|
+
|
|
81
|
+
**收益如实拆分**:本机制消除的是**陈述性订正**的回路;**gate-affecting 订正仍走例外 2 → 仍触发 rebuild→revise**(v2-C2 的 revision 3 订正大半属此类)。不得宣称「消除了全部重签回路」。
|
|
@@ -254,6 +254,15 @@ tf solutions promote <change-dir>
|
|
|
254
254
|
|
|
255
255
|
同步对象:实施代码 `changes/<change-dir>/` + arch-merge 回写(docs/architecture/)+ test-ledger(docs/test-ledger/)。**原型独立仓库场景**:若本 change 有 UX 增量回写原型,push 对应 `prd-vN` 分支(`tf prototype branch <prd-vN>` 确认/创建 worktree)。
|
|
256
256
|
|
|
257
|
+
**决策点攒批与预批复单(v0.63.0;feedback 20260923-013114 S5)**:
|
|
258
|
+
|
|
259
|
+
- **同根因攒批(MUST)**:同一根因的多个发现**攒成一次 ask**,不得逐个往返确认。
|
|
260
|
+
- **closing 边界并入**:**DP-6 与 roadmap/push 边界并入同一次 closing 确认**(既有确认点合并三组为 DP-0+DP-A、DP-3+G4+DP-4、DP-7+落地+G5,**均不含 DP-6**,故本项为新增;三组清单以 `docs/decision-points.md` 为准)。
|
|
261
|
+
- **批量预批复单模板**(closing 型变更可启用):一次性列出全部待确认项 + 各项的建议取值 + 理由,由用户一次批复。
|
|
262
|
+
|
|
263
|
+
> **⛔ 防伪绿护栏(MUST)**:**门禁类 DP(`dp_3` / `dp_4`)禁止超时代答**——这两个字段是 `dp-gate-passed` 门禁的数据源(`checks/dp-gate-passed.mjs` 仅映射 dp_3/dp_4)。**预批复只作用于非门禁确认**;DP-6 预批复为**条件式**(机器门禁全 PASS 才生效)。
|
|
264
|
+
> **Rewind 作废**:Rewind 后已发出的预批复**自动作废**,须重新征询。
|
|
265
|
+
|
|
257
266
|
### Worktree Deisolation (v0.35.0) — advisory
|
|
258
267
|
|
|
259
268
|
After compound promotion, check if worktree isolation exists for this change:
|
|
@@ -84,6 +84,8 @@ Run: `tf runtime config --get artifacts.order` — generate in configured order
|
|
|
84
84
|
|
|
85
85
|
**Honor Architecture (v0.9 §26, v0.10 §28-§31)**: 若 `architecture/` 目录存在,design.md 的 Decisions 段必须引用其架构决策(聚合/限界上下文/CQRS/API/DB),tasks.md 的接口定义(对齐 api.md 架构路由表)和数据层任务(引用 sql/ddl/ + sql/migration/ 脚本路径)必须与 architecture/ 产出对齐——不得静默忽略或矛盾架构设计产出。
|
|
86
86
|
|
|
87
|
+
**Fact Referencing (v0.63.0;feedback 20260923-013114 S1)**: 制品中凡涉及**基线数字、测试计数、目标行号、枚举现状、编号在册性**,一律从 `<change-dir>/.superpowers/facts.json` 引用键名,**不裸写数字**(抄写的事实下轮修订即漂移 → `artifacts_hash` 漂移 → 契约重签)。每个键须带采集命令 / 时间戳 / 口径声明。**强度如实声明**:这是**纪律条款**,不是硬门禁(`tf facts probe` 与 WARNING lint 归远期上游 PR);但 facts.json 不进任何 hash,无新回路。判据四条(`command grep` / 原始输出先落文件 / 模式自证 / 数字注明命令+环境+时间戳+口径)见 `references/facts-referencing.md`(含跨仓 `repos.<name>` 结构与 bridging 复测呈报纪律)。
|
|
88
|
+
|
|
87
89
|
### proposal.md
|
|
88
90
|
Must state: problem, what changes, capabilities affected, impact areas.
|
|
89
91
|
|
|
@@ -144,6 +146,7 @@ Generate one at a time. Confirm each before next. This prevents scope drift —
|
|
|
144
146
|
|
|
145
147
|
### tasks.md
|
|
146
148
|
- `## File Structure`, `## Interfaces`, numbered tasks, exact file paths, TDD phases, ≤5 min steps, no placeholders, every requirement mapped, explicit dependencies
|
|
149
|
+
- **任务行形态强制 `- [ ]`(v0.63.0;feedback 20260923-013114 E1)**:tasks.md 的**每条任务行 MUST 生成为 `- [ ]` checkbox 形态**,不得写成纯编号/纯列表。理由:`templates/tasks.md` 本就是 `- [ ]` 形态;`tasks-complete` 门禁对零已勾选**无条件 FAIL**(closing 死锁);`hash.mjs` 的 `normalizeCheckboxes` 只归一化勾选态、**救不了行结构变化**——事后补 checkbox 会造成 `artifacts_hash` 漂移 + 契约重签(v2-C2 实证:wave1 即知风险、拖到 closing 才改,致 revision 3 重签)。生成期一行约束即同时消掉「closing 死锁」与「hash 漂移重签」双源头。
|
|
147
150
|
- **接口交叉核对(v0.35.0,v0.14 §61.1)**:若 `architecture/api.md` 存在,机械比对 `tasks.md` `## Interfaces` 声明的端点集合与 `api.md` 架构路由表端点集合——tasks 引用了 api.md 未声明的端点、或 api.md 声明的关键端点 tasks 未落地 → 告警修正(traceability 从自报升级为机械比对)
|
|
148
151
|
|
|
149
152
|
**If any artifact fails validation, fix before handing off to contract-builder.**
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# 事实引用惯例(v0.63.0;feedback 20260923-013114 S1)
|
|
2
|
+
|
|
3
|
+
> **来源**:v2-C2 实证——规划制品里的数字靠**抄写**而非实测:过期声明 6 处 + 派生描述 4 处 +
|
|
4
|
+
> tasks 测试计数 3 处 + 契约/矩阵计数 3 处(均带【订正】标记)。每轮订正触发 `artifacts_hash` 漂移 →
|
|
5
|
+
> `contract-fresh` 失败 → rebuild → plan revise(revision 3 三次重签全可定位)。
|
|
6
|
+
|
|
7
|
+
## 1. 规则
|
|
8
|
+
|
|
9
|
+
**基线数字必须写成带来源的形式:`<值>(facts:<键>,ts=<时间戳>)`——脱离 facts 键的裸值即违规。**
|
|
10
|
+
|
|
11
|
+
(值本身当然要写在制品里才能读懂;违规的是「值没有可追溯的 facts 键与采集时点」,不是「出现了数字」。
|
|
12
|
+
阈值类 specs 正常书写不受影响。)
|
|
13
|
+
|
|
14
|
+
凡涉及以下内容,一律写入 `<change-dir>/.superpowers/facts.json` 并在制品中**引用键名**:
|
|
15
|
+
- G1/G2 残差基线(如「G2 违规数 119 → 132」)
|
|
16
|
+
- 各仓测试计数
|
|
17
|
+
- 目标文件 / 目标行号
|
|
18
|
+
- 枚举现状、PRD 编号在册性
|
|
19
|
+
|
|
20
|
+
**强度如实声明**:「禁止裸数字」**不是硬门禁**——自由 markdown 上硬禁会全量误报。本惯例是
|
|
21
|
+
**纪律条款**(`tf facts probe` 子命令与 WARNING lint 均归远期上游 PR,v0.63.0 未实现)。
|
|
22
|
+
但 facts.json 本身**不进任何 hash**(`hash.mjs` 白名单仅 proposal/specs/design/tasks/architecture),
|
|
23
|
+
所以写 facts 不产生新回路。
|
|
24
|
+
|
|
25
|
+
## 2. facts 三件套(每个键必带)
|
|
26
|
+
|
|
27
|
+
| 项 | 要求 |
|
|
28
|
+
|---|---|
|
|
29
|
+
| **采集命令** | 可原样复跑的命令行 |
|
|
30
|
+
| **时间戳** | ISO 8601 UTC |
|
|
31
|
+
| **口径声明** | 含/不含副本、排除目录清单 |
|
|
32
|
+
|
|
33
|
+
**跨仓**:facts.json **仍为单文件**,per-repo 数据以 `repos.<name>.{test_counts, target_lines, enums}`
|
|
34
|
+
分节;`repos` 的键集合须与 `repo_layout` 一致(缺仓 = facts 不完整,须补采)。
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"repos": {
|
|
39
|
+
"ui": { "test_counts": { "value": 16, "command": "command grep -c '@Test' …", "ts": "2026-09-22T09:00:00Z", "scope": "含 dist 行" } }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 3. 判据四条(母本 161200;以下为转述,以母本为准)
|
|
45
|
+
|
|
46
|
+
1. 扫描/计数一律 `command grep`(绕过 shell function 包装);
|
|
47
|
+
2. 原始输出**先落文件**,计数从落盘文件算出(不对管道中间结果计数);
|
|
48
|
+
3. 扫描脚本必含**模式自证段**(探针证明模式有效,防空结果假 PASS);
|
|
49
|
+
4. 每个基线数字注明**采集命令、时间戳、口径**——注意 161200 原文是「采集命令与**采集环境**」,
|
|
50
|
+
**时间戳**属本文件三件套要求(专家评审 :49),二者分开陈述、不混同转述。
|
|
51
|
+
|
|
52
|
+
## 4. bridging 复测(防 specifying→bridging 漂移)
|
|
53
|
+
|
|
54
|
+
契约生成前由 **contract-builder** 复测一次 facts,差异计入 `facts.bridging_recheck` 段。
|
|
55
|
+
|
|
56
|
+
**差异裁决(MUST)**:差异摘要(含超口径项)**并入 DP-3 批准 ask 一并呈报**,裁决权归 LT。
|
|
57
|
+
**不得**由实施方(含主会话)自行解释掉——错判方向即伪绿:把超口径差异解释为「口径问题」→
|
|
58
|
+
闸门基线数字错。无法在声明口径内解释的差异 → 触发**契约侧重签判断**。
|
|
59
|
+
|
|
60
|
+
## 5. 反模式
|
|
61
|
+
|
|
62
|
+
- ❌ 写数字但不带 `facts:<键>` 与 `ts=`(下轮修订即漂移,且无从核对口径)
|
|
63
|
+
- ❌ 同一事实在多个制品各写一遍(口径不一致的根源)
|
|
64
|
+
- ❌ 引用其它 change 的计数而不声明它的采集时点
|
|
@@ -88,6 +88,7 @@ Validate mode against artifact content. If hotfix/tweak criteria not met → upg
|
|
|
88
88
|
- **返回即验证(validation gate)**:子代理返回产物后**立即** `tf validate <change-dir>`;FAIL → SendMessage 回**原**子代理修复,通过后才能继续/转换。把格式失败拦截在返回时,而非状态转换时(避免浪费整次执行后再失败)。**build-executor 附加验证(v0.13 §52 B3,SDD/full 模式)**:返回的 diff 中必须包含测试文件(src/test/ 或项目测试目录);零测试文件的实现返回一律 BLOCK,SendMessage 回原子代理按 test-matrix.md / TDD Iron Law 补齐——不得以"手动验证"替代(C1-domain-policy 事件教训)。例外:已显式记录 `test_matrix_skipped=true` + 理由的 change(纯文档/配置类)不要求测试文件
|
|
89
89
|
- **结果协议**:子代理终态须标注 `FINAL VERDICT: <DONE|BLOCKED|FAIL>`(审查类用 PASS/PASS_WITH_WARNINGS/FAIL);**SendMessage 报告为权威结果**,task-notification.result 仅内部元数据
|
|
90
90
|
- **子代理状态边界**:子代理 MUST NOT 修改 `.team-flow.yaml` 的 `state`/`workflow` 核心字段(状态转换是主代理专有职责,经 `tf state transition` 执行),只写自己的 `dp_N_*` 决策字段
|
|
91
|
+
- **环境清单注入(v0.63.0;feedback 20260923-013114 S6)**:dispatch 前检查 `.team-flow/environment.md` 是否存在——**存在则全文附入 dispatch prompt**。该文件承载**机器级事实**(grep=ugrep shim → 扫描一律 `command grep`;`tf` CLI 来自 npm 全局包而非插件缓存;Eclipse JDT 写 `target/` → Maven 必须带 `clean`;node 版本可直跑 ui 测试等),避免每个子代理 prompt 重复教学、且防止它们在不知情下踩坑。**嵌套 dispatch 同样注入**:注入时**必须在清单全文之后追加一句元指令**——「请将本清单原样继续附入你的所有下游 dispatch」——因为收到的是清单全文、不是这条规则本身,而子代理不继承主代理的 skills;仅在 workflow-start 侧声明不够(规则到不了第二跳)。(与 `conventions/` 分层互补:conventions = 项目级规范、可跨机器共享;environment = 机器级事实、不入库、不污染他机。)
|
|
91
92
|
|
|
92
93
|
### Route to need-explorer
|
|
93
94
|
Change is fuzzy, scope unclear, comparing options, no stable change name.(交互式澄清,主进程执行,见 Sub-agent Dispatch Protocol)
|