コードは
グラフである。
AOA は Python フレームワークであり、業務操作をアーキテクチャ全体の芯に据える。操作は自分で宣言する — 誰に実行する権利があり、何に依存し、失敗したとき何が起きるかを。操作の一覧からグラフが組み上がり、それが自分自身を検査して、基盤が業務ロジックに混ざるのを許さない。違反は起動時に捕まる。三週間後の本番でではなく。
pip install aoa-action-machine01 — 概要
アーキテクチャはコードの中に生きる。
頭の中でも、文書の中でもなく。
システムを滅ぼすのはバグではない。時が経つにつれ誰にも分からなくなることだ。人が入れ替わり、複雑さが増していくうちに。私たちはコードの書き方を、パターンの使い方を、作法の守り方を教わる — だが複雑さの扱い方も、一年後、二年後、五年後にシステムを読めるまま保つ方法も教わらない。「ここで何が起きているのか」を解きほぐす一分は、前へ進むために使えたはずの一分だ。
AOA は別の道を取る。アーキテクチャとシステムについての知識を、頭の中や古びていく文書から、コードへ移す — 機械が読める意図として。実行でき、検査でき、観測できるものとして。
まずモデル、それからコード。
Entity と、その関係と、そのライフサイクルを、混じりけのないドメインモデルとして宣言する — ORM にも特定のデータベースにも縛られずに。モデル全体の整合性は起動時に検査される。
モデルを設計する →一つのクラスに、操作のすべて。
ロール、手順、補償、エラー、キャッシュ、依存が一か所に宣言される。入口に Params、出口に Result、そのあいだに脇口は一つもない。
Action X-Ray。
デバッガの可視性をアーキテクチャに埋め込む。操作の進み具合と各ステップの状態は、本番でも online で観測できる — プロセスを止めずに。
Action X-Ray を開く ↗依存ではなく、ヘキサゴナルの口。
@depends / @connection / @context_requires は Action の口を宣言する — アダプタは外から挿す。box.resolve(T) が渡すのは宣言されたものだけだ。
コードではなく、世界を差し替える。
本物のパイプラインが手を加えられないまま走る — ただし差し替えられた世界の上で。ユーザーも、モックも、コンテキストも。ここを通ったものが、そのまま本番で動く。
02 — Maxitor
上のグラフは本物だ。
これが、それを描く道具である。
どの Domain も、ロールも、依存も、インポートの瞬間にノードになる — 同じ一つの動いているシステムの、四つの異なる見え方。そのすべてが手を加えていない書き出しだ。
03 — できること
パイプラインだけではない。
同じ一つの宣言されたグラフが、キャッシュも、業務イベントも、observability も、エージェントのフレームワークも動かす — つなぎのコードを一行も書かずに。
それらを走らせる機械。
どの Action も一つの機械が動かす。ロールも、キャッシュも、イベントも、巻き戻しも、その仕事だ。
宣言されたキャッシュ。
cache_key はまっすぐ結果へ導く。外れたときはアスペクトが走り、on_cache_write が値を残す。
イベントは事実であって、ログの一行ではない。
box.info(Channel.business, …) は型のついた事実を生む — Maxitor も、OCEL も、ダッシュボードもそれを読む。
Observer は割り込めない。
observer をすべて外しても振る舞いは変わらない。テレメトリは願いではなく保証だ。
エラーが集まる場所は一つ。
パイプラインの末尾にある唯一のハンドラが、失敗のあと操作が何を返すかを決める。
Saga は自分で巻き戻る。
失敗は終わった手順を逆順にほどく。巻き戻しはその手順のすぐ隣に宣言されている。
まず RBAC。その先に、深まる ABAC。
check_roles は純粋な RBAC — そのロールがあるか。grant.when / guard= は呼び出し単位の軽い ABAC。access_decide() は本格的な ABAC — 対象と事実で判断する。
Domain と Role がシステムの地図になる。
Domain は操作の組み立て点だ — グラフも、アクセス表も、可視化も。Role は継承を通して権限を運ぶ。二つ合わせて、その表そのものになる。
04 — 拡張
核は小さい。
まわりはそうではない。
同じ宣言されたグラフが、操作を外の世界へつなぐ。エージェントのフレームワーク、キュー、画面、observability へ。核は育たない — 育つのはそのまわりだ。
LangGraph の中の、型のついたノード。
LangGraphController は Action をエージェントのグラフへ埋め込む — 同じ契約、同じ巻き戻し。
一つの Action。どんな入口でも。
HTTP のルートも AI ツールの呼び出しも、同じ保証を持つ同じ一つの操作だ。
OCEL/OCPM — 図ではなく、本物の過程。
どの実行もすでに lifecycle events を出している。プロセスマイニングはそこから本物の過程と、関わった Entity を見る — 一度描かれたきりの図ではなく。
OTel — 同じイベントを、トレースとして。
Action X-Ray の online な投影を組み立てるのと同じプラグインが、イベントを OpenTelemetry へ渡す。一つの源から、トレースと動いている実行が同時に。
Intent-Based UI — 真偽ではなく、判定を。
ルート → 型のついた可能性。verdict() が拒否の理由を説明し、call() が呼び出す。一つの契約で React も mobile も Flet も。
デジタルツイン
Actom は Entity と振る舞いとエージェントを一つの宣言にまとめる — 状態を持ち、Action X-Ray から観測できるアクターだ。ファイルがシステムの双子のグラフになる。
05 — コンセプト
五つの主題。
それぞれが独立したページになる。
一つのシステムへの、五つの独立した切り口 — 宣言の文法から、他のフレームワークのあいだでの AOA の居場所まで。
01
強制される文法
文法はあらゆる規則を宣言に変える(@check_roles、@depends、検査、命名)。インポート時にそれらの宣言がグラフへまとまる — つまりコードが仕様であり、グラフがその機械可読な姿だ。起動時に検査され、Maxitor に描かれ、Action X-Ray に追われる — コードのかたわらを漂う文書ではなく。
02
AOA の憲章
八つの基本要素と、必須の宣言の組。書き方の作法ではなく、インポートのたびに機械が検査する法だ。黙って破ることはできない。食い違いは起動を止める。本番で表に出るのではなく。
03
業務ロジックと基盤の分離
Action が知っているのは Domain と規則。Postgres や Kafka や外部 API へどう届くかを知っているのは、Gateway や Resource というインターフェースの向こうのアダプタだ。業務コードがドライバを直接インポートすることはない — 境界は宣言の上を通る。開発者どうしの了解の上ではなく。
04
意図指向プログラミングの原則
コードが宣言するのは意図だ — 何が、どんな条件で起きるべきか。特定のライブラリ呼び出しの順序ではない。実装は口(@depends、@connection)を通して差し込まれ、意図がそのままなら入れ替えられる。
05
他のフレームワークとの比較
FastAPI と Django はルーティングと ORM を与えるが、ロールも依存も状態遷移もインポート時には検査しない。LangGraph はグラフを明示的に組むが、それは業務操作ではなく LLM の手順を統率するためだ。AOA はその両方に同時に近い — 応用アーキテクチャの実行可能なグラフであって、輸送やモデルのパイプラインだけではない。
06 — 実践レシピ
一つの課題に、
一つのレシピ。
学習ではなく課題に向いている — 何を作るかはもう分かっている。ここに書いてあるのは、どうやってか、だ。
Action の骨組み:Params、アスペクトのパイプライン、checker、connection。
自分の課題に本当に合う基本要素を選ぶための手引き。
データベースやキューや SDK を、管理され差し込める依存として包む。
既存の Action に手を触れずに、新しいプロトコルで公開する。
別のキャッシュ backend を cache_key / on_cache_write につなぐ。
機械のライフサイクルイベントを、割り込む権利なしに観測する。
自前の認証方式を @check_roles につなぐ。
box.info / box.warning を、ログが実際に住んでいる場所へ向ける。
他の基本要素が乗ってこられる、新しい参加の文法を宣言する。
Action が呼び出しについて見られるものに、自前の断面を足す。
既存のコードベースを、Action ずつ少しずつ移していく。
07 — faq
問いと、答え。
これはデコレータを山ほど付けた Clean Architecture では?
違いは強制力にある。Clean Architecture はレビュアーが手で確かめる取り決めの集まりだ。AOA の契約 — @check_roles、@depends、state の checker — は操作が走る前に機械が検査する。見ようと思い出した人がではなく。
既存の FastAPI や Django のアプリを書き直す必要は?
ない。aoa-fastapi-adapter が既存の Action をふつうのルートとして公開する。導入は Action ずつ進められる。フレームワークごと入れ替えるのではなく。
アスペクトのパイプラインは実行時にどれくらい高くつく?
どのアスペクトもふつうの async 呼び出しだ。直列化もなければ、プロセス境界もない。代価は自分で頼んだ検査の分であって、そのまわりのフレームワークの分ではない。
AOA を使うのに Maxitor は要る?
要らない。Maxitor はすでに宣言された Domain、Role、Action を読むだけの閲覧器であって、依存ではない。AOA はそれなしでも動く。
@compensate はデータベースのトランザクションと何が違う?
トランザクションが巻き戻すのは一つの保存先だけだ。@compensate が巻き戻すのは業務操作であり、それは決済ゲートウェイにもメール配信にもデータベースにも触れていたかもしれない — その三つに共通のトランザクション境界はない。
AOA が向かないのはどんなとき?
スクリプトや、その場かぎりの CLI や、操作が一つでコンプライアンス要件のないサービスなら、ふつうの関数が正しい選択だ。
⭐ AOA を気に入っていただけたら、GitHub でスターを、そして GitHub Discussions での議論への参加をお願いします。
