comparison-basis contract v0.1 — 比較基底の 横断契約 + conformance 計器
comparator 全計器を 横断する 「verdict が どの source の どの field を 突合して 出たか、 その 基底で 何が 見えないか」 を 機械可読に 宣言させる 契約 10 field + 4 gate を 定義し、 適合を 検査する read-only 計器を 追加。 STEP 1609 で harvest_lag に 入れた retention gate 最外化 を 比較基底に 一般化した もの。
1. なぜ この 契約 が 必要だった か
発端は rei-meta-mcp meta_check_coherence("seed_kernel") の 実測 payload:
- 2 source (
rei-memory-localfull flavour vsrei-aios-local-mcppartial flavour) の fingerprint が 異なる structure - 共通 field は
record_count1 つ のみ - verdict は 整数 1 個の 一致判定で 出ているが、 その 事実が 返り値に 現れない
- 片側にしか 存在しない field (latest_id / latest_timestamp) を diff として 報告 = 「差」 ではなく 「欠測」
- 1 source が unreachable でも、 reachable な 2 source が 一致 すれば
coherentを 返し得る (§4 「UNCHECKED は coherent ではない」 の 機械可読 漏れ)
この pattern は harvest_lag / plugin_census / source_freshness にも 同型に 存在しうるので、 1 計器の bug fix ではなく 横断契約に 昇格 させる。
2. 契約 10 field
| field | 意味 | 例 (harvest_lag) |
|---|---|---|
gauge | 計器 ID | "harvest_lag" |
unit | この 基底が 属する 単位 | "arxiv-math.LO" |
sourcesDeclared | 宣言 された 全 source | ["internal", "oracle"] |
sourcesCompared | 実際に 比較に 参加した source | ["internal", "oracle"] |
uncheckedSources | 宣言 されたが 未 到達 | [] |
availableFields | source 別 の 出せる field | {"internal": ["id","publishedAt"], "oracle": ["id","publishedAt"]} |
comparedFields | 実際に 突合した field (= meet) | ["id", "publishedAt"] |
basisOrigin | 基底の 由来 | "intersection" |
separatingPower | 分離力 5 値 順序尺度 | "identity-set" |
undetectable | 基底で 見えない divergence class | ["lag older than compared window is invisible", ...] |
+ verdict field (計器の 出した 判定値、 上記 10 field と 分けて 保持)。
3. 4 gate — verdict と 基底の 関係を 縛る
G1basis gate outermost — comparedFields 空 または separatingPower=none なら 肯定的 verdict 禁止。 「基底が 空なのに 一致している」 と 言わせない。 STEP 1609 の retention gate 最外化 と 同じ 位置づけ (他の どの 条件より 先に 効く)。
G2power honesty — separatingPower < content なら undetectable[] に 1 件以上 必須。 「弱い基底で 見ている」 ことを 読者が 読み取れる ように 強制。
G3meet consistency — comparedFields ⊆ ⋂ availableFields[compared source]。 片側にしか 無い field を diff として 報告するのを 拒む。 basisOrigin='intersection' の ときだけ 効く (非対称比較 'declared' は 通す)。
G4unchecked accounting — uncheckedSources 非空なら 肯定的 verdict 禁止。 rei-meta §4 「UNCHECKED は coherent ではない」 の 機械可読版。
4. SeparatingPower — 分離力 の 順序尺度
none < scalar < multi-scalar < identity-set < content
none: 比較 field が 無い (基底 空)scalar:record_countの みで 判定multi-scalar: 複数 scalar (例:record_count + latest_timestamp)identity-set: id 集合レベルで 一致検証 (record 追加/削除は 検出、 内容変更は 検出不能)content: 全 record の 内容 hash まで 一致検証
5. 実測 basis-audit 結果
npm run comparator:basis-audit による 実測:
| 計器 | unit 数 | verdict | 備考 |
|---|---|---|---|
harvest_lag | 9/9 | CONFORM | windowCompared=0 の 8 feed は 既に N/A (G1 追認) |
plugin_census | 4/4 | CONFORM | countedProbes<2 の class は 既に N/A (G1 追認) |
source_freshness | 50/50 | CONFORM | generatedAt 欠落 は 既に FLOWING (G1 追認) |
rei_meta_coherence | — | N/A (out-of-band) | MCP 応答なので runner の file 巡回 対象外 |
契約は 追認 であり 新規選定 ではない。 file 由来 3 計器は 既に G1 を behavior として 満たしていた ことを 実測で 確認。
6. rei_meta_coherence — 契約 未適合の 実測
唯一 NONCONFORM の 計器。 auditCoherencePayload(payload) による payload 手渡し 監査:
G1-basis-gate: CONFORM — basis non-empty (3 field(s), power=scalar) G2-power-honesty: NONCONFORM — separatingPower=scalar (< content) but undetectable[] is empty G3-meet-consistency: NONCONFORM — 2 compared field(s) outside the meet: latest_id (absent in: rei-memory-local); latest_timestamp (absent in: rei-aios-local-mcp) G4-unchecked-accounting: CONFORM — 1 unchecked source(s) and verdict "divergent" does not assert agreement
反実仮想: 同 payload で status を coherent に すると G4 も 落ちる — remote 未到達のまま coherent を 返せる 状態が 存在。
修正は 別 arc: STEP 1840 で rei-meta-mcp 側を 契約に 適合させた。
7. 成果物
src/aios/comparison-basis-contract/— types / verify / adapters / enumerate / index (5 module)scripts/comparator/run-basis-audit.ts— file 由来 3 計器の 巡回 runnertest/step1838-comparison-basis-contract-test.ts— 79 assertion (STEP 1840 で 81 に 拡張)data/comparator/basis-audit-latest.json— 巡回 出力- STEP 1676 self-description-contract dogfood 適合 (本 module も 8 field 契約に 適合)
Tests: 79/79 PASS + regression 166/166 + tsc --strict 0 errors。
8. Honest scope
- v0.1 は read-only 診断。 計器側 code は 一切 変更していない (診断と fix は 別 arc)。
- 基底は report からの 逆算 であり 計器の 自己申告 では ない。 adapter の 解釈が 入る = false negative 可能。
- G3 は field 名の 集合演算のみ。 同名 field が 同じ 意味か は 検証していない。
- G3 は
basisOrigin='intersection'のとき だけ 効く ので、'declared'を 名乗れば 回避できる (抜け道、 人間 review 依存)。 - G2 は
undetectable[]が 空でない ことだけを 見る。 中身の 妥当性は 人間 review。 positiveVerdictsは 計器ごとの 手動宣言。 verdict 語彙が 増えた ときの 更新漏れで G1/G4 が 素通りする。
9. Novelty 主張なし — Prior-art audit
2026-09-06 prior-art audit の 結論: 「descent / Robinson consistency radius / CQA / N-version programming / Merkle / RV 4値 semantics に 対応物が あり、 枠組みとしての 新規性は 無い」。 6 系統を 突き合わせた 結果、 rei-meta の 乖離検出 に 新理論と 呼べる 差分は 無く、 産物は 仕様の 穴 1 つ (verdict が 比較基底を 宣言しない ため coherent が 「全一致」 と 読まれる) の 昇格 のみ。
10. 関連 STEP
- STEP 1840 — rei-meta-mcp 側を 本契約に 適合 (次 arc、 rei-aios adapter + fixture 追随 込み)
- STEP 1676 — self-description contract (本 module の 原型、 dogfood 対象)
- STEP 1608 / 1609 — N/A 語彙 と retention gate 最外化 (G1 の 起源)
- STEP 1615 — windowCompared field 導入 (harvest_lag G1 の 実装例)
- STEP 1783 — plugin_census の class-of-one gate (G1 の 実装例)
11. STEP 番号 由来
当初 STEP 1836 で 計画したが、 同日中に 別タブが STEP 1836 (comparator-cron mirror centralize) + STEP 1837 (cmix bpc corrigendum、 docs/notepad 先取り) を 使用済と判明したため STEP 1838 に corrigendum rename。 学び: 番号は commit で 確定 する もので、 計画時点の 予約 では ない。 4 系統 check (git log / notes/steps / package.json / docs/notepad) が 全て 必須。
12. 詳細 参照
- Notepad: 2026-09-06T16-55 STEP 1838
- Fragment: notes/steps/STEP_1838.md
- Commit: ff00ec57c
- ← Tools index に 戻る