CRUMB 로고의 식빵 캐릭터만 남긴 이미지: 오른쪽 위 모서리를 한 입 베어 문, 웃는 얼굴의 식빵
전시실로

CRUMB

Generative Game Studio · Demo

한 줄 게임 기획에서 플레이 가능한 초안까지, 에이전트의 작업을 보면서 개입합니다.

CRUMB는 캐주얼 게임 프로토타이핑을 위한 멀티 에이전트 스튜디오 하네스입니다.

설계·개발 · AI 코딩 에이전트 활용

  • CLI로컬 데모
  • 웹 Studio로컬 데모

CRUMB vocabulary

Lens
Game Pipeline
Build
Runtime Verification
Control Plane
Repair
Evidence
  1. spec
  2. build
  3. artifact
  1. qa check
  2. ac predicate
  3. verifier
  1. routing
  2. circuit breaker
  3. budget
  4. intervention
  1. transcript
  2. anti-deception
  3. 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에서 이벤트와 진행 상황, 산출물을 보며 자연어로 개입할 수 있습니다.

공개 저장소를 받아 로컬에서 바로 실행하는 데모입니다.

시스템 구성도 · 공개 커밋 f5e17c0의 코드 경로로 그림
CRUMB 스튜디오 시스템사람은 Studio에서 게임을 제안하고 개입하며, Studio는 inbox에 명령을 씁니다. 코디네이터가 inbox와 transcript의 새 이벤트를 순서대로 reducer에 넘기면, 순수 reducer가 상태와 다음 effect를 정하고 dispatcher만 부작용을 실행합니다. Planner의 명세, Builder의 빌드 · 산출물, 실행 QA의 결과, Verifier의 판정이 모두 transcript 이벤트로 남습니다. Verifier는 투영된 근거만 받고, reducer는 그 점수를 QA 결과로 검사 · 보정한 뒤 PASS면 종료, PARTIAL이면 사람 확인, 그 밖에는 재설계나 재수정으로 보냅니다.게임 제안 · 개입로컬에서 쓰는 사람packages/studio이벤트 · 산출물 보기inbox 명령 쓰기src/transcripttranscript.jsonl · append-onlysrc/loop/coordinator.ts이벤트 루프 · replay · tailsrc/reducer상태 → 다음 effect판정 라우팅session done종료 · PASS 또는 중단 이유src/dispatcher/live.tseffect 실행 · actor spawn판정 입력 투영model-config · presetactor → harness · 모델agent actor · CLIPlanner Lead · 명세Builder · 게임 작성artifacts/게임 파일dispatcher/qa-runner.ts실행 QA · 결정적 검사Verifier actorVerifier · 모델 판정src/validatoranti-deception · 점수 보정사람 · Studio이벤트 제어transcript가 상태의 원본작업 에이전트 · 산출물검증 · 결정1제안 · 개입2user 이벤트3순서대로 reduce4effect5actor 설정6Planner 실행7spec8Builder 실행9파일10빌드 기록11qa_check12실행 대상13qa.result1qa.result2근거만 투영3판정 입력4judge.score5점수 · QA 근거6보정된 판정7종료1보정된 판정2PARTIAL 확인3재설계 · 재수정4종료5제안 · 개입1새 이벤트 · replay2순서대로 reduce3읽기 · SSE

제안에서 플레이까지

