Skip to content

architecture: Edge と Fabric の語彙乖離を機械的に検出する (#379 #390) - #417

Merged
01rabbit merged 1 commit into
mainfrom
claude/zealous-edison-k5vt5j
Sep 20, 2026
Merged

01rabbit merged 1 commit into
mainfrom
claude/zealous-edison-k5vt5j

Conversation

@01rabbit

Copy link
Copy Markdown
Owner

Refs #379, #390

穴

前回 #416 は Edge 自身の語彙をリテラルで固定した。しかし Fabric との一致はどこでも検査していなかった。

Fabric が6つ目の値を得ても、値を改名しても、Edge は緑のまま系全体の正典から乖離しうる。単一定義であることが Azazel#62 の全目的であり、その乖離こそ防ぐべきものである。

Edge が自前の DEFENSIVE_STATES を持つのは誤りではない

本日 Knowledge と Deception から語彙のコピーを排除したが、Edge は同じ話ではない。

役割 コピーの意味
Knowledge / Deception 助言側の consumer 所有していない語の第二の定義。裏口から製品語が正典になる
Edge 状態を生成する権威 生成者自身の定義。アービタは Fabric 不在でも動作しなければならない

決定論的制御経路が任意パッケージに依存しないという既存の姿勢(audit/fabric_adapter.py、fabric_view.py)と同一である。

よって依存は増やさない。 モジュール先頭で import もしない。Fabric が語彙を運んでいるときにだけ、両者の完全一致を要求する。

スキップする guard は guard していない

pytest.importorskip は正しい挙動だが、そのままでは requirements/fabric.txt を古いタグに戻すだけで guard が無言で停止する。何も知らせない。

よってピンファイル自体を検査するテストを併設した。戻す行為そのものが赤くなる。

インストール済み配布物ではなくツリーの宣言を読む — ローカル環境は陳腐化しうるが、CI がインストールする元であり、レビュアーが読むのはツリーである。

比較はタプルで行う。文字列比較では v0.10.0 が v0.9.0 より古いと判定される。前方互換であることは変異試験で確認した。

Fabric pin v0.9.0rc1 → v0.9.0rc2

Edge の CI は requirements/fabric.txt をインストールするため、この bump によって上記 guard が実際に CI で走るようになる。bump 前はスキップされ、何も守っていなかった。v0.9.0rc2 は rc1 に対し加算的・非破壊。

検証

763 passed, 4 skipped

変異試験9件:

変異 結果
Edge が6つ目の値を得る 赤
Edge が値を改名する 赤
Edge が値を落とす 赤
ピンを rc1 に戻す 赤
ピンを v0.8.0 に戻す 赤
ピンを branch に緩める 赤
ピンを v0.9.0 最終版へ進める 緑(前方互換)
ピンを v0.10.0 へ進める 緑(前方互換)

テスト除外について(事実として記録)

当環境では bhusa 系4ファイル12件が失敗するため除外して実行した。本変更とは無関係である。

原因は直接実行で特定済み — py/azazel_edge/bhusa_status.py が gh CLI を subprocess 起動しており、当環境に gh が存在しない(FileNotFoundError: [Errno 2] ... 'gh')。GitHub ホストランナーには gh が存在するため、main の CI は bhusa 込みで緑であることを実行 ID で確認した(run 455、8af1ac0、conclusion success)。

挙動は変えていない

requirements/fabric.txt の1行とテストファイルのみの変更。アービタが何を決めるかには一切触れていない。#379 の「live enforcement semantics を黙って変えてはならない」に従う。

🤖 Generated with Claude Code

https://claude.ai/code/session_01SsboPSj6GyJju6mTXwHHjq


Generated by Claude Code

前回 (#416) は Edge 自身の語彙をリテラルで固定したが、**Fabric との一致は
どこでも検査していなかった**。Fabric が6つ目の値を得ても、値を改名しても、
Edge は緑のまま系全体の正典から乖離しうる。単一定義であることが
Azazel#62 の全目的であり、その乖離こそ防ぐべきものである。

## Edge が自前の DEFENSIVE_STATES を持つのは誤りではない

Knowledge / Deception が語彙を写すのとは性質が異なる。両者は助言側の
consumer であり、コピーは「所有していない語の第二の定義」になる。
Edge は状態を**生成する権威**であり、そのアービタは azazel_fabric が
一切インストールされていなくても動作しなければならない。決定論的制御経路が
任意パッケージに依存しない、という既存の姿勢 (audit/fabric_adapter.py,
fabric_view.py) と同一である。

したがって依存は増やさない。モジュール先頭で import もしない。
**Fabric が語彙を運んでいるときにだけ**両者の完全一致を要求する。

## スキップする guard は guard していない

pytest.importorskip は正しい挙動だが、そのままでは
requirements/fabric.txt を古いタグに戻すだけで guard が無言で停止する。
何も知らせない。

よってピンファイル自体を検査するテストを併設した。戻す行為そのものが
赤くなる。インストール済み配布物ではなくツリーの宣言を読む —
ローカル環境は陳腐化しうるが、CI がインストールする元であり
レビュアーが読むのはツリーである。

比較はタプルで行う。文字列比較では v0.10.0 が v0.9.0 より古いと判定される。
前方互換であることを変異試験で確認した (v0.9.0 最終版・v0.10.0 はいずれも緑)。

## Fabric pin v0.9.0rc1 -> v0.9.0rc2

Edge の CI は requirements/fabric.txt をインストールするため、この bump に
よって上記 guard が実際に CI で走るようになる。bump 前はスキップされ、
何も守っていなかった。v0.9.0rc2 は rc1 に対し加算的・非破壊。

## 検証

763 passed, 4 skipped(当環境で `gh` CLI 未導入のため bhusa 系4ファイルを
除外。原因を直接実行で特定済みで本変更とは無関係。main の CI は
bhusa 込みで緑であることを確認した)。

変異試験9件:
- Edge が6つ目の値を得る / 値を改名する / 値を落とす -> いずれも赤
- ピンを rc1 / v0.8.0 に戻す / branch に緩める -> いずれも赤
- ピンを v0.9.0 最終版 / v0.10.0 に進める -> 緑(前方互換)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SsboPSj6GyJju6mTXwHHjq
@01rabbit
01rabbit marked this pull request as ready for review September 20, 2026 00:57
@01rabbit
01rabbit merged commit 0045501 into main Sep 20, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants