Arcaeon Ledger について
Arcaeon Ledger は、エージェントの操作を記録するハッシュチェーン台帳で、記録の完全性を確認したい開発者向けに追記と検証を行います。単一の JSONL ファイルを使い、チェーンが途切れた行を特定できます。
主な機能
- 01操作記録の追記
- 02ハッシュチェーン完全性の検証
- 03チェーンが切れた行の特定
- 04CLI による追記と検証
- 05実行者と権限情報の記録
活用シーン
- 01エージェントログの改ざん確認
- 02CI やリリース前の台帳検証
- 03実行者と権限情報を記録に含める
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
arcaeon-ledger
オブザーバビリティツールはエージェントが何をしたかを示します。arcaeon-ledgerなら、それを 証明 できます。
すべての記録は、その直前の記録とハッシュチェーンでつながっています。行を編集、削除したり、履歴を並べ替えたりすると、それ以降のリンクがすべて壊れます。verifyは該当する行を正確に示します。記録は自分で管理でき、改ざんされていないことを証明できます。依存関係はゼロ、JSONL ファイルは1つ、動詞は2つです。
pip install arcaeon-ledger # then: from arcaeon_ledger import Ledger
from arcaeon_ledger import Ledger
log = Ledger("agent.log.jsonl")
log.append({"tool": "web.search", "query": "weather in LA", "result_ok": True})
log.append({"tool": "payment", "amount": "49.00", "currency": "USD"})
log.verify() # VerifyResult(ok=True, rows=2, chained=2, ...)
改ざんを見逃さずに検出します。
# someone edits row 2's amount in the file by hand...
log.verify() # VerifyResult(ok=False, first_break="line 2: chain mismatch")
CLI(CIや出荷前のゲートに組み込めます。改ざんされたログはゼロ以外で終了し、一部しか保証できないログが、完全に検証されたログと同じ終了コードで返ることはありません)。
python -m arcaeon_ledger.cli append agent.log.jsonl '{"tool":"search","ok":true}'
python -m arcaeon_ledger.cli verify agent.log.jsonl
python -m arcaeon_ledger.cli verify --strict agent.log.jsonl
verifyの終了コード(0.5.7):
| 終了コード | 意味 |
|---|---|
0 | 完全に検証済み — すべての行を確認し、チェーンに問題がありません(ok: true) |
1 | 破損 — 破損が見つかった(ok: false)、または使い方が誤っています |
3 | 範囲内でのみ検証済み(どの場合もok: null):破損は見つかりませんでしたが、チェーンにつながっていないprechain行が未検証のままスキップされました(verified_scope: "bounded_prechain_skipped")。または、破損が宣言済みのものだけです("bounded_declared_break")。または、ファイルに行がありません("empty")。偽造された「legacy」の先頭追加はここに該当し、0にはなりません。最初の2つをハードエラーの1にするには、--strictを指定してください。 |
CIゲートでは、0だけを成功として扱ってください。
python -m arcaeon_ledger.cli verify agent.log.jsonl
case $? in
0) echo "fully verified" ;;
3) echo "chain intact but prechain rows skipped unverified — inspect, or use --strict" ; exit 1 ;;
*) echo "ledger broken" ; exit 1 ;;
esac
順序だけでなく、誰が操作したかを証明する
ハッシュチェーンは順序の完全性を証明しますが、各エントリを書いたのが誰か、またその人に権限があったかまでは証明できません。authorityブロックを付加して、実行者とその権限範囲を、チェーンにつながれた(改ざんを検知できる)行に結び付けます。
from arcaeon_ledger import Ledger, authority
log = Ledger("agent.log.jsonl")
log.append(
{"tool": "payment", "amount": "49.00"},
authority=authority(
"agent://billing-7",
capability_version="v3", # what they were allowed to do
tool_schema={"name": "payment", "args": ["amount"]}, # hashed, not just named
time_source="ntp", # trust surface of the clock
),
)
これにより、監査での問いは「編集されたか」から「編集され、さらに書き手に権限があったか」へと掘り下げられます。プリンシパル、ケイパビリティ、スキーマハッシュを編集すると、ほかの改ざんと同様にチェーンが壊れます。改ざん検知と権限のリプレイを組み合わせた仕組みです。(ローンチ時のコミュニティからのフィードバックを受けて提供されました。)
これが存在する理由
2026年、エージェント開発者が最も強く感じている未解決の課題は、信頼性と監査のギャップです。エージェントがタスクを「完了」しても、結果がひそかに間違っており、実際に何が起きたかを再現したり、証明したりできません。オブザーバビリティプラットフォームは実行を追跡しますが、改ざんを検知でき、持ち運び可能で、自分で管理できる記録を提供するものはありません。規制も迫っています。EU AI Actは、ハイリスクシステムに対し、そのライフサイクル全体にわたるイベントの自動記録を技術的に可能にするよう求め(第12条第1項)、提供者と導入者に対し、自らの管理下にある範囲で、そのログを少なくとも6か月間保持するよう求めています(第19条第1項、第26条第6項)。同法が義務付けているのは記録と保持です。改ざん検知という言葉は同法にはなく、私たちが加えたものです。保持されたログが今も元のログなのかと問われたとき、信頼するだけでは不十分であり、より確かな答えが必要です。arcaeon-ledgerは、正直さを保てる最小限の形です。導入して自分で管理し、検証できる、暗号学的にチェーン化されたアクションログです。
チェーンの仕組み
chain = sha256(prev_chain + json.dumps(row_without_chain, sort_keys=True, ensure_ascii=False))[:32]
区切り文字に注意してください。チェーン本体では、成果物ダイジェストで使うコンパクトなjson-c14n:v1形式ではなく、Pythonのデフォルトの", "/": "という空白が使われます。他の言語で検証する場合も、この空白を正確に再現する必要があります。
チェーン値は**truncated_sha256_128**です。SHA-256の完全なダイジェストではなく、先頭の32個の16進文字(128ビット)です。完全なSHA-256として誤って引用されないよう、この名前が付けられています。編集や偶発的な変更の検出には128ビットで十分ですが、書き換え後にチェーン自体を計算し直すコストを高くしたい場合には、より弱い値です(atomic-ravenのレビューに感謝します)。
各行は、それ以前の履歴全体を確定します。最初の行は固定の"genesis"シードからチェーン化されます。chainフィールドのない行は、最初のチェーン化された行より前にある場合に限り許容されます(既存のログにも導入できるようにするためです)。チェーンの開始後にチェーン化されていない行が現れた場合、その行自体が問題として報告されます。不一致がある場合、verifyは申告された値を起点に処理を続けます。これにより、1つの破損がノイズのように連鎖するのではなく、後続の損傷も正直に数えられます。
証明できること — そして証明できない5つのこと
ここで正確を期すことは、免責事項ではなく、この製品の本質です。ハッシュチェーンが証明するのは、各行に記録された内容が書き込み後にその場で改ざんされていないことです。ファイル途中の編集、削除、並べ替えはすべてチェーンを破壊し、verify は該当する行を示します。
この文中の1つの単語が0.5.8で変わりました。その理由こそ、このセクションが存在する意味です。以前は「記録されたバイト列」と書かれていましたが、これはチェーンが証明する範囲を超えています。チェーンは、ファイルから読み戻して解析した各行を基に計算されます。また、読み取り側はデコードできないバイト列を正規化します。そのため、そのような領域に含まれる2つの異なるバイト列は同じ内容として読み取られ、同じ判定になります。保護されるのは各行の意味であり、ファイルの正確なバイト列ではありません。バイト単位の保全が必要な場合は、これと併せてファイル自体のハッシュを取ってください。
これだけでは、ほかに次の5つのことは証明できません。
1. 切り詰め。 最新の行を削除しても、残った部分は問題なく検証されます。追記専用チェーンだけではこれを検知できません。一定の間隔で、自分の管理外の場所にヘッドを公開して対処してください。
pin = log.head().as_pin()
# -> "arcaeon-ledger head chain=9f3c… rows=204 as_of=2026-08-13T17:40:00Z"
# post `pin` to a git commit / public comment / notarization anchor.
# a reader compares a fresh head() against the last pin; a truncated or
# re-minted history disagrees. the MAX gap between pins is your security
# parameter, not the average — an attacker picks the gap.
2. 真実性。 チェーンが公証するのは、書き込まれた内容そのものです。幻覚を改ざん検知可能な形で記録しても、チェックサム付きの幻覚であることに変わりはありません。行の内容が現実について語るようにするには、再取得可能な成果物(URL+バイト列、スナップショット、ツールの標準出力)のハッシュを取り、そのダイジェストを行に保存してください。そうすれば第三者が成果物を再取得して照合できます。
3. 作成者。 authority()(上記)は「誰が何を主張したか」を記録しますが、それは行のデータであり、署名ではありません。ジェネシスから再生成する書き換え者は、それも再生成できます。再生成者が先へ進められないのは、外部ヘッドアンカリング(#1)です。
4. 偽造されたレガシー行の前置。 chain フィールドのない行は、最初のチェーン付き行より前であれば許容されます。これは意図的な仕様です。既存のログの履歴を書き換えずに、チェーンをその上に導入できます。ただし、スキップされた行は未検証の行であり、検証器は実際のレガシー履歴と偽造された前置行を区別できません。そのため(0.5.7以降)、行をスキップした非 strict 検証では成功を示しません。ok は None — 「破損は見つからず、対象範囲内で検証済み」— となり、真偽値としては偽です。対象範囲はインバンドで示され(verified_scope: "bounded_prechain_skipped")、件数は prechain に記録されます。CLI の終了コードは 0 ではなく 3 です。すべての行をチェックしたスキャンのみが ok=True を返します。ログがジェネシスからチェーン化されており、正当なレガシー行が一切あってはならない場合は、verify(strict=True) / --strict を指定してください。チェーンのない行をすべて破損として扱い、明確な失敗を返します。(チェーン開始後に挿入されたチェーンなしの行は、どのモードでもすでに検出されます。)
5. 完全性。 これは最も重要な点であり、構造上の問題です。何を append するかはエージェントが決めます。エージェントが記録することを選んだ呼び出しを改ざん検知可能なログに記録しても、自己申告であることに変わりはありません。エージェントが実行できることは、実行しないことも選べるため、このライブラリ内でそれを解決することはできません。
ペンをエージェントの手の届かない場所に移して対処してください。つまり、境界部分で記録します。エージェントが所有せず、スキップできず、見ることもできない、独立したOSプロセス内で記録します。
pip install arcaeon-adapter
python -m arcaeon_adapter --ledger seam.log.jsonl -- <your mcp server command...>
arcaeon-adapter は、MCP クライアントとサーバーの間で JSON-RPC をバイト単位で転送する標準入出力プロキシです。tools/call ごとに1つのハッシュチェーン付き行を、独自の台帳に書き込みます。これをこのライブラリ自身の MCP サーバーにラップした結果、要点を示す数字が得られました。サーバー自身の日誌には0行しか書き込まれませんでしたが、境界ログには5行が記録されました。システムが自らについて報告する内容と、境界で観測された内容との隔たりこそ、測定する価値があるものです。
適用範囲を正直に示すと、このプリミティブが保証するのは*「このファイルはその場で書き換えられていない」*ということです。範囲は小さく、正しく、テスト可能です。その上に重ねるレイヤー(head() による外部アンカリング、成果物との紐付け、署名による作成者の証明、境界での記録)を使って、完全な証拠の主張へと拡張できます。
欠落または空の台帳での verify()
どちらも同じ「データなし」に見えますが、verify() は意図的に区別します。
Ledger("never/written.jsonl").verify()
# VerifyResult(ok=False, rows=0, first_break="unreadable: [Errno 2] No such file...")
open("touched/empty.jsonl", "w").close()
Ledger("touched/empty.jsonl").verify()
# VerifyResult(ok=None, rows=0, chained=0, first_break=None, verified_scope="empty")
一度も作成されていないパスは保証できないため、ok=False、「読み取り不可」となり、ほかの読み取りエラーと同じ扱いです。存在していて本当に空のパスには改ざんできる行がありませんが、確認した行がゼロでも合格にはなりません(0.5.8 以降)。ok=None, rows=0, verified_scope="empty" となり、偽値として評価され、CLI の終了コードは 3 です。verify().ok の値で分岐する自動化では、ファイルがない場合は失敗、空の場合は合格ではないという結果になります。両者を区別するには、first_break と verified_scope を確認してください。
ログが外部で書き込まれた場合:破損を宣言し、再生成しない
遅かれ早かれ、スクリプト、インシデント、あるいはエディターを使う人などが、append() を通さずに JSONL に書き込むことがあります。その時点でチェーンは壊れ、その状態のままです。それが実際の記録だからです。明白な選択肢はどちらも適切ではありません。読者には何も伝わらないまま、常に失敗を示し続けるか、チェーンを再計算してファイルを合格状態にするかです。後者は改ざんにあたり、ひそかに再生成できるチェーンは何の証拠にもなりません。
3 つ目の選択肢が declare_break です。破損の内容を示す行を追加します。
from arcaeon_ledger import declare_break, verify_file
declare_break("agent.log.jsonl", 25,
"Written out of band 2026-08-15 by a session hand-appending JSON "
"instead of calling append(). Content is true and preserved verbatim; "
"no chain value was ever computed for it, so none can honestly be supplied.")
r = verify_file("agent.log.jsonl")
r.ok # None — bounded, NOT True. Falsy.
r.verified_scope # "bounded_declared_break"
r.breaks # 0
r.declared # ["line 25: declared break (Written out of band 2026-08-15 ...)"]
破損は declared に永続的に記録されます。変わるのは、既知で説明済みの破損が、説明のない破損のように見えなくなることです。また、孤立した行の正確なバイト列は sha256 で固定されるため、その行を後から編集すると、ファイルは再び失敗状態になります。ok=True が返されることはありません。 それを返せるのは、すべての行を確認したスキャンだけです。免責された行は確認されていません。verify(strict=True) は宣言をすべて無視します。
この機能について、はっきり述べておきます。これは記録用の仕組みであり、暗号技術ではありません。 ファイルに書き込める人なら誰でも宣言を書けるため、すでに書き込みアクセスを持つ攻撃者に対する防御にはまったくなりません。防ぐのは忘却であり、改ざんではありません。why は検証されない人間の文章なので、誠実な外部書き込みと悪意ある書き込みを見分けることはできません。また、宣言できるのは verify() がすでに検出した破損だけで、誰にも気づかれていない破損には何もできません。誠実なインシデントの記録を明確に残すために使い、台帳を合格状態にする手段としては決して使わないでください。
エージェントが実際に読んだものをバインドする(artefact-binding)
チェーンによって、行が編集されていないことは証明できます。しかし、その行がそもそも真実だったことまでは証明できません。幻覚も事実と同じように忠実に公証されます。再取得可能なソースを示せるケースでは、bind_artefact がその隔たりを埋めます。エージェントが読んだ実際のバイト列をハッシュ化し、そのダイジェストを行に保存することで、第三者がソースを再取得して照合できます。
from arcaeon_ledger import Ledger, bind_artefact
log = Ledger("agent.log.jsonl")
art = bind_artefact("https://example.com/pricing") # or bytes, a file path, or a dict
log.append({"tool": "web.read", "url": "https://example.com/pricing", "artefact": art})
# art -> {"subject": {"name": "...", "digest": {"sha256": "..."}},
# "recipe": "sha256:raw-bytes:v1",
# "digest": "sha256:raw-bytes:v1:<hex>", "bound_at": "...", "source_meta": {...}}
ダイジェストは自己記述型です。裸の 16 進数ハッシュは使いません。それぞれが sha256:<recipe>:<version>:<hex> の形式で、文字列だけから第三者が再現できるよう、レシピ自体を含んでいます。レシピは raw-bytes:v1(読み取ったままの不透明なバイト列)または json-c14n:v1(キーをソートし、コンパクトにした UTF-8 の、仕様を固定して文書化済みの JSON 正規化)です。レシピは凍結され、追記のみでバージョン管理されるため、古い行は常に元のレシピを保持し、ルールが変更されても履歴が改ざんされたように見えることはありません。
誠実に検証してください。
from arcaeon_ledger import verify_artefact
verify_artefact(art) # recipe reproducible + string self-consistent
verify_artefact(art, refetch=True) # for a URL: re-fetch and compare
# -> {"verdict": "live_match", # <- THE answer; read this field
# "digest_ok": True, "reason": None,
# "refetch": "match" | "mismatch" | "unavailable" | "skipped", "notes": [...]}
digest_ok だけではなく、verdict を読み取ってください(0.5.7)。 digest_ok が示すのはオフラインの判定のみです。レシピを再現でき、文字列に矛盾がないことを示し、ライブで再取得した結果が一致しなくても True のままです。トップレベルの verdict タグは、判定全体をひとつのフィールドで示します。"digest_consistent"(オフライン判定は成功し、ライブでの照合は未実施)、"live_match"、"live_mismatch"(ライブの内容が一致しない。変更されたのか改ざんなのかは特定できません)、"live_unavailable"(要求されたライブチェックを実行できませんでした)、またはオフライン判定が失敗した場合は、その型付きの失敗理由自体です。以前は refetch=True の後に if out["digest_ok"] とすると、ライブで不一致でも成功として扱われていました。out["verdict"] == "live_match" なら、そのようなことはありません。
このビルドで再現できないラベルは、成功ではなく型付きの失敗になります。 ダイジェストに、サポート対象のレジストリにないアルゴリズム、レシピ、またはレシピのバージョンが指定されている場合、verify_artefact は digest_ok=False と機械可読な reason(unknown_algorithm、unknown_recipe、unknown_recipe_version、malformed_digest、subject_digest_mismatch のいずれか)を返し、再取得の段階には進みません。そのため、検証できないレシピが "match" として返されることはありません。再計算できないダイジェストはチェックしていないダイジェストであり、「チェックしていない」ものを「検証済み」と報告してはいけません。新しいレシピを追加するときに古いバージョンも SUPPORTED_RECIPE_VERSIONS に残すことで、検証器が一度も提供したことのないラベルを通してしまうことなく、レシピを追記のみとする約束を守れます。
誠実さを保つための境界を、要点なので明確に述べます。 再取得時の mismatch は、内容が変更されたか、または改ざんされたことを意味し、どちらかは特定できません。改ざんの証明として報告することはありません。ウェブの内容は変更され、404 になり、ペイウォールが設定され、ユーザーに応じて表示が変わります。バインディングが証明するのは、*「これは時刻 T にエージェントが読んだと述べたバイト列のダイジェストである」*ということだけで、それ以上のことではありません。自身での取得ではなく中立的なキャプチャを行うには、ソースを公証付きスナップショットに通してください。時刻 T より前に存在していたことを証明するには、ダイジェストを外部にアンカーしてください。どちらも追加するレイヤーであり、暗黙ではなく明示されています。
外部チェック:外部の証人
チェーンだけでは切り詰めを検出できません。最新の行を削っても、残った部分は正常に検証されます(上記の「証明できないこと」を参照)。解決策は証人です。これは、あなた自身の管理外にいる記録者で、一定間隔であなたのヘッド (rows, chain) を保持します。時点 T のピンを証人が取得した後は、切り詰められたログは証人が確認したものより行数が少なくなり、書き換えられたログは証人が確認した行の時点でチェーンが異なります。どちらも隠すことはできません。
from arcaeon_ledger import Ledger, WitnessStore, publish_head, verify_against_witness
log = Ledger("agent.log.jsonl")
witness = WitnessStore("witness_pins.jsonl") # ideally on a host you don't control
publish_head(witness, "billing-agent", log) # record the current head — do this on a cadence
# later — did the log survive intact?
v = verify_against_witness(witness, "billing-agent", log)
v.verdict # "consistent" | "truncated" | "rewritten" | "no_record" | "witness_broken" | "local_broken"
bool(v) # truthy ONLY on "consistent" — a missing pin is no_record, never a false ok
# READ THE VERDICT WITH ITS QUALIFIERS, never the bare string alone:
v.witness_self_integrity # "verified" | "unestablished" | "broken"
単に "consistent" と表示されても、それだけでは不十分です。 判定には witness_self_integrity も含まれます。これは、証人ストアが自身のピンチェーンの完全性を証明できたかどうかを示します。latest() しか公開していないホスト型クライアントは自己検証できないため、その判定は unestablished となります。比較は誠実に行われましたが、そのストアが提供した偽造ピンでも正常に比較されてしまいます。verified はストア自身のチェーンが再計算されたことを、broken は検証に失敗したことを意味します。witness_self_integrity を確認せずに v.verdict == "consistent" だけで分岐する利用者は、ログの誠実さを信頼するのとまったく同じ程度にストアの誠実さを信頼することになります。まさにその信頼関係を置き換えるために、証人が存在します。(2026-08-23 の招待前監査 C14 で確認。このフィールドがあることで、「未確認」が「確認済みで問題なし」と表示されることはありません。)
WitnessStore は参照用の証人です。ピンを記録する、追記専用の JSONL ファイルを 1 つ使用します。ホスト型の証人は、まさにこのオブジェクトを HTTP でラップしただけのものです。ローカルで実行すれば、完全なオフライン環境で、費用がかからず、すべてを自分で管理できる証人になります(ただし、自分で管理する証人の独立性は、そのホストの独立性に左右されます)。
証人が厳密に証明すること。 証人が証明するのは、ログが切り詰められたり書き換えられたりしていないことです。ただし、証人が確認した内容との相対的な比較に限られ、最後のピンを取得した時点までに限られます。最後のピンの後に追加された行は、次のピンを取得するまで保護されません。そのため、セキュリティ上の実際のパラメーターは、ピン間隔の平均ではなく最大値です。攻撃者は間隔を選べるからです。 また、記録された内容が真実かどうかは一切示しません。それはアーティファクトのバインディングが担う役割です(上記参照)。証人が守るのは、履歴の形だけです。
証人が保持するもの。 指紋 (namespace, rows, chain, time) のみで、ログの内容は保持しません。パスワードは設計上どこにも保存されません。証人が侵害されても、盗まれる機密情報はなく、元のログなしでは役に立たないハッシュだけが残ります。
あらゆる MCP エージェントに組み込めます
arcaeon-ledger は依存関係のない MCP サーバーを同梱しているため、あらゆる MCP クライアント(Claude Code など)から、コードを書かずにエージェントへ改ざんを検知できるログ記録機能を提供できます。次のように設定してください。
{
"mcpServers": {
"ledger": {
"command": "python",
"args": ["-m", "arcaeon_ledger.mcp_server", "--log", "agent.log.jsonl"]
}
}
}
エージェントはその後、5 つのツールを使用できます。2 つは 1 つのファイルを扱う オペレーターツール です。
ledger_append(record) はアクションを記録し(チェーンハッシュを返します)、ledger_verify(strict?) はログが完全であることを証明します(または、改ざんされた正確な行を返します)。検証結果はライブラリと同じく 3 値です。ok: true はすべての行が検証されたことを示し、ok: null はチェーンは完全でも、チェーンに含まれない
prechain 行が未検証のままスキップされたことを示します
(verified_scope: "bounded_prechain_skipped" — 検証済みを意味する緑色の結果ではありません)。ok: false は破損を示します。チェーンに含まれない行をハードエラーにするには、strict: true を渡してください。
3 つは エージェントツール(0.7.0)です。出力を誰かに渡す場合、つまり証明を求めるプリンシパルや、あなたを信頼するか判断するピアがいる場合に使います。
| ツール | 用途 | 戻り値 |
|---|---|---|
prove_my_conduct(namespace, events) | 直前に実行したことをまとめて記録し、プリンシパルに 1 つのハッシュを渡します | {rows, head_hash, chain_verified} |
verify_peer_ledger(jsonl_text, strict?) | テキストだけを使って、別のエージェントがエクスポートしたログを判定します | {ok, rows, first_break, declared_breaks} |
declare_break(namespace, reason) | ログが破損した場合、チェーンを再生成するのではなく、その事実を宣言します | {declared_line, declared_breaks, ...} |
prove_my_conduct は追記後に再検証するため、台帳が改ざんされたエージェントは、緑色の結果が付いたヘッドハッシュではなく、chain_verified: false を返します。verify_peer_ledger は first_break を 整数の行番号(または null)として返すため、呼び出し元のエージェントは不正な行を正確に示せます。このツールはあなたの台帳には一切触れません(エクスポートは使い捨ての一時ファイルで検証され、他のすべてのツール呼び出しと同様、呼び出し自体は <log>.calls.jsonl に 1 行記録されます)。解析可能な行がないエクスポートは ok: null(verified_scope: "empty")を返します。何も送らずに緑色の結果を得るのは、最も簡単な偽造だからです。declare_break は何も破損していない場合は拒否され、緑色の結果を復元することはありません。
エージェントの台帳は --ns-dir(デフォルトは --log の隣にある ledgers/)の下に、名前空間ごとに 1 つのファイルとして保存されます。名前空間はパスではなく名前です。使用できる文字は [A-Za-z0-9._-] で、パストラバーサルはサニタイズせずに拒否されます。
MCP は stdio 上の JSON-RPC であり、このサーバーは SDK も追加インストールも不要で、プロトコルを直接扱います。
ステータス
コアライブラリ、CLI、すぐに組み込める MCP サーバー はすべてテスト済みです。ライブラリでは編集・削除・並べ替えによる改ざん(test_ledger.py)をテストし、MCP サーバーではリクエストハンドラーを介した tools/list → append → verify と改ざん検知をテストしました。また、エージェントツールでは名前空間のパストラバーサル、ピアのエクスポートに対する行単位の改ざん検知、破損の宣言をテストしました(test_agent_tools.py)。本番環境で稼働する、ハッシュチェーン方式のアクション台帳から抽出したものです。外部アンカリングには head()(ピンを自分で公開します)とリファレンスウィットネス(前述の WitnessStore)を利用できます。ホスト型ウィットネスプラン(保持、自動ピン留めの頻度設定、コンプライアンス向けエクスポート)は次の段階です。
MIT。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。