# STEP 1838 — comparison-basis-contract

**Timestamp**: 2026-09-06T16:55 (JST)
**Tab worktree**: main (rei-aios-97 [de6edb])
**Commit**: <commit 後に追記>

## 一行 summary

comparator 全計器の verdict に「何をどの field で突合したか」の宣言を義務づける
契約 10 field + 4 gate を定義し、read-only の conformance 計器を追加。

## 主要 finding / evidence

- 発端は rei-meta の meta_check_coherence 実測。2 source の fingerprint flavour が
  full / partial で異なり、共通 field は record_count ただ 1 つ。verdict は
  整数 1 個の一致判定で出ているが、その事実が返り値に現れない。
- 契約は追認であり選定ではない。実測で 3 計器とも既に G1 を behavior として
  満たしていた: harvest_lag windowCompared=0 → 8 feed 全て N/A / =5 → TRUE、
  plugin_census countedProbes<2 → N/A、freshness generatedAt 欠落 → FLOWING。
- basisAudit 実測: harvest_lag 9/9、plugin_census 4/4、source_freshness 50/50
  いずれも CONFORM。rei_meta_coherence は MCP 応答のため file 巡回対象外で N/A。
- rei-meta payload 手渡し監査では G2 (undetectable[] が空) と
  G3 (latest_id / latest_timestamp が meet 外) が NONCONFORM。
- 反実仮想テスト: 同じ payload で status を coherent にすると G4 も落ちる。
  = remote 未到達のまま coherent を返せる状態にある。
- Tests 79/79 PASS、tsc --strict 0 errors。

## Honest scope

- v0.1 は read-only 診断。計器側 code は一切変更していない。
- 基底は report からの逆算であり計器の自己申告ではない。adapter の解釈が入る。
- G3 は field 名の集合演算のみ。同名 field が同じ意味かは検証していない。
- G3 は basisOrigin='intersection' のときだけ効くため、'declared' を名乗れば
  回避できる抜け道が残る。語彙の正しさは人間 review 依存。
- positiveVerdicts は計器ごとの手動宣言。verdict 語彙が増えたときの更新漏れで
  G1/G4 が素通りする。
- 本 STEP は novelty 主張ではない。2026-09-06 の prior-art audit の結論は
  「descent / Robinson consistency radius / CQA / N-version programming /
  Merkle / RV 4値意味論 に対応物があり、枠組みとしての新規性は無い」。
  産物は仕様の穴 1 つ。

## Failure mode (機械学習用 dataset)

- **What could go wrong**: 計器を新設するとき、対称比較を前提にした gate を
  非対称比較にも一律適用してしまう。実際 v0 初版は G3 を全計器に適用し、
  source_freshness を 42/50 NONCONFORM にした。generatedAt vs 時計は片側に
  同名 field が無いのが正常であり、正常な計器を欠陥として落としていた。
- **Prevention**: 契約を書いたら必ず実データで走らせる。型が通ることと
  正しい判定を出すことは別。今回は実 report 3 本に対する実行で判明した。
- **Recovery**: basisOrigin='intersection' のときだけ G3 を効かせる形に修正し、
  同時に「'declared' を名乗れば回避できる」抜け道を honestScope に明記した。
  gate を緩めるときは、緩めたことと残った穴を必ず書き残す。

## STEP 番号 collision の追加所見 (本 arc 固有)

- 計画時点で STEP 1836 を採ったが、別タブが同日中に STEP 1836
  (comparator-cron mirror centralize、commit b580bf391 / d263ba1a5) を先取り、
  さらに STEP 1837 も docs/notepad/2026-09-06T14-48_STEP-1837_cmix-bpc-unit-corrigendum.md
  で未コミットのまま使用済み。よって本 arc は STEP 1838 に確定。
- 学び: 番号確認は 4 系統 (git log / notes/steps / package.json test script /
  docs/notepad) 全部を見る必要がある。git log だけでは notepad 先行が拾えない。
- rename 対象は 11 箇所 (12 substitution)、うち index.ts L53 と test L100 は
  dogfood assertion (MODULE_INFO.step === 数値) で数値そのものを検査するため、
  片方だけ直すと落ちる load-bearing。

## 詳細参照

- 関連 STEP: STEP 1676 (自己記述契約、本 module の原型)、STEP 1608/1609
  (N/A 語彙と retention gate 最外化)、STEP 1615 (windowCompared)、
  STEP 1783 (plugin_census の class-of-one gate)
- 次段: STEP 1839 = rei-meta-mcp 側を本契約に適合させる (別 repo・Python)
