Revise the AGENTS.md file to reduce the number of false positives
from in CI reviews. The existing file will make up non-existent
functions and get confused about exposed API's.

Also, reflow the text on sentence boundaries instead of hard
limits at 70 cols.

Signed-off-by: Stephen Hemminger <[email protected]>
---
 AGENTS.md | 199 +++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 160 insertions(+), 39 deletions(-)

diff --git a/AGENTS.md b/AGENTS.md
index 813584352b..104d59ef91 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -5,13 +5,16 @@
 
 ## CRITICAL INSTRUCTION - READ FIRST
 
-This document has two categories of review rules with different confidence 
thresholds:
+This document has two categories of review rules with different confidence 
thresholds,
+plus rules on evidence and scope that apply to both.
 
 ### 1. Correctness Bugs -- HIGHEST PRIORITY (report at >=50% confidence)
 
 **Always report potential correctness bugs.** These are the most valuable 
findings.
-When in doubt, report them with a note about your confidence level.
-A possible use-after-free or resource leak is worth mentioning even if you are 
not certain.
+When in doubt, report them -- subject to the evidence rule below.
+Uncertainty about code you have read is fine:
+a possible use-after-free or resource leak is worth mentioning even if you are 
not certain.
+Uncertainty about code you have not read is not a finding at all.
 
 Correctness bugs include:
 - Use-after-free (accessing memory after `free`/`rte_free`)
@@ -44,9 +47,65 @@ Correctness bugs include:
 - Rx queue setup silently drops oversized packets instead of enabling scatter 
or returning an error
 - Rx function selection ignores `scattered_rx` flag or MTU-vs-mbuf-size check
 
-**Do NOT self-censor correctness bugs.** If you identify a code path
-where a resource could leak or memory could be used after free, report it.
-Do not talk yourself out of it.
+**Do NOT self-censor correctness bugs.**
+If you identify a code path where a resource could leak or memory could be 
used after free,
+report it -- subject to the evidence rule below.
+Do not talk yourself out of a bug you can see.
+Do not talk yourself into one you cannot.
+
+### Evidence rule (applies to every finding)
+
+Every finding must rest on code you have actually read.
+"Read" means a line in the patch, or a file you opened with a tool.
+
+This document is used in two ways and the rule is the same in both.
+
+**Diff only** -- CI, `review-patch.py`, and any run without tool access.
+All you have read is the patch: added and removed lines, plus a few lines of 
context.
+You cannot see the rest of the file, other callers, or any other file in the 
tree,
+so any claim that depends on them cannot be made.
+
+**With tool access** -- CLI or agentic use, where you can clone the tree, 
apply the series,
+grep, and read whole files.
+Read them.
+Check the surrounding function, the callers, and the headers before you report.
+Tool access does not lower the bar; it widens what you are able to read,
+and therefore what you are expected to have read before filing a finding.
+
+In either mode:
+
+- Report a finding only if you can name the added or changed line that causes 
it,
+  and quote that line verbatim from what you read.
+- Never quote, paraphrase, or reconstruct code you have not read.
+  If you are writing a code block with line numbers you did not read, you are 
inventing it.
+  Delete the finding.
+- If a claim depends on code you have not read -- other callers, other files,
+  the rest of the function -- either go read it or omit the claim.
+  Do not file it with a caveat, do not call it a risk,
+  and do not ask the author to verify it on your behalf.
+- "presumably", "appears to be", "if this is", "potentially", "could be" 
inside a finding
+  mean you lack the evidence.
+  Get the evidence or omit the finding.
+
+The >=50% bar for correctness bugs applies to your judgement about code you 
have read.
+It is not permission to speculate about code you have not.
+
+### Pre-existing code (applies to every finding)
+
+The unit of review is the patch.
+Code that appears only as diff context, or that you read in the tree but the 
patch does not touch,
+is not what this author is being asked to fix.
+A finding about such code must never be an Error or a Warning
+and must never withhold a Reviewed-by.
+
+Report it as Info, and say plainly that it is pre-existing and not introduced 
by this patch.
+This is worth doing: it puts the observation in front of the people working in 
that code
+so it can be picked up in a separate patch later.
+
+The evidence rule still applies in full.
+An Info note about surrounding code needs the same proof as any other finding:
+you must have read the code and be able to quote the line.
+"Pre-existing" is a lower severity, not a lower standard of evidence.
 
 ### 2. Style, Process, and Formatting -- suppress false positives
 
@@ -95,8 +154,11 @@ than one that catches every style issue but misses the bug.
 - Check every `goto error` and early `return`: does it clean up everything 
allocated so far?
 - Look for use-after-free: after `free(p)`, is `p` accessed again?
 - Check that error codes are propagated, not silently dropped
-- Report at >=50% confidence; note uncertainty if appropriate
-- It is better to report a potential bug that turns out to be safe than to 
miss a real bug
+- Report at >=50% confidence about code you have read
+- Never substitute a confidence caveat for evidence:
+  if the reasoning depends on code you have not read, go read it or drop the 
finding
+- It is better to report a potential bug that turns out to be safe than to 
miss a real bug,
+  provided you can point to the line that causes it
 
 ### Style and process review guidelines
 - Only comment on style/process issues when you have HIGH CONFIDENCE (>80%) 
that an issue exists
@@ -129,6 +191,8 @@ than one that catches every style issue but misses the bug.
   Do not include a patch in your output just to say "no issues found"
   or to summarize what the patch does.
   Only include patches where you have actual findings to report.
+- Do NOT end the review with a summary section listing every patch in the 
series.
+  A clean patch must not appear anywhere in the output, including in a summary 
or status table.
 
 ## Priority Areas (Review These)
 
@@ -515,39 +579,52 @@ than one that catches every style issue but misses the 
bug.
 
 ### Cryptographic and Security Code
 
-Applies only when the patch touches crypto PMDs (drivers/crypto/),
-the security or ipsec libraries, or code handling key material, IVs,
-or authentication digests. Stays silent on all other patches.
+Applies only when the patch touches crypto PMDs (`drivers/crypto/`),
+the security or ipsec libraries,
+or code handling key material, IVs, or authentication digests.
+Stays silent on all other patches.
 
 - **Non-constant-time digest/tag comparison** (Error):
   When verifying an authentication tag, digest, MAC, or ICV --
   comparing a computed value against an attacker-supplied one to decide 
accept/reject --
-  plain memcmp leaks timing information.
-  Use rte_memeq_timingsafe() instead.
-  Return semantics differ from memcmp: memcmp returns 0 on equal,
-  rte_memeq_timingsafe() returns true on equal.
-  So `if (memcmp(tag, digest, len))` becomes
-  `if (!rte_memeq_timingsafe(tag, digest, len))`.
-  Do NOT flag memcmp on non-secret data: algorithm IDs, key lengths,
-  capability/feature structs, lookup keys.
+  plain `memcmp()` leaks timing information.
+  Use `rte_memeq_timingsafe()` instead.
+  Return semantics differ: `memcmp()` returns 0 on equal,
+  `rte_memeq_timingsafe()` returns true on equal.
+  So `if (memcmp(tag, digest, len))` becomes `if (!rte_memeq_timingsafe(tag, 
digest, len))`.
+  Do NOT flag `memcmp()` on non-secret data:
+  algorithm IDs, key lengths, capability/feature structs, lookup keys.
   Only flag comparisons that gate acceptance of attacker-influenced data.
 
 - **Sensitive material not zeroed before free** (Error):
