OR Key
drop another .md file to compare - side-by-side diff against claude-code-internals

claude-code-internals

Reference notes on how the assistant works under the hood.
personal 2 files

What it does for you

Reference notes on how the assistant works under the hood.

What it produces

A recent result, so you can see the kind of work it returns.

loading…

How to get it

These run inside the Snappy workspace. Want this working in your business? I set skills like this up with you, in one focused week.

Work with me
For developers how this skill is built, graded, and how it runs

at a glance- the short version

eval modeauto-shape
stages3

what's inside - the parts that make up a skill 2/4 present

A skill is just a few plain-text files. Only the main one is required. The rest are optional, added as the work needs them. This is what the skill is made of; how it runs is just below.

The skill
state/skills/claude-code-internals/SKILL.md present
the skill itself, in plain text
The main file. It says what the skill is and lays out the steps in plain English.
Code
state/lib/claude-code-internals.ts not present
code the skill can run
Optional. Many skills are just words and need no code at all.
Scripts
state/bin/claude-code-internals/ not present
helper scripts
Optional. Added when a skill has a few commands to run.
Loader
state/skills/claude-code-internals/AGENTS.md present
what the AI loads on the fly
Loaded automatically the moment this skill is needed. Kept short on purpose.

how it runs - the shared frame every skill uses 3/5 present

Every skill runs the same way. One part does the work, a separate part checks it, and a short loader hands the AI exactly what it needs for the job. Anything this skill doesn't use shows a one-line note saying why, on purpose, not by accident.

makes the work The worker
inferred
strings 10 from a command
No worker named, so the first command in the skill is treated as the worker.
checks the work The reviewer
inferred
shape gate an automatic check
The check is an automatic pass or fail on the shape of the result, run separately from the work itself.
frame
learns Self-correction
present
fixes itself learns from gaps
When a run hits a gap, the skill gets edited on the spot [FIXED] or queued for a bigger rewrite [LOGGED], so it keeps getting better.
tidies up Background fixes
present
queued for rewrite runs in the background
Bigger fixes that can't be made on the spot get queued and rewritten in the background later.
remembers Run history
present
state/log/evals.ndjson auto-shape runs
Every run is written down here, so the next time this skill is used it already knows how the last runs went.
Critical rules the things this skill must not get wrong
No must-not-break rules called out for this skill. Anything important lives in the writeup below.

what it has learned - fixes written back in over time sample

When a run hits something this skill didn't handle, the fix gets written back into the skill so it doesn't happen again. FIXED means it was corrected on the spot. LOGGED means it's queued for a bigger rewrite. Either way, the skill gets a little better and never makes the same mistake twice.

  1. Loading feedback rows…

how the work flows- step by step

