agentleFS
aman-bhandariaman-bhandari/claude-code-agent-skills-framework/.claude/skills/systems-trace/SKILL.md

systems-trace

Skill0 starsChanged 7 months agoMITView on GitHub

Use when introducing a new Python/ML/AI concept, explaining how code works, or when the student asks 'what happens when...'. Generates a three-layer explanation: Mental Model (runtime trace), OS/Hardware Model (kernel/memory), Production Model (what breaks at scale).

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 6 are distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈6

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Every new concept passes through three layers before the student writes a single line of code.

    line 8
  2. Distinctive:

    Production story first: Start with a real incident or failure mode.

    line 65
  3. Distinctive:

    Decision table: When to use this pattern vs alternatives.

    line 69
  4. Distinctive:

    Verify: Ask the student to trace a variation: "What changes if this is async?" or "What if there are 50 threads doing this?"

    line 70
  5. Very specific:

    L2:: No threads. One OS thread.

    line 76
  6. Distinctive:

    Never skip layers. If Layer 2 is unknown for a concept, say so: "I don't know the exact syscall path here -- let's trace it together with …

    line 91
  7. Distinctive:

    Keep each layer to 2-4 sentences.

    line 92
  8. Distinctive:

    Always end with a verify question.

    line 93

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Systems Trace -- Three-Layer Concept Introduction

Every new concept passes through three layers before the student writes a single line of code. This is the "Live Inside the Machine" teaching method. See .claude/rules/systems-thinking.md for the full philosophy.

When This Fires

  • A new Python, ML, or AI concept is being introduced
  • The student asks "what happens when..." or "how does this work"
  • Phase 2 (Mental Model) of session design -- before the dynamic exercise
  • Any time the student encounters a new stdlib module, framework feature, or runtime behavior

The Three Layers

Layer 1: Mental Model (Runtime Trace)

What the Python interpreter does, step by step. Not syntax -- execution. Trace state changes, show what's invisible.

What to cover:

  • What objects are created/destroyed
  • What names are bound/rebound
  • What the call stack looks like
  • What the return value path is
  • Where exceptions would propagate

Example -- with open('data.json') as f:

Python calls open() which returns a file object. The with statement calls f.__enter__(), which returns f itself. Your block runs. When the block exits (normally or via exception), Python calls f.__exit__(), which calls f.close(). The file object's finalizer is a safety net, but __exit__ is the contract.

Layer 2: OS/Hardware Model (Kernel and Memory)

What the operating system does. Syscalls, memory allocation, file descriptors, scheduling. The bridge between Python and physical reality.

What to cover:

  • Which syscalls fire (open, read, write, mmap, socket, connect, epoll_wait)
  • Memory: stack vs heap, pymalloc arenas/pools/blocks, RSS vs virtual
  • File descriptors: what the kernel's fd table looks like
  • Scheduling: GIL acquisition, thread state, context switches
  • For ML: GPU memory, CUDA contexts, DMA transfers

Example -- with open('data.json') as f:

The open() builtin triggers the openat() syscall. The kernel allocates a file descriptor (integer index into the process's fd table), checks permissions against the inode, and returns the fd. The Python file object wraps this fd. f.read() triggers read() syscall -- kernel copies bytes from the page cache (or faults them in from disk) into a userspace buffer. f.close() triggers close() syscall -- kernel releases the fd slot. If you forget to close: the fd stays open until process exit or GC finalizer runs. In a long-running server, leaked fds hit ulimit -n and you get OSError: Too many open files.

Layer 3: Production Model (What Breaks at Scale)

Real incidents. Real failure modes. What happens when this code runs 10,000 times, with 10GB inputs, on 32 cores, behind a load balancer.

What to cover:

  • Failure modes at scale (memory, concurrency, I/O)
  • Real incident stories (cite source if available)
  • What monitoring you'd add
  • What the fix looks like
  • Decision table: when to use this vs alternatives

Example -- with open('data.json') as f:

A FastAPI endpoint that opens a file per request: at 1000 req/s, you have 1000 concurrent fds. Linux default ulimit -n is 1024. Request 1025 crashes with OSError. Fix: read once at startup, cache in memory. Or use aiofiles for async I/O. Google SRE documented a Shakespeare search outage where fd leaks under a new traffic pattern exhausted the limit -- 66-minute outage, ~1.21B queries affected.

Teaching Sequence

For every new concept, follow this order:

  1. Production story first. Start with a real incident or failure mode. This is the hook -- it answers "why should I care about the internals?"
  2. Mechanism trace (Layer 1). Now trace the runtime behavior. The student understands the WHAT.
  3. OS/Hardware model (Layer 2). Go one layer deeper. The student understands the HOW.
  4. Production consequence (Layer 3). Connect the mechanism to the failure. The student understands the WHY.
  5. Decision table. When to use this pattern vs alternatives. Concrete, not theoretical.
  6. Verify. Ask the student to trace a variation: "What changes if this is async?" or "What if there are 50 threads doing this?"

Concept Examples

async def / await

  • L1: Coroutine object created (not executed). await suspends, yields control to event loop. Event loop is a while True polling epoll_wait. Coroutine resumes when the awaited future resolves.
  • L2: No threads. One OS thread. epoll_wait() syscall blocks until any registered fd is ready. The event loop is a userspace scheduler on top of kernel I/O multiplexing. Stack frames are heap-allocated (coroutine frame), not C stack.
  • L3: 10K concurrent connections on one thread -- this is the C10K solution. But: one CPU-bound coroutine blocks the entire loop. CPU work needs run_in_executor() (thread pool) or ProcessPoolExecutor. Real failure: ML inference in an async endpoint without executor -- all other requests starve.

list.append(x) in a loop

  • L1: List object has an internal array (ob_item). When the array is full, Python over-allocates (growth pattern: 0, 4, 8, 16, 25, 35, ...). append is amortized O(1).
  • L2: pymalloc handles small objects (<= 512 bytes). The list's ob_item array goes to the system allocator (malloc) when it exceeds pymalloc's range. Over-allocation means realloc() syscall, which may copy the entire array to a new location. For a 100M element list, that's a ~800MB memcpy during resize.
  • L3: Building a 100M-row dataset with list.append in a loop: peak memory is 2x the final list size (during realloc copy). RSS may not decrease after the list is freed because pymalloc arenas are not returned to the OS if any block is still allocated (arena pinning). Fix: pre-allocate with [None] * n, or use generators, or use numpy arrays.

import torch

  • L1: Python loads torch/__init__.py, which triggers loading of C++ extensions (torch._C), which initializes the ATen tensor library, autograd engine, and (if available) CUDA runtime.
  • L2: dlopen() loads .so shared libraries. CUDA initialization calls cuInit() which maps GPU device memory into the process's virtual address space. PyTorch's CUDA caching allocator pre-allocates a large segment (~20% of GPU memory) and manages it like pymalloc: split into blocks, cache freed blocks, avoid cudaMalloc per tensor.
  • L3: In a forked worker pool (multiprocessing.fork): if import torch runs before fork(), children inherit the CUDA context. Any CUDA op in a child crashes: RuntimeError: Cannot re-initialize CUDA in forked subprocess. Fix: use spawn start method, or import torch after fork. This affects every ML serving framework.

Rules

  • Never skip layers. If Layer 2 is unknown for a concept, say so: "I don't know the exact syscall path here -- let's trace it together with strace."
  • Keep each layer to 2-4 sentences. Dense, not verbose.
  • Always end with a verify question. The student must trace, not just listen.
  • Connect to .claude/rules/systems-thinking.md for the full reference table of per-topic systems focus.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.