# STEP 2059 — site-verify-signature.sh v1.1: 2-layer self-test + canary UNKNOWN discipline embed

**Timestamp**: 2026-09-16T00:40 (JST)
**Tab worktree**: main (rei-aios-65)
**Commit**: (to be filled by build)

## 一行 summary

STEP 2058 script の self-test が network coupling で 「script broken vs site down」 区別不能 = chat-Claude structural criticism 認諾、 (a) offline layer (pure `classify_verdict` 8 synthetic fixture、 決定的、 network 不要) + (b) live layer (現行 4 fixture、 network 失敗 = SKIP、 FAIL でない) の 2 層化、 canary UNKNOWN discipline を script header comment に spec 昇格 embed、 offline 8/8 + live 4/4 PASS + SKIP path 独立 verify (unreachable host で 4 SKIP + exit 0)。

## 主要 finding / evidence

- **Structural criticism 認諾**: 「診断器 が 被診断対象 に 結合 = site down で 診断器 も 自己不信」 = rei-aios.org 実 down 対象 抱えている 現状 で 現実問題、 仮定でない。 STEP 2058 の `--self-test` は network 前提 で site 落ちる と 4/4 で なくなる = fatal design flaw。
- **2 層 split 実装**:
  - **`classify_verdict(bytes, sig, canary_bytes)`** pure function 抽出、 no I/O / no network / 決定的、 `verify_url` は delegate。
  - **`--self-test-offline`** 8 synthetic fixture (4 REAL boundary case = pid_tuning/syntax/graph/large + 3 FALLBACK case = sig+bytes match / bytes-only / sig-only + 1 boundary edge = bytes off-by-one shell substitution -1 LF case)、 network 不要、 exit 0/1、 script logic bug 決定的検知。 実測 = 8/8 PASS。
  - **`--self-test-live`** 現行 4 fixture (3 REAL boundary + 1 fabricated fallback)、 fetch failure = SKIP (exit 0 with SKIP verdict)、 FAIL でない = script logic は offline で verified、 live は site 健全性 補完 smoke test。 実測 = site up で 4/4 PASS、 unreachable host で 4 SKIP + exit 0 verify。
  - **`--self-test`** combined = offline first + live、 offline FAIL or live FAIL で exit 1、 offline PASS + live SKIP で exit 0 (「script OK + site 状態 inconclusive」 明示)。
- **Canary UNKNOWN discipline spec 昇格**: STEP 2058 実装 で は 既に canary fetch failure = UNKNOWN return (const 2078 fallback しない)、 但し spec 明記 なし。 STEP 2059 script header comment に "Canary UNKNOWN discipline" section 追加、 「When canary fetch fails, the script MUST return UNKNOWN and MUST NOT fall back to a saved constant」 明文、 未来 「便利のため」 改変 予防。
- **Subshell bug lesson 一般化 (memory hook)**: STEP 2058 の subshell double-value bug は 「grep -c matches=0 で exit 1 → `|| echo 0` fallback fire → sig=\"0\\n0\"」 で REAL page (sig=0) で のみ 発火、 FALLBACK page (sig=3) では 発火しない = **fallback-only fixture で self-test 組んだ場合 完全すり抜け**。 chat-Claude core lesson 反映 = 「self-test は 異常系 fixture だけでなく 正常系 fixture 必須、 外部 tool exit code semantics が 正常系で 反転する pattern (grep -c / diff / test 等) を 使う script は 正常系 fixture が critical」 = STEP 2059 offline layer が 材料化 (REAL 4 case が bug 再現 branch)。
- **実 verify pattern (chat-Claude cross-check evidence 引き継ぎ)**: pid_tuning 3809 / syntax 3919 / graph 4021 / fabricated 2078+sig3 / sim.html 35203+redirect の 5 object を STEP 2058 実測 + STEP 2057 chat-Claude 独立 verify で byte-level 一致 verified、 offline layer は 同 numeric evidence を synthetic fixture に 昇格。

## Honest scope

- **主張しないこと**: offline layer の 8 fixture は 実測 evidence に 基づく synthetic case、 全 possible edge case を 網羅 する 主張 なし (例: `bytes=0`, `sig=負数`, canary=0 で 不定 除算類似 挙動 は fixture に なし、 現実的に emerge しない と 判断)。 live layer が SKIP した場合、 site が 「down」 か 「script が site root を 誤解釈」 か は script 単独 で 区別不能 = 「fetch failure まで」 が UNKNOWN 定義、 site vs script vs network の 三分岐 は operator 判断。
- **測っていない残り**: 308 stub body size は 本 STEP でも 未測 (STEP 2058 と 同、 `-L` 固定 で 実測不能)。 offline fixture は canary_bytes=2078 fix の 単一 canary 値 のみ、 canary が 別 site で 別 byte になる ケース の offline verify なし (v2 candidate で multi-canary fixture 追加余地)。
- **G3 title gate**: 変わらず v2+ candidate (defer)、 v1.1 は G1+G2 のみ で 実運用。
- **前提**: bash 3.2+ / `curl` / `wc` / `grep` / `openssl` (fallback = builtin `$$-$RANDOM`)、 offline layer は curl/openssl 不要 (pure bash + wc)。
- **確認していないこと**: chat-Claude 465 page 全 sweep の median 分布 replicate は defer 継続 (offline fixture 8 case で gate correctness verify は 足りる、 median は gate 判定 と 独立)。 STEP 1608 候補 F との 区別 は script header + spec 双方 で 明記 embed 済 だが 実 code review 時 cite discipline は 未来 audit の 責務 (STEP 2058 と 同 status)。

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

