
CRUMB
Generative Game Studio · Demo
1行のゲーム企画からプレイ可能な草案まで、エージェントの作業を見ながら介入します。
CRUMBは、カジュアルゲームのプロトタイピングのためのマルチエージェント・スタジオハーネスです。
CRUMB vocabulary
- spec
- build
- artifact
- qa check
- ac predicate
- verifier
- routing
- circuit breaker
- budget
- intervention
- transcript
- anti-deception
- studio
Spec: planner-lead · goal · question.socratic · step.design · spec · spec.update · acceptance_criteria · researcher · step.research.video · step.research_plan · ac_predicates · D1 spec_fit · research_plan_violationBuild: builder · build · spawn · sandwich.assembled.md · --append-system-prompt · agent-workspace · buildBuilderInputBundle · Phaser CDN · JuiceManager · PER_SPAWN_TIMEOUT_MS · juice_manager_missingArtifact: artifact.created · sha256 · artifacts/game.html · artifacts/game/index.html · pickEntry · artifact-watcher · version.released · manifest.toml · loc_own_bytes · VersionsQA Check: Phaser CDN · pickEntry · loc_own_bytes · qa_check · runQaCheck · qa.result · exec_exit_code · lint_passed · first_interaction · cross_browser_smoke · PLAYWRIGHT SMOKE · runtime_progress · qa-check-effect@v1 · QA_CHECK_TIMEOUT_MS · D2 exec · D6 portability · ac_results · ac_pass_count · deterministic · PASS WITHOUT EXEC · runtime_stalled_under_input · runtime_player_below_ground · forged_qa_result_attemptAC Predicate: acceptance_criteria · ACPredicateItem · predicate_js · runACInteractive · ac_predicates · ac_results · ac_pass_count · ACPredicateLedgerItem · verify_pass_with_ac_failureVerifier: D2 exec · D6 portability · verifier · judge.score · CourtEval · grader · critic · defender · regrader · step.judge · D1 spec_fit · verifier-llm · combineDimScore · PARTIAL · deviation · suggested_change · user_approve_partial · self_bias_risk_same_provider · cross_provider · buildVerifierInputBundle · ScorecardRouting: spawn · routeOnVerdict · verdict_pass · deviation · Critical · Important · Minor · suggested_change · rollback · handoff.rollback · sandwich_append · dispatch · adapter_swapped · user.veto · reduce(state, event)Circuit Breaker: circuit_breaker · CIRCUIT_OPEN_AT · adapter_override · adapter_swapped · circuit_open_auto_respawn · builder_circuit_open · claude-local · probeAdapter · adapter_substituted · intended_model · /swap · /reset-circuitBudget: spec.update · QA_CHECK_TIMEOUT_MS · builder_circuit_open · RESPEC_MAX · VERIFY_MAX · too_many_verify · TOKEN_BUDGET_HARD · token_exhausted · ratchet_revert · adaptive_stop · STUCK_THRESHOLD · budget_exhausted · PER_SPAWN_TIMEOUT_MSIntervention: PARTIAL · sandwich_append · STUCK_THRESHOLD · user.intervene · user.veto · user.approve · user.pause · user_approve_partial · ack · inbox.txt · parseInboxLine · /swap · /reset-circuit · consumed_intervene_ids · /api/sessions/:id/inboxTranscript: version.released · qa.result · qa-check-effect@v1 · dispatch · adapter_substituted · intended_model · ack · consumed_intervene_ids · transcript.jsonl · TranscriptWriter · ULID · O_APPEND · message.schema.json · reduce(state, event) · PURE REDUCER · REPLAY · replay_end_offset · CrumbState · parent_event_id · deterministic · audit_violations · applyEventFirewall · useTranscriptStream · otel.jsonlAnti-Deception: step.research_plan · buildBuilderInputBundle · JuiceManager · verify_pass_with_ac_failure · checkAntiDeception · PASS WITHOUT EXEC · self_bias_risk_same_provider · cross_provider · research_plan_violation · juice_manager_missing · runtime_stalled_under_input · runtime_player_below_ground · audit_violations · applyEventFirewall · forged_qa_result_attempt · buildVerifierInputBundleStudio: @crumb/studio · /api/stream · text/event-stream · useTranscriptStream · dockview-react · Pipeline · Scorecard · Waterfall · Versions · /api/sessions/:id/inbox · otel.jsonl
ゲームを作るエージェントと、それを判定する根拠を分けています。
1行のゲーム企画を、仕様、ビルド、実行検査へとつなぐローカルスタジオのデモです。すべての段階がJSONL transcriptに記録され、純粋なreducerが次のeffectを決め、副作用はdispatcherだけが実行します。実行QAとモデルの判定を分けて、通過、再設計、修正、人による介入のいずれかを決めます。
1行のゲーム企画を入力すると、Claude Code、Codex、Gemini CLIのエージェントがPlanner → Builder → 決定論的QA → Verifierの順に協働し、CRUMB Studioはイベント、進捗、成果物を表示して、自然言語による介入を受け付けます。
公開リポジトリをcloneして、ローカルで実行するデモです。
企画からプレイまで
企画が仕様、ビルド、実行QAへと進みます。すべての段階がtranscriptを経由し、actor同士が互いを呼び出すことはありません。
ゲームの企画 · 介入実行 · 判定: 企画 · 介入inboxにコマンドを書き込み
packages/studio1行のゲーム企画と自然言語の介入をStudioで入力すると、Studioはinboxにコマンドを書き込みます。Studioがtranscriptを直接編集することはありません。
inboxにコマンドを書き込み
packages/studioデータ: userイベントイベントループ · リプレイ · tailsrc/loop/coordinator.tsコーディネーターがinboxのコマンドを読み、userイベントとしてtranscriptに記録します。
イベントループ · リプレイ · tail
src/loop/coordinator.ts実行 · 判定: 順にreduce状態 → 次のeffectsrc/reducerライブのイベントはキューから1つずつreduceし、各イベントのeffectの順序を保ちます。dispatch自体は非同期で動きます。
状態 → 次のeffect
src/reducer実行 · 判定: effecteffectの実行 · actorのspawnsrc/dispatcher/live.tsreducerは、状態と次のeffectだけを決める純粋関数です。goalならPlanner、specならBuilder、buildならqa_checkを選びます。
actor → ハーネス · モデル
model-config · preset実行 · 判定: actorの設定src/dispatcher/live.tsactorをどのハーネス、プロバイダー、モデルで動かすかは、CLIフラグ > 設定 > プリセット > ambient > fallbackの順で決まります。actorは固定のプロバイダーではありません。
effectの実行 · actorのspawn
src/dispatcher/live.ts実行 · 判定: Plannerを実行Planner Lead · 仕様agent actor · CLIdispatcherは投影された入力でPlannerを実行します。条件付きのリサーチはPlannerのリサーチ計画と証拠の引き継ぎを経て続きますが、この構成図では折りたたんでいます。
Planner Lead · 仕様
agent actor · CLIデータ: spectranscript.jsonl · append-onlysrc/transcriptPlannerの仕様はtranscriptイベントとなり、reducerがそれをもとにBuilderを選びます。actor同士が互いを呼び出すことはありません。
effectの実行 · actorのspawn
src/dispatcher/live.ts実行 · 判定: Builderを実行Builder · ゲームを作成agent actor · CLIdispatcherがBuilderを実行します。同じactorが失敗を繰り返すとcircuitが開いてadapterを切り替え、それでも失敗が続けば停止します。
Builder · ゲームを作成
agent actor · CLIデータ: ファイルゲームファイルartifacts/Builderは、エントリファイル、ソース、アセットを成果物として書き込みます。
Builder · ゲームを作成
agent actor · CLIデータ: ビルド記録transcript.jsonl · append-onlysrc/transcriptbuildイベントとartifact.createdが、成果物のidentityとともにtranscriptに記録されます。
effectの実行 · actorのspawn
src/dispatcher/live.ts実行 · 判定: qa_check実行QA · 検査dispatcher/qa-runner.tsbuildイベントの後、reducerは成果物とビルドのidentity、受け入れ条件を含むqa_check effectを発行し、dispatcherがそれを実行します。
ゲームファイル
artifacts/データ: 実行対象実行QA · 検査dispatcher/qa-runner.ts実行QAは、実際の成果物をコードとブラウザの検査で実行します。既定のタイムアウト120秒は設定値です。
実行QA · 検査
dispatcher/qa-runner.tsデータ: qa.resulttranscript.jsonl · append-onlysrc/transcript成功でも失敗でも、結果はsystemのqa.resultイベントとして記録されます。検査が例外を投げても、失敗した項目を含む結果が記録されます。
検証の信頼境界
実行QAは成果物を実際に動かして得た根拠で、Verifierは投影された根拠を判定するモデルです。reducerは両者を突き合わせてから次の経路を選びます。
実行QA · 検査
dispatcher/qa-runner.tsデータ: qa.resulttranscript.jsonl · append-onlysrc/transcript成功でも失敗でも、結果はsystemのqa.resultイベントとして記録されます。検査が例外を投げても、失敗した項目を含む結果が記録されます。
transcript.jsonl · append-only
src/transcriptデータ: 根拠のみ判定入力の投影src/dispatcher/live.tsVerifierの入力は、最新のgoal、spec、build、qa.result、artifact.createdと、選ばれたリサーチの証拠から投影されます。コンテキストを絞るだけで、隔離や漏洩がないことを証明するものではありません。
判定入力の投影
src/dispatcher/live.tsデータ: 判定入力Verifier · モデルの判定Verifier actordispatcherは投影された入力でVerifierを実行します。
Verifier · モデルの判定
Verifier actorデータ: judge.scoretranscript.jsonl · append-onlysrc/transcriptVerifierの判定はjudge.scoreイベントとして記録されます。モデルの判断であり、実行についての事実ではありません。
状態 → 次のeffect
src/reducer実行 · 判定: スコア · QAの根拠anti-deception · スコア補正src/validatorjudge.scoreを受け取ると、reducerはそれをQAの結果、Builderのプロバイダー、リサーチ計画と証拠とともにanti-deception検査に渡します。
anti-deception · スコア補正
src/validatorデータ: 補正された判定判定のルーティングsrc/reducer成功した実行がないPASSはFAILになり、実行に関するスコアは決定論的なQAから補正されます。その他のルールは条件付きの補正であり、真実性一般の証明ではありません。
判定のルーティング
src/reducerデータ: 終了終了 · PASSまたは停止理由session donePASSならセッションはdoneで終わります。予算やcircuitによる停止もdoneで終わりますが停止理由が残るため、doneが常にPASSとは限りません。
失敗と人による介入
PARTIALは人へ、Criticalは再設計へ、ImportantとMinorは修正へ進み、予算やcircuitによる停止は停止理由を残します。
anti-deception · スコア補正
src/validatorデータ: 補正された判定判定のルーティングsrc/reducer成功した実行がないPASSはFAILになり、実行に関するスコアは決定論的なQAから補正されます。その他のルールは条件付きの補正であり、真実性一般の証明ではありません。
判定のルーティング
src/reducer実行 · 判定: PARTIALの確認ゲームの企画 · 介入PARTIALは人の確認を待ちます。
判定のルーティング
src/reducer実行 · 判定: 再設計 · 修正src/dispatcher/live.tsFAILとREJECTのうち、CriticalはPlannerへの再設計に、ImportantとMinorはBuilderへの修正フィードバックに戻り、いずれもdispatcherのeffectとして実行されます。
判定のルーティング
src/reducerデータ: 終了終了 · PASSまたは停止理由session donePASSならセッションはdoneで終わります。予算やcircuitによる停止もdoneで終わりますが停止理由が残るため、doneが常にPASSとは限りません。
ゲームの企画 · 介入実行 · 判定: 企画 · 介入inboxにコマンドを書き込み
packages/studio1行のゲーム企画と自然言語の介入をStudioで入力すると、Studioはinboxにコマンドを書き込みます。Studioがtranscriptを直接編集することはありません。
リプレイと観測
transcriptから状態を再構築してもeffectは実行されず、Studioは同じ記録を読んで表示します。
transcript.jsonl · append-only
src/transcriptデータ: 新しいイベント · リプレイイベントループ · リプレイ · tailsrc/loop/coordinator.tswriterはスキーマを検証し、ULIDと時刻を付けて追記します。リプレイ時は過去のイベントをreduceするだけで、そのeffectは再実行しません。
イベントループ · リプレイ · tail
src/loop/coordinator.ts実行 · 判定: 順にreduce状態 → 次のeffectsrc/reducerライブのイベントはキューから1つずつreduceし、各イベントのeffectの順序を保ちます。dispatch自体は非同期で動きます。
transcript.jsonl · append-only
src/transcript観測 · 報告: 読み取り · SSEイベント · 成果物の表示packages/studioStudioはtranscriptと成果物を読み、SSEで進捗、メトリクス、成果物を表示します。リモートのサービスに送るテレメトリではありません。
すべての接続を同じ太さで表示します。フローを選ぶと、その経路だけを番号付きで強調します。
- 実線 · 入力、結果、記録の流れる方向
- 破線 · 実行、判定、要求
- 長い点線 · 観測と報告、判定とは別
- 太い黒線 · 選んだフロー。番号は順序
- ボックス · コードまたは状態の境界、見出しに名前
- 内側のチップ · その境界の構成要素
- 点線ボックス · その境界の外
- オレンジの枠 · モデルが判断する場所
- イベントループ · reducer · dispatcher
- 記録 · 設定 · 成果物
- 決定的な検査 · 補正
- Studio · actor
公開コミットf5e17c0のコードパスから描きました。actorはランタイムの実行役割であり、このリポジトリの開発に使ったコーディングエージェントとは別のものです。
- 状態の源
- transcriptが状態の源であり、reducerは純粋関数です。副作用(actorの実行、QA、ファイルの書き込み)を行うのはdispatcherだけなので、リプレイは副作用なしで状態を再構築します。
- リプレイの範囲
- リプレイで得られるのは同じ状態であり、LLMの生成やブラウザ・ネットワークの挙動まで決定的になるわけではありません。
- 判定の範囲
- 実行QAは設定された検査だけを確認し、Verifierのスコアは根拠のひとつです。どちらも、ゲームのすべての挙動や面白さ、ユーザーの満足度を測るものではありません。