Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 23 additions & 64 deletions .agents/skills/bpf-tutorial-writing-style/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,102 +5,61 @@ description: Style checklist for English and Chinese bpf-developer-tutorial READ

# BPF Tutorial Writing Style

This checklist is reference material, not a mandatory second pass after `$write-bpf-production-tutorial`. When Claude is the delegated writer, do not use this skill to review or rewrite Claude's result, do not send it to Claude as an additional checklist, and do not ask Claude for another revision. Codex must make local word-choice and punctuation edits after the delegated writing pass while preserving sentence meaning and paragraph structure.

Read the complete guidelines first:
- [Advanced tutorial guideline](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/scripts/guideline_advance.md) for tutorials 40+
- [Basic tutorial guideline](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/scripts/guideline_basic.md) for tutorials 0-39

Then 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.

## Document Structure (strictly follow guideline)

For advanced tutorials (40+), follow this exact section order:

1. **Title**: `# eBPF 教程:[Topic Description]` or `# eBPF Tutorial by Example: [Topic Description]`

2. **Introduction**: Brief intro with a concrete problem scenario. Highlight significance and what readers will learn. Link to complete source once here.

3. **Background / Why This Approach**:
- Explain WHY this approach is needed
- List traditional/alternative approaches and their limitations (e.g., killing process, firewall rules, user-space tools)
- Explain what eBPF/the new kernel feature enables that traditional approaches cannot
- State when the feature entered Linux (kernel version + commit if relevant)

4. **High-Level Mechanism**:
- Explain HOW the eBPF feature/tool works at a high level BEFORE showing code
- Describe the overall flow: what happens in kernel, what happens in user space, how they interact
- Use diagrams for complex flows with branches, waits, ownership transfers, or 3+ dependent states

5. **Code Implementation**:
- First introduce the overall processing logic
- Show complete kernel/BPF source and the core headers needed to understand it
- 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
- After each code block, explain the key parts with paragraph style (not bullet lists)
- Focus on logic and advanced features, not basic syntax
## Let the topic choose the structure

6. **Additional Concepts** (if needed): Deeper explanation of specific features, edge cases, or semantics
Follow `scripts/guideline_advance.md` without turning its suggestions into ten mandatory headings. Use a direct title, a short opening, the background the example actually needs, a high-level flow, complete source with explanation, compilation and execution, a compact ending, and primary references. Choose section names that sound natural for the topic.

7. **Compilation and Execution** (AFTER code, not before):
- Build commands
- Run commands with examples
- Expected output with explanation
- Environment requirements table (kernel version, config, privileges, architecture)

8. **Summary**: Key points, scope boundaries, future extensions

9. **Call to Action**: Repository and website invitation (as blockquote)

10. **References**: Links to kernel commits, upstream selftests, documentation
Introduce information at the point where the reader needs it. Compilation follows the code discussion. Extra concept sections, alternative approaches, requirements tables, and diagrams are useful when they clarify a real decision or a flow with several dependent states.

## Tell one useful story

- Open with a concrete situation that the example can reproduce and the question it answers.
- Near the first mention of eBPF, use one natural sentence to say what eBPF is and why it fits this problem.
- Position the lesson at the narrowest useful capability that the executable really provides. Keep the title, opening, CLI, normal execution path, output, and test focused on that same capability. For example, a tool that learns one domain's A record and checks one TCP port is a minimal DNS-derived IP allowlist rather than a general DNS-aware firewall.
- Open with the concrete question the tool answers. A short factual setup is often enough; avoid invented stories.
- Near the first mention of eBPF, use one natural sentence to say that it runs verified programs at kernel hooks and can send selected state to user space.
- Introduce the relevant kernel subsystem and new feature when the running example needs them. State when the feature entered Linux and what it enabled.
- 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.
- 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.

## Explain the "Why" thoroughly

This is critical. The Background section must explain:
- What problem you're solving
- What traditional approaches exist (killing process, firewall rules, user-space tools like `ss --kill`, sampling, etc.)
- Why each traditional approach doesn't work well (race conditions, incomplete coverage, performance overhead, etc.)
- What the eBPF approach enables that wasn't possible before

Example pattern for the "Why" section:
> **杀掉进程**是最直接的想法,但一个进程往往维护着多条连接,杀进程会中断所有业务流量。
> **防火墙规则**可以阻止新连接,但对已建立的连接无能为力。
> **用户态工具**如 `ss --kill` 依赖 `/proc/net/tcp` 遍历和注入 RST 报文,但这种方式有竞态问题。
> **内核态方案**才能真正解决这个问题。BPF 迭代器可以在持有适当锁的情况下遍历内核的套接字表...
- Present the whole flow before detailed code. Add a diagram only when it makes a branch, wait, retry, ownership transfer, or multi-stage path materially easier to follow.

## Sound like a tutorial

- Use familiar words, direct verbs, and connected paragraphs. Attraction comes from the problem and mechanism rather than promotional language.
- Prefer positive descriptions of what the example does. Put remaining limits and safety boundaries in one short paragraph near the end.
- Prefer positive descriptions of what the example does. Use negative constructions sparingly. Put the most relevant scope note in one short paragraph near the end.
- Use prose for the main explanation and lists for genuinely parallel items.
- Keep each paragraph focused on one job. Connect facts through cause, sequence, or contrast instead of listing them like a specification.
- 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.
- Do not use em dashes, doubled Chinese em dashes, or en dashes as sentence punctuation in either language. Use commas, semicolons, colons, parentheses, or separate sentences instead. Codex checks every target README pair after Claude returns.
- Keep technical names, code identifiers, commands, numbers, output, versions, and references exact.
- Match operational terms to behavior. Call a tool a profiler when it collects a profile such as sampled call paths or a distribution, an index when it maintains a searchable or ordered index, and a policy tool when it actually enforces a decision.
- For a stateful policy, teach the complete trust chain: which event creates candidate state, which fields correlate later events, which checks admit state, how time or deletion retires it, and which hook makes the final decision. Give poisoning, stale-state, and bypass resistance the space required to explain the mechanism.

