{"owner":"gojue","repo":"ecapture","hasSkills":true,"totalSkillsCount":1,"totalTokensCount":3525,"categories":["root-instruction"],"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# AGENTS.md — eCapture repository guide\n\nThis is the canonical repository guide for coding agents. Tool-specific files\nsuch as `CLAUDE.md` and `.github/copilot-instructions.md` are compatibility\nentry points, not separate sources of project truth.\n\n## How to use this guide\n\n- These instructions apply to the entire repository unless a deeper\n  `AGENTS.md` narrows them.\n- For runtime behavior, trust source code and tests. For build behavior, trust\n  `go.mod`, `Makefile`, `variables.mk`, `functions.mk`, and current workflows.\n  For maintained E2E behavior, trust `test/e2e/README.md` and its harness.\n- For architecture/runtime/output work, read `docs/agent/architecture.md` and\n  `docs/agent/output-pipeline.md`.\n- For probes, ABI, CLI config, or generated protocols, read\n  `docs/agent/probe-development.md`.\n- For build, formatting, lint, tests, E2E, or CI, read\n  `docs/agent/build-test.md`.\n- Some older prose may lag the code or build files. This guide and current\n  implementation win on factual conflicts.\n- Keep this file and the relevant detailed guide synchronized when a change\n  invalidates a command, path, invariant, or known limitation.\n\n## Product priorities\n\n- TLS capture is the project's core focus. Give the TLS, GoTLS, and GnuTLS\n  modules high priority, including support for OpenSSL, BoringSSL, Go TLS, and\n  GnuTLS. Protect their correctness, compatibility, and end-to-end behavior\n  when planning changes, reviews, and verification.\n- Bash, Zsh, MySQL, and other non-core modules have lower priority. Maintain\n  them, but prioritize core TLS functionality when work or coverage must be\n  allocated.\n- In user-facing material such as a promotional article, devote roughly 80%\n  of the attention to the core TLS modules and 20% to non-core modules. This\n  is an emphasis guideline, not a fixed quota for code or tests.\n\n### Optional machine-local context\n\nIf `AGENTS.local.md` exists at the repository root, read it before choosing an\nexecution environment or running build, test, cross-compilation, or remote-host\noperations. It may refine *where* commands run, but it must not override this\nrepository's safety, supported-platform, or verification requirements.\n\n- `AGENTS.local.md` is optional and must remain uncommitted.\n- Never require another contributor or a cloud agent to have it.\n- Never copy its machine details into commits, logs, issues, or pull requests.\n- Start from `AGENTS.local.example.md`; do not store credentials in either\n  file.\n\n## Non-negotiable platform boundary\n\neCapture may be edited anywhere, but compilation, linking, linting, tests,\neBPF generation, and execution require Linux. Android artifacts are also\nbuilt on a Linux host.\n\n- Runtime targets: Linux on `x86_64`, `aarch64`, or `loongarch64`; Android on\n  `x86_64` or `aarch64`.\n- Minimum kernels: x86_64 >= 4.18; aarch64 >= 5.5; Linux loongarch64 >= 6.6.\n- Loading probes requires root or the capabilities documented in\n  `docs/minimum-privileges.md`. Maintained E2E harnesses have stricter root\n  requirements.\n- macOS and Windows are editing, formatting, and read-only inspection\n  environments. Do not run `make`, Go builds/tests, lint, eBPF generation, or\n  E2E there.\n- Before using a remote Linux builder, verify its OS, architecture, checkout\n  path, branch, commit, worktree, submodules, and synchronization state. Never\n  assume local edits are present remotely or overwrite remote work.\n- New or changed build/test scripts must reject unsupported OS, architecture,\n  and kernel combinations before doing eBPF work.\n- If the required Linux/root environment is unavailable, report exactly what\n  was not run; never claim an unexecuted build or runtime passed.\n\n## Fast mental model\n\neCapture attaches uprobes, kprobes, and TC programs, reads perf/ring-buffer\nevents, decodes their binary ABI in Go, and routes validated events to output\nhandlers and writers.\n\n```text\nmain.go -> cli.Start() -> Cobra RunE -> runProbe()\n  -> config.Validate() -> factory.CreateProbe()\n  -> Probe.Initialize() / Start()\n  -> embedded eBPF asset + ebpfmanager\n  -> perf/ringbuf sample -> EventDecoder.Decode()\n  -> optional module-private EventPreprocessor\n  -> events.Dispatcher -> text/keylog/pcapng handler -> ByteSink\n                       -> low-latency pcapng -> decrypt SDK -> text ByteSink\n                       -> typed eCaptureQ EVENT publisher\n```\n\n`runProbe` owns signal handling and runtime reload orchestration. A concrete\nprobe owns its eBPF manager, attachments, maps/decoders, and mode-specific\nhandlers. `base.BaseProbe` owns shared logging, the default text handler,\nreaders, dispatch, reorder support, and common shutdown behavior.\n\nSee `docs/agent/architecture.md` for the CLI/probe matrix, repository map, and\npackage ownership.\n\n## Critical cross-file invariants\n\n- CLI imports trigger each probe's `register.go` `init()`. A seemingly unused\n  import may be required for factory registration.\n- Treat attachment and event plumbing as one atomic change:\n\n  ```text\n  C SEC section          <-> manager.Probe.Section\n  C BPF function         <-> EbpfFuncName\n  target symbol/offset   <-> AttachToFuncName / UAddress\n  C map identifier       <-> manager.Map.Name / decoder registration\n  C global variable      <-> manager.ConstantEditor\n  C event layout         <-> Go event struct / DecodeFromBytes\n  ```\n\n- Preserve C/Go event field order, signedness, widths, byte order, arrays, and\n  padding. Validate lengths before slicing. Perf samples may contain trailing\n  alignment padding, so do not identify variants by exact length alone.\n- `Configuration.Validate()` may run more than once and must be idempotent.\n- Concrete probes must follow BaseProbe lifecycle ordering. Track every reader;\n  custom reader loops must use `TrackReader` and `GoReaderLoop` equivalents so\n  shutdown can unblock and join them before closing handlers.\n- Dispatcher fan-out is synchronous and unordered. Multiple readers may call\n  one handler concurrently; handlers/writers must be concurrency-safe and\n  tolerate idempotent close. Perf reorder is per map/reader, not global.\n- Module-private records such as OpenSSL connection metadata are consumed\n  before output dispatch; they enrich captured output events instead of\n  becoming standalone text or typed events.\n- `--logaddr` is operational logging only. For TLS, GoTLS, and GnuTLS,\n  `--eventaddr` is the primary captured-event destination for text (hook or\n  pcapng source), keylog, and pcapng. eCaptureQ is an additive typed publisher,\n  not a ByteSink.\n- Linux production tags are `linux,netgo,ebpfassets,dynamic`; Android uses\n  `ecap_android,netgo,ebpfassets,dynamic`. Preserve CO-RE and non-CO-RE paths.\n- Never hand-edit or commit generated `bytecode/*.o`, `bytecode/*.d`,\n  `.build/`, `assets/ebpf_probe_<target>_<goarch>_bindata.go`, generated LoongArch\n  `vmlinux.h`, `bin/ecapture`, or `coverage.out`. Regenerate Protobuf and\n  stringer outputs from their sources.\n\n## Task guides and verification\n\nBefore changing a probe, event ABI, build flow, or test harness, read the\ncorresponding detailed guide listed above. At minimum:\n\n- Documentation-only changes: verify paths, commands, links, and source facts.\n- Go logic: format touched files, run targeted tests, and complete full race\n  plus production-tag lint gates when Linux is available.\n- Event decoders/ABI: add byte-level malformed, short, and padded-sample tests.\n- eBPF C or manager setup: clean-build both CO-RE and non-CO-RE variants for\n  affected architectures.\n- CLI/output/capture modes: run the relevant strict E2E case on a real\n  Linux/Android kernel.\n- OpenSSL/BoringSSL mappings: test mapping, both asset variants, and the real\n  library version.\n- CI changes: validate least privilege and trusted/untrusted workflow\n  boundaries.\n\nCanonical commands, prerequisites, build races, E2E semantics, and the full\nverification matrix live in `docs/agent/build-test.md`.\n\n## Code conventions\n\n- Module/import path: `github.com/gojue/ecapture/v2`; preserve the `/v2`\n  suffix in new imports.\n- Keep changes focused and follow the nearest working implementation. Probe\n  implementations are not perfectly uniform, so do not copy one blindly.\n- Do not add files unless necessary for the requested change. Prefer reusing\n  existing code, scripts, and tests, and keep changes as small as practical.\n  Avoid unrelated refactors and unnecessary helper layers.\n- In probe/domain lifecycle code, prefer structured constructors and codes in\n  `internal/errors`, adding context where useful. Preserve normal `%w`\n  wrapping at boundaries where that is the local pattern.\n- Use `internal/logger` inside probes/runtime code and zerolog in the CLI\n  layer. Do not add ad-hoc `fmt.Println` or standard `log` calls for runtime\n  logging.\n- Format only touched files: `gofmt`/`goimports` for Go and the repository's\n  exact clang-format style for C. `make format` is a broad C-only target.\n- Keep eBPF verifier limits, bounded loops, stack use, helper availability,\n  and old-kernel compatibility in mind.\n- Preserve the `github.com/google/gopacket` replacement in `go.mod` unless a\n  maintainer explicitly directs otherwise.\n- Root `LICENSE` is Apache-2.0. Preserve each file's existing SPDX header;\n  some imported or kernel-facing headers use other compatible licenses. Do\n  not propagate stale prose that says AGPL, and leave license changes to a\n  maintainer-directed task.\n\n## Safety, Git, and release boundaries\n\n- Captured logs, commands, SQL, keylogs, pcap/pcapng files, and test artifacts\n  may contain secrets. Never commit or paste them unredacted.\n- Preserve unrelated worktree changes. Do not stage, commit, push, open a PR,\n  publish, tag, or release unless the user explicitly requests it.\n- Name new branches with a conventional purpose prefix such as `feat/`,\n  `bugfix/`, `docs/`, `test/`, or `chore/`, followed by a concise kebab-case\n  description.\n- The default branch is `master`. If asked to commit, follow\n  `<package>: <what changed>`, keep the subject <= 70 characters, and explain\n  why in the body as documented in `CONTRIBUTING.md`. Write the entire commit\n  message in English unless the user explicitly requests a specific other\n  language.\n- Write GitHub pull request titles and bodies in English unless the user\n  explicitly requests a specific other language.\n- Keep ordinary fork-PR build/test jobs read-only and secret-free. Keep\n  scanner-specific write permissions narrowly scoped. Any trusted write-back\n  workflow must not execute untrusted fork code or its artifacts.\n- Do not weaken security checks, verifier failures, or E2E assertions merely\n  to make CI green.\n\n## Known state and traps\n\n- GnuTLS uses versioned C assets selected from the detected library patch\n  release; keep the supported version-to-asset table synchronized with\n  `kern/gnutls_*_kern.c`.\n- Runtime reload reattaches process-lifetime output dependencies and creates a\n  fresh probe context, but retains the original factory probe type; it is not\n  a cross-probe hot-swap facility.\n- Shared serializable probe fields are applied through\n  `internal/config.CommonConfig` for every Cobra command and HTTP config\n  factory. Keep process-lifetime output dependencies out of that copy path.\n- HTTP reload distinguishes omitted captured-event destination/rotation fields\n  from explicit empty/zero values. Omitted fields inherit from the active\n  generation, while runtime logger and typed eCaptureQ dependencies are\n  reattached separately.\n- Probe registration currently discards duplicate-registration errors.\n- Every probe uses the shared bytecode selector. `--btf=0` resolves kernel BTF\n  once per process, while explicit modes fail when the linked asset set cannot\n  satisfy them. Generated non-CO-RE objects use `*_kern_noncore.o`.\n- `pkg/event_processor` and `internal/output/encoders` are not in the current\n  production CLI event path.\n- `TARGET_ARCH` selects the build artifact architecture (`amd64`, `arm64`,\n  or `loong64`). `CROSS_ARCH` is a compatible alias used only when\n  `TARGET_ARCH` is unset.\n- Non-CO-RE compilation must retain Kbuild's `-fms-extensions` support for\n  tagged anonymous fields in Linux 6.19+ headers; dropping it breaks field\n  access and structure layout on Linux 7.x.\n  LoongArch CO-RE needs the same support for generated runtime BTF headers.\n  x86 non-CO-RE headers also require `CC_USING_FENTRY` when function tracing\n  is configured; do not enable native `-pg`/`-mfentry` instrumentation for BPF.\n- `make build` is not Go-only. Switching architecture, Android, or asset modes\n  still requires a clean serial validation even though libpcap, bytecode, Go\n  intermediates, and generated asset names are architecture-isolated. The\n  `assets`, `assets_core`, and `assets_noncore` targets for one architecture\n  write the same generated asset; do not request them together in one parallel\n  make invocation.\n- Linux release builds share an Ubuntu 24.04 x86_64 job. Loong64 joins the\n  same release entry point and PR architecture matrix; only amd64/arm64\n  produce Android artifacts. Loong64 is cross-built with `TARGET_ARCH=loong64`\n  and the repository's LLVM 22.1.8 wrappers. Do not substitute `loong64` for the\n  `loongarch64-linux-gnu` C target or `loongarch` Kbuild architecture.\n- Native Linux/loong64 production builds also support Debian 13+ with Clang/\n  LLVM 22.1.8, versioned LLD 22 linking and native multiarch libraries.\n  The Clang driver remains Go's external linker entry point.\n  `builder/init_env.sh` prepares dependencies and kernel inputs. Native CO-RE may use the running kernel's\n  BTF; non-CO-RE still requires prepared LoongArch kernel headers. Building\n  against packaged headers does not establish non-CO-RE compatibility with a\n  different running kernel. See `docs/loong64-support.md`.\n- The dedicated LoongArch E2E job shares `e2e.yml` push/PR/manual triggers,\n  but only trusted repository refs enter the host. It builds CO-RE at the event\n  SHA with LLVM 22.1.8 and runs OpenSSL/GoTLS directly from that checkout through\n  a fixed sudo Shell entry point. Harness output streams live to Actions.\n  Fork PRs retain hosted checks. Root-owned hooks enforce trusted refs and\n  clean job processes, caches and owned TC state; there is no separate E2E unit.\n\n## Focused references\n\n- Architecture and runtime: `docs/agent/architecture.md`\n- Probe and ABI development: `docs/agent/probe-development.md`\n- Build and verification: `docs/agent/build-test.md`\n- User-facing behavior: `README.md`, `README-zh_Hans.md`\n- Build sources: `Makefile`, `variables.mk`, `functions.mk`, `builder/init_env.sh`\n- E2E: `test/e2e/README.md`, `test/e2e/QUICK_REFERENCE.md`\n- Privileges/security: `docs/minimum-privileges.md`, `SECURITY.md`\n- Event forwarding: `docs/event-forward-api.md`, `pkg/ecaptureq/README.md`\n- Generated/config docs: `protobuf/README.md`, `protobuf/PROTOCOLS.md`, `docs/remote-config-update-api.md`\n- GitHub Copilot PR agent: `.github/agents/pr-agent.agent.md`\n"},"files":{"AGENTS.md":"# AGENTS.md — eCapture repository guide\n\nThis is the canonical repository guide for coding agents. Tool-specific files\nsuch as `CLAUDE.md` and `.github/copilot-instructions.md` are compatibility\nentry points, not separate sources of project truth.\n\n## How to use this guide\n\n- These instructions apply to the entire repository unless a deeper\n  `AGENTS.md` narrows them.\n- For runtime behavior, trust source code and tests. For build behavior, trust\n  `go.mod`, `Makefile`, `variables.mk`, `functions.mk`, and current workflows.\n  For maintained E2E behavior, trust `test/e2e/README.md` and its harness.\n- For architecture/runtime/output work, read `docs/agent/architecture.md` and\n  `docs/agent/output-pipeline.md`.\n- For probes, ABI, CLI config, or generated protocols, read\n  `docs/agent/probe-development.md`.\n- For build, formatting, lint, tests, E2E, or CI, read\n  `docs/agent/build-test.md`.\n- Some older prose may lag the code or build files. This guide and current\n  implementation win on factual conflicts.\n- Keep this file and the relevant detailed guide synchronized when a change\n  invalidates a command, path, invariant, or known limitation.\n\n## Product priorities\n\n- TLS capture is the project's core focus. Give the TLS, GoTLS, and GnuTLS\n  modules high priority, including support for OpenSSL, BoringSSL, Go TLS, and\n  GnuTLS. Protect their correctness, compatibility, and end-to-end behavior\n  when planning changes, reviews, and verification.\n- Bash, Zsh, MySQL, and other non-core modules have lower priority. Maintain\n  them, but prioritize core TLS functionality when work or coverage must be\n  allocated.\n- In user-facing material such as a promotional article, devote roughly 80%\n  of the attention to the core TLS modules and 20% to non-core modules. This\n  is an emphasis guideline, not a fixed quota for code or tests.\n\n### Optional machine-local context\n\nIf `AGENTS.local.md` exists at the repository root, read it before choosing an\nexecution environment or running build, test, cross-compilation, or remote-host\noperations. It may refine *where* commands run, but it must not override this\nrepository's safety, supported-platform, or verification requirements.\n\n- `AGENTS.local.md` is optional and must remain uncommitted.\n- Never require another contributor or a cloud agent to have it.\n- Never copy its machine details into commits, logs, issues, or pull requests.\n- Start from `AGENTS.local.example.md`; do not store credentials in either\n  file.\n\n## Non-negotiable platform boundary\n\neCapture may be edited anywhere, but compilation, linking, linting, tests,\neBPF generation, and execution require Linux. Android artifacts are also\nbuilt on a Linux host.\n\n- Runtime targets: Linux on `x86_64`, `aarch64`, or `loongarch64`; Android on\n  `x86_64` or `aarch64`.\n- Minimum kernels: x86_64 >= 4.18; aarch64 >= 5.5; Linux loongarch64 >= 6.6.\n- Loading probes requires root or the capabilities documented in\n  `docs/minimum-privileges.md`. Maintained E2E harnesses have stricter root\n  requirements.\n- macOS and Windows are editing, formatting, and read-only inspection\n  environments. Do not run `make`, Go builds/tests, lint, eBPF generation, or\n  E2E there.\n- Before using a remote Linux builder, verify its OS, architecture, checkout\n  path, branch, commit, worktree, submodules, and synchronization state. Never\n  assume local edits are present remotely or overwrite remote work.\n- New or changed build/test scripts must reject unsupported OS, architecture,\n  and kernel combinations before doing eBPF work.\n- If the required Linux/root environment is unavailable, report exactly what\n  was not run; never claim an unexecuted build or runtime passed.\n\n## Fast mental model\n\neCapture attaches uprobes, kprobes, and TC programs, reads perf/ring-buffer\nevents, decodes their binary ABI in Go, and routes validated events to output\nhandlers and writers.\n\n```text\nmain.go -> cli.Start() -> Cobra RunE -> runProbe()\n  -> config.Validate() -> factory.CreateProbe()\n  -> Probe.Initialize() / Start()\n  -> embedded eBPF asset + ebpfmanager\n  -> perf/ringbuf sample -> EventDecoder.Decode()\n  -> optional module-private EventPreprocessor\n  -> events.Dispatcher -> text/keylog/pcapng handler -> ByteSink\n                       -> low-latency pcapng -> decrypt SDK -> text ByteSink\n                       -> typed eCaptureQ EVENT publisher\n```\n\n`runProbe` owns signal handling and runtime reload orchestration. A concrete\nprobe owns its eBPF manager, attachments, maps/decoders, and mode-specific\nhandlers. `base.BaseProbe` owns shared logging, the default text handler,\nreaders, dispatch, reorder support, and common shutdown behavior.\n\nSee `docs/agent/architecture.md` for the CLI/probe matrix, repository map, and\npackage ownership.\n\n## Critical cross-file invariants\n\n- CLI imports trigger each probe's `register.go` `init()`. A seemingly unused\n  import may be required for factory registration.\n- Treat attachment and event plumbing as one atomic change:\n\n  ```text\n  C SEC section          <-> manager.Probe.Section\n  C BPF function         <-> EbpfFuncName\n  target symbol/offset   <-> AttachToFuncName / UAddress\n  C map identifier       <-> manager.Map.Name / decoder registration\n  C global variable      <-> manager.ConstantEditor\n  C event layout         <-> Go event struct / DecodeFromBytes\n  ```\n\n- Preserve C/Go event field order, signedness, widths, byte order, arrays, and\n  padding. Validate lengths before slicing. Perf samples may contain trailing\n  alignment padding, so do not identify variants by exact length alone.\n- `Configuration.Validate()` may run more than once and must be idempotent.\n- Concrete probes must follow BaseProbe lifecycle ordering. Track every reader;\n  custom reader loops must use `TrackReader` and `GoReaderLoop` equivalents so\n  shutdown can unblock and join them before closing handlers.\n- Dispatcher fan-out is synchronous and unordered. Multiple readers may call\n  one handler concurrently; handlers/writers must be concurrency-safe and\n  tolerate idempotent close. Perf reorder is per map/reader, not global.\n- Module-private records such as OpenSSL connection metadata are consumed\n  before output dispatch; they enrich captured output events instead of\n  becoming standalone text or typed events.\n- `--logaddr` is operational logging only. For TLS, GoTLS, and GnuTLS,\n  `--eventaddr` is the primary captured-event destination for text (hook or\n  pcapng source), keylog, and pcapng. eCaptureQ is an additive typed publisher,\n  not a ByteSink.\n- Linux production tags are `linux,netgo,ebpfassets,dynamic`; Android uses\n  `ecap_android,netgo,ebpfassets,dynamic`. Preserve CO-RE and non-CO-RE paths.\n- Never hand-edit or commit generated `bytecode/*.o`, `bytecode/*.d`,\n  `.build/`, `assets/ebpf_probe_<target>_<goarch>_bindata.go`, generated LoongArch\n  `vmlinux.h`, `bin/ecapture`, or `coverage.out`. Regenerate Protobuf and\n  stringer outputs from their sources.\n\n## Task guides and verification\n\nBefore changing a probe, event ABI, build flow, or test harness, read the\ncorresponding detailed guide listed above. At minimum:\n\n- Documentation-only changes: verify paths, commands, links, and source facts.\n- Go logic: format touched files, run targeted tests, and complete full race\n  plus production-tag lint gates when Linux is available.\n- Event decoders/ABI: add byte-level malformed, short, and padded-sample tests.\n- eBPF C or manager setup: clean-build both CO-RE and non-CO-RE variants for\n  affected architectures.\n- CLI/output/capture modes: run the relevant strict E2E case on a real\n  Linux/Android kernel.\n- OpenSSL/BoringSSL mappings: test mapping, both asset variants, and the real\n  library version.\n- CI changes: validate least privilege and trusted/untrusted workflow\n  boundaries.\n\nCanonical commands, prerequisites, build races, E2E semantics, and the full\nverification matrix live in `docs/agent/build-test.md`.\n\n## Code conventions\n\n- Module/import path: `github.com/gojue/ecapture/v2`; preserve the `/v2`\n  suffix in new imports.\n- Keep changes focused and follow the nearest working implementation. Probe\n  implementations are not perfectly uniform, so do not copy one blindly.\n- Do not add files unless necessary for the requested change. Prefer reusing\n  existing code, scripts, and tests, and keep changes as small as practical.\n  Avoid unrelated refactors and unnecessary helper layers.\n- In probe/domain lifecycle code, prefer structured constructors and codes in\n  `internal/errors`, adding context where useful. Preserve normal `%w`\n  wrapping at boundaries where that is the local pattern.\n- Use `internal/logger` inside probes/runtime code and zerolog in the CLI\n  layer. Do not add ad-hoc `fmt.Println` or standard `log` calls for runtime\n  logging.\n- Format only touched files: `gofmt`/`goimports` for Go and the repository's\n  exact clang-format style for C. `make format` is a broad C-only target.\n- Keep eBPF verifier limits, bounded loops, stack use, helper availability,\n  and old-kernel compatibility in mind.\n- Preserve the `github.com/google/gopacket` replacement in `go.mod` unless a\n  maintainer explicitly directs otherwise.\n- Root `LICENSE` is Apache-2.0. Preserve each file's existing SPDX header;\n  some imported or kernel-facing headers use other compatible licenses. Do\n  not propagate stale prose that says AGPL, and leave license changes to a\n  maintainer-directed task.\n\n## Safety, Git, and release boundaries\n\n- Captured logs, commands, SQL, keylogs, pcap/pcapng files, and test artifacts\n  may contain secrets. Never commit or paste them unredacted.\n- Preserve unrelated worktree changes. Do not stage, commit, push, open a PR,\n  publish, tag, or release unless the user explicitly requests it.\n- Name new branches with a conventional purpose prefix such as `feat/`,\n  `bugfix/`, `docs/`, `test/`, or `chore/`, followed by a concise kebab-case\n  description.\n- The default branch is `master`. If asked to commit, follow\n  `<package>: <what changed>`, keep the subject <= 70 characters, and explain\n  why in the body as documented in `CONTRIBUTING.md`. Write the entire commit\n  message in English unless the user explicitly requests a specific other\n  language.\n- Write GitHub pull request titles and bodies in English unless the user\n  explicitly requests a specific other language.\n- Keep ordinary fork-PR build/test jobs read-only and secret-free. Keep\n  scanner-specific write permissions narrowly scoped. Any trusted write-back\n  workflow must not execute untrusted fork code or its artifacts.\n- Do not weaken security checks, verifier failures, or E2E assertions merely\n  to make CI green.\n\n## Known state and traps\n\n- GnuTLS uses versioned C assets selected from the detected library patch\n  release; keep the supported version-to-asset table synchronized with\n  `kern/gnutls_*_kern.c`.\n- Runtime reload reattaches process-lifetime output dependencies and creates a\n  fresh probe context, but retains the original factory probe type; it is not\n  a cross-probe hot-swap facility.\n- Shared serializable probe fields are applied through\n  `internal/config.CommonConfig` for every Cobra command and HTTP config\n  factory. Keep process-lifetime output dependencies out of that copy path.\n- HTTP reload distinguishes omitted captured-event destination/rotation fields\n  from explicit empty/zero values. Omitted fields inherit from the active\n  generation, while runtime logger and typed eCaptureQ dependencies are\n  reattached separately.\n- Probe registration currently discards duplicate-registration errors.\n- Every probe uses the shared bytecode selector. `--btf=0` resolves kernel BTF\n  once per process, while explicit modes fail when the linked asset set cannot\n  satisfy them. Generated non-CO-RE objects use `*_kern_noncore.o`.\n- `pkg/event_processor` and `internal/output/encoders` are not in the current\n  production CLI event path.\n- `TARGET_ARCH` selects the build artifact architecture (`amd64`, `arm64`,\n  or `loong64`). `CROSS_ARCH` is a compatible alias used only when\n  `TARGET_ARCH` is unset.\n- Non-CO-RE compilation must retain Kbuild's `-fms-extensions` support for\n  tagged anonymous fields in Linux 6.19+ headers; dropping it breaks field\n  access and structure layout on Linux 7.x.\n  LoongArch CO-RE needs the same support for generated runtime BTF headers.\n  x86 non-CO-RE headers also require `CC_USING_FENTRY` when function tracing\n  is configured; do not enable native `-pg`/`-mfentry` instrumentation for BPF.\n- `make build` is not Go-only. Switching architecture, Android, or asset modes\n  still requires a clean serial validation even though libpcap, bytecode, Go\n  intermediates, and generated asset names are architecture-isolated. The\n  `assets`, `assets_core`, and `assets_noncore` targets for one architecture\n  write the same generated asset; do not request them together in one parallel\n  make invocation.\n- Linux release builds share an Ubuntu 24.04 x86_64 job. Loong64 joins the\n  same release entry point and PR architecture matrix; only amd64/arm64\n  produce Android artifacts. Loong64 is cross-built with `TARGET_ARCH=loong64`\n  and the repository's LLVM 22.1.8 wrappers. Do not substitute `loong64` for the\n  `loongarch64-linux-gnu` C target or `loongarch` Kbuild architecture.\n- Native Linux/loong64 production builds also support Debian 13+ with Clang/\n  LLVM 22.1.8, versioned LLD 22 linking and native multiarch libraries.\n  The Clang driver remains Go's external linker entry point.\n  `builder/init_env.sh` prepares dependencies and kernel inputs. Native CO-RE may use the running kernel's\n  BTF; non-CO-RE still requires prepared LoongArch kernel headers. Building\n  against packaged headers does not establish non-CO-RE compatibility with a\n  different running kernel. See `docs/loong64-support.md`.\n- The dedicated LoongArch E2E job shares `e2e.yml` push/PR/manual triggers,\n  but only trusted repository refs enter the host. It builds CO-RE at the event\n  SHA with LLVM 22.1.8 and runs OpenSSL/GoTLS directly from that checkout through\n  a fixed sudo Shell entry point. Harness output streams live to Actions.\n  Fork PRs retain hosted checks. Root-owned hooks enforce trusted refs and\n  clean job processes, caches and owned TC state; there is no separate E2E unit.\n\n## Focused references\n\n- Architecture and runtime: `docs/agent/architecture.md`\n- Probe and ABI development: `docs/agent/probe-development.md`\n- Build and verification: `docs/agent/build-test.md`\n- User-facing behavior: `README.md`, `README-zh_Hans.md`\n- Build sources: `Makefile`, `variables.mk`, `functions.mk`, `builder/init_env.sh`\n- E2E: `test/e2e/README.md`, `test/e2e/QUICK_REFERENCE.md`\n- Privileges/security: `docs/minimum-privileges.md`, `SECURITY.md`\n- Event forwarding: `docs/event-forward-api.md`, `pkg/ecaptureq/README.md`\n- Generated/config docs: `protobuf/README.md`, `protobuf/PROTOCOLS.md`, `docs/remote-config-update-api.md`\n- GitHub Copilot PR agent: `.github/agents/pr-agent.agent.md`\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/gojue/ecapture/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md — eCapture repository guide\n\nThis is the canonical repository guide for coding agents. Tool-specific files\nsuch as `CLAUDE.md` and `.github/copilot-instructions.md` are compatibility\nentry points, not separate sources of project truth.\n\n## How to use this guide\n\n- These instructions apply to the entire repository unless a deeper\n  `AGENTS.md` narrows them.\n- For runtime behavior, trust source code and tests. For build behavior, trust\n  `go.mod`, `Makefile`, `variables.mk`, `functions.mk`, and current workflows.\n  For maintained E2E behavior, trust `test/e2e/README.md` and its harness.\n- For architecture/runtime/output work, read `docs/agent/architecture.md` and\n  `docs/agent/output-pipeline.md`.\n- For probes, ABI, CLI config, or generated protocols, read\n  `docs/agent/probe-development.md`.\n- For build, formatting, lint, tests, E2E, or CI, read\n  `docs/agent/build-test.md`.\n- Some older prose may lag the code or build files. This guide and current\n  implementation win on factual conflicts.\n- Keep this file and the relevant detailed guide synchronized when a change\n  invalidates a command, path, invariant, or known limitation.\n\n## Product priorities\n\n- TLS capture is the project's core focus. Give the TLS, GoTLS, and GnuTLS\n  modules high priority, including support for OpenSSL, BoringSSL, Go TLS, and\n  GnuTLS. Protect their correctness, compatibility, and end-to-end behavior\n  when planning changes, reviews, and verification.\n- Bash, Zsh, MySQL, and other non-core modules have lower priority. Maintain\n  them, but prioritize core TLS functionality when work or coverage must be\n  allocated.\n- In user-facing material such as a promotional article, devote roughly 80%\n  of the attention to the core TLS modules and 20% to non-core modules. This\n  is an emphasis guideline, not a fixed quota for code or tests.\n\n### Optional machine-local context\n\nIf `AGENTS.local.md` exists at the repository root, read it before choosing an\nexecution environment or running build, test, cross-compilation, or remote-host\noperations. It may refine *where* commands run, but it must not override this\nrepository's safety, supported-platform, or verification requirements.\n\n- `AGENTS.local.md` is optional and must remain uncommitted.\n- Never require another contributor or a cloud agent to have it.\n- Never copy its machine details into commits, logs, issues, or pull requests.\n- Start from `AGENTS.local.example.md`; do not store credentials in either\n  file.\n\n## Non-negotiable platform boundary\n\neCapture may be edited anywhere, but compilation, linking, linting, tests,\neBPF generation, and execution require Linux. Android artifacts are also\nbuilt on a Linux host.\n\n- Runtime targets: Linux on `x86_64`, `aarch64`, or `loongarch64`; Android on\n  `x86_64` or `aarch64`.\n- Minimum kernels: x86_64 >= 4.18; aarch64 >= 5.5; Linux loongarch64 >= 6.6.\n- Loading probes requires root or the capabilities documented in\n  `docs/minimum-privileges.md`. Maintained E2E harnesses have stricter root\n  requirements.\n- macOS and Windows are editing, formatting, and read-only inspection\n  environments. Do not run `make`, Go builds/tests, lint, eBPF generation, or\n  E2E there.\n- Before using a remote Linux builder, verify its OS, architecture, checkout\n  path, branch, commit, worktree, submodules, and synchronization state. Never\n  assume local edits are present remotely or overwrite remote work.\n- New or changed build/test scripts must reject unsupported OS, architecture,\n  and kernel combinations before doing eBPF work.\n- If the required Linux/root environment is unavailable, report exactly what\n  was not run; never claim an unexecuted build or runtime passed.\n\n## Fast mental model\n\neCapture attaches uprobes, kprobes, and TC programs, reads perf/ring-buffer\nevents, decodes their binary ABI in Go, and routes validated events to output\nhandlers and writers.\n\n```text\nmain.go -> cli.Start() -> Cobra RunE -> runProbe()\n  -> config.Validate() -> factory.CreateProbe()\n  -> Probe.Initialize() / Start()\n  -> embedded eBPF asset + ebpfmanager\n  -> perf/ringbuf sample -> EventDecoder.Decode()\n  -> optional module-private EventPreprocessor\n  -> events.Dispatcher -> text/keylog/pcapng handler -> ByteSink\n                       -> low-latency pcapng -> decrypt SDK -> text ByteSink\n                       -> typed eCaptureQ EVENT publisher\n```\n\n`runProbe` owns signal handling and runtime reload orchestration. A concrete\nprobe owns its eBPF manager, attachments, maps/decoders, and mode-specific\nhandlers. `base.BaseProbe` owns shared logging, the default text handler,\nreaders, dispatch, reorder support, and common shutdown behavior.\n\nSee `docs/agent/architecture.md` for the CLI/probe matrix, repository map, and\npackage ownership.\n\n## Critical cross-file invariants\n\n- CLI imports trigger each probe's `register.go` `init()`. A seemingly unused\n  import may be required for factory registration.\n- Treat attachment and event plumbing as one atomic change:\n\n  ```text\n  C SEC section          <-> manager.Probe.Section\n  C BPF function         <-> EbpfFuncName\n  target symbol/offset   <-> AttachToFuncName / UAddress\n  C map identifier       <-> manager.Map.Name / decoder registration\n  C global variable      <-> manager.ConstantEditor\n  C event layout         <-> Go event struct / DecodeFromBytes\n  ```\n\n- Preserve C/Go event field order, signedness, widths, byte order, arrays, and\n  padding. Validate lengths before slicing. Perf samples may contain trailing\n  alignment padding, so do not identify variants by exact length alone.\n- `Configuration.Validate()` may run more than once and must be idempotent.\n- Concrete probes must follow BaseProbe lifecycle ordering. Track every reader;\n  custom reader loops must use `TrackReader` and `GoReaderLoop` equivalents so\n  shutdown can unblock and join them before closing handlers.\n- Dispatcher fan-out is synchronous and unordered. Multiple readers may call\n  one handler concurrently; handlers/writers must be concurrency-safe and\n  tolerate idempotent close. Perf reorder is per map/reader, not global.\n- Module-private records such as OpenSSL connection metadata are consumed\n  before output dispatch; they enrich captured output events instead of\n  becoming standalone text or typed events.\n- `--logaddr` is operational logging only. For TLS, GoTLS, and GnuTLS,\n  `--eventaddr` is the primary captured-event destination for text (hook or\n  pcapng source), keylog, and pcapng. eCaptureQ is an additive typed publisher,\n  not a ByteSink.\n- Linux production tags are `linux,netgo,ebpfassets,dynamic`; Android uses\n  `ecap_android,netgo,ebpfassets,dynamic`. Preserve CO-RE and non-CO-RE paths.\n- Never hand-edit or commit generated `bytecode/*.o`, `bytecode/*.d`,\n  `.build/`, `assets/ebpf_probe_<target>_<goarch>_bindata.go`, generated LoongArch\n  `vmlinux.h`, `bin/ecapture`, or `coverage.out`. Regenerate Protobuf and\n  stringer outputs from their sources.\n\n## Task guides and verification\n\nBefore changing a probe, event ABI, build flow, or test harness, read the\ncorresponding detailed guide listed above. At minimum:\n\n- Documentation-only changes: verify paths, commands, links, and source facts.\n- Go logic: format touched files, run targeted tests, and complete full race\n  plus production-tag lint gates when Linux is available.\n- Event decoders/ABI: add byte-level malformed, short, and padded-sample tests.\n- eBPF C or manager setup: clean-build both CO-RE and non-CO-RE variants for\n  affected architectures.\n- CLI/output/capture modes: run the relevant strict E2E case on a real\n  Linux/Android kernel.\n- OpenSSL/BoringSSL mappings: test mapping, both asset variants, and the real\n  library version.\n- CI changes: validate least privilege and trusted/untrusted workflow\n  boundaries.\n\nCanonical commands, prerequisites, build races, E2E semantics, and the full\nverification matrix live in `docs/agent/build-test.md`.\n\n## Code conventions\n\n- Module/import path: `github.com/gojue/ecapture/v2`; preserve the `/v2`\n  suffix in new imports.\n- Keep changes focused and follow the nearest working implementation. Probe\n  implementations are not perfectly uniform, so do not copy one blindly.\n- Do not add files unless necessary for the requested change. Prefer reusing\n  existing code, scripts, and tests, and keep changes as small as practical.\n  Avoid unrelated refactors and unnecessary helper layers.\n- In probe/domain lifecycle code, prefer structured constructors and codes in\n  `internal/errors`, adding context where useful. Preserve normal `%w`\n  wrapping at boundaries where that is the local pattern.\n- Use `internal/logger` inside probes/runtime code and zerolog in the CLI\n  layer. Do not add ad-hoc `fmt.Println` or standard `log` calls for runtime\n  logging.\n- Format only touched files: `gofmt`/`goimports` for Go and the repository's\n  exact clang-format style for C. `make format` is a broad C-only target.\n- Keep eBPF verifier limits, bounded loops, stack use, helper availability,\n  and old-kernel compatibility in mind.\n- Preserve the `github.com/google/gopacket` replacement in `go.mod` unless a\n  maintainer explicitly directs otherwise.\n- Root `LICENSE` is Apache-2.0. Preserve each file's existing SPDX header;\n  some imported or kernel-facing headers use other compatible licenses. Do\n  not propagate stale prose that says AGPL, and leave license changes to a\n  maintainer-directed task.\n\n## Safety, Git, and release boundaries\n\n- Captured logs, commands, SQL, keylogs, pcap/pcapng files, and test artifacts\n  may contain secrets. Never commit or paste them unredacted.\n- Preserve unrelated worktree changes. Do not stage, commit, push, open a PR,\n  publish, tag, or release unless the user explicitly requests it.\n- Name new branches with a conventional purpose prefix such as `feat/`,\n  `bugfix/`, `docs/`, `test/`, or `chore/`, followed by a concise kebab-case\n  description.\n- The default branch is `master`. If asked to commit, follow\n  `<package>: <what changed>`, keep the subject <= 70 characters, and explain\n  why in the body as documented in `CONTRIBUTING.md`. Write the entire commit\n  message in English unless the user explicitly requests a specific other\n  language.\n- Write GitHub pull request titles and bodies in English unless the user\n  explicitly requests a specific other language.\n- Keep ordinary fork-PR build/test jobs read-only and secret-free. Keep\n  scanner-specific write permissions narrowly scoped. Any trusted write-back\n  workflow must not execute untrusted fork code or its artifacts.\n- Do not weaken security checks, verifier failures, or E2E assertions merely\n  to make CI green.\n\n## Known state and traps\n\n- GnuTLS uses versioned C assets selected from the detected library patch\n  release; keep the supported version-to-asset table synchronized with\n  `kern/gnutls_*_kern.c`.\n- Runtime reload reattaches process-lifetime output dependencies and creates a\n  fresh probe context, but retains the original factory probe type; it is not\n  a cross-probe hot-swap facility.\n- Shared serializable probe fields are applied through\n  `internal/config.CommonConfig` for every Cobra command and HTTP config\n  factory. Keep process-lifetime output dependencies out of that copy path.\n- HTTP reload distinguishes omitted captured-event destination/rotation fields\n  from explicit empty/zero values. Omitted fields inherit from the active\n  generation, while runtime logger and typed eCaptureQ dependencies are\n  reattached separately.\n- Probe registration currently discards duplicate-registration errors.\n- Every probe uses the shared bytecode selector. `--btf=0` resolves kernel BTF\n  once per process, while explicit modes fail when the linked asset set cannot\n  satisfy them. Generated non-CO-RE objects use `*_kern_noncore.o`.\n- `pkg/event_processor` and `internal/output/encoders` are not in the current\n  production CLI event path.\n- `TARGET_ARCH` selects the build artifact architecture (`amd64`, `arm64`,\n  or `loong64`). `CROSS_ARCH` is a compatible alias used only when\n  `TARGET_ARCH` is unset.\n- Non-CO-RE compilation must retain Kbuild's `-fms-extensions` support for\n  tagged anonymous fields in Linux 6.19+ headers; dropping it breaks field\n  access and structure layout on Linux 7.x.\n  LoongArch CO-RE needs the same support for generated runtime BTF headers.\n  x86 non-CO-RE headers also require `CC_USING_FENTRY` when function tracing\n  is configured; do not enable native `-pg`/`-mfentry` instrumentation for BPF.\n- `make build` is not Go-only. Switching architecture, Android, or asset modes\n  still requires a clean serial validation even though libpcap, bytecode, Go\n  intermediates, and generated asset names are architecture-isolated. The\n  `assets`, `assets_core`, and `assets_noncore` targets for one architecture\n  write the same generated asset; do not request them together in one parallel\n  make invocation.\n- Linux release builds share an Ubuntu 24.04 x86_64 job. Loong64 joins the\n  same release entry point and PR architecture matrix; only amd64/arm64\n  produce Android artifacts. Loong64 is cross-built with `TARGET_ARCH=loong64`\n  and the repository's LLVM 22.1.8 wrappers. Do not substitute `loong64` for the\n  `loongarch64-linux-gnu` C target or `loongarch` Kbuild architecture.\n- Native Linux/loong64 production builds also support Debian 13+ with Clang/\n  LLVM 22.1.8, versioned LLD 22 linking and native multiarch libraries.\n  The Clang driver remains Go's external linker entry point.\n  `builder/init_env.sh` prepares dependencies and kernel inputs. Native CO-RE may use the running kernel's\n  BTF; non-CO-RE still requires prepared LoongArch kernel headers. Building\n  against packaged headers does not establish non-CO-RE compatibility with a\n  different running kernel. See `docs/loong64-support.md`.\n- The dedicated LoongArch E2E job shares `e2e.yml` push/PR/manual triggers,\n  but only trusted repository refs enter the host. It builds CO-RE at the event\n  SHA with LLVM 22.1.8 and runs OpenSSL/GoTLS directly from that checkout through\n  a fixed sudo Shell entry point. Harness output streams live to Actions.\n  Fork PRs retain hosted checks. Root-owned hooks enforce trusted refs and\n  clean job processes, caches and owned TC state; there is no separate E2E unit.\n\n## Focused references\n\n- Architecture and runtime: `docs/agent/architecture.md`\n- Probe and ABI development: `docs/agent/probe-development.md`\n- Build and verification: `docs/agent/build-test.md`\n- User-facing behavior: `README.md`, `README-zh_Hans.md`\n- Build sources: `Makefile`, `variables.mk`, `functions.mk`, `builder/init_env.sh`\n- E2E: `test/e2e/README.md`, `test/e2e/QUICK_REFERENCE.md`\n- Privileges/security: `docs/minimum-privileges.md`, `SECURITY.md`\n- Event forwarding: `docs/event-forward-api.md`, `pkg/ecaptureq/README.md`\n- Generated/config docs: `protobuf/README.md`, `protobuf/PROTOCOLS.md`, `docs/remote-config-update-api.md`\n- GitHub Copilot PR agent: `.github/agents/pr-agent.agent.md`\n","isInternal":false,"tokens":3525,"sizeBytes":14959}],"systemPromptSnippet":"<yakaai_skills repo=\"gojue/ecapture\">\n<!-- File: AGENTS.md (Tokens: ~3525 | Category: root-instruction) -->\n# AGENTS.md — eCapture repository guide\n\nThis is the canonical repository guide for coding agents. Tool-specific files\nsuch as `CLAUDE.md` and `.github/copilot-instructions.md` are compatibility\nentry points, not separate sources of project truth.\n\n## How to use this guide\n\n- These instructions apply to the entire repository unless a deeper\n  `AGENTS.md` narrows them.\n- For runtime behavior, trust source code and tests. For build behavior, trust\n  `go.mod`, `Makefile`, `variables.mk`, `functions.mk`, and current workflows.\n  For maintained E2E behavior, trust `test/e2e/README.md` and its harness.\n- For architecture/runtime/output work, read `docs/agent/architecture.md` and\n  `docs/agent/output-pipeline.md`.\n- For probes, ABI, CLI config, or generated protocols, read\n  `docs/agent/probe-development.md`.\n- For build, formatting, lint, tests, E2E, or CI, read\n  `docs/agent/build-test.md`.\n- Some older prose may lag the code or build files. This guide and current\n  implementation win on factual conflicts.\n- Keep this file and the relevant detailed guide synchronized when a change\n  invalidates a command, path, invariant, or known limitation.\n\n## Product priorities\n\n- TLS capture is the project's core focus. Give the TLS, GoTLS, and GnuTLS\n  modules high priority, including support for OpenSSL, BoringSSL, Go TLS, and\n  GnuTLS. Protect their correctness, compatibility, and end-to-end behavior\n  when planning changes, reviews, and verification.\n- Bash, Zsh, MySQL, and other non-core modules have lower priority. Maintain\n  them, but prioritize core TLS functionality when work or coverage must be\n  allocated.\n- In user-facing material such as a promotional article, devote roughly 80%\n  of the attention to the core TLS modules and 20% to non-core modules. This\n  is an emphasis guideline, not a fixed quota for code or tests.\n\n### Optional machine-local context\n\nIf `AGENTS.local.md` exists at the repository root, read it before choosing an\nexecution environment or running build, test, cross-compilation, or remote-host\noperations. It may refine *where* commands run, but it must not override this\nrepository's safety, supported-platform, or verification requirements.\n\n- `AGENTS.local.md` is optional and must remain uncommitted.\n- Never require another contributor or a cloud agent to have it.\n- Never copy its machine details into commits, logs, issues, or pull requests.\n- Start from `AGENTS.local.example.md`; do not store credentials in either\n  file.\n\n## Non-negotiable platform boundary\n\neCapture may be edited anywhere, but compilation, linking, linting, tests,\neBPF generation, and execution require Linux. Android artifacts are also\nbuilt on a Linux host.\n\n- Runtime targets: Linux on `x86_64`, `aarch64`, or `loongarch64`; Android on\n  `x86_64` or `aarch64`.\n- Minimum kernels: x86_64 >= 4.18; aarch64 >= 5.5; Linux loongarch64 >= 6.6.\n- Loading probes requires root or the capabilities documented in\n  `docs/minimum-privileges.md`. Maintained E2E harnesses have stricter root\n  requirements.\n- macOS and Windows are editing, formatting, and read-only inspection\n  environments. Do not run `make`, Go builds/tests, lint, eBPF generation, or\n  E2E there.\n- Before using a remote Linux builder, verify its OS, architecture, checkout\n  path, branch, commit, worktree, submodules, and synchronization state. Never\n  assume local edits are present remotely or overwrite remote work.\n- New or changed build/test scripts must reject unsupported OS, architecture,\n  and kernel combinations before doing eBPF work.\n- If the required Linux/root environment is unavailable, report exactly what\n  was not run; never claim an unexecuted build or runtime passed.\n\n## Fast mental model\n\neCapture attaches uprobes, kprobes, and TC programs, reads perf/ring-buffer\nevents, decodes their binary ABI in Go, and routes validated events to output\nhandlers and writers.\n\n```text\nmain.go -> cli.Start() -> Cobra RunE -> runProbe()\n  -> config.Validate() -> factory.CreateProbe()\n  -> Probe.Initialize() / Start()\n  -> embedded eBPF asset + ebpfmanager\n  -> perf/ringbuf sample -> EventDecoder.Decode()\n  -> optional module-private EventPreprocessor\n  -> events.Dispatcher -> text/keylog/pcapng handler -> ByteSink\n                       -> low-latency pcapng -> decrypt SDK -> text ByteSink\n                       -> typed eCaptureQ EVENT publisher\n```\n\n`runProbe` owns signal handling and runtime reload orchestration. A concrete\nprobe owns its eBPF manager, attachments, maps/decoders, and mode-specific\nhandlers. `base.BaseProbe` owns shared logging, the default text handler,\nreaders, dispatch, reorder support, and common shutdown behavior.\n\nSee `docs/agent/architecture.md` for the CLI/probe matrix, repository map, and\npackage ownership.\n\n## Critical cross-file invariants\n\n- CLI imports trigger each probe's `register.go` `init()`. A seemingly unused\n  import may be required for factory registration.\n- Treat attachment and event plumbing as one atomic change:\n\n  ```text\n  C SEC section          <-> manager.Probe.Section\n  C BPF function         <-> EbpfFuncName\n  target symbol/offset   <-> AttachToFuncName / UAddress\n  C map identifier       <-> manager.Map.Name / decoder registration\n  C global variable      <-> manager.ConstantEditor\n  C event layout         <-> Go event struct / DecodeFromBytes\n  ```\n\n- Preserve C/Go event field order, signedness, widths, byte order, arrays, and\n  padding. Validate lengths before slicing. Perf samples may contain trailing\n  alignment padding, so do not identify variants by exact length alone.\n- `Configuration.Validate()` may run more than once and must be idempotent.\n- Concrete probes must follow BaseProbe lifecycle ordering. Track every reader;\n  custom reader loops must use `TrackReader` and `GoReaderLoop` equivalents so\n  shutdown can unblock and join them before closing handlers.\n- Dispatcher fan-out is synchronous and unordered. Multiple readers may call\n  one handler concurrently; handlers/writers must be concurrency-safe and\n  tolerate idempotent close. Perf reorder is per map/reader, not global.\n- Module-private records such as OpenSSL connection metadata are consumed\n  before output dispatch; they enrich captured output events instead of\n  becoming standalone text or typed events.\n- `--logaddr` is operational logging only. For TLS, GoTLS, and GnuTLS,\n  `--eventaddr` is the primary captured-event destination for text (hook or\n  pcapng source), keylog, and pcapng. eCaptureQ is an additive typed publisher,\n  not a ByteSink.\n- Linux production tags are `linux,netgo,ebpfassets,dynamic`; Android uses\n  `ecap_android,netgo,ebpfassets,dynamic`. Preserve CO-RE and non-CO-RE paths.\n- Never hand-edit or commit generated `bytecode/*.o`, `bytecode/*.d`,\n  `.build/`, `assets/ebpf_probe_<target>_<goarch>_bindata.go`, generated LoongArch\n  `vmlinux.h`, `bin/ecapture`, or `coverage.out`. Regenerate Protobuf and\n  stringer outputs from their sources.\n\n## Task guides and verification\n\nBefore changing a probe, event ABI, build flow, or test harness, read the\ncorresponding detailed guide listed above. At minimum:\n\n- Documentation-only changes: verify paths, commands, links, and source facts.\n- Go logic: format touched files, run targeted tests, and complete full race\n  plus production-tag lint gates when Linux is available.\n- Event decoders/ABI: add byte-level malformed, short, and padded-sample tests.\n- eBPF C or manager setup: clean-build both CO-RE and non-CO-RE variants for\n  affected architectures.\n- CLI/output/capture modes: run the relevant strict E2E case on a real\n  Linux/Android kernel.\n- OpenSSL/BoringSSL mappings: test mapping, both asset variants, and the real\n  library version.\n- CI changes: validate least privilege and trusted/untrusted workflow\n  boundaries.\n\nCanonical commands, prerequisites, build races, E2E semantics, and the full\nverification matrix live in `docs/agent/build-test.md`.\n\n## Code conventions\n\n- Module/import path: `github.com/gojue/ecapture/v2`; preserve the `/v2`\n  suffix in new imports.\n- Keep changes focused and follow the nearest working implementation. Probe\n  implementations are not perfectly uniform, so do not copy one blindly.\n- Do not add files unless necessary for the requested change. Prefer reusing\n  existing code, scripts, and tests, and keep changes as small as practical.\n  Avoid unrelated refactors and unnecessary helper layers.\n- In probe/domain lifecycle code, prefer structured constructors and codes in\n  `internal/errors`, adding context where useful. Preserve normal `%w`\n  wrapping at boundaries where that is the local pattern.\n- Use `internal/logger` inside probes/runtime code and zerolog in the CLI\n  layer. Do not add ad-hoc `fmt.Println` or standard `log` calls for runtime\n  logging.\n- Format only touched files: `gofmt`/`goimports` for Go and the repository's\n  exact clang-format style for C. `make format` is a broad C-only target.\n- Keep eBPF verifier limits, bounded loops, stack use, helper availability,\n  and old-kernel compatibility in mind.\n- Preserve the `github.com/google/gopacket` replacement in `go.mod` unless a\n  maintainer explicitly directs otherwise.\n- Root `LICENSE` is Apache-2.0. Preserve each file's existing SPDX header;\n  some imported or kernel-facing headers use other compatible licenses. Do\n  not propagate stale prose that says AGPL, and leave license changes to a\n  maintainer-directed task.\n\n## Safety, Git, and release boundaries\n\n- Captured logs, commands, SQL, keylogs, pcap/pcapng files, and test artifacts\n  may contain secrets. Never commit or paste them unredacted.\n- Preserve unrelated worktree changes. Do not stage, commit, push, open a PR,\n  publish, tag, or release unless the user explicitly requests it.\n- Name new branches with a conventional purpose prefix such as `feat/`,\n  `bugfix/`, `docs/`, `test/`, or `chore/`, followed by a concise kebab-case\n  description.\n- The default branch is `master`. If asked to commit, follow\n  `<package>: <what changed>`, keep the subject <= 70 characters, and explain\n  why in the body as documented in `CONTRIBUTING.md`. Write the entire commit\n  message in English unless the user explicitly requests a specific other\n  language.\n- Write GitHub pull request titles and bodies in English unless the user\n  explicitly requests a specific other language.\n- Keep ordinary fork-PR build/test jobs read-only and secret-free. Keep\n  scanner-specific write permissions narrowly scoped. Any trusted write-back\n  workflow must not execute untrusted fork code or its artifacts.\n- Do not weaken security checks, verifier failures, or E2E assertions merely\n  to make CI green.\n\n## Known state and traps\n\n- GnuTLS uses versioned C assets selected from the detected library patch\n  release; keep the supported version-to-asset table synchronized with\n  `kern/gnutls_*_kern.c`.\n- Runtime reload reattaches process-lifetime output dependencies and creates a\n  fresh probe context, but retains the original factory probe type; it is not\n  a cross-probe hot-swap facility.\n- Shared serializable probe fields are applied through\n  `internal/config.CommonConfig` for every Cobra command and HTTP config\n  factory. Keep process-lifetime output dependencies out of that copy path.\n- HTTP reload distinguishes omitted captured-event destination/rotation fields\n  from explicit empty/zero values. Omitted fields inherit from the active\n  generation, while runtime logger and typed eCaptureQ dependencies are\n  reattached separately.\n- Probe registration currently discards duplicate-registration errors.\n- Every probe uses the shared bytecode selector. `--btf=0` resolves kernel BTF\n  once per process, while explicit modes fail when the linked asset set cannot\n  satisfy them. Generated non-CO-RE objects use `*_kern_noncore.o`.\n- `pkg/event_processor` and `internal/output/encoders` are not in the current\n  production CLI event path.\n- `TARGET_ARCH` selects the build artifact architecture (`amd64`, `arm64`,\n  or `loong64`). `CROSS_ARCH` is a compatible alias used only when\n  `TARGET_ARCH` is unset.\n- Non-CO-RE compilation must retain Kbuild's `-fms-extensions` support for\n  tagged anonymous fields in Linux 6.19+ headers; dropping it breaks field\n  access and structure layout on Linux 7.x.\n  LoongArch CO-RE needs the same support for generated runtime BTF headers.\n  x86 non-CO-RE headers also require `CC_USING_FENTRY` when function tracing\n  is configured; do not enable native `-pg`/`-mfentry` instrumentation for BPF.\n- `make build` is not Go-only. Switching architecture, Android, or asset modes\n  still requires a clean serial validation even though libpcap, bytecode, Go\n  intermediates, and generated asset names are architecture-isolated. The\n  `assets`, `assets_core`, and `assets_noncore` targets for one architecture\n  write the same generated asset; do not request them together in one parallel\n  make invocation.\n- Linux release builds share an Ubuntu 24.04 x86_64 job. Loong64 joins the\n  same release entry point and PR architecture matrix; only amd64/arm64\n  produce Android artifacts. Loong64 is cross-built with `TARGET_ARCH=loong64`\n  and the repository's LLVM 22.1.8 wrappers. Do not substitute `loong64` for the\n  `loongarch64-linux-gnu` C target or `loongarch` Kbuild architecture.\n- Native Linux/loong64 production builds also support Debian 13+ with Clang/\n  LLVM 22.1.8, versioned LLD 22 linking and native multiarch libraries.\n  The Clang driver remains Go's external linker entry point.\n  `builder/init_env.sh` prepares dependencies and kernel inputs. Native CO-RE may use the running kernel's\n  BTF; non-CO-RE still requires prepared LoongArch kernel headers. Building\n  against packaged headers does not establish non-CO-RE compatibility with a\n  different running kernel. See `docs/loong64-support.md`.\n- The dedicated LoongArch E2E job shares `e2e.yml` push/PR/manual triggers,\n  but only trusted repository refs enter the host. It builds CO-RE at the event\n  SHA with LLVM 22.1.8 and runs OpenSSL/GoTLS directly from that checkout through\n  a fixed sudo Shell entry point. Harness output streams live to Actions.\n  Fork PRs retain hosted checks. Root-owned hooks enforce trusted refs and\n  clean job processes, caches and owned TC state; there is no separate E2E unit.\n\n## Focused references\n\n- Architecture and runtime: `docs/agent/architecture.md`\n- Probe and ABI development: `docs/agent/probe-development.md`\n- Build and verification: `docs/agent/build-test.md`\n- User-facing behavior: `README.md`, `README-zh_Hans.md`\n- Build sources: `Makefile`, `variables.mk`, `functions.mk`, `builder/init_env.sh`\n- E2E: `test/e2e/README.md`, `test/e2e/QUICK_REFERENCE.md`\n- Privileges/security: `docs/minimum-privileges.md`, `SECURITY.md`\n- Event forwarding: `docs/event-forward-api.md`, `pkg/ecaptureq/README.md`\n- Generated/config docs: `protobuf/README.md`, `protobuf/PROTOCOLS.md`, `docs/remote-config-update-api.md`\n- GitHub Copilot PR agent: `.github/agents/pr-agent.agent.md`\n</yakaai_skills>"}