前回は、Archifyで小さな構成図を作り、図として確認できるところまで進めました。ただ、図が整っていることと、コードの読み取り結果が合っていることは別です。

次は小さな実装リポジトリを対象にすると書いたので、今回はメモを保存するAPIを用意しました。コードから読み取った構成を図にし、実際にHTTPリクエストを送って照合します。

今回は何を確かめるか

Archifyは、AIコーディングエージェントと組み合わせて構成図などを作るスキルです。CLIで図の仕様を検証し、閲覧用のHTMLを生成できます。Claude Codeの標準機能ではなく、追加して使うものです。Archify公式リポジトリ

今回の実行環境
先に実行環境を分けておきます。今回はCodexで実装とコードの確認を行い、ローカルの.claude/skills/archifyにあるスキルとCLIを使いました。Claude Codeで実行した結果ではありません。使用したArchifyは2.17.0-dev.1です。

私が確認したかったのは、図の箱と矢印にコード上の根拠があるか、そして実行時にもその順番で処理されるかです。CLIがリポジトリを直接解析したわけではありません。コードを読んで図の仕様JSONを組み立て、Archifyで描画しています。

メモの保存と取得だけを実装する

最初からAWS上に構成を作ると、ネットワークや権限設定の確認も混ざります。今回はコードと処理の対応に絞りたかったので、Python標準ライブラリとSQLiteだけにしました。

用意したエンドポイントは三つです。

リクエスト処理
POST /notesメモを保存し、IDと本文を返す
GET /notes/{id}保存したメモを取得する
GET /healthHTTPサーバーが応答するか確認する

保存する本文は文字列に限定しました。前後の空白を除いて1〜200文字なら受け付けます。空の本文や不正なJSONも送り、途中で処理が止まる経路を確認できるようにしています。

実装は次のように分けました。

archify-notes-api/
├── notes_api/
│   ├── server.py       # HTTPルートとJSONの処理
│   ├── service.py      # 入力検証とストアの呼び出し
│   └── store.py        # SQLiteへの保存・取得
├── tests/test_http.py
├── scripts/verify_runtime.py
└── evidence/

この規模なら一つのファイルにも書けます。今回は読み取った関係を追いやすくするために分けました。別々のサービスとして起動する構成ではありません。

起動は、実装ディレクトリで次のコマンドを実行します。検証時のPythonは3.13.5、SQLiteは3.51.2でした。

python3 -m notes_api.server --db notes.sqlite3 --port 8765

待ち受け先は127.0.0.1です。認証やTLSは用意していません。Pythonのhttp.serverも本番用途は推奨されていないため、この実装はローカルでの検証用にしています。Python公式ドキュメント

箱と矢印をコードに戻して確認する

server.pyから呼び出しを追うと、保存時の大まかな関係は次のようになります。

HTTPクライアント → Handler → NoteService → NoteStore → SQLiteファイル

HandlerがJSONを読み、NoteService.create()が本文を検証します。通過した場合にNoteStore.insert()を呼び、SQLiteに保存します。

この関係をArchifyの仕様に落とし込みました。

メモAPIのコードをもとにArchifyで生成した構成図。Handler、NoteService、NoteStoreは同じPythonプロセス内にある
図1:実際に生成したArchifyのHTML画面。矢印は呼び出し・アクセス関係で、すべてのリクエストが最後まで通る意味ではありません。
画像をクリックすると元のサイズで開きます。

図だけを見ると、緑色の三つの箱が別々のAPIにも見えます。コードではNoteService(NoteStore(db_path))として生成し、メソッドを呼んでいるだけです。そのため、同じPythonプロセス内であることを枠に書きました。

SQLiteも独立したDBサーバーではありません。今回はファイルに保存しているので、図にもSQLiteファイルと記載しています。前回の図にあったAWSサービスは引き継いでいません。

対応はファイル単位だけでなく、呼び出し箇所まで残しました。

図の関係確認したコード
Handler → NoteServiceserver.pyservice.create()service.get()
NoteService → NoteStoreservice.pyself.store.insert()self.store.get()
NoteStore → SQLitestore.pyINSERTSELECT、コミット処理

詳細な行番号は実装一式のevidence/code-map.mdにあります。今回は公開リポジトリのURLと固定コミットを用意していないため、Archifyのソース参照機能に架空の情報は入れていません。対象ファイルのSHA-256と照合メモを別に保存しました。

図の生成には、ブログ用プロジェクトのルートで次のコマンドを使いました。

