エージェントのポータビリティ
エージェントはファイルではありません。プロバイダー、プロファイル、バンドル、MCPサーバーを参照する設定エントリと、ディスク上のワークスペースディレクトリで構成されています。あるエージェントを別のインストール環境に移すには両方の部分を移動する必要があり、さらに、そもそも何を移動すべきでないかを判断する必要があります。
エージェントバンドルとは、移植可能な形式です:
<bundle>/
├── zeroclaw-agent.toml — manifest: format version, root alias, provenance,
│ required secrets, carried skill bundles,
│ dropped refs, risk flags
├── config.toml — the config closure this agent needs
├── workspace/ — the agent's workspace tree
└── skills/<alias>/ — content of each skill bundle the agent references
config.toml は断片であり、完全な設定ファイルではありません。エージェントが参照する項目だけを含んでおり、信頼して使う前に内容を読んで確認することを想定しています。
エクスポート
sh
zeroclaw agents export <alias> --out ./my-agent
| フラグ | 効果 |
|---|---|
--out <dir> | 出力先のバンドルディレクトリ。存在しない場合は作成されます。 |
--force | 置き換え先に既存の内容がある場合は、それを置き換えます。 |
Export は インストール先に対して読み取り専用で動作し、次の3点を報告します。受け入れ側のオペレーターが承認することになる機能、削除(スクラブ)された認証情報、そして移行できなかった設定です。
公開済みであり、マージはされていません。 エクスポートはコピー先に隣接するステージング用ディレクトリで構築され、完成後に差し替えられます。そのため:
--forceは出力先を_置き換えます_。新しいマニフェストに含まれていない以前のエクスポートのファイルは、バンドルの一部に見えたまま残るのではなく、削除されます。- エクスポートが報告する失敗(読み取れないワークスペースファイルやディスクの空き容量不足など)が発生した場合、保存先は元の状態のまま残ります。ステージングされたツリーは破棄され、既存のバンドルがあれば元に戻されるため、不完全に書き出されたバンドルを完全なものと誤認することはありません。
- エクスポートが読み取るツリーと重なる出力先は、何も作成される前に拒否されます。この判定は双方向で行われ、ワークスペースとすべてのスキルバンドルに同様に適用されます。ソースの_内部_にある
--outでは、コピーが自身の出力を取り込んでしまいます。一方、内包する--outでは、エクスポート対象のツリーが置き換えられてしまいます。 - 保持される identity パスのコンポーネントおよび skill コンテンツのディレクトリ名は、サポートされるすべてのターゲットで実体化できる文法を使用します。これにより、区切り文字や制御文字、拡張子の有無を問わず
con、nul、lpt1などの Windows 予約名、およびスペースまたはドットで終わる名前は除外されます。安全でない identity パスは削除されます。安全でない skill エイリアスは、手動インポーターがリネームまたは再バインドできるように設定クロージャーに残されますが、そのコンテンツはskills/<alias>/配下には配置されません。この省略はマニフェストに報告されます。フォーマット 1 ではルートエージェントのエイリアスも変更されないままとなるため、そのターゲットでデフォルトワークスペースをコピーする前に、ターゲットと互換性のないエイリアスをリネームしてください。 - 書き出す前に閉包が検証されます。レンダリングされた
config.tomlは再度パースされ、取り込み先のインストールが実行するのと同じバリデーションに、他の内容を含まない設定のみを対象にかけられます。ソースのインストールでは満たせても、バンドルでは満たせない参照(例えば設定されていないプロバイダーやバンドルのエントリ)があれば、エクスポートを拒否し、該当するフィールドを明示します。到着後に失敗するバンドルを生成するのではなく、この動作をとります。 --forceが許可するのは、パス文字列ではなく1つのディレクトリです。エクスポーターは親ディレクトリのハンドルと許可された宛先の識別情報を保持し、公開の前にそれらを再確認します。これらのチェックで検出された宛先の変更は拒否されます。これらのチェックは置換のリスクを軽減しますが、最終的な削除またはリネームとのアトミックな compare-and-swap ではありません。そのため、エクスポートの公開中に別のプロセスが宛先ディレクトリを変更しないようにしてください。
エクスポートが途中で強制終了された場合
スワップは1回の名前変更ではなく、2回の名前変更で構成されています。まず既存のバンドルを脇に移動し、その後にステージングされたバンドルを移動します。これはエクスポートが報告する失敗のロールバックには十分ですが、クラッシュに対してアトミックではありません。2つの名前変更の間でプロセスまたはホストが停止した場合、移行先は存在せず、以前のバンドルはその隣に、ステージングディレクトリと対になる名前で無傷のまま残ります:
<parent>/
├── .zeroclaw-export-<token> staged bundle, incomplete (safe to delete)
└── .zeroclaw-export-old-<token> the previous bundle, unchanged
.zeroclaw-export-old-<token> を宛先の名前に戻すようリネームして復旧します。どちらのディレクトリも隠しディレクトリで、同じ <token> を共有するため、エクスポートが異常終了すると対になったペアが残ります。正常に完了したエクスポートでは、どちらも残りません。
クロージャが保持するもの
[agents.<alias>] から始まり、再構築可能なすべての参照をエクスポートが辿ります:
- エージェントの
risk_profileおよびruntime_profileエントリ; - これは
skill_bundles、knowledge_bundles、mcp_bundlesのエントリ; - これらのバンドルが実際に付与する
[mcp.servers]のエントリを、ランタイムが使用するのと同じパスで解決したものです。そのため、バンドルのexcludeによって削除されたサーバーは、そのバンドルにも含まれません; - エージェントが指定するすべてのプロバイダーエントリ(
model_provider、classifier_provider、summary_provider、tts_provider、transcription_provider)は、キーレスで保持される; - 持ち込まれたランタイムプロファイルが自身の
context_compression.summary_providerで指定するプロバイダーで、エージェントは言及しないものの、ターゲットはプロファイルごとに検証する; - ランタイムの深さと循環のルールの下で到達可能なすべてのモデルプロバイダーのフォールバック。これらも同様にキーレスで保持されます;
- 参照されている各スキルバンドルの内容(
skills/<alias>/配下)。スキルはエージェントのワークスペースではなく、インストール全体の<install>/shared/skills/ツリーにあるため、設定だけではスキルが存在しないエージェントをインポートしてしまいます。各バンドル自身のincludeとexcludeがコピーをフィルタリングするため、バンドルが除外したスキルは移行されません。
マニフェストの skill_bundles リストは、バンドルに_何が含まれているか_を記録するものであり、エクスポートが運ぼうとしたものを記録するものではありません。エージェントに設定されているものの、エクスポート元ホストにディレクトリが存在しないバンドルは、代わりに理由 source_missing とともに dropped に記載され、carried_skills フラグは立てられません。そのため、成果物が実際には持っていない skills/<alias>/ ツリーを宣伝することは決してありません。
クロージャの検証基準は、単独で成立することです。他のエントリが存在しないインストール環境で解析したときに、Config::validate() を通過すること。
スキーマのデフォルトと等しい値は削除されるため、フラグメントにはスキーマ全体ではなく、実際に誰かが選択した内容が表示されます。
意図的に対象外としているもの
省略された各項目は、理由とともにマニフェストの dropped リストに記録されるため、何も黙って消えることはありません。
| 破棄済み | 理由 |
|---|---|
channels | ソースインストールにのみ存在するアカウントと認証情報に名前を付ける |
delegates, workspace.access, workspace.read_memory_from | ターゲット上には存在しない兄弟エージェントの名前を挙げてください。 |
workspace.path | ソースホスト上の絶対パス。 |
identity.aieos_path | エクスポートされたワークスペース内のファイルに、形式独自のパス文法で解決される場合にのみ保持されます。この文法では、/-区切りを使い、..、バックスラッシュ、ドライブまたはUNCの接頭辞、制御文字は使用できません。インポート先のホストは、これらをエクスポート元とは異なる方法で解釈する可能性があるためです。保持されるパスは、この文法に書き換えられます(正規化され、すべてのエクスポート元プラットフォームで /-区切りになります)。そのため、config.toml 内の文字列が、同梱されたファイルを指す文字列になります。memory/ 配下のパス、およびコピーに含まれなかったファイルのパスも破棄されます。 |
delegate_same_risk_profile | falseに設定します: 同じプロファイルでの自動委譲を有効にすると、このエージェントがこれまでペアリングしたことのないターゲット上のエージェントにも到達してしまうためです。 |
risk_profiles.<alias>.approval_route | 出典のインストールチャネルと、個別の承認者を指定します。同名の移行先チャネルが承認権限を黙って引き継ぐことがないよう、このエントリは削除され、その旨が報告されます。削除に伴い、移行元プロファイルの個別承認者ポリシーも削除されるため、その分離が必要な場合は、エージェントを有効化する前に移行先で個別承認者のポリシーを再度バインドしてください。 |
skill_bundles.<alias>.directory | 絶対パスの場合は、ソースホストを示すため削除されます。移行先はエイリアスのデフォルトの場所を自ら解決します。<install>/shared/ の外にあるディレクトリ(スキルバンドル契約が管理するツリー)は、その内容ごと削除されます。バンドルの設定は引き継がれますが、そのスキルはインストールがエクスポートするものではありません。 |
a2a | 外部に公開されるサーフェスであるため、エージェントは意図的に再公開する必要があります。 |
cron_jobs | バンドル形式1では引き継がれません。 |
workspace/memory/ | メモリストア。以下を参照。 |
workspace/MEMORY_SNAPSHOT.md | ストアが再ハイドレートに使用するコアメモリのエクスポート:別の形式のメモリ |
Memory は移行されません
バンドル形式 1 にはメモリが含まれず、それを有効にするフラグもありません。ストアは WAL モードで動作する稼働中の SQLite データベースであり、エージェントの実行中は、コミット済みの状態がデータベース本体と -wal サイドカーに分散して存在します。そのため、これらのファイルを一つずつコピーすると、破損した、または古い状態のデータベースを取り込んでしまう可能性があります。バンドルは、そうした問題に後から気づく場所であってはなりません。メモリを含めるには、静止させたストアに対して SQLite 独自のバックアップ API を使って実行する、本物のスナップショット境界が必要です。これは後のフォーマットバージョンで追加できます。
ディスク上でメモリが取る2つの形式は、どちらも移行されず元の場所に残ります。1つは workspace/memory/ 配下のストア、もう1つはワークスペースルートにあり、エージェントがストアを復元する元になる MEMORY_SNAPSHOT.md です。インポートされたエージェントは、空のメモリの状態から開始します。
ワークスペース内のシンボリックリンクはたどらずにスキップされます。リンク先がワークスペースの外にある可能性があり、また受信側のホストでは別の場所に解決されてしまうためです。
ソースのルートは最初にチェックされます。ワークスペースまたはスキルバンドルのディレクトリがシンボリックリンクの場合は、それをたどらずに拒否されます。たどると、以下のエントリごとのチェックが実行される前に、コピー全体がバンドルの含むべきツリーの外に出てしまうためです。設定で実際のディレクトリを指定してから、もう一度エクスポートしてください。
その祖先も、比較によってではなく構造によって検証されます。デフォルトの場所を使用するソースは、インストールルート(shared、次に skills、次にバンドルディレクトリ。agents、次にエイリアス、次に workspace)から各コンポーネントを順にたどって開かれます。各ステップは直前のコンポーネントのハンドルを経由し、そのたびにシンボリックリンクは拒否されます。リダイレクトされた shared/skills や agents は、インストール内の別の場所を指していても拒否されます。スキルのコンテンツは shared/ 配下の実ディレクトリを通じてのみ読み取られ、デフォルトのワークスペースは agents/ 配下の実ディレクトリを通じてのみ読み取られるためです。インストールルートの_上位_にあるシンボリックリンクはオペレーター自身のパスであり、設定ファイルの場所と同じ信頼レベルで辿られます。オペレーターが別の場所に設定した workspace.path は例外です。その場合は設定された場所が境界となり、最後のコンポーネントのみがリンクとして拒否されます。
エクスポートの実行中もワークスペースは稼働したままです。所有するエージェントが通常のツール呼び出しを通じてワークスペースに書き込む可能性があるためです。そのため、コピー処理がパス名で再度開くことはありません。ワークスペースのルートは一度だけ開かれ、その配下のすべてのエントリは、それを格納しているディレクトリへのハンドルを介して and 分類され、読み取られます。両方の手順とも、シンボリックリンクをたどることを拒否します。これにより、スキップは確認処理ではなく保証となります。途中でエントリがリンクに置き換えられた場合、エクスポートはリダイレクトされるのではなく失敗します。
名前をたどることを拒否しても、そのバイト列がこのツリーに属することの証明にはなりません。そのため、コピーが読み取ろうとしているハンドルに対して、さらに2つのチェックを実行します。
複数の名前を持つファイルはスキップされます。ハードリンクは、ホスト上のどこにでも存在しうる1つのオブジェクトに対する2つ目の名前だからです。
開かれたオブジェクトは、分類されたものと同一でなければなりません。この比較は形状ではなく、ファイルシステムの同一性によって行います。同じディレクトリ内にあるリンク数1の通常ファイルという点では、エントリがunlinkされ、別のホストファイルに置き換えられた場合でも他のすべてのテストに合格してしまうためです。
リンクを拒否すべきなのは、リンク先がワークスペースの_内部_にある場合でも同じです。バンドルには独自のコンテンツ境界があり、ルート外へ出ないリンクであっても、その境界を越えることがあります。バンドルへの取り込みが許可されたファイルをmemory/brain.dbへのリンクに置き換えると、メモリストアが許可された名前のまま含まれてしまいます。また、取り込みが許可されたスキルを、バンドルが除外しているスキルへのリンクに置き換えると、除外されたコンテンツが含まれてしまいます。どちらの場合もワークスペースの外には出ませんが、いずれも許可されていません。
認証情報
スキーマで secret と指定されたフィールドはすべて空文字列にリセットされ、その設定パスはマニフェストの required_secrets に一覧表示されます。これらのパスは zeroclaw config set が受け付けるものと同じなので、バンドルへの入力はそのままコピー&ペーストで行えます。
zeroclaw config set providers.models.anthropic.main.api-key
zeroclaw config set mcp.servers.github.env.GITHUB_TOKEN
Scrubbing は想定ではなく検証されます。暗号化された設定の暗号文がクロージャに残っていた場合、エクスポートはバンドルを書き出さずに中止されます。
スクラビングが行わないこと
スクラブでは、スキーマで機密と指定されたフィールドを空白にします。これは認証情報の検出ではなく、保持している値の内容は確認しません。それ以外のクロージャ内のすべての文字列は、設定どおりにそのまま送信されます。
| 原文どおり引き継ぐ | 資格情報は次の場合にそこに保存されます |
|---|---|
mcp.servers.<name>.url | エンドポイントには、トークンまたは署名付きクエリ文字列が含まれます。 |
mcp.servers.<name>.command, .args | キーは env ではなく、コマンドラインで渡されます。 |
| providers.*.api_url | 自己ホスト型のエンドポイントにはアクセストークンが埋め込まれています。 |
マニフェストは stdio サーバーのコマンドラインを risk_flags にそのまま繰り返し記載するため、args 内の認証情報は設定フラグメントだけでなくマニフェストにも含まれます。
一部の引き継ぎフィールドは、秘密値ではなくても移行先ローカルの状態に依存します。requires_openai_auth = true は、移行先自身の OpenAI 認証ストアを必要とします。モデルプロバイダーおよび MCP の tls_ca_cert_path の値は、エクスポート元ホスト上のファイルを指しているため、移行先ローカルの CA パスに置き換える必要があります。allowed_roots は引き継がれ、extra_filesystem_roots としてフラグが付けられます。インポートしたプロファイルを有効にする前に、各パスを確認するか削除してください。
共有前にバンドルの値を確認してください。スキーマではなく、あなたの目で確認が必要な項目が2つあります。ここで説明されている文字列と、バンドルの内容はスキャンされませんで説明されている同梱ファイルです。
Bundleの内容はスキャンされません
Scrubbing(スクラビング)は、設定の閉包に対してスキーマ駆動で行われるパスです。バンドルに含まれるファイルには及ばず、それ以外の処理も同様にそこには及びません。フィルターはどのファイルを含めるかを決めるだけで、含まれたファイルの中身を検査するものは何もありません。
通常ファイルのうち、ワークスペースおよびスキルのフィルタを通過したものは、バイト単位でそのままコピーされ、シークレットのスキャンは一切行われません。まったくエクスポートされないものは、このページの別の箇所に記載しています: メモリストアとそのスナップショット、シンボリックリンク、特殊ファイル、ハードリンク、スキルバンドルの exclude で除外されたスキル、そしてスキルバンドルのルート直下にある散在する状態ファイル。
スキルバンドルのルートにある個別ファイルや特殊なエントリは、スキルコンテンツのツリーの外にあります。これらはコピーされず、再帰的なスキップ済みエントリ数にも含まれません。引き継ぎ時にこの違いが重要な場合は、ソースのバンドルルートを個別に確認してください。
つまり、ワークスペース内の .env ファイル、メモに貼り付けられた API トークン、リモート URL に認証情報を含む .git/config、エージェントが作業していた非公開文書は、いずれもそのままの状態で持ち出されます。エクスポートでは何個のファイルが含まれたかはわかりますが、その中身まではわかりません。
バンドルを共有する前に、リポジトリを公開する前に読むのと同じように、同梱ファイルを自分で確認してください。エクスポートが内容を保証できるのは、config.toml とマニフェストの部分です。
リスクフラグ
マニフェストの risk_flags リストは、受け入れ側のインストールの信頼境界を広げるバンドル内の各機能を、それを付与する設定パスと結び付けて列挙します。
| フラグ | Raised by |
|---|---|
full_autonomy | level = "full"、操作ごとの承認ゲートはありません。 |
filesystem_escape | _実効_ポリシーが制限なしになるのは、次のいずれかの場合です:workspace_only = false、level = "full"(workspace_only の値にかかわらず制限を無効化)、または workspace.unrestricted_filesystem = true。 |
sandbox_disabled | sandbox_enabled = false. |
approval_bypass | block_high_risk_commands または require_approval_for_medium_risk がオフになっている |
env_passthrough | shell_env_passthrough が空でない場合、ホストの環境変数がシェルのサブプロセスに渡されます。 |
extra_filesystem_roots | allowed_roots が空でないこと。 |
delegation_enabled | delegation_policy.mode = "allow". |
process_spawn | stdio MCPサーバーは、対象ホスト上でローカルプロセスを起動します。 |
untrusted_startup_context | MCPサーバーのpinned_resources:サーバー側で管理されるテキストで、起動時にシステムプロンプトへ読み込まれます。 |
carried_skills | このバンドルには、スキルバンドルの内容が含まれています。エージェントが読む指示と、エージェントが実行する可能性のあるファイルです。 |
信頼できないソースから得たバンドルは、信頼できない入力です。インポートする前に、スクリプトを実行する前に読むのと同じように、config.toml とマニフェストのリスクフラグを読んでください。
インポート中
未実装です。現在、バンドルは手動で適用します。config.toml を既存のインストールの設定にマージし、既存のエイリアスと衝突する場合は名前空間を付けてください。workspace/ をエージェントのワークスペースディレクトリにコピーします。各 skills/<alias>/ は、バンドルで directory が設定されていない限り、お使いの インストールがそのバンドルのエイリアスに対して解決するディレクトリ(既定では <install>/shared/skills/<alias>)にコピーします。最後に、required_secrets に記載された認証情報を用意してください。
将来のzeroclaw agents importが適用する2つのルールです。手動でマージする場合も、これに従ってください:
- インポートによって既存のエントリが上書きされることはありません。
risk_profiles.defaultを参照するバンドルが、お使いのdefaultプロファイルを変更することはあってはなりません。インポートされるエイリアスには名前空間を付けるか、エージェントがローカルのエイリアスを明示的に参照するように指定してください。 - マージ後の設定は、保存する前に
Config::validate()を通過しなければなりません。 参照先が存在しない参照は、次回起動時の不具合ではなく、インポートの失敗として扱われます。
パスを実体化する前に、ターゲットが表現できないルートエージェントまたはスキルバンドルのエイリアスの名前を変更し、フラグメント内の対応する参照を更新してください。これは、Unix で作成したバンドルを Windows に適用する場合に特に重要です。
フォーマットバージョン
Bundle は format_version = 1 を持ちます。エクスポートされたクロージャは自己完結しており、他のエントリが存在しない新規インストール環境でも、読み込みと検証が可能です。