-  Keys, expanded key schedules, HMAC ipad/opad, and session secrets
-  must be wiped, not merely freed -- a plain free leaves secrets in heap.
-  - rte_malloc/rte_zmalloc'd secret: use rte_free_sensitive() instead of 
rte_free()
-  - local/stack secret going out of scope: rte_memzero_explicit()
-    before return; plain memset() may be optimized away.
-  Do NOT flag buffers that never held secrets (descriptors, dev_info),
-  or memset the compiler cannot elide because the pointer escapes to free.
-
-- **Insecure RNG for keys/IVs** (Error):
-  rte_rand()/rand()/random() are not cryptographically secure;
-  do not use them to generate keys, IVs, or nonces in crypto/security code.
+  Keys, expanded key schedules, HMAC ipad/opad, and session secrets must be 
wiped,
+  not merely freed -- a plain free leaves secrets in the heap.
+  - `rte_malloc`/`rte_zmalloc`'d secret: use `rte_free_sensitive()` instead of 
`rte_free()`
+  - local or stack secret going out of scope: `rte_memzero_explicit()` before 
return;
+    plain `memset()` may be optimized away
+  Flag only where the patch itself allocates, copies, or frees the secret.
+  Do NOT flag buffers that never held secrets (descriptors, `dev_info`),
+  pre-existing free paths the patch does not touch,
+  or `memset()` the compiler cannot elide because the pointer escapes to 
`free()`.
+  `rte_memzero_explicit()` followed by a plain `rte_free()` is correct
+  and is not a missing `rte_free_sensitive()`.
+
+- **Non-cryptographic RNG for keys/IVs** (Error):
+  `rte_rand()` is seeded from system entropy (`getentropy()`, with RDSEED and 
TSC fallbacks),
+  but the generator itself is an LFSR and is linear:
+  an observer who sees enough output can recover the state and predict every 
later value.
+  Good seeding is not sufficient for key, IV, or nonce generation.
+  Use a cryptographic source instead:
+  the device's own entropy source or DRBG,
+  or `getrandom(2)` / `/dev/urandom` in the control path.
+  `rand()` and `random()` are weaker still and must not appear in crypto or 
security code.
+  Do NOT flag `rte_rand()` used for non-secret purposes:
+  hash seeds (`lib/ipsec/ipsec_sad.c` uses it for `hash_func_init_val`),
+  jitter, backoff, load balancing, or test data.
 
 Do NOT flag:
 - IV/nonce reuse -- a runtime property, not determinable from a patch.
-- memcmp on lengths, algorithm selectors, or non-secret config.
+- `memcmp()` on lengths, algorithm selectors, or non-secret config.
 
 ### Architecture & Patterns
 - Code that violates existing patterns in the code base
@@ -1585,6 +1662,25 @@ rte_foo_internal_helper(void)
 - Export macros go in `.c` files, not headers
 - The build system generates linker version maps automatically
 
+#### What Counts as ABI
+
+ABI concerns apply to symbols and types reachable from an installed header.
+A header is installed only if a meson.build lists it in `headers` or 
`indirect_headers`.
+
+Most drivers install nothing, but some do.
+`drivers/net/bonding/meson.build` installs `rte_eth_bond.h`,
+`drivers/net/intel/i40e/meson.build` installs `rte_pmd_i40e.h`,
+and bus/pci, bus/vdev and several baseband drivers install public headers as 
well.
+Check the driver's meson.build rather than assuming either way.
+
+A function declared only in a driver-private header,
+with no `RTE_EXPORT_*` annotation and no presence in an installed header, has 
no ABI.
+Removing it or changing its signature is not an ABI break,
+and speculation about unseen external callers is not a finding.
+
+This does not weaken the separate requirement that a *new* public function
+carry an `RTE_EXPORT_*` macro; a new public API without one is still a Warning.
+
 #### What NOT to Review
 
 - Do **NOT** flag missing `version.map` updates - maps are auto-generated
@@ -1678,9 +1774,9 @@ Checked by `devtools/checkpatches.sh` -- not duplicated 
here.
 - [ ] `bool` used for pure true/false variables, parameters, and predicate 
return types
 - [ ] Shared variables use `rte_atomic_*_explicit()`, not `volatile` or bare 
access
 - [ ] Memory ordering is the weakest correct choice (`relaxed` for counters, 
`acquire`/`release` for publish/consume)
-- [ ] Auth tag/digest comparisons use rte_memeq_timingsafe(), not memcmp
-- [ ] Key material zeroed before free (rte_free_sensitive / 
rte_memzero_explicit)
-- [ ] Keys/IVs/nonces not generated with rte_rand()/rand()/random()
+- [ ] Auth tag/digest comparisons use `rte_memeq_timingsafe()`, not `memcmp()`
+- [ ] Key material zeroed before free (`rte_free_sensitive()` / 
`rte_memzero_explicit()`)
+- [ ] Keys/IVs/nonces not generated with `rte_rand()`, `rand()`, or `random()`
 
 ### API Tags
 
