YONAPO RESEARCH
研究記録
MedDSL(仮称)

RESEARCH / RECORD

P2-r:記録に観察者を足す(中核モデルの変更の伝播)の実装と内部評価

原文 docs/research/75-p2-r-results.md

17 KB

GitHubで見る

版 be280c0

この文書の目次 7項目

作成日:2026-10-21。状態:期間つき数量(P2-i)の記録に任意の項目 observer を足し、依存する5拡張を再固定・採用して、両 Python 版の全体回帰を通過。版の記録と履歴の検査を追加。設計73・手指定期待74 に従いました(利用者の承認:2026-10-21「進んでいいよ」。観察者は任意の項目)。73・74 の「未実装」という記載は設計時点の記録として保持します。独立確認・評価用正解の凍結は未実施で、independent_review / evaluation_frozen は false のままです。数値・識別子はすべて架空です。外部資料は新たに参照していません。

1. 行ったこと

項目 内容
P2-i(draft-3) temporal_measurement.py と 仕様:記録に任意の observer(`{kind: human
P2-o(draft-2) 操作 record・correct の任意の observer を台帳へ渡し、選択の根拠に、あるときだけ record_observer。確認の操作は持たない
P2-q(draft-2) 観察者または AI 由来のとき、生成の Provenance を出す(device の観察者は Device、人の観察者の型は宣言 provenance.observer_type、なければ依頼 declare_observer_type)。流れに observer を保持/失うものとして追加
再固定のみ P2-j(draft-3)、P2-m・P2-p(draft-2)。再固定の道具 repin_specs.py で6つの仕様の hash と6つのモジュールの定数が更新され、実行例は生成器で再生成(手編集なし)
実行例 P2-i に O 系列11 JSON(1,757必須パス)、P2-o に6 JSON(2,527)、P2-q に8 JSON(1,446)。計25件の新しい入力
宣言 義務を3つ足した(TM-13・CL-13・QR-12)。6宣言の版と依存の版を更新
検査 P2-i・P2-o・P2-q に各1テスト(観察者の全数と hash への算入、受け渡し、型を推測しない)、変異7件、別計算(P2-q)の更新、版の記録の履歴の検査9テスト(test_observer_version.py)
版の記録 p2-temporal-measurement-draft-2-to-draft-3.json(p2-version-record-draft-2)。生成は make_observer_version_record.py。比較器 regenerated_mismatches を1行一般化した(追加した入力を added_unit だけでなく、宣言した変更の added_inputs 全般から読む)

旧版は、変更前のコミット dc0aabe(P2-q の追加後)として履歴に残ります。新版の実装は 4963f91、版の記録は 3e74796(記録は自身を含む木のコミットを指せないため、別のコミット)。

2. 予測の結果(設計73の Y1〜Y10)

ID 予測 結果
Y1 旧版は旧コミットの木で再現できる 成立。dc0aabe の木で統合評価が合格し、23宣言・313義務・495防護例、manifest 89cb715d…・束 7b13731a… を再現
Y2 旧入力を新版へそのまま渡すと、P2-i の仕様を pin する系列(6系列)の入力は全て profile_spec_mismatch で拒否され、それ以外は同一。黙った再解釈 0 一部成立。黙った再解釈は 0 で、拒否は678件。ただし、同一が59件あった(pin に届く前に拒否される静的な負例など。予測は「全て拒否」)。比べたのは6系列の旧入力737件
Y3 再生成した入力は、hash の値を除いて旧入力と同一。結果も同一(観察者のない旧入力は record_observer を出さないので) 成立。要求が変わった入力 0、期待が変わった入力 0、結果の差 0、料金が変わった入力 0。違いは追加した25件だけ(旧737件、新762件)
Y4 新版で追加した項目を使う入力を旧版の木へ渡すと、旧版は黙って無視せず拒否する 成立。25件全てで、新しい pin のままなら profile_spec_mismatch、旧い pin に替えても invalid_input(未知の項目)。ok は0
Y5 affected() は6拡張を過不足なく列挙する。regenerate は生成器・宣言・索引・台帳を列挙しない(過小) 一部成立。6拡張は過不足なし。過小は予測と完全に一致(宣言6件とモジュール3件〔temporal_display.py・longitudinal.py・observation_projection.py〕。生成器は含まれなかった)。ただし過大が予測外で118件(列挙したが再固定は要らなかった実体。P2-f の例81件を含む。宣言の embedded_in が pin ごとでなく宣言ごとにあるため)
Y6 旧版との差分は750〜800ファイル わずかに外れ。813ファイル(上限を13超過)。新しい実行例・検査・文書を含む。P2-l(単位表2行の改訂)は739
Y7 観察者の有無・値で確認の内容の hash が変わる。観察者のない記録の hash は、仕様の hash の変更だけで変わる 成立。観察者(なし・human・device)で記録の hash は3通りに分かれ、独立に計算した値と一致。観察者のない旧入力は、再生成した要求と hash の値を除いて同一(上の Y3)
Y8 観察者が分かる記録は生成の Provenance を出せる。分からなければ出さない。人の観察者で型の宣言がなければ依頼 成立。観察者(3)×出自(2)×型の宣言(5)×Provenance の宣言(2)の60通りの全数が別計算と一致
Y9 版の記録の書式を変えずに、この更新を宣言できる 成立(比較器に1行の一般化)。書式 p2-version-record-draft-2 と宣言の種類 added_field・repinned で宣言できた。比較器が追加した入力を added_unit の宣言からだけ読んでいたため、読み方を一般化した(書式は不変)
Y10 登録時の防護例の評価が、仕様の hash を期待値に持つ防護例を壊す 外れ。壊れた防護例は0。防護例は観察者のない入力の値を期待していて、hash を持たなかった(P2-l と違い、今回の防護例は改訂の影響を受けなかった)

3. 反例の結果(設計73の Z1〜Z8)

ID 内容 結果
Z1 確認の後に観察者を書き換えた記録 review_record_hash_mismatch(P2-i の O05。P2-i の全数テストでも確認)
Z2 不正な observer P2-i の符号で拒否(invalid_observer・expected_nonempty_string・missing_field・unknown_field・expected_object)。P2-o は P2-i の符号をそのまま返す
Z3 確認の操作に observer unknown_field(P2-o の N03-observer-confirm)
Z4 訂正が観察者を持たない 選ばれた訂正の record_observer は出ない(元の観察者を継がない。P2-i の O04、P2-o の O72)
Z5 人の観察者で型の宣言がない 推測せず依頼 declare_observer_type(P2-q の Q21)
Z6 AI 由来の記録に観察者 生成の Provenance の agent は AI(Device)と観察者の2件(Q23)
Z7 Provenance を宣言せずに観察者がある記録 Provenance は出ず、observer は失うものに残る(Q24)
Z8 旧い pin の入力 新版は profile_spec_mismatch で拒否

4. 分かったこと

  1. 任意の項目の追加は、意味の局所性と、ファイルの規模が別物であることを示した。 意味が変わる入力は新しい25件だけで、旧入力737件の結果は変わらない(hash の値を除く)。一方、書き換わったファイルは813件で、P2-l の単位表2行の改訂(739件)より多い。hash が固定する依存の木が大きくなったため(F5 の続き)。
  2. 観察者を hash 付きの記録の内容にすると、確認と観察者が結ばれる。 観察者を確認の後に変えると、確認は無効になる。記録の hash は仕様の hash を含むので、仕様を改訂すると全ての確認が無効になる(旧い確認は新版へ引き継がない、という既存の規則のとおり)。
  3. 記録モデルの穴は直った。 観察者が分かる記録は、生成の Provenance を出せる。分からない記録は、これまでどおり出せない(F23 の続き:観察者を持たない記録は、依然として存在し得る)。
  4. 意味の変更の宣言は、書式を変えずに書けた。 宣言の種類 added_field は、P0 の draft-2 の更新(P2-d)の先例で足りた。ただし、比較器は追加した入力の読み方を一般化する必要があった。

新しい発見

ID 発見 根拠 限界
F27 操作の列から台帳を組み立てる系列の入力は、hash を持たないので、仕様の hash の置換だけで再固定できる。 P2-o・P2-p・P2-q の入力(3系列)は、置換した入力が新版でそのまま受理される。台帳を直接持つ P2-i・P2-j・P2-m の入力は、確認が拘束する内容の hash を持つので、置換では受理されない。「医療者の操作は hash を扱わない」という設計(CL-2)が、版の更新で再固定の費用を下げた 比較器の置換の測定(substituted)。履歴の検査 3系列は生成器でも再生成した(同じ結果)。置換で足りることは、入力の形に依る
F28 affected() の列挙は過小と過大を同時に持つ。 過小は予測どおり9件(宣言とモジュール)。過大は118件で、列挙は再固定が要る範囲より広い。宣言の embedded_in が pin ごとでなく宣言ごとにあるので、ある pin に無関係な実体も列挙に入る 版の記録の測定値(listed_but_unnecessary=118、unpredicted_repin=9) 過大は安全側(余分に再検証する)。過小は危険側
F29 履歴を取り出して比較する検査は、リポジトリが進むと古い前提を持ち越す。 契約の更新(P2-n)の検査が、旧コミットの宣言と現在の宣言が「宣言した項目だけ違う」ことを求めていたが、後の版の更新(P2-r)で版・依存・仕様が変わり、検査を「その後に版を上げた3件は版に関する項目だけ違う」に緩める必要があった test_the_new_declarations_differ_from_the_old_only_in_the_declared_fields の失敗 履歴に結んだ検査は、後続の変更を例外として手で足す必要がある
F30 旧入力の59件は、pin に届く前に結果が決まる。 静的な負例など、仕様の hash を持たない入力は、版の更新で同じ結果になる。版の更新の影響を受ける入力の数は、入力の総数でなく、pin を持つ入力の数 版の記録の測定値(同一59、拒否678) 分類は比較器による

実装の最中に直した誤り

  • 実装の誤り:0件。25件の手指定の期待は、すべて初回に満たされた。
  • 検査側の調整:(1)版の記録の作成で、「置換では再固定できない」という検査(R1)が、hash を持たない3系列で成り立たなかった。純粋な pin の系列として宣言し直した(F27。期待の更新でなく、入力の形の観察)。(2)Y2 の「全て拒否」は、実測で拒否678・同一59だった。テストを実測の性質(黙った再解釈 0、拒否が9割超)に直し、予測の外れを上の表に残した。(3)P2-n の契約の検査(F29)。(4)観察者を足したことで乱数の列が変わったが、差分の検査は同じ性質を検査する。

5. 検査の強さ

  • 観察者:P2-i の全数(観察者 なし/human/device × 訂正の鎖の2記録、記録の hash が3通り)、不正な観察者9種、確認の後の書き換え。P2-o の受け渡しの全数(9通り)。P2-q の60通り。いずれも別計算または独立な計算と比べた。
  • 変異:7件を追加(観察者の種類の検査の削除、record_observer を出さない、台帳へ渡さない、根拠に出さない、型を推測する、観察者の agent を落とす、観察者の流れを報告しない)。全件検出。
  • 版の手順:V1〜V8 を履歴の検査9テストで確認した(旧版の再現、旧入力の分類、再生成した入力の比較、前方の互換、置換の限界、列挙と実測、費用)。
  • 比較器の変異:G01〜G14 を再実行(比較器を1行変えたため)。全件検出、対照 Z0 は失敗0。
  • 検査器の既存の変異:検査器の共通部品の added の読み方の変更だけで、未完了行の検査(B系列)は変えていない。

6. 検証

Python 3.14.4 と 3.11.17 で、全テスト系列と統合評価を実行しました。

系列 件数 Python 3.14.4 Python 3.11.17
開発 231 通過 通過
追加レビュー系列 52 通過 通過
保存監査 8 通過 通過
P2 444(P2-qの432に、観察者のテスト3と版の履歴の検査9を追加。履歴の検査9件は版の記録を追加するまで実行されない) 通過 通過
統合評価 P1/P0・拡張・全P2・予算・版比較(2記録)。版の記録を加えた後の履歴の検査も通過 通過 通過
P1-d の CLI 照合・保存監査・登録検査 P1 20条件・80 JSON・417必須パス、別枠 P0 の37 JSON・221必須パス、監査600+256+32+1 通過 通過
統合評価の対象 P2-r 追加後の分母
登録・義務・防護例 23宣言・316義務・498防護例参照(P2-qの313・495から、3義務と防護例3を追加)。宣言の数は変わらない
証拠の強さ checked_native_template 200、finite_check 108、hand_derivation 8
独立な拡張の組 192/231(変更なし)
実行例の系列 P2-i 162 JSON・1,757必須パス(+11)、P2-o 147・2,527(+6)、P2-q 83・1,446(+8)。他は変更なし
予算 1,446要求・掃引31,113回、違反0(P2-qは1,421要求・30,579回)。掃引の回数は実測で、予測ではない

予測した分母(義務・防護例・要求の数)は、実行の前に手で導いた値が全て一致しました(掃引の回数だけは実測)。旧い22,052件の挙動 digest と、生成器による全例・宣言のバイト一致も通過しました。固定対象に、設計73・期待74・版の記録・検査・道具を加えました。作成者 snapshot で、independent_review / evaluation_frozen は false です。

  • 新 native 仕様 hash(先頭8桁):P2-i 168e9f87…(draft-2 は 5f5c1388…)、P2-j d1673a14…、P2-m 8e84f905…、P2-o bb87cc22…、P2-p 3f8527fb…、P2-q 422285b0…。数量の仕様 f52ea526… は変更なし
  • 追加前(dc0aabe、P2-qの追加後):1,702ファイル、manifest 89cb715d…、束 7b13731a…
  • 追加後:実装の木(4963f91)は1,731ファイル、manifest b1da2c3e…、束 f54792d8…。版の記録を加えた木(3e74796)は1,732ファイル、manifest 4aa13b97…、束 4861a082…(この文書の追加で固定対象は変わらない)

7. 限界と次

  • 観察者は2種(human・device)の任意の項目だけです(その後 P2-s で必須にし、不明は明示の unknown にしました:78)。同一性の管理(同じ人かの照合、資格)、履歴は扱いません。訂正は元の観察者を継ぎません。
  • 観察者のない記録は、これからも存在します。 生成の Provenance は出せず、observer は失うものに残ります。
  • 版の手順は、1つの更新(任意の項目の追加)の実演です。項目を必須にする更新、項目の意味の変更、削除は試していません。
  • 比較は有限の旧入力(737件)に基づき、旧入力が行使しない新版の変更(観察者)は旧入力の比較では見えません。一般の保存の証明ではありません。
  • 設計者・実装者・検査の作成者が同一で、独立確認はありません。
  • 次の候補は、項目を必須にする更新(旧入力を拒否する版の更新)、revision の entity と activity の符号、CPC の版の監査です。着手前に利用者の確認を取ります。独立確認は将来の英語の別リポジトリで行います。

P2-r

同じ区分の文書