| name | crumb-deep-dive |
| description | >- |
Crumb Deep-Dive Ritual (4-๋จ๊ณ ์ค์บํด๋)
Origin: 2026-05-05 ์ฌ์ฉ์ directive โ "์ถ์ ํ์ง ๋ง๊ณ ๋ก๊ทธ ํน์ ์ด๋ฒคํธ์
๊ฐ์ ๊ด์ธก์ฑ ๋ฐ์ดํฐ๋ก ์์ธ ํ์ ํด" + "์ด ์ ์ฐจ๋ฅผ ์ค์บํด๋๋ก ๊ตณํ๊ณ ".
Live smoke 01KQVSE9PC์์ Studio Output blackbox ์ง๋จ์ Playwright headless
probe๋ก ์ ํํ ์ก์ ๊ฒ์ด first canonical example.
4 stages โ every feature/fix follows this order
Stage 1 โ Implement (narrow PR)
- ํ PR = ๋จ์ผ ์๋ (1-3 commits, 100-300 LOC). PR-Bundle์ architectural
๊ด๋ จ ์๋ ํ๋๋ก ํ์ .
- Pre-PR Quality Gate:
npm run verify (lint:all + typecheck + format:check +
zod:check-envelope + check-lockfile + test + build).
- Sandwich ํ์ผ ๋ณ๊ฒฝ ์
npm run sandwich:update-hashes.
- Lockfile platform-deps ๊ฒ์ฆ:
node scripts/check-lockfile-platform-deps.mjs
(macOS @emnapi pruning ์์ฃผ ์ฌ๋ฐ).
- Commit: imperative mood + ๋ณ๊ฒฝ ์๋ + 1-line ์ ์ง๊ธ ๋ช
์.
Stage 2 โ Verify with raw data (NOT ์ถ์ )
์ ํ ๊ฐ๋ฅํ verification surface 5๊ฐ์ง โ ํญ์ โฅ1๊ฐ ์ฌ์ฉ:
- Live transcript โ
~/.crumb/projects/<id>/sessions/<ulid>/transcript.jsonl
์ง์ jq๋ก query. event kinds / metadata / scores ๋ฑ 1์ฐจ source.
- Playwright headless probe โ
scripts/diag-output.mjs ํจํด (์์ผ๋ฉด ์ฌ์ฌ์ฉ,
์์ผ๋ฉด ad-hoc ์์ฑ). page.goto + console + pageerror + network ์บก์ฒ + screenshot.
- Studio API endpoint โ
curl -s http://127.0.0.1:7321/api/{health,doctor, sessions} ๋๋ /api/sessions/:id/.... server-side state truth.
- Adapter spawn log โ
<sessionDir>/agent-workspace/<actor>/spawn-*.log.
subprocess์ raw stdout/stderr.
- External API/docs โ Vertex AI / Replicate / ElevenLabs official model
docs, GitHub issues. WebFetch๋ก canonical answer.
ํ์ง ๋ง ๊ฒ:
- "์๋ง ~ ๋๋ฌธ์ผ ๊ฒ๋๋ค" โ guesswork ๊ธ์ง
- "๋ณดํต ~ ์
๋๋ค" โ ์ผ๋ฐํ ๊ธ์ง
- ์ฌ์ฉ์ ์๋ ์ถ์ธก โ ์ง์ ๋ฌป๊ธฐ
ํด์ผ ํ ๊ฒ:
- ๋ฐ์ดํฐ location ๋ช
์ (file path + line number ๋๋ API endpoint + jq path)
- ๊ฒฐ์ ์ evidence chain โ A โ B โ C ์ฌ์ค sequence
- ์ฌ๋ฌ evidence๊ฐ ๊ฐ์ ๊ฒฐ๋ก ์ ๊ฐ๋ฆฌํค๋ฉด ๋ช
์ ("transcript + Playwright + spawn
log 3 source ๋ชจ๋ X๋ฅผ ์ง๋ชฉ")
Stage 3 โ Root cause report
Format (โค500 words, markdown):
## ๊ด์ธก์ฑ ๋ฐ์ดํฐ๋ก ํ์ โ <์ฆ์>
### Evidence
- <source 1>: <data citation> โ <fact 1>
- <source 2>: <data citation> โ <fact 2>
- ...
### Root cause
<file:line + 1-line ์ธ๊ณผ chain>
### Implication
<system invariants ์๋ฐฐ ์ฌ๋ถ / Karpathy P# ์๋ฐฐ ์ฌ๋ถ / ๊ธฐ์กด PR๊ณผ์
๊ด๊ณ โ ๊ฐ์ค ๋ถ์ ๋ PR์ด ์์ผ๋ฉด ๋ช
์>
### Improvement options
| ์ต์
| LOC | trade-off |
| A | ~N | ... |
| B | ~M | ... |
| ์ถ์ฒ | โ
<์ต์
> + ์ด์ |
ํ์ ์์:
- file:line ๋๋ endpoint ์ ํ ์ธ์ฉ
- ๊ฐ์ค / ๋ถ์ ๋ ๊ฐ์ค ๋ช
์ (์: "iframe sandbox ์ฐจ๋จ ๊ฐ์ค โ Playwright 200
OK๋ก ํ๊ธฐ")
- Improvement๋ ์ต์
๋งคํธ๋ฆญ์ค + ์ถ์ฒ ํํ โ ์ฌ์ฉ์ ๊ฒฐ์ ๊ถ ๋ณด์กด
Stage 4 โ Improvement PR (๋ณ๊ฐ)
- Stage 3 ๋ณด๊ณ ๋ฅผ ๊ทธ๋๋ก PR description์ "Why" section์ ์ธ์ฉ
- Stage 1 PR๊ณผ ๋ค๋ฅธ branch + ๋ค๋ฅธ PR number. ๊ฐ์ PR์ ๋ฌถ์ง ์์ (์ฌ์ฉ์๊ฐ
Stage 3 ๋ณด๊ณ ๋ณด๊ณ ๊ฒฐ์ ํ ์งํ).
- ์์ ๋จ์๋ก โ ํ๋์ root cause๋ง fix.
- ๋จธ์ง ํ main์ ๋ฐ์๋๋ฉด ์ฆ์ Stage 1์ผ๋ก ritual ๋ค์ ์์ ๊ฐ๋ฅ (๋๋ ๋ค๋ฅธ
feature๋ก ์ด๋).
When to skip the ritual
- Trivial change (๋จ์ผ file rename / typo / format-only): Stage 2-3 skip,
๋ฐ๋ก commit.
- Reverting a regression when the regression cause is already documented in
prior commit history / PR description: ๊ทธ ์ธ์ฉ์ผ๋ก Stage 3 ๋์ฒด ๊ฐ๋ฅ.
- Pure refactor with no behavior change: ๊ธฐ์กด tests๊ฐ Stage 2 ์ญํ โ
์ฌ์ฉ์๊ฐ ๋ณ๋ ๋ณด๊ณ ์๊ตฌ ์๋ง Stage 3.
๊ทธ ์ธ ๋ชจ๋ feature / bug fix: 4-stage ๊ฐ์ .
Examples
Example 1 โ Studio Output blackbox (2026-05-05, canonical)
- Stage 1: ์ฌ์ฉ์๊ฐ "Output ์ฌ์ ํ ๋ธ๋๋ฐ์ค" ๋ณด๊ณ . ์ถ์ ์ต์
5๊ฐ (CDN ์ฐจ๋จ,
WebGL fail, JS error, sandbox CSP, canvas size 0).
- Stage 2:
scripts/diag-output.mjs ์์ฑ. Playwright headless 9 modules
๋ก๋ + console + pageerror + canvas ์บก์ฒ. ๊ฒฐ๊ณผ: ๋ชจ๋ 200 OK / pageerror = "Identifier 'remaining' has already been declared" 1๊ฑด / canvas ๋ฏธ์์ฑ.
- Stage 3: file:line ์ ํ ์ธ์ฉ โ
artifacts/game/src/scenes/GameScene.js: 231 + :239 const remaining ์ค๋ณต. 5๊ฐ ์ถ์ ์ต์
์ค 4๊ฐ ๋ฐ์ดํฐ๋ก ํ๊ธฐ (CDN
200 OK / WebGL warning๋ง / sandbox attr ๋ฌด๊ด / canvas 0์ด ์๋๋ผ ๋ฏธ์์ฑ).
Root cause = builder LLM ์์ฑ ์ค์. Improvement ์ต์
A (์์์ ), B (์ฌ๋น๋),
C (qa-runner spec-driven boot predicate์ผ๋ก ๋ฏธ๋ฆฌ ์ก๊ธฐ โ PR #231 ์ ์ฉ๋จ,
follow-up).
- Stage 4: PR #233 (Output console rail) โ ๊ฐ์ case๊ฐ ๋ค์์ ๋ฐ์ํ๋ฉด
Studio๊ฐ ์ฆ์ surfaceํ๋๋ก iframe contentWindow.console hooking.
Example 2 โ Provider mix 0% on google/openai (2026-05-05)
- Stage 1: ์ฌ์ฉ์๊ฐ "google/openai 0% ๊ฐ ์๋ชป๋จ" ๋ณด๊ณ .
- Stage 2: transcript jq query โ
metadata.provider ๋ณ event count + tokens.
๊ฒฐ๊ณผ: google 5 events / step.research.video์ 27,902 tokens_in stamped /
agent.stop์๋ null.
- Stage 3:
ServiceMap.tsx:154 computeProviderMix๊ฐ agent.stop ๋ง sum
ํ๋ ๊ฒ root cause. gemini-sdk adapter๋ SpawnResult.usage ๋ฏธ๋ฐํ. ๋ ๊ณณ fix.
- Stage 4: PR #233 (d) โ ServiceMap.tsx + gemini-sdk.ts ๋์ ์์ .
Tooling shortcut
์์ฃผ ์ฐ๋ jq pattern (transcript inspection):
TX=~/.crumb/projects/<id>/sessions/<ulid>/transcript.jsonl
jq -r '.kind' "$TX" | sort | uniq -c | sort -rn
jq -r '.metadata.provider // "(none)"' "$TX" | sort | uniq -c
tail -10 "$TX" | jq -r '"\(.ts | split("T")[1] | split(".")[0]) [\(.from)] \(.kind) | \(.body // "" | .[0:120])"'
jq -r 'select(.metadata.tokens_in or .metadata.tokens_out) | {kind, from, in: .metadata.tokens_in, out: .metadata.tokens_out}' "$TX"
jq -r 'select(.kind=="judge.score" or .kind=="verify.result" or .kind=="handoff.rollback") | {ts, body: (.body | .[0:150])}' "$TX"
์์ฃผ ์ฐ๋ Playwright probe (scripts/diag-output.mjs): page load + console +
pageerror + network + canvas state + screenshot.
References
- AGENTS.md ยงArchitecture invariants โ Stage 2-3๋ invariant ์๋ฐฐ ์ฌ๋ถ ์ฒดํฌ
ํ๋ ์๋ฆฌ
.skills/anti-deception-checklist/SKILL.md (gitignored) โ Stage 3์์
"fake success" / "test deletion" ๋ฑ anti-pattern ํํผ ์ฒดํฌ๋ฆฌ์คํธ
.skills/agent-ops-debugging/SKILL.md โ multi-agent system root cause
๋ถ์ ํจํด (Safe Default anti-pattern, ContextVar DI ๋ฑ)
wiki/synthesis/ โ Stage 3 ๋ณด๊ณ ๊ฐ wiki page๋ก promote๋ ๊ฐ์น๊ฐ ์์ ๋
์์ฑ ์์น