@namewta/speculo 0.1.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/LICENSE +21 -0
- package/README.md +89 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +58 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.js +60 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/utils.d.ts +1 -0
- package/dist/src/utils.js +11 -0
- package/dist/src/utils.js.map +1 -0
- package/package.json +54 -0
- package/speculo/.speculo/.config/LESSONS.md +9 -0
- package/speculo/.speculo/.config/RULES.md +9 -0
- package/speculo/.speculo/.config/adr/.gitkeep +1 -0
- package/speculo/.speculo/.config/context/.gitkeep +1 -0
- package/speculo/.speculo/archive/dev/.gitkeep +0 -0
- package/speculo/.speculo/archive/doc/.gitkeep +1 -0
- package/speculo/.speculo/commands/.gitkeep +0 -0
- package/speculo/.speculo/dev/.gitkeep +0 -0
- package/speculo/.speculo/dev/docs-sync-state.json +14 -0
- package/speculo/.speculo/dev-status.json +3 -0
- package/speculo/.speculo/doc/.gitkeep +1 -0
- package/speculo/.speculo/doc-status.json +3 -0
- package/speculo/commands/archive.md +53 -0
- package/speculo/commands/caveman.md +43 -0
- package/speculo/commands/grill-me.md +42 -0
- package/speculo/commands/handoff.md +42 -0
- package/speculo/commands/scaffold-exercises.md +50 -0
- package/speculo/commands/status.md +51 -0
- package/speculo/commands/write-a-skill.md +46 -0
- package/speculo/skills/caveman/SKILL.md +38 -0
- package/speculo/skills/caveman/references/compression-rules.md +102 -0
- package/speculo/skills/github-npm-ops/SKILL.md +53 -0
- package/speculo/skills/github-npm-ops/references/ci-and-security-ops.md +178 -0
- package/speculo/skills/github-npm-ops/references/failure-recovery.md +132 -0
- package/speculo/skills/github-npm-ops/references/issue-pr-triage.md +219 -0
- package/speculo/skills/github-npm-ops/references/package-json-checklist.md +171 -0
- package/speculo/skills/github-npm-ops/references/preflight-checklist.md +39 -0
- package/speculo/skills/github-npm-ops/references/publish-detection.md +68 -0
- package/speculo/skills/github-npm-ops/references/release-notes-injection.md +236 -0
- package/speculo/skills/github-npm-ops/references/release-pipeline.md +108 -0
- package/speculo/skills/github-npm-ops/references/setup-npm-token.md +63 -0
- package/speculo/skills/github-npm-ops/references/troubleshooting-playbook.md +305 -0
- package/speculo/skills/github-npm-ops/references/version-bump-flow.md +232 -0
- package/speculo/skills/github-npm-ops/references/workflow-yaml-reference.md +268 -0
- package/speculo/skills/grill-me/SKILL.md +40 -0
- package/speculo/skills/handoff/SKILL.md +41 -0
- package/speculo/skills/scaffold-exercises/SKILL.md +41 -0
- package/speculo/skills/scaffold-exercises/references/exercise-structure.md +85 -0
- package/speculo/skills/scaffold-exercises/references/lint-and-git.md +54 -0
- package/speculo/skills/speculo-write/SKILL.md +53 -0
- package/speculo/skills/speculo-write/references/asset-selection-sop.md +65 -0
- package/speculo/skills/speculo-write/references/command-authoring-sop.md +92 -0
- package/speculo/skills/speculo-write/references/migration-sop.md +101 -0
- package/speculo/skills/speculo-write/references/persistence-contract-sop.md +123 -0
- package/speculo/skills/speculo-write/references/skill-authoring-sop.md +195 -0
- package/speculo/skills/speculo-write/references/validation-checklist.md +73 -0
- package/speculo/skills/speculo-write/references/workflow-authoring-sop.md +130 -0
- package/speculo/workflows/dev/00-INDEX.md +56 -0
- package/speculo/workflows/dev/01-grill-with-docs/01-grill-with-docs.md +79 -0
- package/speculo/workflows/dev/01-grill-with-docs/ADR-FORMAT.md +49 -0
- package/speculo/workflows/dev/01-grill-with-docs/CONTEXT-FORMAT.md +65 -0
- package/speculo/workflows/dev/01-grill-with-docs/grill-context-scan.md +30 -0
- package/speculo/workflows/dev/01-grill-with-docs/grill-decision.md +38 -0
- package/speculo/workflows/dev/02-prd/02-prd.md +64 -0
- package/speculo/workflows/dev/02-prd/prd-synthesis.md +30 -0
- package/speculo/workflows/dev/02-prd/prd-zoom-out.md +29 -0
- package/speculo/workflows/dev/03-tdd/03-tdd.md +80 -0
- package/speculo/workflows/dev/03-tdd/deep-modules.md +33 -0
- package/speculo/workflows/dev/03-tdd/interface-design.md +31 -0
- package/speculo/workflows/dev/03-tdd/mocking.md +60 -0
- package/speculo/workflows/dev/03-tdd/refactoring.md +10 -0
- package/speculo/workflows/dev/03-tdd/tdd-finish.md +28 -0
- package/speculo/workflows/dev/03-tdd/tdd-loop.md +33 -0
- package/speculo/workflows/dev/03-tdd/tdd-plan.md +30 -0
- package/speculo/workflows/dev/03-tdd/tests.md +61 -0
- package/speculo/workflows/dev/D-docs-sync/D-docs-sync.md +97 -0
- package/speculo/workflows/dev/D-docs-sync/agents-contract.md +95 -0
- package/speculo/workflows/dev/D-docs-sync/changelog-contract.md +155 -0
- package/speculo/workflows/dev/D-docs-sync/docs-sync-diff.md +50 -0
- package/speculo/workflows/dev/D-docs-sync/docs-sync-finish.md +33 -0
- package/speculo/workflows/dev/D-docs-sync/docs-sync-state.md +32 -0
- package/speculo/workflows/dev/D-docs-sync/docs-sync-update.md +35 -0
- package/speculo/workflows/dev/D-docs-sync/readme-contract.md +124 -0
- package/speculo/workflows/dev/D-docs-sync/state-json-schema.md +155 -0
- package/speculo/workflows/dev/H-diagnose/H-diagnose.md +80 -0
- package/speculo/workflows/dev/H-diagnose/diagnose-fix.md +34 -0
- package/speculo/workflows/dev/H-diagnose/diagnose-guide.md +114 -0
- package/speculo/workflows/dev/H-diagnose/diagnose-loop.md +32 -0
- package/speculo/workflows/dev/H-diagnose/scripts/hitl-loop.template.sh +41 -0
- package/speculo/workflows/dev/I-to-issues/I-to-issues.md +70 -0
- package/speculo/workflows/dev/I-to-issues/issues-slices.md +31 -0
- package/speculo/workflows/dev/R-review/R-review.md +82 -0
- package/speculo/workflows/dev/R-review/review-setup.md +39 -0
- package/speculo/workflows/dev/R-review/review-two-axis.md +33 -0
- package/speculo/workflows/dev/_templates/diagnosis-template.md +19 -0
- package/speculo/workflows/dev/_templates/docs-sync-report-template.md +28 -0
- package/speculo/workflows/dev/_templates/docs-sync-state-template.json +14 -0
- package/speculo/workflows/dev/_templates/grill-context-map-template.md +19 -0
- package/speculo/workflows/dev/_templates/grill-decision-log-template.md +19 -0
- package/speculo/workflows/dev/_templates/issues-slices-template.md +19 -0
- package/speculo/workflows/dev/_templates/prd-overview-template.md +19 -0
- package/speculo/workflows/dev/_templates/prd-template.md +25 -0
- package/speculo/workflows/dev/_templates/regression-template.md +19 -0
- package/speculo/workflows/dev/_templates/review-report-template.md +16 -0
- package/speculo/workflows/dev/_templates/review-sources-template.md +24 -0
- package/speculo/workflows/dev/_templates/tdd-log-template.md +16 -0
- package/speculo/workflows/dev/_templates/tdd-plan-template.md +19 -0
- package/speculo/workflows/dev/_templates/tdd-verification-template.md +16 -0
- package/speculo/workflows/doc/00-INDEX.md +51 -0
- package/speculo/workflows/doc/B-writing-beats/B-writing-beats.md +77 -0
- package/speculo/workflows/doc/B-writing-beats/writing-beats-append.md +31 -0
- package/speculo/workflows/doc/B-writing-beats/writing-beats-options.md +29 -0
- package/speculo/workflows/doc/E-edit-article/E-edit-article.md +77 -0
- package/speculo/workflows/doc/E-edit-article/edit-article-plan.md +30 -0
- package/speculo/workflows/doc/E-edit-article/edit-article-rewrite.md +31 -0
- package/speculo/workflows/doc/F-writing-fragments/F-writing-fragments.md +78 -0
- package/speculo/workflows/doc/F-writing-fragments/writing-fragments-interview.md +32 -0
- package/speculo/workflows/doc/F-writing-fragments/writing-fragments-log.md +29 -0
- package/speculo/workflows/doc/S-writing-shape/S-writing-shape.md +79 -0
- package/speculo/workflows/doc/S-writing-shape/writing-shape-block.md +32 -0
- package/speculo/workflows/doc/S-writing-shape/writing-shape-opening.md +27 -0
- package/speculo/workflows/doc/_templates/edit-article-plan-template.md +24 -0
- package/speculo/workflows/doc/_templates/edit-article-template.md +6 -0
- package/speculo/workflows/doc/_templates/writing-article-template.md +6 -0
- package/speculo/workflows/doc/_templates/writing-beat-options-template.md +20 -0
- package/speculo/workflows/doc/_templates/writing-fragments-template.md +6 -0
- package/speculo/workflows/doc/_templates/writing-interview-log-template.md +20 -0
- package/speculo/workflows/doc/_templates/writing-shape-log-template.md +24 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Diff Collect Phase
|
|
2
|
+
|
|
3
|
+
## 输入
|
|
4
|
+
|
|
5
|
+
- `.speculo/dev/docs-sync-state.json`
|
|
6
|
+
- `LAST_SYNC_SHA`
|
|
7
|
+
- 当前 `HEAD`
|
|
8
|
+
|
|
9
|
+
## 产物
|
|
10
|
+
|
|
11
|
+
- `.speculo/dev/<change>/docs-sync-report.md`,由 `../_templates/docs-sync-report-template.md` 填写或追加
|
|
12
|
+
|
|
13
|
+
## 填写引导
|
|
14
|
+
|
|
15
|
+
固定收集以下信息:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
RANGE="$LAST_SYNC_SHA..HEAD"
|
|
19
|
+
git log --oneline --no-merges "$RANGE"
|
|
20
|
+
git diff --name-status "$RANGE"
|
|
21
|
+
git diff --shortstat "$RANGE"
|
|
22
|
+
git diff --name-only "$RANGE" | awk -F/ '{print $1"/"$2}' | sort | uniq -c | sort -rn
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
有疑问的具体改动再读取:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git log -p "$RANGE" -- <specific-path>
|
|
29
|
+
git show <sha> -- <specific-file>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
把变更按对外可见性映射到 `tracked_docs`:
|
|
33
|
+
|
|
34
|
+
- 对外能力变化:README 类 + CHANGELOG
|
|
35
|
+
- 内部重构但行为未变:视情况写 CHANGELOG 或 AGENTS 类约定
|
|
36
|
+
- 依赖升级:CHANGELOG 聚合;安全 CVE 进 Security
|
|
37
|
+
- CI/CD 变化:CHANGELOG + AGENTS / CONTRIBUTING 的发布约定
|
|
38
|
+
- 文档自身:仅在对外可见时写 CHANGELOG 的文档类条目
|
|
39
|
+
- 测试 / 开发工具链:通常不进 CHANGELOG;AGENTS 的测试要求酌情更新
|
|
40
|
+
- 新增顶层目录 / 顶级文件:如 AGENTS 类存在仓库布局章节则必须同步
|
|
41
|
+
|
|
42
|
+
## 边界
|
|
43
|
+
|
|
44
|
+
- 不把每个 commit 都写成文档条目。
|
|
45
|
+
- 不修改未列入 `tracked_docs` 的文档,除非先获得用户确认并更新 state。
|
|
46
|
+
|
|
47
|
+
## 完成准则
|
|
48
|
+
|
|
49
|
+
- git 差异素材已记录到 report
|
|
50
|
+
- 已列出要更新的文档和理由,或判定空同步
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# State Write Phase
|
|
2
|
+
|
|
3
|
+
## 输入
|
|
4
|
+
|
|
5
|
+
- 更新后的 tracked docs
|
|
6
|
+
- `.speculo/dev/docs-sync-state.json`
|
|
7
|
+
- `.speculo/dev/<change>/docs-sync-report.md`
|
|
8
|
+
- 当前 `HEAD`
|
|
9
|
+
|
|
10
|
+
## 产物
|
|
11
|
+
|
|
12
|
+
- 更新后的 `.speculo/dev/docs-sync-state.json`
|
|
13
|
+
- 完整的 `.speculo/dev/<change>/docs-sync-report.md`
|
|
14
|
+
|
|
15
|
+
## 填写引导
|
|
16
|
+
|
|
17
|
+
1. 运行项目级校验;命令根据项目工具链决定。
|
|
18
|
+
2. 如果所有差异都无需文档修改,仍把 `last_sync_sha` 推进到当前 `HEAD`,并把 `synced_docs` 置为 `[]`。
|
|
19
|
+
3. 如果修改了文档,验证通过后再推进 state。
|
|
20
|
+
4. 写回 state 时按 `state-json-schema.md` 字段顺序,2 空格缩进,尾部换行。
|
|
21
|
+
5. 原子化写入:先写 `.speculo/dev/docs-sync-state.json.tmp`,再 rename。
|
|
22
|
+
6. 按 report 模板向用户报告范围、改动文档、新基线和验证命令。
|
|
23
|
+
|
|
24
|
+
## 边界
|
|
25
|
+
|
|
26
|
+
- 验证失败时不推进 `last_sync_sha`。
|
|
27
|
+
- 不把敏感信息、绝对路径或完整 diff 写入 state。
|
|
28
|
+
|
|
29
|
+
## 完成准则
|
|
30
|
+
|
|
31
|
+
- state 已原子写入或明确记录阻塞原因
|
|
32
|
+
- report 已包含同步范围、改动文档、验证结果
|
|
33
|
+
- `.status.json` 的 `docs_sync_status` 已更新
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# State Read Phase
|
|
2
|
+
|
|
3
|
+
## 输入
|
|
4
|
+
|
|
5
|
+
- `.speculo/dev/docs-sync-state.json`
|
|
6
|
+
- `git rev-parse HEAD`
|
|
7
|
+
- `../_templates/docs-sync-state-template.json`
|
|
8
|
+
|
|
9
|
+
## 产物
|
|
10
|
+
|
|
11
|
+
- `.speculo/dev/docs-sync-state.json`
|
|
12
|
+
- `.speculo/dev/<change>/docs-sync-report.md`
|
|
13
|
+
|
|
14
|
+
## 填写引导
|
|
15
|
+
|
|
16
|
+
1. 设置 `STATE_FILE=".speculo/dev/docs-sync-state.json"`。
|
|
17
|
+
2. 若 state 文件不存在,复制 `../_templates/docs-sync-state-template.json` 为骨架,把 `state_path` 设为 `.speculo/dev/docs-sync-state.json`。
|
|
18
|
+
3. 读取 `last_sync_sha` 和当前 `HEAD`。
|
|
19
|
+
4. 若 `tracked_docs` 为空,列出候选文档,请用户确认后写入 state;本次不修改对外文档。
|
|
20
|
+
5. 若 `last_sync_sha` 为 `null`,把当前 `HEAD` 建为初始基线;本次不修改对外文档。
|
|
21
|
+
6. 若 `last_sync_sha == HEAD`,报告 docs 已同步,无需操作。
|
|
22
|
+
|
|
23
|
+
## 边界
|
|
24
|
+
|
|
25
|
+
- 不把 state 写到仓库根目录。
|
|
26
|
+
- 不在首次运行时猜测 `tracked_docs`。
|
|
27
|
+
- 不修改对外文档。
|
|
28
|
+
|
|
29
|
+
## 完成准则
|
|
30
|
+
|
|
31
|
+
- 已确定是否首次运行、无需同步或继续进入 diff collect
|
|
32
|
+
- `.status.json` 的 `docs_sync_status` 已更新
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Docs Update Phase
|
|
2
|
+
|
|
3
|
+
## 输入
|
|
4
|
+
|
|
5
|
+
- `.speculo/dev/<change>/docs-sync-report.md`
|
|
6
|
+
- state 中的 `tracked_docs`
|
|
7
|
+
- git 差异素材
|
|
8
|
+
- 按需读取的 contract 文件
|
|
9
|
+
|
|
10
|
+
## 产物
|
|
11
|
+
|
|
12
|
+
- 更新后的 tracked docs
|
|
13
|
+
- `.speculo/dev/<change>/docs-sync-report.md`
|
|
14
|
+
|
|
15
|
+
## 填写引导
|
|
16
|
+
|
|
17
|
+
1. 更新 README 类文档前读取 `readme-contract.md`。
|
|
18
|
+
2. 更新 AGENTS / AI 代理手册类文档前读取 `agents-contract.md`。
|
|
19
|
+
3. 更新 CHANGELOG 类文档前读取 `changelog-contract.md`。
|
|
20
|
+
4. 所有文档只做差量修改,保留既有结构、语气和字段。
|
|
21
|
+
5. 多语言镜像文档必须结构对等;代码实体不翻译。
|
|
22
|
+
6. CHANGELOG 顶部必须保留 `[Unreleased]`。
|
|
23
|
+
7. AGENTS 类的仓库布局小节必须反映实际顶层目录变化。
|
|
24
|
+
|
|
25
|
+
## 边界
|
|
26
|
+
|
|
27
|
+
- 不整页重写 README 或代理手册。
|
|
28
|
+
- 不添加没有对应代码来源的计划中能力。
|
|
29
|
+
- 不把 docs-sync state 放回 skill 或 workflow 目录。
|
|
30
|
+
|
|
31
|
+
## 完成准则
|
|
32
|
+
|
|
33
|
+
- 需要同步的 tracked docs 已完成差量修改
|
|
34
|
+
- `docs-sync-report.md` 记录每个文档的修改理由和摘要
|
|
35
|
+
- `docs-sync-report.md` 无残留 `[TODO:]`
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# README 类文档同步契约(通用)
|
|
2
|
+
|
|
3
|
+
README 类文档(`README.md`、各语言镜像版本如 `README-ZH.md` / `README.zh-CN.md` / `README-JA.md`)面向初次接触项目的外部读者。本契约提供**与具体项目无关的通用规则**;项目独有的小节结构、表格内容由项目自身的现有 README 决定,同步时保留既有结构做差量更新即可。
|
|
4
|
+
|
|
5
|
+
## 多语言镜像对等原则
|
|
6
|
+
|
|
7
|
+
如果项目维护了多语言 README,任何单边改动都必须在同一次同步内把其他语言版本补齐,包括:
|
|
8
|
+
|
|
9
|
+
1. **章节数量对等**:一级、二级标题数量相同
|
|
10
|
+
2. **章节顺序对等**:同样的标题在相同位置出现
|
|
11
|
+
3. **表格列数对等**:每个表格的列数相同,行数尽量一致
|
|
12
|
+
4. **代码块对等**:命令、路径、配置示例逐字相同,只翻译前后的说明文字
|
|
13
|
+
5. **链接对等**:外链 URL 相同;站内链接指向对方语言版本的对应文件
|
|
14
|
+
|
|
15
|
+
**不翻译的内容**(视为代码实体):
|
|
16
|
+
|
|
17
|
+
- CLI 命令、命令行标志、子命令名
|
|
18
|
+
- 文件/目录路径、文件名
|
|
19
|
+
- 版本号、依赖名、包名
|
|
20
|
+
- 环境变量名、配置键
|
|
21
|
+
- 函数名、类名、API 路由
|
|
22
|
+
|
|
23
|
+
## 顶部约定(项目通用)
|
|
24
|
+
|
|
25
|
+
建议 README 顶部保留(按项目现状为准):
|
|
26
|
+
|
|
27
|
+
1. 项目名称(一级标题)
|
|
28
|
+
2. 简短描述段(blockquote 或正文段落,一两句话)
|
|
29
|
+
3. 状态徽章(build / npm version / downloads / license / node version 等;均为代码实体,所有语言版本保持一致)
|
|
30
|
+
4. 如存在多语言镜像:语言切换行,格式建议 `**Languages:** **English** · [简体中文](./README-ZH.md)` 或等价形式
|
|
31
|
+
|
|
32
|
+
改动徽章或语言切换行时所有语言版本同步。
|
|
33
|
+
|
|
34
|
+
## 典型小节与同步触发器
|
|
35
|
+
|
|
36
|
+
下表给出常见小节及其通用同步触发条件;实际存在哪些小节由项目决定。
|
|
37
|
+
|
|
38
|
+
| 常见小节 | 同步触发条件 |
|
|
39
|
+
|---------|-------------|
|
|
40
|
+
| 简介 / 它解决什么问题 | 项目定位(tagline、package.json description 等)变化 |
|
|
41
|
+
| 特性列表 | 新增/移除对外能力 |
|
|
42
|
+
| Quick Start | 入口命令、安装命令、最小示例代码变化 |
|
|
43
|
+
| 安装 | 发布渠道、安装命令、前置依赖变化 |
|
|
44
|
+
| 使用 / 用法 | 主用例、典型调用方式变化 |
|
|
45
|
+
| CLI Reference | CLI 入口(通常是 `src/cli/**`、`cmd/**`、`bin/**` 等)命令增删或签名变化 |
|
|
46
|
+
| API Reference | 公共 API 导出表面变化 |
|
|
47
|
+
| 配置 | 支持的配置键、默认值、环境变量变化 |
|
|
48
|
+
| 架构 / 核心设计 | 顶层模块边界或核心抽象变化 |
|
|
49
|
+
| 开发 | `package.json#scripts` / `Makefile` / `justfile` / `pyproject.toml` 的任务入口变化 |
|
|
50
|
+
| 发布 / Release Pipeline | CI workflow / release automation 步骤变化 |
|
|
51
|
+
| 致谢 / Acknowledgements | 新增/移除显著借鉴项目、贡献者 |
|
|
52
|
+
| License | LICENSE 文件变化(通常只在换 license 时) |
|
|
53
|
+
|
|
54
|
+
## Quick Start 命令同步规则
|
|
55
|
+
|
|
56
|
+
代码块内容在所有语言版本中**逐字相同**,只翻译说明文字:
|
|
57
|
+
|
|
58
|
+
英文示例:
|
|
59
|
+
|
|
60
|
+
````markdown
|
|
61
|
+
```bash
|
|
62
|
+
some-cli init --name my-project
|
|
63
|
+
```
|
|
64
|
+
Initialize with a project name.
|
|
65
|
+
````
|
|
66
|
+
|
|
67
|
+
中文示例:
|
|
68
|
+
|
|
69
|
+
````markdown
|
|
70
|
+
```bash
|
|
71
|
+
some-cli init --name my-project
|
|
72
|
+
```
|
|
73
|
+
指定项目名进行初始化。
|
|
74
|
+
````
|
|
75
|
+
|
|
76
|
+
## CLI / API Reference 表同步规则
|
|
77
|
+
|
|
78
|
+
CLI / API 参考表必须反映代码中的实际入口(如 `src/cli/index.ts` 的 `program.command(...)` 声明、公共 API 导出列表、OpenAPI schema 等)。
|
|
79
|
+
|
|
80
|
+
同步流程:
|
|
81
|
+
|
|
82
|
+
1. 从代码中枚举实际命令 / 端点 / 导出符号
|
|
83
|
+
2. 对比现有 README 表格
|
|
84
|
+
3. 新增条目 → 所有语言版本同时加一行
|
|
85
|
+
4. 删除 / 改名 → 所有语言版本同步
|
|
86
|
+
5. 签名变化(参数、返回值、标志、必选/可选)→ 同步
|
|
87
|
+
|
|
88
|
+
表头在所有语言版本的列数固定;仅列名翻译。
|
|
89
|
+
|
|
90
|
+
## 目录 / 项目结构小节同步规则
|
|
91
|
+
|
|
92
|
+
如 README 含有项目结构树,它是代码树的当前快照。每次同步对照实际顶层目录,新增 / 删除 / 重命名要跟进。
|
|
93
|
+
|
|
94
|
+
建议约定:
|
|
95
|
+
|
|
96
|
+
- 只列到第二层目录;更深层用 `*` 或省略号
|
|
97
|
+
- 右侧注释可翻译,左侧路径全语言版本保持一致
|
|
98
|
+
|
|
99
|
+
## Development / Release 小节同步规则
|
|
100
|
+
|
|
101
|
+
- `开发` / `Development` 小节中的命令列表来自项目的任务运行器(`package.json#scripts`、`Makefile`、`justfile` 等);新增脚本时所有语言版本同步
|
|
102
|
+
- `Release` / `发布流程` 小节反映 CI 实际步骤;workflow 改动(步骤增删、action 换版本、flag 变化)时同步
|
|
103
|
+
- 约束类语句(例如"版本号必须与 tag 对齐")在所有语言版本中等价表达,不能丢失
|
|
104
|
+
|
|
105
|
+
## 文档交叉引用
|
|
106
|
+
|
|
107
|
+
如 README 有"相关文档 / Documentation"小节,所有语言版本都应互相指向对方语言版本与其他站内文档(AGENTS / CHANGELOG / CONTRIBUTING 等)。
|
|
108
|
+
|
|
109
|
+
## 常见错位示例
|
|
110
|
+
|
|
111
|
+
| 情形 | 处理 |
|
|
112
|
+
|------|------|
|
|
113
|
+
| 新增了一个二级标题但忘记在其他语言版本添加 | 同一次同步补齐 |
|
|
114
|
+
| 某表格某行描述改了,但其他语言版本未改 | 同步对应行 |
|
|
115
|
+
| CLI 参考加了新命令但另一语言未加 | 所有语言版本同步 |
|
|
116
|
+
| 徽章版本换了 | 所有语言版本同步 |
|
|
117
|
+
| 外链项目 URL 改了(项目迁移) | 所有语言版本同步 |
|
|
118
|
+
|
|
119
|
+
## 不做的事
|
|
120
|
+
|
|
121
|
+
- 不整页重写现有 README;只做差量修改
|
|
122
|
+
- 不翻译代码实体
|
|
123
|
+
- 不在 README 里复述 CHANGELOG / AGENTS 里的内容
|
|
124
|
+
- 不添加没有对应代码来源的"计划中"能力(那是 CHANGELOG 的工作)
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# state 文件 Schema(docs-sync 持久化状态)
|
|
2
|
+
|
|
3
|
+
**默认存储位置**:`.speculo/dev/docs-sync-state.json`
|
|
4
|
+
|
|
5
|
+
本 workflow 在首次运行时会按默认路径创建;后续读写均以同一路径为准。不要把 docs-sync state 放到仓库根目录。
|
|
6
|
+
|
|
7
|
+
**定位**:
|
|
8
|
+
|
|
9
|
+
- docs-sync workflow **唯一**的跨 change 持久化状态
|
|
10
|
+
- 每次成功同步后原子化写入
|
|
11
|
+
- 必须跟随仓库提交到 git(作为同步基线的事实来源)
|
|
12
|
+
- **不放在 workflow 资产目录内**:workflow 目录是只读知识资产,状态属于项目 `.speculo/`
|
|
13
|
+
|
|
14
|
+
**初始化模板**:`../_templates/docs-sync-state-template.json`
|
|
15
|
+
|
|
16
|
+
## 字段定义
|
|
17
|
+
|
|
18
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
19
|
+
|------|------|:---:|------|
|
|
20
|
+
| `schema_version` | integer | ✓ | 当前 `1`;字段破坏性变化时递增 |
|
|
21
|
+
| `skill` | string | ✓ | 固定为 `"docs-sync"`,便于多技能共用项目根目录时辨识 |
|
|
22
|
+
| `state_path` | string | ✓ | 自描述字段:state 文件相对仓库根的路径;协助协作者理解文件位置 |
|
|
23
|
+
| `tracked_docs` | string[] | ✓ | 本项目纳入同步的文档路径(相对仓库根);首次运行后由用户确认写入 |
|
|
24
|
+
| `last_sync_sha` | string (40 hex) \| `null` | ✓ | 上次成功同步后记录的 commit SHA;下次 diff 的起点;首次运行前为 `null` |
|
|
25
|
+
| `last_sync_short` | string (7 hex) \| `null` | ✓ | `last_sync_sha` 的前 7 位,便于日志阅读 |
|
|
26
|
+
| `last_sync_commit_subject` | string \| `null` | ✓ | 上次基线 commit 的 subject 行 |
|
|
27
|
+
| `last_sync_commit_date` | string (ISO 8601) \| `null` | ✓ | 上次基线 commit 的 author date |
|
|
28
|
+
| `last_sync_run_at` | string (ISO 8601 UTC) \| `null` | ✓ | 本次同步**完成写入**时刻;与 `last_sync_commit_date` 不同 —— 前者是"我什么时候做的",后者是"基线 commit 什么时候创建的" |
|
|
29
|
+
| `previous_sync_sha` | string (40 hex) \| `null` | ✓ | 上一次的 `last_sync_sha`;首次运行时为 `null` |
|
|
30
|
+
| `total_syncs` | integer | ✓ | 累计触发次数(含空同步) |
|
|
31
|
+
| `synced_docs` | string[] | ✓ | 本次**实际被修改**的对外文档文件名数组;空同步时为 `[]` |
|
|
32
|
+
|
|
33
|
+
**禁止**放入的字段:
|
|
34
|
+
|
|
35
|
+
- commit 详细 diff(太大,用 git 现取)
|
|
36
|
+
- 用户个人信息
|
|
37
|
+
- 密钥 / token
|
|
38
|
+
- 绝对路径(影响跨环境协作)
|
|
39
|
+
|
|
40
|
+
## 典型状态
|
|
41
|
+
|
|
42
|
+
### 首次运行前(骨架 / 模板刚复制)
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"schema_version": 1,
|
|
47
|
+
"skill": "docs-sync",
|
|
48
|
+
"state_path": ".speculo/dev/docs-sync-state.json",
|
|
49
|
+
"tracked_docs": [],
|
|
50
|
+
"last_sync_sha": null,
|
|
51
|
+
"last_sync_short": null,
|
|
52
|
+
"last_sync_commit_subject": null,
|
|
53
|
+
"last_sync_commit_date": null,
|
|
54
|
+
"last_sync_run_at": null,
|
|
55
|
+
"previous_sync_sha": null,
|
|
56
|
+
"total_syncs": 0,
|
|
57
|
+
"synced_docs": []
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 建立基线后(首次运行完成)
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"schema_version": 1,
|
|
66
|
+
"skill": "docs-sync",
|
|
67
|
+
"state_path": ".speculo/dev/docs-sync-state.json",
|
|
68
|
+
"tracked_docs": ["README.md", "CHANGELOG.md"],
|
|
69
|
+
"last_sync_sha": "2d16d7a4d7f5da165c565b9aa3265824be133214",
|
|
70
|
+
"last_sync_short": "2d16d7a",
|
|
71
|
+
"last_sync_commit_subject": "chore: initial release",
|
|
72
|
+
"last_sync_commit_date": "2026-05-10T09:48:14+08:00",
|
|
73
|
+
"last_sync_run_at": "2026-05-10T12:00:00Z",
|
|
74
|
+
"previous_sync_sha": null,
|
|
75
|
+
"total_syncs": 0,
|
|
76
|
+
"synced_docs": []
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 常规同步(实际改了两份文档)
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"schema_version": 1,
|
|
85
|
+
"skill": "docs-sync",
|
|
86
|
+
"state_path": ".speculo/dev/docs-sync-state.json",
|
|
87
|
+
"tracked_docs": ["README.md", "CHANGELOG.md"],
|
|
88
|
+
"last_sync_sha": "abc1234def5678...",
|
|
89
|
+
"last_sync_short": "abc1234",
|
|
90
|
+
"last_sync_commit_subject": "feat(cli): add --json to status",
|
|
91
|
+
"last_sync_commit_date": "2026-05-15T10:20:30+08:00",
|
|
92
|
+
"last_sync_run_at": "2026-05-15T14:00:00Z",
|
|
93
|
+
"previous_sync_sha": "2d16d7a4d7f5da165c565b9aa3265824be133214",
|
|
94
|
+
"total_syncs": 3,
|
|
95
|
+
"synced_docs": ["README.md", "CHANGELOG.md"]
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 空同步(diff 全是文档自身)
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"schema_version": 1,
|
|
104
|
+
"skill": "docs-sync",
|
|
105
|
+
"state_path": ".speculo/dev/docs-sync-state.json",
|
|
106
|
+
"tracked_docs": ["README.md", "CHANGELOG.md"],
|
|
107
|
+
"last_sync_sha": "ffe9876abc5432...",
|
|
108
|
+
"last_sync_short": "ffe9876",
|
|
109
|
+
"last_sync_commit_subject": "docs(readme): fix typo",
|
|
110
|
+
"last_sync_commit_date": "2026-05-16T09:00:00+08:00",
|
|
111
|
+
"last_sync_run_at": "2026-05-16T11:00:00Z",
|
|
112
|
+
"previous_sync_sha": "abc1234def5678...",
|
|
113
|
+
"total_syncs": 4,
|
|
114
|
+
"synced_docs": []
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 写入规范
|
|
119
|
+
|
|
120
|
+
1. **原子化**:先写 `<state>.tmp`,再 `mv <state>.tmp <state>`。直接覆盖可能导致中断时 state 被截断
|
|
121
|
+
2. **格式化**:使用 2 空格缩进,尾部换行
|
|
122
|
+
3. **字段顺序**:保持上述表格顺序,便于 diff 阅读
|
|
123
|
+
4. **不保留注释**:JSON 标准不支持注释;所有解释都放本文件
|
|
124
|
+
|
|
125
|
+
## 读取容错
|
|
126
|
+
|
|
127
|
+
读取 state 文件时按以下降级链处理:
|
|
128
|
+
|
|
129
|
+
1. 文件不存在 → 首次运行流程:复制 `../_templates/docs-sync-state-template.json` 到 `.speculo/dev/docs-sync-state.json`,基线设为当前 HEAD,请用户确认 `tracked_docs`
|
|
130
|
+
2. JSON 解析失败 → 报错退出,要求用户手动修复或删除
|
|
131
|
+
3. `schema_version > 1` → 报错退出,提示技能版本过旧
|
|
132
|
+
4. `last_sync_sha` 不是 40 字符十六进制且不为 `null` → 视为损坏,回退到首次运行
|
|
133
|
+
|
|
134
|
+
## 版本演进规则
|
|
135
|
+
|
|
136
|
+
`schema_version` 只在**破坏性**字段变化时递增:
|
|
137
|
+
|
|
138
|
+
- 加字段(optional 或有默认值):**不**递增
|
|
139
|
+
- 删字段 / 改字段类型 / 改字段语义:递增
|
|
140
|
+
|
|
141
|
+
递增时必须在本文件追加"vN → vN+1 迁移"小节,描述如何处理老格式。
|
|
142
|
+
|
|
143
|
+
## 与 git 的协作
|
|
144
|
+
|
|
145
|
+
- state 文件**提交到 git**,作为仓库的一部分
|
|
146
|
+
- `last_sync_sha` 引用的 commit 必须在当前分支的历史中
|
|
147
|
+
- 如果多人协作导致 state 文件冲突:保留 `last_sync_sha` 值较新(即在 git 历史中更靠后)的那个,`total_syncs` 取较大值,`previous_sync_sha` 取被保留一方的值
|
|
148
|
+
|
|
149
|
+
## 不要做的事
|
|
150
|
+
|
|
151
|
+
- 不要把 state 文件放进 `.gitignore`
|
|
152
|
+
- 不要手动编辑 `last_sync_sha`(除非在修复损坏状态)
|
|
153
|
+
- 不要把敏感信息、机器信息、用户信息写入
|
|
154
|
+
- 不要让 `total_syncs` 回退
|
|
155
|
+
- 不要把 state 文件放回 workflow 资产目录——它属于项目 `.speculo/` 状态,不属于 framework 资产
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: dev/H-diagnose
|
|
3
|
+
category: dev
|
|
4
|
+
name: Diagnose Hotfix
|
|
5
|
+
description: 针对 Bug、异常和性能回退执行反馈循环驱动的诊断与修复
|
|
6
|
+
keywords: [diagnose, hotfix, bug, debug, performance, 回归]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Diagnose Hotfix 工作流执行指引
|
|
10
|
+
|
|
11
|
+
本工作流是 `dev/H` 入口,用于处理 Bug、异常、测试失败和性能回退。诊断循环指引已内置在本 workflow 目录中。
|
|
12
|
+
|
|
13
|
+
## 内置指引
|
|
14
|
+
|
|
15
|
+
### 何时使用
|
|
16
|
+
|
|
17
|
+
当用户报告 Bug、异常、测试失败、性能回退,或 dev workflow 进入 `dev/H` hotfix/diagnose 路径时使用。
|
|
18
|
+
|
|
19
|
+
### 输入
|
|
20
|
+
|
|
21
|
+
- 用户描述的失败现象、日志、复现步骤或性能症状
|
|
22
|
+
- 当前 change 目录:`.speculo/dev/<change>/`
|
|
23
|
+
- 可运行的测试、脚本、服务或其他反馈循环
|
|
24
|
+
|
|
25
|
+
### 输出
|
|
26
|
+
|
|
27
|
+
- `.speculo/dev/<change>/diagnosis.md`
|
|
28
|
+
- `.speculo/dev/<change>/regression.md`
|
|
29
|
+
- 诊断记录、假设列表、插桩结果、修复与回归验证结论
|
|
30
|
+
- 若缺少可信反馈循环,输出已尝试方法和需要用户提供的材料
|
|
31
|
+
|
|
32
|
+
### 执行原则
|
|
33
|
+
|
|
34
|
+
完整诊断循环为:复现 -> 最小化 -> 假设 -> 插桩 -> 修复 -> 回归测试。仅在明确合理时才跳过阶段。
|
|
35
|
+
|
|
36
|
+
反馈循环是核心。必须优先建立快速、确定、可信、可由 agent 运行的通过/失败信号。没有可信反馈循环时,不进入假设阶段;记录已尝试方法和需要用户提供的材料。
|
|
37
|
+
|
|
38
|
+
详细诊断纪律在同目录 `diagnose-guide.md`。必须由人类操作才能复现时,按 `scripts/hitl-loop.template.sh` 建立结构化 HITL 循环。
|
|
39
|
+
|
|
40
|
+
## 阶段
|
|
41
|
+
|
|
42
|
+
### 1. Diagnose Loop — 反馈循环与假设
|
|
43
|
+
- 规范:`diagnose-loop.md`
|
|
44
|
+
- 模板:`../_templates/diagnosis-template.md`
|
|
45
|
+
- 产物:`diagnosis.md`
|
|
46
|
+
- 完成准则:
|
|
47
|
+
- 已建立可信反馈循环,或记录无法建立的原因与所需材料
|
|
48
|
+
- 已记录复现、3-5 个排序假设和插桩结果
|
|
49
|
+
- `diagnosis.md` 无残留 `[TODO:]`
|
|
50
|
+
|
|
51
|
+
### 2. Fix Regression — 修复与回归
|
|
52
|
+
- 规范:`diagnose-fix.md`
|
|
53
|
+
- 模板:`../_templates/regression-template.md`
|
|
54
|
+
- 产物:`regression.md`
|
|
55
|
+
- 完成准则:
|
|
56
|
+
- 已在正确接缝添加或说明无法添加回归测试
|
|
57
|
+
- 原始反馈循环已重新验证
|
|
58
|
+
- `regression.md` 无残留 `[TODO:]`
|
|
59
|
+
|
|
60
|
+
## 依赖
|
|
61
|
+
|
|
62
|
+
- 软依赖:无
|
|
63
|
+
- 硬依赖:无
|
|
64
|
+
|
|
65
|
+
## 状态扩展字段
|
|
66
|
+
|
|
67
|
+
本工作流需在同 change 的 `.status.json` 追加:
|
|
68
|
+
|
|
69
|
+
- `dev_entry` (string) — 固定为 `dev/H`
|
|
70
|
+
- `embedded_guides` (array) — 包含 `diagnose`
|
|
71
|
+
- `feedback_loop` (none | weak | trusted | blocked) — 反馈循环状态
|
|
72
|
+
- `hypothesis_status` (open | testing | confirmed | rejected | blocked) — 假设状态
|
|
73
|
+
- `regression_test` (added | not-possible | not-needed | blocked) — 回归测试状态
|
|
74
|
+
- `debug_artifacts` (array) — 临时脚本、日志标记或 trace 路径
|
|
75
|
+
|
|
76
|
+
## 完成与状态更新
|
|
77
|
+
|
|
78
|
+
- 进入每个 phase 时更新 `current_phase` 和 `phase_history`。
|
|
79
|
+
- 若需要 TDD 实现修复,可嵌入 `../03-tdd/03-tdd.md` 的 Slice Loop。
|
|
80
|
+
- 修复验证完成后可把 `change_status` 置为 `completed`,或移交后续 review/handoff。
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Fix Regression Phase
|
|
2
|
+
|
|
3
|
+
## 输入
|
|
4
|
+
|
|
5
|
+
- `diagnosis.md`
|
|
6
|
+
- 已确认或最高可信假设
|
|
7
|
+
- 原始反馈循环和可用测试接缝
|
|
8
|
+
- `H-diagnose.md` 中的内置诊断指引
|
|
9
|
+
- 同目录 `diagnose-guide.md`
|
|
10
|
+
|
|
11
|
+
## 产物
|
|
12
|
+
|
|
13
|
+
- `.speculo/dev/<change>/regression.md`,由 `../_templates/regression-template.md` 填写
|
|
14
|
+
|
|
15
|
+
## 填写引导
|
|
16
|
+
|
|
17
|
+
1. 在修复前寻找能复现真实 Bug 模式的回归测试接缝。
|
|
18
|
+
2. 存在正确接缝时,先写失败测试,再应用修复,再验证通过。
|
|
19
|
+
3. 不存在正确接缝时,记录架构发现和后续改善建议。
|
|
20
|
+
4. 重新运行原始反馈循环,确认用户报告的问题不再复现。
|
|
21
|
+
5. 清理所有带标记的调试日志和一次性原型。
|
|
22
|
+
6. 完成前确认回归测试通过或缺少接缝已记录,所有 `[DEBUG-...]` 插桩已移除,最终正确假设已写入 `regression.md`。
|
|
23
|
+
|
|
24
|
+
## 边界
|
|
25
|
+
|
|
26
|
+
- 不提交未验证修复。
|
|
27
|
+
- 不自动归档 change。
|
|
28
|
+
- 不修改 `.speculo/.config/RULES.md` 或用户未明确授权的项目规则文档。
|
|
29
|
+
|
|
30
|
+
## 完成准则
|
|
31
|
+
|
|
32
|
+
- `regression.md` 无残留 `[TODO:]`
|
|
33
|
+
- `.status.json` 已记录 `regression_test`
|
|
34
|
+
- 原始反馈循环重新验证完成或阻塞原因已记录
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# 诊断
|
|
2
|
+
|
|
3
|
+
针对疑难 Bug 和性能回退的纪律化诊断循环。复现 -> 最小化 -> 假设 -> 插桩 -> 修复 -> 回归测试。当用户报告 Bug、异常、失败测试或性能回退时使用。
|
|
4
|
+
|
|
5
|
+
一套针对疑难 Bug 的纪律。仅在明确合理时才跳过阶段。
|
|
6
|
+
|
|
7
|
+
探索代码库时,使用项目的领域术语表来建立相关模块的清晰心智模型,并查阅你所触及区域的 ADR。
|
|
8
|
+
|
|
9
|
+
## 阶段 1 —— 构建反馈循环
|
|
10
|
+
|
|
11
|
+
**这是整个技能的核心。** 其余都是机械操作。如果你拥有一个快速、确定性的、可由 agent 运行的通过/失败信号来检测 Bug,你就能找到原因——二分查找、假设检验和插桩都只是在消费这个信号。如果没有这样的信号,再多的代码凝视也救不了你。
|
|
12
|
+
|
|
13
|
+
在这里投入不成比例的努力。**要大胆,要有创造力,绝不放弃。**
|
|
14
|
+
|
|
15
|
+
### 构建方法——大致按此顺序尝试
|
|
16
|
+
|
|
17
|
+
1. **失败测试** —— 在能触及 Bug 的任何接缝处编写——单元测试、集成测试、端到端测试。
|
|
18
|
+
2. **Curl / HTTP 脚本** —— 对运行中的开发服务器发请求。
|
|
19
|
+
3. **CLI 调用** —— 使用 fixture 输入,将 stdout 与已知正确的快照做 diff。
|
|
20
|
+
4. **无头浏览器脚本**(Playwright / Puppeteer)——驱动 UI,对 DOM/控制台/网络进行断言。
|
|
21
|
+
5. **重放捕获的 trace。** 将真实的网络请求/载荷/事件日志保存到磁盘;隔离地重放经过代码路径。
|
|
22
|
+
6. **一次性测试工具。** 启动系统的最小子集(一个服务,mock 依赖),通过单个函数调用触发 Bug 代码路径。
|
|
23
|
+
7. **属性/模糊循环。** 如果 Bug 是「有时输出错误」,运行 1000 个随机输入寻找失败模式。
|
|
24
|
+
8. **二分查找工具。** 如果 Bug 出现在两个已知状态之间(commit、数据集、版本),自动化「在状态 X 启动、检查、重复」,以便用 `git bisect run` 定位。
|
|
25
|
+
9. **差异循环。** 将相同输入分别通过旧版本和新版本(或两种配置),diff 输出。
|
|
26
|
+
10. **HITL bash 脚本。** 最后手段。如果必须由人类点击,用同目录 `scripts/hitl-loop.template.sh` 来驱动他们,使循环仍然结构化。捕获的输出反馈给你。
|
|
27
|
+
|
|
28
|
+
构建正确的反馈循环,Bug 就解决了 90%。
|
|
29
|
+
|
|
30
|
+
### 在循环本身上迭代
|
|
31
|
+
|
|
32
|
+
把循环当作产品来对待。一旦你有了_一个_循环,问自己:
|
|
33
|
+
|
|
34
|
+
- 能更快吗?(缓存设置、跳过无关初始化、缩小测试范围。)
|
|
35
|
+
- 能让信号更锐利吗?(断言具体症状,而不是「没有崩溃」。)
|
|
36
|
+
- 能更确定吗?(固定时间、设定随机种子、隔离文件系统、冻结网络。)
|
|
37
|
+
|
|
38
|
+
一个 30 秒的不稳定循环几乎不比没有循环好。一个 2 秒的确定性循环是调试超能力。
|
|
39
|
+
|
|
40
|
+
### 非确定性 Bug
|
|
41
|
+
|
|
42
|
+
目标不是干净的复现,而是**更高的复现率**。循环触发 100 次,并行化,增加压力,缩小时间窗口,注入 sleep。50% 概率出现的 Bug 可以调试;1% 的不行——持续提高复现率直到可以调试。
|
|
43
|
+
|
|
44
|
+
### 当你确实无法构建循环时
|
|
45
|
+
|
|
46
|
+
停下来明确说明。列出你尝试过的内容。向用户请求:(a) 访问能复现问题的环境,(b) 捕获的产物(HAR 文件、日志转储、核心转储、带时间戳的屏幕录制),或 (c) 在生产环境添加临时插桩的权限。在没有循环的情况下**不要**进入假设阶段。
|
|
47
|
+
|
|
48
|
+
在你拥有一个你信任的循环之前,不要进入阶段 2。
|
|
49
|
+
|
|
50
|
+
## 阶段 2 —— 复现
|
|
51
|
+
|
|
52
|
+
运行循环,观察 Bug 出现。
|
|
53
|
+
|
|
54
|
+
确认:
|
|
55
|
+
|
|
56
|
+
- [ ] 循环产生的是**用户**描述的失败模式——而不是附近碰巧的另一个失败。错误的 Bug = 错误的修复。
|
|
57
|
+
- [ ] 失败在多次运行中可复现(或者,对于非确定性 Bug,以足够高的概率复现以便调试)。
|
|
58
|
+
- [ ] 你已捕获了确切的症状(错误信息、错误输出、慢响应时间),以便后续阶段能验证修复确实解决了问题。
|
|
59
|
+
|
|
60
|
+
在你复现 Bug 之前不要继续。
|
|
61
|
+
|
|
62
|
+
## 阶段 3 —— 假设
|
|
63
|
+
|
|
64
|
+
在测试任何假设之前,先产生 **3–5 个排序的假设**。单假设生成会锚定在第一个看似合理的想法上。
|
|
65
|
+
|
|
66
|
+
每个假设必须是**可证伪的**:说明它做出的预测。
|
|
67
|
+
|
|
68
|
+
> 格式:「如果 <X> 是原因,那么 <改变 Y> 将使 Bug 消失 / <改变 Z> 将使它更严重。」
|
|
69
|
+
|
|
70
|
+
如果你无法说明预测,这个假设只是一种感觉——丢弃或锐化它。
|
|
71
|
+
|
|
72
|
+
**在测试之前将排序列表展示给用户。** 他们通常拥有能即时重新排序的领域知识(「我们刚部署了 #3 的变更」),或者知道他们已经排除的假设。低成本的检查点,大幅节省时间。不要因此阻塞——如果用户不在,按你的排序继续。
|
|
73
|
+
|
|
74
|
+
## 阶段 4 —— 插桩
|
|
75
|
+
|
|
76
|
+
每个探针必须映射到阶段 3 中的特定预测。**每次只改变一个变量。**
|
|
77
|
+
|
|
78
|
+
工具偏好:
|
|
79
|
+
|
|
80
|
+
1. **调试器 / REPL 检查**(如果环境支持)。一个断点胜过十个日志。
|
|
81
|
+
2. **定向日志** —— 在能区分假设的边界处打日志。
|
|
82
|
+
3. 绝不「把所有东西都打日志然后 grep」。
|
|
83
|
+
|
|
84
|
+
**给每个调试日志加上唯一前缀标签**,例如 `[DEBUG-a4f2]`。最后的清理变成一次 grep。未标记的日志保留;带标记的日志删除。
|
|
85
|
+
|
|
86
|
+
**性能分支。** 对于性能回退,日志通常是错的。正确做法:建立基线测量(计时工具、`performance.now()`、profiler、查询计划),然后二分查找。先测量,后修复。
|
|
87
|
+
|
|
88
|
+
## 阶段 5 —— 修复 + 回归测试
|
|
89
|
+
|
|
90
|
+
在修复**之前**编写回归测试——但前提是在**正确的接缝**处。
|
|
91
|
+
|
|
92
|
+
正确的接缝是指测试能在调用点触发**真实 Bug 模式**的地方。如果唯一可用的接缝太浅(当 Bug 需要多个调用者时只有单调用者测试,无法复制触发 Bug 的调用链的单元测试),那么在该处的回归测试只会给出虚假的信心。
|
|
93
|
+
|
|
94
|
+
**如果不存在正确的接缝,这本身就是发现。** 记录下来。代码库架构正在阻止 Bug 被锁定。在下一阶段标记此问题。
|
|
95
|
+
|
|
96
|
+
如果存在正确的接缝:
|
|
97
|
+
|
|
98
|
+
1. 将最小化复现转化为该接缝处的失败测试。
|
|
99
|
+
2. 观察它失败。
|
|
100
|
+
3. 应用修复。
|
|
101
|
+
4. 观察它通过。
|
|
102
|
+
5. 针对原始(未最小化的)场景重新运行阶段 1 的反馈循环。
|
|
103
|
+
|
|
104
|
+
## 阶段 6 —— 清理 + 事后分析
|
|
105
|
+
|
|
106
|
+
在宣布完成之前必须做:
|
|
107
|
+
|
|
108
|
+
- [ ] 原始复现不再复现(重新运行阶段 1 的循环)
|
|
109
|
+
- [ ] 回归测试通过(或缺少接缝已记录)
|
|
110
|
+
- [ ] 所有 `[DEBUG-...]` 插桩已移除(用 `grep` 搜索前缀)
|
|
111
|
+
- [ ] 一次性原型已删除(或移到明确标记的调试位置)
|
|
112
|
+
- [ ] 最终正确的假设已写在 commit / PR 信息中——以便下一个调试者从中学习
|
|
113
|
+
|
|
114
|
+
**然后问:什么能预防这个 Bug?** 如果答案涉及架构变更(没有好的测试接缝、纠缠的调用者、隐藏的耦合),将具体信息交给 `/improve-codebase-architecture` 技能处理。在修复**之后**提出建议,而不是之前——你现在比开始时拥有更多信息。
|