Use this Chinese paragraph only as a voice reference for connected rhythm, restrained symbols, and technical density:

> libbpf 是一个 C/C++ 的 eBPF 用户态加载和控制库,随着内核一起分发,几乎已经成为 eBPF 用户态事实上的 API 标准,libbpf 也支持 CO-RE(Compile Once Run Everywhere) 的解决方案,即预编译的 bpf 代码可以在不同内核版本上正常工作,而无需为每个特定内核重新编译。
> libbpf 是一个 C/C++ 的 eBPF 用户态加载和控制库,随着内核一起分发,几乎已经成为 eBPF 用户态事实上的 API 标准,libbpf 也支持 CO-RE(Compile Once, Run Everywhere) 的解决方案,即预编译的 bpf 代码可以在不同内核版本上正常工作,而无需为每个特定内核重新编译。

## Teach from complete source
## Teach from the code that matters

- 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.
- 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.
- 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.
- Introduce one component, show the code needed to understand it in an ordinary Markdown fence, then explain the important logic before moving to the next component.
- Show the core kernel-side eBPF program in full when its complete control flow is the lesson. Large or secondary kernel files may use focused excerpts when the omitted parts do not carry the mechanism being taught.
- Keep the user-space discussion compact. Show the loader, configuration, event loop, and cleanup functions only when they help explain the interaction with BPF. A complete user-space loader is optional, and omitting boilerplate is not a tutorial failure.
- Keep every included code excerpt faithful to the repository source. Link to the tutorial directory once so readers can inspect the complete implementation.
- Use neither `<details>` nor HTML synchronization markers.
- Link to the complete lesson once through its GitHub directory. Avoid an opening catalog of individual files.
- Every Markdown link uses an absolute `https://github.com/...` target. Omit a link when no stable GitHub target exists.
- Avoid an opening catalog of individual files.
- Every Markdown link uses a stable absolute `https://` target. GitHub, kernel.org, and authoritative documentation sites are all valid; relative links are prohibited.
- Public prose contains no local path, shared test repository, VM name, copy route, cache, prompt, model, agent, or trace detail.

## Finish the lesson

- Show copyable build and run commands, representative real output, and what that output proves.
- State kernel, configuration, privilege, architecture, and hardware requirements that affect the example (use a table).
- End with a compact scope boundary, summary, repository invitation, and primary references.
- End with a compact summary, repository invitation, and primary references.
- Keep the English and Chinese files aligned on structure, facts, source, commands, output, limits, and references while allowing each language to sound natural.

The 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.
The 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. It does not need to reproduce every line of user-space implementation.
3 changes: 3 additions & 0 deletions .agents/skills/find-bpf-tutorial-topic/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ For every serious candidate, write seven short fields:

Defer an idea when these fields remain vague. A helper name alone is not a tutorial topic.

Before marking a feature-driven candidate ready, verify the complete API path against the target kernel. Check the intended BPF program type, map fields, helpers or kfunc sets, sleepability, locking, and verifier restrictions together; a selftest using another program type is not evidence that the proposed hook can use the same API. Build and load the smallest representative probe in KVM when static inspection leaves doubt. If the target program type cannot use the feature, choose a scenario where it can instead of routing data through user space solely to make the API appear in the example.

## Apply the practicality gate before scoring

Walk through the proposed public workflow as an operator, separately from the deterministic test harness:
Expand Down Expand Up @@ -98,6 +100,7 @@ A candidate can become `ready` only when:
- the repository does not already teach the same flow;
- the example can fit one coherent tutorial;
- primary sources establish the technical claims;
- the intended program type can load every required map and API on the target kernel;
- required kernel, architecture, privilege, and hardware conditions are known;
- the likely maintenance burden is proportionate to its value.

Expand Down
7 changes: 5 additions & 2 deletions .agents/skills/test-bpf-tutorial-kvm/scripts/run-in-kvm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,15 @@ fi
die "/dev/kvm is not available with read/write permission; refusing a TCG fallback"

benchmark_root=$(realpath -e -- "$benchmark_root")
kernel_source=$benchmark_root/vendor/linux-framework
kernel_build=$benchmark_root/vendor/build/x86/linux
kernel_source_link=$kernel_build/source
kernel_image=$kernel_build/arch/x86/boot/bzImage
kernel_config=$kernel_build/.config
kernel_release_file=$kernel_build/include/config/kernel.release

[[ -d $kernel_source ]] || die "kernel source directory is missing: $kernel_source"
[[ -e $kernel_source_link ]] || die "kernel build source link is missing: $kernel_source_link"
kernel_source=$(realpath -e -- "$kernel_source_link")
[[ -d $kernel_source ]] || die "kernel build source directory is missing: $kernel_source"
[[ -s $kernel_image ]] || die "built benchmark kernel is missing: $kernel_image"
[[ -r $kernel_config ]] || die "kernel config is missing: $kernel_config"
[[ -r $kernel_release_file ]] || die "kernel release file is missing: $kernel_release_file"
Expand Down Expand Up @@ -191,6 +193,7 @@ printf '%s\n' \
'KVM preflight: OK' \
"benchmark_root=$benchmark_root" \
"kernel_image=$kernel_image" \
"kernel_source=$kernel_source" \
"kernel_release=$kernel_release" \
"kernel_sha256=$kernel_sha256" \
"kernel_config_sha256=$config_sha256" \
Expand Down
Loading