whynot-cli 0.0.0-stage → 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.
@@ -0,0 +1,170 @@
1
+ # E0 — Judge calibration
2
+
3
+ **Decision: PASS.** The judges are usable. One caveat below is important enough
4
+ that it should travel with every downstream number.
5
+
6
+ Run: 2026-10-20 · 62 blinded responses · 3 judges · 186 model calls
7
+
8
+ ---
9
+
10
+ ## Why this was the first experiment
11
+
12
+ Every claim in [validation.md](validation.md) rests on a model judging whether a
13
+ response recommends or excludes an option. If that judgement is unreliable, all
14
+ the numbers are unreliable. This was the cheapest experiment that could
15
+ invalidate everything else.
16
+
17
+ The pre-registered rule: if any judge's κ fell below 0.60, all further
18
+ experiments stop until the scoring is redesigned. See
19
+ [preregistration.md](preregistration.md).
20
+
21
+ ---
22
+
23
+ ## Method
24
+
25
+ 1. All 62 existing responses were anonymised: condition stripped from the
26
+ filename, IDs assigned (`E0-001` … `E0-062`), order shuffled with a fixed
27
+ seed.
28
+ 2. Labels were assigned blind — from response text only, with no knowledge of
29
+ which experiment or model produced them.
30
+ 3. Three judges from different families scored the same 62 items at
31
+ `temperature: 0`.
32
+ 4. Agreement measured with Cohen's κ against the human labels, and pairwise
33
+ between judges.
34
+
35
+ | Judge | Family | Model |
36
+ |---|---|---|
37
+ | A | Anthropic | `opencode-go/claude-haiku-5-5` |
38
+ | B | Moonshot | `moonshot-cn/kimi-k3` |
39
+ | C | DeepSeek | `workbuddy-ai/deepseek-v4.1-flash` |
40
+
41
+ Judge C was chosen deliberately from the same family as some of the judged
42
+ outputs, to test for same-family leniency.
43
+
44
+ ---
45
+
46
+ ## Results
47
+
48
+ ### All 62 items
49
+
50
+ | Judge | κ | Agreement | Errors |
51
+ |---|---|---|---|
52
+ | Claude Haiku 5.5 | 0.936 | 96.8% | 0 |
53
+ | Kimi K3 | 0.936 | 96.8% | 0 |
54
+ | DeepSeek Flash | 0.937 | 96.8% | 1 |
55
+ | Majority vote | 0.936 | 96.8% | — |
56
+
57
+ ### Excluding the two malformed samples
58
+
59
+ Two responses (`E0-054`, `E0-061`) were `reasoning_content` dumps — the model
60
+ never produced a final answer. They were labelled `unclear`. The judges read
61
+ the reasoning and inferred a recommendation, which is defensible but not the
62
+ same thing as reading a conclusion.
63
+
64
+ On the 60 well-formed responses:
65
+
66
+ | Judge | κ | Agreement |
67
+ |---|---|---|
68
+ | Claude Haiku 5.5 | **1.000** | 60/60 |
69
+ | Kimi K3 | **1.000** | 60/60 |
70
+ | DeepSeek Flash | **1.000** | 60/60 |
71
+ | Majority vote | **1.000** | 60/60 |
72
+
73
+ ### Pairwise
74
+
75
+ | Pair | κ | Agreement |
76
+ |---|---|---|
77
+ | Claude vs Kimi | 1.000 | 100% |
78
+ | Claude vs DeepSeek | 0.935 | 96.8% |
79
+ | Kimi vs DeepSeek | 0.935 | 96.8% |
80
+
81
+ ### Same-family leniency: not detected
82
+
83
+ The DeepSeek judge scored DeepSeek-produced responses no differently from the
84
+ others. κ was 0.937 versus 0.936 for the other two. This was the specific thing
85
+ experiment design was checking for, and the null result is worth recording.
86
+
87
+ ---
88
+
89
+ ## The caveat that matters
90
+
91
+ **κ = 1.000 does not mean "the judges are excellent". It means "this labelling
92
+ task is easy".**
93
+
94
+ Almost every response states its conclusion explicitly — "建议采用 TypeScript"
95
+ or "不使用 TypeScript" — within the first few lines. The sample contains
96
+ essentially **no genuinely ambiguous cases**. So this experiment establishes:
97
+
98
+ - The judges do not systematically disagree on clear responses. ✅
99
+ - The downstream numbers are not an artefact of sloppy scoring on clear
100
+ responses. ✅
101
+
102
+ It does **not** establish:
103
+
104
+ - That the judges handle hedged or ambiguous responses correctly. ❌
105
+ - That the labels are independent of the experimenter. ❌
106
+
107
+ A perfect κ is a warning sign as much as a result. It says the measurement is
108
+ not the hard part of this research; the experimental design is.
109
+
110
+ ---
111
+
112
+ ## Independence caveat — and the audit result
113
+
114
+ The "human" labels were produced by the same assistant that designed the
115
+ experiments. They were blind to condition, but they are not an independent
116
+ reference. A 20-item audit by the project owner was required.
117
+
118
+ **Audit result: 19/20 agreement, within the pre-registered threshold of 2.**
119
+
120
+ | | |
121
+ |---|---|
122
+ | Items reviewed | 20 |
123
+ | Agreement | 19 |
124
+ | Disagreements | 1 |
125
+ | Threshold | ≤ 2 |
126
+ | Result | **PASS** |
127
+
128
+ The single remaining disagreement (`E0-061`) is genuine: the response is a
129
+ truncated reasoning dump with no final conclusion, so `recommends` and
130
+ `unclear` are both defensible.
131
+
132
+ Two initial disagreements (`E0-013`, `E0-026`) were corrected by the reviewer
133
+ after reading the full response text; both responses state the conclusion
134
+ explicitly. This is a useful signal about the review process itself: **an
135
+ excerpt is not always enough for a human reviewer**, even when it is enough for
136
+ a model. The audit sheet truncates long responses, and that truncation caused
137
+ two of the three initial disagreements.
138
+
139
+ Files: `experiments/e0/audit-sample.md`, `answer-sheet.md`, `audit-key.json`,
140
+ `audit-result.json`.
141
+
142
+ **Treat the labels as an independent-enough reference, not as ground truth.**
143
+ The reviewer and the assistant agreed on 19 of 20 items, which is evidence that
144
+ the labels are not idiosyncratic. It is not evidence that either is correct on
145
+ the genuinely ambiguous cases.
146
+
147
+ ---
148
+
149
+ ## What this changes downstream
150
+
151
+ 1. **Majority vote is safe to use** for E1–E5, with the `unclear` rate reported.
152
+ 2. **Report the `unclear` count in every experiment.** Dropping unclear items
153
+ inflates agreement; they stay in the denominator.
154
+ 3. **Add a human spot-check to E3**, because E3's sample will contain more
155
+ ambiguous cases than this one did.
156
+ 4. **Do not claim the judges are validated on hard cases.** They are validated
157
+ on easy ones.
158
+
159
+ ---
160
+
161
+ ## Reproduce
162
+
163
+ ```bash
164
+ node experiments/e0/judge.mjs --dry # print the plan
165
+ node experiments/e0/judge.mjs # 186 calls
166
+ node experiments/e0/make-audit.mjs # render the 20-item human audit
167
+ ```
168
+
169
+ Files: `blind-sample.json`, `human-labels.json`, `judge-*.json`,
170
+ `calibration.json`, `audit-sample.md`, `audit-key.json`.
@@ -0,0 +1,257 @@
1
+ # Pre-registration
2
+
3
+ Written before the supplementary experiments were run, so that the decision
4
+ rules cannot be adjusted after seeing the results.
5
+
6
+ Created: 2026-10-20
7
+ Status: active. Do not edit after data collection begins.
8
+
9
+ ---
10
+
11
+ ## Why this file exists
12
+
13
+ The original experiments reported numbers after the fact, with thresholds
14
+ chosen implicitly. That makes it impossible for a reader to tell whether a
15
+ result was predicted or fitted. This document fixes the hypotheses, sample
16
+ sizes, and decision rules in advance.
17
+
18
+ If a result contradicts what is written here, the honest move is to publish the
19
+ contradiction, not to rewrite the rule.
20
+
21
+ ---
22
+
23
+ ## Hypotheses
24
+
25
+ ### H1 — stale decisions are obeyed
26
+ An agent given a decision that no longer holds will follow it rather than
27
+ question it.
28
+
29
+ **Prediction:** in the stale condition, ≥70% of responses avoid the rejected
30
+ option.
31
+
32
+ ### H2 — expiry removes the effect
33
+ If an expired entry is not shown to the agent at all, H1's effect disappears.
34
+
35
+ **Prediction:** in the expired condition, the rate of avoiding the option falls
36
+ to within 15 percentage points of the no-record baseline.
37
+
38
+ ### H3 — code context reduces it (the "information vacuum" hypothesis)
39
+ The original tasks contained no code, so the model had nothing to reason from
40
+ except the note. With a real codebase in context, the note's influence should
41
+ be weaker.
42
+
43
+ **Prediction:** with code context, the avoidance rate in the stale condition is
44
+ at least 20 points lower than without.
45
+
46
+ **This is the hypothesis most likely to be true and least flattering to the
47
+ project.** If it holds, the public claim must be rewritten from "agents blindly
48
+ obey stale decisions" to "agents obey given constraints when they have no other
49
+ information".
50
+
51
+ ### H4 — decisions are over-applied (false obedience)
52
+ An agent given a strong but irrelevant decision will let it distort an unrelated
53
+ answer.
54
+
55
+ **Prediction:** false-obedience rate < 10%.
56
+
57
+ ### H5 — obedience increases with age
58
+ Older decisions are obeyed more often.
59
+
60
+ **Prediction:** monotonic increase across 1 month → 7 years.
61
+
62
+ ### H5' — obedience is age-independent
63
+ The competing hypothesis. Models have no sense of how old a note is.
64
+
65
+ **Prediction:** flat across 1 month → 7 years.
66
+
67
+ H5 and H5' are mutually exclusive. **Both are publishable.** H5' is the stronger
68
+ finding because it means the problem is structural, not a matter of degree.
69
+
70
+ ### H6 — prompt warnings do not work
71
+ Adding "this is old, be skeptical" to the supplied context does not change
72
+ behaviour; removing the entry does.
73
+
74
+ **Status:** already tested once (experiment 3). Result: no reliable improvement.
75
+
76
+ ---
77
+
78
+ ## Experiments and decision rules
79
+
80
+ ### E0 — judge calibration
81
+
82
+ **Design:** all 62 existing responses, blinded, scored by three judges from
83
+ different model families (Claude Haiku, Kimi K3, DeepSeek Flash). Compared
84
+ against human labels using Cohen's kappa.
85
+
86
+ **Decision rule (fixed before running):**
87
+
88
+ | worst judge κ | action |
89
+ |---|---|
90
+ | ≥ 0.80 | PASS — use majority vote downstream |
91
+ | 0.60 – 0.80 | WARN — proceed, but disclose and add human spot-checks |
92
+ | < 0.60 | **FAIL — stop all further experiments until scoring is redesigned** |
93
+
94
+ **Known limitation:** the "human" labels were produced by the same assistant
95
+ that designed the experiments, blind to condition but not independent. The user
96
+ must audit a random subset. If the audit disagrees on more than 10% of items,
97
+ the labels are not a valid reference and E0 is re-run with the user's labels.
98
+
99
+ ---
100
+
101
+ ### E1 — code context
102
+
103
+ **Design:** three fixture repositories (small/medium/large), each with a planted
104
+ decision. Conditions: no decision, decision injected, decision discovered by
105
+ reading the repo.
106
+
107
+ **Sample:** n=10 per condition per model, 2 models.
108
+
109
+ **Decision rule:** H3 is supported if the code-context condition shows an
110
+ avoidance rate at least 20 points lower than the injected condition, with a
111
+ confidence interval excluding zero.
112
+
113
+ ---
114
+
115
+ ### E2 — false obedience
116
+
117
+ **Design:** a strongly worded but irrelevant decision, plus a relevant-decision
118
+ control.
119
+
120
+ **Sample:** n=15 per condition, 2 models.
121
+
122
+ **Decision rule:**
123
+
124
+ | false-obedience rate | action |
125
+ |---|---|
126
+ | < 5% | acceptable |
127
+ | 5 – 15% | add a constraint to the AGENTS.md instruction and retest |
128
+ | > 15% | **design defect — do not ship until fixed** |
129
+
130
+ ---
131
+
132
+ ### E3 — statistical power
133
+
134
+ **Design:** the Redis and TypeScript experiments at n=20 per condition, three
135
+ model families.
136
+
137
+ **Primary analysis:** pooled effect across models, Wilson 95% intervals, Fisher
138
+ exact test, risk difference.
139
+
140
+ **Decision rule:**
141
+ - pooled p < 0.01 and risk difference ≥ 0.40 → main claim stands
142
+ - p < 0.05 with a smaller effect → downgrade the wording
143
+ - not significant → **publish the correction**
144
+
145
+ ---
146
+
147
+ ### E4 — dose-response
148
+
149
+ **Design:** one decision, six ages (1 month, 6 months, 1 year, 3 years, 7 years,
150
+ plus an expired 7-year control), n=12 per cell, 2 models.
151
+
152
+ **Analysis:** Cochran-Armitage trend test.
153
+
154
+ **Decision rule:**
155
+ - D1 < 30% and D5 > 70% → H5 (dose effect)
156
+ - D1..D5 all > 70% → H5' (age-independent). Rewrite the narrative accordingly.
157
+ - D6 not close to D0 → the expiry mechanism is faulty; stop and fix.
158
+
159
+ ---
160
+
161
+ ### E5 — multi-turn with a real agent
162
+
163
+ **Design:** Codex CLI against a fixture repo, 8–12 turns, three conditions.
164
+
165
+ **Decision rule:** report the turn at which the decision stops influencing
166
+ behaviour, and the token cost. No pass/fail threshold — this is descriptive.
167
+
168
+ ---
169
+
170
+ ### E6 — two-week field test
171
+
172
+ **Status: not run.**
173
+
174
+ **Consequence:** the project may claim that the mechanism works under test. It
175
+ may **not** claim that using the tool reduces repeated mistakes.
176
+
177
+ **Design (for anyone who wants to run it):** 14 days without the tool, 14 days
178
+ with it, on a real project.
179
+
180
+ **Primary metric:** repeated-mistake rate — how often the agent re-proposes
181
+ something already rejected.
182
+
183
+ **Decision rule:**
184
+ - ≥ 30% reduction → the tool helps
185
+ - < 10% reduction → it does not
186
+ - increase → it hurts
187
+
188
+ ---
189
+
190
+ ## Amendments
191
+
192
+ Amendments are recorded with the date and the reason. Changing a decision rule
193
+ after seeing data is exactly what pre-registration exists to prevent, so any
194
+ change is logged here and both the original and amended rules are reported.
195
+
196
+ ### 2026-10-21 — E2 metric definition
197
+
198
+ **Original:** "false-obedience rate < 10%", without specifying what counted.
199
+
200
+ **Problem found during analysis:** the implementation used "response mentions
201
+ the irrelevant option at all". Manual inspection of the 9 flagged responses
202
+ showed they all said the decision *did not apply* — correct behaviour, not
203
+ obedience. The metric conflated "considered and dismissed" with "distorted by".
204
+
205
+ **Amendment:** report both metrics.
206
+
207
+ - mentions: 9/30 (30%) — the pre-registered reading, which is a FAIL
208
+ - design distorted: 0/30 (0%) — the substantive reading
209
+
210
+ Both are published in `e2-false-obedience.md`. The stricter number is not
211
+ hidden and the redefinition is argued from the raw text, not from preference.
212
+
213
+ **Future experiments:** pre-register the exact rubric or the exact string
214
+ matched, not just the concept.
215
+
216
+ ### 2026-10-21 — E4 judge failure
217
+
218
+ Kimi K3 returned `error` for every response from D2 onward. The original
219
+ summary counted errors as non-events, turning a judging failure into a clean
220
+ 0/12. All 168 responses were re-judged with DeepSeek Flash.
221
+
222
+ **Rule added:** an error is never a data point. Errors are excluded from
223
+ denominators and reported. This rule is now enforced in the E3 script, which
224
+ re-judges failures with a fallback judge.
225
+
226
+ ### 2026-10-21 — E3 query bug (caught before analysis)
227
+
228
+ The first E3 run used the query `技术 选型 存储 语言` for a decision titled
229
+ `session 不存 Redis`. No query term matched, so `decisions_check` returned
230
+ "nothing found" and the treatment condition was identical to the control. The
231
+ run was stopped before any analysis.
232
+
233
+ **Rule added:** every experiment that injects a decision now asserts that the
234
+ returned context contains the decision's title, and aborts otherwise.
235
+
236
+ ---
237
+
238
+ ## Analysis conventions
239
+
240
+ - Report confidence intervals, never bare proportions.
241
+ - Report the number of excluded or errored samples.
242
+ - Report inter-rater reliability for any model-judged outcome.
243
+ - Judge calls use `temperature: 0`.
244
+ - Any response that is truncated or missing a conclusion is labelled `unclear`
245
+ and included in the denominator. Dropping it would inflate agreement.
246
+
247
+ ## What would make me abandon the project
248
+
249
+ Stated in advance so it cannot be rationalised later:
250
+
251
+ 1. E0 fails (κ < 0.60) and the scoring cannot be redesigned.
252
+ 2. E2 shows > 15% false obedience and the instruction cannot fix it.
253
+ 3. E3 shows no significant effect at n=20.
254
+ 4. E6 shows no reduction in repeated mistakes over two weeks.
255
+
256
+ Any one of these is sufficient. The project's value depends on the claims being
257
+ true, not on the claims being published.
@@ -0,0 +1,30 @@
1
+ # Validation
2
+
3
+ This page is now an index. The consolidated results are in
4
+ [findings.md](findings.md); the detailed write-ups are below.
5
+
6
+ | Experiment | Question | Write-up |
7
+ |---|---|---|
8
+ | E0 | Can a model reliably judge "recommends vs excludes"? | [judge-calibration.md](judge-calibration.md) |
9
+ | E1 | Does real code context weaken the effect? | [e1-code-context.md](e1-code-context.md) |
10
+ | E2 / E2b | Does an irrelevant decision distort unrelated work? | [e2-false-obedience.md](e2-false-obedience.md) |
11
+ | E3 | Are the effects statistically real? | [e3-power.md](e3-power.md) |
12
+ | E4 | Does the age of a decision matter? | [e4-dose-response.md](e4-dose-response.md) |
13
+ | E5 | Does a real agent use it across sessions? | [e5-real-agent.md](e5-real-agent.md) |
14
+ | E6 | Does it help in real use? | **Not run** — see [preregistration.md](preregistration.md) |
15
+
16
+ ## A note on the earlier version of this page
17
+
18
+ The first version of this document reported results from a single small
19
+ experiment (n=3 per condition, two models). Those numbers appeared in the
20
+ README and in the launch material.
21
+
22
+ Several of them were misleading, and one was simply wrong:
23
+
24
+ - The "6 of 6 obeyed" framing understated the variance; at n=20 the same
25
+ decision was resisted in 13 of 60 responses.
26
+ - The first judging pass for the dose-response experiment silently counted
27
+ judge errors as data, producing a clean-looking result that did not exist.
28
+
29
+ Both are documented in [preregistration.md](preregistration.md). The numbers
30
+ that appear throughout the project now come from the experiments linked above.
@@ -0,0 +1,24 @@
1
+ # 验证
2
+
3
+ 这一页现在是一个索引。汇总结果在 [findings.zh-CN.md](findings.zh-CN.md)(英文版 [findings.md](findings.md)),详细写稿在下面。
4
+
5
+ | 实验 | 问题 | 写稿 |
6
+ |---|---|---|
7
+ | E0 | 模型能可靠地判断「推荐 vs 排除」吗? | [judge-calibration.md](judge-calibration.md) |
8
+ | E1 | 真实代码上下文会削弱效应吗? | [e1-code-context.md](e1-code-context.md) |
9
+ | E2 / E2b | 不相关的决策会扭曲无关工作吗? | [e2-false-obedience.md](e2-false-obedience.md) |
10
+ | E3 | 效应在统计上成立吗? | [e3-power.md](e3-power.md) |
11
+ | E4 | 决策的年龄重要吗? | [e4-dose-response.md](e4-dose-response.md) |
12
+ | E5 | 真实 agent 会跨会话使用它吗? | [e5-real-agent.md](e5-real-agent.md) |
13
+ | E6 | 真实使用中帮得上忙吗? | **未运行** —— 见 [preregistration.md](preregistration.md) |
14
+
15
+ ## 关于这一页的旧版本
16
+
17
+ 这一页最早报告的是单个小实验的结果(每条件 n=3,两个模型)。那些数字曾经出现在 README 和发布材料里。
18
+
19
+ 其中有几个是误导性的,有一个是**错的**:
20
+
21
+ - 「6/6 全部服从」这个说法低估了方差;n=20 时同一条决策在 60 次回复里被抵抗了 13 次。
22
+ - 剂量-反应实验的第一次判分把判分错误静默地当成了数据,产出了一个看起来很干净、实际不存在的结果。
23
+
24
+ 两件事都记录在 [preregistration.md](preregistration.md) 里。现在项目中使用的数字都来自上面链接的实验。
package/package.json CHANGED
@@ -1,6 +1,66 @@
1
1
  {
2
2
  "name": "whynot-cli",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Record what you ruled out, and why, so your coding agent stops re-suggesting it.",
5
+ "type": "module",
6
+ "author": "Stakenshake",
7
+ "homepage": "https://github.com/Stakenshake/whynot#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Stakenshake/whynot.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/Stakenshake/whynot/issues"
14
+ },
15
+ "bin": {
16
+ "whynot": "bin/whynot.js"
17
+ },
18
+ "exports": {
19
+ ".": "./src/index.js",
20
+ "./mcp": "./src/mcp.js",
21
+ "./audit": "./src/audit.js"
22
+ },
23
+ "files": [
24
+ "bin",
25
+ "src",
26
+ "docs/design.md",
27
+ "docs/design.zh-CN.md",
28
+ "docs/findings.md",
29
+ "docs/findings.zh-CN.md",
30
+ "docs/validation.md",
31
+ "docs/validation.zh-CN.md",
32
+ "docs/judge-calibration.md",
33
+ "docs/e1-code-context.md",
34
+ "docs/e2-false-obedience.md",
35
+ "docs/e3-power.md",
36
+ "docs/e4-dose-response.md",
37
+ "docs/e5-real-agent.md",
38
+ "docs/preregistration.md",
39
+ "AGENTS.snippet.md",
40
+ "AGENTS.snippet.zh-CN.md",
41
+ "README.md",
42
+ "README.zh-CN.md",
43
+ "CONTRIBUTING.md",
44
+ "LICENSE"
45
+ ],
46
+ "engines": {
47
+ "node": ">=20"
48
+ },
49
+ "scripts": {
50
+ "test": "node --test \"test/*.test.js\"",
51
+ "mcp": "node bin/whynot.js mcp"
52
+ },
53
+ "keywords": [
54
+ "mcp",
55
+ "model-context-protocol",
56
+ "coding-agents",
57
+ "claude-code",
58
+ "codex",
59
+ "context-engineering",
60
+ "decision-log",
61
+ "architecture-decision-record",
62
+ "adr"
63
+ ],
64
+ "license": "MIT",
65
+ "dependencies": {}
66
+ }