- **What could go wrong 1 (diagnosis / diagnosed 結合 antipattern)**: 診断器 が 被診断対象 の 健全性 を 前提 = 対象 down で 診断器 も 自己不信 に 陥る、 「script broken vs subject down」 区別不能 で 誤 alert 連発。
- **Prevention 1**: 2 層 split (a) pure logic layer (subject 不要、 決定的、 script bug のみ検知) + (b) live layer (subject 依存、 fetch failure = SKIP)、 combined verdict で 「script OK + subject inconclusive」 を 明示 emit。 offline layer は confidence の 主源、 live layer は 補完 smoke。
- **What could go wrong 2 (fallback-only fixture coverage hole)**: 異常系 fixture のみ で self-test 組む、 「正常系 で trigger する failure pattern」 (exit code semantics 反転 の 逆 side bug) が 発火 branch が test 対象 外、 script bug が 「self-test 4/4 PASS」 で silent 通過。
- **Prevention 2**: fixture 選定 discipline = 常に (a) 正常系 + (b) 異常系 + (c) boundary (bytes off-by-one 等) の 全 branch 網羅、 fixture list header に 「REAL 4 case + FALLBACK 3 case + boundary 1 case」 明記、 外部 tool exit semantics 依存 script は 特に 正常系 fixture critical。
- **What could go wrong 3 (canary UNKNOWN 「便利のため」 fallback 改変)**: 未来 修正で canary 失敗時 定数 fallback (const 2078) 追加、 v0-draft FALLBACK_CANONICAL_BYTES 失敗 mode 再導入、 gate が live site から decouple、 drift silent。
- **Prevention 3**: script header comment に "Canary UNKNOWN discipline" section を STEP 2059 で spec 昇格 embed、 未来 code review 時 cite 前提、 「便利のため」 patch を PR 段階で reject 根拠 documented。
- **What could go wrong 4 (offline fixture staleness)**: 実 site の real page min ratio が 1.83 → 1.5 未満 に drift (小さい tool page emerge) or fallback size が 2078 → 別値 に 変化、 offline fixture が 実 site と 乖離、 offline 8/8 PASS でも 実 gate 判定 と 不整合。
- **Prevention 4**: live layer が boundary 3 URL (pid_tuning/syntax/graph) の 実測 を 継続、 実測 値 が fixture と drift したら chat-Claude 465-sweep re-run で fixture 更新 trigger、 或いは boundary fixture URL を dynamic に (script が index sweep で min 3 抽出) は v2 candidate。

## 詳細参照

- **Source**: `scripts/site-verify-signature.sh` (STEP 2059 update、 v1.1、 bash 3.2+、 3 self-test mode)
- **Predecessor**: `docs/notepad/2026-09-16T00-24_STEP-2058_site-verify-signature-script-v1-land.md` (v1 initial land)
- **Spec**: `docs/notepad/2026-09-16T00-08_STEP-2057_signature-spec-v1-canary-revision.md` (v1 spec、 canary method、 STEP 1608 区別、 STEP 2059 canary UNKNOWN discipline 追記 候補 = 別 STEP or 本 fragment cite で 代替)
- **継承**: [[step-2058-site-verify-signature-script-v1-land]] + [[step-2058-subshell-fallback-double-value-bug-pattern]] + [[step-2057-signature-spec-v1-canary-revision]] + [[step-2055-shell-substitution-strips-trailing-lf]] + [[step-1608-candidate-f-withdrawal]]
- **Pending items 更新** (rei-aios-65 tab 実行不能):
  - STEP 2050 page F2 訂正 (rei-aios-19 帰還 or override 待ち) — 継続
  - rei-aios.org DNS 到達不能 root-cause (STEP 1908 §8) — **v1.1 完了 で D candidate 実行 可 に (chat-Claude A → D 順推奨、 script が site down 診断 tool として 併用可、 offline layer で script 側 correctness 独立 verify 可能)**
  - CF Pages routing 独立 audit (F2 起点) — 別 STEP candidate
  - G3 title pattern locale-safe 較正 (v2+ candidate) — defer
  - 465 page 独立 sweep (統計分布 verify) — defer (offline 8 fixture で 足りる)