제안이 명세 · 빌드 · 실행 QA로 이어집니다. 모든 단계가 transcript를 거치며, actor끼리 직접 부르지 않습니다.

  1. 게임 제안 · 개입실행 · 판정: 제안 · 개입inbox 명령 쓰기packages/studio

    한 줄 게임 제안과 자연어 개입을 Studio에서 입력하면, Studio는 inbox에 명령을 씁니다. Studio가 transcript를 직접 고치지는 않습니다.

  2. inbox 명령 쓰기packages/studio데이터: user 이벤트이벤트 루프 · replay · tailsrc/loop/coordinator.ts

    코디네이터가 inbox 명령을 읽어 user 이벤트로 바꿔 transcript에 남깁니다.

  3. 이벤트 루프 · replay · tailsrc/loop/coordinator.ts실행 · 판정: 순서대로 reduce상태 → 다음 effectsrc/reducer

    실시간 이벤트는 큐에서 하나씩 reduce하고, 각 이벤트의 effect 순서를 지킵니다. dispatch 자체는 비동기로 돕니다.

  4. 상태 → 다음 effectsrc/reducer실행 · 판정: effecteffect 실행 · actor spawnsrc/dispatcher/live.ts

    reducer는 순수 함수로 상태와 다음 effect만 정합니다. goal이 오면 Planner, spec이 오면 Builder, build가 오면 qa_check를 고릅니다.

  5. actor → harness · 모델model-config · preset실행 · 판정: actor 설정src/dispatcher/live.ts

    어떤 harness · 공급사 · 모델로 actor를 실행할지는 CLI 지정 > 설정 > 프리셋 > ambient > fallback 순서로 정해집니다. actor는 고정된 공급사가 아닙니다.

  6. effect 실행 · actor spawnsrc/dispatcher/live.ts실행 · 판정: Planner 실행Planner Lead · 명세agent actor · CLI

    dispatcher가 투영된 입력으로 Planner를 실행합니다. 조건부 리서치는 Planner의 리서치 계획과 증거 handoff로 이어지며, 이 지도에서는 접어 두었습니다.

  7. Planner Lead · 명세agent actor · CLI데이터: spectranscript.jsonl · append-onlysrc/transcript

    Planner의 명세가 transcript 이벤트가 되고, reducer가 그 spec을 보고 Builder를 고릅니다. actor끼리 서로 부르지 않습니다.

  8. effect 실행 · actor spawnsrc/dispatcher/live.ts실행 · 판정: Builder 실행Builder · 게임 작성agent actor · CLI

    dispatcher가 Builder를 실행합니다. 같은 actor가 거듭 실패하면 circuit이 열려 adapter를 바꾸고, 그래도 반복되면 멈춥니다.

  9. Builder · 게임 작성agent actor · CLI데이터: 파일게임 파일artifacts/

    Builder가 진입 파일 · 소스 · 에셋을 산출물로 씁니다.

  10. Builder · 게임 작성agent actor · CLI데이터: 빌드 기록transcript.jsonl · append-onlysrc/transcript

    build 이벤트와 artifact.created가 산출물의 identity와 함께 transcript에 남습니다.

  11. effect 실행 · actor spawnsrc/dispatcher/live.ts실행 · 판정: qa_check실행 QA · 결정적 검사dispatcher/qa-runner.ts

    build 이벤트 뒤 reducer가 artifact · build identity와 수락 조건을 담은 qa_check effect를 내고, dispatcher가 실행합니다.

  12. 게임 파일artifacts/데이터: 실행 대상실행 QA · 결정적 검사dispatcher/qa-runner.ts

    실행 QA는 실제 산출물을 코드 · 브라우저 검사로 실행합니다. 기본 시간 제한 120초는 설정값입니다.

  13. 실행 QA · 결정적 검사dispatcher/qa-runner.ts데이터: qa.resulttranscript.jsonl · append-onlysrc/transcript

    성공이든 실패든 system qa.result 이벤트로 남습니다. 검사 중 예외가 나도 실패 항목을 담은 결과가 기록됩니다.

검증의 신뢰 경계

실행 QA는 산출물을 직접 실행한 근거이고, Verifier는 투영된 근거로 판정하는 모델입니다. reducer가 두 근거를 맞춰 본 뒤에 다음 경로를 정합니다.

  1. 실행 QA · 결정적 검사dispatcher/qa-runner.ts데이터: qa.resulttranscript.jsonl · append-onlysrc/transcript

    성공이든 실패든 system qa.result 이벤트로 남습니다. 검사 중 예외가 나도 실패 항목을 담은 결과가 기록됩니다.

  2. transcript.jsonl · append-onlysrc/transcript데이터: 근거만 투영판정 입력 투영src/dispatcher/live.ts

    Verifier 입력은 최신 goal · spec · build · qa.result · artifact.created와 고른 리서치 증거로 투영됩니다. 문맥을 줄일 뿐, 격리나 유출 없음의 증명은 아닙니다.

  3. 판정 입력 투영src/dispatcher/live.ts데이터: 판정 입력Verifier · 모델 판정Verifier actor

    dispatcher가 투영된 입력으로 Verifier를 실행합니다.

  4. Verifier · 모델 판정Verifier actor데이터: judge.scoretranscript.jsonl · append-onlysrc/transcript

    Verifier의 판정은 judge.score 이벤트로 남습니다. 모델의 판정이며 실행의 사실이 아닙니다.

  5. 상태 → 다음 effectsrc/reducer실행 · 판정: 점수 · QA 근거anti-deception · 점수 보정src/validator

    reducer는 judge.score를 받으면 QA 결과, Builder 공급사, 리서치 계획 · 증거와 함께 anti-deception 검사에 넘깁니다.

  6. anti-deception · 점수 보정src/validator데이터: 보정된 판정판정 라우팅src/reducer

    성공한 실행이 없는데 PASS면 FAIL로 바꾸고, 실행 관련 점수는 결정적 QA로 고칩니다. 그 밖의 규칙은 조건부 보정이며 진실성 일반의 증명은 아닙니다.

  7. 판정 라우팅src/reducer데이터: 종료종료 · PASS 또는 중단 이유session done

    PASS면 done입니다. 예산 · circuit으로 멈춘 경우도 done이지만 중단 이유가 따로 남으므로, done이 늘 PASS는 아닙니다.

