作成日:2026-10-21。状態:宣言の書式を p2-extension-manifest-draft-2 に上げ、inherits を必須の項目にして、20宣言を再宣言し、両 Python 版の全体回帰を通過。利用者の指示(2026-10-21「継承を宣言する欄(H8)を契約に足す」)に従い、設計59・手指定期待60 を実装の前に固定しました。両文書の「未変更」という記載は設計時点の記録として保持します。独立確認・評価用正解の凍結は未実施で、運用方針29 に従います。外部資料・患者情報・実データは使っていません。
1. 行ったこと
| 項目 | 内容 |
|---|---|
| 契約の書式 | extensions.py:MANIFEST_SCHEMA を draft-2 に、inherits を必須の項目(from・fragment・obligation・witnesses、証人がなければ witness_gap)に。書式の検査 _check_inherits、登録の規則(元の解決、証人の所有と評価)、登録の順(継承の元を先に) |
| 列挙・独立 | affected():元の拡張が影響を受けたら、継承する側を理由 inherits:… で列挙(依存と同じ反復で推移)。independent_pairs():継承の辺を、依存・読み取りと同じく結合として扱う |
| 再宣言 | 20宣言を draft-2 に。inherits の表は gen_extension_manifests.py の一箇所にまとめた。項目は9、証人は30、理由つきの欠落は2 |
| 版の比較の道具 | p2_checks.py:木の宣言と registry を、その木の実装で扱う(tree_affected)。作業ツリーの registry に旧い宣言を渡さない |
| 疑いの探索 | inheritance_suspects.py:二つの拡張だけが共有する識別子らしい文字列定数による疑い。登録の条件ではなく測定の道具 |
| 検査 | test_inheritance.py 36テスト(書式・解決・証人・列挙・独立・順序・元の断片の変更・疑いの探索・契約の版)。契約の検査は、前提の拡張の一覧を宣言(依存と継承)から求める形に変更 |
| 変異 | registry の変異表に19件(X55〜X73)を足し、X30 を新しい伝播に合わせて更新(表は72件) |
| 統合評価 | 継承の項目・証人・欠落を分母に追加(9・30・2)。独立な拡張の組は150から143 |
変更しなかったもの:拡張の実装モジュール、native 仕様、旧実行例。src/med_dsl で変えたのは registry(extensions.py)だけ。
2. 予測の結果(設計59の N1〜N9)
| ID | 予測 | 結果 |
|---|---|---|
| N1 | 変更は registry・宣言・検査・道具に限り、拡張の実装・仕様・旧実行例は変えない | 成立。src/med_dsl の変更は extensions.py のみ。examples/ の変更は固定対象の台帳のみ |
| N2 | 手で挙げた8件が見つかり、予測外が1件以上見つかる | 成立(ただし予測外は探索で見つかった)。8件は全て宣言できた。予測外は1件:P2-f(数量)← P1(有限予測)。P2-f は設計で「予測の検証関数を流用しない」と書くが、有理数の入力の形(invalid_rational)と63bit上限(rational_integer_limit)の理由名と規則を再び述べている。設計文書の「と同じ」の検索では挙がらず、疑いの探索で見つけた。宣言の強制は、探索なしでは、この1件を挙げなかった |
| N3 | 8件のうち6件に既存の例の組で証人が付き、2件は理由つきの欠落。証人は計26 | 成立。証人のある6件・26証人、欠落2件(#4 P2-k ← P2-e、#8 P2-g ← P2-e)。予測外の1件に4証人が付き、合計は9項目・30証人・欠落2。証人にした30組は、入力の構造が断片について等しい例どうしを出力を見る前に選んだもので、登録時に全て一致した(最初の登録で1件の食い違いが出たのは、予測外の1件の証人の位置を私が誤って書いたため。inheritance_witness_unresolved で検出され、位置を直した) |
| N4 | measurement.py の変更は5件、temporal.py は1件から7件、display.py は2件、temporal_measurement.py と quantity.py は変化なし |
成立(予測外が1つ)。5つの列挙は予測と完全に一致。予測外:forecast.py(P1)の変更が、1件から7件(予測、P2-f、P2-f に依存する5件)に広がった。これは予測外の継承による。既存の5つの検査の期待を、宣言から手で導いた値に更新した |
| N5 | 独立な組は150から144 | 一部成立。予測した6組は全て独立でなくなった。予測外の継承の1組が加わり、143。減る組は全て、依存・読み取りで結ばれていなかった組 |
| N6 | 元の断片の変更は、元の防護例に捕まらず証人が捕まえるものと、証人も捕まえず差分の検査だけが捕まえるものがある | 成立(§4 E1。d4 の個別の予測は外れた) |
| N7 | draft-2 にすると版の比較の道具が失敗し、木ごとの registry で直る | 成立。修正前:QuantityVersionTests.setUpClass が Refused: unsupported_manifest_schema@schema_version; missing_field@inherits で失敗(作業ツリーの registry が旧い木の宣言を拒否)。修正後:P2-l の記録の検証を含む55テストが通る |
| N8 | 疑いの探索は、宣言した継承の半数以上を見つけるが、適合率は半数未満 | 一部成立。共通の語彙も数える最初の版は104/150組を疑い、適合率は約0.05(予測どおり)。そこから私が調整した版(二つの拡張だけが持つ定数)は、再現率5/7(0.71)、適合率5/6(0.83)で、適合率の予測は外れた。調整は既知の継承を見た後で行ったので、未知の継承の検出力の見積りではない(§4 E2) |
| N9 | 宣言の差は schema_version と inherits だけ |
成立。直前のコミット 3c16f68 の20宣言との差が、20件とも宣言した2項目のみ |
3. 反例の結果(設計59の X1〜X7)
| ID | 結果 |
|---|---|
| X1 | 欠落は missing_field、draft-1 は unsupported_manifest_schema、形の不正は invalid_inherits/invalid_inheritance。旧い20宣言は全て新しい registry に拒否された |
| X2 | 自己(self_inheritance)、未登録(unresolved_inheritance)、重複(duplicate_inheritance)、相互の継承は解決できず拒否。同じ元でも断片が違えば別の項目として登録される |
| X3 | inheritance_obligation_missing、inheritance_obligation_without_checks |
| X4 | inheritance_witness_mismatch、inheritance_witness_unresolved、witness_example_not_owned、missing_witness_example、invalid_witness。registry が評価の関数を持たないとき、証人は評価されない(防護例と同じ) |
| X5 | unexplained_witness_gap(理由なし・空の理由)、witness_gap_with_witnesses。空の inherits は登録される |
| X6 | §4 E1 |
| X7 | 継承がないのに宣言した場合の検査は書けない(限界)。証人の一致は断片の一致の証拠で、継承の真偽の証明ではない |
4. 実験
E1 元の断片の変更(N6)
P2-g の matched_context の判定(measurement.py の _assess)を、断片の中で一つずつ壊した木で、全宣言を登録し直し、P2-m と P2-g の差分の検査(324対)を実行しました。
| 壊し方 | 元の登録 | 継承する側の登録 | 差分の検査 |
|---|---|---|---|
d1 different_method を出さない |
拒否(防護例) | 解決できず拒否 | 失敗 |
d2 different_specimen を出さない |
登録される | 証人が拒否 | 失敗 |
d3 different_property を出さない |
登録される | 証人が拒否 | 失敗 |
| d4 specimen/method の ref だけを比べ、version を見ない | 拒否(防護例) | 解決できず拒否 | 失敗 |
d5 different_subject を出さない(断片の外) |
登録される | 影響なし | 一致(対照) |
| d6 最初の差だけを出す | 登録される | 登録される | 失敗(差分の検査だけが捕まえる) |
P2-m の段階では、これらはいずれも差分の検査(テスト)だけが捕まえていました。継承を宣言すると、d2・d3 は登録の時点で捕まります。d6(複数の差が同時にあるとき)は、証人が単一の差の例しか持たないので、証人でも元の防護例でも捕まらず、全数の差分の検査だけが捕まえます(証人は差分の検査の代わりにならない)。予測では d4 を「元は登録され、証人が捕まえる」としましたが、P2-g の防護例が version の比較を覆っていて、外れました。
E2 疑いの探索(N8)
| 版 | 疑いの組 | 宣言した継承の組に対する再現率 | 適合率 |
|---|---|---|---|
| 共通の語彙も数える(3定数以上) | 104 / 150 | 5/7 | 約0.05 |
| 二つの拡張だけが共有する定数(2以上) | 6 / 150 | 5/7(0.71) | 5/6(0.83) |
見つけた5組は、P2-m ← P2-g、P2-j ← P2-h、P2-i ← P2-g、P2-k ← P2-e、P2-f ← P1(予測外)。偽の疑い1組は P2-m と P2-j で、同じ親(P2-i)を呼ぶための語彙の共有でした。見逃した2組は P2-i ← P2-e(期間の分類)と P2-g ← P2-e(可視性)で、語彙が違う、または定数にならない規則です。2番目の版は、既知の継承を見た後で調整したので、適合率の高さは未知の継承の検出力の見積りではありません。
E3 契約の版の更新(N7・N9)
draft-1 → draft-2 を、版の手順(旧版を履歴から再現し、旧入力は黙って再解釈されず、差は宣言した変更だけ)で検証しました。旧い宣言20件は全て新しい registry に拒否され(旧入力を黙って再解釈しない)、新しい宣言との差は宣言した2項目だけ、旧い木の列挙はその木の registry で行えて(measurement.py の変更で2件。新しい registry では5件)、P2-l の記録の検証が再び通ります。
5. 分かったこと
- 継承は宣言に書けて、半分は登録時に確かめられる。 9項目のうち7項目に、既存の例だけで証人が付いた(30証人)。欠落の2項目は、構造的に等しい例の組がないという理由が宣言に残る。
- 欄を必須にしただけでは、書かれなかった継承は出てこない。 予測外の1件を見つけたのは疑いの探索で、設計文書の読み直しではない。探索は、語彙の共有というヒューリスティックで、見逃しもある(7組のうち2組)。未宣言の継承を機械的に排除する手段はない。
- 証人は単一の差を覆うが、組み合わせを覆わない。 d6 のように、断片の中の相互作用(複数の差が同時にある)の変更は、証人にも元の防護例にも捕まらず、全数の差分の検査だけが捕まえた。登録時の証人は、差分の検査の代わりではなく、早い警告である。
- 継承の辺は、再検証の範囲を広げる。 P2-e の
temporal.pyの変更が列挙する拡張は1件から7件に、P1 の予測の変更は1件から7件になった。これは過大ではなく、これまで見えなかった結合を表す。一方、独立な組は150から143に減り、「独立」の意味が、構造の独立から、構造と意味の独立に変わった。 - 契約の版が変わると、版の道具は旧い木を旧い実装で扱う必要がある。 作業ツリーの registry に旧い木の宣言を渡す道具は、書式の更新で失敗した。P2-d の V2(旧版は旧版の契約で再現)の原則は、版の比較の道具自体にも要る。
- 手で保つ一覧がまた一つ見つかった。 契約の検査が、拡張ごとの前提の拡張を手で書いた一覧で保っていた。継承を足すと、その一覧が35件の誤りになった。宣言の依存と継承から求める形に直した(F4・F6 に続く三つ目の、一覧を内容から求める修正)。
- 偽りの宣言は検査できない。 証人が一致することは、再述の存在を示さない。継承がないのに宣言すること、継承があるのに宣言しないことは、機械的には排除できない。
6. 検査の強さ
- 登録側の変異:継承の規則に対する19件(X55〜X73)と、更新した X30 の計20件を、
test_inheritanceとtest_extension_contractを実行して全て検出(最小の検出は1テストの失敗)。 - 元の断片の変更:E1 の6通り(§4)。
- 書式・解決・証人:X1〜X5 の拒否の全コードを、同梱の宣言を書き換えて確認。拒否は全か無かで、登録の状態は変わらない。
- 列挙・独立の規則:人工の木で、元から継承する側へ(逆は及ばない)、推移、依存との併記、継承の辺による結合を確認。
7. 検証
Python 3.14.4 と 3.11.17 で、全テスト系列と統合評価を実行しました。最初の実行では、P2 系列で1件が失敗しました(統合評価の集計テストが使う模擬の報告に、新しい分母 inherits の欄がなかった。実装の誤りではなく、テストの更新漏れ)。直して固定対象を更新し、両 Python 版を最初からやり直した結果が次です。
| 系列 | 件数 | Python 3.14.4 | Python 3.11.17 |
|---|---|---|---|
| 開発 | 231 | 通過 | 通過 |
| 追加レビュー系列 | 52 | 通過 | 通過 |
| 保存監査 | 8 | 通過 | 通過 |
| P2 | 387(P2-mの351に、継承36を追加) | 通過 | 通過 |
| 統合評価 | P1/P0・拡張・全P2・予算・版比較(2記録) | 通過 | 通過 |
| P1-d の CLI 照合・保存監査・登録検査 | P1 20条件・80 JSON・417必須パス、別枠 P0 の37 JSON・221必須パス、監査600+256+32+1、登録20・拒否0 | 通過 | 通過 |
| 統合評価の対象 | P2-n 追加後の分母 |
|---|---|
| 登録・義務・防護例 | 20宣言・259義務・441防護例参照(P2-mから変更なし) |
| 継承(新しい分母) | 9項目・証人30・理由つきの欠落2 |
| 独立な拡張の組 | 143/171(P2-mは150/171) |
| 実行例・予算 | 変更なし:P2系列の例と必須パス、1,111要求・掃引20,909回、違反0 |
旧い22,052件の挙動 digest と、生成器による全例・宣言のバイト一致も通過しました(宣言は新しい書式で再生成して一致)。固定対象に、設計59・期待60・継承の検査・探索の道具を加えました。作成者 snapshot で、independent_review / evaluation_frozen は false です。
- 追加前(
3c16f68、P2-mの追加後):1,355ファイル、manifestcbf877d0…、束fcd90770… - 追加後:1,359ファイル、manifest
4b4d4f81…、束527725eb… - 変更したファイル:既存49、新規5。内訳は、宣言20と索引、registry 1、版の比較の道具・統合評価・宣言の生成器・変異表の道具、検査4、固定対象の台帳と監査、文書8。実装モジュール・仕様・旧実行例の変更は0
8. 限界と次
- 証人は、既存の例の組が構造的に等しいことを、私が入力から選んだものです。選び方に誤りがあれば、一致しない(今回は30組が一致)か、一致しても意味のない一致になり得ます。
- 継承の関係は一種類(断片での観測の一致)です。差を伴う継承(精密化の追加)や、同じ拡張の版の間の継承(P2-l の VR-1)は、この欄の対象外です。
- 宣言した9項目は、私が設計文書と探索で挙げた範囲です。20宣言のうち14宣言は
inherits: [](継承なし)を明示していますが、これは私の判断であり、独立の確認はありません。 - 設計者・実装者・検査の作成者が同一で、独立確認はありません。
- 次の候補は、複数の出力先への射影(C7)、実資料評価と薄い臨床ライブラリの試作範囲の選定、継承の関係の拡張(差を伴う継承、版の間の継承)です。着手前に利用者の確認を取ります。独立確認は将来の英語の別リポジトリで行います。