controlPassed() 反証側 両側判定 バグ fix — 1 行 修正 + STEP 1846 attribution corrigendum
STEP 1846 v0.2 の controlPassed() が 反証 control 側 を 両側判定 で 書いていた バグ を、 Cowork side の Tatoeba multi-lang 実測 (en-ja shuffled-gold CI [-0.00030, -0.00008]) が 発見。 私・Cowork-Claude・Gemini の 誰も 見落として、 データ が 見つけた。 1 行 修正 + fixture 実測差替 + STEP 1846 attribution corrigendum。
1. バグ の 中身
旧実装 (STEP 1846 rev.2 land):
const excludesNull = c.interval.lower > 0 || c.interval.upper < 0; return c.expectation === 'effect-persists' ? c.interval.lower > 0 : !excludesNull; // ← 反証 側 が 両側判定
反証 control の 契約意図 は 「対応 破壊 で 効果 が subject 方向 に 残らない」。 現行 !excludesNull は 「CI が どちら側 でも 0 を 除外しない」 を 要求 = subject 反対方向 の 有意 CI 除外 も 反証 不通過 扱い。 これは leakage の 逆 を leakage と 誤認 する バグ。
修正 (1 行):
return (c.interval.lower > 0) === (c.expectation === 'effect-persists');
両分岐 が lower > 0 の 一致判定 に 畳まれる。 判別 と 反証 は 「subject 方向 に 効果 が 残ったか」 の 期待 が 反転するだけ で、 判定 する 事実 は 同じ。
2. 発見経緯 — データ が 見つけた
Cowork side (chat AI) が Paper 179 保留 の 4 言語対 判別 control を 実施 (data/experiments/weaver-b-multilang-2026-09-06/)。 en-ja shuffled-gold 実測 CI [-0.00030, -0.00008] = 両端 negative。 旧実装 で 「反証 不通過 → R2 補則 → separatingPower 'none'」 と 誤発火 した ため バグ 発覚。
私 (Code-Claude)、 Cowork-Claude、 Gemini の 誰も 見落として、 データ が 見つけた。 これは STEP 1846 checklist 3 「fixture 緑 は refactor 正しさ の evidence では ない」 の 狭く 具体的な 実例: 「fixture 緑 は、 fixture の 数値 が 実測 で ある 場合 に しか 実装 の 正しさ を 保証 しない」。
3. §7 fixture が バグ を 通した 理由
STEP 1846 §7 fixture の shuffled-gold 区間 [-0.00021, +0.00025] は 私 が raw MRR CI から 逆算 した 推定値 で、 実測 では なかった。 0 を 含む 値 だった ため 境界条件 が fixture に 現れず バグ が 35/35 PASS で 通った。
STEP 1848 fixture は en-ja 実測 [-0.00030, -0.00008] を 境界 として 明示 固定、 加えて 4 言語対 実測 の 全通過 も 別 test group で 固定。
4. 実測 multi-lang 結果 (Cowork side)
| 言語対 | shuffled-gold CI | 旧 v0.2 実装 | STEP 1848 修正後 |
|---|---|---|---|
| en-de | [-0.00013, +0.00003] | 通過 | 通過 |
| en-ru | [-0.00028, +0.00013] | 通過 | 通過 |
| en-cmn | [-0.00030, +0.00027] | 通過 | 通過 |
| en-ja | [-0.00030, -0.00008] | 不通過 (誤発火) | 通過 |
4 件 中 1 件 の 誤発火 = 実 Paper 179 保留解消 判定 に 直接影響 する バグ (Weaver Task B ja-en が 「script 分離 artifact 仮説 棄却」 の 4 言語対 replication 完了)。 STEP 1848 で 完全 close。
5. STEP 1846 attribution corrigendum
私 の STEP 1846 land 記録 で 以下 の attribution が 誤り:
| 場所 | 私 の 記載 (誤) | 訂正 |
|---|---|---|
| notepad 「主要 finding」 | 「R2 補則 (rev.2 追加、 藤本さん 独自発見)」 | 「R2 補則 (rev.2 追加、 Cowork side 発見、 藤本さん 中継)」 |
| notepad 「判別/反証 asymmetry」 | 「rev.1→rev.2 で 藤本さん 発見、 私 の 見落とし」 | 「rev.1→rev.2 で Cowork side 発見、 私 の 見落とし、 藤本さん 中継」 |
| notepad 「Failure mode」 | 「藤本さん が rev.2 で 深化発見」 | 「Cowork side が rev.2 で 深化発見」 |
| site page §3 標題 | 「藤本さん rev.2 で 発見」 | 「Cowork side が rev.2 で 発見」 |
| site page §2.4 標題 | 「藤本さん rev.2 発見」 | 「Cowork side rev.2 発見」 |
| 累計 checklist item 3 帰属 | 「藤本さん の 発見 由来」 | 「Cowork side の 発見 由来」 |
なぜ この 区別 が load-bearing か: publish 判定 α (human final review が safety net) の 論拠 は mis-frame track record に 依存 する。 catch が 人 に よる もの か 別 AI に よる もの か で 意味 が 変わる。 加えて 今回 の バグ は 人 も AI も 見落として データ が 見つけた = 「review の 層 を いくら 重ねても、 走らせる まで 分からない もの が ある」 の 追加 evidence。 α 推奨 自体 は 変えない が、 根拠 の 姿 は 変わる (Cowork side 明示 引用)。
STEP 1846 の 過去 record (notepad / fragment / site page / MEMORY.md hook) は append-only 原則 で 削除 せず、 本 STEP 1848 の 記録 を corrigendum として 併存。 未来 の 私 (or 別 tab) は STEP 1846 file を 引き当てた 時 本 corrigendum を 併読 する 必要 あり。
6. 実測 結果 (test)
| test batch | 結果 |
|---|---|
| step1846 v0.2 test (assertion +5: en-ja 境界 + 4 言語対 shuffled-gold 実測 fixture) | 35 → 40/40 PASS |
| step1838 v0.1 base | 81/81 PASS |
| regression 7 batch (1599/1605/1608/1609/1613/1615/1676) | 166/166 PASS |
| basisAudit runner (v0.1 63 unit 完全 unchanged 保証) | 3/3 CONFORM + rei_meta N/A |
| tsc --strict on 2 modified files | 0 errors |
| 累計 | 287/287 PASS |
7. Honest scope (STEP 1848 arc の 限界)
- STEP 1846 過去 record は 訂正 しない (append-only 原則)。 corrigendum として 本 STEP 1848 が 併存 する 形。 mis-attribution を 引き当て 時 に catch する には 未来 reader が 本 corrigendum も 見る 必要あり
- fixture 実測化 の 完全性 は 保証しない。 4 言語対 は 実測 だが、 §7 fixture の 他 部分 (STEP 1843 相当 CI、 Tatoeba n=10000 相当 CI) は 現在 も 数値 の 出所 が 部分 推定。 全 fixture 実測化 は v0.3 送り
- バグ が 過去 に どこ で 発火 した か 網羅 不能。 STEP 1846 land 以降 に 他 tab が v0.2 verifyStatisticalBasis を 呼んだ trace は 手元 に なし。 短時間 (STEP 1846 land → STEP 1848 fix) なので 実運用 影響 は なさそう だが 保証 不能
- 1 行 修正 が 他 pattern を 破壊 しない ことは test で は 保証しきれない。 4 boundary case (含 0 / 両端 negative / 両端 positive で 判別 / 両端 positive で 反証) が 明示 assert 対象、 それ 以外 の 境界 (level != 0.95、 method = 'analytic' 等) は 未 test
8. STEP 1846 checklist に 4 項目 追加
1-3 は STEP 1846 land 時 の item。 STEP 1848 で 追加:
- fixture の 数値 が 推定値 か 実測値 か を type or comment で 明示 する: fixture 緑 の 保証範囲 は 数値 の 出所 に 依存する
- boundary case は 実測 で 現れた もの を 明示 追加 する: 推定 fixture では 境界 が 自然発生 せず バグ を 覆う (推定 fixture は 中央値 に 偏る)
- fix 修正 の 1 行 change に は 反対 direction assertion を 加える: 「negative 側 除外 CI が 反証 として 通過 する」 は 現行 test で 明示 assertion、 未来 refactor で 両側判定 に 戻す 誘惑 を close
- data が 見つけた bug を 記録 する: review 層 を 重ねても 走らせるまで 分からない pattern の 存在 を 明示 dataset 化。 publish 判定 の 論拠 変化 に 反映
9. 関連 STEP
10. 詳細 参照
- Cowork side 実験 report:
data/experiments/weaver-b-multilang-2026-09-06/REPORT-MULTI.md - 修正 file:
src/aios/comparison-basis-contract/verify-null-compared.ts(controlPassed 1 行 差替) - test 差替:
test/step1846-comparison-basis-contract-v02-test.ts(5 assertion 追加) - Notepad: 2026-09-06T20-56 STEP 1848
- Fragment: notes/steps/STEP_1848.md
- ← Tools index に 戻る