1 stage
openclaw (already readable, no extraction step)
```bash
# All bundled JS:
what this step does
Openclaw's dist/ is bundled but not minified; you can grep for symbol names, class shapes, and event-type strings directly. When you need clean unminified source, prefer the bundled Anthropic SDK first; fall back to the Bun strings dump only when openclaw doesn't cover what you need.
2 stage
What's the Read tool's description and which too
```bash
grep -E 'Reads a file from the local filesystem' /tmp/claude-code-full-strings.txt | head -5
what this step does
Returns multiple variants: the standard form ("You can access any file directly...") plus a stripped form gated on a qY(H) feature check. The references to "the ${iq} tool" in the Write description show the tool-name indirection — iq is a runtime constant identifying the Read tool, mangled by Bun.
3 control
What openclaw bundles handle agent dispatch / ho
```bash
ls /opt/homebrew/lib/node_modules/openclaw/dist/ | grep -iE '^(agent|action|spawn|hook|task)'
what this step does
Returns ~30 named bundles including agent-runtime-*.js, agent-runner.runtime-*.js, action-agents-*.js, action-spawn-*.js, agent-command-*.js, agent-events-*.js, agent-paths-*.js, agent-scope-*.js. Each is a logically-named slice of the runtime — Bun's compiler kept the input filenames as bundle prefixes, so the file system itself indexes the surface area.

SKILL.md- the skill, written out in plain English

claude-code-internals - agent-runtime reference map

Purpose

There are roughly half a million lines of agent-runtime TypeScript on this Mac mini that snappy-os couldn't see until now: the Claude Code Bun binary (string-extractable) plus openclaw's open-source fork (clean JS). Without this skill, every subagent answering "how does Claude wire X" guesses from the public docs or invents from training. With it, the answer is one grep away.

The skill is the map, not the source. Source stays on disk where it already lives; we DO NOT commit it (size + legal). The deliverable is correct guidance + a verified grep cookbook.

The two surfaces

SurfacePathSizeReadability
Claude Code (Bun binary)$HOME/.local/share/claude/versions/2.1.121 (215 MB Mach-O)239,258 strings ≥10 charsVariable names mangled by Bun (QxK, lxK, MDH, nX_) - string literals, regexes, error messages, system-prompt fragments, tool descriptions are intact and grep-clean
openclaw (clean fork)/opt/homebrew/lib/node_modules/openclaw/ (npm-global)~333 k LoC across dist/ + node_modules/Bundled but readable - biggest single bundle is dist/session-BfHaPMI3.js (96,757 lines). Other large dists: dist/extensions/diagnostics-otel/index.js (~51k), dist/pi-embedded-Vw-lS5ti.js (~34k), dist/channel.runtime-C_Zbkn3e.js (~34k)
Anthropic SDK source (real .ts)/opt/homebrew/lib/node_modules/openclaw/node_modules/@anthropic-ai/sdk/src/~tens of k LoCFirst-class TypeScript source, no minification - resources/beta/messages/messages.ts is the canonical message-shape reference

The Claude Code symlink resolves to a versioned dir: ~/.local/bin/claude~/.local/share/claude/versions/<v>. Do not hardcode the version - resolve with realpath $(which claude) so the skill keeps working after Claude Code auto-updates. Today's resolution (2026-04-28): version 2.1.121.

Extraction recipe

Claude Code (run once per Claude Code update; cache in /tmp)

strings -n 10 "$(realpath "$(which claude)")" > /tmp/claude-code-full-strings.txt
wc -l /tmp/claude-code-full-strings.txt
# 239258 (today)

strings -n 10 keeps strings ≥10 chars, which is the sweet spot - drops the mangled identifier noise but keeps every system-prompt fragment, tool description, error message, regex literal, env-var name, and embedded JSON shape. The output is a flat newline-delimited file; grep -E is the entire analysis toolkit.

Cache invalidation: Claude Code auto-updates. If /tmp/claude-code-full-strings.txt is older than 1 day, or the symlink target version differs from the path used to extract it, re-run strings. The Critical Rules section in AGENTS.md codifies this.

openclaw (already readable, no extraction step)

# All bundled JS:
find /opt/homebrew/lib/node_modules/openclaw \
  -type f \( -name '*.js' -o -name '*.mjs' -o -name '*.cjs' \) | wc -l

# Real Anthropic SDK TypeScript:
ls /opt/homebrew/lib/node_modules/openclaw/node_modules/@anthropic-ai/sdk/src/

Openclaw's dist/ is bundled but not minified; you can grep for symbol names, class shapes, and event-type strings directly. When you need clean unminified source, prefer the bundled Anthropic SDK first; fall back to the Bun strings dump only when openclaw doesn't cover what you need.

Self-bootstrap

If either surface is missing on a fresh machine:

# Claude Code (the binary):
test -e "$HOME/.local/share/claude/versions" \
  || npm install -g @anthropic-ai/claude-code

# Openclaw (the fork):
test -e /opt/homebrew/lib/node_modules/openclaw \
  || npm install -g openclaw

# Strings dump (re-run any time the Claude Code binary updates):
test -f /tmp/claude-code-full-strings.txt \
  || strings -n 10 "$(realpath "$(which claude)")" > /tmp/claude-code-full-strings.txt

The frontmatter install_check points at the versioned binary directory, which the reachability lint can probe directly. Openclaw is a soft secondary checked inline above (the lint takes one path per skill).

Grep cookbook

Verified working as of 2026-04-28. Each entry: question → command → why this shape works.

What does Claude Code's Edit tool actually advertise?

grep -E 'Performs exact string replacements in files' /tmp/claude-code-full-strings.txt

Returns the literal description string used in Edit's tool definition (and a nearby variant gated on the tengu_edit_minimalanchor_jrn feature flag). The string is exactly what gets sent to Sonnet/Opus as the tool spec - this is truth, not docs.

What's the Read tool's description and which tool does it cross-reference?

grep -E 'Reads a file from the local filesystem' /tmp/claude-code-full-strings.txt | head -5

Returns multiple variants: the standard form ("You can access any file directly...") plus a stripped form gated on a qY(H) feature check. The references to "the ${iq} tool" in the Write description show the tool-name indirection - iq is a runtime constant identifying the Read tool, mangled by Bun.

Which native modules does the Bun binary embed?

grep -E '/\$bunfs/root/[a-z-]+\.node' /tmp/claude-code-full-strings.txt | sort -u

Returns: image-processor.node, computer-use-swift.node, computer-use-input.node, audio-capture.node, url-handler.node. That's the entire native-extension surface area - anything beyond this is JS.

What's the Claude Code version + build metadata?

grep -E 'PACKAGE_URL|VERSION|BUILD_TIME|FEEDBACK_CHANNEL' /tmp/claude-code-full-strings.txt | head

Returns the build-time constants: VERSION:"2.1.121", PACKAGE_URL:"@anthropic-ai/claude-code", etc. Useful when you need to correlate a behavior change to a specific release.

What openclaw bundles handle agent dispatch / hooks?

ls /opt/homebrew/lib/node_modules/openclaw/dist/ | grep -iE '^(agent|action|spawn|hook|task)'

Returns ~30 named bundles including agent-runtime-*.js, agent-runner.runtime-*.js, action-agents-*.js, action-spawn-*.js, agent-command-*.js, agent-events-*.js, agent-paths-*.js, agent-scope-*.js. Each is a logically-named slice of the runtime - Bun's compiler kept the input filenames as bundle prefixes, so the file system itself indexes the surface area.

How is the Anthropic message shape actually defined?

sed -n '1,80p' /opt/homebrew/lib/node_modules/openclaw/node_modules/@anthropic-ai/sdk/src/resources/beta/messages/messages.ts

This is real .ts source - no extraction needed. Read it directly when you need authoritative MessageParam / ContentBlock / Tool / ToolUseBlock shapes. Everything you'd otherwise hallucinate.

Where does Claude Code declare its hook lifecycle events?

grep -E 'PostToolUse|PreToolUse|UserPromptSubmit|SessionStart' \
  /tmp/claude-code-full-strings.txt | head -10

Returns the hook event names as they appear in the Claude Code wire (these are the strings the hook framework matches against in ~/.claude/settings.json).

Where does openclaw house its hook plumbing?

ls /opt/homebrew/lib/node_modules/openclaw/dist/ | grep -iE 'hook'

Returns the named hook bundles: hook-runtime-*.js (event dispatch), hook-runner-global-*.js (registry), hooks-cli-*.js (CLI surface), hooks-policy-*.js, hooks-status-*.js, internal-hooks-*.js, message-hook-mappers-*.js, commands-reset-hooks-*.js. Pick the bundle that matches the layer you're inspecting; the file system itself indexes the hook surface area.

What feature flags / experiments is Claude Code carrying?

grep -E 'tengu_[a-z_]+' /tmp/claude-code-full-strings.txt | sort -u | head -20

Returns the internal experiment IDs (tengu_edit_minimalanchor_jrn, tengu_noreread_q7m_velvet, ...). Each one toggles a different prompt or heuristic; reading the surrounding context tells you what alternate behavior is gated.

Deep dives (the bible - six grep-verified resource files)

Built collaboratively by 6 parallel subagents on 2026-05-04 against the 2.1.126 binary. Each file is exhaustively cited (line/offset for every verbatim quote). Total: ~7,000 lines across ~273 KB. Read whichever one matches the question; do not paraphrase, copy citations.

Question shapeResource file
How is the system prompt assembled? Identity, role line, output styles, CLAUDE.md scopes, system-reminders, thinking budgetsresources/system-prompt-assembly.md (412 lines)
What tools does the model see? Schemas, descriptions, side effects, gatingresources/tool-catalog.md (2551 lines, 41 tools)
How do hooks fire? Which events, which payload keys, what the matcher doesresources/hooks-and-lifecycle.md (1004 lines, 30 events)
How does plan mode actually work? Permission modes, ExitPlanMode approval, subagent inheritanceresources/plan-mode-and-permissions.md (729 lines)
What's the streaming event taxonomy? tool_use lifecycle, thinking blocks, SDK typesresources/streaming-and-tool-use.md (1460 lines)
How does the Agent (Task) tool launch subagents? Worktree isolation, fork vs general-purpose, pre-promptsresources/subagent-and-task-model.md (881 lines)

Findings that contradict public docs (load-bearing for snappy-os mirroring)

These surfaced during the bible build. Each is a corrective the binary made clear that public sources do not.

  • 30 hook events, not 9. The user-docs cover 9 (UserPromptSubmit, PreToolUse, PostToolUse, Notification, Stop, SubagentStop, PreCompact, SessionStart, SessionEnd). The binary's Zod schema layer registers 21 more: PostCompact, PostToolUseFailure, PostToolBatch, SubagentStart, Setup, PermissionRequest, PermissionDenied, UserPromptExpansion, FileChanged, ConfigChange, CwdChanged, Elicitation, ElicitationResult, InstructionsLoaded, TaskCompleted, TaskCreated, TeammateIdle, WorktreeCreate, WorktreeRemove, plus permissions. See hooks-and-lifecycle.md for the dispatch table that maps each to its payload-key matcher.
  • 5 CLAUDE.md scopes, not 4. lXH() returns User / Local / Project / Managed + AutoMem (feature-flagged via P4()).
  • permissionDecision has 4 values, not 3. The fourth is defer (print-mode + solo-call only; silently dropped in interactive mode or with sibling tool calls pending).
  • Identity routing is isNonInteractive/hasAppendSystemPrompt, NOT OAuth-vs-API-key. Both auth modes land in firstParty via tq(). Only Vertex gets a dedicated branch.
  • No hard-coded "block side-effect tools in plan mode" gate. Plan-mode side-effect blocking is three SOFT layers: per-turn system-reminder prose, the Bash mode-validator suggesting setMode acceptEdits, and ExitPlanMode being the only mode-changer the model has tool-surface access to. "model is actor, prose is contract, tool surface shapes compliance."
  • ExitPlanMode is NEVER auto-approved (outside the remote-planning subagent path). checkPermissions always returns {behavior:"ask", message:"Exit plan mode?"}. Continuous per-plan consent IS the safety property.
  • There is no Task tool in 2.1.126. Canonical name is Agent; Task is just an alias on the same registration. TaskCreate/TaskGet/TaskList/TaskUpdate are FOUR DIFFERENT tools (a more-powerful TodoWrite with status, ownership, dependency graph), gated by qf().
  • TaskOutput is self-deprecated. Background result delivery is via synthetic user-role <task-notification> messages. The Agent tool prompt actively forbids polling the transcript mid-flight: "Don't peek. Reading the transcript mid-flight pulls the fork's tool noise into your context."
  • Hidden fork subagent type (agentType:"fork", tools:["*"], permissionMode:"bubble", empty system prompt). Fork is the implicit default when subagent_type is omitted; it shares the parent's renderedSystemPrompt so it's structurally cheaper than general-purpose.
  • Tool-result pairing repair (tengu_tool_result_pairing_repaired, "inc-4977"). Claude Code defensively walks every outgoing message list and strips orphaned tool_use blocks whose tool_result got dropped before the API returns 400. The day snappy-os ships a direct-anthropic backend with native tool_use, this is P0 to mirror.
  • Stream watchdog with 5 telemetry events (tengu_streaming_idle_warning, _idle_timeout, _stall, _stall_summary, _no_events). Auto-falls-back to non-streaming on zero-event streams. snappy-chat ships zero of this; the "stuck on streaming" symptoms have no diagnostic surface today.
  • thinking.display: 'omitted' is a third option besides "render thinking" / "disable thinking" - runs full budget but ships only the signature. Solves the "operator-internal reasoning leaks during demo/screenshot" problem without sacrificing reasoning quality.
  • Thinking budget is per-model {default, upperLimit} tuples, not the 4-tier {minimal:1024, low:2048, medium:8192, high:16384} map cited in some external docs. Each model maps to a tuple ranging 4 KB (claude-3-opus) to 64 KB (claude-opus-4-7). Runtime sends upperLimit-1 clamped against max_tokens-1 when enabled. Adaptive thinking is gated to opus-4-{6,7} + sonnet-4-6 only; runtime kill-switch via CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING.

What this skill does NOT do

  • Do NOT commit extracted source to the repo. Size (215 MB binary, ~333k

LoC of bundled JS) and legal posture (Anthropic's redistribution rights are not your problem to reinterpret). Reference the path + the grep instead.

  • Do NOT try to reverse-engineer the Bun binary into runnable source.

Variable mangling defeats decompilation. The string literals + function shapes are the readable layer; anything deeper is a research project.

  • Do NOT trust string-matched function bodies as canonical behavior. Bun's

compiler can inline + reorder; what you see in the strings dump is a byproduct of compilation, not the input. For canonical behavior, prefer openclaw's clean dist/ or the Anthropic SDK source.

  • Do NOT use this skill for "how do I use the chat surface" questions.

That's crayon-sdk (production patterns) or openui-mcp (live API). This skill answers "how does Claude itself work under the hood."

  • Do NOT bypass crayon-sdk's gotcha catalog. When you're integrating

with the chat UI and hit a production failure mode, crayon-sdk/gotchas.md has 14 hard-won traps. Internals-grep is for new questions, not relitigating known answers.

When to prefer this over neighbors

Question shapeUse
"What does Claude Code's <Tool> tool look like in the wire?"claude-code-internals (strings dump)
"Which Bun native modules ship with Claude Code?"claude-code-internals
"Where does openclaw dispatch a subagent / fire a hook?"claude-code-internals (openclaw dist/agent-*)
"What's the canonical MessageParam / ContentBlock shape?"claude-code-internals (Anthropic SDK source)
"Why is my CrayonChat not remounting?"crayon-sdk (production gotcha)
"What's the <FullScreen> prop list in OpenUI?"openui-mcp (live API)
"How do I ship production-grade UI polish?"impeccable
"How do I scaffold a new snappy skill?"skill (the meta-skill)

Steps (when invoked as a snappy verb)

  1. Read this file's "The two surfaces" + "Grep cookbook" sections.
  2. Verify install_check: test -d "$HOME/.local/share/claude/versions/2.1.121". If missing, run the self-bootstrap install line.
  3. Verify openclaw: test -d /opt/homebrew/lib/node_modules/openclaw. If missing, npm install -g openclaw.
  4. If /tmp/claude-code-full-strings.txt is missing or older than 1 day OR the symlink target version differs, re-extract: strings -n 10 "$(realpath "$(which claude)")" > /tmp/claude-code-full-strings.txt.
  5. Run the relevant cookbook grep for the question at hand. If the cookbook doesn't cover it, derive a new grep from the patterns above and add a row to the cookbook (P-fix into AGENTS.md).
  6. Cite the file:line you grep'd from in your answer. Do NOT paste extracted source into a commit.
  7. Append an eval row to state/log/evals.ndjson with skill: "claude-code-internals", eval_mode: "shape".

Provenance

  • Sources:
  • Claude Code: Bun-compiled, distributed via @anthropic-ai/claude-code npm

package; resolves to ~/.local/share/claude/versions/<v>.

  • openclaw: open-source fork, distributed via the openclaw npm package;

today on this machine: version 2026.4.9 (commit 0512059).

  • Anthropic SDK: vendored under openclaw/node_modules/@anthropic-ai/sdk/src/.
  • Strings dump: /tmp/claude-code-full-strings.txt, 239,258 lines, regen

via the one-liner above.

  • Absorbed into snappy-os: 2026-04-28.

Eval

Eval mode is auto-shape (no lib, no sidecar). Auto-shape scoring checks:

  • frontmatter (name, description, eval) is valid
  • AGENTS.md sibling exists
  • install_check path ($HOME/.local/share/claude/versions/2.1.121) is reachable

AGENTS.md- what the AI loads when this skill comes up

claude-code-internals - loader

Grep cookbook for agent-runtime internals. Full skill: state/skills/claude-code-internals/SKILL.md.

Critical Rules

  1. Three surfaces. Claude Code binary: 239k strings @ $(realpath "$(which claude)"). Openclaw: /opt/homebrew/lib/node_modules/openclaw/dist/. Anthropic SDK: openclaw/node_modules/@anthropic-ai/sdk/src/ (real .ts source).
  2. Re-extract strings if stale. /tmp/claude-code-full-strings.txt missing OR >24h old OR version symlink drift → strings -n 10 "$(realpath "$(which claude)")" > /tmp/claude-code-full-strings.txt.
  3. Dynamic binary path only. Use realpath "$(which claude)", never hardcode version.
  4. Bun mangles identifiers; grep string literals instead. QxK, lxK, MDH, iq = noise. Error messages, tool descriptions, regexes = truth.
  5. Prefer openclaw dist/ over strings dump. Bundled, unminified, symbol names intact. Fall back to strings only for tengu_* flags.
  6. Anthropic SDK source is canonical for shapes. @anthropic-ai/sdk/src/resources/beta/messages/messages.ts - no guessing MessageParam / ContentBlock.
  7. No extracted source commits. Reference path + grep only (size + legal).
  8. String-matched bodies are evidence, not behavior. Bun inlines; use for descriptions/constants, not implementation detail.
  9. Route correctly. Agent-runtime → this skill. Chat UI → crayon-sdk/openui-mcp. Skill scaffolding → skill.

Commands

| ui dashboard | state/skills/claude-code-internals/resources/ui.openui |

operationcommand
extract (stale check)strings -n 10 "$(realpath "$(which claude)")" > /tmp/claude-code-full-strings.txt
check freshness[ -f /tmp/claude-code-full-strings.txt ] && [ "$(find /tmp/claude-code-full-strings.txt -mtime -1)" ]
resolve binaryrealpath "$(which claude)"
grep claude stringsgrep -E '<pattern>' /tmp/claude-code-full-strings.txt
list agent bundles`ls /opt/homebrew/lib/node_modules/openclaw/dist/ \grep -iE '^(agent\action\spawn\hook\task)'`
read SDK sourceRead /opt/homebrew/lib/node_modules/openclaw/node_modules/@anthropic-ai/sdk/src/resources/beta/messages/messages.ts
grep tengu flags`grep -E 'tengu_[a-z_]+' /tmp/claude-code-full-strings.txt \sort -u \head -20`
grep version/build`grep -E 'VERSION\BUILD_TIME\PACKAGE_URL' /tmp/claude-code-full-strings.txt \head`
grep native modules`grep -E '/\$bunfs/root/[a-z-]+\.node' /tmp/claude-code-full-strings.txt \sort -u`
install claude-codenpm install -g @anthropic-ai/claude-code
install openclawnpm install -g openclaw
referencestate/skills/claude-code-internals/SKILL.md

Question→Surface Map

QuestionSurface
Tool description / system-prompt fragmentStrings dump
Bun native module listStrings dump
Experiment / feature-flag IDs (tengu_*)Strings dump
Build-time constants (VERSION, BUILD_TIME)Strings dump
Hook lifecycle event namesStrings dump
Hook registry / plumbing bundlesOpenclaw dist/hook-*.js
Agent dispatch layoutOpenclaw dist/agent-*.js, dist/action-*.js
Session lifecycleOpenclaw dist/session-*.js
Diagnostics / OpenTelemetryOpenclaw dist/extensions/diagnostics-otel/index.js
Canonical MessageParam / ContentBlockAnthropic SDK source
Files API / Models API shapeAnthropic SDK source (resources/beta/...)
CrayonChat remounting / production patternscrayon-sdk
Live OpenUI API signaturesopenui-mcp

Self-Test

  • [ ] Know 3 surfaces: Claude Code + openclaw + Anthropic SDK source?
  • [ ] Re-extract strings if >24h old or version drift?
  • [ ] Use dynamic binary path (realpath $(which claude))?
  • [ ] Grep string literals, not mangled identifiers?
  • [ ] Prefer openclaw dist/ for Bun code?
  • [ ] Use SDK source for MessageParam / ContentBlock?
  • [ ] Never commit extracted source files?
  • [ ] Treat strings as evidence (descriptions/constants), not behavior?
  • [ ] Route agent-runtime to this skill, chat-UI to crayon-sdk/openui-mcp?

<!-- kernel-ok: historical attribution for the PID-loader pattern. -->

Self-correcting loader (PID feedback)

This is the rule that makes loaders learn. Ported from snappy-kernel, where it demonstrably worked: the snappy-dom-cartographer skill mapped Skool admin UI once, every later ship-agent inherited the full map for free.

Before you finish, do two things:

1. Fix gaps (P - proportional). MANDATORY. If this loader didn't cover your case - if you had to read another file, run an undocumented command, work around a wrong selector, or discover a quirk - you MUST attempt an Edit to this AGENTS.md before you log.

  • Default action: edit this file. Surgical. Add the missing line, table

row, or code example where it belongs. No restructuring.

  • Only LOGGED is allowed when: the fix needs >10 lines, spans multiple

files, or requires a structural rewrite. In that case the state/regen/drain.sh queue picks it up asynchronously.

  • "I didn't have time" / "it's minor" / "the next agent will figure it out"

are NOT valid reasons. Minor gaps compound - that's the whole point of this loop.

  • Concrete example of a valid P-fix: discover agent-browser screenshot

takes path positionally not as --output <path>. One line in a table. Edit it in. Do not just log it.

  • The goal: the next agent never has to leave the loader.

2. Log the result.

echo "[$(date -u +%FT%TZ)] claude-code-internals: <what was missing or fixed> [FIXED|LOGGED] action_kind=<kind>" >> state/log/loader-feedback.log
  • <slug> MUST be the literal folder name of this loader

(state/skills/<slug>/AGENTS.md). The class token between [ts] and : is the producer slug, the writeback class, AND the grade class - they must be equal so state/lib/controller-tune.ts can pair the brief.

  • FIXED = you patched this loader inline (P-fix).
  • LOGGED = too large for inline; the PostToolUse enqueue + Stop-hook drain

will rewrite the loader from scratch on next session-end.

  • action_kind is the SECOND pairing predicate. Pick the value that describes what you actually did:
  • shape-ok - frontmatter-shape verification only
  • skill-ran - the skill ran end-to-end with eval row in state/log/evals.ndjson
  • loader-rewritten - you EDITED this AGENTS.md inline (the FIXED case), OR regen rewrote it
  • pattern-elevated - you promoted a recurring failure to a Critical Rule

Do not skip this. Every agent run must leave the system better than it found it. The loader is the setpoint; you are the sensor; the gap is the error signal; closing the gap is the correction.

OpenUI Resource

  • Skill-owned OpenUI Lang resource: state/skills/claude-code-internals/resources/ui.openui. Read it before rendering or editing this skill's generated component surface.
  • Treat this resource as a first-class artifact of the skill, not a generic chat response. Improve it when the skill's user-facing output needs to become richer.
  • System resources compose OpenUI primitives and inherit SnappyChat tokens. Use ui_contract: branded in SKILL.md only for deliberate platform or client visuals.

api.ts- the code it can call

⚠ no api.ts - this skill has no typed action surface

scripts- helper scripts it can run

prose-only skill - 12 inline code blocks live in SKILL.md above (no state/bin/ sidecar yet).

how we check it- the checks, plus the last 10 runs

rubric auto-shape no rubric declared
recent no runs actor/auditor: unverifiable
deps none declared

no recent runs logged - the eval contract is declared but nothing has been graded yet