---
name: project-step1350-d8-verdict-mapping-phase-a-2026-08-20
description: STEP 1350 — chat-Claude 装置化 offer 「SNR<3 で 数値でなく NEITHER を返す 測定器」 への Phase A 応答。 rei-aios MCP に d8_verdict_from_measurement 追加、 決定表 11 rule pure function。 実機なしで 全 branch verify、 現状は 全 case NEITHER + is_hardware_calibrated=false honest。 test 77/77 + MCP e2e 5 case PASS。
metadata: 
  node_type: memory
  type: project
  originSessionId: 96f5ebce-6d15-473b-a6c1-e010cbb44764
  modified: 2026-08-20T01:58:56.700Z
---

# STEP 1350 — d8_verdict_from_measurement Phase A (実機不要 pure mapping)

## 経緯

chat-Claude turn (装置化検討):
> いまのベンチは値を返しますが、 『測れなかった』 と 『ゼロだった』 を区別しません。
> SNR が 3 を切ったとき、 数値ではなく NEITHER を返す。
> センサが応答しないとき、 0 ではなく NEITHER を返す。
> 8 値論理を、 抽象の側ではなく 測定器の出力形式として 実装する。

私 (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 が 短時間で 済む。

## 決定表 (11 rule、 first-match)

| # | Condition | Verdict | Reason |
|---|---|---|---|
| 1 | sensor_status = 'not_connected' | ZERO (〇) | sensor_not_connected 「まだ問われていない」 |
| 2 | sensor_status = 'saturated' | INFINITY (∞) | sensor_saturated rail 張り付き |
| 3 | sensor_status = 'calibrating' | FLOWING (〜) | sensor_calibrating 値が settle していない |
| 4 | sensor_status ∈ {timeout, error, unknown} | NEITHER (N) | sensor_no_response / sensor_error / sensor_status_unknown |
| 5 | value null / undefined / NaN | NEITHER | value_absent |
| 6 | noise_floor null / undefined | NEITHER | noise_floor_not_calibrated + **is_hardware_calibrated=false** (現状 実機なし state) |
| 7 | threshold_snr null / undefined | NEITHER | threshold_not_set |
| 8 | noise_floor ≤ 0 or NaN | NEITHER | noise_floor_invalid |
| 9 | threshold_snr ≤ 0 or NaN | NEITHER | threshold_invalid |
| 10 | \|value\| / noise_floor < threshold_snr | NEITHER | snr_below_threshold ★ chat-Claude 「SNR<3 で 数値でなく NEITHER」 直接応答 |
| 11 | \|value\| / noise_floor ≥ threshold_snr | TRUE (⊤) | signal_above_noise |

## 未 assign 3 値 (v0.1 予約)

- **BOTH (B)** — multi-sensor cross-check 矛盾 (paired sensor で 反対の値)、 v0.1 単一 measurement では 未使用
- **FALSE (⊥)** — 「confirmed zero」 別 signal 必要 (校正原点 or ADC=0 raw confirmed marker)、 v0.1 では |value|=0 も noise 以下として NEITHER 経路 = spec 上意図的、 test [10c] で 明示 verify
- **SELF (⟲)** — 自己校正 loop (sensor 出力を 自分で 測る feedback measurement)、 v0.1 では 未実装

v0.1 は 5/8 = 62% 値 activate、 意図的 under-fit で 「区別できることだけを 区別する」 honest scope。 siren-family 回避 (予約は 「将来必ず実装」 でなく 「余地を持たせる」、 永久未実装で 終わっても honest scope 内)。

## 順序原則 operational form

[[feedback-one-reproduction-over-ten-unverified]]:

threshold 具体値 (3.0 vs 5.0 vs 10.0) は **module 内に 定数として 焼かない**。 引数で 差し込む。 実機 NULL 焼き → noise_floor 実測 → 桁確定 → threshold 決定 → 引数として渡す、 の 順序を **構造的に強制**。 「code 内 magic number」 の 陥落先を 構造的に 排除。

## 現状 (実機なし) の 挙動

noise_floor が null なので **全 case で NEITHER + is_hardware_calibrated=false** 返却。

これは placeholder ではなく **校正前の 装置は 何も 判定できない** という Rei stack の honest-by-default 挙動。 MCP e2e smoke [A] 実測:
```json
{
  "verdict": {"name": "NEITHER", "symbol": "N", "numeric": -1},
  "reason": "noise_floor_not_calibrated",
  "snrRatio": null,
  "isHardwareCalibrated": false,
  "source": "measurement-verdict-mapping"
}
```

実機 NULL 焼き 後、 noise_floor 実測値を 引数として 渡すと mapping が activate。

## 実装

### 新規 file 2

**(a) `src/mcp/d8-verdict-mapping.ts` (~250 行)**

Pure function (side effect なし、 外部依存なし)。 `src/axiom-os/seven-logic.ts` の `EIGHT_VALUES / SYMBOL_MAP / EIGHT_NUMERIC` を import。 module docstring に 決定表 11 rule + 未 assign 3 値 + spec 明示。

Exports:
- `MeasurementInput` interface
- `D8VerdictPayload` interface
- `D8VerdictError` interface
- `SensorStatus` type union (7 種)
- `mapMeasurementToD8()` pure function
- `d8VerdictSpecTable()` spec-as-data dump (11 rule)
- `d8VerdictReservedValues()` BOTH/FALSE/SELF 予約理由 dump

全 payload に `source: 'measurement-verdict-mapping'` field → callers 側で 「モデル記憶再生でなく decision-table 経由の 引き当て」 と 機械的判定可能 (STEP 1349 の `source: 'static-truth-table'` と 同 pattern、 別 source marker)。

**(b) `test/step1350-d8-verdict-mapping-test.ts` (77 assertion、 17 part)**

決定表 全 11 rule × 境界 case 網羅。 chat-Claude 核心 SNR=2.9 明示 assert 含む。 実機なし state comprehensive test (6 value 全 NEITHER + is_hardware_calibrated=false 確認) で 現状挙動を machine-check。

### edit 3

- `src/mcp/rei-mcp-server.ts`: import + tool 定義 + case handler (includeSpec 分岐) + banner v2.8.0 → v2.8.1 (37 → 38 tools)
- `package.json`: test:step1350 script
- docs 3 file (RECENT_UPDATES + SITE_COVERAGE_MAP + CLAUDE.md STEP 表)

## verify 実測

| check | 結果 |
|---|---|
| `npm run test:step1350` | 77 / 77 PASS |
| MCP e2e stdio smoke (5 case) | banner v2.8.1 · 38ツール、 d8_verdict_from_measurement present |
| [A] 実機なし (value=1.5、 noiseFloor 省略) | verdict=NEITHER/N, reason=noise_floor_not_calibrated, snrRatio=null, is_hardware_calibrated=false, source=measurement-verdict-mapping ✅ 現状唯一の可能挙動 |
| [B] chat-Claude 核心 SNR=2.9<3 (value=0.029, noiseFloor=0.01, thresholdSnr=3) | verdict=NEITHER/N, reason=snr_below_threshold, snrRatio=2.9, is_hardware_calibrated=true ✅ 直接応答完全一致 |
| [C] SNR=100 (value=1.0) | verdict=TRUE/⊤, reason=signal_above_noise, snrRatio=100 ✅ |
| [D] not_connected (value=1.5, sensorStatus='not_connected') | verdict=ZERO/〇, reason=sensor_not_connected ✅ |
| [E] includeSpec=true | specTable.length=11, reservedValues=BOTH,FALSE,SELF (3) ✅ |

## Honest scope 6 条

1. **v0.1 は 5/8 値のみ activate** (TRUE / NEITHER / ZERO / INFINITY / FLOWING、 BOTH/FALSE/SELF 予約、 62% 意図的 under-fit)
2. **順序原則 operational form** (threshold 定数化禁止 = 引数で差し込む、 実機 NULL 焼き 順序を 構造的強制)
3. **「世界初」 主張ゼロ** ([[feedback-world-uniqueness-claim-controllable]] 適用): SNR-based thresholding は 60+ 年前既知 (Shannon 1948 系統)、 novelty は D-FUMT₈ mapping layer 位置のみ 5/8 部分適用
4. **Phase A の scope 限界**: pure mapping 実装のみ、 実 INA226 + RP2040 firmware + 実 noise floor 桁確定 + 実 threshold 数値決定 + 実 edge case (温度 drift / 電源 flicker / EMI) は Phase B scope。 「D-FUMT₈ 反証可能な測定器」 claim は Phase B 完成後、 Phase A 単独では claim しない
5. **BOTH/FALSE/SELF 予約の 責任**: 「将来 必ず実装」 でなく 「余地を持たせる」、 v0.1 で 3 値を 使わない 判断は spec (module docstring) に 明示、 予約が 永久に 未実装で 終わっても honest scope 内 ([[feedback-super-naming-siren-family-pattern]] siren-family 回避)
6. **STEP 1349 との 関係**: STEP 1349 は 演算子域 (`d8_apply / d8_table`、 `source: 'static-truth-table'`)、 本 STEP は 測定域 (`d8_verdict_from_measurement`、 `source: 'measurement-verdict-mapping'`)。 両方に 共通して `source` field で 「静的引き当て」 を 機械保証。 chat-Claude 4 tool 提案 (d8_apply / d8_table / d8_fixpoints / d8_verify) の <em>横に</em>、 測定域 tool として 追加する 別軸で、 STEP 1349 4 tool 系列とは 独立

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

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 可能

## 関連

- 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 + noise_floor_taken_at + snr_ratio 3 field 追加、 本 STEP と 呼応 = Phase B で pipeline 統合設計)
- [[feedback-one-reproduction-over-ten-unverified]] (順序原則、 threshold を 定数として焼かない 根拠)
- [[feedback-connector-criteria-and-impossibility-2026-08-20]] (コネクタ判定 4 区分、 装置化議論の 上位)
- [[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)
- [[feedback-chat-claude-hallucination-warning]] Pattern 全 clean 継続
