
CRUMB
Generative Game Studio · Demo
한 줄 게임 기획에서 플레이 가능한 초안까지, 에이전트의 작업을 보면서 개입합니다.
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
게임을 만드는 에이전트와, 실행을 판정하는 근거를 나눕니다.
한 줄의 게임 제안을 명세 · 빌드 · 실행 검사로 잇는 로컬 스튜디오 데모입니다. 모든 단계가 JSONL transcript에 남고, 순수 reducer가 다음 effect를 정하며, 부작용은 dispatcher만 실행합니다. 실제 실행 QA와 모델 판정을 나눠 통과 · 재설계 · 재수정 · 사람 개입을 정합니다.
한 줄로 게임을 제안하면 Claude Code · Codex · Gemini CLI 에이전트가 Planner → Builder → 결정적 QA → Verifier 순서로 협업하고, CRUMB Studio에서 이벤트와 진행 상황, 산출물을 보며 자연어로 개입할 수 있습니다.
공개 저장소를 받아 로컬에서 바로 실행하는 데모입니다.
제안에서 플레이까지
제안이 명세 · 빌드 · 실행 QA로 이어집니다. 모든 단계가 transcript를 거치며, actor끼리 직접 부르지 않습니다.
게임 제안 · 개입실행 · 판정: 제안 · 개입inbox 명령 쓰기
packages/studio한 줄 게임 제안과 자연어 개입을 Studio에서 입력하면, Studio는 inbox에 명령을 씁니다. Studio가 transcript를 직접 고치지는 않습니다.
inbox 명령 쓰기
packages/studio데이터: user 이벤트이벤트 루프 · replay · tailsrc/loop/coordinator.ts코디네이터가 inbox 명령을 읽어 user 이벤트로 바꿔 transcript에 남깁니다.
이벤트 루프 · replay · tail
src/loop/coordinator.ts실행 · 판정: 순서대로 reduce상태 → 다음 effectsrc/reducer실시간 이벤트는 큐에서 하나씩 reduce하고, 각 이벤트의 effect 순서를 지킵니다. dispatch 자체는 비동기로 돕니다.
상태 → 다음 effect
src/reducer실행 · 판정: effecteffect 실행 · actor spawnsrc/dispatcher/live.tsreducer는 순수 함수로 상태와 다음 effect만 정합니다. goal이 오면 Planner, spec이 오면 Builder, build가 오면 qa_check를 고릅니다.
actor → harness · 모델
model-config · preset실행 · 판정: actor 설정src/dispatcher/live.ts어떤 harness · 공급사 · 모델로 actor를 실행할지는 CLI 지정 > 설정 > 프리셋 > ambient > fallback 순서로 정해집니다. actor는 고정된 공급사가 아닙니다.
effect 실행 · actor spawn
src/dispatcher/live.ts실행 · 판정: Planner 실행Planner Lead · 명세agent actor · CLIdispatcher가 투영된 입력으로 Planner를 실행합니다. 조건부 리서치는 Planner의 리서치 계획과 증거 handoff로 이어지며, 이 지도에서는 접어 두었습니다.
Planner Lead · 명세
agent actor · CLI데이터: spectranscript.jsonl · append-onlysrc/transcriptPlanner의 명세가 transcript 이벤트가 되고, reducer가 그 spec을 보고 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가 artifact · build 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/validatorreducer는 judge.score를 받으면 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/studio한 줄 게임 제안과 자연어 개입을 Studio에서 입력하면, Studio는 inbox에 명령을 씁니다. Studio가 transcript를 직접 고치지는 않습니다.
재생과 관측
transcript에서 상태를 다시 만들 때는 effect를 실행하지 않고, Studio는 같은 기록을 읽어 보여 줍니다.
transcript.jsonl · append-only
src/transcript데이터: 새 이벤트 · replay이벤트 루프 · replay · tailsrc/loop/coordinator.tswriter는 schema를 검사하고 ULID · 시각을 붙여 append-only로 씁니다. 재생할 때는 지난 이벤트를 reduce만 하고 effect는 다시 실행하지 않습니다.
이벤트 루프 · replay · tail
src/loop/coordinator.ts실행 · 판정: 순서대로 reduce상태 → 다음 effectsrc/reducer실시간 이벤트는 큐에서 하나씩 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만 실행하므로, 재생은 effect 없이 상태만 다시 만듭니다.
- 재생의 범위
- 재생으로 같은 상태를 얻는다는 뜻이며, LLM 생성이나 브라우저 · 네트워크 동작까지 결정적이라는 뜻은 아닙니다.
- 판정의 범위
- 실행 QA는 설정한 검사만 확인하고, Verifier 점수는 근거의 한 갈래입니다. 게임의 모든 동작이나 재미, 사용자 만족을 측정하지 않습니다.