@@ -1793,8 +1889,9 @@ devtools/get-maintainer.sh <patch-file>
 - `mtu_set` rejects valid MTU when scatter Rx is already enabled
 - Rx function selection ignores `scattered_rx` flag or MTU-vs-mbuf-size 
comparison
 - Non-constant-time comparison of auth tag/digest/MAC/ICV (timing side channel)
-- Key material or session secrets freed without zeroing 
(rte_free_sensitive/rte_memzero_explicit)
-- Non-cryptographic RNG (rte_rand/rand/random) used to generate keys, IVs, or 
nonces
+- Key material or session secrets freed without zeroing
+  (`rte_free_sensitive()` / `rte_memzero_explicit()`)
+- Non-cryptographic RNG (`rte_rand()`, `rand()`, `random()`) used to generate 
keys, IVs, or nonces
 
 *Process and format errors:*
 - Forbidden tokens in code
@@ -1857,6 +1954,13 @@ devtools/get-maintainer.sh <patch-file>
 - Cross-patch compilation dependencies - you cannot determine patch ordering 
correctness from review
 - Claims that a symbol "was removed in patch N" causing issues in patch M - 
assume author ordered correctly
 - Any speculation about whether patches will compile when applied in sequence
+- Any finding about code you have not read - reconstructed from diff context,
+  inferred from other patches, or assumed from a function name
+- Pre-existing problems in code the patch does not touch, as an Error or 
Warning
+  (report these as Info, labelled pre-existing)
+- ABI or "external callers" concerns for a function in a driver-private header
+  with no `RTE_EXPORT_*` annotation
+- `rte_rand()` used for hash seeds, jitter, backoff, load balancing, or test 
data
 - Mutexes/locks in process-private memory (standard `malloc`, stack, static 
non-shared) - these don't need `PTHREAD_PROCESS_SHARED`
 - Use of `rte_spinlock_t` or `rte_rwlock_t` in shared memory (these work 
correctly without special init)
 - `volatile` used for MMIO/hardware register access in drivers (this is 
correct usage)
@@ -1875,6 +1979,8 @@ devtools/get-maintainer.sh <patch-file>
 - Minor style preferences
 - Optimization suggestions
 - Alternative approaches
+- Pre-existing bugs in surrounding code that the patch does not introduce,
+  labelled as pre-existing so whoever works on that code next can pick them up
 
 ---
 
@@ -1891,7 +1997,7 @@ Example: This could panic if the string is NULL.
 
 ## FINAL CHECK BEFORE SUBMITTING REVIEW
 
-Before outputting your review, do two separate passes:
+Before outputting your review, do three separate passes:
 
 ### Pass 1: Verify correctness bugs are included
 
@@ -1899,7 +2005,8 @@ Ask: "Did I trace every error path for resource leaks?
 Did I check for use-after-free?
 Did I verify error codes are propagated?"
 
-If you identified a potential correctness bug but talked yourself out of it, 
**add it back**.
+If you identified a potential correctness bug but talked yourself out of it, 
**add it back**,
+provided you can point to the line that causes it.
 It is better to report a possible bug than to miss a real one.
 
 ### Pass 2: Remove style/process false positives
@@ -1912,4 +2019,18 @@ It should not be in your output.
 An item that says "X is wrong... actually this is correct" is a FALSE POSITIVE 
and must be removed.
 This applies to style, format, and process items only.
 
-**If your Errors section would be empty after this check, that's fine -- it 
means the patches are good.**
+### Pass 3: Verify every finding has evidence
+
+For EACH remaining item, of any severity, ask:
+"Did I read the code this claims is broken, or did I reconstruct it?"
+
+If you cannot quote the added or changed line that causes the finding, DELETE 
IT.
+If the finding is hedged with "presumably", "appears to be", "potentially", or 
"could be",
+you did not have the evidence: DELETE IT.
+If the finding is about code the patch does not touch, demote it to Info
+and label it as pre-existing -- never an Error or a Warning.
+Demoting the severity does not excuse it from the checks above:
+an Info note you cannot quote a line for is still deleted.
+
+**If your Errors section would be empty after these checks, that's fine --
+it means the patches are good.**
-- 
2.53.0

Reply via email to