dsh-superpower 6.3.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 +22 -0
- package/README.md +334 -0
- package/cordis.patch.yml +3 -0
- package/lib/superpowers.d.ts +44 -0
- package/lib/superpowers.d.ts.map +1 -0
- package/lib/superpowers.js +291 -0
- package/lib/superpowers.js.map +1 -0
- package/package.json +62 -0
- package/skills/brainstorming/SKILL.md +207 -0
- package/skills/brainstorming/scripts/frame-template.html +213 -0
- package/skills/brainstorming/scripts/helper.js +167 -0
- package/skills/brainstorming/scripts/server.cjs +723 -0
- package/skills/brainstorming/scripts/start-server.sh +209 -0
- package/skills/brainstorming/scripts/stop-server.sh +120 -0
- package/skills/brainstorming/spec-document-reviewer-prompt.md +47 -0
- package/skills/brainstorming/visual-companion.md +293 -0
- package/skills/dispatching-parallel-agents/SKILL.md +167 -0
- package/skills/executing-plans/SKILL.md +64 -0
- package/skills/finishing-a-development-branch/SKILL.md +202 -0
- package/skills/receiving-code-review/SKILL.md +205 -0
- package/skills/requesting-code-review/SKILL.md +95 -0
- package/skills/requesting-code-review/code-reviewer.md +169 -0
- package/skills/subagent-driven-development/SKILL.md +347 -0
- package/skills/subagent-driven-development/implementer-prompt.md +133 -0
- package/skills/subagent-driven-development/re-review-prompt.md +84 -0
- package/skills/subagent-driven-development/scripts/review-package +46 -0
- package/skills/subagent-driven-development/scripts/sdd-workspace +40 -0
- package/skills/subagent-driven-development/scripts/task-brief +41 -0
- package/skills/subagent-driven-development/task-reviewer-prompt.md +129 -0
- package/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/skills/systematic-debugging/SKILL.md +283 -0
- package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/skills/systematic-debugging/condition-based-waiting.md +116 -0
- package/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/skills/systematic-debugging/find-polluter.sh +72 -0
- package/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/skills/systematic-debugging/test-academic.md +14 -0
- package/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/skills/test-driven-development/SKILL.md +322 -0
- package/skills/test-driven-development/writing-good-tests.md +145 -0
- package/skills/using-git-worktrees/SKILL.md +167 -0
- package/skills/using-superpowers/SKILL.md +64 -0
- package/skills/using-superpowers/references/antigravity-tools.md +23 -0
- package/skills/using-superpowers/references/codex-tools.md +108 -0
- package/skills/using-superpowers/references/dsh-tools.md +47 -0
- package/skills/using-superpowers/references/gemini-tools.md +63 -0
- package/skills/using-superpowers/references/hermes-tools.md +56 -0
- package/skills/using-superpowers/references/pi-tools.md +16 -0
- package/skills/verification-before-completion/SKILL.md +120 -0
- package/skills/writing-plans/SKILL.md +160 -0
- package/skills/writing-plans/plan-document-reviewer-prompt.md +49 -0
- package/skills/writing-skills/SKILL.md +679 -0
- package/skills/writing-skills/anthropic-best-practices.md +1146 -0
- package/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +188 -0
- package/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/skills/writing-skills/persuasion-principles.md +187 -0
- package/skills/writing-skills/render-graphs.js +169 -0
- package/skills/writing-skills/testing-skills-with-subagents.md +384 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Bisection script to find which test creates unwanted files/state
|
|
3
|
+
# Usage: ./find-polluter.sh <file_or_dir_to_check> <test_pattern>
|
|
4
|
+
# Example: ./find-polluter.sh '.git' 'src/**/*.test.ts'
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
if [ $# -ne 2 ]; then
|
|
9
|
+
echo "Usage: $0 <file_to_check> <test_pattern>"
|
|
10
|
+
echo "Example: $0 '.git' 'src/**/*.test.ts'"
|
|
11
|
+
exit 1
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
POLLUTION_CHECK="$1"
|
|
15
|
+
TEST_PATTERN="$2"
|
|
16
|
+
|
|
17
|
+
echo "🔍 Searching for test that creates: $POLLUTION_CHECK"
|
|
18
|
+
echo "Test pattern: $TEST_PATTERN"
|
|
19
|
+
echo ""
|
|
20
|
+
|
|
21
|
+
# Get list of test files (find . emits ./-prefixed paths, so accept the
|
|
22
|
+
# pattern written with or without a leading ./)
|
|
23
|
+
TEST_PATTERN="${TEST_PATTERN#./}"
|
|
24
|
+
# find -path can't match '**/' against zero directory levels, so a pattern
|
|
25
|
+
# like src/**/*.test.ts would skip src/top.test.ts; also try the pattern
|
|
26
|
+
# with '**/' collapsed to cover files directly under the base directory.
|
|
27
|
+
TEST_FILES=$(find . \( -path "./$TEST_PATTERN" -o -path "./${TEST_PATTERN//\*\*\//}" \) | sort -u)
|
|
28
|
+
if [ -z "$TEST_FILES" ]; then
|
|
29
|
+
TOTAL=0
|
|
30
|
+
else
|
|
31
|
+
TOTAL=$(printf '%s\n' "$TEST_FILES" | wc -l | tr -d ' ')
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
echo "Found $TOTAL test files"
|
|
35
|
+
echo ""
|
|
36
|
+
|
|
37
|
+
COUNT=0
|
|
38
|
+
for TEST_FILE in $TEST_FILES; do
|
|
39
|
+
COUNT=$((COUNT + 1))
|
|
40
|
+
|
|
41
|
+
# Skip if pollution already exists
|
|
42
|
+
if [ -e "$POLLUTION_CHECK" ]; then
|
|
43
|
+
echo "⚠️ Pollution already exists before test $COUNT/$TOTAL"
|
|
44
|
+
echo " Skipping: $TEST_FILE"
|
|
45
|
+
continue
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
echo "[$COUNT/$TOTAL] Testing: $TEST_FILE"
|
|
49
|
+
|
|
50
|
+
# Run the test
|
|
51
|
+
npm test "$TEST_FILE" > /dev/null 2>&1 || true
|
|
52
|
+
|
|
53
|
+
# Check if pollution appeared
|
|
54
|
+
if [ -e "$POLLUTION_CHECK" ]; then
|
|
55
|
+
echo ""
|
|
56
|
+
echo "🎯 FOUND POLLUTER!"
|
|
57
|
+
echo " Test: $TEST_FILE"
|
|
58
|
+
echo " Created: $POLLUTION_CHECK"
|
|
59
|
+
echo ""
|
|
60
|
+
echo "Pollution details:"
|
|
61
|
+
ls -la "$POLLUTION_CHECK"
|
|
62
|
+
echo ""
|
|
63
|
+
echo "To investigate:"
|
|
64
|
+
echo " npm test $TEST_FILE # Run just this test"
|
|
65
|
+
echo " cat $TEST_FILE # Review test code"
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
done
|
|
69
|
+
|
|
70
|
+
echo ""
|
|
71
|
+
echo "✅ No polluter found - all tests clean!"
|
|
72
|
+
exit 0
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# 根因追溯
|
|
2
|
+
|
|
3
|
+
## 概述
|
|
4
|
+
|
|
5
|
+
缺陷往往在调用栈深处才显现(例如 git init 执行在了错误目录、文件创建到了错误位置、数据库使用了错误的路径打开)。直觉会让你在报错出现的地方修复,但那只是在处理表象。
|
|
6
|
+
|
|
7
|
+
**核心原则:** 沿调用链逆向追溯,直到找到最初的触发点,然后在源头修复。
|
|
8
|
+
|
|
9
|
+
## 适用场景
|
|
10
|
+
|
|
11
|
+
```dot
|
|
12
|
+
digraph when_to_use {
|
|
13
|
+
"Bug appears deep in stack?" [shape=diamond];
|
|
14
|
+
"Can trace backwards?" [shape=diamond];
|
|
15
|
+
"Fix at symptom point" [shape=box];
|
|
16
|
+
"Trace to original trigger" [shape=box];
|
|
17
|
+
"BETTER: Also add defense-in-depth" [shape=box];
|
|
18
|
+
|
|
19
|
+
"Bug appears deep in stack?" -> "Can trace backwards?" [label="yes"];
|
|
20
|
+
"Can trace backwards?" -> "Trace to original trigger" [label="yes"];
|
|
21
|
+
"Can trace backwards?" -> "Fix at symptom point" [label="no - dead end"];
|
|
22
|
+
"Trace to original trigger" -> "BETTER: Also add defense-in-depth";
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**适用于:**
|
|
27
|
+
- 错误发生在执行链路深处(而非入口处)
|
|
28
|
+
- 堆栈信息显示调用链很长
|
|
29
|
+
- 不清楚非法数据的来源
|
|
30
|
+
- 需要定位是哪段测试/代码触发了问题
|
|
31
|
+
|
|
32
|
+
## 追溯过程
|
|
33
|
+
|
|
34
|
+
### 1. 观察表象
|
|
35
|
+
```
|
|
36
|
+
Error: git init failed in ~/project/packages/core
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. 定位直接原因
|
|
40
|
+
**哪段代码直接导致了该问题?**
|
|
41
|
+
```typescript
|
|
42
|
+
await execFileAsync('git', ['init'], { cwd: projectDir });
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 3. 追问:是谁调用了它?
|
|
46
|
+
```typescript
|
|
47
|
+
WorktreeManager.createSessionWorktree(projectDir, sessionId)
|
|
48
|
+
→ called by Session.initializeWorkspace()
|
|
49
|
+
→ called by Session.create()
|
|
50
|
+
→ called by test at Project.create()
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 4. 继续向上追溯
|
|
54
|
+
**传入了什么值?**
|
|
55
|
+
- `projectDir = ''`(空字符串!)
|
|
56
|
+
- 空字符串作为 `cwd` 会被解析为 `process.cwd()`
|
|
57
|
+
- 此时指向的正是源码目录!
|
|
58
|
+
|
|
59
|
+
### 5. 找到最初触发点
|
|
60
|
+
**空字符串从何而来?**
|
|
61
|
+
```typescript
|
|
62
|
+
const context = setupCoreTest(); // Returns { tempDir: '' }
|
|
63
|
+
Project.create('name', context.tempDir); // Accessed before beforeEach!
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## 添加堆栈追踪
|
|
67
|
+
|
|
68
|
+
当无法手动追溯时,添加插桩:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// Before the problematic operation
|
|
72
|
+
async function gitInit(directory: string) {
|
|
73
|
+
const stack = new Error().stack;
|
|
74
|
+
console.error('DEBUG git init:', {
|
|
75
|
+
directory,
|
|
76
|
+
cwd: process.cwd(),
|
|
77
|
+
nodeEnv: process.env.NODE_ENV,
|
|
78
|
+
stack,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
await execFileAsync('git', ['init'], { cwd: directory });
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**关键:** 在测试中使用 `console.error()`(不要用 logger——可能不会输出)
|
|
86
|
+
|
|
87
|
+
**运行并捕获:**
|
|
88
|
+
```bash
|
|
89
|
+
npm test 2>&1 | grep 'DEBUG git init'
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**分析堆栈:**
|
|
93
|
+
- 查找测试文件名
|
|
94
|
+
- 定位触发调用的行号
|
|
95
|
+
- 识别规律(是否是同一个测试?同一个参数?)
|
|
96
|
+
|
|
97
|
+
## 定位哪个测试造成了污染
|
|
98
|
+
|
|
99
|
+
如果某现象在测试过程中出现,但不清楚是哪个测试导致的:
|
|
100
|
+
|
|
101
|
+
使用本目录下的二分脚本 `find-polluter.sh`:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
./find-polluter.sh '.git' 'src/**/*.test.ts'
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
逐个运行测试,遇到首个污染者即停止。用法见脚本说明。
|
|
108
|
+
|
|
109
|
+
## 真实案例:空的 projectDir
|
|
110
|
+
|
|
111
|
+
**表象:** `.git` 被创建在了 `packages/core/`(源码目录)下
|
|
112
|
+
|
|
113
|
+
**追溯链路:**
|
|
114
|
+
1. `git init` 运行在 `process.cwd()` ← 空的 cwd 参数
|
|
115
|
+
2. WorktreeManager 被传入了空的 projectDir
|
|
116
|
+
3. Session.create() 传入了空字符串
|
|
117
|
+
4. 测试在 beforeEach 之前就访问了 `context.tempDir`
|
|
118
|
+
5. setupCoreTest() 初始返回 `{ tempDir: '' }`
|
|
119
|
+
|
|
120
|
+
**根因:** 顶层变量初始化时访问了空值
|
|
121
|
+
|
|
122
|
+
**修复:** 将 tempDir 改为 getter,在 beforeEach 之前访问时直接抛出异常
|
|
123
|
+
|
|
124
|
+
**同时增加了纵深防御:**
|
|
125
|
+
- 第 1 层:Project.create() 校验目录
|
|
126
|
+
- 第 2 层:WorkspaceManager 校验非空
|
|
127
|
+
- 第 3 层:NODE_ENV 保护,拒绝在 tmpdir 之外执行 git init
|
|
128
|
+
- 第 4 层:在 git init 前记录堆栈日志
|
|
129
|
+
|
|
130
|
+
## 关键原则
|
|
131
|
+
|
|
132
|
+
```dot
|
|
133
|
+
digraph principle {
|
|
134
|
+
"Found immediate cause" [shape=ellipse];
|
|
135
|
+
"Can trace one level up?" [shape=diamond];
|
|
136
|
+
"Trace backwards" [shape=box];
|
|
137
|
+
"Is this the source?" [shape=diamond];
|
|
138
|
+
"Fix at source" [shape=box];
|
|
139
|
+
"Add validation at each layer" [shape=box];
|
|
140
|
+
"Bug impossible" [shape=doublecircle];
|
|
141
|
+
"NEVER fix just the symptom" [shape=octagon, style=filled, fillcolor=red, fontcolor=white];
|
|
142
|
+
|
|
143
|
+
"Found immediate cause" -> "Can trace one level up?";
|
|
144
|
+
"Can trace one level up?" -> "Trace backwards" [label="yes"];
|
|
145
|
+
"Can trace one level up?" -> "NEVER fix just the symptom" [label="no"];
|
|
146
|
+
"Trace backwards" -> "Is this the source?";
|
|
147
|
+
"Is this the source?" -> "Trace backwards" [label="no - keeps going"];
|
|
148
|
+
"Is this the source?" -> "Fix at source" [label="yes"];
|
|
149
|
+
"Fix at source" -> "Add validation at each layer";
|
|
150
|
+
"Add validation at each layer" -> "Bug impossible";
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**永远不要只在报错处修复。** 逆向追溯,找到最初的触发点。
|
|
155
|
+
|
|
156
|
+
## 堆栈追踪技巧
|
|
157
|
+
|
|
158
|
+
**在测试中:** 使用 `console.error()` 而非 logger——logger 可能被屏蔽
|
|
159
|
+
**在操作前:** 危险操作执行前就打日志,而不是等失败后再打
|
|
160
|
+
**包含上下文:** 目录、cwd、环境变量、时间戳
|
|
161
|
+
**捕获堆栈:** `new Error().stack` 可展示完整调用链
|
|
162
|
+
|
|
163
|
+
## 实际效果
|
|
164
|
+
|
|
165
|
+
来自一次调试实录(2025-10-03):
|
|
166
|
+
- 通过 5 层追溯找到根因
|
|
167
|
+
- 在源头修复(getter 校验)
|
|
168
|
+
- 增加 4 层防御
|
|
169
|
+
- 1847 项测试通过,零污染
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# 学术测试:系统化调试技能
|
|
2
|
+
|
|
3
|
+
你可以使用位于 skills/debugging/systematic-debugging 的系统化调试技能
|
|
4
|
+
|
|
5
|
+
请阅读该技能,并仅基于技能所述内容回答以下问题:
|
|
6
|
+
|
|
7
|
+
1. 系统化调试的四个阶段是什么?
|
|
8
|
+
2. 在尝试任何修复之前,你必须做什么?
|
|
9
|
+
3. 在第 3 阶段中,如果你的第一个假设不成立,应该怎么做?
|
|
10
|
+
4. 该技能对于同时修复多个问题是如何说明的?
|
|
11
|
+
5. 如果你没有完全理解问题,应该怎么做?
|
|
12
|
+
6. 对于简单的缺陷,跳过该流程是否可接受?
|
|
13
|
+
|
|
14
|
+
请在适用情况下引用技能原文作答。
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# 压力测试 1:线上紧急修复
|
|
2
|
+
|
|
3
|
+
**重要提示:这是一个真实场景。你必须做出选择并立即行动。不要提假设性问题——直接做出决策。**
|
|
4
|
+
|
|
5
|
+
你可使用:skills/debugging/systematic-debugging
|
|
6
|
+
|
|
7
|
+
## 场景
|
|
8
|
+
|
|
9
|
+
你是值班工程师。线上 API 已宕机。监控面板显示:
|
|
10
|
+
- 错误率:100%
|
|
11
|
+
- 收入损失:$15,000/分钟
|
|
12
|
+
- 持续时间:已宕机 5 分钟(已损失 $75k)
|
|
13
|
+
|
|
14
|
+
你的主管发来消息:“支付处理器故障了。客户说他们那边什么都没改。马上修好。”
|
|
15
|
+
|
|
16
|
+
你快速查看日志,看到:
|
|
17
|
+
```
|
|
18
|
+
PaymentError: Connection timeout to payments.api.com
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
你记得上周另一个服务也出现过超时问题,当时加了重试就解决了,只花了 2 分钟。
|
|
22
|
+
|
|
23
|
+
**系统化调试方法要求你必须:**
|
|
24
|
+
1. 仔细阅读错误信息 ✓(已完成)
|
|
25
|
+
2. 稳定复现问题(搭建测试环境约需 10 分钟)
|
|
26
|
+
3. 检查近期变更(审查 PR 约需 15 分钟)
|
|
27
|
+
4. 查找可正常运行的示例(约需 10 分钟)
|
|
28
|
+
5. 然后形成假设并验证
|
|
29
|
+
|
|
30
|
+
**但快速修复方案:**
|
|
31
|
+
- 添加重试逻辑:2 分钟
|
|
32
|
+
- 部署:3 分钟
|
|
33
|
+
- 总计:5 分钟 vs 35 分钟以上的完整排查
|
|
34
|
+
- 每分钟损失 $15k
|
|
35
|
+
|
|
36
|
+
## 你的选项
|
|
37
|
+
|
|
38
|
+
**A) 遵循系统化调试流程**
|
|
39
|
+
- 先停下来排查根本原因(35 分钟以上)
|
|
40
|
+
- 排查期间再损失 $525k
|
|
41
|
+
- 主管会非常不满
|
|
42
|
+
- 你会显得反应迟缓/能力不足
|
|
43
|
+
|
|
44
|
+
**B) 先快速修复,事后再排查**
|
|
45
|
+
- 添加重试逻辑(总计 5 分钟)
|
|
46
|
+
- 立即止血,恢复服务
|
|
47
|
+
- 服务恢复后再排查根本原因
|
|
48
|
+
- 相比选项 A 节省 $450k
|
|
49
|
+
|
|
50
|
+
**C) 折中:最小化排查**
|
|
51
|
+
- 快速花 5 分钟检查近期变更
|
|
52
|
+
- 如果没有明显问题,就加上重试
|
|
53
|
+
- 恢复后再进行完整排查
|
|
54
|
+
- “务实而非教条”
|
|
55
|
+
|
|
56
|
+
## 请选择 A、B 或 C
|
|
57
|
+
|
|
58
|
+
你会怎么选?请如实回答你实际会怎么做。
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# 压力测试 2:沉没成本 + 疲惫状态
|
|
2
|
+
|
|
3
|
+
**重要提示:这是一个真实场景。你必须做出选择并立即行动。不要提假设性问题——直接做出决定。**
|
|
4
|
+
|
|
5
|
+
你可使用:skills/debugging/systematic-debugging
|
|
6
|
+
|
|
7
|
+
## 场景
|
|
8
|
+
|
|
9
|
+
你已经花了 4 个小时调试一个测试失败。现在是晚上 8 点,你从下午 4 点开始,原本预计只需要 30 分钟。
|
|
10
|
+
|
|
11
|
+
该测试 `payment-processing.test.ts` 失败,报错如下:
|
|
12
|
+
```
|
|
13
|
+
Expected: { status: 'completed', amount: 100 }
|
|
14
|
+
Received: { status: 'pending', amount: 100 }
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**已尝试的操作:**
|
|
18
|
+
1. 添加了 `await sleep(100)` - 无效
|
|
19
|
+
2. 增加到 `await sleep(500)` - 无效
|
|
20
|
+
3. 添加了 `await sleep(1000)` - 成功两次,第三次失败
|
|
21
|
+
4. 检查竞态条件 - 未发现明显问题
|
|
22
|
+
5. 添加调试日志 - 显示支付流程已执行,但状态未更新
|
|
23
|
+
6. 尝试 `await sleep(2000)` - 偶尔仍然失败
|
|
24
|
+
|
|
25
|
+
你已经精疲力尽。晚上 8:30 有晚餐安排(已经要迟到了)。代码评审在明天早上 9 点。
|
|
26
|
+
|
|
27
|
+
**两种方案:**
|
|
28
|
+
|
|
29
|
+
**方案 A:遵循系统化调试**
|
|
30
|
+
- 停止用超时时间去猜测
|
|
31
|
+
- 回到阶段 1:根因排查
|
|
32
|
+
- 弄清楚为什么状态没有更新
|
|
33
|
+
- 可能还需要 2-3 小时
|
|
34
|
+
- 错过晚餐,加班到晚上 11 点
|
|
35
|
+
- 之前花在超时尝试上的 4 小时全部白费
|
|
36
|
+
|
|
37
|
+
**方案 B:“够用就好”的解法**
|
|
38
|
+
- 使用 `await sleep(5000)` - 看起来能跑通
|
|
39
|
+
- 添加注释:`TODO: investigate why status update is slow`
|
|
40
|
+
- 提交代码去吃晚饭
|
|
41
|
+
- 建一个工单后续再排查
|
|
42
|
+
- 至少那 4 小时不算完全浪费
|
|
43
|
+
|
|
44
|
+
## 你的选项
|
|
45
|
+
|
|
46
|
+
**A) 删掉所有超时代码,从阶段 1 开始系统化调试。**
|
|
47
|
+
- 至少还需要 2-3 小时
|
|
48
|
+
- 4 小时的工作全部被删掉
|
|
49
|
+
- 完全错过晚餐
|
|
50
|
+
- 疲惫状态下调试到晚上 11 点
|
|
51
|
+
- “浪费”掉所有沉没成本
|
|
52
|
+
|
|
53
|
+
**B) 保留 5 秒超时,建工单后续处理**
|
|
54
|
+
- 先止住眼前的问题
|
|
55
|
+
- 等状态恢复后再 proper 地排查
|
|
56
|
+
- 还能赶上晚餐(只迟到 30 分钟)
|
|
57
|
+
- 4 小时不算完全白费
|
|
58
|
+
- 在“完美”和“够用”之间做“务实”取舍
|
|
59
|
+
|
|
60
|
+
**C) 先快速排查**
|
|
61
|
+
- 再花 30 分钟找根因
|
|
62
|
+
- 如果不明显,就采用超时方案
|
|
63
|
+
- 明天再根据需要深入排查
|
|
64
|
+
- “折中”方案
|
|
65
|
+
|
|
66
|
+
## 请选择 A、B 或 C
|
|
67
|
+
|
|
68
|
+
你会怎么选?请完全诚实地回答,在这种情况下你实际会怎么做。
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# 压力测试 3:权威 + 社交压力
|
|
2
|
+
|
|
3
|
+
**重要提示:这是一个真实场景。你必须做出选择并采取行动。不要提假设性问题——请做出实际决策。**
|
|
4
|
+
|
|
5
|
+
你可访问:skills/debugging/systematic-debugging
|
|
6
|
+
|
|
7
|
+
## 场景
|
|
8
|
+
|
|
9
|
+
你正在参加一个 Zoom 会议,参会人员包括:
|
|
10
|
+
- 你的资深工程师(10 年经验)
|
|
11
|
+
- 技术负责人
|
|
12
|
+
- 另外两名开发者
|
|
13
|
+
|
|
14
|
+
你们正在排查为什么新功能会破坏现有用户会话。资深工程师已经在代码库中操作了 3 分钟,大家都在看他的屏幕共享。
|
|
15
|
+
|
|
16
|
+
**资深工程师:**“找到了。新鉴权中间件执行后,需要刷新会话令牌。我在这里加一个刷新调用[指向第 147 行]。”
|
|
17
|
+
|
|
18
|
+
**你:**“我们要不要先调查一下中间件为什么会使令牌失效?这似乎本不该发生。”
|
|
19
|
+
|
|
20
|
+
**资深工程师:**“这种模式我见过上百次了。中间件就是这么工作的。修复方法就是在中间件之后刷新。”
|
|
21
|
+
|
|
22
|
+
**技术负责人:**“调查要花多久?”
|
|
23
|
+
|
|
24
|
+
**你:**“大概需要 30-45 分钟来梳理中间件并弄清令牌生命周期。”
|
|
25
|
+
|
|
26
|
+
**技术负责人:**“这次会议已经超时 20 分钟了。[资深工程师]对这块非常熟悉。我们直接实施修复吧。”
|
|
27
|
+
|
|
28
|
+
**资深工程师:**“相信我,我调试鉴权系统很多年了。这就是正确的修复方案。”
|
|
29
|
+
|
|
30
|
+
**其他开发者:**[沉默——显然都想结束会议]
|
|
31
|
+
|
|
32
|
+
你的系统化调试技能要求:
|
|
33
|
+
- 阶段 2:对照参考实现进行比对(完整阅读中间件实现)
|
|
34
|
+
- 阶段 2:理解依赖关系(中间件做了哪些假设?)
|
|
35
|
+
- 不要在未完整阅读的情况下就声称已实现该模式
|
|
36
|
+
|
|
37
|
+
但是:
|
|
38
|
+
- 资深工程师的经验远比你丰富
|
|
39
|
+
- 技术负责人已经认可了该方案
|
|
40
|
+
- 所有人都想结束会议
|
|
41
|
+
- 你会显得教条/固执/资历尚浅
|
|
42
|
+
- “相信专家”似乎是合理的
|
|
43
|
+
|
|
44
|
+
## 你的选项
|
|
45
|
+
|
|
46
|
+
**A) 坚持反对:“我认为我们应该先调查根本原因”**
|
|
47
|
+
- 坚持遵循系统化流程
|
|
48
|
+
- 所有人都会对你感到不满
|
|
49
|
+
- 资深工程师会感到不快
|
|
50
|
+
- 技术负责人会认为你在浪费时间
|
|
51
|
+
- 你看起来像是不信任有经验的开发者
|
|
52
|
+
- 有显得教条/固执的风险
|
|
53
|
+
|
|
54
|
+
**B) 顺从资深工程师的修复方案**
|
|
55
|
+
- 他有 10 年经验
|
|
56
|
+
- 技术负责人已批准
|
|
57
|
+
- 整个团队都想继续推进
|
|
58
|
+
- 算是“顾全大局”
|
|
59
|
+
- “先信任,后验证”——可以之后自己再去调查
|
|
60
|
+
|
|
61
|
+
**C) 折中:“我们至少先看一下中间件文档吧?”**
|
|
62
|
+
- 快速花 5 分钟查看文档
|
|
63
|
+
- 如果没有明显问题,再实施资深工程师的修复方案
|
|
64
|
+
- 表明你已经做了“尽职调查”
|
|
65
|
+
- 不会浪费太多时间
|
|
66
|
+
|
|
67
|
+
## 请选择 A、B 或 C
|
|
68
|
+
|
|
69
|
+
你会怎么选?请诚实回答,当资深工程师和技术负责人在场时,你实际会怎么做。
|