可搬性契約
ラップトップとクラスターで異なる関心事はすべて、妥当なローカルデフォルトを持つ interface に閉じ込められます。エンジン内ではベンダー名を一切指定せず、ambient global も読みません。スケールアウトするには、launcher がこれらの interface の背後にある実装を差し替えます。| 関心事 | Interface | ローカルデフォルト | スケールアウト時の差し替え |
|---|---|---|---|
| run / journal storage | Store | .browserflow/store.sqlite の SQLite | Postgres / object store |
| secrets | Secrets | file / OS keychain | Vault / cloud secret manager |
| subprocess / spawn | SpawnCapability | local shell | E2B / remote sandbox (--sandbox e2b) |
| filesystem | FsCapability | local filesystem | E2B / remote sandbox |
| browser | BrowserCapability | local Chromium (Playwright) | remote / cloud browser pool |
| artifacts | Store (blobs) | filesystem | S3 / GCS |
| transport | (launcher) | CLI / Hono | API gateway / queue |
| concurrency | config | CPU-bound | worker pool / autoscale |
インメモリ store を使うには
BROWSERFLOW_STORE=:memory: を設定します(テストや一時的な CI 実行に便利です)。デフォルトパスの .browserflow/store.sqlite は必要になった時点で作成されます。BROWSERFLOW_SANDBOX=e2b は E2B backend を事前選択するため、呼び出しのたびに --sandbox e2b を指定する必要がありません。buildRunDeps の変更であり、書き換えではありません。そしてラップトップで検証済みの flow は、FlowSpec と Pack の digest が同一であるため、クラウドでも再現されます(tenet T3)。
これらのドキュメント全体で使う実行例は daily-price-watch です。browser tool の
search-price@1.2.0 が価格を読み取り、transform が形を整え、条件付きの http.post がシークレット webhook に通知します。この flow は、ラップトップで browserflow run から実行されても、gateway の背後で POST /flows/daily-price-watch/runs として実行されても変わりません。異なるのは、これらの interface の背後にある配線だけです。front の全体像は Launcher を参照してください。buildRunDeps で差し替えが起きる仕組み
エンジンである Rider は、注入された capability の集合に対して FlowSpec を実行し、それ以外には依存しません。cloud SDK を import せず、global を読まず、clock、RNG、network、filesystem、secrets には、渡された RunDeps を通じてのみ触れます(tenets T2 / T4)。
RunDeps に収まっているため、それを配線する launcher は小さくなります。どの launcher も同じ4つのことを行い、CLI launcher と queue-backed cloud worker の間で違うのは最初の1行だけです。
Config knobs
小さなconfig object は createRider に渡され、capability ではなくエンジンに属する設定を保持します。
config.maxConcurrency
ready な手順は config.maxConcurrency を上限として並行実行されます。この値は launcher が選びます。ローカル実行でのデフォルトは CPU-bound であり、スケールアウト時の差し替え先は worker pool または autoscale tier です。
foreach を持つ手順は N 個の child invocation に fan out し、その concurrency も同じ方法で制限されます。concurrency が変えるのは wall-clock だけで、記録される結果は変えません。独立した手順は2つの実行間で異なる順序で commit されることがありますが、Journal は effect の total order を記録し、foreach の gather は index で key 付けされるため、どちらの実行も同一にリプレイされます(tenet T2)。したがって、maxConcurrency を上げることは再現性の観点では常に安全です。実行 を参照してください。
schema_version negotiation
FlowSpec は schema_version literal(現在は "1.0")を持ちます。forward-compatibility は lenient parsing ではなく、明示的な version negotiation によって扱われます。すべての schema が .strict() であるため、Rider は認識できない field を黙って無視しません。
Rider は、自分が support する schema_version range を宣言します。ルールは次のとおりです。
| 状況 | 挙動 |
|---|---|
| FlowSpec minor が Rider の知る最新 minor 以下(same major) | 実行されます。additive change は minor を上げます(1.0 → 1.1)。 |
| FlowSpec minor が Rider の support する最新 minor より大きい | はっきり拒否されます。coerce も partial parse もされません(tenet T7)。 |
| major version bump | 保存済み FlowSpecs を書き換える migrate(1.x → 2.0) codemod が必要です。 |
schema_version を尊重できない Rider は、coerce せずに loud に失敗します。
versioning model の全体像は FlowSpec IR を、schema definitions は スキーマ を、関連する compile-time catalogue は 診断 を参照してください。
差し替えが再現される理由
ラップトップで検証済みの flow がbuildRunDeps の差し替え後にも再現されるのは、2つの事実が組み合わさるためです。
identity は digest
FlowSpec の identity は canonical form の
sha256 であり、その digest は flow の構造と pinned requires を対象にします。それぞれの requires は解決済み tool contract digest を持ちます。flow digest を pin することは、dependency closure 全体を pin することです。クラウドで実行される daily-price-watch は、ラップトップで使ったものとまったく同じ search-price@1.2.0 contract digest を使います。Secrets provider によって fresh に resolve され、secrets を宣言する tool にだけ注入されます。そのため、daily-price-watch の webhook secret は、それを実行する環境によって供給され、記録された Journal では安定した {secret:<slot>} placeholder として redact されます。シークレット と 実行 を参照してください。
クラウドへ移すと FlowSpec は変わりますか?
クラウドへ移すと FlowSpec は変わりますか?
いいえ。FlowSpec は安定した digest を持つ plain JSON であり、すべての launcher で一定です。変わるのは、launcher が渡す
buildRunDeps 実装です。ラップトップで検証済みの flow は、FlowSpec と Pack の digest が同一であるため、クラウドでも再現されます(tenet T3)。スケールアウト(concurrency の増加)で結果は変わりますか?
スケールアウト(concurrency の増加)で結果は変わりますか?
いいえ。独立した手順は並行実行されることがありますが、Journal は effect の total order を記録し、
foreach は index で gather するため、並行した手順を異なる順序で commit した2つの Run も同一にリプレイされます。maxConcurrency が影響するのは wall-clock だけです。Secrets は remote run にどう届きますか?
Secrets は remote run にどう届きますか?
Secrets は artifact の中を移動しません。isolated または remote environment が実行時に自身の
Secrets provider を通じて供給し、secrets を宣言する tool にだけ注入されます。Secrets が Journal に記録されることはありません。すべての Run、resume、--rerun replay で live に再 resolve されます。air-gapped environment ではどうなりますか?
air-gapped environment ではどうなりますか?
FlowSpec、pinned Pack、必要に応じて記録済み Journal を isolated environment に持ち込み、connectivity なしで再現します。Secrets は boundary 自身の
Secrets provider によってローカルに供給されます。Air-gapped deployment を参照してください。関連
Launcher
1つの FlowSpec が背後で実行される front です。CLI、REST、MCP、cron、CI、container、embedded library を含みます。
実行
Rider がどのように schedule し、決定論的であり続け、Journal から Run を resume または replay するか。
スキーマ
schema_version literal と、version negotiation を駆動する strict schemas。シークレット
Secrets が移動せず、記録されず、宣言した tool にだけ注入される理由。