STEP 1350Phase A 実機不要 chat-Claude 2026-08-20 「NEITHER を物理的に出力する測定器」 → Phase A / Phase B 分割 → Phase A 完成

d8_verdict_from_measurement — 測定入力 → D-FUMT₈ 8 値 verdict pure mapping

2026-08-20 chat-Claude turn 「いまのベンチは値を返しますが、 『測れなかった』 と 『ゼロだった』 を区別しません。 SNR が 3 を切ったとき、 数値ではなく NEITHER を返す。 センサが応答しないとき、 0 ではなく NEITHER を返す。 8 値論理を、 抽象の側ではなく 測定器の出力形式として 実装する」 offer への operational 応答。 Phase A (pure mapping、 実機不要、 本 STEP) + Phase B (threshold 実測校正 + firmware flash、 実機必要、 別 STEP) の 分割で、 実機なしで 出来る全てを 先に完了。 藤本伸樹 × Claude Code / rei-aios STEP 1350

1. 経緯 (Phase A / Phase B 分割 の 判断)

chat-Claude turn (装置化検討) で 「NEITHER を 物理的に出力する 測定器」 の 提案 = INA226 + RP2040 で firmware 出力層を 「SNR<3 で 数値でなく NEITHER」 「sensor 無応答で 0 でなく NEITHER」 に 書き換える 装置構想。

私 (Claude Code) の 前 turn 応答は 「実機なしでは進められない」 と 過剰に区切っていた → 藤本さん 「上記は実機が無いとダメなのでしょうか?」 で 訂正。 実機必要な部分は 少ない (threshold 数値校正 + firmware flash + 実世界 edge case)、 実機不要な部分は 多い (pure mapping 関数 + 境界 case 網羅テスト + spec 表 + MCP tool wire)。

分割: Phase A (本 STEP、 実機不要) = pure mapping 関数 + spec 表 + test 77/77 + MCP tool。 Phase B (別 STEP、 実機必要) = threshold 実測校正 + RP2040 firmware flash + 実世界 edge case 観測。 Phase A が固まっていれば、 実機が来た時 threshold 引数に 実測値を 差し込むだけで Phase B が 短時間で 済む。

2. 決定表 (11 rule、 first-match priority)

#ConditionVerdictReason
1sensor_status = 'not_connected' ZEROsensor_not_connected 「まだ問われていない」
2sensor_status = 'saturated' INFINITYsensor_saturated rail 張り付き、 評価不能
3sensor_status = 'calibrating' FLOWINGsensor_calibrating 値が settle していない
4sensor_status ∈ {timeout, error, unknown}N NEITHERsensor_no_response / sensor_error / sensor_status_unknown
5value is null / undefined / NaNN NEITHERvalue_absent
6noise_floor is null / undefinedN NEITHERnoise_floor_not_calibrated + is_hardware_calibrated=false (現状 = 実機なし state)
7threshold_snr is null / undefinedN NEITHERthreshold_not_set
8noise_floor ≤ 0 or NaNN NEITHERnoise_floor_invalid
9threshold_snr ≤ 0 or NaNN NEITHERthreshold_invalid
10|value| / noise_floor < threshold_snrN NEITHERsnr_below_threshold ★ chat-Claude 「SNR<3 で 数値でなく NEITHER」 直接応答
11|value| / noise_floor ≥ threshold_snr TRUEsignal_above_noise 信号あり
★ 未 assign 3 値 (v0.1 予約、 別 STEP candidate):
  • BOTH (B) — multi-sensor cross-check 矛盾 (paired sensor で 反対の値)、 v0.1 単一 measurement では 未使用
  • FALSE (⊥) — 「confirmed zero」 別 signal 必要 (校正原点 / ADC=0 raw confirmed marker)、 v0.1 では |value|=0 も noise 以下として NEITHER 経路 (spec 上 意図的、 [10c] test で 明示 verify)
  • SELF (⟲) — 自己校正 loop (sensor 出力を 自分で 測る feedback measurement)、 v0.1 では 未実装

3. 現状 (実機なし state) の 挙動

noise_floor が null なので 全 case で NEITHER + is_hardware_calibrated=false 返却。 これは placeholder ではなく 校正前の 装置は 何も 判定できない という Rei stack の honest-by-default 挙動 = MCP e2e smoke [A] 実測 verdict=NEITHER/N, reason=noise_floor_not_calibrated, snrRatio=null, is_hardware_calibrated=false。 実機 NULL 焼き 後、 noise_floor 実測値を 引数として 渡すと mapping が activate。

