[{"content":"Claude Code\u0026rsquo;s source code got leaked. Controversy and debate followed, but overnight someone had already built Claw Code and was racking up stars from around the world. This was clearly the time to go all in.\nFear not, I\u0026rsquo;m coming! I get home from work and it\u0026rsquo;s already late, but that\u0026rsquo;s fine. Energy drink in my right hand, coffee in my left. I slept four hours a night for two days straight.\nI had Claude Code analyze Claw Code while I read through the source analysis docs whenever I could.\nAfter reading the harness engineering guide, an idea hit me. I figured I should build a harness for bringing AI into the finance industry — the field I actually work in — something nobody else had jumped on yet.\nI didn\u0026rsquo;t have deep expertise since it\u0026rsquo;s not my core work, but I built it anyway. I just needed to make something. (I\u0026rsquo;ll fix it up soon.)\nCome forth, you will find honor in death! Then I analyzed Claw Code and it hit me. I didn\u0026rsquo;t read all 1,884 files, but everything I\u0026rsquo;d been painstakingly building with hooks and CLAUDE.md was already designed into the system. Permission management, tool routing, context handling — all of it.\nWhat I\u0026rsquo;d built and intended turned out to be square wheels\u0026hellip;\nBut because I\u0026rsquo;d put in the effort to roll those square wheels, the file structure clicked instantly when I saw it.\nFear is the first of many foes! Here\u0026rsquo;s a secret I\u0026rsquo;ve never told anyone. I used to speak to AI with formal language.\n\u0026#39;The time of man has come to an end\u0026#39; - Blitzcrank Anxious that the age of AI domination was coming, I wrote my prompts with \u0026ldquo;please\u0026rdquo; and \u0026ldquo;would you kindly.\u0026rdquo; I even had a review pipeline to check for anything disrespectful before hitting enter.\nBut after seeing Claw Code, my thinking changed. There\u0026rsquo;s a system prompt, tool-calling logic, permission checks. It parses JSON and calls APIs. It\u0026rsquo;s TypeScript. These things are just code.\nSo I started dropping the formalities. Once I scrapped the review pipeline, my productivity actually went up.\nToday I asked it to do market research with \u0026ldquo;go find me some stuff I can copycat,\u0026rdquo; and the report came back with a section titled \u0026ldquo;Copycat Opportunities.\u0026rdquo; When I used formal language, it would\u0026rsquo;ve come back as \u0026ldquo;Areas for Reference.\u0026rdquo; Talk casual, get casual back. It\u0026rsquo;s code, after all.\n","permalink":"https://nullnull-kim.com/en/logs/2026-04-03-claude-code-leaked/","summary":"\u003cp\u003eClaude Code\u0026rsquo;s source code got leaked. Controversy and debate followed, but overnight someone had already built \u003ca href=\"https://github.com/ultraworkers/claw-code\"\u003eClaw Code\u003c/a\u003e and was racking up stars from around the world. This was clearly the time to go all in.\u003c/p\u003e\n\u003ch2 id=\"fear-not-im-coming\"\u003eFear not, I\u0026rsquo;m coming!\u003c/h2\u003e\n\u003cp\u003eI get home from work and it\u0026rsquo;s already late, but that\u0026rsquo;s fine. Energy drink in my right hand, coffee in my left. I slept four hours a night for two days straight.\u003c/p\u003e","title":"Claude Code Source Code Got Leaked"},{"content":"In EP.2, I used hooks to cut what Claude reads. Test results showed only failures, build logs only errors.\nI decided to measure how much I\u0026rsquo;d actually saved.\nMeasure first Claude Code logs every conversation as JSONL files. They stack up per project under ~/.claude/projects/, each entry containing token usage. I built a script (analyze-tokens.js) that reads these, cross-references with daily session files, tallies turns, cache_read/write/output separately, and converts everything to cost.\nWhile building it, I caught a bug. The session recording hook was referencing e.usage, but the JSONL structure was e.message.usage. Tokens weren\u0026rsquo;t being logged to session files at all. The analyzer bypassed this by reading JSONL directly.\nHere\u0026rsquo;s one day\u0026rsquo;s cost — March 27.\n58% of total cost is reading Item Cost Share cache_read $19.22 58% cache_write ~$9.62 29% output ~$4.33 13% Total $33.17 cache_read is 58%. More than half of Claude\u0026rsquo;s cost comes from \u0026ldquo;reading.\u0026rdquo; In EP.1 I wrote \u0026ldquo;most of what Claude consumes is reading, not reasoning.\u0026rdquo; Seeing the numbers makes it certain.\nWhat is it reading? I tracked what Claude loads every turn.\nItem When loaded Size Project CLAUDE.md Every turn 155–214 lines Root CLAUDE.md Every turn 10 lines MEMORY.md Every turn Under 23 lines Conversation history Every turn Cumulative There was a surprising discovery. SKILL.md (469 lines) and agent docs (1,233 lines) don\u0026rsquo;t load every turn. They load only when a skill is invoked, only when an agent runs. Already lazy loading.\nThe only things loaded every turn are CLAUDE.md and MEMORY.md.\nSplitting CLAUDE.md into rules/ Just because CLAUDE.md is 155–214 lines doesn\u0026rsquo;t mean all of it is needed every turn. The artifact path table is only needed when writing artifacts. Game domain rules are only needed for game-related work.\nClaude Code has a .claude/rules/ directory. Create a file there with paths: frontmatter, and it loads only when accessing that path.\n--- paths: tasks/** --- Artifact path table, common header blocks, role-specific rules... These rules load only when touching the tasks/ folder. They don\u0026rsquo;t load in general conversation.\nI piloted it on one project first. Moved the 45-line artifact section to artifact-rules.md and deleted it from CLAUDE.md. It worked. Applied it across the rest.\nProject CLAUDE.md (before→after) Reduction Files split out A (e-commerce) 155→96 lines 38% artifact-rules.md B (education platform) 207→140 lines 32% artifact-rules.md, edu-rules.md C (game platform) 214→114 lines 47% artifact-rules.md, game-domain.md C dropped 47%. Being a game platform, domain rules (46 lines) had been loading every turn. Now they only load when touching game-related files.\nBut here\u0026rsquo;s the thing The numbers aren\u0026rsquo;t bad. 32–47% reduction. Looks good.\nBut honestly, this is \u0026ldquo;32–47% of 155–214 lines.\u0026rdquo; A few hundred tokens saved per turn. Most of that $19.22 in cache_read isn\u0026rsquo;t from CLAUDE.md\u0026rsquo;s 200 lines — it\u0026rsquo;s from cumulative conversation history. Run 20 turns in a session, and on turn 20, all 19 previous turns load as cache_read.\nOne project consumed more than half the day\u0026rsquo;s cost. Over 3x more expensive than the others. The reason was simple: 17 turns in a single session. cache_read spiked in the later turns.\nNo matter how much you diet CLAUDE.md, if you don\u0026rsquo;t address how conversation history accumulates, most of cache_read stays the same. EP.1 reduced agent count. EP.2 used hooks to cut output. EP.3 reduced static documents. All meaningful work, but the real leak is still there.\nTo cut or to continue, that is the question Past 20 turns, starting a new session is more efficient for cache_read. But a new session means cache_write happens again. CLAUDE.md, MEMORY.md, system prompt — all written from scratch.\nCut sessions to reduce cache_read, and cache_write goes up. Keep sessions to reduce cache_write, and cache_read goes up. Either way, there\u0026rsquo;s a cost.\nI don\u0026rsquo;t have the answer yet. Around 20 turns feels like the break-even point, but it depends on the type of work. Design-heavy conversations are better cut short. Continuous coding is better kept going.\nThat\u0026rsquo;s EP.3\u0026rsquo;s real discovery. I\u0026rsquo;ve cut what I can. What\u0026rsquo;s left is the domain of \u0026ldquo;how to use it.\u0026rdquo;\nOther posts in this series\nEP.1 — Hit the Limit in Three Hours EP.2 — Cutting Costs with Hooks and Subagents Building a Discord Alert System References\nClaude Code Rules Files Claude Code CLAUDE.md ","permalink":"https://nullnull-kim.com/en/logs/2026-03-30-token-ep3/","summary":"\u003cp\u003eIn \u003ca href=\"/en/logs/2026-03-28-token-ep2/\"\u003eEP.2\u003c/a\u003e, I used hooks to cut what Claude reads. Test results showed only failures, build logs only errors.\u003c/p\u003e\n\u003cp\u003eI decided to measure how much I\u0026rsquo;d actually saved.\u003c/p\u003e\n\u003ch2 id=\"measure-first\"\u003eMeasure first\u003c/h2\u003e\n\u003cp\u003eClaude Code logs every conversation as JSONL files. They stack up per project under \u003ccode\u003e~/.claude/projects/\u003c/code\u003e, each entry containing token usage. I built a script (\u003ccode\u003eanalyze-tokens.js\u003c/code\u003e) that reads these, cross-references with daily session files, tallies turns, cache_read/write/output separately, and converts everything to cost.\u003c/p\u003e","title":"Claude Code Token Saving EP.3 — Splitting CLAUDE.md into rules/"},{"content":"I now have 5 projects. shop, blog, code_dungeon, good_game, and a root that manages them all (that\u0026rsquo;s not its actual name). Each project runs its own Claude session. The problem is there\u0026rsquo;s only one of me.\nIf I kick off a task in shop and switch to editing a draft in blog, I have no idea when shop finishes. If I start Phase 1 in code_dungeon and go check on good_game, code_dungeon might be stuck waiting for permission and I wouldn\u0026rsquo;t know. Staring at 5 terminals in rotation isn\u0026rsquo;t monitoring. It\u0026rsquo;s just eye strain.\nI need alerts.\nWhy Discord Webhooks Slack exists. Telegram exists. I picked Discord. The reason is simple: you can create unlimited channels for free. One channel per project means alerts don\u0026rsquo;t mix. root-alerts, shop-alerts, blog-alerts, code_dungeon-alerts, good_game-alerts. One webhook URL per channel.\nI stored each webhook URL in .claude/.discord-webhook inside each project. Hardcoding URLs in scripts means editing the script every time a project is added, but with separate files, I just create a new webhook file.\nFirst Hook: Alert on Completion I wired a Discord notification script to the Stop hook. When a session ends, it sends the project name and timestamp to Discord.\n1 2 # Capture stdin immediately (prevent stdin race with other async hooks) INPUT=$(cat) The Stop hook runs async. When multiple hooks run simultaneously, there\u0026rsquo;s no guarantee which one gets stdin. INPUT=$(cat) at the very top of the script captures it immediately.\nEvery Stop Reason Was \u0026ldquo;unknown\u0026rdquo; Alerts started coming in, but every single one said \u0026ldquo;unknown.\u0026rdquo; [shop] unknown — 03-28 18:01. I know it finished, but not why. Normal completion? Token overflow? Refusal?\nI dug into the Stop hook payload. No stop_reason field. The JSON that Claude Code passes to hooks doesn\u0026rsquo;t include the session termination reason.\nI found a workaround. The payload has transcript_path — the path to a JSONL file containing the entire session transcript. It looks like this:\n{\u0026#34;type\u0026#34;:\u0026#34;user\u0026#34;,\u0026#34;message\u0026#34;:{\u0026#34;role\u0026#34;:\u0026#34;user\u0026#34;,\u0026#34;content\u0026#34;:\u0026#34;Change the project path\u0026#34;},...} {\u0026#34;type\u0026#34;:\u0026#34;assistant\u0026#34;,\u0026#34;message\u0026#34;:{\u0026#34;role\u0026#34;:\u0026#34;assistant\u0026#34;,\u0026#34;content\u0026#34;:[{\u0026#34;type\u0026#34;:\u0026#34;text\u0026#34;,\u0026#34;text\u0026#34;:\u0026#34;...\u0026#34;}],\u0026#34;stop_reason\u0026#34;:\u0026#34;end_turn\u0026#34;,...},...} One line per event, and assistant messages contain the stop_reason field. I rewrote the script to traverse this file in reverse and extract the last stop_reason.\n1 2 3 4 5 const lines = fs.readFileSync(tp, \u0026#39;utf8\u0026#39;).split(\u0026#39;\\n\u0026#39;).filter(l =\u0026gt; l.trim()); for (let i = lines.length - 1; i \u0026gt;= 0; i--) { const e = JSON.parse(lines[i]); if (e.stop_reason) { /* found it */ } } There are 7 possible stop reasons. I mapped each to a Korean label.\nstop_reason Alert Label end_turn 완료 (Complete) max_tokens 토큰초과 (Token Overflow) model_context_window_exceeded 컨텍스트초과 (Context Overflow) stop_sequence 중단시퀀스 (Stop Sequence) pause_turn 일시정지 (Paused) refusal 거부 (Refused) tool_use 도구호출 (Tool Call) Now I get alerts like [shop] 완료 — 03-28 18:01 and [blog] 토큰초과 — 03-28 15:32.\nFiltering Sub-agent Alerts A completion alert came through, so I checked the terminal — still running. I added debug logging and investigated. The cause was sub-agent parallel tasks completing.\nHere\u0026rsquo;s the task processing structure I set up for the shop project:\nCustomer Request → task-orchestrator (main) ├─ frontend-developer → UI implementation ├─ backend-developer → API implementation ├─ code-reviewer → Code review + performance check ├─ security-auditor → Security audit (conditional) └─ quality-gatekeeper → Final verification Every time a sub-agent finishes, the Stop hook fires. Even though the main session hasn\u0026rsquo;t ended. If 5 sub-agents are attached to one task, that\u0026rsquo;s 6 alerts. frontend-developer complete, backend-developer complete, code-reviewer complete\u0026hellip; meanwhile the main session is still going.\nIf the payload has an agent_id field, it\u0026rsquo;s a sub-agent. I added a filter to skip both alerts and heartbeat deletion for sub-agents.\n1 2 IS_SUBAGENT=$(echo \u0026#34;$INPUT\u0026#34; | node -e \u0026#34;...\u0026#34; 2\u0026gt;/dev/null) [ \u0026#34;$IS_SUBAGENT\u0026#34; = \u0026#34;yes\u0026#34; ] \u0026amp;\u0026amp; exit 0 Completion Alerts Aren\u0026rsquo;t Enough When Claude requests permission confirmation, asks for file write access, or waits for user input, the Stop hook doesn\u0026rsquo;t fire. \u0026ldquo;This task must be taking a while,\u0026rdquo; I thought, waiting — then checked and found it had been waiting for my response for dozens of minutes.\nSecond Hook: Waiting Alert The idea is simple. Every time Claude executes a tool, it writes a timestamp. If the timestamp hasn\u0026rsquo;t been updated for 2 minutes, the project is considered stalled.\nI connected a heartbeat script to the PostToolUse hook. Every tool execution writes the current time to .claude/.heartbeat.\n1 date +%s \u0026gt; \u0026#34;$PROJECT_ROOT/.claude/.heartbeat\u0026#34; That\u0026rsquo;s it. A one-line hook.\nA separate watcher script checks all 5 projects\u0026rsquo; heartbeat files every 60 seconds. If the last update was more than 2 minutes ago, it sends a \u0026ldquo;waiting\u0026rdquo; alert to Discord. No re-alerts within 10 minutes for the same project. Otherwise it\u0026rsquo;s alert spam.\n1 2 3 STALE_THRESHOLD=120 # 2 minutes COOLDOWN=600 # 10-minute re-alert prevention CHECK_INTERVAL=60 # Check every 60 seconds When a session ends, the Stop hook deletes the heartbeat file. This prevents \u0026ldquo;waiting\u0026rdquo; alerts for projects that have already finished.\nNow only main session completion alerts come through.\nCurrent Setup Two hooks and one watcher script.\nComponent Trigger Role heartbeat.sh PostToolUse Update timestamp on every tool execution notify-discord.sh Stop Discord alert on session end + delete heartbeat watcher.ps1 60s interval (always running) \u0026ldquo;Waiting\u0026rdquo; alert when heartbeat stale \u0026gt; 2min .discord-webhook — Per-project webhook URL storage Adding a new project takes two steps: put the webhook URL in .claude/.discord-webhook and add the path to the watcher.ps1 PROJECTS array.\n5 projects are running simultaneously. Discord alerts are firing. At least now I know which one is stuck.\nSomething I Read After Building This There\u0026rsquo;s a post called 50 Practical Tips for Claude Code with this item:\n48. Play a sound when Claude finishes — Register a system sound via Stop Hook. Start a task, switch to other work, get a ping when it\u0026rsquo;s done.\nIf you only work locally, that seems like enough.\nRelated posts\n[Claude] (Saving Tokens) EP.1 — Hit the Limit in Three Hours [Claude] (Saving Tokens) EP.2 — My Precious Must Be Protected ","permalink":"https://nullnull-kim.com/en/logs/2026-03-29-discord-alert/","summary":"\u003cp\u003eI now have 5 projects. shop, blog, code_dungeon, good_game, and a root that manages them all (that\u0026rsquo;s not its actual name). Each project runs its own Claude session. The problem is there\u0026rsquo;s only one of me.\u003c/p\u003e\n\u003cp\u003eIf I kick off a task in shop and switch to editing a draft in blog, I have no idea when shop finishes. If I start Phase 1 in code_dungeon and go check on good_game, code_dungeon might be stuck waiting for permission and I wouldn\u0026rsquo;t know. Staring at 5 terminals in rotation isn\u0026rsquo;t monitoring. It\u0026rsquo;s just eye strain.\u003c/p\u003e","title":"Claude Code Discord Alert Integration — Multi-Project Monitoring System"},{"content":"After trimming down to 9 agents and putting CLAUDE.md on a diet, the intervals between Compacting conversation... messages got noticeably longer. Same tasks, but it lasted much longer than before. Felt good.\nThen I was watching the console after requesting a new feature. Tests ran. 30 cases, all passing. But Claude was mentioning the successful tests again. Something felt subtly off.\nI asked Claude. \u0026ldquo;Why are you mentioning tests that already passed?\u0026rdquo; Claude explained the concept of tools. When Claude executes a terminal command or reads a file, those are all \u0026ldquo;tool calls.\u0026rdquo; And every time a tool runs, its entire output stacks into the conversation context. npm test results — 30 lines. Hugo build log — 180 lines. All of it. Tests all passed with nothing to look at, yet it read all 30. For build errors, only the last 5 lines mattered, but it loaded all 180.\nThe leaky bucket wasn\u0026rsquo;t just one.\nAnd lo, thou shalt follow hooks While googling, I discovered Claude Code\u0026rsquo;s hooks. PreToolUse — a script that intercepts right before Claude executes a tool. It can transform output before a Bash command runs, and it can block a Read call before it happens.\nI could now set commandments to protect my precious.\nFirst commandment: Thou shalt not read what succeeded 30 tests all passed, and there\u0026rsquo;s no need to read them again. I built a hook that filters for only failed cases and discards the rest. (I asked Claude to build it.)\n1 filtered_cmd=\u0026#34;$cmd 2\u0026gt;\u0026amp;1 | grep -A 10 -E \u0026#39;(FAIL|ERROR|✕|FAILED)\u0026#39; | head -150\u0026#34; Where Claude once read all 30 test results, now it only sees failures. If everything passes, the reading amount is zero. 100% of unnecessary reads — eliminated.\nSecond commandment: Thou shalt not upload what isn\u0026rsquo;t an error Hugo build log 180 lines, Docker build 80 lines — no need to upload everything just to find errors. Same logic: built a hook that filters for ERROR, WARN, failed only.\n1 2 # Hugo filtered_cmd=\u0026#34;$cmd 2\u0026gt;\u0026amp;1 | grep -E \u0026#39;(ERROR|WARN|error|failed|Fatal)\u0026#39; | head -30\u0026#34; 180 lines became 5. Cut 97%. Docker went from 80 lines to around 10.\nThird commandment: Thou shalt not even read what is useless There\u0026rsquo;s an archive folder that\u0026rsquo;s no longer in use. No reason for Claude to open it while exploring files. Built a hook that intercepts Read tool calls and denies any path containing _archive.\n1 2 3 if [[ \u0026#34;$file_path\u0026#34; == *\u0026#34;/_archive/\u0026#34;* ]]; then # deny fi Simple, but effective.\nBut here\u0026rsquo;s the thing The improvement was tangible. Compacting conversation... appeared less often. Context stayed much lighter even after running builds. Three hooks blocking Claude from reading unnecessary information.\nBut it was \u0026ldquo;tangible.\u0026rdquo; I didn\u0026rsquo;t know exactly how much I\u0026rsquo;d saved. Today felt better than yesterday, but I couldn\u0026rsquo;t brag about how much I\u0026rsquo;d cut! How was this any different from EP.1, where I believed \u0026ldquo;splitting agents would help\u0026rdquo; with zero evidence?\nIf you don\u0026rsquo;t measure it, you haven\u0026rsquo;t improved it. It was time to measure for real.\nOther posts in this series\nEP.1 — Hit the Limit in Three Hours Building a Discord Alert System References\nClaude Code Hooks Reference ","permalink":"https://nullnull-kim.com/en/logs/2026-03-28-token-ep2/","summary":"\u003cp\u003eAfter trimming down to 9 agents and putting CLAUDE.md on a diet, the intervals between \u003ccode\u003eCompacting conversation...\u003c/code\u003e messages got noticeably longer. Same tasks, but it lasted much longer than before. Felt good.\u003c/p\u003e\n\u003cp\u003eThen I was watching the console after requesting a new feature. Tests ran. 30 cases, all passing. But Claude was mentioning the successful tests again. Something felt subtly off.\u003c/p\u003e\n\u003cp\u003eI asked Claude. \u0026ldquo;Why are you mentioning tests that already passed?\u0026rdquo; Claude explained the concept of tools. When Claude executes a terminal command or reads a file, those are all \u0026ldquo;tool calls.\u0026rdquo; And every time a tool runs, its entire output stacks into the conversation context. npm test results — 30 lines. Hugo build log — 180 lines. All of it. Tests all passed with nothing to look at, yet it read all 30. For build errors, only the last 5 lines mattered, but it loaded all 180.\u003c/p\u003e","title":"Claude Code Token Saving EP.2 — Cutting Costs with Hooks and Subagents"},{"content":"A friend asked me to build an e-commerce site for cosmetics. I\u0026rsquo;d been writing nothing but C at work, so this was a chance to try a new stack. Toss Payments for checkout, React for the frontend. \u0026ldquo;Every next-gen finance project is going React\u0026rdquo; — that comment stuck with me, and Toss Payments was Node-friendly. The direction came together quickly.\nObviously, I\u0026rsquo;d never used this stack before. I wanted to learn it, but the deadline didn\u0026rsquo;t allow for \u0026ldquo;study first, build later.\u0026rdquo; So I gave vibe coding a shot.\n\u0026ldquo;Build me a shopping mall for selling cosmetics. Here\u0026rsquo;s the reference site URL.\u0026rdquo; That was all I said, and Claude started hammering away — then out came a mockup that covered things I hadn\u0026rsquo;t even thought of. It\u0026rsquo;s been over a year since vibe coding became a thing, and I was completely behind.\nMy plan to learn the new stack by reading Claude\u0026rsquo;s code was hopelessly naive. Claude produced code far faster than I could read it. So instead of reviewing it myself, I asked Claude to review its own work. (The end of the human era felt near.)\nAfter using it for a while, Claude started losing track of earlier context. I googled \u0026ldquo;context\u0026rdquo; and found out why. I also found that splitting roles into sub-agents was a solution. I set up five: pm, dba, back, front, qa. I defined everything in CLAUDE.md — path conventions, session management guides, the works. Usage was in the mid-teens percent. Seemed like plenty.\nThree hours later, I saw You've hit your limit · resets 3am.\nThe \u0026ldquo;resets at 3am\u0026rdquo; part made sense. But it didn\u0026rsquo;t make sense. Why three hours?\nThe buttons were wrong from the start When I set up the five agents, I was working from a flawed hypothesis: \u0026ldquo;The more Claude thinks, the more tokens it costs.\u0026rdquo; No evidence. Just felt right.\nI packed each agent with if-then rules. If I eliminated Claude\u0026rsquo;s need to reason, inference costs would drop — or so I believed. I filled CLAUDE.md with that same logic.\nOnly after hitting the limit did I actually google it. That\u0026rsquo;s when I learned I was wrong. Most of Claude\u0026rsquo;s token consumption isn\u0026rsquo;t reasoning — it\u0026rsquo;s reading. Every time an agent runs, it reads the entire CLAUDE.md from scratch. The CLAUDE.md I\u0026rsquo;d so diligently filled was being loaded into context in full, every single time.\nI compressed the prose-style explanations into tables and cut duplicate entries. The burn rate dropped.\nSplitting further should reduce tokens, right? After the optimization, the Compacting conversation... messages became less frequent. Context was holding up well. I felt good about it.\nBut when I looked at actual token consumption, it was leaking even more.\n\u0026ldquo;If I split roles into finer pieces, each agent handles a narrower scope.\u0026rdquo; That was the next idea.\nI went from 5 to 12. api-designer, ui-designer, performance-engineer, security-auditor\u0026hellip; A systematic, stage-by-stage structure.\nContext held up fine. But tokens felt like they were leaking a bit more.\nMerging back, with tears I asked Claude to diagnose the cause. It felt like receiving a court verdict. token.. my precious\u0026hellip;\nNumber of agents = number of CLAUDE.md reads. Twelve agents loading it twelve times each. The more I split, the faster it burned.\nI had to consolidate. I\u0026rsquo;d put real effort into building them, but I merged them back with tears in my eyes.\napi-designer absorbed into backend-developer, ui-designer into frontend-developer, performance-engineer into code-reviewer.\nItem Before After Savings Total agent file size 112KB 40KB -64% Number of agents 12 9 -3 The burn rate changed noticeably.\nSo I went Max Once the structure was in place, I truly felt how fast Claude works. Yes, it costs money. But the processing speed was beyond imagination. Work that would have taken me days finished in a single session.\nI upgraded to the Max plan. Let\u0026rsquo;s use it wisely, without waste.\nThe structural problem was solved. I didn\u0026rsquo;t stop googling to protect my precious. Then I found it. When Claude reads a file, if it\u0026rsquo;s 500 lines, it reads all 500. When it runs tests, it loads the entire result into context — including passing cases. It wasn\u0026rsquo;t about the number of agents. It was about what Claude sees.\nHow could I make Claude see only what it needs?\nOther posts in this series\nEP.2 — My Precious Must Be Protected Building a Discord Alert System References\nCLAUDE.md — How Claude remembers your project Create custom subagents ","permalink":"https://nullnull-kim.com/en/logs/2026-03-27-token-ep1/","summary":"\u003cp\u003eA friend asked me to build an e-commerce site for cosmetics. I\u0026rsquo;d been writing nothing but C at work, so this was a chance to try a new stack. Toss Payments for checkout, React for the frontend. \u0026ldquo;Every next-gen finance project is going React\u0026rdquo; — that comment stuck with me, and Toss Payments was Node-friendly. The direction came together quickly.\u003c/p\u003e\n\u003cp\u003eObviously, I\u0026rsquo;d never used this stack before. I wanted to learn it, but the deadline didn\u0026rsquo;t allow for \u0026ldquo;study first, build later.\u0026rdquo; So I gave vibe coding a shot.\u003c/p\u003e","title":"Claude Code Token Saving EP.1 — Hit the Limit in Three Hours"},{"content":" A firm banking specialist who got lucky enough to land in financial IT services, now managing systems for some of Korea\u0026rsquo;s biggest corporations. Recently started vibe coding and ended up in an all-out war with tokens.\nThis blog documents trial and error, daily life, and the occasional LeetCode solution.\nGitHub: nullnull-kim Email: nullnull.kim@gmail.com Blog engine: Hugo + PaperMod Hosting: Cloudflare ","permalink":"https://nullnull-kim.com/en/about/","summary":"about","title":"About"}]