node .claude/skills/archify/bin/archify.mjs deliver architecture \
  articles/diagrams/20260908-archify-notes-repository.architecture.json \
  articles/diagrams/20260908-archify-notes-repository.html \
  --quality showcase --json

ここでも少し修正が入りました。最初はINSERT / SELECTのラベルがNoteStoreに重なり、検証で止まりました。診断に沿ってラベル位置を直し、画面で確認して余白も詰めています。最終版は9項目の検証を通過し、エラー・警告は0件でした。

図の検証とコードの照合は別
ただし、これは図の検証結果です。コードと意味が一致しているかは、この後に別途確認します。

HTTPで動かすと、途中で終わる経路が見える

実装ディレクトリで、テストと実行記録用のスクリプトを動かしました。

python3 -m unittest discover -s tests -v
python3 scripts/verify_runtime.py

最初のテスト実行は、作業環境の制限でソケットを作れず、PermissionErrorになりました。APIの入力処理に到達する前の失敗です。ローカルHTTPの待ち受けが許可された実行環境でやり直すと、10件のテストが通りました。

テストではモックに置き換えず、実際のHTTP通信と一時ファイルのSQLiteを使っています。さらに別の検証スクリプトでは、サーバープロセスを終了し、新しいプロセスで同じDBを開き直しました。

実HTTPで確認した7ケースの結果。正常保存、取得、入力不正、JSON不正、存在しないID、health、別プロセス再起動後の取得を比較
図2:実行結果のevidence/runtime.jsonから作成した比較画像です。Archifyの出力画面ではありません。400・404は想定どおりの応答です。
画像をクリックすると元のサイズで開きます。

保存が成功したときは、次の順番が記録されました。

http.route
http.parse_json
service.validate
db.insert.committed
http.201

空白だけの本文を送った場合は、service.validateの後にhttp.400で終わります。保存処理には進みません。JSON自体が壊れている場合は、サービスを呼ぶ前に終了しました。

ここは構成図だけでは読み取りにくいと感じました。箱同士がつながっていても、入力によって通る範囲は違います。

healthが200でも、DBが使えるとは限らない

もう一つ確認したのがGET /healthです。この実装では、Handlerから直接200を返します。

if path == "/health":
    return self.reply(200, {"status": "ok"}, trace)

実際の記録もhttp.route → http.200だけでした。さらにテストでは、起動後にnotesテーブルを削除してからhealthを呼びました。それでも200が返ります。

これは不具合を見つけたというより、今回のhealthが何を確認しているかを確かめた結果です。HTTPに応答できることは分かりますが、DBを使えることまでは分かりません。

起動時とリクエスト時を分けて確認する
ただし、DBにまったく依存しないという書き方も違いました。サーバー起動時にはNoteStoreがテーブルを初期化します。リクエスト中にDBを読まないことと、起動時にもDBを使わないことは分けて書く必要があります。

ログだけで判断しないようにした

今回のトレースは、実装に埋め込んだ記録です。記録する位置を間違えれば、ログも間違います。そのため、トレースの順番だけで正しいと判断しないようにしました。

保存後にはSQLiteへ直接SELECTし、(1, "構成を照合")の1行が残っていることを確認しました。入力不正のテストでは、応答が400であることに加え、DBが空のままであることも確認しています。

別プロセスでの再起動後も、同じIDと本文を取得できました。少なくとも今回試した保存・取得では、プロセス内のメモリだけにデータを持っている実装ではありません。

一方で、並行書き込みやDBロック、障害時の復旧は試していません。図の検証もHTTPテストも、それらまで保証するものではありません。

次は変更後の図を追ってみたい

今回の範囲では、コードから整理した呼び出し関係と、実HTTPで通った処理を照合できました。私には、図を見て終わるよりも、途中で終わる経路を一つずつ確認するほうが理解につながったと感じられました。

ただ、自作した小さな実装を同じエージェントが読んだ検証です。未知のリポジトリでも正確に読み取れる、とまでは言えません。

次に試すこと
次はこのAPIに処理を一つ追加し、コードの変更に合わせて図のどこが変わるかを追いたいと思います。保存の前後に処理が増えたとき、矢印と説明が古いまま残らないかを確認したいです。

ここまで読んでいただき、ありがとうございます。もしこの記事の技術や考え方に少しでも興味を持っていただけたら、ネクストのエンジニアと気軽に話してみませんか。

  • 選考ではありません
  • 履歴書不要
  • 技術の話が中心
  • 所要時間30分程度
  • オンラインOK

エンジニアと話してみる