feat: シリーズで誰も発行していなかった effect: id を Edge が発行する - #419
Merged
Merged
Conversation
Fabric#15 の effect_contracts は effect: 型 id を鍵にする。シリーズ全体を 実測したところ、**どのリポジトリもそれを発行していなかった。** そのため EffectObservation と OutcomeObservationEnvelope は、どの製品が採用しても 生産者が存在しえなかった。materializer である Azazel-Deception は、 観測する対象を持てなかった(Azazel-Deception#46)。 連鎖の先頭はここに属する。DefensiveEffectRef は authority_class = producer_decision_ref を持ち、Edge の決定論アービタが シリーズ唯一の決定権限である。決定していない製品はそのクラスを名乗れない。 py/azazel_edge/outcome/effect_export.py が、アービタが既に作った ActionExecutionReceipt を横断参照として描画する。決定も選択も強制もしない。 決定論経路はこのモジュールを import しない(テストで固定)。 ## 埋めずに拒否する3件 **lease の無いアクション。** Fabric は expires_at を要求し、Edge の receipt では省略可能である。期限を捏造すれば、Edge が時限を切っていない effect に ついて「切った」と報告するレコードができる。 **ROUTE_CHANGE。** EffectClass に対応する値が無い。この enum は意図的に 小さく、「2製品が同じ effect について話せるように名付ける」ものであって 製品が作れる effect を網羅しない。近い値に寄せれば別の effect を記述する。 **UNKNOWN。** Fabric が未知を observe_only に落とすのは**消費者**が fail-safe になるためである。生産者が同じことをすれば、識別できなかった mechanism について observe_only を**主張**することになる。 ## scope は不透明なハンドルとして渡す Fabric はここに opaque typed ref を要求し、理由も述べている — provider コマンドであってはならず、受信側が作用すべきアドレスであってもならない。 Edge の scope は match フィールドの map なので、その digest を publish する。 map は Edge ローカルに留まり、渡るのは Edge が解決でき受信側が作用できない ハンドルである。 ## effect id は execution を同定し、mechanism を同定しない observed mechanism が後で訂正されたとき id が動けば、それまでに行われた 観測がすべて孤立する。id の入力は decision / action / execution の3つだけで あることを直接固定した。 ## 既存テストの誤検知を1件直した test_nothing_on_the_deterministic_path_imports_this_export_surface は ファイル本文の部分一致で shared_export の importer を探していた。本モジュール が docstring で shared_export を引用した時点で誤検知した。**コメントで壊れる 境界検査は、コメントを消すことで回避される。** import を構文解析する形に 直した。 ## 既存の失敗12件について main 上でも同じ12件が失敗する。**本 PR は1件も増やしていない**(main と branch の FAILED 集合が完全一致することを実測)。原因は bhusa_status.py が gh(GitHub CLI)を subprocess で呼び、未インストール環境で FileNotFoundError が伝播すること。--skip-github フラグは存在するが既定経路が劣化しない。 本 PR の範囲外なので触っていない。 ## 検証 tests/test_outcome_effect_export.py 18 passed tests 全体: 12 failed, 808 passed(12 は上記の既存失敗) | 変異 | 結果 | |---|---| | lease 不在時に期限を捏造 | CAUGHT | | ROUTE_CHANGE を近い class に割り当てる | CAUGHT | | UNKNOWN を observe_only に落とす | CAUGHT (3) | | scope をそのまま載せる | CAUGHT | | effect_id が mechanism を含む | **最初は生存** → 入力3件を直接固定して捕捉 | | 2つの mechanism が同じ class を名乗る | CAUGHT | | authority_class を下げる | CAUGHT | Refs 01rabbit/Azazel-Deception#46, 01rabbit/Azazel-Fabric#49 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SsboPSj6GyJju6mTXwHHjq
01rabbit
marked this pull request as ready for review
September 20, 2026 12:10
01rabbit
added a commit
to 01rabbit/Azazel-Deception
that referenced
this pull request
Sep 20, 2026
F-05。effect_contracts は生産者2つ(Deception の PresentedTerrainRef、 Edge の DefensiveEffectRef)を持ちながら**消費者が0**だった。契約は一度も 読まれておらず、相互運用は未知のままだった。R1c ゲートが問うているのは 「シリアライズできるか」ではなく「受け取った側と食い違わないか」であり、 **最初の読み取りこそが食い違いの表面化する場所**である。 runtime/effect_projection.py が Edge の DefensiveEffectRef を受理し、 それに対する EffectObservation を出す。これは同時に、本 repo が 「生産者が存在しえない」と記録していた穴を塞ぐ: 観測は effect: 型 id を 鍵にするが、シリーズの誰もそれを発行していなかった。Azazel-Edge#419 が 発行するようになった。 ## 拒否は教義であって好みではない AZ-06 は Edge が承認した環境を実体化する。よって: **decision を伴わない effect を拒否する。** advisory_inference は助言、 planned_shadow は検討であって承認ではない。実体化すれば AZ-06 が 「示唆を環境に変える段」になる。まさに持っていない権限である。 **redirection 以外を拒否する。** network_isolation や notify_only の背後に AZ-06 が提示するものは無い。producer_evidence が redirection 機構のみを 受理するのと同じ理由である。 **自分が作った effect を拒否する。** 自分の生産物が指示として戻ってくれば、 authority_class が何であれ、それは自分が決定していることになる。 ## 観測は trace を呼び出し側から受け取らない effect から取る。呼び出し側が trace を名乗れる観測は、無関係なインシデントに 紐付けられる。しかも連鎖検査は通る — 両半分が互いに一致し、他の何とも 一致しないからである。 authority_class も status から導出する。Fabric は live な status に active_materialized を要求し、それ以外では禁止するので、呼び出し側が渡せる 値は「一致するか拒否されるか」しかない。導出すれば、正しい値が1つしかない フィールドが消える。 ## 連鎖検査は到達不能な backstop ではない — 測定した 現在の構成では失敗しえない(trace も effect_ref も effect から読む)。 しかし trace_id を呼び出し側パラメータにする変異を当てると、 **この呼び出しがある状態で11件、無い状態で3件**が失敗する。 8件はこの検査が捕まえている。trace を交渉不能にしているのはこれである。 コメントを測定結果に合わせた。 ## 検証 590 passed, 8 skipped (574 → 590) | 変異 | 結果 | |---|---| | decision を伴わない effect を受け入れる | CAUGHT | | redirection 以外も materialize する | CAUGHT | | 自分が作った effect を受け入れる | CAUGHT | | 観測の trace を呼び出し側から受け取る | CAUGHT (11) | | live でない status に active_materialized を付ける | CAUGHT (4) | | 期限切れの live 観測を許す | CAUGHT | | 観測 id が status と時刻を無視する | CAUGHT | | 連鎖検査を外す | 単独では無変化(上記のとおり構成上失敗しえない) | 役目を終えたガード (test_nothing_in_the_series_mints_an_effect_id_so_observations_are_blocked)は 削除せず、次に重要な不変条件 — AZ-06 の観測が名指す effect に実際に連鎖する こと — へ置き換えた。 Refs 01rabbit/Azazel-Edge#419, 01rabbit/Azazel-Fabric#15 Claude-Session: https://claude.ai/code/session_01SsboPSj6GyJju6mTXwHHjq Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fabric#15 の
effect_contractsはeffect:型 id を鍵にします。シリーズ全体を実測したところ、どのリポジトリもそれを発行していませんでした。そのため
EffectObservationとOutcomeObservationEnvelopeは、どの製品が採用しても生産者が存在しえませんでした。materializer である Azazel-Deception は、観測する対象を持てませんでした(Azazel-Deception#46)。連鎖の先頭はここに属します。
DefensiveEffectRefはauthority_class = producer_decision_refを持ち、Edge の決定論アービタがシリーズ唯一の決定権限です。決定していない製品はそのクラスを名乗れません。py/azazel_edge/outcome/effect_export.pyが、アービタが既に作ったActionExecutionReceiptを横断参照として描画します。決定も選択も強制もしません。決定論経路はこのモジュールを import しません(テストで固定)。埋めずに拒否する3件
expires_atを要求し、Edge の receipt では省略可能。期限を捏造すれば、Edge が時限を切っていない effect について「切った」と報告するレコードができるROUTE_CHANGEEffectClassに対応値なし。この enum は意図的に小さく、「2製品が同じ effect について話せるように名付ける」ものであって網羅しない。近い値に寄せれば別の effect を記述するUNKNOWNobserve_onlyに落とすのは消費者が fail-safe になるため。生産者が同じことをすれば、識別できなかった mechanism についてobserve_onlyを主張することになるscope は不透明なハンドルとして渡す
Fabric はここに opaque typed ref を要求し、理由も述べています — provider コマンドであってはならず、受信側が作用すべきアドレスであってもならない。
Edge の scope は match フィールドの map なので、その digest を publish します。map は Edge ローカルに留まり、渡るのは Edge が解決でき受信側が作用できないハンドルです。
effect id は execution を同定し、mechanism を同定しない
observed mechanism が後で訂正されたとき id が動けば、それまでに行われた観測がすべて孤立します。 id の入力は decision / action / execution の3つだけであることを直接固定しました。
既存テストの誤検知を1件直した
test_nothing_on_the_deterministic_path_imports_this_export_surfaceはファイル本文の部分一致でshared_exportの importer を探していました。本モジュールが docstring でshared_exportを引用した時点で誤検知します。コメントで壊れる境界検査は、コメントを消すことで回避されます。 import を構文解析する形に直しました。
既存の失敗12件について
main上でも同じ12件が失敗します。本 PR は1件も増やしていません(mainと branch の FAILED 集合が完全一致することを実測)。原因は
py/azazel_edge/bhusa_status.pyがgh(GitHub CLI)を subprocess で呼び、未インストール環境でFileNotFoundErrorが伝播することです。--skip-githubフラグは存在しますが既定経路が劣化しません。 本 PR の範囲外なので触っていません。検証
ROUTE_CHANGEを近い class に割り当てるUNKNOWNをobserve_onlyに落とすeffect_idが mechanism を含むauthority_classを下げる生存した変異は、テストの主張が docstring の主張より狭かったためです。「mechanism 引数を変えて比較する」は引数を変えており、receipt のフィールドが id に紛れ込んでも通ります。id の入力が3つだけであることを直接固定して捕捉しました。
🤖 Generated with Claude Code
https://claude.ai/code/session_01SsboPSj6GyJju6mTXwHHjq
Generated by Claude Code