Add repository-local tutorial agent skills (#218)

* Add repository-local tutorial agent skills

* Enforce tutorial writer safety boundaries

* Reduce trace verifier complexity

* Add cross-model tutorial writing review

* Refresh apt metadata in libbpf CI

* Split tutorial workflow and writing style skills

* Check complete tutorial source blocks

* Harden the tutorial writing workflow

* Refactor source block validation

* Close tutorial workflow isolation gaps

* Test the isolated writer trace verifier

* Keep complete-source synchronization byte exact

* Separate tutorial and Skill review gates

* Simplify the tutorial writing workflow

* Keep tutorial source and explanations together

* Keep public tutorial references self-contained

* Restore tutorial checker executable bits

* Refine tutorial writing workflow

* Prefer positive tutorial prose

* Add diagram guidance to tutorial skills

* Standardize tutorial source links

---------

Co-authored-by: LinuxDev9002 <i@littlefisher.me>
This commit is contained in:
云微
2026-07-19 14:56:27 -07:00
committed by GitHub
parent c054586a39
commit d055a0833f
16 changed files with 1344 additions and 1 deletions

View File

@@ -0,0 +1,70 @@
---
name: bpf-tutorial-writing-style
description: Repository-local prose and bilingual checklist for drafting, rewriting, or reviewing advanced bpf-developer-tutorial README.md and README.zh.md files. Use to match the readable voice of 49-hid and the useful depth of 47-cuda-events while preserving implementation facts, complete source, commands, evidence, caveats, and references.
---
# BPF Tutorial Writing Style
Use this Skill for writing quality only. Use `$write-bpf-production-tutorial` for build, KVM, exact-source checks, and PR steps.
Read all three references before drafting or reviewing:
1. [Advanced tutorial guidelines](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/.agents/skills/bpf-tutorial-writing-style/references/advanced-tutorial-guidelines.md) contains the complete project-provided requirements and must remain intact.
2. [Repository house style](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/.agents/skills/bpf-tutorial-writing-style/references/repository-house-style.md) explains how to learn from existing tutorials without copying their defects.
3. [Prose and bilingual checklist](https://github.com/eunomia-bpf/bpf-developer-tutorial/blob/main/.agents/skills/bpf-tutorial-writing-style/references/prose-and-bilingual-checklist.md) carries the relevant eunomia.dev writing discipline into this repository.
Also read the English and Chinese versions of `47-cuda-events` and `49-hid` in full. Existing lessons are examples of rhythm, depth, and teaching order, not templates. Verified code, real output, primary sources, and the user's requirements remain authoritative.
## Write for a reader
Start with a short, truthful scene the reader can picture. Show one observable problem or useful action, then raise the technical question that the lesson will answer. Keep one example, packet, event, task, device interaction, or failure as the thread through the article, so the opening scene returns naturally when the code and output are explained.
Treat the scene as a teaching device, not a license to write fiction. Do not invent a named operator, customer, outage, deployment, benchmark, urgency, or result. If the implementation is a bounded lab tool, make the scene a bounded lab situation and let the real mechanism make it interesting.
Use oral English, familiar words, and connected sentences. Write natural Chinese independently from the same facts. Chinese punctuation should be restrained: prefer one or two connected sentences that carry one technical thought over a row of short, period-heavy statements. Prefer causal explanation over inventories. A paragraph should tell the reader what happens, why it happens, and what that enables.
Prefer positive, concrete statements throughout the tutorial. Explain what the hook, program, loader, command, or test does and which scope it covers. Rewrite `not`, `do not`, `cannot`, `will not`, `不要`, `不能`, `不会`, `并非`, and `别` whenever the same fact has an accurate positive form, and remove every double negative. Keep at most one compact boundary paragraph near the end, limited to two sentences, instead of distributing failure, limitation, and safety warnings through the article.
Keep the actor close to the action. Start important sentences with a concrete component, use active voice when ownership matters, connect short facts through cause and effect, and give `this`, `it`, `这` and `它` an unmistakable referent. Put the claim before detailed evidence, use verbs instead of abstract noun phrases, and end a sentence on the new fact the reader should remember.
Do not write like a paper, specification, PR description, release note, test log, or compliance report. Build and KVM evidence belongs in compilation and execution, where it should support a claim instead of becoming the article's main plot.
## Draw the relationship when prose starts carrying a graph
Use a small technical diagram when the running example crosses at least three dependent states, branches and later rejoins, waits and retries, transfers ownership, or connects one component to several consumers. The diagram should let the reader see a relationship that would otherwise require rereading a paragraph. Keep a simple linear filter, a single hook, or a two-step command in prose.
Build diagrams from verified code and tests. Prefer code identifiers and short labels, one clear direction, restrained color, and enough whitespace to read the figure at ordinary README width. Introduce the figure with the concrete packet, event, task, or device interaction already used in the story, then explain the decisive branch or ownership change after the image. A diagram supports the narrative; it does not replace the source walkthrough.
Keep the editable DOT, Mermaid, or SVG source beside the rendered PNG. Use descriptive alt text and a canonical absolute GitHub target for the image. A language-neutral figure can serve both README files when code identifiers carry the flow; prose-heavy labels call for matched Chinese and English assets.
## Keep the source readable
Include complete core source exactly as implemented. Teach one component at a time: introduce its role, present its source inline, and immediately explain the important logic before moving on. Do not hide source in `<details>` and do not separate a long source dump from all of its explanation.
Do not simplify code, insert ellipses, or rewrite comments. Present complete source in ordinary Markdown fenced code blocks without HTML synchronization markers, then verify it against the real file.
Place one complete-source callout near the opening and link only the lesson's GitHub directory. Let the directory serve as the entry point for source, build files, fixtures, and tests, while later component sections name individual files beside their complete code blocks.
Use canonical GitHub absolute URLs for every other Markdown link, even when the target belongs to the current lesson. Never use `./`, `../`, or another host. If no stable GitHub URL exists, leave the text unlinked. This rule overrides link patterns in older lessons and the website call to action in the advanced guidelines.
Keep local infrastructure private. Do not name workspace paths, shared lab repositories, VM instances, copy routes, caches, or agent trace locations in a tutorial or PR description. Retain only public reproducibility facts such as architecture, kernel version and commit, configuration, commands, and captured output.
## Keep scope honest
Describe what the implementation actually provides. A bounded lab command is a bounded lab command. Do not inflate it into a daemon, controller, production scheduler, security product, or operational platform.
State requirements and explain cleanup through the normal lifecycle. Collect failure conditions, limitations, and safety boundaries into one compact paragraph of at most two sentences near the end. Move low-level kernel provenance into a compact requirements or reproducibility note.
## Final reader check
Read the finished lesson in order once. The reader should be able to answer:
- What concrete problem does this lesson solve?
- How does one packet or event move through kernel and user space?
- Which eBPF mechanism makes that possible?
- Which code deserves close attention?
- How do I build, run, and recognize success?
- What does the captured output prove?
- Where does the example stop?
Revise if the reader instead encounters a code wall, repeated disclaimers, a validation transcript, dense spec-sheet paragraphs, literal Chinese translation, or a scenario larger than the tool. This reader check is a judgment pass, not a reason to add reviewers or models.

View File

@@ -0,0 +1,4 @@
interface:
display_name: "BPF Tutorial Writing Style"
short_description: "Check advanced eBPF tutorial prose and structure"
default_prompt: "Use $bpf-tutorial-writing-style to draft or review this advanced eBPF tutorial in the repository house style."

View File

@@ -0,0 +1,80 @@
# Blog Guidelines for Advanced eBPF Tutorials
This document outlines the key patterns and requirements for writing advanced eBPF tutorials. Advanced tutorials focus on complex eBPF programs, tools, or features that extend beyond basic concepts. They require a deeper understanding of eBPF and kernel interactions.
The audience for advanced tutorials includes developers, system administrators, and security professionals with intermediate to advanced eBPF knowledge. The goal is to provide in-depth explanations of advanced eBPF topics and practical examples that readers can apply in real-world scenarios.
The key point in tone: Using oral English, clear and simple words and short sentence, make it attractive and easy to read, do not make it like a paper. Not too much fancy words, try to be attracive.
You should also include all the details and information I provide to you. do not simplify or change any of them, you just need to regorganize them in a more attractive way as a tutorial blog.
## starting with a clear and descriptive title
Begin with a clear and descriptive title:
```
# eBPF Tutorial by Example: [Advanced Topic]
```
Kick off with a brief intro to the advanced eBPF topic you're covering, and the example or tool you'll discuss. Highlight its significance and how it extends beyond basic concepts. Let readers know what they'll learn and why it's important.
## Incroduction to the concept, tool and Background
(Come up with a better session title)
Provide an overview of the specific eBPF programs, tools, or features you'll discuss. Explain their purpose, use cases, and the key eBPF features or kernel events involved. Focus on aspects that are crucial for advanced understanding.
## High-Level Code Analysis
Dive into the kernel-mode eBPF code and user-space code, focusing on high-level concepts rather than basic syntax.
Always include the full code as it is first. then break down the key parts.
Try to avoid using too much list, make it more like a story.
Follow the steps:
1. First, introduce The overall processing logic in both kernel and user space.
2. Then break down the kernel-mode eBPF code, include
- How the eBPF program is structured.
- Key eBPF functionalities utilized.
- How the code interacts with kernel events.
Do not make them a list, make them some paragraphs, you can also quote some code snippets to explain the key parts of the code if needed, focus on the logic and features used in advanced eBPF development. Don't make it too long, but make sure it is informative enough and you explain everything a advanced eBPF developer wants to know.
3. Then briefly explain the user-space code
Aim to help readers grasp how the code works without getting bogged down in basic details.
## Any more detailed concepts or features explanation
If there are other information or features that are important to understand the code, you can add them here.
## 5. Compilation and Execution
Provide instructions on compiling and running the eBPF programs, noting any advanced configurations or dependencies. Include commands and what readers should expect as output. Typically, you can run `make` in the relevant directory in the tutorial repository to build the code.
Include links to complete source code and resources:
- **Repository:** <https://github.com/eunomia-bpf/bpf-developer-tutorial>
## 6. Summary and Call to Action
Wrap up by summarizing the key points. Emphasize the advanced concepts covered and encourage readers to apply this knowledge. Invite them to explore more examples and tutorials, as one paragraph:
> If you'd like to dive deeper into eBPF, check out our tutorial repository at <https://github.com/eunomia-bpf/bpf-developer-tutorial>.
## reference
You should include the important references and resources that used in the tutorial. If this is from other sources like kernel sample or tools, make sure to include them here and clearly mention them in the tutorial.
## Additional Guidelines
- **Clarity:** Use simple language and short sentences to explain complex ideas. But the information should be complete and detailed.
- **Focus on Advanced Concepts:** Assume readers have basic eBPF knowledge; skip elementary explanations.
- **Engagement:** Encourage readers to think critically and engage with the material.
- **Consistency:** Keep a consistent style and formatting throughout.
- **Code Formatting:** Ensure code snippets are well-formatted and highlight key parts. Do not change or simplify any of the code and commands, keep them as they are.
- **Proofreading:** Double-check for errors and ensure technical accuracy.
- **Accessibility:** Make the content valuable for readers with advanced expertise, avoiding unnecessary simplifications.

View File

@@ -0,0 +1,119 @@
# Prose and bilingual checklist
This checklist carries the relevant eunomia.dev writing discipline into advanced eBPF tutorials. It is self-contained and does not depend on a global or external Skill.
Use it as a reader-focused editing guide, not as a reason to add review rounds. Technical fidelity is mandatory. Numeric paragraph ranges and stylistic labels are diagnostic signals that still require judgment.
## Fidelity is the first gate
- **Must fix:** Any code, command, captured output, number, version, requirement, limitation, negative result, cleanup behavior, reference, or scope-bearing qualifier from the supplied material is missing or changed.
- Preserve technical names and project names. Do not replace them with vague pronouns across paragraphs.
- Treat numbers as claims. State what was measured, under which conditions, and what the result does or does not prove.
- Avoid absolute words such as “always,” “never,” “cannot,” and “impossible” unless the implementation or a primary source proves the boundary.
- Do not invent output, benchmark numbers, PIDs, paths, errors, production uses, or performance conclusions.
- Reorganize for teaching, but do not simplify away technical information. During a rewrite, compare the final text against the entry version from the end backwards and account for every removed paragraph.
- Preserving a fact does not require repeating it. Put each requirement, failure behavior, cleanup rule, and limitation at the one point where it helps the reader most.
## Voice and argument
- Use oral, direct English with familiar words and short connected sentences. Write as an experienced developer explaining a working tool, not as a paper, merge report, release note, or test log.
- Open with a short, truthful story or concrete scenario that the implementation can reproduce. Show an observable symptom, action, packet, event, task, device interaction, or failure, then raise the technical question instead of answering everything in the first paragraph.
- Carry the same concrete thread into the mechanism, code, and output sections. The opening should pay off when the reader sees where the event goes and how the result is produced.
- Do not fabricate a persona, customer, production incident, deployment, benchmark, urgency, or result. Avoid “In this tutorial, we will explore,” generic eBPF history, product promotion, and an abstract-style contribution list.
- Let each section answer the question raised by the previous one. A useful progression is problem, background, whole-system flow, complete code, focused walkthrough, deeper concept, compilation and execution, limits, summary, and references.
- Give each paragraph one primary job. If a paragraph establishes context, explains a mechanism, reports evidence, and states a limitation at once, split it.
- Prefer active voice and concrete actors. Name the hook, BPF program, map, callback, loader, fixture, command, or kernel rather than using “it,” “this,” “the approach,” or “the result.”
- Replace spec-sheet prose with causal explanation. If three neighboring sentences can be reordered without changing the paragraph, connect each fact to what it enables or why it matters.
- Avoid fancy or promotional words, clickbait, exclamation marks, vague superlatives, hollow calls to action, and self-praise. Attraction should come from a concrete problem and a mechanism the reader can reuse.
- Do not overuse lists. Use prose for the implementation story and lists only when parallel items become easier to scan.
- Do not let provenance become the plot. Kernel commits, guest versions, CI details, and test matrices belong in a compact reproducibility note unless the lesson is specifically about them.
- Match the scenario to the tool. A small fixture, lab command, or feature demonstration can be valuable without being described as a production service.
## Diagram decision and presentation
- Add a diagram when it makes a real relationship visible: three or more dependent state changes, a branch/retry loop, ownership transfer, or one component feeding several later actions.
- Keep a simple linear filter, single attach point, or two-step command in prose. The figure count follows teaching value rather than article length.
- Derive every node, edge, label, and branch from implementation or test evidence. A diagram carries technical claims and receives the same fidelity review as prose.
- Prefer a reviewable DOT, Mermaid, or SVG source and commit it beside the rendered PNG. Use deterministic rendering so another agent can reproduce the asset after a code change.
- Use short labels, code identifiers, one dominant reading direction, restrained color, and text that remains legible at README width.
- Introduce the packet, event, task, or device interaction before the figure. Explain the important branch, retry, or ownership change immediately after it.
- Use descriptive alt text and a canonical absolute GitHub image target. Keep both README files aligned on the same figure and conclusion; use paired assets when language-specific labels materially help readers.
- Update the diagram in the same change whenever implementation or prose changes its state sequence, ownership, branch condition, or cleanup path.
## Positive and concrete sentences
- Use a positive statement of behavior or scope. Write “The loader observes one child that it creates” instead of “The loader does not monitor every exec on the system.” Write “The example implements one aggregate FIFO” instead of opening with the scheduler policies it lacks.
- Rewrite `not`, `do not`, `does not`, `cannot`, `will not`, `不要`, `不能`, `不会`, `并非` and `别` whenever an accurate positive form exists. Remove double negatives and paragraphs built from consecutive negative sentences.
- Keep the supported scope exact while using positive wording. “The example focuses on one child” describes the implemented behavior without implying that system-wide monitoring already exists.
- Collect failure conditions, unsupported behavior, limitations, and safety boundaries near the end in one paragraph of at most two sentences. The main narrative should stay with the working path.
- Start important sentences with a concrete actor such as the hook, BPF program, map, callback, loader, fixture, kernel, or command. Keep that subject close to its verb and prefer active voice when ownership or sequencing matters.
- Connect three or more short declarative sentences through cause, contrast, or sequence. A pair of short sentences can create emphasis, while a longer note-like run should become a causal paragraph.
- Give vague referents a name. Replace an unclear `this`, `it`, `they`, `这`, `它` or `这种方式` with the component or mechanism it denotes.
- Put the claim or practical meaning before a block of numbers, counters, or output. The reader should know what the evidence demonstrates before reading the evidence.
- Prefer direct verbs over nominalizations and filler. Use “the callback reads,” “the loader attaches,” and “the test verifies” instead of “performs a read,” “conducts attachment,” or “provides verification.”
- Place known context near the sentence opening and the new result near the end. This topic-to-stress order helps adjacent sentences form one path instead of a fact catalog.
Treat this wording as a negative example:
> 这个例子故意只做聚合 FIFO,没有 class、公平调度、ECN、burst 控制。用它做实验可以,但别往物理网卡上挂,也别当生产调度器。
The paragraph defines the example through missing features and repeated warnings, so the useful mechanism disappears behind negation. Rewrite it around the implemented path and a concrete learning setting:
> 这个例子用一条聚合 FIFO 展示 skb 所有权、发送时序和 qdisc 清理,适合在 veth、TAP 或 IFB 这类受控接口上观察完整流程,更完整的调度器可以在此基础上加入 class、公平调度、ECN 和 burst 控制。
Apply the same repair in English. Replace a paragraph built from “no classes,” “not production,” and “do not attach” with the mechanism the reader can run, the controlled setting that fits it, and the natural extensions that follow.
## Paragraph and sentence checks
- English paragraphs usually work best at 40–90 words. Inspect every paragraph above 110 words. Three consecutive paragraphs above 90 words are **Must fix**.
- Chinese paragraphs usually work best at 120–260 Chinese characters. Inspect every paragraph above 320 characters. Three consecutive paragraphs above 260 characters are **Must fix**.
- The ranges are diagnostic tripwires, not quotas. Short transitions and longer indivisible mechanism explanations are allowed.
- Keep a sentence's subject near its verb. Split long modifiers, dangling introductions, and sentences that make the reader hold several clauses before reaching the action.
- Avoid weak openings such as “It is,” “There is,” and “This is” when a concrete subject is available.
- Do not stack three or more short note-like sentences. Connect cause, mechanism, and consequence.
- Avoid a pair of neighboring negative sentences when positive wording can carry the same facts. Reserve the compact final boundary paragraph for the remaining limits.
- Cut filler such as “in order to,” “utilize,” “it is important to note that,” “due to the fact that,” “in terms of,” and “with respect to.” Prefer direct verbs.
- Do not use spaced English em dashes (` — `) or Chinese em dashes (`——`) in prose.
- Do not join independent clauses with semicolons. Use two sentences or a conjunction.
- Use colons only to introduce a list, code block, or table. Rewrite claim-colon-evidence and Chinese noun-phrase-colon openings as sentences.
## Code and evidence presentation
- Present full core source exactly as it exists before excerpting it again for explanation. Use ordinary Markdown fenced code blocks with no HTML markers, then require the workflow Skill's read-only `--check` mode to pass against the complete source inventory. Never silently shorten functions, replace blocks with ellipses, translate comments, or “clean up” commands.
- Teach one component at a time. Introduce the file's role, present its complete source inline, and immediately explain the parts that matter before starting the next component.
- Never hide source in `<details>` and never place several complete files in one uninterrupted dump followed by a distant walkthrough. Long examples need stronger component boundaries and local explanations, not collapsed code.
- Explain what advanced developers need to know: program type, attach point, context restrictions, helper or kfunc semantics, map ownership, state lifetime, concurrency, verifier constraints, event/control path, error handling, and cleanup.
- Keep build and run commands copyable. Explain prerequisites before the command and interpret real output after it.
- Label volatile fields and distinguish demonstrations, functional tests, and benchmarks.
- Use one opening complete-source callout that links only to the lesson directory. Treat that directory as the entry point for implementation, build files, fixtures, and tests; name individual files as code labels next to their complete source blocks instead of listing file links in the opening.
- Use canonical GitHub absolute URLs for every Markdown link, including links to the current lesson. Reject every `./`, `../`, or non-GitHub target. If no stable GitHub URL exists, do not add a link. This repository rule overrides link examples in precedents and the advanced guideline's website call to action.
- Keep local infrastructure and agent state private. Never publish workspace paths, shared lab repository or VM names, host-to-guest copy routes, cache locations, prompt stores, or trace paths. Public reproducibility may include architecture, kernel version and commit, configuration, commands, and captured output.
## Natural Chinese
- Compose Chinese from the facts and paragraph role, not from English sentence order. The two languages may use different sentence and paragraph boundaries.
- Keep punctuation restrained. When several clauses explain one subject, mechanism, or consequence, connect them naturally with commas instead of turning each clause into a separate short sentence. Prefer one or two complete sentences per ordinary paragraph; do not create a choppy sequence of periods.
- Do not imitate “short English sentences” mechanically in Chinese. A cohesive Chinese sentence may carry the concept, mechanism, compatibility boundary, and motivation together when they belong to one thought.
- Still split a sentence when its subject drifts, the causal relation becomes unclear, or the reader must hold unrelated facts at once. Fewer periods are a voice preference, not permission for an unreadable run-on sentence.
- Translate ordinary concept nouns consistently. Keep proper nouns, product names, code, commands, file names, function names, and genuine terms of art in English.
- Do not begin a Chinese prose sentence with an English common noun. Avoid English clause splicing and glossary-style prose where every other concept stays in English.
- Use full-width Chinese punctuation. Put a half-width space between CJK text and Latin letters or digits, such as “64 个事件” and “eBPF 程序.”
- Write table headings in Chinese. Translate ordinary prose inside comments only when the code block is illustrative; when the block claims to be complete source, preserve it byte-for-byte in both languages.
- Read every Chinese paragraph aloud. Rewrite literal translations, English word order, and stiff phrases that a developer would not use in conversation.
Use this paragraph as a compact Chinese voice reference. Learn its connected rhythm, restrained symbols, technical density, and direct statement of motivation; do not copy its subject matter into unrelated lessons:
> libbpf 是一个 C/C++ 的 eBPF 用户态加载和控制库,随着内核一起分发,几乎已经成为 eBPF 用户态事实上的 API 标准,libbpf 也支持 CO-RE(Compile Once – Run Everywhere) 的解决方案,即预编译的 bpf 代码可以在不同内核版本上正常工作,而无需为每个特定内核重新编译。我们希望尽可能的保持与 libbpf 的用户态 API 以及行为一致,尽可能减少应用迁移到 Wasm (如果需要的话)的成本。
The sample is not a factual source. Do not copy `libbpf`, CO-RE, Wasm, API claims, compatibility claims, or any other technical content from it unless the lesson's fact pack independently requires that content. Leakage from the sample into an unrelated lesson is a **Must fix** failure.
## Bilingual consistency
- Keep the same macro structure, examples, complete code payload, commands, output, claims, numbers, caveats, limitations, summary, and references in both files.
- Corresponding headings should promise the same content, but they do not need literal translations.
- A near-perfect line-for-line prose translation is a review smell. Confirm that each language reads naturally even when that changes sentence or paragraph boundaries.
- When one version changes a fact, example, figure, command, code block, output, or limitation, update the other in the same pass.
## Final reader check
After reading in order, an intermediate or advanced eBPF developer should be able to explain the real problem, the kernel/user-space flow, why the advanced capability is needed, how the core code works, how to build and run it, what the captured output proves, and where the example stops. If the reader remembers only a feature name, a code wall, repeated caveats, or a validation transcript, revise the narrative.

View File

@@ -0,0 +1,48 @@
# Repository house style
New advanced lessons should feel at home beside `src/47-cuda-events/` and `src/49-hid/`. Read both English/Chinese README pairs in full. Use `47-cuda-events` as a depth reference for an end-to-end tool and `49-hid` as the stronger reference for voice, pacing, and teaching through a concrete device problem.
These lessons are precedents, not perfect templates. Do not copy their unsupported claims, stale version language, inconsistent punctuation, or unnecessary feature catalogs. Verified implementation facts and current project rules win whenever a precedent differs.
Read at most one additional completed bilingual lesson when it offers a closer subsystem pattern. For networking, good candidates include `20-tc`, `41-xdp-tcpdump`, `42-xdp-loadbalancer`, and `50-tcx`. Choose by teaching need, not by directory number.
## Build one continuous story
Open with a concrete situation the reader can picture. Name the small tool or example and the useful result, but do not preview every version, counter, failure case, and test in the opening.
Give enough background to explain why the hook or kernel subsystem matters. Then introduce the whole kernel/user-space path before individual functions. Keep returning to the same packet, event, device, or failure so adjacent sections feel causally connected.
Present complete core source exactly as required by the advanced tutorial guidelines, but organize it by component. Introduce one file, show it inline, explain its important behavior, and only then move to the next file. Never hide source in `<details>` and never make readers cross several complete files before reaching the explanation.
After the source, explain the BPF structure, attach point, state and ownership, relevant helpers or kfuncs, kernel interaction, user-space lifecycle, error handling, and cleanup. Spend words on advanced constraints and surprising behavior. Do not explain ordinary C syntax.
Compilation and execution should show copyable commands, representative real output, and what that output means. Put public kernel provenance, commit IDs, and compatibility data in a compact requirements or reproducibility paragraph. Do not name local workspaces, shared lab repositories, VM instances, copy routes, caches, agent traces, or the PR's validation history.
End with an honest boundary, a short summary, the required invitation, and primary references.
## Lessons from the 53-egress-pacer rewrite
The first `53-egress-pacer` draft was technically accurate but still failed as a tutorial. It:
- packed the scenario, kernel version, algorithm, counters, conflict behavior, and test result into the opening;
- gave the reader only a few setup paragraphs before several hundred lines of source;
- repeated the same conflict, signal, cleanup, KVM, or safety caveat in the introduction, implementation, run section, and limitations;
- read like an artifact report because validation details received more emphasis than the mechanism;
- called a fixed-duration lab demo a production or operational tool without matching CLI capabilities;
- wrote Chinese by following English sentence order.
The rewrite kept all four complete source files, commands, output, versions, failure paths, and limits. It replaced the invented production story with an honest lab scope and followed one skb through ownership and timing. Reader review then exposed a structural problem: collecting the files before their explanations made the tutorial read like a design document. The corrected method places each complete file beside its component explanation, as tutorials 47 and 49 do.
Reuse the corrected method, not exact section counts. Shrink overloaded openings, give the reader one useful mental model, and alternate complete component source with nearby explanation. Keep each technical fact, but place it once where the reader is ready for it.
## Preserve modern correctness
- Use captured output and identify fields that vary across runs.
- Source version, performance, deployment, adoption, and upstream-history claims.
- State the minimum kernel, config, privilege, architecture, and hardware requirements.
- Explain at least one meaningful failure or boundary path and relevant cleanup.
- Distinguish a functional KVM run from a benchmark.
- Avoid unsupported claims such as “production-ready,” “safe,” “negligible,” or “complete visibility.”
- Keep Markdown consistent. Use full-width Chinese punctuation and spaces between CJK text and Latin letters or digits.
English and Chinese must share the same promise, section progression, source, commands, output, facts, caveats, summary, and references. Natural expression matters more than sentence-for-sentence symmetry.