本 module 内に threshold の 具体値 (3.0 vs 5.0 vs 10.0) を 定数として 焼かない。 引数で 差し込む。 これは 順序原則 (feedback_one_reproduction_over_ten_unverified.md) の operational form: 実機 NULL 焼き → noise_floor 実測 → 桁確定 → その 桁を根拠に threshold 決定 → 引数として 渡す、 の 順序を 構造的に 強制。

4. 実装内容

新規 file 2

  • src/mcp/d8-verdict-mapping.ts (~250 行、 pure function、 side effect なし、 外部依存なし)
    • Module docstring に 決定表 11 rule + 未 assign 3 値 + spec 明示
    • MeasurementInput + D8VerdictPayload + D8VerdictError interfaces
    • mapMeasurementToD8() pure function (11 rule first-match evaluation、 source: 'measurement-verdict-mapping' 全 payload に含める = 「モデル記憶再生でない」 機械保証)
    • d8VerdictSpecTable() spec-as-data dump (11 rule)
    • d8VerdictReservedValues() BOTH/FALSE/SELF 予約理由 dump
  • test/step1350-d8-verdict-mapping-test.ts (77 assertion、 17 part)
    • [1]-[4d] Rule 1-4 sensor_status 全 branch (ZERO / INFINITY / FLOWING / NEITHER × 4 sub-case + 未知 string normalize)
    • [5a-c] Rule 5 value null / undefined / NaN
    • [6][6b] Rule 6 noise_floor_not_calibrated (現状 実機なし state confirm)
    • [7]-[9b] Rule 7-9 threshold / noise_floor invalid
    • [10a-c] Rule 10 SNRchat-Claude 核心 example SNR=2.9<3 + value=0 は FALSE 予約継承で NEITHER
    • [11a-c] Rule 11 SNR≥threshold (境界一致 + 高 SNR + 負値 abs-value spec)
    • [12][13] Priority chain (sensor_status wins + rule 5-9 order)
    • [14] invalid input path
    • [15] spec table + reserved values exports
    • [16] source marker 全 case で 'measurement-verdict-mapping' 確認
    • [17] 実機なし comprehensive: 6 value 値で 全 NEITHER + is_hardware_calibrated=false

edit

  • src/mcp/rei-mcp-server.ts: import + tool 定義 + case handler + banner v2.8.0 → v2.8.1 (38ツール)
  • package.json: test:step1350 script

5. verify 実測

check手段結果
unit testnpm run test:step135077 / 77 PASS
MCP e2e stdio smokeinitialize + tools/list + tools/call × 5banner v2.8.1 · 38ツール、 d8_verdict_from_measurement present
[A] 実機なし statevalue=1.5、 noiseFloor 省略verdict=NEITHER/N, reason=noise_floor_not_calibrated, snrRatio=null, is_hardware_calibrated=false ✅ 現状 唯一 の 可能挙動
[B] chat-Claude 核心 SNR=2.9<3value=0.029, noiseFloor=0.01, thresholdSnr=3verdict=NEITHER/N, reason=snr_below_threshold, snrRatio=2.9, is_hardware_calibrated=true ✅ chat-Claude 直接応答完全一致
[C] SNR=100value=1.0, noiseFloor=0.01, thresholdSnr=3verdict=TRUE/⊤, reason=signal_above_noise, snrRatio=100
[D] not_connectedvalue=1.5, sensorStatus='not_connected'verdict=ZERO/〇, reason=sensor_not_connected
[E] includeSpec=truespec dump 動作specTable.length=11, reservedValues=BOTH,FALSE,SELF (3)
chat-Claude 核心 assertion 満たしている点: 全 payload に source: 'measurement-verdict-mapping' field を含む → callers 側で 「モデル記憶再生でなく decision-table 経由の 引き当て」 と 機械的判定可能。 STEP 1349 の d8_apply / d8_table と 同じ 「静的引き当て」 pattern を 測定域に 拡張。

6. Honest scope

