{"owner":"eunomia-bpf","repo":"bpf-developer-tutorial","hasSkills":true,"totalSkillsCount":10,"totalTokensCount":8300,"categories":["claude-rule","anthropic-skill"],"hasMcp":false,"mcpConfig":null,"found":["CLAUDE.md",".agents/skills/test-bpf-tutorial-kvm/references/tutorial-patterns.md",".agents/skills/write-bpf-production-tutorial/agents/openai.yaml",".agents/skills/bpf-tutorial-writing-style/SKILL.md",".agents/skills/write-bpf-production-tutorial/SKILL.md",".agents/skills/test-bpf-tutorial-kvm/SKILL.md",".agents/skills/find-bpf-tutorial-topic/SKILL.md",".agents/skills/test-bpf-tutorial-kvm/agents/openai.yaml",".agents/skills/find-bpf-tutorial-topic/agents/openai.yaml",".agents/skills/bpf-tutorial-writing-style/agents/openai.yaml"],"skills":{"CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nThis is the eBPF Developer Tutorial repository - a comprehensive learning resource for eBPF development. It provides 48+ practical examples progressing from beginner to advanced topics using modern eBPF frameworks like libbpf, Cilium eBPF, and libbpf-rs.\n\n## Common Development Tasks\n\n### Building eBPF Examples\n\nMost examples use libbpf and follow this pattern:\n```bash\ncd src/<example-number>-<example-name>\nmake\n```\n\nFor Rust examples (in src/37-uprobe-rust/):\n```bash\ncd src/37-uprobe-rust/<example>\ncargo build\n```\n\n### Running Examples\n\nMost examples require root privileges:\n```bash\nsudo ./<binary-name>\n# or with timeout for continuous monitoring tools:\nsudo timeout -s 2 3 ./<binary-name>\n```\n\n### Clean Build Artifacts\n```bash\nmake clean\n```\n\n## Architecture\n\n### Build System\n- **Framework**: GNU Make with libbpf\n- **BPF Compilation**: Clang/LLVM compiles `.bpf.c` → `.bpf.o`\n- **Skeleton Generation**: bpftool generates `.skel.h` from BPF objects\n- **User Space**: GCC compiles C programs linking with libbpf\n- **Dependencies**: All in `src/third_party/` (libbpf, bpftool, blazesym, vmlinux headers)\n\n### Directory Structure\n- `src/0-10`: Basic eBPF concepts (kprobes, uprobes, tracepoints)\n- `src/11-18`: Advanced libbpf development\n- `src/19-21,29,41-42`: Networking (LSM, TC, XDP, sockops)\n- `src/22-28,34`: Security topics\n- `src/31,37`: Language integration (Go, Rust)\n- `src/44-45`: BPF schedulers\n- `src/47`: GPU tracing\n- Each tutorial has its own Makefile and README\n\n### Key Components\n1. **vmlinux headers**: Pre-generated for x86, arm, arm64, riscv, powerpc, loongarch\n2. **CO-RE (Compile Once, Run Everywhere)**: Uses BTF for kernel compatibility\n3. **Multiple frameworks**: libbpf (primary), eunomia-bpf, Cilium eBPF, libbpf-rs",".agents/skills/test-bpf-tutorial-kvm/references/tutorial-patterns.md":"# BPF tutorial KVM test patterns\n\nResolve the wrapper from the tutorial worktree:\n\n```bash\nTUTORIAL_ROOT=\"$(git rev-parse --show-toplevel)\"\nRUNNER=\"$TUTORIAL_ROOT/.agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh\"\n```\n\nAll paths below are host paths exposed at the same location in the virtme-ng guest.\n\n## One-shot loader or self-test\n\n```bash\n\"$RUNNER\" --cwd \"$LESSON\" -- ./loader --self-test\n```\n\nPrefer a self-test that loads the BPF object, exercises a deterministic input, checks the map or return value, and detaches before exiting.\n\n## Long-running tracer plus a trigger\n\nThe loader, trigger, signal, and output assertion must all occur inside the same guest:\n\n```bash\n\"$RUNNER\" --cwd \"$LESSON\" --timeout 90 -- bash -lc '\nset -euo pipefail\nout=$(mktemp)\n./tracer >\"$out\" 2>&1 &\npid=$!\ntrap '\\''kill -INT \"$pid\" 2>/dev/null || true; wait \"$pid\" 2>/dev/null || true'\\'' EXIT\nsleep 1\ntrue                         # replace with the deterministic traced event\nsleep 1\nkill -INT \"$pid\"\nwait \"$pid\" || test $? -eq 130\ntrap - EXIT\ngrep -F \"expected event\" \"$out\"\n'\n```\n\nKeep the host timeout longer than the guest-side lifecycle. Avoid an unbounded `timeout ./tracer` assertion because exit 124 proves only that it was killed.\n\n## XDP or TC\n\nFor a userspace-backed interface and outbound guest traffic:\n\n```bash\n\"$RUNNER\" --cwd \"$LESSON\" --network user -- bash -lc '\nset -euo pipefail\nip -brief link\n./loader --interface eth0 &\npid=$!\ntrap '\\''kill -INT \"$pid\" 2>/dev/null || true; wait \"$pid\" 2>/dev/null || true'\\'' EXIT\nping -c 1 -W 2 10.0.2.2\n# Assert counters or emitted events here.\n'\n```\n\nUse `--network loop` for guest-local network testing. Prefer `BPF_PROG_TEST_RUN` when the lesson is about program behavior rather than attachment mechanics.\n\n## sched_ext, LSM, and cgroup programs\n\n- Verify the exact config symbol in the printed kernel config before booting, for example `CONFIG_SCHED_CLASS_EXT=y` or `CONFIG_BPF_LSM=y`.\n- Keep sched_ext registration bounded and assert that the scheduler exits or unregisters cleanly.\n- Create test cgroups only inside the guest's cgroup2 mount.\n- Test LSM enforcement on guest-local temporary files or processes, never on host resources mounted read-write.\n\n## Returning generated output\n\nThe tutorial directory is read-only by default. Create a dedicated output directory and expose only it when a test must retain logs or generated files:\n\n```bash\nmkdir -p \"$LESSON/test-output\"\n\"$RUNNER\" --cwd \"$LESSON\" --rwdir \"$LESSON/test-output\" -- \\\n    ./loader --output \"$LESSON/test-output/smoke.json\"\n```\n\nGuest root can modify any `--rwdir` path. Never expose a repository root, `.git`, credentials, task histories, or agent traces just for convenience.\n\n## Interpreting failures\n\n- **Preflight fails:** repair KVM/tool/artifact availability; do not fall back to the host kernel.\n- **Guest kernel mismatch:** the image and build metadata are inconsistent; rebuild or repair the benchmark artifact separately.\n- **`bpftool` asks for `linux-tools-<guest-version>`:** the Ubuntu `/usr/sbin/bpftool` wrapper was selected. On this machine, use the real binary at `/usr/local/sbin/bpftool` after confirming it with `--version`.\n- **Unknown helper, attach type, or kfunc:** compare lesson requirements with the built kernel release/config/BTF. Report a kernel gap rather than changing the host test boundary.\n- **Permission error inside guest:** confirm the command is running as guest root and that bpffs/debugfs/tracefs/cgroup2 mounted. Do not add host `sudo`.\n- **Read-only filesystem:** write under `/tmp`, or explicitly expose a narrow output directory with `--rwdir`.\n- **Timeout 124:** inspect loader cleanup and the trigger. A timeout is not a passing tracer test.\n- **Verifier rejection:** preserve the complete verifier log and distinguish an intentional negative test from a compatibility regression.\n",".agents/skills/write-bpf-production-tutorial/agents/openai.yaml":"interface:\n  display_name: \"BPF Tutorial Writer\"\n  short_description: \"Design and test practical bilingual eBPF lessons\"\n  default_prompt: \"Use $write-bpf-production-tutorial to turn this eBPF example into a practical, tested bilingual tutorial.\"\n",".agents/skills/bpf-tutorial-writing-style/SKILL.md":"---\nname: bpf-tutorial-writing-style\ndescription: Style checklist for English and Chinese bpf-developer-tutorial README files. Use while drafting or reviewing a tutorial so it reads like the established series, preserves technical detail, and presents complete kernel source clearly.\n---\n\n# BPF Tutorial Writing Style\n\nRead the complete guidelines first:\n- [Advanced tutorial guideline](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/scripts/guideline_advance.md) for tutorials 40+\n- [Basic tutorial guideline](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/scripts/guideline_basic.md) for tutorials 0-39\n\nThen read the English and Chinese versions of `47-cuda-events`, `48-energy`, and `49-hid` as style references. Learn their teaching rhythm and level of detail without copying their topic or wording.\n\n## Document Structure (strictly follow guideline)\n\nFor advanced tutorials (40+), follow this exact section order:\n\n1. **Title**: `# eBPF 教程：[Topic Description]` or `# eBPF Tutorial by Example: [Topic Description]`\n\n2. **Introduction**: Brief intro with a concrete problem scenario. Highlight significance and what readers will learn. Link to complete source once here.\n\n3. **Background / Why This Approach**: \n   - Explain WHY this approach is needed\n   - List traditional/alternative approaches and their limitations (e.g., killing process, firewall rules, user-space tools)\n   - Explain what eBPF/the new kernel feature enables that traditional approaches cannot\n   - State when the feature entered Linux (kernel version + commit if relevant)\n\n4. **High-Level Mechanism**:\n   - Explain HOW the eBPF feature/tool works at a high level BEFORE showing code\n   - Describe the overall flow: what happens in kernel, what happens in user space, how they interact\n   - Use diagrams for complex flows with branches, waits, ownership transfers, or 3+ dependent states\n\n5. **Code Implementation**:\n   - First introduce the overall processing logic\n   - Show complete kernel/BPF source and the core headers needed to understand it\n   - Include the complete user-space loader when it is concise; when it is long, use focused excerpts that cover the normal user workflow and link to the lesson directory for the full file\n   - After each code block, explain the key parts with paragraph style (not bullet lists)\n   - Focus on logic and advanced features, not basic syntax\n\n6. **Additional Concepts** (if needed): Deeper explanation of specific features, edge cases, or semantics\n\n7. **Compilation and Execution** (AFTER code, not before):\n   - Build commands\n   - Run commands with examples\n   - Expected output with explanation\n   - Environment requirements table (kernel version, config, privileges, architecture)\n\n8. **Summary**: Key points, scope boundaries, future extensions\n\n9. **Call to Action**: Repository and website invitation (as blockquote)\n\n10. **References**: Links to kernel commits, upstream selftests, documentation\n\n## Tell one useful story\n\n- Open with a concrete situation that the example can reproduce and the question it answers.\n- Near the first mention of eBPF, use one natural sentence to say what eBPF is and why it fits this problem.\n- Introduce the relevant kernel subsystem and new feature when the running example needs them. State when the feature entered Linux and what it enabled.\n- Follow one packet, event, task, or device interaction through kernel space and user space. Explain what happens, why it happens, and what the next step enables.\n- Present the whole flow before detailed code. A small diagram helps when the reader must track a branch, wait, retry, ownership transfer, or at least three dependent states.\n\n## Explain the \"Why\" thoroughly\n\nThis is critical. The Background section must explain:\n- What problem you're solving\n- What traditional approaches exist (killing process, firewall rules, user-space tools like `ss --kill`, sampling, etc.)\n- Why each traditional approach doesn't work well (race conditions, incomplete coverage, performance overhead, etc.)\n- What the eBPF approach enables that wasn't possible before\n\nExample pattern for the \"Why\" section:\n> **杀掉进程**是最直接的想法，但一个进程往往维护着多条连接，杀进程会中断所有业务流量。\n> **防火墙规则**可以阻止新连接，但对已建立的连接无能为力。\n> **用户态工具**如 `ss --kill` 依赖 `/proc/net/tcp` 遍历和注入 RST 报文，但这种方式有竞态问题。\n> **内核态方案**才能真正解决这个问题。BPF 迭代器可以在持有适当锁的情况下遍历内核的套接字表...\n\n## Sound like a tutorial\n\n- Use familiar words, direct verbs, and connected paragraphs. Attraction comes from the problem and mechanism rather than promotional language.\n- Prefer positive descriptions of what the example does. Put remaining limits and safety boundaries in one short paragraph near the end.\n- Use prose for the main explanation and lists for genuinely parallel items.\n- Keep each paragraph focused on one job. Connect facts through cause, sequence, or contrast instead of listing them like a specification.\n- Write Chinese naturally from the same facts instead of translating English sentence by sentence. Use restrained punctuation and spaces between Chinese text and Latin letters or numbers.\n- Keep technical names, code identifiers, commands, numbers, output, versions, and references exact.\n\nUse this Chinese paragraph only as a voice reference for connected rhythm, restrained symbols, and technical density:\n\n> libbpf 是一个 C/C++ 的 eBPF 用户态加载和控制库，随着内核一起分发，几乎已经成为 eBPF 用户态事实上的 API 标准，libbpf 也支持 CO-RE(Compile Once – Run Everywhere) 的解决方案，即预编译的 bpf 代码可以在不同内核版本上正常工作，而无需为每个特定内核重新编译。\n\n## Teach from complete source\n\n- Introduce one component, show its complete kernel/BPF source in an ordinary Markdown fence, then explain the important logic before moving to the next component.\n- Show core headers completely. Include a complete user-space file when it remains readable; otherwise use focused excerpts that preserve the public control flow without making the tutorial a source dump.\n- Keep every complete source block byte-exact. Preserve comments and commands in excerpts, and link once to the lesson directory for omitted user-space details.\n- Use neither `<details>` nor HTML synchronization markers.\n- Link to the complete lesson once through its GitHub directory. Avoid an opening catalog of individual files.\n- Every Markdown link uses an absolute `https://github.com/...` target. Omit a link when no stable GitHub target exists.\n- Public prose contains no local path, shared test repository, VM name, copy route, cache, prompt, model, agent, or trace detail.\n\n## Finish the lesson\n\n- Show copyable build and run commands, representative real output, and what that output proves.\n- State kernel, configuration, privilege, architecture, and hardware requirements that affect the example (use a table).\n- End with a compact scope boundary, summary, repository invitation, and primary references.\n- Keep the English and Chinese files aligned on structure, facts, source, commands, output, limits, and references while allowing each language to sound natural.\n\nThe final read should answer: what problem is solved, how one event moves through the system, which eBPF mechanism makes it possible, which code matters, how to run it, what success looks like, and where the example stops.\n",".agents/skills/write-bpf-production-tutorial/SKILL.md":"---\nname: write-bpf-production-tutorial\ndescription: Design, write, or rewrite one practical bilingual bpf-developer-tutorial lesson with pinned Claude Opus 4.5, then verify the public workflow and prose against the implementation. Use when creating README.md and README.zh.md, checking whether a tutorial tool has a realistic CLI and lifecycle, preserving complete kernel source, testing the example, or preparing tutorial changes for review.\n---\n\n# Write a BPF Tutorial\n\nUse `$bpf-tutorial-writing-style` for the finished prose. Keep this workflow small: prepare reliable source material, let one pinned writer complete both languages, then check what it actually wrote.\n\n## 1. Prepare the lesson\n\nRead these inputs before writing:\n\n- `scripts/guideline_advance.md` for tutorials 40+, `scripts/guideline_basic.md` for tutorials 0-39;\n- both README files from `src/47-cuda-events`, `src/48-energy`, and `src/49-hid` as style references;\n- the lesson's implementation, headers, Makefile, fixtures, and tests;\n- the current README pair when revising an existing lesson;\n- primary upstream sources for versions and feature semantics.\n\nCollect the facts the reader needs: the problem, why traditional approaches fail, the kernel/user-space flow, feature versions, requirements, intended public commands, real output, concurrency or admission behavior, cleanup, limits, and references. Keep every claim grounded in the code, tests, captured output, or a primary source. Preserve an existing draft before a from-scratch rewrite.\n\nBuild and run the example when the environment supports it. Use `$test-bpf-tutorial-kvm` for kernel features that need the repository's KVM environment. Runtime details support the tutorial; local workspace paths, VM names, shared repositories, caches, prompts, and agent traces stay private.\n\n## 2. Pass the practical-design gate\n\nValidate the tool as an operator before writing prose. Keep its public workflow separate from the deterministic fixture:\n\n- State the operational question, the exact command a reader would run, the independent workload or target, the useful output, and how the tool stops.\n- Classify the lifecycle. A scan or atomic control action may be one-shot; a tracer or monitor must attach before the workload and remain active until a signal, duration, or real completion condition.\n- Do not turn a blocked toy child or `/bin/true` fixture into the public CLI merely because it removes a test race. Launch-scoped tracing is valid only when it is the intended real workflow.\n- Emit and test an explicit readiness signal before starting an independent workload. Do not use a fixed sleep as proof that setup or attachment completed.\n- Check target scope and filters, concurrent state, admission bounds, drop and failure counters, exit status, normal cleanup, signal cleanup, and destructive-action safety in proportion to the lesson.\n- For asynchronous work, stop admission first, wait for completed work rather than merely entered callbacks, drain output, report stable health, and only then destroy resources.\n- Execute the documented command as written. The test must prove the real lifecycle plus one relevant failure or cleanup path, not only that the BPF program loaded.\n- Describe the current public workflow directly. Do not narrate removed flags, old child-command modes, or other migration history unless backward compatibility is itself the lesson.\n- Keep repository tests out of the reader-facing tutorial path. Use them as private validation evidence, but teach the normal command, independent workload, useful tool output, and shutdown sequence.\n- Show only output emitted by the documented tool in public examples. Never include harness lines such as `TEST-*` or `PASS`, fixture setup, test assertions, or local test-infrastructure provenance.\n\nIf the implementation only demonstrates a helper but is awkward or misleading as a tool, revise the implementation and test before asking the writer to explain it. Do not let polished prose overclaim an impractical design.\n\n## 3. Structure requirements\n\nFor advanced tutorials (40+), follow this exact section order as defined in `$bpf-tutorial-writing-style`:\n\n1. **Title + Introduction**: Concrete problem scenario, link to source\n2. **Background / Why This Approach**: Explain traditional approaches and their limitations, then what eBPF enables\n3. **High-Level Mechanism**: How the feature works before showing code\n4. **Code Implementation**: Complete kernel/BPF source and core headers, plus a complete user-space loader when concise or focused user-space excerpts when long, then paragraph explanations\n5. **Additional Concepts** (if needed)\n6. **Compilation and Execution**: AFTER code analysis, not before\n7. **Summary + Call to Action**\n8. **References**\n\nThe \"Background / Why\" section is critical. It must explain:\n- What traditional approaches exist\n- Why each doesn't work well\n- What the eBPF approach enables\n\n## 4. Let Opus write\n\nClaude Opus writes all reader-facing tutorial prose. Use the exact model ID `claude-opus-4-5-20251101`. Stop if that model is unavailable instead of substituting another model.\n\nUse one non-interactive invocation for the complete English and Chinese pair. The prompt stays short and names only:\n\n- the two target README files;\n- `scripts/guideline_advance.md` or `scripts/guideline_basic.md`;\n- `$bpf-tutorial-writing-style`;\n- `src/47-cuda-events`, `src/48-energy`, and `src/49-hid` as style references;\n- the request to read the implementation and write both files completely before returning.\n\nDo not paste a second checklist, paragraph plan, fact inventory, or review rubric into the prompt. Add a technical fact only when it is unavailable in the repository.\n\nRun Claude from the repository root with the pinned model and permission to read the repository and write the two README files. Opus does not commit or push.\n\n## 5. Check the result\n\nInspect both files and the diff instead of trusting the model's final message. Confirm that:\n\n- both languages are complete and tell the same technical story;\n- the documented command, target, lifecycle, signals, concurrency bounds, cleanup, and health output match the practical design gate;\n- the opening reads like a tutorial rather than an abstract or feature list;\n- there is a \"Why\" section explaining traditional approaches and their limitations;\n- the high-level mechanism is explained BEFORE code sections;\n- compilation/execution is AFTER code analysis;\n- every kernel/BPF source and core header appears once in a complete ordinary Markdown fence; a concise user-space loader should also be complete, while a long loader may use focused excerpts that cover the normal public control flow;\n- code, commands, output, versions, requirements, cleanup, and limits agree with the repository;\n- sample output comes from the normal public workflow and contains no test-harness or migration/deprecation narration;\n- the opening source link points only to the lesson directory;\n- every published link is an absolute `https://github.com/...` URL;\n- no local infrastructure, prompt, model, agent, or trace detail appears in public text.\n\nCheck the required complete-source inventory with the bundled `sync-source-blocks.py`: always include kernel/BPF sources and core headers, and include user-space files only when the README presents them as complete. Then run `git diff --check`, the lesson build, its tests, the exact documented public command, and the relevant runtime test. Treat a functional run as a functional run rather than a benchmark.\n\nRead the finished pair once as an intermediate eBPF developer. If a concrete problem remains, give Opus a short defect list in the same session and let it revise the whole pair before returning. Keep prompts, responses, partial drafts, and failed runs; never delete real conversation or agent history.\n\nStop after the reviewed local result unless the user asks to commit, push, or update a PR.\n",".agents/skills/test-bpf-tutorial-kvm/SKILL.md":"---\nname: test-bpf-tutorial-kvm\ndescription: Build and smoke-test bpf-developer-tutorial lessons without loading BPF programs into the host kernel. Use when creating, changing, reviewing, or debugging an eBPF tutorial and the runtime test should reuse the already-built x86 kernel under bpf-benchmark through virtme-ng/KVM. Also use for checking whether a tutorial needs a newer kernel feature. Do not use this workflow for performance benchmarking or for rebuilding the benchmark kernel.\n---\n\n# Test BPF Tutorials in KVM\n\nCompile tutorial code on the host, but run every command that loads, attaches, or exercises BPF inside a short-lived KVM guest using the kernel artifact already built by `bpf-benchmark`.\n\n## Safety boundary\n\n- Never load or attach a tutorial BPF program on the host. This includes `bpftool prog load`, loaders, `make run`, XDP/TC attachment, sched_ext registration, and LSM/cgroup attachment.\n- Do not rebuild or modify `bpf-benchmark`, its kernel tree, its Git state, caches, results, or conversation/agent-history data.\n- Do not silently fall back to the host kernel or to TCG. Stop if `/dev/kvm`, `vng`, or the expected benchmark kernel is unavailable.\n- Treat the tutorial directory as read-only in the guest by default. Use `--rwdir` only for a path that must return guest-generated files to the host.\n- Use bounded commands. The wrapper applies a host-side timeout; add a shorter guest-side `timeout` to long-running loaders when useful.\n- Report a KVM run as a functional smoke test, not as benchmark-quality evidence.\n- Keep this infrastructure private in public prose. A tutorial or PR description may state the architecture, kernel version and commit, configuration, commands, and captured output, but must not name `bpf-benchmark`, local paths, VM instances, mount routes, caches, or agent-state locations.\n\n## Default locations\n\nResolve the tutorial checkout and skill from the current Git worktree:\n\n```bash\nTUTORIAL_ROOT=\"$(git rev-parse --show-toplevel)\"\nRUNNER=\"$TUTORIAL_ROOT/.agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh\"\n```\n\nThe helper reads `BPF_BENCHMARK_ROOT`, defaulting to a `bpf-benchmark` checkout next to the tutorial repository. Its `--cwd` defaults to the caller's current directory.\n\nThe reused kernel is:\n\n```text\n$BPF_BENCHMARK_ROOT/vendor/build/x86/linux/arch/x86/boot/bzImage\n```\n\n## Workflow\n\n### 1. Validate the repositories and instructions\n\nRead every applicable `AGENTS.md` or equivalent repository instruction before acting.\n\nRequire a real tutorial checkout before implementation or testing. A valid checkout has lesson sources and a working Git worktree, not only a `.git` fragment. If it is incomplete, stop and explain that the checkout must be restored; do not clone over it or delete the remnant without explicit authorization.\n\nThe top-level `bpf-benchmark` Git repository does not need to be healthy for artifact reuse. The wrapper validates the kernel image, build config, kernel source worktree, KVM device, and toolchain independently.\n\nRun the preflight:\n\n```bash\n\"$RUNNER\" --check\n```\n\n### 2. Inspect before building\n\nRead the lesson README, Makefile, source, and existing test commands. Identify separately:\n\n1. a compile-only host command;\n2. the userspace loader or runtime command;\n3. the event or workload that proves the program works;\n4. any required network, cgroup, tracefs, debugfs, or kernel-config feature.\n\nUse `make -n` or inspect recipes before choosing a target. A target that invokes a loader is a guest command, even if it also compiles.\n\n### 3. Build on the host\n\nRun only compile and static-generation steps on the host. Prefer the lesson's documented build target. Preserve generated `.bpf.o`, skeletons, and userspace binaries in the lesson directory so the guest sees the exact host-built artifacts.\n\nDo not use `sudo` for the build. Do not run a post-build loader on the host.\n\n### 4. Run inside the benchmark-kernel guest\n\nPass the runtime command after `--`. Arguments are preserved without host re-evaluation.\n\n```bash\nTUTORIAL_ROOT=\"$(git rev-parse --show-toplevel)\"\nRUNNER=\"$TUTORIAL_ROOT/.agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh\"\nLESSON=\"$TUTORIAL_ROOT/src/<lesson>\"\n\n\"$RUNNER\" --cwd \"$LESSON\" -- ./loader --help\n```\n\nThe wrapper boots the built benchmark `bzImage` with KVM, verifies the guest release, runs as guest root, mounts bpffs/debugfs/tracefs/cgroup2, prints provenance, and powers off when the command exits. It defaults to 2 vCPUs, 4G RAM, no network, and 120 seconds.\n\nUse `--network user` only when the test needs an external/userspace-backed interface. Use `--network loop` for a guest-local loop network. Prefer `BPF_PROG_TEST_RUN` or deterministic guest-local traffic when either is sufficient.\n\nRead [the tutorial test patterns](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/.agents/skills/test-bpf-tutorial-kvm/references/tutorial-patterns.md) for tracer, network, writable-output, and failure-diagnosis patterns.\n\n### 5. Verify the behavior, not only the exit code\n\nCapture enough evidence to connect an input event to the expected BPF output: attach confirmation, a deterministic trigger in the same guest, expected map/event output, and clean detach or process exit. Negative tests should verify the expected verifier or attach failure.\n\nFor a new lesson, test at least:\n\n- host compile from a clean lesson build state when safe;\n- KVM preflight;\n- one successful guest runtime path;\n- one relevant error or cleanup path;\n- documentation commands exactly as written.\n\nDo not clean unrelated files or repository-wide caches to create a clean build state.\n\n### 6. Report provenance and limitations\n\nInclude the guest `uname -r`, benchmark kernel source commit, kernel image SHA-256, lesson commit or dirty state, host build command, guest command, and the observed result. The wrapper prints kernel provenance automatically.\n\nIf the tutorial requires a feature absent from the built config or kernel, report the missing symbol/helper/attach type and stop. Propose a benchmark-kernel rebuild or upgrade separately; do not perform it as a fallback.\n\n## Wrapper interface\n\n```text\nrun-in-kvm.sh --check\nrun-in-kvm.sh [--cwd PATH] [--cpus N] [--memory SIZE]\n              [--timeout SECONDS] [--network none|user|loop]\n              [--rwdir PATH]... [--append KERNEL_ARGS]...\n              [--dry-run] [--verbose] -- COMMAND [ARG...]\n```\n\nUse `--dry-run` to inspect the generated `vng`/QEMU launch without booting. `--rwdir` is an explicit trust decision because guest root can change that host path.\n",".agents/skills/find-bpf-tutorial-topic/SKILL.md":"---\nname: find-bpf-tutorial-topic\ndescription: Audit bpf-developer-tutorial coverage, research current Linux BPF work and real open-source eBPF projects, maintain the repository tutorial candidate registry, and rank the next lesson by reader value, operational usefulness, eBPF leverage, reproducibility, distinctness, teaching clarity, ecosystem evidence, maturity, and maintenance cost. Use when deciding what eBPF tutorial to write next, checking whether an idea is already covered or practically usable, comparing feature-driven and scenario-driven topics, refreshing the topic roadmap, or asking which candidate has the highest value.\n---\n\n# Find the Next BPF Tutorial Topic\n\nChoose one lesson-sized problem with lasting teaching value. Treat kernel changes as capability evidence and open-source projects as evidence that the problem matters.\n\n## Resolve the repository\n\nWork from a complete Git checkout and derive absolute paths:\n\n```bash\nREPO_ROOT=\"$(git rev-parse --show-toplevel)\"\nCANDIDATES=\"$REPO_ROOT/TUTORIAL_IDEAS.md\"\n```\n\nRead `CANDIDATES` before researching. Preserve its history: keep existing candidates and change their status to `covered`, `superseded`, `deferred`, or `rejected` with a reason instead of deleting them.\n\n## Audit existing coverage\n\nInspect the current worktree, open tutorial branches or PRs when available, and every first-level directory under `src`. Include numbered lessons, unnumbered lessons such as `cgroup`, and grouped material such as `features` and `xpu`; exclude vendored source such as `third_party` from the coverage decision. Read enough implementation and prose to distinguish a shared helper from a genuinely covered mechanism.\n\nUse `rg` to search candidate hook names, helpers, program types, protocols, and scenarios across README and source files. Record the closest existing lesson for every candidate. A new scenario can reuse an existing primitive when it teaches a different diagnostic or control pattern; a renamed example of the same flow is duplicate coverage.\n\nPay special attention to unmerged lessons in the current worktree so the roadmap does not recommend work already under review.\n\n## Research capabilities and real use cases\n\nUse current primary sources. Search more broadly than Linux:\n\n1. Linux BPF merge commits, documentation, selftests, libbpf, and bpftool releases establish semantics, version requirements, and reference behavior.\n2. Active observability and profiling projects reveal recurring operational questions. Include OpenTelemetry OBI and profiler, Parca, Pyroscope, Coroot, Odigos, and comparable projects.\n3. Networking projects reveal reusable datapath patterns. Include Cilium, Hubble, Kmesh, Katran, sched_ext, and comparable projects.\n4. Security projects reveal concrete detection and enforcement scenarios. Include Tetragon, Falco, Tracee, and comparable projects.\n5. Packaging and lifecycle projects reveal deployment gaps. Include Inspektor Gadget and bpfman.\n6. AI, accelerator, storage, and runtime projects reveal newer workloads. Include agtap, eCapture, io_uring tools, OpenTelemetry profiler GPU work, GPU/NCCL projects, and comparable projects.\n\nPrefer official repositories, release notes, documentation, selftests, and papers from the project authors. Use popularity only as supporting context. Recent releases, repeated implementations across independent projects, and concrete tests are stronger evidence.\n\nConvert each project feature into a small independent lesson. Teach the mechanism and the question it answers rather than writing an installation guide for the source project.\n\n## Define the runnable lesson before scoring\n\nFor every serious candidate, write seven short fields:\n\n- the concrete question a reader can reproduce;\n- the event, packet, request, task, or workload followed end to end;\n- the BPF hook, map, helper, kfunc, or program type that makes the answer possible;\n- the exact command a reader would realistically run and the decision or action its output enables;\n- the natural lifecycle: single-pass action, bounded diagnostic, or persistent monitor, including how it stops and cleans up;\n- the deterministic fixture and observable success output;\n- the closest existing lesson and the new knowledge this candidate adds.\n\nDefer an idea when these fields remain vague. A helper name alone is not a tutorial topic.\n\n## Apply the practicality gate before scoring\n\nWalk through the proposed public workflow as an operator, separately from the deterministic test harness:\n\n- A naturally one-shot operation, such as an iterator scan or atomic state change, may run once and exit. An observability or enforcement monitor must attach before independent workloads, remain useful for its natural lifetime, and stop cleanly by signal, duration, or an explicit completion condition.\n- The fixture may be artificial, but the public command must not exist only to launch `/bin/true` or another toy trigger. A launch-scoped command is acceptable only when launch scoping is itself the lesson's real use case.\n- Require an explicit readiness signal before an independent workload starts; fixed sleeps do not prove that attachment or setup finished.\n- Define target scope and filters, concurrent-event or admission behavior, failure and drop visibility, cleanup after normal exit and signals, and what a reader does with the result.\n- For asynchronous work, define shutdown as: stop admission, wait for completed work rather than merely started callbacks, drain output, report stable health, then destroy resources.\n- Reject a design whose output merely proves that a helper ran. The output must answer the stated operational question or drive the stated action.\n\nRedesign or defer a candidate when the fixture is its only plausible user, when the lifecycle contradicts the scenario, or when safe cleanup and bounded resource behavior cannot be explained and tested.\n\n## Score value\n\nScore from evidence, then subtract costs. Keep the breakdown in working notes and place the final score in `TUTORIAL_IDEAS.md`.\n\n| Dimension | Maximum | Question |\n|---|---:|---|\n| Reader problem | 20 | Does it answer a recurring, consequential question? |\n| Operational usefulness | 15 | Is the public command and lifecycle useful outside the test fixture? |\n| eBPF leverage | 15 | Does eBPF provide visibility or control that ordinary tools cannot provide as cleanly? |\n| Coverage gap | 15 | Does it add a distinct mechanism or scenario to this repository? |\n| Reproducibility | 10 | Can one bounded local or KVM fixture prove the result? |\n| Teaching clarity | 10 | Can the lesson follow one understandable path and show decisive output? |\n| Ecosystem evidence | 10 | Do maintained projects or upstream tests validate the use case? |\n| Maturity | 5 | Are the required kernel and userspace interfaces stable enough to maintain? |\n\nSubtract up to 20 points for unstable private interfaces, broad multi-service scope, unusual hardware, cloud or Kubernetes requirements, fragile protocol parsing, and high version-specific maintenance.\n\nNewness breaks close ties; it does not replace reader value. Favor a stable lesson that solves a real problem over a new helper without a compelling use case.\n\n## Apply the admission gates\n\nA candidate can become `ready` only when:\n\n- it has a concrete reproducible problem and expected output;\n- its documented invocation and lifecycle match how a reader would use the tool outside the fixture;\n- its target scope, concurrency or admission bound, failure visibility, and cleanup path are explicit;\n- eBPF is central to the solution;\n- the repository does not already teach the same flow;\n- the example can fit one coherent tutorial;\n- primary sources establish the technical claims;\n- required kernel, architecture, privilege, and hardware conditions are known;\n- the likely maintenance burden is proportionate to its value.\n\nClassify a small addition to an existing lesson as `maintenance` rather than creating a new numbered tutorial. Classify an immature upstream feature as `watch` until it reaches a suitable stable kernel or userspace release.\n\n## Maintain the candidate registry\n\nUpdate `CANDIDATES` with:\n\n- the audit date;\n- candidate status and score;\n- the smallest useful lesson scope;\n- the closest existing coverage;\n- primary project or upstream sources;\n- the reason for any status change.\n\nAdd newly found candidates. Retain covered and rejected entries as an append-only decision record. Update scores when repository coverage, upstream maturity, available test infrastructure, or ecosystem evidence changes.\n\n## Recommend one next lesson\n\nReturn the top three and select one winner. Explain the winner through its problem, reusable mechanism, deterministic demonstration, repository gap, and maintenance cost. State why the most fashionable alternative ranked lower when that tradeoff is material.\n\nSeparate these conclusions when useful:\n\n- highest overall tutorial value;\n- strongest new-kernel-feature lesson;\n- most timely or attention-grabbing scenario;\n- best topic that can run in the current KVM environment.\n\nDo not implement the winner unless the user also asks to write it.\n",".agents/skills/test-bpf-tutorial-kvm/agents/openai.yaml":"interface:\n  display_name: \"Test BPF Tutorials in KVM\"\n  short_description: \"Build locally and test with the benchmark KVM kernel\"\n  default_prompt: \"Use $test-bpf-tutorial-kvm to build this BPF tutorial locally and run its smoke test with the bpf-benchmark KVM kernel.\"\n",".agents/skills/find-bpf-tutorial-topic/agents/openai.yaml":"interface:\n  display_name: \"Find BPF Tutorial Topic\"\n  short_description: \"Rank practical, high-value eBPF tutorial topics\"\n  default_prompt: \"Use $find-bpf-tutorial-topic to audit coverage, practical usability, and recommend the next eBPF tutorial.\"\n",".agents/skills/bpf-tutorial-writing-style/agents/openai.yaml":"interface:\n  display_name: \"BPF Tutorial Writing Style\"\n  short_description: \"Check advanced eBPF tutorial prose and structure\"\n  default_prompt: \"Use $bpf-tutorial-writing-style to draft or review this advanced eBPF tutorial in the repository house style.\"\n"},"files":{"CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nThis is the eBPF Developer Tutorial repository - a comprehensive learning resource for eBPF development. It provides 48+ practical examples progressing from beginner to advanced topics using modern eBPF frameworks like libbpf, Cilium eBPF, and libbpf-rs.\n\n## Common Development Tasks\n\n### Building eBPF Examples\n\nMost examples use libbpf and follow this pattern:\n```bash\ncd src/<example-number>-<example-name>\nmake\n```\n\nFor Rust examples (in src/37-uprobe-rust/):\n```bash\ncd src/37-uprobe-rust/<example>\ncargo build\n```\n\n### Running Examples\n\nMost examples require root privileges:\n```bash\nsudo ./<binary-name>\n# or with timeout for continuous monitoring tools:\nsudo timeout -s 2 3 ./<binary-name>\n```\n\n### Clean Build Artifacts\n```bash\nmake clean\n```\n\n## Architecture\n\n### Build System\n- **Framework**: GNU Make with libbpf\n- **BPF Compilation**: Clang/LLVM compiles `.bpf.c` → `.bpf.o`\n- **Skeleton Generation**: bpftool generates `.skel.h` from BPF objects\n- **User Space**: GCC compiles C programs linking with libbpf\n- **Dependencies**: All in `src/third_party/` (libbpf, bpftool, blazesym, vmlinux headers)\n\n### Directory Structure\n- `src/0-10`: Basic eBPF concepts (kprobes, uprobes, tracepoints)\n- `src/11-18`: Advanced libbpf development\n- `src/19-21,29,41-42`: Networking (LSM, TC, XDP, sockops)\n- `src/22-28,34`: Security topics\n- `src/31,37`: Language integration (Go, Rust)\n- `src/44-45`: BPF schedulers\n- `src/47`: GPU tracing\n- Each tutorial has its own Makefile and README\n\n### Key Components\n1. **vmlinux headers**: Pre-generated for x86, arm, arm64, riscv, powerpc, loongarch\n2. **CO-RE (Compile Once, Run Everywhere)**: Uses BTF for kernel compatibility\n3. **Multiple frameworks**: libbpf (primary), eunomia-bpf, Cilium eBPF, libbpf-rs",".agents/skills/test-bpf-tutorial-kvm/references/tutorial-patterns.md":"# BPF tutorial KVM test patterns\n\nResolve the wrapper from the tutorial worktree:\n\n```bash\nTUTORIAL_ROOT=\"$(git rev-parse --show-toplevel)\"\nRUNNER=\"$TUTORIAL_ROOT/.agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh\"\n```\n\nAll paths below are host paths exposed at the same location in the virtme-ng guest.\n\n## One-shot loader or self-test\n\n```bash\n\"$RUNNER\" --cwd \"$LESSON\" -- ./loader --self-test\n```\n\nPrefer a self-test that loads the BPF object, exercises a deterministic input, checks the map or return value, and detaches before exiting.\n\n## Long-running tracer plus a trigger\n\nThe loader, trigger, signal, and output assertion must all occur inside the same guest:\n\n```bash\n\"$RUNNER\" --cwd \"$LESSON\" --timeout 90 -- bash -lc '\nset -euo pipefail\nout=$(mktemp)\n./tracer >\"$out\" 2>&1 &\npid=$!\ntrap '\\''kill -INT \"$pid\" 2>/dev/null || true; wait \"$pid\" 2>/dev/null || true'\\'' EXIT\nsleep 1\ntrue                         # replace with the deterministic traced event\nsleep 1\nkill -INT \"$pid\"\nwait \"$pid\" || test $? -eq 130\ntrap - EXIT\ngrep -F \"expected event\" \"$out\"\n'\n```\n\nKeep the host timeout longer than the guest-side lifecycle. Avoid an unbounded `timeout ./tracer` assertion because exit 124 proves only that it was killed.\n\n## XDP or TC\n\nFor a userspace-backed interface and outbound guest traffic:\n\n```bash\n\"$RUNNER\" --cwd \"$LESSON\" --network user -- bash -lc '\nset -euo pipefail\nip -brief link\n./loader --interface eth0 &\npid=$!\ntrap '\\''kill -INT \"$pid\" 2>/dev/null || true; wait \"$pid\" 2>/dev/null || true'\\'' EXIT\nping -c 1 -W 2 10.0.2.2\n# Assert counters or emitted events here.\n'\n```\n\nUse `--network loop` for guest-local network testing. Prefer `BPF_PROG_TEST_RUN` when the lesson is about program behavior rather than attachment mechanics.\n\n## sched_ext, LSM, and cgroup programs\n\n- Verify the exact config symbol in the printed kernel config before booting, for example `CONFIG_SCHED_CLASS_EXT=y` or `CONFIG_BPF_LSM=y`.\n- Keep sched_ext registration bounded and assert that the scheduler exits or unregisters cleanly.\n- Create test cgroups only inside the guest's cgroup2 mount.\n- Test LSM enforcement on guest-local temporary files or processes, never on host resources mounted read-write.\n\n## Returning generated output\n\nThe tutorial directory is read-only by default. Create a dedicated output directory and expose only it when a test must retain logs or generated files:\n\n```bash\nmkdir -p \"$LESSON/test-output\"\n\"$RUNNER\" --cwd \"$LESSON\" --rwdir \"$LESSON/test-output\" -- \\\n    ./loader --output \"$LESSON/test-output/smoke.json\"\n```\n\nGuest root can modify any `--rwdir` path. Never expose a repository root, `.git`, credentials, task histories, or agent traces just for convenience.\n\n## Interpreting failures\n\n- **Preflight fails:** repair KVM/tool/artifact availability; do not fall back to the host kernel.\n- **Guest kernel mismatch:** the image and build metadata are inconsistent; rebuild or repair the benchmark artifact separately.\n- **`bpftool` asks for `linux-tools-<guest-version>`:** the Ubuntu `/usr/sbin/bpftool` wrapper was selected. On this machine, use the real binary at `/usr/local/sbin/bpftool` after confirming it with `--version`.\n- **Unknown helper, attach type, or kfunc:** compare lesson requirements with the built kernel release/config/BTF. Report a kernel gap rather than changing the host test boundary.\n- **Permission error inside guest:** confirm the command is running as guest root and that bpffs/debugfs/tracefs/cgroup2 mounted. Do not add host `sudo`.\n- **Read-only filesystem:** write under `/tmp`, or explicitly expose a narrow output directory with `--rwdir`.\n- **Timeout 124:** inspect loader cleanup and the trigger. A timeout is not a passing tracer test.\n- **Verifier rejection:** preserve the complete verifier log and distinguish an intentional negative test from a compatibility regression.\n",".agents/skills/write-bpf-production-tutorial/agents/openai.yaml":"interface:\n  display_name: \"BPF Tutorial Writer\"\n  short_description: \"Design and test practical bilingual eBPF lessons\"\n  default_prompt: \"Use $write-bpf-production-tutorial to turn this eBPF example into a practical, tested bilingual tutorial.\"\n",".agents/skills/bpf-tutorial-writing-style/SKILL.md":"---\nname: bpf-tutorial-writing-style\ndescription: Style checklist for English and Chinese bpf-developer-tutorial README files. Use while drafting or reviewing a tutorial so it reads like the established series, preserves technical detail, and presents complete kernel source clearly.\n---\n\n# BPF Tutorial Writing Style\n\nRead the complete guidelines first:\n- [Advanced tutorial guideline](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/scripts/guideline_advance.md) for tutorials 40+\n- [Basic tutorial guideline](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/scripts/guideline_basic.md) for tutorials 0-39\n\nThen read the English and Chinese versions of `47-cuda-events`, `48-energy`, and `49-hid` as style references. Learn their teaching rhythm and level of detail without copying their topic or wording.\n\n## Document Structure (strictly follow guideline)\n\nFor advanced tutorials (40+), follow this exact section order:\n\n1. **Title**: `# eBPF 教程：[Topic Description]` or `# eBPF Tutorial by Example: [Topic Description]`\n\n2. **Introduction**: Brief intro with a concrete problem scenario. Highlight significance and what readers will learn. Link to complete source once here.\n\n3. **Background / Why This Approach**: \n   - Explain WHY this approach is needed\n   - List traditional/alternative approaches and their limitations (e.g., killing process, firewall rules, user-space tools)\n   - Explain what eBPF/the new kernel feature enables that traditional approaches cannot\n   - State when the feature entered Linux (kernel version + commit if relevant)\n\n4. **High-Level Mechanism**:\n   - Explain HOW the eBPF feature/tool works at a high level BEFORE showing code\n   - Describe the overall flow: what happens in kernel, what happens in user space, how they interact\n   - Use diagrams for complex flows with branches, waits, ownership transfers, or 3+ dependent states\n\n5. **Code Implementation**:\n   - First introduce the overall processing logic\n   - Show complete kernel/BPF source and the core headers needed to understand it\n   - Include the complete user-space loader when it is concise; when it is long, use focused excerpts that cover the normal user workflow and link to the lesson directory for the full file\n   - After each code block, explain the key parts with paragraph style (not bullet lists)\n   - Focus on logic and advanced features, not basic syntax\n\n6. **Additional Concepts** (if needed): Deeper explanation of specific features, edge cases, or semantics\n\n7. **Compilation and Execution** (AFTER code, not before):\n   - Build commands\n   - Run commands with examples\n   - Expected output with explanation\n   - Environment requirements table (kernel version, config, privileges, architecture)\n\n8. **Summary**: Key points, scope boundaries, future extensions\n\n9. **Call to Action**: Repository and website invitation (as blockquote)\n\n10. **References**: Links to kernel commits, upstream selftests, documentation\n\n## Tell one useful story\n\n- Open with a concrete situation that the example can reproduce and the question it answers.\n- Near the first mention of eBPF, use one natural sentence to say what eBPF is and why it fits this problem.\n- Introduce the relevant kernel subsystem and new feature when the running example needs them. State when the feature entered Linux and what it enabled.\n- Follow one packet, event, task, or device interaction through kernel space and user space. Explain what happens, why it happens, and what the next step enables.\n- Present the whole flow before detailed code. A small diagram helps when the reader must track a branch, wait, retry, ownership transfer, or at least three dependent states.\n\n## Explain the \"Why\" thoroughly\n\nThis is critical. The Background section must explain:\n- What problem you're solving\n- What traditional approaches exist (killing process, firewall rules, user-space tools like `ss --kill`, sampling, etc.)\n- Why each traditional approach doesn't work well (race conditions, incomplete coverage, performance overhead, etc.)\n- What the eBPF approach enables that wasn't possible before\n\nExample pattern for the \"Why\" section:\n> **杀掉进程**是最直接的想法，但一个进程往往维护着多条连接，杀进程会中断所有业务流量。\n> **防火墙规则**可以阻止新连接，但对已建立的连接无能为力。\n> **用户态工具**如 `ss --kill` 依赖 `/proc/net/tcp` 遍历和注入 RST 报文，但这种方式有竞态问题。\n> **内核态方案**才能真正解决这个问题。BPF 迭代器可以在持有适当锁的情况下遍历内核的套接字表...\n\n## Sound like a tutorial\n\n- Use familiar words, direct verbs, and connected paragraphs. Attraction comes from the problem and mechanism rather than promotional language.\n- Prefer positive descriptions of what the example does. Put remaining limits and safety boundaries in one short paragraph near the end.\n- Use prose for the main explanation and lists for genuinely parallel items.\n- Keep each paragraph focused on one job. Connect facts through cause, sequence, or contrast instead of listing them like a specification.\n- Write Chinese naturally from the same facts instead of translating English sentence by sentence. Use restrained punctuation and spaces between Chinese text and Latin letters or numbers.\n- Keep technical names, code identifiers, commands, numbers, output, versions, and references exact.\n\nUse this Chinese paragraph only as a voice reference for connected rhythm, restrained symbols, and technical density:\n\n> libbpf 是一个 C/C++ 的 eBPF 用户态加载和控制库，随着内核一起分发，几乎已经成为 eBPF 用户态事实上的 API 标准，libbpf 也支持 CO-RE(Compile Once – Run Everywhere) 的解决方案，即预编译的 bpf 代码可以在不同内核版本上正常工作，而无需为每个特定内核重新编译。\n\n## Teach from complete source\n\n- Introduce one component, show its complete kernel/BPF source in an ordinary Markdown fence, then explain the important logic before moving to the next component.\n- Show core headers completely. Include a complete user-space file when it remains readable; otherwise use focused excerpts that preserve the public control flow without making the tutorial a source dump.\n- Keep every complete source block byte-exact. Preserve comments and commands in excerpts, and link once to the lesson directory for omitted user-space details.\n- Use neither `<details>` nor HTML synchronization markers.\n- Link to the complete lesson once through its GitHub directory. Avoid an opening catalog of individual files.\n- Every Markdown link uses an absolute `https://github.com/...` target. Omit a link when no stable GitHub target exists.\n- Public prose contains no local path, shared test repository, VM name, copy route, cache, prompt, model, agent, or trace detail.\n\n## Finish the lesson\n\n- Show copyable build and run commands, representative real output, and what that output proves.\n- State kernel, configuration, privilege, architecture, and hardware requirements that affect the example (use a table).\n- End with a compact scope boundary, summary, repository invitation, and primary references.\n- Keep the English and Chinese files aligned on structure, facts, source, commands, output, limits, and references while allowing each language to sound natural.\n\nThe final read should answer: what problem is solved, how one event moves through the system, which eBPF mechanism makes it possible, which code matters, how to run it, what success looks like, and where the example stops.\n",".agents/skills/write-bpf-production-tutorial/SKILL.md":"---\nname: write-bpf-production-tutorial\ndescription: Design, write, or rewrite one practical bilingual bpf-developer-tutorial lesson with pinned Claude Opus 4.5, then verify the public workflow and prose against the implementation. Use when creating README.md and README.zh.md, checking whether a tutorial tool has a realistic CLI and lifecycle, preserving complete kernel source, testing the example, or preparing tutorial changes for review.\n---\n\n# Write a BPF Tutorial\n\nUse `$bpf-tutorial-writing-style` for the finished prose. Keep this workflow small: prepare reliable source material, let one pinned writer complete both languages, then check what it actually wrote.\n\n## 1. Prepare the lesson\n\nRead these inputs before writing:\n\n- `scripts/guideline_advance.md` for tutorials 40+, `scripts/guideline_basic.md` for tutorials 0-39;\n- both README files from `src/47-cuda-events`, `src/48-energy`, and `src/49-hid` as style references;\n- the lesson's implementation, headers, Makefile, fixtures, and tests;\n- the current README pair when revising an existing lesson;\n- primary upstream sources for versions and feature semantics.\n\nCollect the facts the reader needs: the problem, why traditional approaches fail, the kernel/user-space flow, feature versions, requirements, intended public commands, real output, concurrency or admission behavior, cleanup, limits, and references. Keep every claim grounded in the code, tests, captured output, or a primary source. Preserve an existing draft before a from-scratch rewrite.\n\nBuild and run the example when the environment supports it. Use `$test-bpf-tutorial-kvm` for kernel features that need the repository's KVM environment. Runtime details support the tutorial; local workspace paths, VM names, shared repositories, caches, prompts, and agent traces stay private.\n\n## 2. Pass the practical-design gate\n\nValidate the tool as an operator before writing prose. Keep its public workflow separate from the deterministic fixture:\n\n- State the operational question, the exact command a reader would run, the independent workload or target, the useful output, and how the tool stops.\n- Classify the lifecycle. A scan or atomic control action may be one-shot; a tracer or monitor must attach before the workload and remain active until a signal, duration, or real completion condition.\n- Do not turn a blocked toy child or `/bin/true` fixture into the public CLI merely because it removes a test race. Launch-scoped tracing is valid only when it is the intended real workflow.\n- Emit and test an explicit readiness signal before starting an independent workload. Do not use a fixed sleep as proof that setup or attachment completed.\n- Check target scope and filters, concurrent state, admission bounds, drop and failure counters, exit status, normal cleanup, signal cleanup, and destructive-action safety in proportion to the lesson.\n- For asynchronous work, stop admission first, wait for completed work rather than merely entered callbacks, drain output, report stable health, and only then destroy resources.\n- Execute the documented command as written. The test must prove the real lifecycle plus one relevant failure or cleanup path, not only that the BPF program loaded.\n- Describe the current public workflow directly. Do not narrate removed flags, old child-command modes, or other migration history unless backward compatibility is itself the lesson.\n- Keep repository tests out of the reader-facing tutorial path. Use them as private validation evidence, but teach the normal command, independent workload, useful tool output, and shutdown sequence.\n- Show only output emitted by the documented tool in public examples. Never include harness lines such as `TEST-*` or `PASS`, fixture setup, test assertions, or local test-infrastructure provenance.\n\nIf the implementation only demonstrates a helper but is awkward or misleading as a tool, revise the implementation and test before asking the writer to explain it. Do not let polished prose overclaim an impractical design.\n\n## 3. Structure requirements\n\nFor advanced tutorials (40+), follow this exact section order as defined in `$bpf-tutorial-writing-style`:\n\n1. **Title + Introduction**: Concrete problem scenario, link to source\n2. **Background / Why This Approach**: Explain traditional approaches and their limitations, then what eBPF enables\n3. **High-Level Mechanism**: How the feature works before showing code\n4. **Code Implementation**: Complete kernel/BPF source and core headers, plus a complete user-space loader when concise or focused user-space excerpts when long, then paragraph explanations\n5. **Additional Concepts** (if needed)\n6. **Compilation and Execution**: AFTER code analysis, not before\n7. **Summary + Call to Action**\n8. **References**\n\nThe \"Background / Why\" section is critical. It must explain:\n- What traditional approaches exist\n- Why each doesn't work well\n- What the eBPF approach enables\n\n## 4. Let Opus write\n\nClaude Opus writes all reader-facing tutorial prose. Use the exact model ID `claude-opus-4-5-20251101`. Stop if that model is unavailable instead of substituting another model.\n\nUse one non-interactive invocation for the complete English and Chinese pair. The prompt stays short and names only:\n\n- the two target README files;\n- `scripts/guideline_advance.md` or `scripts/guideline_basic.md`;\n- `$bpf-tutorial-writing-style`;\n- `src/47-cuda-events`, `src/48-energy`, and `src/49-hid` as style references;\n- the request to read the implementation and write both files completely before returning.\n\nDo not paste a second checklist, paragraph plan, fact inventory, or review rubric into the prompt. Add a technical fact only when it is unavailable in the repository.\n\nRun Claude from the repository root with the pinned model and permission to read the repository and write the two README files. Opus does not commit or push.\n\n## 5. Check the result\n\nInspect both files and the diff instead of trusting the model's final message. Confirm that:\n\n- both languages are complete and tell the same technical story;\n- the documented command, target, lifecycle, signals, concurrency bounds, cleanup, and health output match the practical design gate;\n- the opening reads like a tutorial rather than an abstract or feature list;\n- there is a \"Why\" section explaining traditional approaches and their limitations;\n- the high-level mechanism is explained BEFORE code sections;\n- compilation/execution is AFTER code analysis;\n- every kernel/BPF source and core header appears once in a complete ordinary Markdown fence; a concise user-space loader should also be complete, while a long loader may use focused excerpts that cover the normal public control flow;\n- code, commands, output, versions, requirements, cleanup, and limits agree with the repository;\n- sample output comes from the normal public workflow and contains no test-harness or migration/deprecation narration;\n- the opening source link points only to the lesson directory;\n- every published link is an absolute `https://github.com/...` URL;\n- no local infrastructure, prompt, model, agent, or trace detail appears in public text.\n\nCheck the required complete-source inventory with the bundled `sync-source-blocks.py`: always include kernel/BPF sources and core headers, and include user-space files only when the README presents them as complete. Then run `git diff --check`, the lesson build, its tests, the exact documented public command, and the relevant runtime test. Treat a functional run as a functional run rather than a benchmark.\n\nRead the finished pair once as an intermediate eBPF developer. If a concrete problem remains, give Opus a short defect list in the same session and let it revise the whole pair before returning. Keep prompts, responses, partial drafts, and failed runs; never delete real conversation or agent history.\n\nStop after the reviewed local result unless the user asks to commit, push, or update a PR.\n",".agents/skills/test-bpf-tutorial-kvm/SKILL.md":"---\nname: test-bpf-tutorial-kvm\ndescription: Build and smoke-test bpf-developer-tutorial lessons without loading BPF programs into the host kernel. Use when creating, changing, reviewing, or debugging an eBPF tutorial and the runtime test should reuse the already-built x86 kernel under bpf-benchmark through virtme-ng/KVM. Also use for checking whether a tutorial needs a newer kernel feature. Do not use this workflow for performance benchmarking or for rebuilding the benchmark kernel.\n---\n\n# Test BPF Tutorials in KVM\n\nCompile tutorial code on the host, but run every command that loads, attaches, or exercises BPF inside a short-lived KVM guest using the kernel artifact already built by `bpf-benchmark`.\n\n## Safety boundary\n\n- Never load or attach a tutorial BPF program on the host. This includes `bpftool prog load`, loaders, `make run`, XDP/TC attachment, sched_ext registration, and LSM/cgroup attachment.\n- Do not rebuild or modify `bpf-benchmark`, its kernel tree, its Git state, caches, results, or conversation/agent-history data.\n- Do not silently fall back to the host kernel or to TCG. Stop if `/dev/kvm`, `vng`, or the expected benchmark kernel is unavailable.\n- Treat the tutorial directory as read-only in the guest by default. Use `--rwdir` only for a path that must return guest-generated files to the host.\n- Use bounded commands. The wrapper applies a host-side timeout; add a shorter guest-side `timeout` to long-running loaders when useful.\n- Report a KVM run as a functional smoke test, not as benchmark-quality evidence.\n- Keep this infrastructure private in public prose. A tutorial or PR description may state the architecture, kernel version and commit, configuration, commands, and captured output, but must not name `bpf-benchmark`, local paths, VM instances, mount routes, caches, or agent-state locations.\n\n## Default locations\n\nResolve the tutorial checkout and skill from the current Git worktree:\n\n```bash\nTUTORIAL_ROOT=\"$(git rev-parse --show-toplevel)\"\nRUNNER=\"$TUTORIAL_ROOT/.agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh\"\n```\n\nThe helper reads `BPF_BENCHMARK_ROOT`, defaulting to a `bpf-benchmark` checkout next to the tutorial repository. Its `--cwd` defaults to the caller's current directory.\n\nThe reused kernel is:\n\n```text\n$BPF_BENCHMARK_ROOT/vendor/build/x86/linux/arch/x86/boot/bzImage\n```\n\n## Workflow\n\n### 1. Validate the repositories and instructions\n\nRead every applicable `AGENTS.md` or equivalent repository instruction before acting.\n\nRequire a real tutorial checkout before implementation or testing. A valid checkout has lesson sources and a working Git worktree, not only a `.git` fragment. If it is incomplete, stop and explain that the checkout must be restored; do not clone over it or delete the remnant without explicit authorization.\n\nThe top-level `bpf-benchmark` Git repository does not need to be healthy for artifact reuse. The wrapper validates the kernel image, build config, kernel source worktree, KVM device, and toolchain independently.\n\nRun the preflight:\n\n```bash\n\"$RUNNER\" --check\n```\n\n### 2. Inspect before building\n\nRead the lesson README, Makefile, source, and existing test commands. Identify separately:\n\n1. a compile-only host command;\n2. the userspace loader or runtime command;\n3. the event or workload that proves the program works;\n4. any required network, cgroup, tracefs, debugfs, or kernel-config feature.\n\nUse `make -n` or inspect recipes before choosing a target. A target that invokes a loader is a guest command, even if it also compiles.\n\n### 3. Build on the host\n\nRun only compile and static-generation steps on the host. Prefer the lesson's documented build target. Preserve generated `.bpf.o`, skeletons, and userspace binaries in the lesson directory so the guest sees the exact host-built artifacts.\n\nDo not use `sudo` for the build. Do not run a post-build loader on the host.\n\n### 4. Run inside the benchmark-kernel guest\n\nPass the runtime command after `--`. Arguments are preserved without host re-evaluation.\n\n```bash\nTUTORIAL_ROOT=\"$(git rev-parse --show-toplevel)\"\nRUNNER=\"$TUTORIAL_ROOT/.agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh\"\nLESSON=\"$TUTORIAL_ROOT/src/<lesson>\"\n\n\"$RUNNER\" --cwd \"$LESSON\" -- ./loader --help\n```\n\nThe wrapper boots the built benchmark `bzImage` with KVM, verifies the guest release, runs as guest root, mounts bpffs/debugfs/tracefs/cgroup2, prints provenance, and powers off when the command exits. It defaults to 2 vCPUs, 4G RAM, no network, and 120 seconds.\n\nUse `--network user` only when the test needs an external/userspace-backed interface. Use `--network loop` for a guest-local loop network. Prefer `BPF_PROG_TEST_RUN` or deterministic guest-local traffic when either is sufficient.\n\nRead [the tutorial test patterns](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/.agents/skills/test-bpf-tutorial-kvm/references/tutorial-patterns.md) for tracer, network, writable-output, and failure-diagnosis patterns.\n\n### 5. Verify the behavior, not only the exit code\n\nCapture enough evidence to connect an input event to the expected BPF output: attach confirmation, a deterministic trigger in the same guest, expected map/event output, and clean detach or process exit. Negative tests should verify the expected verifier or attach failure.\n\nFor a new lesson, test at least:\n\n- host compile from a clean lesson build state when safe;\n- KVM preflight;\n- one successful guest runtime path;\n- one relevant error or cleanup path;\n- documentation commands exactly as written.\n\nDo not clean unrelated files or repository-wide caches to create a clean build state.\n\n### 6. Report provenance and limitations\n\nInclude the guest `uname -r`, benchmark kernel source commit, kernel image SHA-256, lesson commit or dirty state, host build command, guest command, and the observed result. The wrapper prints kernel provenance automatically.\n\nIf the tutorial requires a feature absent from the built config or kernel, report the missing symbol/helper/attach type and stop. Propose a benchmark-kernel rebuild or upgrade separately; do not perform it as a fallback.\n\n## Wrapper interface\n\n```text\nrun-in-kvm.sh --check\nrun-in-kvm.sh [--cwd PATH] [--cpus N] [--memory SIZE]\n              [--timeout SECONDS] [--network none|user|loop]\n              [--rwdir PATH]... [--append KERNEL_ARGS]...\n              [--dry-run] [--verbose] -- COMMAND [ARG...]\n```\n\nUse `--dry-run` to inspect the generated `vng`/QEMU launch without booting. `--rwdir` is an explicit trust decision because guest root can change that host path.\n",".agents/skills/find-bpf-tutorial-topic/SKILL.md":"---\nname: find-bpf-tutorial-topic\ndescription: Audit bpf-developer-tutorial coverage, research current Linux BPF work and real open-source eBPF projects, maintain the repository tutorial candidate registry, and rank the next lesson by reader value, operational usefulness, eBPF leverage, reproducibility, distinctness, teaching clarity, ecosystem evidence, maturity, and maintenance cost. Use when deciding what eBPF tutorial to write next, checking whether an idea is already covered or practically usable, comparing feature-driven and scenario-driven topics, refreshing the topic roadmap, or asking which candidate has the highest value.\n---\n\n# Find the Next BPF Tutorial Topic\n\nChoose one lesson-sized problem with lasting teaching value. Treat kernel changes as capability evidence and open-source projects as evidence that the problem matters.\n\n## Resolve the repository\n\nWork from a complete Git checkout and derive absolute paths:\n\n```bash\nREPO_ROOT=\"$(git rev-parse --show-toplevel)\"\nCANDIDATES=\"$REPO_ROOT/TUTORIAL_IDEAS.md\"\n```\n\nRead `CANDIDATES` before researching. Preserve its history: keep existing candidates and change their status to `covered`, `superseded`, `deferred`, or `rejected` with a reason instead of deleting them.\n\n## Audit existing coverage\n\nInspect the current worktree, open tutorial branches or PRs when available, and every first-level directory under `src`. Include numbered lessons, unnumbered lessons such as `cgroup`, and grouped material such as `features` and `xpu`; exclude vendored source such as `third_party` from the coverage decision. Read enough implementation and prose to distinguish a shared helper from a genuinely covered mechanism.\n\nUse `rg` to search candidate hook names, helpers, program types, protocols, and scenarios across README and source files. Record the closest existing lesson for every candidate. A new scenario can reuse an existing primitive when it teaches a different diagnostic or control pattern; a renamed example of the same flow is duplicate coverage.\n\nPay special attention to unmerged lessons in the current worktree so the roadmap does not recommend work already under review.\n\n## Research capabilities and real use cases\n\nUse current primary sources. Search more broadly than Linux:\n\n1. Linux BPF merge commits, documentation, selftests, libbpf, and bpftool releases establish semantics, version requirements, and reference behavior.\n2. Active observability and profiling projects reveal recurring operational questions. Include OpenTelemetry OBI and profiler, Parca, Pyroscope, Coroot, Odigos, and comparable projects.\n3. Networking projects reveal reusable datapath patterns. Include Cilium, Hubble, Kmesh, Katran, sched_ext, and comparable projects.\n4. Security projects reveal concrete detection and enforcement scenarios. Include Tetragon, Falco, Tracee, and comparable projects.\n5. Packaging and lifecycle projects reveal deployment gaps. Include Inspektor Gadget and bpfman.\n6. AI, accelerator, storage, and runtime projects reveal newer workloads. Include agtap, eCapture, io_uring tools, OpenTelemetry profiler GPU work, GPU/NCCL projects, and comparable projects.\n\nPrefer official repositories, release notes, documentation, selftests, and papers from the project authors. Use popularity only as supporting context. Recent releases, repeated implementations across independent projects, and concrete tests are stronger evidence.\n\nConvert each project feature into a small independent lesson. Teach the mechanism and the question it answers rather than writing an installation guide for the source project.\n\n## Define the runnable lesson before scoring\n\nFor every serious candidate, write seven short fields:\n\n- the concrete question a reader can reproduce;\n- the event, packet, request, task, or workload followed end to end;\n- the BPF hook, map, helper, kfunc, or program type that makes the answer possible;\n- the exact command a reader would realistically run and the decision or action its output enables;\n- the natural lifecycle: single-pass action, bounded diagnostic, or persistent monitor, including how it stops and cleans up;\n- the deterministic fixture and observable success output;\n- the closest existing lesson and the new knowledge this candidate adds.\n\nDefer an idea when these fields remain vague. A helper name alone is not a tutorial topic.\n\n## Apply the practicality gate before scoring\n\nWalk through the proposed public workflow as an operator, separately from the deterministic test harness:\n\n- A naturally one-shot operation, such as an iterator scan or atomic state change, may run once and exit. An observability or enforcement monitor must attach before independent workloads, remain useful for its natural lifetime, and stop cleanly by signal, duration, or an explicit completion condition.\n- The fixture may be artificial, but the public command must not exist only to launch `/bin/true` or another toy trigger. A launch-scoped command is acceptable only when launch scoping is itself the lesson's real use case.\n- Require an explicit readiness signal before an independent workload starts; fixed sleeps do not prove that attachment or setup finished.\n- Define target scope and filters, concurrent-event or admission behavior, failure and drop visibility, cleanup after normal exit and signals, and what a reader does with the result.\n- For asynchronous work, define shutdown as: stop admission, wait for completed work rather than merely started callbacks, drain output, report stable health, then destroy resources.\n- Reject a design whose output merely proves that a helper ran. The output must answer the stated operational question or drive the stated action.\n\nRedesign or defer a candidate when the fixture is its only plausible user, when the lifecycle contradicts the scenario, or when safe cleanup and bounded resource behavior cannot be explained and tested.\n\n## Score value\n\nScore from evidence, then subtract costs. Keep the breakdown in working notes and place the final score in `TUTORIAL_IDEAS.md`.\n\n| Dimension | Maximum | Question |\n|---|---:|---|\n| Reader problem | 20 | Does it answer a recurring, consequential question? |\n| Operational usefulness | 15 | Is the public command and lifecycle useful outside the test fixture? |\n| eBPF leverage | 15 | Does eBPF provide visibility or control that ordinary tools cannot provide as cleanly? |\n| Coverage gap | 15 | Does it add a distinct mechanism or scenario to this repository? |\n| Reproducibility | 10 | Can one bounded local or KVM fixture prove the result? |\n| Teaching clarity | 10 | Can the lesson follow one understandable path and show decisive output? |\n| Ecosystem evidence | 10 | Do maintained projects or upstream tests validate the use case? |\n| Maturity | 5 | Are the required kernel and userspace interfaces stable enough to maintain? |\n\nSubtract up to 20 points for unstable private interfaces, broad multi-service scope, unusual hardware, cloud or Kubernetes requirements, fragile protocol parsing, and high version-specific maintenance.\n\nNewness breaks close ties; it does not replace reader value. Favor a stable lesson that solves a real problem over a new helper without a compelling use case.\n\n## Apply the admission gates\n\nA candidate can become `ready` only when:\n\n- it has a concrete reproducible problem and expected output;\n- its documented invocation and lifecycle match how a reader would use the tool outside the fixture;\n- its target scope, concurrency or admission bound, failure visibility, and cleanup path are explicit;\n- eBPF is central to the solution;\n- the repository does not already teach the same flow;\n- the example can fit one coherent tutorial;\n- primary sources establish the technical claims;\n- required kernel, architecture, privilege, and hardware conditions are known;\n- the likely maintenance burden is proportionate to its value.\n\nClassify a small addition to an existing lesson as `maintenance` rather than creating a new numbered tutorial. Classify an immature upstream feature as `watch` until it reaches a suitable stable kernel or userspace release.\n\n## Maintain the candidate registry\n\nUpdate `CANDIDATES` with:\n\n- the audit date;\n- candidate status and score;\n- the smallest useful lesson scope;\n- the closest existing coverage;\n- primary project or upstream sources;\n- the reason for any status change.\n\nAdd newly found candidates. Retain covered and rejected entries as an append-only decision record. Update scores when repository coverage, upstream maturity, available test infrastructure, or ecosystem evidence changes.\n\n## Recommend one next lesson\n\nReturn the top three and select one winner. Explain the winner through its problem, reusable mechanism, deterministic demonstration, repository gap, and maintenance cost. State why the most fashionable alternative ranked lower when that tradeoff is material.\n\nSeparate these conclusions when useful:\n\n- highest overall tutorial value;\n- strongest new-kernel-feature lesson;\n- most timely or attention-grabbing scenario;\n- best topic that can run in the current KVM environment.\n\nDo not implement the winner unless the user also asks to write it.\n",".agents/skills/test-bpf-tutorial-kvm/agents/openai.yaml":"interface:\n  display_name: \"Test BPF Tutorials in KVM\"\n  short_description: \"Build locally and test with the benchmark KVM kernel\"\n  default_prompt: \"Use $test-bpf-tutorial-kvm to build this BPF tutorial locally and run its smoke test with the bpf-benchmark KVM kernel.\"\n",".agents/skills/find-bpf-tutorial-topic/agents/openai.yaml":"interface:\n  display_name: \"Find BPF Tutorial Topic\"\n  short_description: \"Rank practical, high-value eBPF tutorial topics\"\n  default_prompt: \"Use $find-bpf-tutorial-topic to audit coverage, practical usability, and recommend the next eBPF tutorial.\"\n",".agents/skills/bpf-tutorial-writing-style/agents/openai.yaml":"interface:\n  display_name: \"BPF Tutorial Writing Style\"\n  short_description: \"Check advanced eBPF tutorial prose and structure\"\n  default_prompt: \"Use $bpf-tutorial-writing-style to draft or review this advanced eBPF tutorial in the repository house style.\"\n"},"items":[{"name":"openai.yaml","path":".agents/skills/bpf-tutorial-writing-style/agents/openai.yaml","rawUrl":"https://raw.githubusercontent.com/eunomia-bpf/bpf-developer-tutorial/HEAD/.agents/skills/bpf-tutorial-writing-style/agents/openai.yaml","title":"Agents Skill","category":"anthropic-skill","format":"yaml","content":"interface:\n  display_name: \"BPF Tutorial Writing Style\"\n  short_description: \"Check advanced eBPF tutorial prose and structure\"\n  default_prompt: \"Use $bpf-tutorial-writing-style to draft or review this advanced eBPF tutorial in the repository house style.\"\n","isInternal":false,"tokens":57,"sizeBytes":258},{"name":"SKILL.md","path":".agents/skills/bpf-tutorial-writing-style/SKILL.md","rawUrl":"https://raw.githubusercontent.com/eunomia-bpf/bpf-developer-tutorial/HEAD/.agents/skills/bpf-tutorial-writing-style/SKILL.md","title":"bpf-tutorial-writing-style","category":"anthropic-skill","format":"markdown","content":"---\nname: bpf-tutorial-writing-style\ndescription: Style checklist for English and Chinese bpf-developer-tutorial README files. Use while drafting or reviewing a tutorial so it reads like the established series, preserves technical detail, and presents complete kernel source clearly.\n---\n\n# BPF Tutorial Writing Style\n\nRead the complete guidelines first:\n- [Advanced tutorial guideline](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/scripts/guideline_advance.md) for tutorials 40+\n- [Basic tutorial guideline](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/scripts/guideline_basic.md) for tutorials 0-39\n\nThen read the English and Chinese versions of `47-cuda-events`, `48-energy`, and `49-hid` as style references. Learn their teaching rhythm and level of detail without copying their topic or wording.\n\n## Document Structure (strictly follow guideline)\n\nFor advanced tutorials (40+), follow this exact section order:\n\n1. **Title**: `# eBPF 教程：[Topic Description]` or `# eBPF Tutorial by Example: [Topic Description]`\n\n2. **Introduction**: Brief intro with a concrete problem scenario. Highlight significance and what readers will learn. Link to complete source once here.\n\n3. **Background / Why This Approach**: \n   - Explain WHY this approach is needed\n   - List traditional/alternative approaches and their limitations (e.g., killing process, firewall rules, user-space tools)\n   - Explain what eBPF/the new kernel feature enables that traditional approaches cannot\n   - State when the feature entered Linux (kernel version + commit if relevant)\n\n4. **High-Level Mechanism**:\n   - Explain HOW the eBPF feature/tool works at a high level BEFORE showing code\n   - Describe the overall flow: what happens in kernel, what happens in user space, how they interact\n   - Use diagrams for complex flows with branches, waits, ownership transfers, or 3+ dependent states\n\n5. **Code Implementation**:\n   - First introduce the overall processing logic\n   - Show complete kernel/BPF source and the core headers needed to understand it\n   - Include the complete user-space loader when it is concise; when it is long, use focused excerpts that cover the normal user workflow and link to the lesson directory for the full file\n   - After each code block, explain the key parts with paragraph style (not bullet lists)\n   - Focus on logic and advanced features, not basic syntax\n\n6. **Additional Concepts** (if needed): Deeper explanation of specific features, edge cases, or semantics\n\n7. **Compilation and Execution** (AFTER code, not before):\n   - Build commands\n   - Run commands with examples\n   - Expected output with explanation\n   - Environment requirements table (kernel version, config, privileges, architecture)\n\n8. **Summary**: Key points, scope boundaries, future extensions\n\n9. **Call to Action**: Repository and website invitation (as blockquote)\n\n10. **References**: Links to kernel commits, upstream selftests, documentation\n\n## Tell one useful story\n\n- Open with a concrete situation that the example can reproduce and the question it answers.\n- Near the first mention of eBPF, use one natural sentence to say what eBPF is and why it fits this problem.\n- Introduce the relevant kernel subsystem and new feature when the running example needs them. State when the feature entered Linux and what it enabled.\n- Follow one packet, event, task, or device interaction through kernel space and user space. Explain what happens, why it happens, and what the next step enables.\n- Present the whole flow before detailed code. A small diagram helps when the reader must track a branch, wait, retry, ownership transfer, or at least three dependent states.\n\n## Explain the \"Why\" thoroughly\n\nThis is critical. The Background section must explain:\n- What problem you're solving\n- What traditional approaches exist (killing process, firewall rules, user-space tools like `ss --kill`, sampling, etc.)\n- Why each traditional approach doesn't work well (race conditions, incomplete coverage, performance overhead, etc.)\n- What the eBPF approach enables that wasn't possible before\n\nExample pattern for the \"Why\" section:\n> **杀掉进程**是最直接的想法，但一个进程往往维护着多条连接，杀进程会中断所有业务流量。\n> **防火墙规则**可以阻止新连接，但对已建立的连接无能为力。\n> **用户态工具**如 `ss --kill` 依赖 `/proc/net/tcp` 遍历和注入 RST 报文，但这种方式有竞态问题。\n> **内核态方案**才能真正解决这个问题。BPF 迭代器可以在持有适当锁的情况下遍历内核的套接字表...\n\n## Sound like a tutorial\n\n- Use familiar words, direct verbs, and connected paragraphs. Attraction comes from the problem and mechanism rather than promotional language.\n- Prefer positive descriptions of what the example does. Put remaining limits and safety boundaries in one short paragraph near the end.\n- Use prose for the main explanation and lists for genuinely parallel items.\n- Keep each paragraph focused on one job. Connect facts through cause, sequence, or contrast instead of listing them like a specification.\n- Write Chinese naturally from the same facts instead of translating English sentence by sentence. Use restrained punctuation and spaces between Chinese text and Latin letters or numbers.\n- Keep technical names, code identifiers, commands, numbers, output, versions, and references exact.\n\nUse this Chinese paragraph only as a voice reference for connected rhythm, restrained symbols, and technical density:\n\n> libbpf 是一个 C/C++ 的 eBPF 用户态加载和控制库，随着内核一起分发，几乎已经成为 eBPF 用户态事实上的 API 标准，libbpf 也支持 CO-RE(Compile Once – Run Everywhere) 的解决方案，即预编译的 bpf 代码可以在不同内核版本上正常工作，而无需为每个特定内核重新编译。\n\n## Teach from complete source\n\n- Introduce one component, show its complete kernel/BPF source in an ordinary Markdown fence, then explain the important logic before moving to the next component.\n- Show core headers completely. Include a complete user-space file when it remains readable; otherwise use focused excerpts that preserve the public control flow without making the tutorial a source dump.\n- Keep every complete source block byte-exact. Preserve comments and commands in excerpts, and link once to the lesson directory for omitted user-space details.\n- Use neither `<details>` nor HTML synchronization markers.\n- Link to the complete lesson once through its GitHub directory. Avoid an opening catalog of individual files.\n- Every Markdown link uses an absolute `https://github.com/...` target. Omit a link when no stable GitHub target exists.\n- Public prose contains no local path, shared test repository, VM name, copy route, cache, prompt, model, agent, or trace detail.\n\n## Finish the lesson\n\n- Show copyable build and run commands, representative real output, and what that output proves.\n- State kernel, configuration, privilege, architecture, and hardware requirements that affect the example (use a table).\n- End with a compact scope boundary, summary, repository invitation, and primary references.\n- Keep the English and Chinese files aligned on structure, facts, source, commands, output, limits, and references while allowing each language to sound natural.\n\nThe final read should answer: what problem is solved, how one event moves through the system, which eBPF mechanism makes it possible, which code matters, how to run it, what success looks like, and where the example stops.\n","frontmatter":{"name":"bpf-tutorial-writing-style","description":"Style checklist for English and Chinese bpf-developer-tutorial README files. Use while drafting or reviewing a tutorial so it reads like the established series, preserves technical detail, and presents complete kernel source clearly."},"isInternal":false,"tokens":1672,"sizeBytes":7594},{"name":"openai.yaml","path":".agents/skills/find-bpf-tutorial-topic/agents/openai.yaml","rawUrl":"https://raw.githubusercontent.com/eunomia-bpf/bpf-developer-tutorial/HEAD/.agents/skills/find-bpf-tutorial-topic/agents/openai.yaml","title":"Agents Skill","category":"anthropic-skill","format":"yaml","content":"interface:\n  display_name: \"Find BPF Tutorial Topic\"\n  short_description: \"Rank practical, high-value eBPF tutorial topics\"\n  default_prompt: \"Use $find-bpf-tutorial-topic to audit coverage, practical usability, and recommend the next eBPF tutorial.\"\n","isInternal":false,"tokens":58,"sizeBytes":251},{"name":"SKILL.md","path":".agents/skills/find-bpf-tutorial-topic/SKILL.md","rawUrl":"https://raw.githubusercontent.com/eunomia-bpf/bpf-developer-tutorial/HEAD/.agents/skills/find-bpf-tutorial-topic/SKILL.md","title":"find-bpf-tutorial-topic","category":"anthropic-skill","format":"markdown","content":"---\nname: find-bpf-tutorial-topic\ndescription: Audit bpf-developer-tutorial coverage, research current Linux BPF work and real open-source eBPF projects, maintain the repository tutorial candidate registry, and rank the next lesson by reader value, operational usefulness, eBPF leverage, reproducibility, distinctness, teaching clarity, ecosystem evidence, maturity, and maintenance cost. Use when deciding what eBPF tutorial to write next, checking whether an idea is already covered or practically usable, comparing feature-driven and scenario-driven topics, refreshing the topic roadmap, or asking which candidate has the highest value.\n---\n\n# Find the Next BPF Tutorial Topic\n\nChoose one lesson-sized problem with lasting teaching value. Treat kernel changes as capability evidence and open-source projects as evidence that the problem matters.\n\n## Resolve the repository\n\nWork from a complete Git checkout and derive absolute paths:\n\n```bash\nREPO_ROOT=\"$(git rev-parse --show-toplevel)\"\nCANDIDATES=\"$REPO_ROOT/TUTORIAL_IDEAS.md\"\n```\n\nRead `CANDIDATES` before researching. Preserve its history: keep existing candidates and change their status to `covered`, `superseded`, `deferred`, or `rejected` with a reason instead of deleting them.\n\n## Audit existing coverage\n\nInspect the current worktree, open tutorial branches or PRs when available, and every first-level directory under `src`. Include numbered lessons, unnumbered lessons such as `cgroup`, and grouped material such as `features` and `xpu`; exclude vendored source such as `third_party` from the coverage decision. Read enough implementation and prose to distinguish a shared helper from a genuinely covered mechanism.\n\nUse `rg` to search candidate hook names, helpers, program types, protocols, and scenarios across README and source files. Record the closest existing lesson for every candidate. A new scenario can reuse an existing primitive when it teaches a different diagnostic or control pattern; a renamed example of the same flow is duplicate coverage.\n\nPay special attention to unmerged lessons in the current worktree so the roadmap does not recommend work already under review.\n\n## Research capabilities and real use cases\n\nUse current primary sources. Search more broadly than Linux:\n\n1. Linux BPF merge commits, documentation, selftests, libbpf, and bpftool releases establish semantics, version requirements, and reference behavior.\n2. Active observability and profiling projects reveal recurring operational questions. Include OpenTelemetry OBI and profiler, Parca, Pyroscope, Coroot, Odigos, and comparable projects.\n3. Networking projects reveal reusable datapath patterns. Include Cilium, Hubble, Kmesh, Katran, sched_ext, and comparable projects.\n4. Security projects reveal concrete detection and enforcement scenarios. Include Tetragon, Falco, Tracee, and comparable projects.\n5. Packaging and lifecycle projects reveal deployment gaps. Include Inspektor Gadget and bpfman.\n6. AI, accelerator, storage, and runtime projects reveal newer workloads. Include agtap, eCapture, io_uring tools, OpenTelemetry profiler GPU work, GPU/NCCL projects, and comparable projects.\n\nPrefer official repositories, release notes, documentation, selftests, and papers from the project authors. Use popularity only as supporting context. Recent releases, repeated implementations across independent projects, and concrete tests are stronger evidence.\n\nConvert each project feature into a small independent lesson. Teach the mechanism and the question it answers rather than writing an installation guide for the source project.\n\n## Define the runnable lesson before scoring\n\nFor every serious candidate, write seven short fields:\n\n- the concrete question a reader can reproduce;\n- the event, packet, request, task, or workload followed end to end;\n- the BPF hook, map, helper, kfunc, or program type that makes the answer possible;\n- the exact command a reader would realistically run and the decision or action its output enables;\n- the natural lifecycle: single-pass action, bounded diagnostic, or persistent monitor, including how it stops and cleans up;\n- the deterministic fixture and observable success output;\n- the closest existing lesson and the new knowledge this candidate adds.\n\nDefer an idea when these fields remain vague. A helper name alone is not a tutorial topic.\n\n## Apply the practicality gate before scoring\n\nWalk through the proposed public workflow as an operator, separately from the deterministic test harness:\n\n- A naturally one-shot operation, such as an iterator scan or atomic state change, may run once and exit. An observability or enforcement monitor must attach before independent workloads, remain useful for its natural lifetime, and stop cleanly by signal, duration, or an explicit completion condition.\n- The fixture may be artificial, but the public command must not exist only to launch `/bin/true` or another toy trigger. A launch-scoped command is acceptable only when launch scoping is itself the lesson's real use case.\n- Require an explicit readiness signal before an independent workload starts; fixed sleeps do not prove that attachment or setup finished.\n- Define target scope and filters, concurrent-event or admission behavior, failure and drop visibility, cleanup after normal exit and signals, and what a reader does with the result.\n- For asynchronous work, define shutdown as: stop admission, wait for completed work rather than merely started callbacks, drain output, report stable health, then destroy resources.\n- Reject a design whose output merely proves that a helper ran. The output must answer the stated operational question or drive the stated action.\n\nRedesign or defer a candidate when the fixture is its only plausible user, when the lifecycle contradicts the scenario, or when safe cleanup and bounded resource behavior cannot be explained and tested.\n\n## Score value\n\nScore from evidence, then subtract costs. Keep the breakdown in working notes and place the final score in `TUTORIAL_IDEAS.md`.\n\n| Dimension | Maximum | Question |\n|---|---:|---|\n| Reader problem | 20 | Does it answer a recurring, consequential question? |\n| Operational usefulness | 15 | Is the public command and lifecycle useful outside the test fixture? |\n| eBPF leverage | 15 | Does eBPF provide visibility or control that ordinary tools cannot provide as cleanly? |\n| Coverage gap | 15 | Does it add a distinct mechanism or scenario to this repository? |\n| Reproducibility | 10 | Can one bounded local or KVM fixture prove the result? |\n| Teaching clarity | 10 | Can the lesson follow one understandable path and show decisive output? |\n| Ecosystem evidence | 10 | Do maintained projects or upstream tests validate the use case? |\n| Maturity | 5 | Are the required kernel and userspace interfaces stable enough to maintain? |\n\nSubtract up to 20 points for unstable private interfaces, broad multi-service scope, unusual hardware, cloud or Kubernetes requirements, fragile protocol parsing, and high version-specific maintenance.\n\nNewness breaks close ties; it does not replace reader value. Favor a stable lesson that solves a real problem over a new helper without a compelling use case.\n\n## Apply the admission gates\n\nA candidate can become `ready` only when:\n\n- it has a concrete reproducible problem and expected output;\n- its documented invocation and lifecycle match how a reader would use the tool outside the fixture;\n- its target scope, concurrency or admission bound, failure visibility, and cleanup path are explicit;\n- eBPF is central to the solution;\n- the repository does not already teach the same flow;\n- the example can fit one coherent tutorial;\n- primary sources establish the technical claims;\n- required kernel, architecture, privilege, and hardware conditions are known;\n- the likely maintenance burden is proportionate to its value.\n\nClassify a small addition to an existing lesson as `maintenance` rather than creating a new numbered tutorial. Classify an immature upstream feature as `watch` until it reaches a suitable stable kernel or userspace release.\n\n## Maintain the candidate registry\n\nUpdate `CANDIDATES` with:\n\n- the audit date;\n- candidate status and score;\n- the smallest useful lesson scope;\n- the closest existing coverage;\n- primary project or upstream sources;\n- the reason for any status change.\n\nAdd newly found candidates. Retain covered and rejected entries as an append-only decision record. Update scores when repository coverage, upstream maturity, available test infrastructure, or ecosystem evidence changes.\n\n## Recommend one next lesson\n\nReturn the top three and select one winner. Explain the winner through its problem, reusable mechanism, deterministic demonstration, repository gap, and maintenance cost. State why the most fashionable alternative ranked lower when that tradeoff is material.\n\nSeparate these conclusions when useful:\n\n- highest overall tutorial value;\n- strongest new-kernel-feature lesson;\n- most timely or attention-grabbing scenario;\n- best topic that can run in the current KVM environment.\n\nDo not implement the winner unless the user also asks to write it.\n","frontmatter":{"name":"find-bpf-tutorial-topic","description":"Audit bpf-developer-tutorial coverage, research current Linux BPF work and real open-source eBPF projects, maintain the repository tutorial candidate registry, and rank the next lesson by reader value, operational usefulness, eBPF leverage, reproducibility, distinctness, teaching clarity, ecosystem evidence, maturity, and maintenance cost. Use when deciding what eBPF tutorial to write next, checking whether an idea is already covered or practically usable, comparing feature-driven and scenario-driven topics, refreshing the topic roadmap, or asking which candidate has the highest value."},"isInternal":false,"tokens":1798,"sizeBytes":9144},{"name":"openai.yaml","path":".agents/skills/test-bpf-tutorial-kvm/agents/openai.yaml","rawUrl":"https://raw.githubusercontent.com/eunomia-bpf/bpf-developer-tutorial/HEAD/.agents/skills/test-bpf-tutorial-kvm/agents/openai.yaml","title":"Agents Skill","category":"anthropic-skill","format":"yaml","content":"interface:\n  display_name: \"Test BPF Tutorials in KVM\"\n  short_description: \"Build locally and test with the benchmark KVM kernel\"\n  default_prompt: \"Use $test-bpf-tutorial-kvm to build this BPF tutorial locally and run its smoke test with the bpf-benchmark KVM kernel.\"\n","isInternal":false,"tokens":68,"sizeBytes":271},{"name":"tutorial-patterns.md","path":".agents/skills/test-bpf-tutorial-kvm/references/tutorial-patterns.md","rawUrl":"https://raw.githubusercontent.com/eunomia-bpf/bpf-developer-tutorial/HEAD/.agents/skills/test-bpf-tutorial-kvm/references/tutorial-patterns.md","title":"References Skill","category":"anthropic-skill","format":"markdown","content":"# BPF tutorial KVM test patterns\n\nResolve the wrapper from the tutorial worktree:\n\n```bash\nTUTORIAL_ROOT=\"$(git rev-parse --show-toplevel)\"\nRUNNER=\"$TUTORIAL_ROOT/.agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh\"\n```\n\nAll paths below are host paths exposed at the same location in the virtme-ng guest.\n\n## One-shot loader or self-test\n\n```bash\n\"$RUNNER\" --cwd \"$LESSON\" -- ./loader --self-test\n```\n\nPrefer a self-test that loads the BPF object, exercises a deterministic input, checks the map or return value, and detaches before exiting.\n\n## Long-running tracer plus a trigger\n\nThe loader, trigger, signal, and output assertion must all occur inside the same guest:\n\n```bash\n\"$RUNNER\" --cwd \"$LESSON\" --timeout 90 -- bash -lc '\nset -euo pipefail\nout=$(mktemp)\n./tracer >\"$out\" 2>&1 &\npid=$!\ntrap '\\''kill -INT \"$pid\" 2>/dev/null || true; wait \"$pid\" 2>/dev/null || true'\\'' EXIT\nsleep 1\ntrue                         # replace with the deterministic traced event\nsleep 1\nkill -INT \"$pid\"\nwait \"$pid\" || test $? -eq 130\ntrap - EXIT\ngrep -F \"expected event\" \"$out\"\n'\n```\n\nKeep the host timeout longer than the guest-side lifecycle. Avoid an unbounded `timeout ./tracer` assertion because exit 124 proves only that it was killed.\n\n## XDP or TC\n\nFor a userspace-backed interface and outbound guest traffic:\n\n```bash\n\"$RUNNER\" --cwd \"$LESSON\" --network user -- bash -lc '\nset -euo pipefail\nip -brief link\n./loader --interface eth0 &\npid=$!\ntrap '\\''kill -INT \"$pid\" 2>/dev/null || true; wait \"$pid\" 2>/dev/null || true'\\'' EXIT\nping -c 1 -W 2 10.0.2.2\n# Assert counters or emitted events here.\n'\n```\n\nUse `--network loop` for guest-local network testing. Prefer `BPF_PROG_TEST_RUN` when the lesson is about program behavior rather than attachment mechanics.\n\n## sched_ext, LSM, and cgroup programs\n\n- Verify the exact config symbol in the printed kernel config before booting, for example `CONFIG_SCHED_CLASS_EXT=y` or `CONFIG_BPF_LSM=y`.\n- Keep sched_ext registration bounded and assert that the scheduler exits or unregisters cleanly.\n- Create test cgroups only inside the guest's cgroup2 mount.\n- Test LSM enforcement on guest-local temporary files or processes, never on host resources mounted read-write.\n\n## Returning generated output\n\nThe tutorial directory is read-only by default. Create a dedicated output directory and expose only it when a test must retain logs or generated files:\n\n```bash\nmkdir -p \"$LESSON/test-output\"\n\"$RUNNER\" --cwd \"$LESSON\" --rwdir \"$LESSON/test-output\" -- \\\n    ./loader --output \"$LESSON/test-output/smoke.json\"\n```\n\nGuest root can modify any `--rwdir` path. Never expose a repository root, `.git`, credentials, task histories, or agent traces just for convenience.\n\n## Interpreting failures\n\n- **Preflight fails:** repair KVM/tool/artifact availability; do not fall back to the host kernel.\n- **Guest kernel mismatch:** the image and build metadata are inconsistent; rebuild or repair the benchmark artifact separately.\n- **`bpftool` asks for `linux-tools-<guest-version>`:** the Ubuntu `/usr/sbin/bpftool` wrapper was selected. On this machine, use the real binary at `/usr/local/sbin/bpftool` after confirming it with `--version`.\n- **Unknown helper, attach type, or kfunc:** compare lesson requirements with the built kernel release/config/BTF. Report a kernel gap rather than changing the host test boundary.\n- **Permission error inside guest:** confirm the command is running as guest root and that bpffs/debugfs/tracefs/cgroup2 mounted. Do not add host `sudo`.\n- **Read-only filesystem:** write under `/tmp`, or explicitly expose a narrow output directory with `--rwdir`.\n- **Timeout 124:** inspect loader cleanup and the trigger. A timeout is not a passing tracer test.\n- **Verifier rejection:** preserve the complete verifier log and distinguish an intentional negative test from a compatibility regression.\n","isInternal":false,"tokens":942,"sizeBytes":3860},{"name":"SKILL.md","path":".agents/skills/test-bpf-tutorial-kvm/SKILL.md","rawUrl":"https://raw.githubusercontent.com/eunomia-bpf/bpf-developer-tutorial/HEAD/.agents/skills/test-bpf-tutorial-kvm/SKILL.md","title":"test-bpf-tutorial-kvm","category":"anthropic-skill","format":"markdown","content":"---\nname: test-bpf-tutorial-kvm\ndescription: Build and smoke-test bpf-developer-tutorial lessons without loading BPF programs into the host kernel. Use when creating, changing, reviewing, or debugging an eBPF tutorial and the runtime test should reuse the already-built x86 kernel under bpf-benchmark through virtme-ng/KVM. Also use for checking whether a tutorial needs a newer kernel feature. Do not use this workflow for performance benchmarking or for rebuilding the benchmark kernel.\n---\n\n# Test BPF Tutorials in KVM\n\nCompile tutorial code on the host, but run every command that loads, attaches, or exercises BPF inside a short-lived KVM guest using the kernel artifact already built by `bpf-benchmark`.\n\n## Safety boundary\n\n- Never load or attach a tutorial BPF program on the host. This includes `bpftool prog load`, loaders, `make run`, XDP/TC attachment, sched_ext registration, and LSM/cgroup attachment.\n- Do not rebuild or modify `bpf-benchmark`, its kernel tree, its Git state, caches, results, or conversation/agent-history data.\n- Do not silently fall back to the host kernel or to TCG. Stop if `/dev/kvm`, `vng`, or the expected benchmark kernel is unavailable.\n- Treat the tutorial directory as read-only in the guest by default. Use `--rwdir` only for a path that must return guest-generated files to the host.\n- Use bounded commands. The wrapper applies a host-side timeout; add a shorter guest-side `timeout` to long-running loaders when useful.\n- Report a KVM run as a functional smoke test, not as benchmark-quality evidence.\n- Keep this infrastructure private in public prose. A tutorial or PR description may state the architecture, kernel version and commit, configuration, commands, and captured output, but must not name `bpf-benchmark`, local paths, VM instances, mount routes, caches, or agent-state locations.\n\n## Default locations\n\nResolve the tutorial checkout and skill from the current Git worktree:\n\n```bash\nTUTORIAL_ROOT=\"$(git rev-parse --show-toplevel)\"\nRUNNER=\"$TUTORIAL_ROOT/.agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh\"\n```\n\nThe helper reads `BPF_BENCHMARK_ROOT`, defaulting to a `bpf-benchmark` checkout next to the tutorial repository. Its `--cwd` defaults to the caller's current directory.\n\nThe reused kernel is:\n\n```text\n$BPF_BENCHMARK_ROOT/vendor/build/x86/linux/arch/x86/boot/bzImage\n```\n\n## Workflow\n\n### 1. Validate the repositories and instructions\n\nRead every applicable `AGENTS.md` or equivalent repository instruction before acting.\n\nRequire a real tutorial checkout before implementation or testing. A valid checkout has lesson sources and a working Git worktree, not only a `.git` fragment. If it is incomplete, stop and explain that the checkout must be restored; do not clone over it or delete the remnant without explicit authorization.\n\nThe top-level `bpf-benchmark` Git repository does not need to be healthy for artifact reuse. The wrapper validates the kernel image, build config, kernel source worktree, KVM device, and toolchain independently.\n\nRun the preflight:\n\n```bash\n\"$RUNNER\" --check\n```\n\n### 2. Inspect before building\n\nRead the lesson README, Makefile, source, and existing test commands. Identify separately:\n\n1. a compile-only host command;\n2. the userspace loader or runtime command;\n3. the event or workload that proves the program works;\n4. any required network, cgroup, tracefs, debugfs, or kernel-config feature.\n\nUse `make -n` or inspect recipes before choosing a target. A target that invokes a loader is a guest command, even if it also compiles.\n\n### 3. Build on the host\n\nRun only compile and static-generation steps on the host. Prefer the lesson's documented build target. Preserve generated `.bpf.o`, skeletons, and userspace binaries in the lesson directory so the guest sees the exact host-built artifacts.\n\nDo not use `sudo` for the build. Do not run a post-build loader on the host.\n\n### 4. Run inside the benchmark-kernel guest\n\nPass the runtime command after `--`. Arguments are preserved without host re-evaluation.\n\n```bash\nTUTORIAL_ROOT=\"$(git rev-parse --show-toplevel)\"\nRUNNER=\"$TUTORIAL_ROOT/.agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh\"\nLESSON=\"$TUTORIAL_ROOT/src/<lesson>\"\n\n\"$RUNNER\" --cwd \"$LESSON\" -- ./loader --help\n```\n\nThe wrapper boots the built benchmark `bzImage` with KVM, verifies the guest release, runs as guest root, mounts bpffs/debugfs/tracefs/cgroup2, prints provenance, and powers off when the command exits. It defaults to 2 vCPUs, 4G RAM, no network, and 120 seconds.\n\nUse `--network user` only when the test needs an external/userspace-backed interface. Use `--network loop` for a guest-local loop network. Prefer `BPF_PROG_TEST_RUN` or deterministic guest-local traffic when either is sufficient.\n\nRead [the tutorial test patterns](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/.agents/skills/test-bpf-tutorial-kvm/references/tutorial-patterns.md) for tracer, network, writable-output, and failure-diagnosis patterns.\n\n### 5. Verify the behavior, not only the exit code\n\nCapture enough evidence to connect an input event to the expected BPF output: attach confirmation, a deterministic trigger in the same guest, expected map/event output, and clean detach or process exit. Negative tests should verify the expected verifier or attach failure.\n\nFor a new lesson, test at least:\n\n- host compile from a clean lesson build state when safe;\n- KVM preflight;\n- one successful guest runtime path;\n- one relevant error or cleanup path;\n- documentation commands exactly as written.\n\nDo not clean unrelated files or repository-wide caches to create a clean build state.\n\n### 6. Report provenance and limitations\n\nInclude the guest `uname -r`, benchmark kernel source commit, kernel image SHA-256, lesson commit or dirty state, host build command, guest command, and the observed result. The wrapper prints kernel provenance automatically.\n\nIf the tutorial requires a feature absent from the built config or kernel, report the missing symbol/helper/attach type and stop. Propose a benchmark-kernel rebuild or upgrade separately; do not perform it as a fallback.\n\n## Wrapper interface\n\n```text\nrun-in-kvm.sh --check\nrun-in-kvm.sh [--cwd PATH] [--cpus N] [--memory SIZE]\n              [--timeout SECONDS] [--network none|user|loop]\n              [--rwdir PATH]... [--append KERNEL_ARGS]...\n              [--dry-run] [--verbose] -- COMMAND [ARG...]\n```\n\nUse `--dry-run` to inspect the generated `vng`/QEMU launch without booting. `--rwdir` is an explicit trust decision because guest root can change that host path.\n","frontmatter":{"name":"test-bpf-tutorial-kvm","description":"Build and smoke-test bpf-developer-tutorial lessons without loading BPF programs into the host kernel. Use when creating, changing, reviewing, or debugging an eBPF tutorial and the runtime test should reuse the already-built x86 kernel under bpf-benchmark through virtme-ng/KVM. Also use for checking whether a tutorial needs a newer kernel feature. Do not use this workflow for performance benchmarking or for rebuilding the benchmark kernel."},"isInternal":false,"tokens":1491,"sizeBytes":6574},{"name":"openai.yaml","path":".agents/skills/write-bpf-production-tutorial/agents/openai.yaml","rawUrl":"https://raw.githubusercontent.com/eunomia-bpf/bpf-developer-tutorial/HEAD/.agents/skills/write-bpf-production-tutorial/agents/openai.yaml","title":"Agents Skill","category":"anthropic-skill","format":"yaml","content":"interface:\n  display_name: \"BPF Tutorial Writer\"\n  short_description: \"Design and test practical bilingual eBPF lessons\"\n  default_prompt: \"Use $write-bpf-production-tutorial to turn this eBPF example into a practical, tested bilingual tutorial.\"\n","isInternal":false,"tokens":55,"sizeBytes":247},{"name":"SKILL.md","path":".agents/skills/write-bpf-production-tutorial/SKILL.md","rawUrl":"https://raw.githubusercontent.com/eunomia-bpf/bpf-developer-tutorial/HEAD/.agents/skills/write-bpf-production-tutorial/SKILL.md","title":"write-bpf-production-tutorial","category":"anthropic-skill","format":"markdown","content":"---\nname: write-bpf-production-tutorial\ndescription: Design, write, or rewrite one practical bilingual bpf-developer-tutorial lesson with pinned Claude Opus 4.5, then verify the public workflow and prose against the implementation. Use when creating README.md and README.zh.md, checking whether a tutorial tool has a realistic CLI and lifecycle, preserving complete kernel source, testing the example, or preparing tutorial changes for review.\n---\n\n# Write a BPF Tutorial\n\nUse `$bpf-tutorial-writing-style` for the finished prose. Keep this workflow small: prepare reliable source material, let one pinned writer complete both languages, then check what it actually wrote.\n\n## 1. Prepare the lesson\n\nRead these inputs before writing:\n\n- `scripts/guideline_advance.md` for tutorials 40+, `scripts/guideline_basic.md` for tutorials 0-39;\n- both README files from `src/47-cuda-events`, `src/48-energy`, and `src/49-hid` as style references;\n- the lesson's implementation, headers, Makefile, fixtures, and tests;\n- the current README pair when revising an existing lesson;\n- primary upstream sources for versions and feature semantics.\n\nCollect the facts the reader needs: the problem, why traditional approaches fail, the kernel/user-space flow, feature versions, requirements, intended public commands, real output, concurrency or admission behavior, cleanup, limits, and references. Keep every claim grounded in the code, tests, captured output, or a primary source. Preserve an existing draft before a from-scratch rewrite.\n\nBuild and run the example when the environment supports it. Use `$test-bpf-tutorial-kvm` for kernel features that need the repository's KVM environment. Runtime details support the tutorial; local workspace paths, VM names, shared repositories, caches, prompts, and agent traces stay private.\n\n## 2. Pass the practical-design gate\n\nValidate the tool as an operator before writing prose. Keep its public workflow separate from the deterministic fixture:\n\n- State the operational question, the exact command a reader would run, the independent workload or target, the useful output, and how the tool stops.\n- Classify the lifecycle. A scan or atomic control action may be one-shot; a tracer or monitor must attach before the workload and remain active until a signal, duration, or real completion condition.\n- Do not turn a blocked toy child or `/bin/true` fixture into the public CLI merely because it removes a test race. Launch-scoped tracing is valid only when it is the intended real workflow.\n- Emit and test an explicit readiness signal before starting an independent workload. Do not use a fixed sleep as proof that setup or attachment completed.\n- Check target scope and filters, concurrent state, admission bounds, drop and failure counters, exit status, normal cleanup, signal cleanup, and destructive-action safety in proportion to the lesson.\n- For asynchronous work, stop admission first, wait for completed work rather than merely entered callbacks, drain output, report stable health, and only then destroy resources.\n- Execute the documented command as written. The test must prove the real lifecycle plus one relevant failure or cleanup path, not only that the BPF program loaded.\n- Describe the current public workflow directly. Do not narrate removed flags, old child-command modes, or other migration history unless backward compatibility is itself the lesson.\n- Keep repository tests out of the reader-facing tutorial path. Use them as private validation evidence, but teach the normal command, independent workload, useful tool output, and shutdown sequence.\n- Show only output emitted by the documented tool in public examples. Never include harness lines such as `TEST-*` or `PASS`, fixture setup, test assertions, or local test-infrastructure provenance.\n\nIf the implementation only demonstrates a helper but is awkward or misleading as a tool, revise the implementation and test before asking the writer to explain it. Do not let polished prose overclaim an impractical design.\n\n## 3. Structure requirements\n\nFor advanced tutorials (40+), follow this exact section order as defined in `$bpf-tutorial-writing-style`:\n\n1. **Title + Introduction**: Concrete problem scenario, link to source\n2. **Background / Why This Approach**: Explain traditional approaches and their limitations, then what eBPF enables\n3. **High-Level Mechanism**: How the feature works before showing code\n4. **Code Implementation**: Complete kernel/BPF source and core headers, plus a complete user-space loader when concise or focused user-space excerpts when long, then paragraph explanations\n5. **Additional Concepts** (if needed)\n6. **Compilation and Execution**: AFTER code analysis, not before\n7. **Summary + Call to Action**\n8. **References**\n\nThe \"Background / Why\" section is critical. It must explain:\n- What traditional approaches exist\n- Why each doesn't work well\n- What the eBPF approach enables\n\n## 4. Let Opus write\n\nClaude Opus writes all reader-facing tutorial prose. Use the exact model ID `claude-opus-4-5-20251101`. Stop if that model is unavailable instead of substituting another model.\n\nUse one non-interactive invocation for the complete English and Chinese pair. The prompt stays short and names only:\n\n- the two target README files;\n- `scripts/guideline_advance.md` or `scripts/guideline_basic.md`;\n- `$bpf-tutorial-writing-style`;\n- `src/47-cuda-events`, `src/48-energy`, and `src/49-hid` as style references;\n- the request to read the implementation and write both files completely before returning.\n\nDo not paste a second checklist, paragraph plan, fact inventory, or review rubric into the prompt. Add a technical fact only when it is unavailable in the repository.\n\nRun Claude from the repository root with the pinned model and permission to read the repository and write the two README files. Opus does not commit or push.\n\n## 5. Check the result\n\nInspect both files and the diff instead of trusting the model's final message. Confirm that:\n\n- both languages are complete and tell the same technical story;\n- the documented command, target, lifecycle, signals, concurrency bounds, cleanup, and health output match the practical design gate;\n- the opening reads like a tutorial rather than an abstract or feature list;\n- there is a \"Why\" section explaining traditional approaches and their limitations;\n- the high-level mechanism is explained BEFORE code sections;\n- compilation/execution is AFTER code analysis;\n- every kernel/BPF source and core header appears once in a complete ordinary Markdown fence; a concise user-space loader should also be complete, while a long loader may use focused excerpts that cover the normal public control flow;\n- code, commands, output, versions, requirements, cleanup, and limits agree with the repository;\n- sample output comes from the normal public workflow and contains no test-harness or migration/deprecation narration;\n- the opening source link points only to the lesson directory;\n- every published link is an absolute `https://github.com/...` URL;\n- no local infrastructure, prompt, model, agent, or trace detail appears in public text.\n\nCheck the required complete-source inventory with the bundled `sync-source-blocks.py`: always include kernel/BPF sources and core headers, and include user-space files only when the README presents them as complete. Then run `git diff --check`, the lesson build, its tests, the exact documented public command, and the relevant runtime test. Treat a functional run as a functional run rather than a benchmark.\n\nRead the finished pair once as an intermediate eBPF developer. If a concrete problem remains, give Opus a short defect list in the same session and let it revise the whole pair before returning. Keep prompts, responses, partial drafts, and failed runs; never delete real conversation or agent history.\n\nStop after the reviewed local result unless the user asks to commit, push, or update a PR.\n","frontmatter":{"name":"write-bpf-production-tutorial","description":"Design, write, or rewrite one practical bilingual bpf-developer-tutorial lesson with pinned Claude Opus 4.5, then verify the public workflow and prose against the implementation. Use when creating README.md and README.zh.md, checking whether a tutorial tool has a realistic CLI and lifecycle, preserving complete kernel source, testing the example, or preparing tutorial changes for review."},"isInternal":false,"tokens":1616,"sizeBytes":7942},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/eunomia-bpf/bpf-developer-tutorial/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nThis is the eBPF Developer Tutorial repository - a comprehensive learning resource for eBPF development. It provides 48+ practical examples progressing from beginner to advanced topics using modern eBPF frameworks like libbpf, Cilium eBPF, and libbpf-rs.\n\n## Common Development Tasks\n\n### Building eBPF Examples\n\nMost examples use libbpf and follow this pattern:\n```bash\ncd src/<example-number>-<example-name>\nmake\n```\n\nFor Rust examples (in src/37-uprobe-rust/):\n```bash\ncd src/37-uprobe-rust/<example>\ncargo build\n```\n\n### Running Examples\n\nMost examples require root privileges:\n```bash\nsudo ./<binary-name>\n# or with timeout for continuous monitoring tools:\nsudo timeout -s 2 3 ./<binary-name>\n```\n\n### Clean Build Artifacts\n```bash\nmake clean\n```\n\n## Architecture\n\n### Build System\n- **Framework**: GNU Make with libbpf\n- **BPF Compilation**: Clang/LLVM compiles `.bpf.c` → `.bpf.o`\n- **Skeleton Generation**: bpftool generates `.skel.h` from BPF objects\n- **User Space**: GCC compiles C programs linking with libbpf\n- **Dependencies**: All in `src/third_party/` (libbpf, bpftool, blazesym, vmlinux headers)\n\n### Directory Structure\n- `src/0-10`: Basic eBPF concepts (kprobes, uprobes, tracepoints)\n- `src/11-18`: Advanced libbpf development\n- `src/19-21,29,41-42`: Networking (LSM, TC, XDP, sockops)\n- `src/22-28,34`: Security topics\n- `src/31,37`: Language integration (Go, Rust)\n- `src/44-45`: BPF schedulers\n- `src/47`: GPU tracing\n- Each tutorial has its own Makefile and README\n\n### Key Components\n1. **vmlinux headers**: Pre-generated for x86, arm, arm64, riscv, powerpc, loongarch\n2. **CO-RE (Compile Once, Run Everywhere)**: Uses BTF for kernel compatibility\n3. **Multiple frameworks**: libbpf (primary), eunomia-bpf, Cilium eBPF, libbpf-rs","isInternal":false,"tokens":543,"sizeBytes":1894}],"systemPromptSnippet":"<yakaai_skills repo=\"eunomia-bpf/bpf-developer-tutorial\">\n<!-- File: .agents/skills/bpf-tutorial-writing-style/agents/openai.yaml (Tokens: ~57 | Category: anthropic-skill) -->\ninterface:\n  display_name: \"BPF Tutorial Writing Style\"\n  short_description: \"Check advanced eBPF tutorial prose and structure\"\n  default_prompt: \"Use $bpf-tutorial-writing-style to draft or review this advanced eBPF tutorial in the repository house style.\"\n\n<!-- File: .agents/skills/bpf-tutorial-writing-style/SKILL.md (Tokens: ~1672 | Category: anthropic-skill) -->\n---\nname: bpf-tutorial-writing-style\ndescription: Style checklist for English and Chinese bpf-developer-tutorial README files. Use while drafting or reviewing a tutorial so it reads like the established series, preserves technical detail, and presents complete kernel source clearly.\n---\n\n# BPF Tutorial Writing Style\n\nRead the complete guidelines first:\n- [Advanced tutorial guideline](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/scripts/guideline_advance.md) for tutorials 40+\n- [Basic tutorial guideline](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/scripts/guideline_basic.md) for tutorials 0-39\n\nThen read the English and Chinese versions of `47-cuda-events`, `48-energy`, and `49-hid` as style references. Learn their teaching rhythm and level of detail without copying their topic or wording.\n\n## Document Structure (strictly follow guideline)\n\nFor advanced tutorials (40+), follow this exact section order:\n\n1. **Title**: `# eBPF 教程：[Topic Description]` or `# eBPF Tutorial by Example: [Topic Description]`\n\n2. **Introduction**: Brief intro with a concrete problem scenario. Highlight significance and what readers will learn. Link to complete source once here.\n\n3. **Background / Why This Approach**: \n   - Explain WHY this approach is needed\n   - List traditional/alternative approaches and their limitations (e.g., killing process, firewall rules, user-space tools)\n   - Explain what eBPF/the new kernel feature enables that traditional approaches cannot\n   - State when the feature entered Linux (kernel version + commit if relevant)\n\n4. **High-Level Mechanism**:\n   - Explain HOW the eBPF feature/tool works at a high level BEFORE showing code\n   - Describe the overall flow: what happens in kernel, what happens in user space, how they interact\n   - Use diagrams for complex flows with branches, waits, ownership transfers, or 3+ dependent states\n\n5. **Code Implementation**:\n   - First introduce the overall processing logic\n   - Show complete kernel/BPF source and the core headers needed to understand it\n   - Include the complete user-space loader when it is concise; when it is long, use focused excerpts that cover the normal user workflow and link to the lesson directory for the full file\n   - After each code block, explain the key parts with paragraph style (not bullet lists)\n   - Focus on logic and advanced features, not basic syntax\n\n6. **Additional Concepts** (if needed): Deeper explanation of specific features, edge cases, or semantics\n\n7. **Compilation and Execution** (AFTER code, not before):\n   - Build commands\n   - Run commands with examples\n   - Expected output with explanation\n   - Environment requirements table (kernel version, config, privileges, architecture)\n\n8. **Summary**: Key points, scope boundaries, future extensions\n\n9. **Call to Action**: Repository and website invitation (as blockquote)\n\n10. **References**: Links to kernel commits, upstream selftests, documentation\n\n## Tell one useful story\n\n- Open with a concrete situation that the example can reproduce and the question it answers.\n- Near the first mention of eBPF, use one natural sentence to say what eBPF is and why it fits this problem.\n- Introduce the relevant kernel subsystem and new feature when the running example needs them. State when the feature entered Linux and what it enabled.\n- Follow one packet, event, task, or device interaction through kernel space and user space. Explain what happens, why it happens, and what the next step enables.\n- Present the whole flow before detailed code. A small diagram helps when the reader must track a branch, wait, retry, ownership transfer, or at least three dependent states.\n\n## Explain the \"Why\" thoroughly\n\nThis is critical. The Background section must explain:\n- What problem you're solving\n- What traditional approaches exist (killing process, firewall rules, user-space tools like `ss --kill`, sampling, etc.)\n- Why each traditional approach doesn't work well (race conditions, incomplete coverage, performance overhead, etc.)\n- What the eBPF approach enables that wasn't possible before\n\nExample pattern for the \"Why\" section:\n> **杀掉进程**是最直接的想法，但一个进程往往维护着多条连接，杀进程会中断所有业务流量。\n> **防火墙规则**可以阻止新连接，但对已建立的连接无能为力。\n> **用户态工具**如 `ss --kill` 依赖 `/proc/net/tcp` 遍历和注入 RST 报文，但这种方式有竞态问题。\n> **内核态方案**才能真正解决这个问题。BPF 迭代器可以在持有适当锁的情况下遍历内核的套接字表...\n\n## Sound like a tutorial\n\n- Use familiar words, direct verbs, and connected paragraphs. Attraction comes from the problem and mechanism rather than promotional language.\n- Prefer positive descriptions of what the example does. Put remaining limits and safety boundaries in one short paragraph near the end.\n- Use prose for the main explanation and lists for genuinely parallel items.\n- Keep each paragraph focused on one job. Connect facts through cause, sequence, or contrast instead of listing them like a specification.\n- Write Chinese naturally from the same facts instead of translating English sentence by sentence. Use restrained punctuation and spaces between Chinese text and Latin letters or numbers.\n- Keep technical names, code identifiers, commands, numbers, output, versions, and references exact.\n\nUse this Chinese paragraph only as a voice reference for connected rhythm, restrained symbols, and technical density:\n\n> libbpf 是一个 C/C++ 的 eBPF 用户态加载和控制库，随着内核一起分发，几乎已经成为 eBPF 用户态事实上的 API 标准，libbpf 也支持 CO-RE(Compile Once – Run Everywhere) 的解决方案，即预编译的 bpf 代码可以在不同内核版本上正常工作，而无需为每个特定内核重新编译。\n\n## Teach from complete source\n\n- Introduce one component, show its complete kernel/BPF source in an ordinary Markdown fence, then explain the important logic before moving to the next component.\n- Show core headers completely. Include a complete user-space file when it remains readable; otherwise use focused excerpts that preserve the public control flow without making the tutorial a source dump.\n- Keep every complete source block byte-exact. Preserve comments and commands in excerpts, and link once to the lesson directory for omitted user-space details.\n- Use neither `<details>` nor HTML synchronization markers.\n- Link to the complete lesson once through its GitHub directory. Avoid an opening catalog of individual files.\n- Every Markdown link uses an absolute `https://github.com/...` target. Omit a link when no stable GitHub target exists.\n- Public prose contains no local path, shared test repository, VM name, copy route, cache, prompt, model, agent, or trace detail.\n\n## Finish the lesson\n\n- Show copyable build and run commands, representative real output, and what that output proves.\n- State kernel, configuration, privilege, architecture, and hardware requirements that affect the example (use a table).\n- End with a compact scope boundary, summary, repository invitation, and primary references.\n- Keep the English and Chinese files aligned on structure, facts, source, commands, output, limits, and references while allowing each language to sound natural.\n\nThe final read should answer: what problem is solved, how one event moves through the system, which eBPF mechanism makes it possible, which code matters, how to run it, what success looks like, and where the example stops.\n\n<!-- File: .agents/skills/find-bpf-tutorial-topic/agents/openai.yaml (Tokens: ~58 | Category: anthropic-skill) -->\ninterface:\n  display_name: \"Find BPF Tutorial Topic\"\n  short_description: \"Rank practical, high-value eBPF tutorial topics\"\n  default_prompt: \"Use $find-bpf-tutorial-topic to audit coverage, practical usability, and recommend the next eBPF tutorial.\"\n\n<!-- File: .agents/skills/find-bpf-tutorial-topic/SKILL.md (Tokens: ~1798 | Category: anthropic-skill) -->\n---\nname: find-bpf-tutorial-topic\ndescription: Audit bpf-developer-tutorial coverage, research current Linux BPF work and real open-source eBPF projects, maintain the repository tutorial candidate registry, and rank the next lesson by reader value, operational usefulness, eBPF leverage, reproducibility, distinctness, teaching clarity, ecosystem evidence, maturity, and maintenance cost. Use when deciding what eBPF tutorial to write next, checking whether an idea is already covered or practically usable, comparing feature-driven and scenario-driven topics, refreshing the topic roadmap, or asking which candidate has the highest value.\n---\n\n# Find the Next BPF Tutorial Topic\n\nChoose one lesson-sized problem with lasting teaching value. Treat kernel changes as capability evidence and open-source projects as evidence that the problem matters.\n\n## Resolve the repository\n\nWork from a complete Git checkout and derive absolute paths:\n\n```bash\nREPO_ROOT=\"$(git rev-parse --show-toplevel)\"\nCANDIDATES=\"$REPO_ROOT/TUTORIAL_IDEAS.md\"\n```\n\nRead `CANDIDATES` before researching. Preserve its history: keep existing candidates and change their status to `covered`, `superseded`, `deferred`, or `rejected` with a reason instead of deleting them.\n\n## Audit existing coverage\n\nInspect the current worktree, open tutorial branches or PRs when available, and every first-level directory under `src`. Include numbered lessons, unnumbered lessons such as `cgroup`, and grouped material such as `features` and `xpu`; exclude vendored source such as `third_party` from the coverage decision. Read enough implementation and prose to distinguish a shared helper from a genuinely covered mechanism.\n\nUse `rg` to search candidate hook names, helpers, program types, protocols, and scenarios across README and source files. Record the closest existing lesson for every candidate. A new scenario can reuse an existing primitive when it teaches a different diagnostic or control pattern; a renamed example of the same flow is duplicate coverage.\n\nPay special attention to unmerged lessons in the current worktree so the roadmap does not recommend work already under review.\n\n## Research capabilities and real use cases\n\nUse current primary sources. Search more broadly than Linux:\n\n1. Linux BPF merge commits, documentation, selftests, libbpf, and bpftool releases establish semantics, version requirements, and reference behavior.\n2. Active observability and profiling projects reveal recurring operational questions. Include OpenTelemetry OBI and profiler, Parca, Pyroscope, Coroot, Odigos, and comparable projects.\n3. Networking projects reveal reusable datapath patterns. Include Cilium, Hubble, Kmesh, Katran, sched_ext, and comparable projects.\n4. Security projects reveal concrete detection and enforcement scenarios. Include Tetragon, Falco, Tracee, and comparable projects.\n5. Packaging and lifecycle projects reveal deployment gaps. Include Inspektor Gadget and bpfman.\n6. AI, accelerator, storage, and runtime projects reveal newer workloads. Include agtap, eCapture, io_uring tools, OpenTelemetry profiler GPU work, GPU/NCCL projects, and comparable projects.\n\nPrefer official repositories, release notes, documentation, selftests, and papers from the project authors. Use popularity only as supporting context. Recent releases, repeated implementations across independent projects, and concrete tests are stronger evidence.\n\nConvert each project feature into a small independent lesson. Teach the mechanism and the question it answers rather than writing an installation guide for the source project.\n\n## Define the runnable lesson before scoring\n\nFor every serious candidate, write seven short fields:\n\n- the concrete question a reader can reproduce;\n- the event, packet, request, task, or workload followed end to end;\n- the BPF hook, map, helper, kfunc, or program type that makes the answer possible;\n- the exact command a reader would realistically run and the decision or action its output enables;\n- the natural lifecycle: single-pass action, bounded diagnostic, or persistent monitor, including how it stops and cleans up;\n- the deterministic fixture and observable success output;\n- the closest existing lesson and the new knowledge this candidate adds.\n\nDefer an idea when these fields remain vague. A helper name alone is not a tutorial topic.\n\n## Apply the practicality gate before scoring\n\nWalk through the proposed public workflow as an operator, separately from the deterministic test harness:\n\n- A naturally one-shot operation, such as an iterator scan or atomic state change, may run once and exit. An observability or enforcement monitor must attach before independent workloads, remain useful for its natural lifetime, and stop cleanly by signal, duration, or an explicit completion condition.\n- The fixture may be artificial, but the public command must not exist only to launch `/bin/true` or another toy trigger. A launch-scoped command is acceptable only when launch scoping is itself the lesson's real use case.\n- Require an explicit readiness signal before an independent workload starts; fixed sleeps do not prove that attachment or setup finished.\n- Define target scope and filters, concurrent-event or admission behavior, failure and drop visibility, cleanup after normal exit and signals, and what a reader does with the result.\n- For asynchronous work, define shutdown as: stop admission, wait for completed work rather than merely started callbacks, drain output, report stable health, then destroy resources.\n- Reject a design whose output merely proves that a helper ran. The output must answer the stated operational question or drive the stated action.\n\nRedesign or defer a candidate when the fixture is its only plausible user, when the lifecycle contradicts the scenario, or when safe cleanup and bounded resource behavior cannot be explained and tested.\n\n## Score value\n\nScore from evidence, then subtract costs. Keep the breakdown in working notes and place the final score in `TUTORIAL_IDEAS.md`.\n\n| Dimension | Maximum | Question |\n|---|---:|---|\n| Reader problem | 20 | Does it answer a recurring, consequential question? |\n| Operational usefulness | 15 | Is the public command and lifecycle useful outside the test fixture? |\n| eBPF leverage | 15 | Does eBPF provide visibility or control that ordinary tools cannot provide as cleanly? |\n| Coverage gap | 15 | Does it add a distinct mechanism or scenario to this repository? |\n| Reproducibility | 10 | Can one bounded local or KVM fixture prove the result? |\n| Teaching clarity | 10 | Can the lesson follow one understandable path and show decisive output? |\n| Ecosystem evidence | 10 | Do maintained projects or upstream tests validate the use case? |\n| Maturity | 5 | Are the required kernel and userspace interfaces stable enough to maintain? |\n\nSubtract up to 20 points for unstable private interfaces, broad multi-service scope, unusual hardware, cloud or Kubernetes requirements, fragile protocol parsing, and high version-specific maintenance.\n\nNewness breaks close ties; it does not replace reader value. Favor a stable lesson that solves a real problem over a new helper without a compelling use case.\n\n## Apply the admission gates\n\nA candidate can become `ready` only when:\n\n- it has a concrete reproducible problem and expected output;\n- its documented invocation and lifecycle match how a reader would use the tool outside the fixture;\n- its target scope, concurrency or admission bound, failure visibility, and cleanup path are explicit;\n- eBPF is central to the solution;\n- the repository does not already teach the same flow;\n- the example can fit one coherent tutorial;\n- primary sources establish the technical claims;\n- required kernel, architecture, privilege, and hardware conditions are known;\n- the likely maintenance burden is proportionate to its value.\n\nClassify a small addition to an existing lesson as `maintenance` rather than creating a new numbered tutorial. Classify an immature upstream feature as `watch` until it reaches a suitable stable kernel or userspace release.\n\n## Maintain the candidate registry\n\nUpdate `CANDIDATES` with:\n\n- the audit date;\n- candidate status and score;\n- the smallest useful lesson scope;\n- the closest existing coverage;\n- primary project or upstream sources;\n- the reason for any status change.\n\nAdd newly found candidates. Retain covered and rejected entries as an append-only decision record. Update scores when repository coverage, upstream maturity, available test infrastructure, or ecosystem evidence changes.\n\n## Recommend one next lesson\n\nReturn the top three and select one winner. Explain the winner through its problem, reusable mechanism, deterministic demonstration, repository gap, and maintenance cost. State why the most fashionable alternative ranked lower when that tradeoff is material.\n\nSeparate these conclusions when useful:\n\n- highest overall tutorial value;\n- strongest new-kernel-feature lesson;\n- most timely or attention-grabbing scenario;\n- best topic that can run in the current KVM environment.\n\nDo not implement the winner unless the user also asks to write it.\n\n<!-- File: .agents/skills/test-bpf-tutorial-kvm/agents/openai.yaml (Tokens: ~68 | Category: anthropic-skill) -->\ninterface:\n  display_name: \"Test BPF Tutorials in KVM\"\n  short_description: \"Build locally and test with the benchmark KVM kernel\"\n  default_prompt: \"Use $test-bpf-tutorial-kvm to build this BPF tutorial locally and run its smoke test with the bpf-benchmark KVM kernel.\"\n\n<!-- File: .agents/skills/test-bpf-tutorial-kvm/references/tutorial-patterns.md (Tokens: ~942 | Category: anthropic-skill) -->\n# BPF tutorial KVM test patterns\n\nResolve the wrapper from the tutorial worktree:\n\n```bash\nTUTORIAL_ROOT=\"$(git rev-parse --show-toplevel)\"\nRUNNER=\"$TUTORIAL_ROOT/.agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh\"\n```\n\nAll paths below are host paths exposed at the same location in the virtme-ng guest.\n\n## One-shot loader or self-test\n\n```bash\n\"$RUNNER\" --cwd \"$LESSON\" -- ./loader --self-test\n```\n\nPrefer a self-test that loads the BPF object, exercises a deterministic input, checks the map or return value, and detaches before exiting.\n\n## Long-running tracer plus a trigger\n\nThe loader, trigger, signal, and output assertion must all occur inside the same guest:\n\n```bash\n\"$RUNNER\" --cwd \"$LESSON\" --timeout 90 -- bash -lc '\nset -euo pipefail\nout=$(mktemp)\n./tracer >\"$out\" 2>&1 &\npid=$!\ntrap '\\''kill -INT \"$pid\" 2>/dev/null || true; wait \"$pid\" 2>/dev/null || true'\\'' EXIT\nsleep 1\ntrue                         # replace with the deterministic traced event\nsleep 1\nkill -INT \"$pid\"\nwait \"$pid\" || test $? -eq 130\ntrap - EXIT\ngrep -F \"expected event\" \"$out\"\n'\n```\n\nKeep the host timeout longer than the guest-side lifecycle. Avoid an unbounded `timeout ./tracer` assertion because exit 124 proves only that it was killed.\n\n## XDP or TC\n\nFor a userspace-backed interface and outbound guest traffic:\n\n```bash\n\"$RUNNER\" --cwd \"$LESSON\" --network user -- bash -lc '\nset -euo pipefail\nip -brief link\n./loader --interface eth0 &\npid=$!\ntrap '\\''kill -INT \"$pid\" 2>/dev/null || true; wait \"$pid\" 2>/dev/null || true'\\'' EXIT\nping -c 1 -W 2 10.0.2.2\n# Assert counters or emitted events here.\n'\n```\n\nUse `--network loop` for guest-local network testing. Prefer `BPF_PROG_TEST_RUN` when the lesson is about program behavior rather than attachment mechanics.\n\n## sched_ext, LSM, and cgroup programs\n\n- Verify the exact config symbol in the printed kernel config before booting, for example `CONFIG_SCHED_CLASS_EXT=y` or `CONFIG_BPF_LSM=y`.\n- Keep sched_ext registration bounded and assert that the scheduler exits or unregisters cleanly.\n- Create test cgroups only inside the guest's cgroup2 mount.\n- Test LSM enforcement on guest-local temporary files or processes, never on host resources mounted read-write.\n\n## Returning generated output\n\nThe tutorial directory is read-only by default. Create a dedicated output directory and expose only it when a test must retain logs or generated files:\n\n```bash\nmkdir -p \"$LESSON/test-output\"\n\"$RUNNER\" --cwd \"$LESSON\" --rwdir \"$LESSON/test-output\" -- \\\n    ./loader --output \"$LESSON/test-output/smoke.json\"\n```\n\nGuest root can modify any `--rwdir` path. Never expose a repository root, `.git`, credentials, task histories, or agent traces just for convenience.\n\n## Interpreting failures\n\n- **Preflight fails:** repair KVM/tool/artifact availability; do not fall back to the host kernel.\n- **Guest kernel mismatch:** the image and build metadata are inconsistent; rebuild or repair the benchmark artifact separately.\n- **`bpftool` asks for `linux-tools-<guest-version>`:** the Ubuntu `/usr/sbin/bpftool` wrapper was selected. On this machine, use the real binary at `/usr/local/sbin/bpftool` after confirming it with `--version`.\n- **Unknown helper, attach type, or kfunc:** compare lesson requirements with the built kernel release/config/BTF. Report a kernel gap rather than changing the host test boundary.\n- **Permission error inside guest:** confirm the command is running as guest root and that bpffs/debugfs/tracefs/cgroup2 mounted. Do not add host `sudo`.\n- **Read-only filesystem:** write under `/tmp`, or explicitly expose a narrow output directory with `--rwdir`.\n- **Timeout 124:** inspect loader cleanup and the trigger. A timeout is not a passing tracer test.\n- **Verifier rejection:** preserve the complete verifier log and distinguish an intentional negative test from a compatibility regression.\n\n<!-- File: .agents/skills/test-bpf-tutorial-kvm/SKILL.md (Tokens: ~1491 | Category: anthropic-skill) -->\n---\nname: test-bpf-tutorial-kvm\ndescription: Build and smoke-test bpf-developer-tutorial lessons without loading BPF programs into the host kernel. Use when creating, changing, reviewing, or debugging an eBPF tutorial and the runtime test should reuse the already-built x86 kernel under bpf-benchmark through virtme-ng/KVM. Also use for checking whether a tutorial needs a newer kernel feature. Do not use this workflow for performance benchmarking or for rebuilding the benchmark kernel.\n---\n\n# Test BPF Tutorials in KVM\n\nCompile tutorial code on the host, but run every command that loads, attaches, or exercises BPF inside a short-lived KVM guest using the kernel artifact already built by `bpf-benchmark`.\n\n## Safety boundary\n\n- Never load or attach a tutorial BPF program on the host. This includes `bpftool prog load`, loaders, `make run`, XDP/TC attachment, sched_ext registration, and LSM/cgroup attachment.\n- Do not rebuild or modify `bpf-benchmark`, its kernel tree, its Git state, caches, results, or conversation/agent-history data.\n- Do not silently fall back to the host kernel or to TCG. Stop if `/dev/kvm`, `vng`, or the expected benchmark kernel is unavailable.\n- Treat the tutorial directory as read-only in the guest by default. Use `--rwdir` only for a path that must return guest-generated files to the host.\n- Use bounded commands. The wrapper applies a host-side timeout; add a shorter guest-side `timeout` to long-running loaders when useful.\n- Report a KVM run as a functional smoke test, not as benchmark-quality evidence.\n- Keep this infrastructure private in public prose. A tutorial or PR description may state the architecture, kernel version and commit, configuration, commands, and captured output, but must not name `bpf-benchmark`, local paths, VM instances, mount routes, caches, or agent-state locations.\n\n## Default locations\n\nResolve the tutorial checkout and skill from the current Git worktree:\n\n```bash\nTUTORIAL_ROOT=\"$(git rev-parse --show-toplevel)\"\nRUNNER=\"$TUTORIAL_ROOT/.agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh\"\n```\n\nThe helper reads `BPF_BENCHMARK_ROOT`, defaulting to a `bpf-benchmark` checkout next to the tutorial repository. Its `--cwd` defaults to the caller's current directory.\n\nThe reused kernel is:\n\n```text\n$BPF_BENCHMARK_ROOT/vendor/build/x86/linux/arch/x86/boot/bzImage\n```\n\n## Workflow\n\n### 1. Validate the repositories and instructions\n\nRead every applicable `AGENTS.md` or equivalent repository instruction before acting.\n\nRequire a real tutorial checkout before implementation or testing. A valid checkout has lesson sources and a working Git worktree, not only a `.git` fragment. If it is incomplete, stop and explain that the checkout must be restored; do not clone over it or delete the remnant without explicit authorization.\n\nThe top-level `bpf-benchmark` Git repository does not need to be healthy for artifact reuse. The wrapper validates the kernel image, build config, kernel source worktree, KVM device, and toolchain independently.\n\nRun the preflight:\n\n```bash\n\"$RUNNER\" --check\n```\n\n### 2. Inspect before building\n\nRead the lesson README, Makefile, source, and existing test commands. Identify separately:\n\n1. a compile-only host command;\n2. the userspace loader or runtime command;\n3. the event or workload that proves the program works;\n4. any required network, cgroup, tracefs, debugfs, or kernel-config feature.\n\nUse `make -n` or inspect recipes before choosing a target. A target that invokes a loader is a guest command, even if it also compiles.\n\n### 3. Build on the host\n\nRun only compile and static-generation steps on the host. Prefer the lesson's documented build target. Preserve generated `.bpf.o`, skeletons, and userspace binaries in the lesson directory so the guest sees the exact host-built artifacts.\n\nDo not use `sudo` for the build. Do not run a post-build loader on the host.\n\n### 4. Run inside the benchmark-kernel guest\n\nPass the runtime command after `--`. Arguments are preserved without host re-evaluation.\n\n```bash\nTUTORIAL_ROOT=\"$(git rev-parse --show-toplevel)\"\nRUNNER=\"$TUTORIAL_ROOT/.agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh\"\nLESSON=\"$TUTORIAL_ROOT/src/<lesson>\"\n\n\"$RUNNER\" --cwd \"$LESSON\" -- ./loader --help\n```\n\nThe wrapper boots the built benchmark `bzImage` with KVM, verifies the guest release, runs as guest root, mounts bpffs/debugfs/tracefs/cgroup2, prints provenance, and powers off when the command exits. It defaults to 2 vCPUs, 4G RAM, no network, and 120 seconds.\n\nUse `--network user` only when the test needs an external/userspace-backed interface. Use `--network loop` for a guest-local loop network. Prefer `BPF_PROG_TEST_RUN` or deterministic guest-local traffic when either is sufficient.\n\nRead [the tutorial test patterns](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/.agents/skills/test-bpf-tutorial-kvm/references/tutorial-patterns.md) for tracer, network, writable-output, and failure-diagnosis patterns.\n\n### 5. Verify the behavior, not only the exit code\n\nCapture enough evidence to connect an input event to the expected BPF output: attach confirmation, a deterministic trigger in the same guest, expected map/event output, and clean detach or process exit. Negative tests should verify the expected verifier or attach failure.\n\nFor a new lesson, test at least:\n\n- host compile from a clean lesson build state when safe;\n- KVM preflight;\n- one successful guest runtime path;\n- one relevant error or cleanup path;\n- documentation commands exactly as written.\n\nDo not clean unrelated files or repository-wide caches to create a clean build state.\n\n### 6. Report provenance and limitations\n\nInclude the guest `uname -r`, benchmark kernel source commit, kernel image SHA-256, lesson commit or dirty state, host build command, guest command, and the observed result. The wrapper prints kernel provenance automatically.\n\nIf the tutorial requires a feature absent from the built config or kernel, report the missing symbol/helper/attach type and stop. Propose a benchmark-kernel rebuild or upgrade separately; do not perform it as a fallback.\n\n## Wrapper interface\n\n```text\nrun-in-kvm.sh --check\nrun-in-kvm.sh [--cwd PATH] [--cpus N] [--memory SIZE]\n              [--timeout SECONDS] [--network none|user|loop]\n              [--rwdir PATH]... [--append KERNEL_ARGS]...\n              [--dry-run] [--verbose] -- COMMAND [ARG...]\n```\n\nUse `--dry-run` to inspect the generated `vng`/QEMU launch without booting. `--rwdir` is an explicit trust decision because guest root can change that host path.\n\n<!-- File: .agents/skills/write-bpf-production-tutorial/agents/openai.yaml (Tokens: ~55 | Category: anthropic-skill) -->\ninterface:\n  display_name: \"BPF Tutorial Writer\"\n  short_description: \"Design and test practical bilingual eBPF lessons\"\n  default_prompt: \"Use $write-bpf-production-tutorial to turn this eBPF example into a practical, tested bilingual tutorial.\"\n\n<!-- File: .agents/skills/write-bpf-production-tutorial/SKILL.md (Tokens: ~1616 | Category: anthropic-skill) -->\n---\nname: write-bpf-production-tutorial\ndescription: Design, write, or rewrite one practical bilingual bpf-developer-tutorial lesson with pinned Claude Opus 4.5, then verify the public workflow and prose against the implementation. Use when creating README.md and README.zh.md, checking whether a tutorial tool has a realistic CLI and lifecycle, preserving complete kernel source, testing the example, or preparing tutorial changes for review.\n---\n\n# Write a BPF Tutorial\n\nUse `$bpf-tutorial-writing-style` for the finished prose. Keep this workflow small: prepare reliable source material, let one pinned writer complete both languages, then check what it actually wrote.\n\n## 1. Prepare the lesson\n\nRead these inputs before writing:\n\n- `scripts/guideline_advance.md` for tutorials 40+, `scripts/guideline_basic.md` for tutorials 0-39;\n- both README files from `src/47-cuda-events`, `src/48-energy`, and `src/49-hid` as style references;\n- the lesson's implementation, headers, Makefile, fixtures, and tests;\n- the current README pair when revising an existing lesson;\n- primary upstream sources for versions and feature semantics.\n\nCollect the facts the reader needs: the problem, why traditional approaches fail, the kernel/user-space flow, feature versions, requirements, intended public commands, real output, concurrency or admission behavior, cleanup, limits, and references. Keep every claim grounded in the code, tests, captured output, or a primary source. Preserve an existing draft before a from-scratch rewrite.\n\nBuild and run the example when the environment supports it. Use `$test-bpf-tutorial-kvm` for kernel features that need the repository's KVM environment. Runtime details support the tutorial; local workspace paths, VM names, shared repositories, caches, prompts, and agent traces stay private.\n\n## 2. Pass the practical-design gate\n\nValidate the tool as an operator before writing prose. Keep its public workflow separate from the deterministic fixture:\n\n- State the operational question, the exact command a reader would run, the independent workload or target, the useful output, and how the tool stops.\n- Classify the lifecycle. A scan or atomic control action may be one-shot; a tracer or monitor must attach before the workload and remain active until a signal, duration, or real completion condition.\n- Do not turn a blocked toy child or `/bin/true` fixture into the public CLI merely because it removes a test race. Launch-scoped tracing is valid only when it is the intended real workflow.\n- Emit and test an explicit readiness signal before starting an independent workload. Do not use a fixed sleep as proof that setup or attachment completed.\n- Check target scope and filters, concurrent state, admission bounds, drop and failure counters, exit status, normal cleanup, signal cleanup, and destructive-action safety in proportion to the lesson.\n- For asynchronous work, stop admission first, wait for completed work rather than merely entered callbacks, drain output, report stable health, and only then destroy resources.\n- Execute the documented command as written. The test must prove the real lifecycle plus one relevant failure or cleanup path, not only that the BPF program loaded.\n- Describe the current public workflow directly. Do not narrate removed flags, old child-command modes, or other migration history unless backward compatibility is itself the lesson.\n- Keep repository tests out of the reader-facing tutorial path. Use them as private validation evidence, but teach the normal command, independent workload, useful tool output, and shutdown sequence.\n- Show only output emitted by the documented tool in public examples. Never include harness lines such as `TEST-*` or `PASS`, fixture setup, test assertions, or local test-infrastructure provenance.\n\nIf the implementation only demonstrates a helper but is awkward or misleading as a tool, revise the implementation and test before asking the writer to explain it. Do not let polished prose overclaim an impractical design.\n\n## 3. Structure requirements\n\nFor advanced tutorials (40+), follow this exact section order as defined in `$bpf-tutorial-writing-style`:\n\n1. **Title + Introduction**: Concrete problem scenario, link to source\n2. **Background / Why This Approach**: Explain traditional approaches and their limitations, then what eBPF enables\n3. **High-Level Mechanism**: How the feature works before showing code\n4. **Code Implementation**: Complete kernel/BPF source and core headers, plus a complete user-space loader when concise or focused user-space excerpts when long, then paragraph explanations\n5. **Additional Concepts** (if needed)\n6. **Compilation and Execution**: AFTER code analysis, not before\n7. **Summary + Call to Action**\n8. **References**\n\nThe \"Background / Why\" section is critical. It must explain:\n- What traditional approaches exist\n- Why each doesn't work well\n- What the eBPF approach enables\n\n## 4. Let Opus write\n\nClaude Opus writes all reader-facing tutorial prose. Use the exact model ID `claude-opus-4-5-20251101`. Stop if that model is unavailable instead of substituting another model.\n\nUse one non-interactive invocation for the complete English and Chinese pair. The prompt stays short and names only:\n\n- the two target README files;\n- `scripts/guideline_advance.md` or `scripts/guideline_basic.md`;\n- `$bpf-tutorial-writing-style`;\n- `src/47-cuda-events`, `src/48-energy`, and `src/49-hid` as style references;\n- the request to read the implementation and write both files completely before returning.\n\nDo not paste a second checklist, paragraph plan, fact inventory, or review rubric into the prompt. Add a technical fact only when it is unavailable in the repository.\n\nRun Claude from the repository root with the pinned model and permission to read the repository and write the two README files. Opus does not commit or push.\n\n## 5. Check the result\n\nInspect both files and the diff instead of trusting the model's final message. Confirm that:\n\n- both languages are complete and tell the same technical story;\n- the documented command, target, lifecycle, signals, concurrency bounds, cleanup, and health output match the practical design gate;\n- the opening reads like a tutorial rather than an abstract or feature list;\n- there is a \"Why\" section explaining traditional approaches and their limitations;\n- the high-level mechanism is explained BEFORE code sections;\n- compilation/execution is AFTER code analysis;\n- every kernel/BPF source and core header appears once in a complete ordinary Markdown fence; a concise user-space loader should also be complete, while a long loader may use focused excerpts that cover the normal public control flow;\n- code, commands, output, versions, requirements, cleanup, and limits agree with the repository;\n- sample output comes from the normal public workflow and contains no test-harness or migration/deprecation narration;\n- the opening source link points only to the lesson directory;\n- every published link is an absolute `https://github.com/...` URL;\n- no local infrastructure, prompt, model, agent, or trace detail appears in public text.\n\nCheck the required complete-source inventory with the bundled `sync-source-blocks.py`: always include kernel/BPF sources and core headers, and include user-space files only when the README presents them as complete. Then run `git diff --check`, the lesson build, its tests, the exact documented public command, and the relevant runtime test. Treat a functional run as a functional run rather than a benchmark.\n\nRead the finished pair once as an intermediate eBPF developer. If a concrete problem remains, give Opus a short defect list in the same session and let it revise the whole pair before returning. Keep prompts, responses, partial drafts, and failed runs; never delete real conversation or agent history.\n\nStop after the reviewed local result unless the user asks to commit, push, or update a PR.\n\n<!-- File: CLAUDE.md (Tokens: ~543 | Category: claude-rule) -->\n# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nThis is the eBPF Developer Tutorial repository - a comprehensive learning resource for eBPF development. It provides 48+ practical examples progressing from beginner to advanced topics using modern eBPF frameworks like libbpf, Cilium eBPF, and libbpf-rs.\n\n## Common Development Tasks\n\n### Building eBPF Examples\n\nMost examples use libbpf and follow this pattern:\n```bash\ncd src/<example-number>-<example-name>\nmake\n```\n\nFor Rust examples (in src/37-uprobe-rust/):\n```bash\ncd src/37-uprobe-rust/<example>\ncargo build\n```\n\n### Running Examples\n\nMost examples require root privileges:\n```bash\nsudo ./<binary-name>\n# or with timeout for continuous monitoring tools:\nsudo timeout -s 2 3 ./<binary-name>\n```\n\n### Clean Build Artifacts\n```bash\nmake clean\n```\n\n## Architecture\n\n### Build System\n- **Framework**: GNU Make with libbpf\n- **BPF Compilation**: Clang/LLVM compiles `.bpf.c` → `.bpf.o`\n- **Skeleton Generation**: bpftool generates `.skel.h` from BPF objects\n- **User Space**: GCC compiles C programs linking with libbpf\n- **Dependencies**: All in `src/third_party/` (libbpf, bpftool, blazesym, vmlinux headers)\n\n### Directory Structure\n- `src/0-10`: Basic eBPF concepts (kprobes, uprobes, tracepoints)\n- `src/11-18`: Advanced libbpf development\n- `src/19-21,29,41-42`: Networking (LSM, TC, XDP, sockops)\n- `src/22-28,34`: Security topics\n- `src/31,37`: Language integration (Go, Rust)\n- `src/44-45`: BPF schedulers\n- `src/47`: GPU tracing\n- Each tutorial has its own Makefile and README\n\n### Key Components\n1. **vmlinux headers**: Pre-generated for x86, arm, arm64, riscv, powerpc, loongarch\n2. **CO-RE (Compile Once, Run Everywhere)**: Uses BTF for kernel compatibility\n3. **Multiple frameworks**: libbpf (primary), eunomia-bpf, Cilium eBPF, libbpf-rs\n</yakaai_skills>"}