@namewta/speculo 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -2
- package/dist/src/cli.js +40 -6
- package/dist/src/cli.js.map +1 -1
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/skills-mirror.d.ts +38 -0
- package/dist/src/skills-mirror.js +160 -0
- package/dist/src/skills-mirror.js.map +1 -0
- package/package.json +3 -2
- package/template/canonical/README.md +7 -1
- package/template/canonical/canonical-specdev-engineering-cognitive-mentor.md +2040 -0
- package/template/canonical/canonical-specdev-goal-plan.md +1379 -0
- package/template/canonical/canonical-specdev-grill-with-docs.md +848 -285
- package/template/canonical/canonical-specdev-spec.md +1061 -46
- package/template/canonical/canonical-specdev-tickets.md +1529 -175
- package/template/canonical/canonical-specdev-wayfinder.md +677 -107
- package/template/commands/git-repository-audit.md +682 -0
- package/template/workflows/specdev/A-archive-and-consolidate/A-archive-and-consolidate.md +69 -36
- package/template/workflows/specdev/A-archive-and-consolidate/archive-checklist.md +15 -0
- package/template/workflows/specdev/A-archive-and-consolidate/knowledge-promotion-rules.md +32 -0
- package/template/workflows/specdev/D-diagnose-bugs/D-diagnose-bugs.md +51 -51
- package/template/workflows/specdev/D-diagnose-bugs/diagnosis-template.md +64 -0
- package/template/workflows/specdev/E-engineering-cognitive-mentor/E-engineering-cognitive-mentor.md +252 -0
- package/template/workflows/specdev/E-engineering-cognitive-mentor/architecture-guidance.md +90 -0
- package/template/workflows/specdev/E-engineering-cognitive-mentor/bug-guidance.md +80 -0
- package/template/workflows/specdev/E-engineering-cognitive-mentor/codebase-guidance.md +107 -0
- package/template/workflows/specdev/E-engineering-cognitive-mentor/comprehension-and-closure.md +95 -0
- package/template/workflows/specdev/E-engineering-cognitive-mentor/domain-learning-guidance.md +62 -0
- package/template/workflows/specdev/E-engineering-cognitive-mentor/evidence-and-options.md +132 -0
- package/template/workflows/specdev/E-engineering-cognitive-mentor/interaction-protocol.md +116 -0
- package/template/workflows/specdev/E-engineering-cognitive-mentor/mentor-report-template.md +135 -0
- package/template/workflows/specdev/E-engineering-cognitive-mentor/mode-routing.md +47 -0
- package/template/workflows/specdev/E-engineering-cognitive-mentor/persistence-and-resume.md +147 -0
- package/template/workflows/specdev/E-engineering-cognitive-mentor/requirements-guidance.md +92 -0
- package/template/workflows/specdev/G-grill-with-docs/G-grill-with-docs.md +100 -30
- package/template/workflows/specdev/G-grill-with-docs/adr-format.md +22 -77
- package/template/workflows/specdev/G-grill-with-docs/context-format.md +27 -53
- package/template/workflows/specdev/G-grill-with-docs/domain-modeling-rules.md +6 -82
- package/template/workflows/specdev/G-grill-with-docs/grilling-protocol.md +32 -49
- package/template/workflows/specdev/G-grill-with-docs/log-format.md +16 -98
- package/template/workflows/specdev/I-implement/I-implement.md +168 -52
- package/template/workflows/specdev/I-implement/code-review-process.md +10 -76
- package/template/workflows/specdev/I-implement/codebase-design-glossary.md +12 -109
- package/template/workflows/specdev/I-implement/deepening.md +12 -32
- package/template/workflows/specdev/I-implement/design-it-twice.md +6 -41
- package/template/workflows/specdev/I-implement/evidence-template.md +69 -0
- package/template/workflows/specdev/I-implement/execution-preflight.md +20 -0
- package/template/workflows/specdev/I-implement/tdd-examples.md +10 -135
- package/template/workflows/specdev/I-implement/tdd-rules.md +12 -28
- package/template/workflows/specdev/I-init-setup/I-init-setup.md +81 -86
- package/template/workflows/specdev/I-init-setup/change-status-template.json +15 -0
- package/template/workflows/specdev/I-init-setup/config-template.json +26 -0
- package/template/workflows/specdev/I-init-setup/domain-layout-template.md +23 -0
- package/template/workflows/specdev/I-init-setup/status-labels-template.md +55 -0
- package/template/workflows/specdev/I-init-setup/status-template.json +7 -0
- package/template/workflows/specdev/I-init-setup/tracking-template.md +10 -0
- package/template/workflows/specdev/INDEX.md +165 -82
- package/template/workflows/specdev/P-goal-plan/P-goal-plan.md +108 -44
- package/template/workflows/specdev/P-goal-plan/completion-control.md +79 -0
- package/template/workflows/specdev/P-goal-plan/goal-plan-template.md +105 -0
- package/template/workflows/specdev/P-goal-plan/orchestration-protocol.md +115 -0
- package/template/workflows/specdev/P-goal-plan/planning-modes.md +70 -0
- package/template/workflows/specdev/R-review-architecture/R-review-architecture.md +103 -40
- package/template/workflows/specdev/R-review-architecture/architecture-review-report-template.html +58 -0
- package/template/workflows/specdev/R-review-architecture/architecture-review-template.md +68 -0
- package/template/workflows/specdev/R-review-architecture/proposal-to-ticket.md +11 -0
- package/template/workflows/specdev/S-spec/S-spec.md +103 -49
- package/template/workflows/specdev/S-spec/spec-readiness.md +16 -0
- package/template/workflows/specdev/S-spec/spec-template.md +95 -0
- package/template/workflows/specdev/T-tickets/T-tickets.md +146 -133
- package/template/workflows/specdev/T-tickets/decomposition-rules.md +56 -0
- package/template/workflows/specdev/T-tickets/ticket-readiness.md +45 -0
- package/template/workflows/specdev/T-tickets/ticket-template.md +124 -0
- package/template/workflows/specdev/T-tickets/tickets-map-template.md +52 -50
- package/template/workflows/specdev/T-triage/T-triage.md +32 -63
- package/template/workflows/specdev/T-triage/triage-template.md +29 -0
- package/template/workflows/specdev/W-wayfinder/W-wayfinder.md +88 -155
- package/template/workflows/specdev/W-wayfinder/investigation-ticket-template.md +50 -0
- package/template/workflows/specdev/W-wayfinder/wayfinder-map-template.md +46 -0
- package/template/workflows/specdev/_state/status.json +1 -1
- package/template/workflows/specdev/common/README.md +47 -0
- package/template/workflows/specdev/common/rules/artifact-contract.md +57 -0
- package/template/workflows/specdev/common/rules/code-commenting-rule.md +39 -0
- package/template/workflows/specdev/common/rules/deviation-control.md +43 -0
- package/template/workflows/specdev/common/rules/evidence-and-verification.md +57 -0
- package/template/workflows/specdev/common/rules/path-ownership.md +35 -0
- package/template/workflows/specdev/common/rules/path-reference-contract.md +116 -0
- package/template/workflows/specdev/common/rules/planning-principles.md +57 -0
- package/template/workflows/specdev/common/rules/readiness-and-depth.md +51 -0
- package/template/workflows/specdev/common/schemas/change-status.schema.json +170 -0
- package/template/workflows/specdev/common/schemas/config.schema.json +54 -0
- package/template/workflows/specdev/common/schemas/goal-plan.schema.json +21 -0
- package/template/workflows/specdev/common/schemas/spec.schema.json +16 -0
- package/template/workflows/specdev/common/schemas/status.schema.json +149 -0
- package/template/workflows/specdev/common/schemas/ticket.schema.json +130 -0
- package/template/workflows/specdev/common/schemas/tickets-map.schema.json +14 -0
- package/template/workflows/specdev/common/skills/dev-worktree/SKILL.md +28 -0
- package/template/workflows/specdev/common/skills/dev-worktree/references/create.md +30 -0
- package/template/workflows/specdev/common/skills/dev-worktree/references/finalize.md +16 -0
- package/template/workflows/specdev/common/skills/research/SKILL.md +43 -0
- package/template/workflows/specdev/common/tools/README.md +16 -0
- package/template/workflows/specdev/common/tools/validate-specdev.mjs +1155 -0
- package/template/canonical/canonical-teach.md +0 -301
- package/template/workflows/specdev/A-archive-and-consolidate/archive-rules.md +0 -49
- package/template/workflows/specdev/A-archive-and-consolidate/cleanup-rules.md +0 -80
- package/template/workflows/specdev/A-archive-and-consolidate/consolidation-rules.md +0 -122
- package/template/workflows/specdev/A-archive-and-consolidate/discrimination-guide.md +0 -96
- package/template/workflows/specdev/A-archive-and-consolidate/knowledge-graduation.md +0 -51
- package/template/workflows/specdev/D-diagnose-bugs/cleanup-postmortem.md +0 -37
- package/template/workflows/specdev/D-diagnose-bugs/feedback-loop-techniques.md +0 -84
- package/template/workflows/specdev/D-diagnose-bugs/hypothesis-format.md +0 -46
- package/template/workflows/specdev/D-diagnose-bugs/instrumentation-rules.md +0 -51
- package/template/workflows/specdev/I-init-setup/domain-layout.md +0 -55
- package/template/workflows/specdev/I-init-setup/status-labels.md +0 -53
- package/template/workflows/specdev/I-init-setup/tracking-convention.md +0 -52
- package/template/workflows/specdev/P-goal-plan/execution-sections.md +0 -126
- package/template/workflows/specdev/P-goal-plan/governance-sections.md +0 -103
- package/template/workflows/specdev/P-goal-plan/input-validation.md +0 -94
- package/template/workflows/specdev/P-goal-plan/lead-orchestration-protocol.md +0 -158
- package/template/workflows/specdev/P-goal-plan/quick-reference-table.md +0 -60
- package/template/workflows/specdev/P-goal-plan/vision-sections.md +0 -80
- package/template/workflows/specdev/R-review-architecture/exploration-guide.md +0 -103
- package/template/workflows/specdev/R-review-architecture/html-report-template.md +0 -124
- package/template/workflows/specdev/T-triage/artifact-templates.md +0 -122
- package/template/workflows/specdev/T-triage/intake-rules.md +0 -71
- package/template/workflows/specdev/T-triage/routing-rules.md +0 -70
- package/template/workflows/specdev/T-triage/understanding-rules.md +0 -102
- package/template/workflows/specdev/_state/adr/.gitkeep +0 -0
- package/template/workflows/specdev/_state/context/.gitkeep +0 -0
- package/template/workflows/specdev/_state/research/.gitkeep +0 -0
- package/template/workflows/specdev/common/dev-worktree/SKILL.md +0 -48
- package/template/workflows/specdev/common/dev-worktree/references/create.md +0 -63
- package/template/workflows/specdev/common/dev-worktree/references/finalize.md +0 -102
- package/template/workflows/specdev/common/handoff/SKILL.md +0 -42
- package/template/workflows/specdev/common/neat-freak/SKILL.md +0 -210
- package/template/workflows/specdev/common/neat-freak/references/agent-paths.md +0 -72
- package/template/workflows/specdev/common/neat-freak/references/governance.md +0 -88
- package/template/workflows/specdev/common/neat-freak/references/sync-matrix.md +0 -77
- package/template/workflows/specdev/common/neat-freak/references/verification.md +0 -92
- package/template/workflows/specdev/common/neat-freak/scripts/audit-inventory.sh +0 -106
- package/template/workflows/specdev/common/prototype/LOGIC.md +0 -89
- package/template/workflows/specdev/common/prototype/SKILL.md +0 -78
- package/template/workflows/specdev/common/prototype/UI.md +0 -120
- package/template/workflows/specdev/common/research/SKILL.md +0 -54
- package/template/workflows/specdev/common/resolving-merge-conflicts/SKILL.md +0 -14
- package/template/workflows/specdev/common/scripts/hitl-loop.template.sh +0 -41
- package/template/workflows/specdev/common/triage/AGENT-BRIEF.md +0 -204
- package/template/workflows/specdev/common/triage/OUT-OF-SCOPE.md +0 -104
- package/template/workflows/specdev/common/triage/SKILL.md +0 -112
|
@@ -1,278 +1,1632 @@
|
|
|
1
1
|
# 拆分 Tickets
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 网页平台运行约定
|
|
4
|
+
|
|
5
|
+
本文是可独立上传的单文件能力快照,不依赖 Speculo CLI 的根别名或源目录。执行时统一采用以下逻辑布局:
|
|
6
|
+
|
|
7
|
+
- 项目根下的 `specdev/` 是状态区;全局配置与状态分别为 `specdev/config.json` 和 `specdev/status.json`。
|
|
8
|
+
- 当前 change 位于 `specdev/changes/{change}/`,其中 `{change}` 使用 `YYYY-MM-DD-<kebab-topic>`。
|
|
9
|
+
- 当前 change 的设计、规划和证据工件都写入该目录;永久 ADR、领域上下文和研究分别写入 `specdev/adr/`、`specdev/context/` 和 `specdev/research/`。
|
|
10
|
+
- `specdev/config.json` 或 `specdev/status.json` 不存在时,分别按下方 `<config-template>` 和 `<status-template>` 标签创建;新建 change 时按下方 `<change-status-template>` 标签创建 `.status.json`。对应 schema 用于结构核对。
|
|
11
|
+
- 项目代码与测试始终使用项目根相对路径;不写机器绝对路径。工件之间使用上述逻辑路径,不使用 Speculo 的运行时路径标签。
|
|
12
|
+
- 如果网页平台不能直接写项目文件,则按目标文件名输出完整内容,并在答复中明确应保存的位置;不得把“无法写文件”伪装成已经持久化。
|
|
13
|
+
- 若本地项目提供 Speculo Node 校验器,可运行它补充结构校验;纯网页环境按本文内联的 schema、Ready 清单和完成标准逐项核对,并明确记录未运行的自动校验。
|
|
14
|
+
- 提交、推送、合并、部署、发布、归档移动和不可逆迁移仍需用户明确授权。
|
|
15
|
+
|
|
16
|
+
Ticket 是**决策完备的微型执行计划**:它消除执行者在目标、范围、公共契约、关键顺序和验收上的关键决策,但不展开逐行代码、局部变量或可从现有惯例自然推导的实现细节。
|
|
17
|
+
|
|
18
|
+
本 work 保留原有能力:代码库探索、prefactor 识别、曳光弹垂直切片、真实阻塞边、用户粒度核对、宽重构的 expand-contract 排序、Ticket 独立文件和总体 Tickets Map。
|
|
19
|
+
|
|
20
|
+
## 输入
|
|
21
|
+
|
|
22
|
+
优先读取:
|
|
23
|
+
|
|
24
|
+
- 当前 Spec:`specdev/changes/{change}/spec.md`
|
|
25
|
+
- 当前架构决策:`specdev/changes/{change}/ADR.md`
|
|
26
|
+
- 当前领域上下文:`specdev/changes/{change}/CONTEXT.md`
|
|
27
|
+
- 当前设计日志:`specdev/changes/{change}/LOG.md`
|
|
28
|
+
- Bug 诊断:`specdev/changes/{change}/diagnosis.md`
|
|
29
|
+
- 永久架构决策:`specdev/adr/`
|
|
30
|
+
- 永久领域上下文:`specdev/context/`
|
|
31
|
+
- 项目当前代码、测试、配置、schema 和 CI 事实。
|
|
32
|
+
|
|
33
|
+
若尚无 `specdev/changes/{change}/spec.md`,只有在用户提供的计划或对话已经等价覆盖目标、范围、关键决定和可判定验收时才可继续;否则建议先运行 “编写 Spec 阶段”。
|
|
4
34
|
|
|
5
35
|
## 流程
|
|
6
36
|
|
|
7
|
-
### 1.
|
|
37
|
+
### 1. 输入预检
|
|
8
38
|
|
|
9
|
-
|
|
39
|
+
1. 读取所有存在的上游工件;
|
|
40
|
+
2. 检查 `specdev/changes/{change}/spec.md` 的 `ready_for_tickets`;
|
|
41
|
+
3. 按 下方 `<artifact-contract>` 标签 处理 Spec、ADR、用户决定与代码事实的冲突;
|
|
42
|
+
4. 将未知项分类为可发现事实、高影响用户决定和低影响实现细节;
|
|
43
|
+
5. 高影响未决问题没有关闭时停止,不通过更详细的 Ticket 文字伪装决策完备。
|
|
10
44
|
|
|
11
|
-
|
|
12
|
-
- 如果已有 spec,读取变更目录下的 spec.md —— 这是 ticket 拆分的首要依据。
|
|
13
|
-
- 读取变更目录下的 ADR.md 了解本 change 的架构决策——ticket 不应与已做出的决策冲突。
|
|
14
|
-
- 读取变更目录下的 CONTEXT.md 了解本 change 的领域词汇表。
|
|
15
|
-
- 读取永久架构决策目录(specdev/adr/)—— 已确认并提升到永久的架构决策,始终反映项目当前架构现状。
|
|
16
|
-
- 读取永久领域词汇表目录(specdev/context/)—— 已确认并提升到永久的领域词汇表,始终反映项目当前领域术语现状。
|
|
45
|
+
**完成标准**:拆分依据、权威顺序、合同范围与未决问题已明确。
|
|
17
46
|
|
|
18
|
-
|
|
47
|
+
### 2. 探索代码库与实现地形
|
|
19
48
|
|
|
20
|
-
|
|
49
|
+
如果尚未探索,进行只读探索:
|
|
21
50
|
|
|
22
|
-
|
|
51
|
+
- 找到行为入口、稳定接口、测试接缝、数据流和错误路径;
|
|
52
|
+
- 查找相邻或类似实现,优先复用项目现有模式;
|
|
53
|
+
- 识别可能修改的模块、公共路径、共享文件、迁移索引和全局注册点;
|
|
54
|
+
- 查找现有测试命令、夹具、类型检查、构建和 CI 门禁;
|
|
55
|
+
- 对照 `specdev/changes/{change}/CONTEXT.md` 使用项目领域词汇;
|
|
56
|
+
- 对照 `specdev/changes/{change}/ADR.md` 与 `specdev/adr/` 避免重新争论已接受决策。
|
|
23
57
|
|
|
24
|
-
|
|
58
|
+
遇到不熟悉的模块、外部依赖或第三方库时,使用 下方 `<research>` 标签,再继续拆分。
|
|
25
59
|
|
|
26
|
-
|
|
60
|
+
#### Prefactor
|
|
27
61
|
|
|
28
|
-
|
|
29
|
-
- 识别即将被修改的模块——它们的接口是否清晰?依赖是否合理?
|
|
30
|
-
- 如果某个模块的当前结构会使后续实现变得复杂,先提出一个重构 ticket,放在功能 tickets 之前。
|
|
31
|
-
- 预重构必须独立有价值——不是为了"更干净"而重构,而是为了"让后续变更更安全/更简单"。
|
|
62
|
+
遵循“让变更变容易,然后做容易的变更”:
|
|
32
63
|
|
|
33
|
-
|
|
64
|
+
- 如果当前接口、依赖或接缝会使后续实现明显不安全或重复,提出前置 prefactor Ticket;
|
|
65
|
+
- prefactor 必须说明它解除的具体阻碍;
|
|
66
|
+
- prefactor 必须独立有价值且可验证;
|
|
67
|
+
- 不为了“更干净”而创建与目标无关的重构 Ticket。
|
|
34
68
|
|
|
35
|
-
|
|
69
|
+
**完成标准**:实现地形、稳定接缝、共享路径与必要 prefactor 已识别。
|
|
36
70
|
|
|
37
|
-
### 3.
|
|
71
|
+
### 3. 草拟曳光弹式垂直切片
|
|
38
72
|
|
|
39
|
-
|
|
73
|
+
加载 下方 `<decomposition-rules>` 标签。每个切片应横向穿过交付该行为所需的最小层次组合,而不是把数据库、后端、前端和测试拆成互相无价值的水平 Ticket。
|
|
40
74
|
|
|
41
|
-
|
|
42
|
-
- 一个完成的切片可以独立演示或验证——用户可以感知到它交付的行为
|
|
43
|
-
- 每个切片的大小适配单个全新上下文窗口——一个 agent 会话可以在不间断的情况下完成它
|
|
44
|
-
- 任何预重构应最先完成——它们解除后续 tickets 的阻塞
|
|
75
|
+
每个 Ticket 必须:
|
|
45
76
|
|
|
46
|
-
|
|
77
|
+
- 交付一个可观察行为,或一个能独立解除后续阻塞的安全准备能力;
|
|
78
|
+
- 完成后可以独立演示、测试或验证;
|
|
79
|
+
- 适合一个全新 Agent 上下文在不中断的情况下完成;
|
|
80
|
+
- 与其他 Ticket 有实质行为差异;
|
|
81
|
+
- 只依赖真正阻止它开始的前置产物;
|
|
82
|
+
- 自带至少一种完成证据。
|
|
47
83
|
|
|
48
|
-
|
|
84
|
+
#### 宽重构例外
|
|
49
85
|
|
|
50
|
-
|
|
51
|
-
2. **分批迁移调用点**:按影响范围分批(按包、按目录),每批是一个由扩展阶段阻塞的独立 ticket。保持 CI 逐批绿色,因为旧形式仍然存在。
|
|
52
|
-
3. **收缩**:当没有调用方残留时删除旧形式,由一个由所有迁移批次阻塞的 ticket 负责。
|
|
86
|
+
字段重命名、共享符号类型变化、协议升级等宽机械变更无法安全塞入单个垂直切片时,按以下顺序:
|
|
53
87
|
|
|
54
|
-
|
|
88
|
+
1. **Expand**:在旧形式旁增加新形式,保持旧调用方可工作;
|
|
89
|
+
2. **Migrate batches**:按包、目录、消费者或风险分批迁移,每批独立成 Ticket;
|
|
90
|
+
3. **Contract**:确认旧调用点为零后删除旧形式;
|
|
91
|
+
4. 若迁移批次无法各自保持绿色,使用隔离集成分支和最终集成验证 Gate,但仍保留明确的批次与责任边界。
|
|
55
92
|
|
|
56
|
-
|
|
93
|
+
**完成标准**:每个 Ticket 的可观察产出、真实阻塞边和验证方式已草拟。
|
|
57
94
|
|
|
58
|
-
### 4.
|
|
95
|
+
### 4. 判定规划深度与风险
|
|
59
96
|
|
|
60
|
-
|
|
97
|
+
按 下方 `<readiness-and-depth>` 标签 为每个 Ticket 标注:
|
|
61
98
|
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
99
|
+
- `lite`:局部、可逆、沿用既有模式、无公共契约或迁移影响;
|
|
100
|
+
- `standard`:大多数多文件或跨层垂直切片;
|
|
101
|
+
- `deep`:公共 API/schema、数据迁移、安全/隐私/资金、不可逆操作、expand-contract、共享核心路径、多 Agent 或高事故半径。
|
|
65
102
|
|
|
66
|
-
|
|
103
|
+
规划深度不是优先级,也不是 Gate。每个 Ticket 必须记录触发该深度的原因。
|
|
67
104
|
|
|
68
|
-
|
|
69
|
-
- 阻塞边是否正确 —— 每个 ticket 是否只依赖于真正阻碍它的 tickets?是否有不必要的阻塞关系?
|
|
70
|
-
- 是否有 tickets 应合并或进一步拆分?
|
|
105
|
+
### 5. 写成决策完备 Ticket
|
|
71
106
|
|
|
72
|
-
|
|
107
|
+
使用 下方 `<ticket-template>` 标签 填写:
|
|
73
108
|
|
|
74
|
-
|
|
109
|
+
- 战略目标、可观察产出与来源追踪;
|
|
110
|
+
- 当前代码事实和需求差距;
|
|
111
|
+
- 已锁定决策、低影响假设和未决问题;
|
|
112
|
+
- IN / REUSE / OUT;
|
|
113
|
+
- 用户或调用者视角的端到端行为;
|
|
114
|
+
- Standard/Deep 的接口、输入输出、不变量、数据流、失败与兼容契约;
|
|
115
|
+
- 有序执行路线和安全落点;
|
|
116
|
+
- expected、writable、read-only、shared 路径;
|
|
117
|
+
- 正常、失败和回归验证矩阵;
|
|
118
|
+
- 用户界面交互受影响时的 Lead E2E Gate;
|
|
119
|
+
- Deep 的迁移、兼容窗口、监控、回滚和不可逆批准点;
|
|
120
|
+
- 可判定验收标准。
|
|
75
121
|
|
|
76
|
-
|
|
122
|
+
路径所有权必须遵守 下方 `<path-ownership>` 标签,证据设计必须遵守 下方 `<evidence-and-verification>` 标签。
|
|
77
123
|
|
|
78
|
-
|
|
124
|
+
### 6. 构建依赖 DAG、合同覆盖与并发检查
|
|
79
125
|
|
|
80
|
-
|
|
126
|
+
1. 使用 Ticket ID 建立 `blocked_by`;
|
|
127
|
+
2. 检测循环和不存在的引用;
|
|
128
|
+
3. 识别根 Ticket、汇合点、扇出与收缩点;
|
|
129
|
+
4. 为每个 Spec 验收合同映射至少一个 Ticket;
|
|
130
|
+
5. 检查并行候选的 `writable_paths` 是否相交;
|
|
131
|
+
6. 共享路径必须指定唯一 owner,通常由 Lead 或专门 Ticket 修改;
|
|
132
|
+
7. 不得用依赖边表达“可能更方便”或纯粹的人员交接。
|
|
81
133
|
|
|
82
|
-
|
|
134
|
+
使用 下方 `<tickets-map-template>` 标签 草拟总体 Map。
|
|
83
135
|
|
|
84
|
-
|
|
136
|
+
### 7. Definition of Ready
|
|
85
137
|
|
|
86
|
-
|
|
138
|
+
加载 下方 `<ticket-readiness>` 标签 逐个检查。
|
|
87
139
|
|
|
88
|
-
|
|
140
|
+
存在以下任一情况时 `ready: false`:
|
|
89
141
|
|
|
90
|
-
|
|
91
|
-
|
|
142
|
+
- 会改变行为、接口、数据、兼容、安全、范围或验收的未决问题;
|
|
143
|
+
- 依赖缺失或 DAG 有环;
|
|
144
|
+
- 可写路径不明确或并行所有权冲突;
|
|
145
|
+
- 验证方法不能执行且没有批准的替代证据;
|
|
146
|
+
- 单个新上下文无法完成;
|
|
147
|
+
- Standard/Deep 缺少有序执行路线;
|
|
148
|
+
- Deep 缺少迁移、兼容、监控、回滚或批准点。
|
|
149
|
+
|
|
150
|
+
### 8. 与用户核对
|
|
151
|
+
|
|
152
|
+
以完整编号列表展示所有 Ticket,至少包含:
|
|
153
|
+
|
|
154
|
+
- 标题;
|
|
155
|
+
- 可观察交付;
|
|
156
|
+
- 被阻塞于;
|
|
157
|
+
- Planning Depth 与触发原因;
|
|
158
|
+
- 风险;
|
|
159
|
+
- Ready 状态;
|
|
160
|
+
- 关键未决问题;
|
|
161
|
+
- 预计并行组和共享路径 owner。
|
|
162
|
+
|
|
163
|
+
核对:
|
|
164
|
+
|
|
165
|
+
- 粒度是否适合单一上下文;
|
|
166
|
+
- 是否出现水平切片;
|
|
167
|
+
- 阻塞边是否真实;
|
|
168
|
+
- 是否应合并、进一步拆分或增加 prefactor;
|
|
169
|
+
- 合同是否全部覆盖;
|
|
170
|
+
- 路径所有权和验证是否可信。
|
|
171
|
+
|
|
172
|
+
每次修改后重新展示完整列表,直到用户批准。用户明确要求一次性自主规划且不存在高影响未知项时,可使用推荐默认值并把假设写入 Ticket,不为形式重复询问。
|
|
173
|
+
|
|
174
|
+
### 9. 发布
|
|
175
|
+
|
|
176
|
+
创建:
|
|
177
|
+
|
|
178
|
+
- Ticket 目录:`specdev/changes/{change}/ticket/`
|
|
179
|
+
- Tickets Map:`specdev/changes/{change}/tickets-map.md`
|
|
180
|
+
- Evidence 目录:`specdev/changes/{change}/evidence/`
|
|
181
|
+
|
|
182
|
+
按拓扑顺序写入 Ticket:
|
|
183
|
+
|
|
184
|
+
```text
|
|
185
|
+
specdev/changes/{change}/ticket/NN-<ticket-name>.md
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
`NN` 使用两位或更多位零填充数字;Ticket frontmatter ID 使用 `T-NN`。Ticket 的 `blocked_by` 使用 Ticket ID,而不是相对文件路径。
|
|
189
|
+
|
|
190
|
+
使用 下方 `<ticket-template>` 标签 和 下方 `<tickets-map-template>` 标签 生成工件,并对照:
|
|
191
|
+
|
|
192
|
+
- 下方 `<ticket-schema>` 标签
|
|
193
|
+
- 下方 `<tickets-map-schema>` 标签
|
|
194
|
+
|
|
195
|
+
运行:
|
|
196
|
+
|
|
197
|
+
> **结构校验:** 本地项目若已安装 Speculo,使用其 Node 校验器检查当前 change;
|
|
198
|
+
> 纯网页环境逐项核对本文内联的 schema、Ready 清单和完成标准,并记录自动校验未运行。
|
|
199
|
+
|
|
200
|
+
更新 `specdev/status.json` 与 `specdev/changes/{change}/.status.json`。
|
|
201
|
+
|
|
202
|
+
## 完成标准
|
|
203
|
+
|
|
204
|
+
- Ticket 目录和 Map 已写入本文约定的位置;
|
|
205
|
+
- Spec 合同全部 covered 或有明确批准的 deferred;
|
|
206
|
+
- DAG 无环、阻塞引用存在;
|
|
207
|
+
- Ready Ticket 无高影响未知项;
|
|
208
|
+
- 并行 Ticket 无未解决的可写冲突;
|
|
209
|
+
- 每个 Ticket 可独立验证且适配单一上下文;
|
|
210
|
+
- Prefactor 与 expand-contract 使用条件正确;
|
|
211
|
+
- 用户已批准拆分或明确授权自主发布;
|
|
212
|
+
- 校验器无 error。
|
|
213
|
+
|
|
214
|
+
## 子文件引用
|
|
92
215
|
|
|
93
|
-
-
|
|
94
|
-
-
|
|
216
|
+
- 拆分规则:下方 `<decomposition-rules>` 标签
|
|
217
|
+
- Ticket 就绪规则:下方 `<ticket-readiness>` 标签
|
|
218
|
+
- Ticket 模板:下方 `<ticket-template>` 标签
|
|
219
|
+
- Tickets Map 模板:下方 `<tickets-map-template>` 标签
|
|
95
220
|
|
|
96
|
-
|
|
221
|
+
## 下一步
|
|
222
|
+
|
|
223
|
+
满足任一情况时建议运行 “目标规划阶段”:Ticket 数量达到或超过 10、存在多 Agent 并行、Deep Ticket、迁移、共享契约、多个 Gate 或高风险发布。少量线性 Ready Ticket 可直接进入 “实现阶段”。
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## 参考内容
|
|
228
|
+
|
|
229
|
+
以下内容均已内联。主流程提到标签时,直接使用对应标签中的完整规则、模板或 schema。
|
|
230
|
+
|
|
231
|
+
<decomposition-rules>
|
|
232
|
+
|
|
233
|
+
# Ticket 拆分规则
|
|
234
|
+
|
|
235
|
+
本文件由 “拆分 Tickets 阶段” 在草拟切片时加载,并受 下方 `<planning-principles>` 标签 约束。
|
|
236
|
+
|
|
237
|
+
## 好的垂直切片
|
|
238
|
+
|
|
239
|
+
- 从稳定入口到可观察结果形成闭环;
|
|
240
|
+
- 包含该行为所需的最小 schema、接口、交互与测试组合;
|
|
241
|
+
- 完成后仓库处于可验证状态;
|
|
242
|
+
- 与其他切片有实质行为差异;
|
|
243
|
+
- 可以由一个全新上下文完成;
|
|
244
|
+
- 不需要执行者重新决定外部行为或公共契约。
|
|
245
|
+
|
|
246
|
+
## 拆分信号
|
|
247
|
+
|
|
248
|
+
出现任一情况应拆分:
|
|
249
|
+
|
|
250
|
+
- 包含两个可独立发布或验证的用户行为;
|
|
251
|
+
- 需要多个不同领域或架构决策;
|
|
252
|
+
- 预计超出单一上下文;
|
|
253
|
+
- `writable_paths` 过宽且可通过接缝隔离;
|
|
254
|
+
- 验证必须等到不相关工作完成;
|
|
255
|
+
- 一个部分高风险、另一部分低风险;
|
|
256
|
+
- 一个部分改变共享契约,其他部分只是消费者迁移。
|
|
257
|
+
|
|
258
|
+
## 合并信号
|
|
97
259
|
|
|
98
|
-
|
|
260
|
+
出现任一情况应合并:
|
|
99
261
|
|
|
100
|
-
|
|
262
|
+
- 两个 Ticket 单独完成都没有可观察价值或安全准备价值;
|
|
263
|
+
- 只是按技术层水平分割;
|
|
264
|
+
- 验收、代码范围和证据高度重叠;
|
|
265
|
+
- 依赖边只是人为交接,没有真实前置产物;
|
|
266
|
+
- 拆分后每个 Ticket 都需要重复相同关键上下文和同一不可分割验证。
|
|
101
267
|
|
|
102
|
-
|
|
103
|
-
- **与该 ticket 相关的已确认决策**:逐条列出与本 ticket 范围相关的已拍板决策(从 ADR、spec 或对话中提取),防止实现时重新扯皮
|
|
104
|
-
- **与该 ticket 相关的当前现状**:逐条列出与本 ticket 相关的、与需求不符的现有代码/行为。格式:文件路径 + 当前行为 + 为何不满足需求。可附近似行号作定位提示,不作承诺——实施时以现场代码为准
|
|
105
|
-
- **该 ticket 的预期产出**:完成后可观察到的行为变化
|
|
268
|
+
## 特殊模式
|
|
106
269
|
|
|
107
|
-
|
|
270
|
+
### Prefactor
|
|
108
271
|
|
|
109
|
-
|
|
110
|
-
|---------------------|-------------------------|-------------------------|
|
|
111
|
-
| ... | ... | ... |
|
|
272
|
+
必须说明解除的具体阻碍、后续受益 Ticket 和独立验证。不能只写“清理代码”。
|
|
112
273
|
|
|
113
|
-
|
|
274
|
+
### Expand-contract
|
|
114
275
|
|
|
115
|
-
|
|
276
|
+
先扩展兼容层,再分批迁移,最后收缩。每批应保持绿色;不能保持绿色时必须有隔离集成分支与最终集成 Gate。
|
|
116
277
|
|
|
117
|
-
|
|
278
|
+
### Research spike
|
|
118
279
|
|
|
119
|
-
|
|
280
|
+
未知足以阻止决策时,进入 “寻路阶段”。调查 Ticket 只回答决策问题,不顺手实现产品代码。
|
|
120
281
|
|
|
121
|
-
|
|
122
|
-
- 修改 path/to/existing.ts —— 改动内容
|
|
282
|
+
### Shared contract
|
|
123
283
|
|
|
124
|
-
|
|
284
|
+
先由单一 owner Ticket 修改共享契约并形成稳定证据,再扇出消费者 Ticket。共享路径规则见 下方 `<path-ownership>` 标签。
|
|
125
285
|
|
|
126
|
-
|
|
286
|
+
### Bug fix
|
|
127
287
|
|
|
128
|
-
|
|
129
|
-
|------|------|
|
|
130
|
-
| path | 为何需要阅读 |
|
|
288
|
+
已确认根因时,以 `specdev/changes/{change}/diagnosis.md` 的修复契约为依据;根因未知时先运行 “Bug 诊断阶段”。
|
|
131
289
|
|
|
132
|
-
|
|
290
|
+
</decomposition-rules>
|
|
133
291
|
|
|
134
|
-
|
|
292
|
+
<ticket-readiness>
|
|
135
293
|
|
|
136
|
-
|
|
294
|
+
# Ticket Definition of Ready
|
|
137
295
|
|
|
138
|
-
|
|
296
|
+
本检查由 “拆分 Tickets 阶段” 使用,并细化 下方 `<readiness-and-depth>` 标签。
|
|
139
297
|
|
|
140
|
-
|
|
141
|
-
2. 关键技术点
|
|
298
|
+
## 通用门禁
|
|
142
299
|
|
|
143
|
-
|
|
300
|
+
- [ ] frontmatter 字段完整,Ticket ID、文件名和 `specdev/changes/{change}/tickets-map.md` 一致。
|
|
301
|
+
- [ ] 可观察产出单一、明确且可验证。
|
|
302
|
+
- [ ] 来源和验收合同映射存在。
|
|
303
|
+
- [ ] IN、REUSE、OUT 无冲突。
|
|
304
|
+
- [ ] 高影响未决问题为零。
|
|
305
|
+
- [ ] `blocked_by` 指向存在的 Ticket,DAG 无环。
|
|
306
|
+
- [ ] `expected_changes`、`writable_paths`、`read_only_paths` 和 `shared_paths` 中的项目路径都使用项目根相对路径。
|
|
307
|
+
- [ ] `writable_paths` 非空,或明确为仅文档、调查或无代码变更。
|
|
308
|
+
- [ ] 每个 shared path 在 `shared_path_owners` 中有唯一 owner。
|
|
309
|
+
- [ ] 正常、失败和回归至少各有一条验证,或有可信的不适用原因。
|
|
310
|
+
- [ ] 仅当用户界面交互受影响时定义 E2E,且 owner 为 Lead 集成 Gate。
|
|
311
|
+
- [ ] Evidence 位置明确为 `specdev/changes/{change}/evidence/T-NN.md`。
|
|
312
|
+
- [ ] 单个全新上下文能够完成;否则已拆分。
|
|
313
|
+
- [ ] 所有内部文件与目录引用使用本文约定的逻辑路径。
|
|
144
314
|
|
|
145
|
-
|
|
146
|
-
|
|
315
|
+
## Standard 门禁
|
|
316
|
+
|
|
317
|
+
- [ ] 实现契约包含入口、输入输出、不变量、状态或数据流、失败行为和兼容。
|
|
318
|
+
- [ ] 有 3–7 步有序执行路线。
|
|
319
|
+
- [ ] 路径所有权足以支持并发判断。
|
|
320
|
+
- [ ] 验证矩阵可以证明外部行为,而非只检查内部调用。
|
|
321
|
+
|
|
322
|
+
## Deep 门禁
|
|
323
|
+
|
|
324
|
+
- [ ] 迁移顺序、兼容窗口、监控、回滚或前向恢复、收缩条件和批准点完整。
|
|
325
|
+
- [ ] 安全、隐私、资金或数据完整性风险有缓解与验证。
|
|
326
|
+
- [ ] 跨 Agent 路径所有权和集成 Gate 明确。
|
|
327
|
+
- [ ] expand-contract 的收缩条件可通过扫描、指标、查询或测试证明。
|
|
328
|
+
|
|
329
|
+
## Ready 状态
|
|
330
|
+
|
|
331
|
+
只有全部适用项通过时才能设置:
|
|
332
|
+
|
|
333
|
+
```yaml
|
|
334
|
+
ready: true
|
|
335
|
+
status: ready
|
|
147
336
|
```
|
|
148
337
|
|
|
149
|
-
|
|
338
|
+
未通过时保持 `ready: false`,并在未决问题、阻塞原因或偏差记录中写明原因。
|
|
339
|
+
|
|
340
|
+
</ticket-readiness>
|
|
341
|
+
|
|
342
|
+
<ticket-template>
|
|
343
|
+
|
|
344
|
+
## 产物 YAML 头部
|
|
345
|
+
|
|
346
|
+
生成该工件时,将以下字段写在文档开头的 YAML frontmatter 中:
|
|
347
|
+
|
|
348
|
+
```yaml
|
|
349
|
+
schema_version: 3
|
|
350
|
+
artifact: ticket
|
|
351
|
+
change: <YYYY-MM-DD-topic>
|
|
352
|
+
id: T-01
|
|
353
|
+
title: <标题>
|
|
354
|
+
status: draft
|
|
355
|
+
planning_depth: standard
|
|
356
|
+
planning_depth_reason: <触发该深度的事实>
|
|
357
|
+
ready: false
|
|
358
|
+
risk: medium
|
|
359
|
+
blocked_by: []
|
|
360
|
+
contract_ids: [AC-001]
|
|
361
|
+
owner: unassigned
|
|
362
|
+
expected_changes: ["src/example.ts"]
|
|
363
|
+
writable_paths: ["src/example/**"]
|
|
364
|
+
read_only_paths: []
|
|
365
|
+
shared_paths: []
|
|
366
|
+
shared_path_owners: []
|
|
367
|
+
```
|
|
150
368
|
|
|
151
|
-
|
|
152
|
-
- **状态**初始固定为"未开始";实现者开始工作时改为"进行中",完成后改为"已完成"
|
|
153
|
-
- **战略与背景**是必填段——为执行者提供该 ticket 的决策锚点和当前现状。从 spec、ADR、对话中提取,不确定的标记 `[待确认]`
|
|
154
|
-
- **范围边界**是必填段——明确本 ticket 的 IN/REUSE/OUT 三列,防止范围蔓延。OUT 列吸收"明确不做"的内容
|
|
155
|
-
- **交付物**列出本 ticket 产出的具体文件——新增标 **新增**,修改不标,重构标 **重构**。让执行者明确知道要动哪些文件
|
|
156
|
-
- **需阅读的文件**仅在涉及非显而易见的代码区域时填写——告诉执行者上下文边界
|
|
157
|
-
- **保留/不动**是本 ticket 的安全边界——显式列出不能碰的代码/契约/数据。无则写"无"
|
|
158
|
-
- **实现要点**仅在 ticket 涉及有意义的架构决策时填写(3-7 条)。简单 ticket 省略
|
|
159
|
-
- **验收标准**使用 `- [ ]` checklist 格式,每条具体、可独立验证。优先写可执行命令,其次写手动检查步骤
|
|
160
|
-
- 描述统一使用深层模块设计词汇:模块/接口/接缝/适配器,而非组件/服务/边界
|
|
369
|
+
# Ticket T-01: <标题>
|
|
161
370
|
|
|
162
|
-
|
|
371
|
+
- **Ticket 文件:** `specdev/changes/{change}/ticket/01-<ticket-name>.md`
|
|
372
|
+
- **总体 Map:** `specdev/changes/{change}/tickets-map.md`
|
|
373
|
+
- **上游 Spec:** `specdev/changes/{change}/spec.md`
|
|
374
|
+
- **完成 Evidence:** `specdev/changes/{change}/evidence/T-01.md`
|
|
163
375
|
|
|
164
|
-
|
|
376
|
+
## 1. 战略与来源
|
|
165
377
|
|
|
166
|
-
|
|
378
|
+
- **目标:** 做什么、为什么、基于什么现有能力。
|
|
379
|
+
- **可观察产出:** 完成后用户、调用者或系统外部可以观察到什么。
|
|
380
|
+
- **来源:** `US-###`、`AC-###`、`ADR-###`、`USER-DECISION`、`CODE`、`RESEARCH` 或 `DIAG-###`。
|
|
381
|
+
- **当前事实:** 相关现状与目标差距;项目文件使用项目根相对路径,例如 `src/example.ts`。
|
|
382
|
+
- **Planning Depth 原因:** 说明为什么是 Lite、Standard 或 Deep。
|
|
167
383
|
|
|
168
|
-
|
|
384
|
+
## 2. 决策状态
|
|
169
385
|
|
|
170
|
-
|
|
386
|
+
### 已锁定决策
|
|
171
387
|
|
|
172
|
-
-
|
|
173
|
-
- **编号**列使用 `01`、`02`、`10` 格式(两位零填充阿拉伯数字,不含 `#`),代表依赖顺序
|
|
174
|
-
- **被阻塞于**列填写阻塞者的编号(如 `01`、`02, 05`)
|
|
175
|
-
- **状态**列由 T-tickets 初始化为"未开始",后续由实现者手动更新——始终以对应 ticket 文件中的状态字段为权威来源
|
|
176
|
-
- **Gate** 列(P0/P1/P2)和 **Contract ID** 列由 P-goal-plan 填充;T-tickets 阶段留空或标 `[待标注]`
|
|
177
|
-
- **依赖关系**用 ASCII 树形图展示阻塞链——T-tickets 写入基础结构,P-goal-plan 叠加门禁标注
|
|
178
|
-
- **横切关注点**只放跨 ticket 的规则——单 ticket 的规则留在该 ticket 文件内
|
|
179
|
-
- **阻塞关系说明**在依赖图非平凡时补充文字解释
|
|
388
|
+
- ...
|
|
180
389
|
|
|
181
|
-
|
|
390
|
+
### 已采用的低影响假设
|
|
182
391
|
|
|
183
|
-
|
|
392
|
+
- 无。
|
|
184
393
|
|
|
185
|
-
|
|
186
|
-
|------|------|----------|
|
|
187
|
-
| tickets-map-template(参见下方 `<tickets-map-template>` 标签) | tickets-map.md 权威模板——执行清单六列表格、门禁标注 DAG、并行规则、横切关注点 | 进入步骤 5c「写入 tickets-map.md」时加载——T-tickets 按此模板输出基础结构,P-goal-plan 随后标注 Gate、Contract ID 和门禁 DAG |
|
|
394
|
+
### 未决问题
|
|
188
395
|
|
|
189
|
-
|
|
396
|
+
无。
|
|
190
397
|
|
|
191
|
-
|
|
192
|
-
- 变更目录下的 `ticket/` 目录 —— 独立 ticket 文件目录,每个文件命名为 `NN-<ticket-name>.md`(`NN` = `01`, `02`, ..., `10`, ...)
|
|
193
|
-
- 变更目录下的 spec.md —— 上游 spec(拆分依据)
|
|
194
|
-
- 永久架构决策目录(specdev/adr/)—— 已确认并提升的 ADR
|
|
195
|
-
- 永久领域词汇表目录(specdev/context/)—— 已确认并提升的 CONTEXT
|
|
398
|
+
存在会改变行为、接口、数据、兼容、安全、范围、迁移或验收的问题时,frontmatter 中 `ready` 必须为 `false`。
|
|
196
399
|
|
|
197
|
-
##
|
|
400
|
+
## 3. 范围边界
|
|
198
401
|
|
|
199
|
-
|
|
402
|
+
| IN(本 Ticket 构建) | REUSE(复用且不改变契约) | OUT(明确不做) |
|
|
403
|
+
|---|---|---|
|
|
404
|
+
| ... | ... | ... |
|
|
200
405
|
|
|
201
|
-
|
|
406
|
+
## 4. 要构建什么
|
|
202
407
|
|
|
203
|
-
|
|
408
|
+
从用户或调用者视角描述一条完整行为路径:入口、动作、可观察结果、失败行为和边界。不要按数据库、后端、前端、测试等技术层分段罗列。
|
|
204
409
|
|
|
205
|
-
|
|
410
|
+
## 5. 实现契约
|
|
411
|
+
|
|
412
|
+
<!-- Lite 可压缩为适用条目;Standard 和 Deep 必填。 -->
|
|
413
|
+
|
|
414
|
+
- **入口或接缝:**
|
|
415
|
+
- **输入与输出:**
|
|
416
|
+
- **公共接口变化:** 无 / ...
|
|
417
|
+
- **不变量:**
|
|
418
|
+
- **状态或数据流:**
|
|
419
|
+
- **错误与失败行为:**
|
|
420
|
+
- **兼容要求:**
|
|
421
|
+
- **安全与隐私要求:** 不适用:原因 / ...
|
|
422
|
+
|
|
423
|
+
## 6. 执行路线
|
|
206
424
|
|
|
207
|
-
|
|
425
|
+
<!-- Lite 通常 1–3 步;Standard 和 Deep 通常 3–7 步。描述行为顺序、安全落点和验证时机,不写逐行代码。 -->
|
|
208
426
|
|
|
209
|
-
|
|
427
|
+
1. 建立或确认验证接缝,使目标行为或关键风险按预期失败。
|
|
428
|
+
2. ...
|
|
429
|
+
3. 形成保持仓库可验证的安全落点。
|
|
430
|
+
4. 运行定向验证和适用回归。
|
|
210
431
|
|
|
211
|
-
##
|
|
432
|
+
## 7. 路径访问契约
|
|
212
433
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
434
|
+
- **预计修改点:** 与 `expected_changes` 对齐,仅作导航。
|
|
435
|
+
- **可写范围:** 与 `writable_paths` 对齐;越界前必须停止。
|
|
436
|
+
- **只读上下文:** 与 `read_only_paths` 对齐。
|
|
437
|
+
- **共享路径:** 与 `shared_paths` 对齐;每项在 `shared_path_owners` 指定唯一 owner。
|
|
438
|
+
- **保留或不动:** 无 / ...
|
|
218
439
|
|
|
219
|
-
|
|
220
|
-
> **被阻塞于**列填写阻塞本 ticket 的 ticket 编号(如 `01`、`02, 05`),执行者需自行打开对应 ticket 文件查看其状态。不可仅凭此表判断——始终以对应 ticket 文件中的状态字段为准。
|
|
221
|
-
> **Gate 列**:P0 = 核心基础设施(阻塞所有后续工作)/ P1 = 主要功能切片 / P2 = 增强和边界情况。由 P-goal-plan 填充,T-tickets 阶段留空或标注 `[待标注]`。
|
|
222
|
-
> **Contract ID 列**:如有冻结合同/验收文档,填写本 ticket 覆盖的验收条目 ID(如 `P0-01, P1-03`);无合同则填 `—`。由 P-goal-plan 填充。
|
|
440
|
+
项目路径必须写成项目根相对路径。SpecDev 工件必须使用本文约定的逻辑路径。
|
|
223
441
|
|
|
224
|
-
##
|
|
442
|
+
## 8. 验证矩阵
|
|
225
443
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
444
|
+
| 行为或风险 | 验证接缝 | 命令或步骤 | 预期结果 | Evidence |
|
|
445
|
+
|---|---|---|---|---|
|
|
446
|
+
| 正常路径 | ... | ... | ... | `specdev/changes/{change}/evidence/T-01.md` |
|
|
447
|
+
| 失败路径 | ... | ... | ... | `specdev/changes/{change}/evidence/T-01.md` |
|
|
448
|
+
| 回归 | ... | ... | ... | `specdev/changes/{change}/evidence/T-01.md` |
|
|
229
449
|
|
|
230
|
-
|
|
231
|
-
- 每行一个 ticket,缩进表示依赖深度
|
|
232
|
-
- → 表示依赖关系(A → B 表示 B 依赖 A)
|
|
233
|
-
- 用注释标注门禁边界:--- P0 gate ---
|
|
234
|
-
- 可立即开始的 ticket 标注 [READY]
|
|
235
|
-
- 扇出点标注 [FAN-OUT: N路并行]
|
|
450
|
+
不适用的关键风险类别必须写“不适用:原因”。
|
|
236
451
|
|
|
237
|
-
|
|
238
|
-
01 [READY] → 02 [FAN-OUT: 3路并行]
|
|
239
|
-
├→ 03 [P0]
|
|
240
|
-
├→ 04 [P1]
|
|
241
|
-
└→ 05 [P1]
|
|
242
|
-
--- P0 gate ---
|
|
243
|
-
03 → 06 [P1] → 07 [P2]
|
|
244
|
-
-->
|
|
452
|
+
仅当用户界面交互受影响时增加 E2E 行;owner 固定为 Lead 集成 Gate,Worker 只提供场景与预期。
|
|
245
453
|
|
|
454
|
+
## 9. 发布、迁移与恢复
|
|
455
|
+
|
|
456
|
+
<!-- Deep 必填;其他深度仅在适用时保留。 -->
|
|
457
|
+
|
|
458
|
+
- **迁移顺序:** 不适用:原因 / ...
|
|
459
|
+
- **兼容窗口:** 不适用:原因 / ...
|
|
460
|
+
- **监控信号:** 不适用:原因 / ...
|
|
461
|
+
- **回滚或前向恢复:**
|
|
462
|
+
- **不可逆操作与批准点:** 无 / ...
|
|
463
|
+
- **收缩条件:** 不适用:原因 / 旧调用点、旧数据或旧协议使用量为零并有 Evidence。
|
|
464
|
+
|
|
465
|
+
## 10. 验收标准
|
|
466
|
+
|
|
467
|
+
- [ ] `AC-001`:<可判定结果>。
|
|
468
|
+
- [ ] 验证矩阵全部执行并记录到 `specdev/changes/{change}/evidence/T-01.md`。
|
|
469
|
+
- [ ] 实际项目修改未超出 `writable_paths`,shared path 由指定 owner 修改。
|
|
470
|
+
- [ ] 未发生未批准的范围、契约或发布偏差。
|
|
471
|
+
- [ ] Ticket、Tickets Map 和 Evidence 状态一致。
|
|
472
|
+
|
|
473
|
+
</ticket-template>
|
|
474
|
+
|
|
475
|
+
<tickets-map-template>
|
|
476
|
+
|
|
477
|
+
## 产物 YAML 头部
|
|
478
|
+
|
|
479
|
+
生成该工件时,将以下字段写在文档开头的 YAML frontmatter 中:
|
|
480
|
+
|
|
481
|
+
```yaml
|
|
482
|
+
schema_version: 3
|
|
483
|
+
artifact: tickets-map
|
|
484
|
+
change: <YYYY-MM-DD-topic>
|
|
485
|
+
status: draft
|
|
246
486
|
```
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
487
|
+
|
|
488
|
+
# Tickets Map: <工作名称>
|
|
489
|
+
|
|
490
|
+
- **Map:** `specdev/changes/{change}/tickets-map.md`
|
|
491
|
+
- **Spec:** `specdev/changes/{change}/spec.md`
|
|
492
|
+
- **Ticket 目录:** `specdev/changes/{change}/ticket/`
|
|
493
|
+
- **Evidence 目录:** `specdev/changes/{change}/evidence/`
|
|
494
|
+
- **可选 Goal Plan:** `specdev/changes/{change}/goal-plan.md`
|
|
495
|
+
|
|
496
|
+
## 1. 目标与拆分策略
|
|
497
|
+
|
|
498
|
+
引用主要用户故事、验收合同和架构决策,说明所有 Ticket 共同交付的目标、切片原则、prefactor 和 expand-contract 选择。不要复制整个 Spec。
|
|
499
|
+
|
|
500
|
+
## 2. 执行清单
|
|
501
|
+
|
|
502
|
+
| ID | Ticket | 可观察产出 | Blocked By | Depth | Risk | Ready | Owner | Contract IDs | Wave/Gate | Status |
|
|
503
|
+
|---|---|---|---|---|---|---|---|---|---|---|
|
|
504
|
+
| T-01 | `specdev/changes/{change}/ticket/01-<ticket-name>.md` | ... | — | standard | medium | yes | unassigned | AC-001 | — | ready |
|
|
505
|
+
|
|
506
|
+
Ticket frontmatter 是状态、依赖、深度和路径访问契约的权威;本表是同步投影,不得独立修改出另一套真相。
|
|
507
|
+
|
|
508
|
+
## 3. 依赖 DAG
|
|
509
|
+
|
|
510
|
+
```text
|
|
511
|
+
T-01 [READY]
|
|
512
|
+
├─→ T-02
|
|
513
|
+
└─→ T-03
|
|
514
|
+
└─→ T-04
|
|
251
515
|
```
|
|
252
516
|
|
|
253
|
-
|
|
517
|
+
每条边必须表示真实开始条件。标记关键汇合点、prefactor、expand、migrate、observe、contract 和集成验证点。
|
|
518
|
+
|
|
519
|
+
## 4. 合同覆盖矩阵
|
|
254
520
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
-
|
|
258
|
-
- 共享文件修改后,所有并发子代理需在继续前同步
|
|
521
|
+
| Contract ID | 覆盖 Ticket | 验证接缝 | 状态 | 说明 |
|
|
522
|
+
|---|---|---|---|---|
|
|
523
|
+
| AC-001 | T-01 | ... | covered | ... |
|
|
259
524
|
|
|
260
|
-
|
|
525
|
+
`uncovered` 必须修复;`deferred` 必须有用户批准、原因和后续归属。
|
|
261
526
|
|
|
262
|
-
|
|
527
|
+
## 5. 并行与路径所有权
|
|
263
528
|
|
|
264
|
-
-
|
|
265
|
-
-
|
|
266
|
-
-
|
|
529
|
+
- 最大并发来自 `specdev/config.json`。
|
|
530
|
+
- shared owner 为 Lead 或专用 Ticket。
|
|
531
|
+
- 项目路径契约以 Ticket frontmatter 为准。
|
|
532
|
+
- 并行写代码的 Ticket 使用独立 worktree;只读调查不需要。
|
|
267
533
|
|
|
268
|
-
|
|
534
|
+
| Ticket A | Ticket B | Writable 交集 | 真实依赖 | 处理 |
|
|
535
|
+
|---|---|---|---|---|
|
|
536
|
+
| T-02 | T-03 | 无 | 否 | 可并行 |
|
|
269
537
|
|
|
270
|
-
|
|
538
|
+
## 6. Gate、Wave 与集成点
|
|
271
539
|
|
|
272
|
-
|
|
540
|
+
T-tickets 可以标注候选 Wave 和行为里程碑。需要正式跨 Ticket 编排时,由 “目标规划阶段” 完成 Gate、Wave、owner、发布与恢复,并把结果投影回本 Map。
|
|
273
541
|
|
|
274
|
-
##
|
|
542
|
+
## 7. 横切契约与风险
|
|
275
543
|
|
|
276
|
-
|
|
544
|
+
只记录跨多个 Ticket 的数据、安全、兼容、共享接口、迁移、发布和恢复规则。单 Ticket 规则留在具体 `specdev/changes/{change}/ticket/NN-<ticket-name>.md`。
|
|
545
|
+
|
|
546
|
+
## 8. 同步规则
|
|
547
|
+
|
|
548
|
+
- Ticket 状态变化后同步执行清单;
|
|
549
|
+
- Ticket ID、路径、依赖或 frontmatter 不一致时,以 Ticket 文件为权威并修复本 Map;
|
|
550
|
+
- Goal Plan 存在时,Wave、Gate 和 owner 以 `specdev/changes/{change}/goal-plan.md` 为编排权威;
|
|
551
|
+
- 依赖、合同覆盖或路径所有权变化后运行 Speculo Node 校验器;
|
|
552
|
+
- 内部工件使用本文约定的逻辑路径,不用 Markdown 链接充当状态引用。
|
|
277
553
|
|
|
278
554
|
</tickets-map-template>
|
|
555
|
+
|
|
556
|
+
<planning-principles>
|
|
557
|
+
|
|
558
|
+
# 规划原则
|
|
559
|
+
|
|
560
|
+
SpecDev 的规划目标是“决策完备、细节最小充分、能够验证”,不是把每个任务写成逐行施工脚本。
|
|
561
|
+
|
|
562
|
+
## 1. 先探索,后提问
|
|
563
|
+
|
|
564
|
+
先读取相关入口、配置、schema、类型、测试、相邻实现、当前工件和历史决策。未知项分为:
|
|
565
|
+
|
|
566
|
+
- **可发现事实**:通过只读探索解决,不询问用户;
|
|
567
|
+
- **高影响偏好或取舍**:无法从仓库推导,且会改变行为、架构、风险、范围、迁移或验收时才询问;
|
|
568
|
+
- **低影响实现细节**:由实现者遵循现有惯例决定。
|
|
569
|
+
|
|
570
|
+
外部事实研究使用 下方 `<research>` 标签。
|
|
571
|
+
|
|
572
|
+
## 2. 决策完备
|
|
573
|
+
|
|
574
|
+
一个 Plan 或 Ticket 达到以下状态才可执行:
|
|
575
|
+
|
|
576
|
+
- 目标和成功标准明确;
|
|
577
|
+
- IN、REUSE、OUT 与不变量明确;
|
|
578
|
+
- 公共接口、数据和兼容策略已锁定或明确不变化;
|
|
579
|
+
- 失败行为和关键边界有结论;
|
|
580
|
+
- 依赖、路径所有权和批准点明确;
|
|
581
|
+
- 验证方式和 Evidence 位置明确;
|
|
582
|
+
- 不存在会改变上述内容的高影响未决问题。
|
|
583
|
+
|
|
584
|
+
决策完备不要求逐文件穷举、逐函数步骤、逐行代码、重复代码库事实或虚构未来路径。
|
|
585
|
+
|
|
586
|
+
## 3. 最小充分细节
|
|
587
|
+
|
|
588
|
+
- 局部、低风险、沿用现有模式的切片使用 Lite。
|
|
589
|
+
- 多文件或跨层垂直切片使用 Standard。
|
|
590
|
+
- 公共契约、迁移、安全、不可逆操作、共享核心路径或复杂协作使用 Deep。
|
|
591
|
+
|
|
592
|
+
详细条件位于 下方 `<readiness-and-depth>` 标签。
|
|
593
|
+
|
|
594
|
+
## 4. 计划与执行分离
|
|
595
|
+
|
|
596
|
+
规划阶段可以读取、搜索、静态分析和执行只读或非修改性验证,不实现产品代码。执行阶段不重新决定已锁定的产品和架构事项。计划与代码事实冲突时,按 下方 `<deviation-control>` 标签 退回修订。
|
|
597
|
+
|
|
598
|
+
## 5. 以可验证目标委托
|
|
599
|
+
|
|
600
|
+
每个交付物至少有一种可重复证据:测试、类型检查、lint、构建、API 示例、截图对比、迁移 dry-run、查询结果或手动步骤。验证绑定外部行为或稳定接缝,不把私有实现细节当作唯一证据。
|
|
601
|
+
|
|
602
|
+
## 6. 委托而非微操
|
|
603
|
+
|
|
604
|
+
Ticket 告诉执行者:做什么、为什么、不能改变什么、按什么顺序形成安全落点、怎样证明。执行者决定:在现有代码惯例内怎样组织局部实现。只有高风险或非显然的接口、迁移和顺序需要写入执行路线。
|
|
605
|
+
|
|
606
|
+
## 7. 分层规划
|
|
607
|
+
|
|
608
|
+
- Spec 决定外部行为。
|
|
609
|
+
- Ticket 是决策完备的微型执行计划。
|
|
610
|
+
- Tickets Map 决定依赖和覆盖投影。
|
|
611
|
+
- Goal Plan 只在协调复杂度需要时决定跨 Ticket 编排。
|
|
612
|
+
- Implement 在既定契约内完成代码和 Evidence。
|
|
613
|
+
|
|
614
|
+
职责细节见 下方 `<artifact-contract>` 标签。
|
|
615
|
+
|
|
616
|
+
</planning-principles>
|
|
617
|
+
|
|
618
|
+
<artifact-contract>
|
|
619
|
+
|
|
620
|
+
# 工件职责与权威裁决
|
|
621
|
+
|
|
622
|
+
SpecDev 通过分层工件避免同一决策被多个模型反复重做。每个工件只承担自己的权威边界。
|
|
623
|
+
|
|
624
|
+
## 1. 工件职责
|
|
625
|
+
|
|
626
|
+
| 工件 | 具体位置 | 必须决定 | 不应决定 |
|
|
627
|
+
|---|---|---|---|
|
|
628
|
+
| 分诊 | `specdev/changes/{change}/triage.md` | 请求类别、影响、风险、缺失输入和下一 work | 详细实现方案 |
|
|
629
|
+
| 诊断 | `specdev/changes/{change}/diagnosis.md` | 复现、证据、根因、修复不变量和回归契约 | 未经验证的修复实现 |
|
|
630
|
+
| 设计日志 | `specdev/changes/{change}/LOG.md` | 讨论轨迹、确认、延后、替代与废弃结论 | 当前架构权威摘要 |
|
|
631
|
+
| 领域上下文 | `specdev/changes/{change}/CONTEXT.md` | 当前领域术语、语义和稳定不变量 | 临时会议记录 |
|
|
632
|
+
| 架构决策 | `specdev/changes/{change}/ADR.md` | 已接受架构决策、原因、后果和替代关系 | 尚未决定的方案集合 |
|
|
633
|
+
| Spec | `specdev/changes/{change}/spec.md` | 用户问题、外部行为、范围、验收合同、非功能要求和已锁定实现约束 | 文件级施工步骤 |
|
|
634
|
+
| Ticket | `specdev/changes/{change}/ticket/NN-<ticket-name>.md` | 单一垂直切片的行为、决策、范围、路径所有权、执行路线和验证证据 | 跨 Ticket 里程碑治理 |
|
|
635
|
+
| Tickets Map | `specdev/changes/{change}/tickets-map.md` | 依赖 DAG、合同覆盖、Ready 投影、并行候选和路径冲突 | 单 Ticket 的完整实现契约 |
|
|
636
|
+
| Goal Plan | `specdev/changes/{change}/goal-plan.md` | 跨 Ticket 调度、Gate、共享所有权、迁移顺序、集成和偏差治理 | 复制 Ticket 全文 |
|
|
637
|
+
| Evidence | `specdev/changes/{change}/evidence/T-NN.md` | 实际修改、命令、结果、验收映射、偏差、风险和提交引用 | 新的产品或架构决策 |
|
|
638
|
+
|
|
639
|
+
## 2. 权威顺序
|
|
640
|
+
|
|
641
|
+
同一事项冲突时按下列顺序裁决:
|
|
642
|
+
|
|
643
|
+
1. 用户最新明确决定;
|
|
644
|
+
2. 当前已接受架构决策:`specdev/changes/{change}/ADR.md`;
|
|
645
|
+
3. 当前外部行为权威:`specdev/changes/{change}/spec.md`;
|
|
646
|
+
4. 当前 Ticket 契约:`specdev/changes/{change}/ticket/NN-<ticket-name>.md`;
|
|
647
|
+
5. 当前跨 Ticket 编排:`specdev/changes/{change}/goal-plan.md`;
|
|
648
|
+
6. 当前代码与运行事实;
|
|
649
|
+
7. 旧计划、旧日志和未经确认的推断。
|
|
650
|
+
|
|
651
|
+
代码事实可以证明计划已过时,但不能静默改写用户目标或已接受契约。出现这种情况时,按 下方 `<deviation-control>` 标签 退回相应工件修订。
|
|
652
|
+
|
|
653
|
+
## 3. 来源追踪
|
|
654
|
+
|
|
655
|
+
高影响条目应带来源标识:
|
|
656
|
+
|
|
657
|
+
- `USER-DECISION:<date-or-summary>`;
|
|
658
|
+
- `ADR-###`;
|
|
659
|
+
- `US-###` 或 `AC-###`;
|
|
660
|
+
- `CODE:project/relative/path`;
|
|
661
|
+
- `RESEARCH:<Url>https://example.com/source</Url>`;
|
|
662
|
+
- `DIAG-###`。
|
|
663
|
+
|
|
664
|
+
来源追踪解释“为什么这样决定”,不要求为普通描述逐句加标签。
|
|
665
|
+
|
|
666
|
+
## 4. 冲突处理
|
|
667
|
+
|
|
668
|
+
1. 指明冲突事项和双方来源;
|
|
669
|
+
2. 判断冲突属于事实过时、产品取舍、架构取舍、Ticket 范围还是调度问题;
|
|
670
|
+
3. 按本规则的权威顺序提出裁决;
|
|
671
|
+
4. 若改变外部行为、公共契约、数据、安全、范围、迁移或验收,必须获得用户或指定批准人决定;
|
|
672
|
+
5. 更新真正拥有该决策的工件;
|
|
673
|
+
6. 在 `specdev/changes/{change}/LOG.md` 保留被替代结论和原因;
|
|
674
|
+
7. 重新执行结构校验;纯网页环境按本文的内联规则人工核对。
|
|
675
|
+
|
|
676
|
+
不得仅在下游工件中覆盖上游权威。
|
|
677
|
+
|
|
678
|
+
</artifact-contract>
|
|
679
|
+
|
|
680
|
+
<readiness-and-depth>
|
|
681
|
+
|
|
682
|
+
# 规划深度与执行就绪
|
|
683
|
+
|
|
684
|
+
## 1. Planning Depth
|
|
685
|
+
|
|
686
|
+
### Lite
|
|
687
|
+
|
|
688
|
+
适用条件通常全部满足:范围局部、行为明确、沿用既有模式、无公共接口或数据迁移、无安全或高事故半径影响、易回滚、无需并行协调。
|
|
689
|
+
|
|
690
|
+
最低内容:目标、范围、项目路径授权、1–3 条执行路线、验收标准和验证方法。
|
|
691
|
+
|
|
692
|
+
### Standard
|
|
693
|
+
|
|
694
|
+
适用于大多数跨多个文件或技术层的垂直切片。
|
|
695
|
+
|
|
696
|
+
额外要求:锁定决策与假设、接口接缝、输入输出、不变量、失败行为、有序执行路线、验证矩阵和路径所有权。
|
|
697
|
+
|
|
698
|
+
### Deep
|
|
699
|
+
|
|
700
|
+
任一条件触发:公共 API、schema、wire format、数据迁移、认证授权、隐私、资金、不可逆操作、expand-contract、共享核心路径、多 Agent 复杂协作、多个实质架构方案或高事故半径。
|
|
701
|
+
|
|
702
|
+
额外要求:数据流或状态转换、兼容窗口、迁移顺序、可观测性、回滚、风险缓解、收缩条件和人工批准点。
|
|
703
|
+
|
|
704
|
+
## 2. Ticket Definition of Ready
|
|
705
|
+
|
|
706
|
+
Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
|
|
707
|
+
|
|
708
|
+
- 外部行为和可观察产出明确;
|
|
709
|
+
- IN、REUSE、OUT 无冲突;
|
|
710
|
+
- 高影响决策已锁定;
|
|
711
|
+
- 没有会改变行为、接口、数据、兼容、安全、范围或验收的未决问题;
|
|
712
|
+
- 依赖存在且无循环;
|
|
713
|
+
- `writable_paths`、`read_only_paths` 和 `shared_paths` 使用项目根相对路径;
|
|
714
|
+
- shared path 有唯一 owner;
|
|
715
|
+
- 验收标准可判定;
|
|
716
|
+
- 验证矩阵覆盖正常、失败和回归风险,或有可信的不适用理由;
|
|
717
|
+
- Standard 或 Deep Ticket 有有序执行路线;
|
|
718
|
+
- Deep Ticket 有迁移、兼容、监控、回滚和批准点,或逐项说明不适用;
|
|
719
|
+
- 单个全新上下文可以完成,否则必须拆分。
|
|
720
|
+
|
|
721
|
+
详细检查位于 下方 `<ticket-readiness>` 标签。
|
|
722
|
+
|
|
723
|
+
## 3. Spec Readiness
|
|
724
|
+
|
|
725
|
+
`specdev/changes/{change}/spec.md` 只有在外部行为、范围、公共接口、数据、安全、兼容、迁移和验收合同不存在高影响未知项时,才可设置 `ready_for_tickets: true`。
|
|
726
|
+
|
|
727
|
+
## 4. 假设规则
|
|
728
|
+
|
|
729
|
+
- 低影响、可逆的默认值可以作为显式假设继续;
|
|
730
|
+
- 高影响假设不得用于强行通过 Ready;
|
|
731
|
+
- 实现者发现假设不成立时,按 下方 `<deviation-control>` 标签 处理;
|
|
732
|
+
- 假设必须有适用范围和验证方式。
|
|
733
|
+
|
|
734
|
+
</readiness-and-depth>
|
|
735
|
+
|
|
736
|
+
<path-ownership>
|
|
737
|
+
|
|
738
|
+
# 路径所有权与并发规则
|
|
739
|
+
|
|
740
|
+
路径所有权是并行执行的硬边界,不是文件预测清单。
|
|
741
|
+
|
|
742
|
+
## 1. 四类路径
|
|
743
|
+
|
|
744
|
+
- `expected_changes`:预计修改的项目路径,仅用于导航;每项写成项目根相对路径。
|
|
745
|
+
- `writable_paths`:实现者获准修改的项目路径或 glob,是硬约束。
|
|
746
|
+
- `read_only_paths`:建立上下文但不得修改的项目路径。
|
|
747
|
+
- `shared_paths`:多个 Ticket 可能需要修改的项目路径,必须指定唯一 owner。
|
|
748
|
+
|
|
749
|
+
示例:
|
|
750
|
+
|
|
751
|
+
```yaml
|
|
752
|
+
expected_changes: ["src/auth/session.ts"]
|
|
753
|
+
writable_paths: ["src/auth/**"]
|
|
754
|
+
read_only_paths: ["src/users/**"]
|
|
755
|
+
shared_paths: ["package.json"]
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
## 2. 所有权规则
|
|
759
|
+
|
|
760
|
+
1. 可能并行的 Ticket,其 `writable_paths` 不得相交。
|
|
761
|
+
2. glob 与具体路径按覆盖关系判断,不得只比较字符串。
|
|
762
|
+
3. 根依赖清单、锁文件、根导出、共享 schema、迁移索引、全局路由和跨 Ticket 合同文件默认视为 shared。
|
|
763
|
+
4. shared path 只能由 Lead 或专用 owner Ticket 修改;消费者 Ticket 只读。
|
|
764
|
+
5. 需要越界时先停止,按 下方 `<deviation-control>` 标签 提出 ownership change;不得先改后报。
|
|
765
|
+
6. 前置 Ticket 改变目录结构后,后续 Ticket 开始前重新解析项目路径;若授权范围语义未改变,可只更新导航路径。
|
|
766
|
+
7. 不得把“最后解决合并冲突”当作所有权方案。
|
|
767
|
+
|
|
768
|
+
## 3. Worktree 与分支
|
|
769
|
+
|
|
770
|
+
并行写代码的 Ready Ticket 使用隔离 worktree;只读调查和顺序执行默认共用当前工作区。Worktree 防止工作区污染,路径所有权防止逻辑冲突,两者不能互相替代。
|
|
771
|
+
|
|
772
|
+
生命周期由 Lead 按 下方 `<dev-worktree>` 标签 管理,编排规则位于 “目标规划阶段的 Lead 编排规则”。
|
|
773
|
+
|
|
774
|
+
</path-ownership>
|
|
775
|
+
|
|
776
|
+
<evidence-and-verification>
|
|
777
|
+
|
|
778
|
+
# 证据与验证规范
|
|
779
|
+
|
|
780
|
+
验证回答“怎样证明行为已经正确发生”,Evidence 回答“实际运行了什么、结果是什么、仍有什么风险”。
|
|
781
|
+
|
|
782
|
+
## 1. 验证矩阵
|
|
783
|
+
|
|
784
|
+
每一行绑定一个行为、合同或风险:
|
|
785
|
+
|
|
786
|
+
| 行为或风险 | 验证接缝 | 方法或命令 | 预期结果 | Evidence |
|
|
787
|
+
|---|---|---|---|---|
|
|
788
|
+
| 正常路径 | 公共接口 | 项目定向测试 | 指定外部行为成立 | `specdev/changes/{change}/evidence/T-NN.md` |
|
|
789
|
+
| 无效输入 | schema 或公共接口 | 定向失败测试 | 稳定错误行为成立 | `specdev/changes/{change}/evidence/T-NN.md` |
|
|
790
|
+
| 回归 | 现有测试套件 | 项目回归命令 | 相关既有行为保持 | `specdev/changes/{change}/evidence/T-NN.md` |
|
|
791
|
+
|
|
792
|
+
命令引用项目脚本时,项目文件路径使用项目根相对路径,例如 `package.json` 或 `Makefile`。
|
|
793
|
+
|
|
794
|
+
## 2. 最小充分验证
|
|
795
|
+
|
|
796
|
+
选择最接近目标行为的稳定接缝:
|
|
797
|
+
|
|
798
|
+
1. 公共接口或契约集成测试;
|
|
799
|
+
2. 稳定接缝上的单元测试;
|
|
800
|
+
3. 类型检查、静态分析、lint 和构建;
|
|
801
|
+
4. 可重复手动步骤、截图或查询结果;
|
|
802
|
+
5. 代码阅读推断。
|
|
803
|
+
|
|
804
|
+
E2E 仅在变更影响用户界面交互时加入验证矩阵,并且只由 Lead 在集成阶段执行。Worker 只记录场景、预期结果和待执行状态。API、CLI、后端、库或数据变更默认使用其稳定接缝,不追加 E2E。
|
|
805
|
+
|
|
806
|
+
低层证据不能替代明确要求的用户行为证据。高风险迁移还需要 dry-run、调用点扫描、数据核对、监控信号或回滚演练。
|
|
807
|
+
|
|
808
|
+
## 3. 失败分类
|
|
809
|
+
|
|
810
|
+
每个失败必须分类为:
|
|
811
|
+
|
|
812
|
+
- 本 Ticket 引入的新失败;
|
|
813
|
+
- 基线已存在的失败;
|
|
814
|
+
- 环境、权限或基础设施失败;
|
|
815
|
+
- 验证本身无效或无法观察目标行为。
|
|
816
|
+
|
|
817
|
+
不得通过跳过测试、放宽断言、吞错、删除用例或把命令移出验证矩阵来制造绿色。
|
|
818
|
+
|
|
819
|
+
## 4. Evidence 最低内容
|
|
820
|
+
|
|
821
|
+
每个完成 Ticket 在 `specdev/changes/{change}/evidence/T-NN.md` 记录:
|
|
822
|
+
|
|
823
|
+
- 基线、分支或 worktree;
|
|
824
|
+
- 实际修改的项目路径;
|
|
825
|
+
- 每条命令、退出状态和结果摘要;
|
|
826
|
+
- 每条验收合同的证据映射;
|
|
827
|
+
- 未运行项与原因;
|
|
828
|
+
- 新失败、既有失败和环境失败;
|
|
829
|
+
- 偏差及批准;
|
|
830
|
+
- 残余风险;
|
|
831
|
+
- worktree、提交或 PR 引用;
|
|
832
|
+
- 最终结论。
|
|
833
|
+
|
|
834
|
+
无法运行关键验证、存在未批准偏差或 Evidence 不完整时,Ticket 不得标为 `done`。
|
|
835
|
+
|
|
836
|
+
</evidence-and-verification>
|
|
837
|
+
|
|
838
|
+
<deviation-control>
|
|
839
|
+
|
|
840
|
+
# 偏差控制
|
|
841
|
+
|
|
842
|
+
偏差是“当前事实或实现需要偏离已批准工件”的显式事件。偏差不是普通进度说明,也不能作为先改后补文档的许可证。
|
|
843
|
+
|
|
844
|
+
## 1. 偏差等级
|
|
845
|
+
|
|
846
|
+
- **local**:只改变局部实现,不改变 Ticket 的行为、范围、公共契约、路径所有权或验证;记录到 Evidence 后可继续。
|
|
847
|
+
- **ticket**:改变 Ticket 的执行路线、可写范围、局部契约或验收映射,但不改变 Spec;必须停止相关修改、更新 Ticket 并获得 owner 或 Lead 批准。
|
|
848
|
+
- **spec**:改变外部行为、范围、用户故事、验收合同或非功能要求;必须返回 “编写 Spec 阶段”。
|
|
849
|
+
- **architecture**:改变已接受架构决策或公共架构约束;必须返回 “设计访谈能力” 并更新 `specdev/changes/{change}/ADR.md`。
|
|
850
|
+
- **release**:改变迁移、兼容窗口、发布门禁、回滚或不可逆批准点;必须停止并获得明确人工批准。
|
|
851
|
+
|
|
852
|
+
## 2. 触发条件
|
|
853
|
+
|
|
854
|
+
以下任一情况必须建立偏差:
|
|
855
|
+
|
|
856
|
+
- 当前代码事实使批准路线不可行;
|
|
857
|
+
- 需要修改 Ticket 未授权的项目路径;
|
|
858
|
+
- 需要修改 shared path,但当前实现者不是 owner;
|
|
859
|
+
- 验证接缝无法证明验收合同;
|
|
860
|
+
- 发现新的安全、数据、兼容、性能或迁移风险;
|
|
861
|
+
- 依赖、合同或外部参考权威已变化;
|
|
862
|
+
- 实际行为将与 Spec 或 ADR 不一致。
|
|
863
|
+
|
|
864
|
+
## 3. 偏差记录
|
|
865
|
+
|
|
866
|
+
偏差记录写入对应 Evidence:`specdev/changes/{change}/evidence/T-NN.md`,并至少包含:
|
|
867
|
+
|
|
868
|
+
- 偏差 ID 与等级;
|
|
869
|
+
- 触发事实和证据;
|
|
870
|
+
- 受影响工件与路径;
|
|
871
|
+
- 继续、回退、修订或拆分的选项;
|
|
872
|
+
- 推荐方案和风险;
|
|
873
|
+
- 批准人、批准时间和批准范围;
|
|
874
|
+
- 最终处理结果。
|
|
875
|
+
|
|
876
|
+
需要改变上层工件时,Evidence 只记录事件;真正的权威变更必须写回对应 Spec、Ticket、ADR 或 Goal Plan。
|
|
877
|
+
|
|
878
|
+
## 4. 停止规则
|
|
879
|
+
|
|
880
|
+
- 未批准的 ticket、spec、architecture 或 release 偏差不得继续实现。
|
|
881
|
+
- 不得通过扩大 `writable_paths`、删除测试、降低断言或把风险改写成“已知限制”来绕过停止。
|
|
882
|
+
- 偏差影响并发 Agent 时,Lead 必须暂停受影响 Wave,重新计算路径所有权、依赖和 Gate。
|
|
883
|
+
|
|
884
|
+
</deviation-control>
|
|
885
|
+
|
|
886
|
+
<research>
|
|
887
|
+
|
|
888
|
+
# SpecDev Research
|
|
889
|
+
|
|
890
|
+
## 触发
|
|
891
|
+
|
|
892
|
+
当外部 API、库版本、协议、法规、产品能力或最佳实践会改变设计/实现决策,且当前材料不足时使用。
|
|
893
|
+
|
|
894
|
+
## 流程
|
|
895
|
+
|
|
896
|
+
1. 写清楚要支持的具体决策和停止条件。
|
|
897
|
+
2. 优先官方文档、规范、源代码、论文或维护者材料;技术问题优先一手来源。
|
|
898
|
+
3. 核对版本、发布日期、适用环境和已知限制。
|
|
899
|
+
4. 区分:来源明确事实、代码库事实、推断、建议。
|
|
900
|
+
5. 对关键结论至少交叉验证;来源冲突时并列呈现,不强行调和。
|
|
901
|
+
6. 记录摘要、证据、置信度、对 ADR/Spec/Ticket 的影响和仍未知项。
|
|
902
|
+
7. 长期有效且经实现验证后才可由 Archive 提升到永久 research。
|
|
903
|
+
|
|
904
|
+
## 输出模板
|
|
905
|
+
|
|
906
|
+
```markdown
|
|
907
|
+
# Research: <问题>
|
|
908
|
+
- 决策用途:
|
|
909
|
+
- 范围/版本:
|
|
910
|
+
- 停止条件:
|
|
911
|
+
|
|
912
|
+
## Findings
|
|
913
|
+
### R-001
|
|
914
|
+
- 结论:
|
|
915
|
+
- 类型:官方事实 / 代码事实 / 推断 / 建议
|
|
916
|
+
- 来源:
|
|
917
|
+
- 置信度:high / medium / low
|
|
918
|
+
- 适用限制:
|
|
919
|
+
- 对工件影响:
|
|
920
|
+
|
|
921
|
+
## Conflicts and Unknowns
|
|
922
|
+
## Recommendation
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
不得长篇复制受版权保护的来源;使用短引文和自己的准确摘要。
|
|
926
|
+
|
|
927
|
+
</research>
|
|
928
|
+
|
|
929
|
+
<dev-worktree>
|
|
930
|
+
|
|
931
|
+
# SpecDev Dev Worktree
|
|
932
|
+
|
|
933
|
+
## 适用范围
|
|
934
|
+
|
|
935
|
+
- 仅用于并行写代码且路径所有权不冲突的 Ready Ticket。
|
|
936
|
+
- 只读调查和顺序执行默认共用当前工作区。
|
|
937
|
+
- Lead 管理创建、集成和清理;Worker 只实现、验证并返回 Evidence。
|
|
938
|
+
- 平台原生 worktree 优先;不可用时使用 Git worktree。
|
|
939
|
+
|
|
940
|
+
## 生命周期
|
|
941
|
+
|
|
942
|
+
1. 创建或恢复时加载 下方 `<dev-worktree-create>` 标签。
|
|
943
|
+
2. Worker 完成后将记录从 `active` 更新为 `review`,返回 Ticket 状态、Evidence 路径、`workspace_ref`、commit 或 PR 引用,以及条件性 Lead E2E。
|
|
944
|
+
3. Lead 集成或清理时加载 下方 `<dev-worktree-finalize>` 标签。
|
|
945
|
+
|
|
946
|
+
状态依次为 `planned → active → review → integrated → removed`;失败进入 `blocked`。记录写入 `specdev/changes/{change}/.status.json` 的 `worktrees`。
|
|
947
|
+
|
|
948
|
+
## 边界
|
|
949
|
+
|
|
950
|
+
- 每个并行 Ticket 使用独立 worktree、分支和相同 `base_sha`。
|
|
951
|
+
- 持久状态只保存 `workspace_ref`,不保存机器绝对路径。
|
|
952
|
+
- E2E 仅由 Lead 在集成阶段执行,且仅适用于用户界面交互受影响的变更。
|
|
953
|
+
- 合并、推送、PR、删除分支或 worktree 仍需用户授权。
|
|
954
|
+
|
|
955
|
+
</dev-worktree>
|
|
956
|
+
|
|
957
|
+
<dev-worktree-create>
|
|
958
|
+
|
|
959
|
+
# 创建或恢复 Ticket Worktree
|
|
960
|
+
|
|
961
|
+
## 前置
|
|
962
|
+
|
|
963
|
+
- Ticket `ready: true`,依赖完成,写路径无冲突。
|
|
964
|
+
- `specdev/config.json` 中 `git.worktree_for_parallel: true`。
|
|
965
|
+
- Lead 已固定所有并行 Ticket 共用的 `base_sha`。
|
|
966
|
+
|
|
967
|
+
## 创建
|
|
968
|
+
|
|
969
|
+
1. 若 `specdev/changes/{change}/.status.json` 的 `worktrees` 已有该 Ticket 的 `active` 或 `review` 记录,解析 `workspace_ref` 并验证分支、`base_sha` 和工作区状态;一致则恢复。
|
|
970
|
+
2. 否则优先调用平台原生 worktree 能力;不可用时从 `base_sha` 执行 `git worktree add -b <ticket-branch> <physical-path> <base-sha>`。物理路径必须位于主工作树之外。
|
|
971
|
+
3. 分支使用 `speculo/<change>/<ticket-id>`;现有分支或目标路径未能匹配记录时停止。
|
|
972
|
+
4. 安装项目所需依赖,运行最小基线检查。E2E 不属于 Worker 基线。
|
|
973
|
+
5. 写入 `worktrees`:
|
|
974
|
+
|
|
975
|
+
```json
|
|
976
|
+
{
|
|
977
|
+
"ticket_id": "T-01",
|
|
978
|
+
"owner": "<worker>",
|
|
979
|
+
"provider": "native",
|
|
980
|
+
"base_sha": "<sha>",
|
|
981
|
+
"branch": "speculo/<change>/T-01",
|
|
982
|
+
"workspace_ref": "<provider-opaque-or-project-relative-ref>",
|
|
983
|
+
"status": "active",
|
|
984
|
+
"updated_at": "<ISO-8601>"
|
|
985
|
+
}
|
|
986
|
+
```
|
|
987
|
+
|
|
988
|
+
完成条件:工作区可定位、基线可用、状态记录与实际分支一致。失败时设为 `blocked` 并保留现场。
|
|
989
|
+
|
|
990
|
+
</dev-worktree-create>
|
|
991
|
+
|
|
992
|
+
<dev-worktree-finalize>
|
|
993
|
+
|
|
994
|
+
# 集成与清理 Ticket Worktree
|
|
995
|
+
|
|
996
|
+
## Lead 集成
|
|
997
|
+
|
|
998
|
+
1. 确认记录为 `review`,读取 Worker Evidence,实际修改未越过路径契约。
|
|
999
|
+
2. 在目标集成基线上应用变更并运行受影响的定向与回归验证。
|
|
1000
|
+
3. 仅当变更影响用户界面交互时,由 Lead 运行验收所需的最小 E2E;Worker 只提供场景和预期结果。
|
|
1001
|
+
4. 验证通过后将记录更新为 `integrated`;冲突或失败时设为 `blocked` 并保留 worktree。
|
|
1002
|
+
|
|
1003
|
+
## 清理
|
|
1004
|
+
|
|
1005
|
+
1. 取得用户对删除 worktree 和分支的授权。
|
|
1006
|
+
2. 从主工作树或平台管理入口移除已集成 worktree。
|
|
1007
|
+
3. 确认 worktree 不再注册后删除对应分支,并将状态更新为 `removed`。
|
|
1008
|
+
|
|
1009
|
+
PR 或暂缓集成时保留 worktree。清理失败时停止;仅在用户明确要求时使用强制删除。
|
|
1010
|
+
|
|
1011
|
+
</dev-worktree-finalize>
|
|
1012
|
+
|
|
1013
|
+
<config-template>
|
|
1014
|
+
|
|
1015
|
+
```json
|
|
1016
|
+
{
|
|
1017
|
+
"schema_version": 3,
|
|
1018
|
+
"interaction_language": "zh-CN",
|
|
1019
|
+
"artifact_language": "zh-CN",
|
|
1020
|
+
"git": {
|
|
1021
|
+
"auto_commit": false,
|
|
1022
|
+
"default_branch": null,
|
|
1023
|
+
"worktree_for_parallel": true
|
|
1024
|
+
},
|
|
1025
|
+
"execution": {
|
|
1026
|
+
"max_parallel": 3,
|
|
1027
|
+
"deep_ticket_human_approval": true,
|
|
1028
|
+
"shared_path_owner": "lead"
|
|
1029
|
+
},
|
|
1030
|
+
"verification": {
|
|
1031
|
+
"test": null,
|
|
1032
|
+
"typecheck": null,
|
|
1033
|
+
"lint": null,
|
|
1034
|
+
"build": null
|
|
1035
|
+
},
|
|
1036
|
+
"planning": {
|
|
1037
|
+
"default_depth": "standard",
|
|
1038
|
+
"require_ready_gate": true,
|
|
1039
|
+
"require_evidence": true
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
</config-template>
|
|
1045
|
+
|
|
1046
|
+
<config-schema>
|
|
1047
|
+
|
|
1048
|
+
```json
|
|
1049
|
+
{
|
|
1050
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1051
|
+
"$id": "urn:speculo:specdev:config:v3",
|
|
1052
|
+
"title": "SpecDev Configuration",
|
|
1053
|
+
"type": "object",
|
|
1054
|
+
"required": ["schema_version", "interaction_language", "artifact_language", "git", "execution", "verification", "planning"],
|
|
1055
|
+
"properties": {
|
|
1056
|
+
"schema_version": {"const": 3},
|
|
1057
|
+
"interaction_language": {"type": "string", "minLength": 1},
|
|
1058
|
+
"artifact_language": {"type": "string", "minLength": 1},
|
|
1059
|
+
"git": {
|
|
1060
|
+
"type": "object",
|
|
1061
|
+
"required": ["auto_commit", "default_branch", "worktree_for_parallel"],
|
|
1062
|
+
"properties": {
|
|
1063
|
+
"auto_commit": {"type": "boolean"},
|
|
1064
|
+
"default_branch": {"type": ["string", "null"]},
|
|
1065
|
+
"worktree_for_parallel": {"type": "boolean"}
|
|
1066
|
+
},
|
|
1067
|
+
"additionalProperties": true
|
|
1068
|
+
},
|
|
1069
|
+
"execution": {
|
|
1070
|
+
"type": "object",
|
|
1071
|
+
"required": ["max_parallel", "deep_ticket_human_approval", "shared_path_owner"],
|
|
1072
|
+
"properties": {
|
|
1073
|
+
"max_parallel": {"type": "integer", "minimum": 1},
|
|
1074
|
+
"deep_ticket_human_approval": {"type": "boolean"},
|
|
1075
|
+
"shared_path_owner": {"type": "string", "minLength": 1}
|
|
1076
|
+
},
|
|
1077
|
+
"additionalProperties": true
|
|
1078
|
+
},
|
|
1079
|
+
"verification": {
|
|
1080
|
+
"type": "object",
|
|
1081
|
+
"required": ["test", "typecheck", "lint", "build"],
|
|
1082
|
+
"properties": {
|
|
1083
|
+
"test": {"type": ["string", "null"]},
|
|
1084
|
+
"typecheck": {"type": ["string", "null"]},
|
|
1085
|
+
"lint": {"type": ["string", "null"]},
|
|
1086
|
+
"build": {"type": ["string", "null"]}
|
|
1087
|
+
},
|
|
1088
|
+
"additionalProperties": true
|
|
1089
|
+
},
|
|
1090
|
+
"planning": {
|
|
1091
|
+
"type": "object",
|
|
1092
|
+
"required": ["default_depth", "require_ready_gate", "require_evidence"],
|
|
1093
|
+
"properties": {
|
|
1094
|
+
"default_depth": {"enum": ["lite", "standard", "deep"]},
|
|
1095
|
+
"require_ready_gate": {"type": "boolean"},
|
|
1096
|
+
"require_evidence": {"type": "boolean"}
|
|
1097
|
+
},
|
|
1098
|
+
"additionalProperties": true
|
|
1099
|
+
}
|
|
1100
|
+
},
|
|
1101
|
+
"additionalProperties": true
|
|
1102
|
+
}
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1105
|
+
</config-schema>
|
|
1106
|
+
|
|
1107
|
+
<status-template>
|
|
1108
|
+
|
|
1109
|
+
```json
|
|
1110
|
+
{
|
|
1111
|
+
"schema_version": 3,
|
|
1112
|
+
"workflow": "specdev",
|
|
1113
|
+
"active": [],
|
|
1114
|
+
"work_history": [],
|
|
1115
|
+
"completed": []
|
|
1116
|
+
}
|
|
1117
|
+
```
|
|
1118
|
+
|
|
1119
|
+
</status-template>
|
|
1120
|
+
|
|
1121
|
+
<status-schema>
|
|
1122
|
+
|
|
1123
|
+
```json
|
|
1124
|
+
{
|
|
1125
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1126
|
+
"$id": "urn:speculo:specdev:status:v3",
|
|
1127
|
+
"title": "SpecDev Global Status",
|
|
1128
|
+
"type": "object",
|
|
1129
|
+
"required": [
|
|
1130
|
+
"schema_version",
|
|
1131
|
+
"workflow",
|
|
1132
|
+
"active",
|
|
1133
|
+
"work_history",
|
|
1134
|
+
"completed"
|
|
1135
|
+
],
|
|
1136
|
+
"properties": {
|
|
1137
|
+
"schema_version": {
|
|
1138
|
+
"const": 3
|
|
1139
|
+
},
|
|
1140
|
+
"workflow": {
|
|
1141
|
+
"const": "specdev"
|
|
1142
|
+
},
|
|
1143
|
+
"active": {
|
|
1144
|
+
"type": "array",
|
|
1145
|
+
"items": {
|
|
1146
|
+
"type": "object",
|
|
1147
|
+
"required": [
|
|
1148
|
+
"change",
|
|
1149
|
+
"current_work",
|
|
1150
|
+
"works_run",
|
|
1151
|
+
"result"
|
|
1152
|
+
],
|
|
1153
|
+
"properties": {
|
|
1154
|
+
"change": {
|
|
1155
|
+
"type": "string"
|
|
1156
|
+
},
|
|
1157
|
+
"current_work": {
|
|
1158
|
+
"type": [
|
|
1159
|
+
"string",
|
|
1160
|
+
"null"
|
|
1161
|
+
]
|
|
1162
|
+
},
|
|
1163
|
+
"works_run": {
|
|
1164
|
+
"type": "array",
|
|
1165
|
+
"items": {
|
|
1166
|
+
"type": "string"
|
|
1167
|
+
}
|
|
1168
|
+
},
|
|
1169
|
+
"result": {
|
|
1170
|
+
"type": [
|
|
1171
|
+
"string",
|
|
1172
|
+
"null"
|
|
1173
|
+
]
|
|
1174
|
+
},
|
|
1175
|
+
"claimed_investigations": {
|
|
1176
|
+
"type": "array",
|
|
1177
|
+
"items": {
|
|
1178
|
+
"type": "object",
|
|
1179
|
+
"required": [
|
|
1180
|
+
"id",
|
|
1181
|
+
"owner",
|
|
1182
|
+
"claimed_at"
|
|
1183
|
+
],
|
|
1184
|
+
"properties": {
|
|
1185
|
+
"id": {
|
|
1186
|
+
"type": "string"
|
|
1187
|
+
},
|
|
1188
|
+
"owner": {
|
|
1189
|
+
"type": "string"
|
|
1190
|
+
},
|
|
1191
|
+
"session": {
|
|
1192
|
+
"type": [
|
|
1193
|
+
"string",
|
|
1194
|
+
"null"
|
|
1195
|
+
]
|
|
1196
|
+
},
|
|
1197
|
+
"claimed_at": {
|
|
1198
|
+
"type": "string"
|
|
1199
|
+
}
|
|
1200
|
+
},
|
|
1201
|
+
"additionalProperties": true
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
},
|
|
1205
|
+
"additionalProperties": true
|
|
1206
|
+
}
|
|
1207
|
+
},
|
|
1208
|
+
"work_history": {
|
|
1209
|
+
"type": "array",
|
|
1210
|
+
"items": {
|
|
1211
|
+
"type": "object",
|
|
1212
|
+
"required": [
|
|
1213
|
+
"change",
|
|
1214
|
+
"work_id",
|
|
1215
|
+
"started_at",
|
|
1216
|
+
"completed_at",
|
|
1217
|
+
"result"
|
|
1218
|
+
],
|
|
1219
|
+
"properties": {
|
|
1220
|
+
"change": {
|
|
1221
|
+
"type": "string"
|
|
1222
|
+
},
|
|
1223
|
+
"work_id": {
|
|
1224
|
+
"type": "string",
|
|
1225
|
+
"pattern": "^specdev/"
|
|
1226
|
+
},
|
|
1227
|
+
"started_at": {
|
|
1228
|
+
"type": "string"
|
|
1229
|
+
},
|
|
1230
|
+
"completed_at": {
|
|
1231
|
+
"type": [
|
|
1232
|
+
"string",
|
|
1233
|
+
"null"
|
|
1234
|
+
]
|
|
1235
|
+
},
|
|
1236
|
+
"result": {
|
|
1237
|
+
"type": [
|
|
1238
|
+
"string",
|
|
1239
|
+
"null"
|
|
1240
|
+
]
|
|
1241
|
+
}
|
|
1242
|
+
},
|
|
1243
|
+
"additionalProperties": true
|
|
1244
|
+
}
|
|
1245
|
+
},
|
|
1246
|
+
"completed": {
|
|
1247
|
+
"type": "array",
|
|
1248
|
+
"items": {
|
|
1249
|
+
"type": "object",
|
|
1250
|
+
"required": [
|
|
1251
|
+
"change",
|
|
1252
|
+
"archived_at",
|
|
1253
|
+
"archive_path"
|
|
1254
|
+
],
|
|
1255
|
+
"properties": {
|
|
1256
|
+
"change": {
|
|
1257
|
+
"type": "string"
|
|
1258
|
+
},
|
|
1259
|
+
"archived_at": {
|
|
1260
|
+
"type": "string"
|
|
1261
|
+
},
|
|
1262
|
+
"archive_path": {
|
|
1263
|
+
"type": "string",
|
|
1264
|
+
"pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"
|
|
1265
|
+
}
|
|
1266
|
+
},
|
|
1267
|
+
"additionalProperties": true
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
},
|
|
1271
|
+
"additionalProperties": true
|
|
1272
|
+
}
|
|
1273
|
+
```
|
|
1274
|
+
|
|
1275
|
+
</status-schema>
|
|
1276
|
+
|
|
1277
|
+
<change-status-template>
|
|
1278
|
+
|
|
1279
|
+
```json
|
|
1280
|
+
{
|
|
1281
|
+
"schema_version": 3,
|
|
1282
|
+
"artifact": "change-status",
|
|
1283
|
+
"change": "<YYYY-MM-DD-topic>",
|
|
1284
|
+
"change_status": "active",
|
|
1285
|
+
"current_work": null,
|
|
1286
|
+
"created_at": "<ISO-8601>",
|
|
1287
|
+
"updated_at": "<ISO-8601>",
|
|
1288
|
+
"completed_at": null,
|
|
1289
|
+
"archived": false,
|
|
1290
|
+
"archive_path": null,
|
|
1291
|
+
"blockers": [],
|
|
1292
|
+
"deviations": [],
|
|
1293
|
+
"worktrees": []
|
|
1294
|
+
}
|
|
1295
|
+
```
|
|
1296
|
+
|
|
1297
|
+
</change-status-template>
|
|
1298
|
+
|
|
1299
|
+
<change-status-schema>
|
|
1300
|
+
|
|
1301
|
+
```json
|
|
1302
|
+
{
|
|
1303
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1304
|
+
"$id": "urn:speculo:specdev:change-status:v3",
|
|
1305
|
+
"title": "SpecDev Change Status",
|
|
1306
|
+
"type": "object",
|
|
1307
|
+
"required": [
|
|
1308
|
+
"schema_version",
|
|
1309
|
+
"artifact",
|
|
1310
|
+
"change",
|
|
1311
|
+
"change_status",
|
|
1312
|
+
"current_work",
|
|
1313
|
+
"created_at",
|
|
1314
|
+
"updated_at",
|
|
1315
|
+
"completed_at",
|
|
1316
|
+
"archived",
|
|
1317
|
+
"archive_path",
|
|
1318
|
+
"blockers",
|
|
1319
|
+
"deviations"
|
|
1320
|
+
],
|
|
1321
|
+
"properties": {
|
|
1322
|
+
"schema_version": {
|
|
1323
|
+
"const": 3
|
|
1324
|
+
},
|
|
1325
|
+
"artifact": {
|
|
1326
|
+
"const": "change-status"
|
|
1327
|
+
},
|
|
1328
|
+
"change": {
|
|
1329
|
+
"type": "string",
|
|
1330
|
+
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*$"
|
|
1331
|
+
},
|
|
1332
|
+
"change_status": {
|
|
1333
|
+
"enum": [
|
|
1334
|
+
"active",
|
|
1335
|
+
"blocked",
|
|
1336
|
+
"completed",
|
|
1337
|
+
"archived"
|
|
1338
|
+
]
|
|
1339
|
+
},
|
|
1340
|
+
"current_work": {
|
|
1341
|
+
"type": [
|
|
1342
|
+
"string",
|
|
1343
|
+
"null"
|
|
1344
|
+
]
|
|
1345
|
+
},
|
|
1346
|
+
"created_at": {
|
|
1347
|
+
"type": "string",
|
|
1348
|
+
"minLength": 1
|
|
1349
|
+
},
|
|
1350
|
+
"updated_at": {
|
|
1351
|
+
"type": "string",
|
|
1352
|
+
"minLength": 1
|
|
1353
|
+
},
|
|
1354
|
+
"completed_at": {
|
|
1355
|
+
"type": [
|
|
1356
|
+
"string",
|
|
1357
|
+
"null"
|
|
1358
|
+
]
|
|
1359
|
+
},
|
|
1360
|
+
"archived": {
|
|
1361
|
+
"type": "boolean"
|
|
1362
|
+
},
|
|
1363
|
+
"archive_path": {
|
|
1364
|
+
"anyOf": [
|
|
1365
|
+
{
|
|
1366
|
+
"type": "null"
|
|
1367
|
+
},
|
|
1368
|
+
{
|
|
1369
|
+
"type": "string",
|
|
1370
|
+
"pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"
|
|
1371
|
+
}
|
|
1372
|
+
]
|
|
1373
|
+
},
|
|
1374
|
+
"blockers": {
|
|
1375
|
+
"type": "array",
|
|
1376
|
+
"items": {
|
|
1377
|
+
"type": "string"
|
|
1378
|
+
}
|
|
1379
|
+
},
|
|
1380
|
+
"deviations": {
|
|
1381
|
+
"type": "array",
|
|
1382
|
+
"items": {
|
|
1383
|
+
"type": "string"
|
|
1384
|
+
}
|
|
1385
|
+
},
|
|
1386
|
+
"worktrees": {
|
|
1387
|
+
"type": "array",
|
|
1388
|
+
"items": {
|
|
1389
|
+
"type": "object",
|
|
1390
|
+
"required": [
|
|
1391
|
+
"ticket_id",
|
|
1392
|
+
"owner",
|
|
1393
|
+
"provider",
|
|
1394
|
+
"base_sha",
|
|
1395
|
+
"branch",
|
|
1396
|
+
"workspace_ref",
|
|
1397
|
+
"status",
|
|
1398
|
+
"updated_at"
|
|
1399
|
+
],
|
|
1400
|
+
"properties": {
|
|
1401
|
+
"ticket_id": {
|
|
1402
|
+
"type": "string",
|
|
1403
|
+
"pattern": "^T-[0-9]{2,}$"
|
|
1404
|
+
},
|
|
1405
|
+
"owner": {
|
|
1406
|
+
"type": "string",
|
|
1407
|
+
"minLength": 1
|
|
1408
|
+
},
|
|
1409
|
+
"provider": {
|
|
1410
|
+
"enum": [
|
|
1411
|
+
"native",
|
|
1412
|
+
"git",
|
|
1413
|
+
"external"
|
|
1414
|
+
]
|
|
1415
|
+
},
|
|
1416
|
+
"base_sha": {
|
|
1417
|
+
"type": "string",
|
|
1418
|
+
"minLength": 1
|
|
1419
|
+
},
|
|
1420
|
+
"branch": {
|
|
1421
|
+
"type": "string",
|
|
1422
|
+
"minLength": 1
|
|
1423
|
+
},
|
|
1424
|
+
"workspace_ref": {
|
|
1425
|
+
"type": "string",
|
|
1426
|
+
"minLength": 1,
|
|
1427
|
+
"pattern": "^(?!/)(?![A-Za-z]:[\\\\/]).+"
|
|
1428
|
+
},
|
|
1429
|
+
"status": {
|
|
1430
|
+
"enum": [
|
|
1431
|
+
"planned",
|
|
1432
|
+
"active",
|
|
1433
|
+
"review",
|
|
1434
|
+
"integrated",
|
|
1435
|
+
"removed",
|
|
1436
|
+
"blocked"
|
|
1437
|
+
]
|
|
1438
|
+
},
|
|
1439
|
+
"updated_at": {
|
|
1440
|
+
"type": "string",
|
|
1441
|
+
"minLength": 1
|
|
1442
|
+
}
|
|
1443
|
+
},
|
|
1444
|
+
"additionalProperties": true
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
},
|
|
1448
|
+
"allOf": [
|
|
1449
|
+
{
|
|
1450
|
+
"if": {
|
|
1451
|
+
"properties": {
|
|
1452
|
+
"change_status": {
|
|
1453
|
+
"const": "archived"
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
},
|
|
1457
|
+
"then": {
|
|
1458
|
+
"properties": {
|
|
1459
|
+
"archived": {
|
|
1460
|
+
"const": true
|
|
1461
|
+
},
|
|
1462
|
+
"archive_path": {
|
|
1463
|
+
"type": "string",
|
|
1464
|
+
"pattern": "^specdev/archive/[0-9]{4}-[0-9]{2}/.+/$"
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
],
|
|
1470
|
+
"additionalProperties": true
|
|
1471
|
+
}
|
|
1472
|
+
```
|
|
1473
|
+
|
|
1474
|
+
</change-status-schema>
|
|
1475
|
+
|
|
1476
|
+
<ticket-schema>
|
|
1477
|
+
|
|
1478
|
+
```json
|
|
1479
|
+
{
|
|
1480
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1481
|
+
"$id": "urn:speculo:specdev:ticket:v3",
|
|
1482
|
+
"title": "SpecDev Ticket Frontmatter",
|
|
1483
|
+
"type": "object",
|
|
1484
|
+
"required": [
|
|
1485
|
+
"schema_version",
|
|
1486
|
+
"artifact",
|
|
1487
|
+
"change",
|
|
1488
|
+
"id",
|
|
1489
|
+
"title",
|
|
1490
|
+
"status",
|
|
1491
|
+
"planning_depth",
|
|
1492
|
+
"planning_depth_reason",
|
|
1493
|
+
"ready",
|
|
1494
|
+
"risk",
|
|
1495
|
+
"blocked_by",
|
|
1496
|
+
"contract_ids",
|
|
1497
|
+
"owner",
|
|
1498
|
+
"expected_changes",
|
|
1499
|
+
"writable_paths",
|
|
1500
|
+
"read_only_paths",
|
|
1501
|
+
"shared_paths",
|
|
1502
|
+
"shared_path_owners"
|
|
1503
|
+
],
|
|
1504
|
+
"properties": {
|
|
1505
|
+
"schema_version": {
|
|
1506
|
+
"const": 3
|
|
1507
|
+
},
|
|
1508
|
+
"artifact": {
|
|
1509
|
+
"const": "ticket"
|
|
1510
|
+
},
|
|
1511
|
+
"change": {
|
|
1512
|
+
"type": "string",
|
|
1513
|
+
"minLength": 1
|
|
1514
|
+
},
|
|
1515
|
+
"id": {
|
|
1516
|
+
"type": "string",
|
|
1517
|
+
"pattern": "^T-[0-9]{2,}$"
|
|
1518
|
+
},
|
|
1519
|
+
"title": {
|
|
1520
|
+
"type": "string",
|
|
1521
|
+
"minLength": 1
|
|
1522
|
+
},
|
|
1523
|
+
"status": {
|
|
1524
|
+
"enum": [
|
|
1525
|
+
"draft",
|
|
1526
|
+
"ready",
|
|
1527
|
+
"in_progress",
|
|
1528
|
+
"blocked",
|
|
1529
|
+
"review",
|
|
1530
|
+
"done",
|
|
1531
|
+
"deviated",
|
|
1532
|
+
"cancelled"
|
|
1533
|
+
]
|
|
1534
|
+
},
|
|
1535
|
+
"planning_depth": {
|
|
1536
|
+
"enum": [
|
|
1537
|
+
"lite",
|
|
1538
|
+
"standard",
|
|
1539
|
+
"deep"
|
|
1540
|
+
]
|
|
1541
|
+
},
|
|
1542
|
+
"planning_depth_reason": {
|
|
1543
|
+
"type": "string",
|
|
1544
|
+
"minLength": 1
|
|
1545
|
+
},
|
|
1546
|
+
"ready": {
|
|
1547
|
+
"type": "boolean"
|
|
1548
|
+
},
|
|
1549
|
+
"risk": {
|
|
1550
|
+
"enum": [
|
|
1551
|
+
"low",
|
|
1552
|
+
"medium",
|
|
1553
|
+
"high",
|
|
1554
|
+
"critical"
|
|
1555
|
+
]
|
|
1556
|
+
},
|
|
1557
|
+
"blocked_by": {
|
|
1558
|
+
"type": "array",
|
|
1559
|
+
"items": {
|
|
1560
|
+
"type": "string",
|
|
1561
|
+
"pattern": "^T-[0-9]{2,}$"
|
|
1562
|
+
},
|
|
1563
|
+
"uniqueItems": true
|
|
1564
|
+
},
|
|
1565
|
+
"contract_ids": {
|
|
1566
|
+
"type": "array",
|
|
1567
|
+
"items": {
|
|
1568
|
+
"type": "string"
|
|
1569
|
+
},
|
|
1570
|
+
"uniqueItems": true
|
|
1571
|
+
},
|
|
1572
|
+
"owner": {
|
|
1573
|
+
"type": "string",
|
|
1574
|
+
"minLength": 1
|
|
1575
|
+
},
|
|
1576
|
+
"expected_changes": {
|
|
1577
|
+
"$ref": "#/$defs/pathArray"
|
|
1578
|
+
},
|
|
1579
|
+
"writable_paths": {
|
|
1580
|
+
"$ref": "#/$defs/pathArray"
|
|
1581
|
+
},
|
|
1582
|
+
"read_only_paths": {
|
|
1583
|
+
"$ref": "#/$defs/pathArray"
|
|
1584
|
+
},
|
|
1585
|
+
"shared_paths": {
|
|
1586
|
+
"$ref": "#/$defs/pathArray"
|
|
1587
|
+
},
|
|
1588
|
+
"shared_path_owners": {
|
|
1589
|
+
"type": "array",
|
|
1590
|
+
"items": {
|
|
1591
|
+
"type": "string",
|
|
1592
|
+
"pattern": "^(?!/)(?![A-Za-z]:).+\\s*=>\\s*[^=].+$"
|
|
1593
|
+
},
|
|
1594
|
+
"uniqueItems": true
|
|
1595
|
+
}
|
|
1596
|
+
},
|
|
1597
|
+
"$defs": {
|
|
1598
|
+
"pathArray": {
|
|
1599
|
+
"type": "array",
|
|
1600
|
+
"items": {
|
|
1601
|
+
"type": "string",
|
|
1602
|
+
"pattern": "^(?!/)(?![A-Za-z]:).+$"
|
|
1603
|
+
},
|
|
1604
|
+
"uniqueItems": true
|
|
1605
|
+
}
|
|
1606
|
+
},
|
|
1607
|
+
"additionalProperties": true
|
|
1608
|
+
}
|
|
1609
|
+
```
|
|
1610
|
+
|
|
1611
|
+
</ticket-schema>
|
|
1612
|
+
|
|
1613
|
+
<tickets-map-schema>
|
|
1614
|
+
|
|
1615
|
+
```json
|
|
1616
|
+
{
|
|
1617
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1618
|
+
"$id": "urn:speculo:specdev:tickets-map:v3",
|
|
1619
|
+
"title": "SpecDev Tickets Map Frontmatter",
|
|
1620
|
+
"type": "object",
|
|
1621
|
+
"required": ["schema_version", "artifact", "change", "status"],
|
|
1622
|
+
"properties": {
|
|
1623
|
+
"schema_version": {"const": 3},
|
|
1624
|
+
"artifact": {"const": "tickets-map"},
|
|
1625
|
+
"change": {"type": "string", "minLength": 1},
|
|
1626
|
+
"status": {"enum": ["draft", "ready", "in_progress", "completed", "blocked"]}
|
|
1627
|
+
},
|
|
1628
|
+
"additionalProperties": true
|
|
1629
|
+
}
|
|
1630
|
+
```
|
|
1631
|
+
|
|
1632
|
+
</tickets-map-schema>
|