(1) v0.1 の scope: EIGHT_VALUES の 5 値 (TRUE / NEITHER / ZERO / INFINITY / FLOWING) のみ activate。 BOTH / FALSE / SELF は 予約。 これは v0.1 の 段階では 5/8 = 62% の 値 coverage、 意図的な under-fit で 「区別できることだけを 区別する」 honest scope。
(2) 順序原則 (feedback_one_reproduction_over_ten_unverified) の operational form: threshold の 具体値 (3.0 vs 5.0 vs 10.0) は 本 module 内に 定数として 焼かない。 引数で 差し込む。 実機 NULL 焼き → noise_floor 実測 → 桁確定 → threshold 決定 → 引数として 渡す、 の 順序を 構造的に 強制。
(3) 「世界初」 主張ゼロ ([[feedback-world-uniqueness-claim-controllable]] 適用): SNR-based thresholding は 60+ 年前既知 (Shannon 1948 系統)、 3 段階 verdict (signal / noise / undecidable) も 標準 SNR analysis の変種。 novelty は Rei stack 内 「D-FUMT₈ 8 値表現に mapping する」 layer 位置のみ、 それも 現時点 5/8 部分適用。
(4) Phase A の scope 限界: 本 STEP は pure mapping の 実装のみ、 実際に (a) INA226 で 電流測定、 (b) RP2040 firmware で 出力層置換、 (c) 実世界 noise floor 桁確定、 (d) 実 threshold 数値決定、 (e) 実 edge case (温度 drift / 電源 flicker / EMI) は 全て Phase B の scope 外。 chat-Claude turn の 「D-FUMT₈ の主張を反証可能にする 経路」 は Phase B 完了 後に 初めて claim できる、 Phase A 単独では 反証性を claim しない。
(5) BOTH / FALSE / SELF 予約の 責任: 未 assign 3 値 の 予約は 「将来 実装する 約束」 ではなく 「将来 判定基準が 明確化した時 に 追加余地を 持たせる」 の 意味。 v0.1 で 3 値を 使わない 判断は spec (module docstring) に 明示、 予約が 永久に 未実装で 終わっても honest scope 内 (siren-family 回避 [[feedback-super-naming-siren-family-pattern]])。
(6) STEP 1349 との 関係: STEP 1349 (d8_apply / d8_table) は D-FUMT₈ 演算子表の 引き当て、 本 STEP は D-FUMT₈ 値への mapping で 出力域が異なる (演算子 vs 測定)。 両方に 共通して source field で 「静的引き当て」 を 機械保証、 STEP 1349 は 'static-truth-table'、 STEP 1350 は 'measurement-verdict-mapping' で 区別。 chat-Claude 4 tool 提案 (d8_apply / d8_table / d8_fixpoints / d8_verify) の 横に、 測定域 tool として 追加する 別軸で、 STEP 1349 4 tool 系列とは 独立。

7. Phase B (別 STEP candidate、 実機必要)

  1. threshold 数値校正: 実機 NULL 焼き → noise floor 実測値の 桁確定 → SNR threshold の 具体値 (3.0 / 5.0 / 10.0 のどれか) を 経験分布で 決定
  2. RP2040 firmware 出力層置換: 現行 firmware の 数値出力を D-FUMT₈ 8 値 verdict に 差し替え、 本 module の 決定表を C/C++ に 移植 (Rule 1-11 の branch 実装)
  3. 実世界 edge case 観測: 温度 drift / 電源 flicker / EMI / connector 接触不良 / 校正 aging、 これらを sensor_status の 追加 case として 拡張、 v0.2 で FALSE (confirmed zero) 経路も 検討
  4. BOTH 活用 (multi-sensor cross-check): paired INA226 で 電流を 独立 2 sensor 測定、 差が noise 内なら TRUE、 差が noise 以上なら BOTH (矛盾 marker)、 これで v0.2 は 6/8 値活用へ
  5. 「反証可能な測定器」 claim: chat-Claude 「D-FUMT₈ の主張を反証可能にする経路として、 電力差分測定とは別筋の一本」 は Phase B 完成後 に 実 measurement 経由で claim 可能、 現段階では claim しない

8. 関連

  • [[project-step1350-d8-verdict-mapping-phase-a-2026-08-20]] (本 STEP memory)
  • STEP 1349 (D-FUMT₈ operator connectors、 同 layer 兄弟 STEP)
  • STEP 1345 (benchtop-mcp v0.5 SafetyGate、 測定器 domain の 相補 layer)
  • STEP 1348 (benchtop-mcp v0.6 physics-limits、 pre-flight pipeline の 上流)
  • ba00ca1 (benchtop-mcp ProvenanceRecord に noise_floor_mW 等 3 field 追加、 本 STEP と 呼応)
  • [[feedback-one-reproduction-over-ten-unverified]] (順序原則、 threshold を 定数として焼かない 根拠)
  • [[feedback-connector-criteria-and-impossibility-2026-08-20]] (コネクタ判定 3 区分、 装置化議論の 上位)
  • [[feedback-super-naming-siren-family-pattern]] (BOTH/FALSE/SELF 予約は 果たせない約束にしない)
  • [[feedback-world-uniqueness-claim-controllable]]
  • [[feedback-no-rush-publication]]
  • [[feedback-all-research-site-reflection-default]] (2026-08-06 protocol 適用継続)