실패와 사람 개입

PARTIAL은 사람 확인, Critical은 재설계, Important · Minor는 재수정으로 가고, 예산 · circuit으로 멈추면 중단 이유를 남깁니다.

  1. anti-deception · 점수 보정src/validator데이터: 보정된 판정판정 라우팅src/reducer

    성공한 실행이 없는데 PASS면 FAIL로 바꾸고, 실행 관련 점수는 결정적 QA로 고칩니다. 그 밖의 규칙은 조건부 보정이며 진실성 일반의 증명은 아닙니다.

  2. 판정 라우팅src/reducer실행 · 판정: PARTIAL 확인게임 제안 · 개입

    PARTIAL이면 사람의 확인을 기다립니다.

  3. 판정 라우팅src/reducer실행 · 판정: 재설계 · 재수정src/dispatcher/live.ts

    FAIL · REJECT 가운데 Critical은 Planner 재설계로, Important · Minor는 Builder 수정 피드백으로 갑니다. 모두 dispatcher의 effect로 실행됩니다.

  4. 판정 라우팅src/reducer데이터: 종료종료 · PASS 또는 중단 이유session done

    PASS면 done입니다. 예산 · circuit으로 멈춘 경우도 done이지만 중단 이유가 따로 남으므로, done이 늘 PASS는 아닙니다.

  5. 게임 제안 · 개입실행 · 판정: 제안 · 개입inbox 명령 쓰기packages/studio

    한 줄 게임 제안과 자연어 개입을 Studio에서 입력하면, Studio는 inbox에 명령을 씁니다. Studio가 transcript를 직접 고치지는 않습니다.

재생과 관측

transcript에서 상태를 다시 만들 때는 effect를 실행하지 않고, Studio는 같은 기록을 읽어 보여 줍니다.

  1. transcript.jsonl · append-onlysrc/transcript데이터: 새 이벤트 · replay이벤트 루프 · replay · tailsrc/loop/coordinator.ts

    writer는 schema를 검사하고 ULID · 시각을 붙여 append-only로 씁니다. 재생할 때는 지난 이벤트를 reduce만 하고 effect는 다시 실행하지 않습니다.

  2. 이벤트 루프 · replay · tailsrc/loop/coordinator.ts실행 · 판정: 순서대로 reduce상태 → 다음 effectsrc/reducer

    실시간 이벤트는 큐에서 하나씩 reduce하고, 각 이벤트의 effect 순서를 지킵니다. dispatch 자체는 비동기로 돕니다.

  3. transcript.jsonl · append-onlysrc/transcript관측 · 보고: 읽기 · SSE이벤트 · 산출물 보기packages/studio

    Studio는 transcript와 산출물을 읽어 SSE로 진행 · 지표 · 산출물을 보여 줍니다. 외부 서비스로 보내는 원격 계측이 아닙니다.

모든 연결을 같은 굵기로 보여 줍니다. 흐름을 고르면 그 경로만 번호와 함께 강조됩니다.

  • 실선 · 입력 · 결과 · 기록이 흐르는 방향
  • 파선 · 실행 · 판정 · 요청
  • 긴 점선 · 관측 · 보고, 판정과 별개
  • 굵은 검은 선 · 고른 흐름, 번호는 순서
  • 상자 · 코드 · 상태 경계, 머리말에 이름
  • 안쪽 칩 · 그 경계의 구성 요소
  • 점선 상자 · 그 경계 밖
  • 주황 테두리 · 모델이 판단하는 곳
  • 이벤트 루프 · reducer · dispatcher
  • 기록 · 설정 · 산출물
  • 결정적 검사 · 보정
  • Studio · actor

공개 커밋 f5e17c0의 코드 경로로 그렸습니다. actor는 런타임의 실행 역할이며, 이 저장소를 만든 코딩 에이전트와 다릅니다.

상태의 원본
transcript가 상태의 원본이고 reducer는 순수 함수입니다. 부작용(actor 실행, QA, 파일 쓰기)은 dispatcher만 실행하므로, 재생은 effect 없이 상태만 다시 만듭니다.
재생의 범위
재생으로 같은 상태를 얻는다는 뜻이며, LLM 생성이나 브라우저 · 네트워크 동작까지 결정적이라는 뜻은 아닙니다.
판정의 범위
실행 QA는 설정한 검사만 확인하고, Verifier 점수는 근거의 한 갈래입니다. 게임의 모든 동작이나 재미, 사용자 만족을 측정하지 않습니다.