Skip to content

review: eleven rules a board-support PR walked straight through - #2451

Closed
openipc-ai wants to merge 1 commit into
masterfrom
review-rules-2446
Closed

openipc-ai wants to merge 1 commit into
masterfrom
review-rules-2446

Conversation

@openipc-ai

Copy link
Copy Markdown
Collaborator

Problem

PR #2446 (Imou Cue 2 board support) is exactly the kind of change best_practices.md and
pr_compliance_checklist.yaml exist to catch: a whole retail camera filed into the shared
tree, with a binary blob, a boot-time download, and a sensor patch against one of our own
repositories. The automated review found eight of the twelve problems in it. The four
it missed and the five it half-caught are gaps in what we wrote down, not in the reviewer —
so this writes them down.

No hardware; this is review configuration only.

What was missing

The binaries gate could not see a binary. It enumerated .ko/.so/.a/.bin, so
general/overlay/etc/ir/nrxset — an executable with no extension — came back from the
describe pass as "the supplied patch contains no textual changes", which is precisely what
a blob looks like to anything reading a diff as text. The gate now keys on the
Binary files ... differ marker, which is the one signal that always survives, and says
outright that general/overlay/ is never the place for a compiled artefact. A register
table copied out of a vendor's driver is folded in as the same failure written in C.

ipctool is not on a camera. general/package/ipctool/ipctool.mk installs ipcinfo
and nothing else; /usr/sbin/ipctool is a symlink to extutils, whose ipctool) arm curls
the tool from the latest release into /tmp on first use. In a boot script that is a
network fetch during boot, from a floating tag, repeated every boot because /tmp is tmpfs,
and a silent no-op until the network is up. #2446 ran ipctool i2cset from rc.local
twelve seconds in, on a WiFi-only board.

An overlay file needs no Config.in, so nothing catches one nothing reads. /etc/ir/nrxset
and /etc/ir/nrx_night_06.txt are read by nothing in firmware, builder or majestic, and the
PR's own two comments disagree about whether they are used at all. Cost lands on every board,
several of which sit within 32 KB of their cap.

S95majestic is not a thin wrapper. It passes -s, finds the daemon with
start-stop-daemon -x rather than a pidfile, waits up to ten seconds for the sensor HAL to
be released, and starts under trap '' HUP — its own comment records 25 deaths out of 25
without that, measured on a hi3516ev200. A hand-rolled killall majestic; sleep 3; majestic &
throws all of it away, which is what #2446 shipped, on that same SoC.

Every patch in this tree targets an upstream we cannot commit to — ffmpeg, mbedTLS,
vtund, libre, siproxd, ZeroTier, libwebsockets, f2fs-tools, the Realtek drivers. A patch
against hisilicon-opensdk does not: its SITE is openipc/openhisilicon, and the file
being patched is checked in there. OpenIPC/openhisilicon and OpenIPC/sensors join the
redirect table, which listed only linux, builder, ipctool and majestic.

And the tree's per-device seams are documented nowhere. customizer.sh, muxes.sh,
gpio.conf, late-overlays.list and the excludes lists are a complete mechanism, shipped
per device in builder at the same paths (96, 15, 18 and 9 devices respectively) — and absent
from the wiki, which is why somebody writes an S01leds with GPIO 0, 4 and 9 typed into it.
"Move it to builder" is half an answer; review should say which seam it becomes. Two smaller
notes ride along: the additive, so it changes nothing exemption belongs to load_<vendor>
case arms and not to the overlay, where etc/wireless/usb has quietly reached 46
retail-model arms in 327 lines; and an excludes list added here is keyed
<model>_<variant>, the generic board's key too, so #2446's list took libsns_imx307.so
and default.ini away from hi3516ev200_lite itself.

devmem in a shipped script is now a question. majestic #751 landed four days before
#2446 and its commit message is the rule: "Somebody who solders an IR lamp, a button or an
I²C sensor to their board writes devmem into rc.local, because nothing in the camera knows
the pad exists. That line is undone by anything that exports the pad and lost on the next
reflash."

Changes

File
best_practices.md new §1.4, §1.5, §2.5, §3.5, §4.4, §6.3, §7.3, §7.4; §2.4 and the §8 summary extended
pr_compliance_checklist.yaml 3 new gates (OpenIPC-package patches, reachability, commands on the image); binaries, device-specific values and script conventions extended — 13 gates to 16
.pr_agent.toml the same, as reviewer guidance
CLAUDE.md two rows in the redirect table, four bullets in "what the tree will not accept", the seams named

#2446 is still open. best_practices.md's header said every rule traces to a closed PR;
that sentence now admits the occasional open one, rather than the citations quietly being
wrong.

Hardware tested on

Not applicable, and not hedging: this is review configuration, documentation and repository
metadata, which pr_compliance_checklist.yaml and the template both name as exempt. No file
here reaches an image.

Evidence

The checks this change class does admit:

$ python3 .github/scripts/ci-matrix.py --self-test
ci-matrix: self-test ok (99 boards, 136 packages, 56 cases)

$ python3 .github/scripts/lint-workflow-shell.py --self-test
self-test passed

$ git diff --name-only origin/master | python3 .github/scripts/ci-matrix.py --stdin
ci-matrix: 0/99 boards (needs_build=False) --- nothing that reaches a build

Both edited config files still parse, and .pr_agent.toml still carries no token that trips
Qodo's hardened loader (the failure mode from #2268):

$ python3 -c "import yaml; d=yaml.safe_load(open('pr_compliance_checklist.yaml')); print(len(d['pr_compliances']), 'gates')"
16 gates

$ python3 -c "import tomllib; d=tomllib.load(open('.pr_agent.toml','rb')); print(list(d))"
['github_app', 'review_agent']

$ grep -ciE 'ld_preload|@(json|format|py|get)' .pr_agent.toml
0

Scope

  • No kernel patches under general/package/all-patches/linux/ (those go to OpenIPC/linux)
  • No files specific to a single retail camera model (those go to OpenIPC/builder)
  • No probing or bring-up tooling (that goes to OpenIPC/ipctool)
  • Nothing under general/overlay/ or in a shared load_<vendor> script hardcodes a value specific to my board
  • No LD_PRELOAD, and no binaries that cannot be rebuilt from source

#2446 (Imou Cue 2 board support) is the shape of PR these files exist to
catch, and the automated review caught eight of twelve problems in it. The
four it missed, and the five it half-caught, are all gaps in what we wrote
down rather than gaps in the reviewer.

The binaries gate enumerated .ko/.so/.a/.bin, so an executable with no
extension at all -- general/overlay/etc/ir/nrxset -- was reported back as
"contains no textual changes", which is exactly what a blob looks like to
anything reading a diff as text. The gate now keys on the "Binary files ...
differ" marker, which is the one signal that survives, and says outright
that general/overlay/ is never the place for a compiled artefact. A
register table copied out of a vendor's driver gets the same treatment: it
is the same provenance failure written in C.

Three things the tree already owns had no rule at all. ipctool is not on a
camera -- the package installs ipcinfo, and /usr/sbin/ipctool is an
extutils arm that curls the tool from a "latest" release into tmpfs at
first use -- so calling it from rc.local twelve seconds into boot on a
WiFi-only board is four bad properties at once. An overlay file needs no
Config.in, so nothing caught /etc/ir/nrxset and nrx_night_06.txt, which
nothing in firmware, builder or majestic reads. And S95majestic carries an
-s argument, a start-stop-daemon lookup, a ten-second wait for the sensor
HAL and a trap '' HUP that its own comment measured at 25 deaths out of 25
on a hi3516ev200 -- all of which a hand-rolled killall-and-relaunch throws
away, on that same SoC.

Every patch in this tree targets an upstream we cannot commit to. A patch
against hisilicon-opensdk does not: its SITE is openipc/openhisilicon, and
the file being patched is checked in there. That repository and
OpenIPC/sensors join the redirect table, which listed only linux, builder,
ipctool and majestic.

The rest is telling contributors what already exists. customizer.sh,
muxes.sh, gpio.conf, late-overlays.list and the excludes lists are a
complete per-device mechanism, shipped per device in builder at the same
paths -- and documented nowhere, which is why somebody writes an S01leds
with GPIO 0, 4 and 9 typed into it instead. "Move it to builder" is half an
answer; say which seam it becomes. Two smaller notes go with it: the
"additive, so it changes nothing" exemption belongs to load_<vendor> case
arms and not to the overlay, where etc/wireless/usb has quietly reached 46
retail-model arms; and an excludes list added here is keyed <model>_<variant>,
which is the generic board's key too, so #2446's list took libsns_imx307.so
away from hi3516ev200_lite itself.

Lastly, devmem in a shipped script is now a question rather than a given.
majestic #751 landed four days before #2446 and its commit message is the
rule: somebody who solders a lamp to a board writes devmem into rc.local
because nothing in the camera knows the pad exists, and that line is undone
by anything that exports the pad and lost on the next reflash.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Expand PR compliance rules for board-support changes

⚙️ Configuration changes 📝 Documentation ✨ Enhancement 🕐 20-40 Minutes

Grey Divider

AI Description

• Adds compliance gates for upstream patches, shipped-file reachability, and command availability.
• Strengthens binary, board-specific, and daemon lifecycle review rules.
• Documents repository ownership and supported per-device customization seams.
Diagram

graph TD
  A["Board PR Diff"] --> E["Qodo Review"] --> F["Review Findings"] --> H["Correct Repository"]
  B["Compliance Checklist"] --> E
  C["Reviewer Guidance"] --> E
  D["Best Practices"] --> F
  G["Contributor Guide"] --> F
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Generate guidance from a canonical policy catalog
  • ➕ Keeps checklist, agent prompt, and contributor documentation synchronized.
  • ➕ Enables automated detection of missing or contradictory rule mappings.
  • ➕ Reduces future maintenance across duplicated policy text.
  • ➖ Requires a schema and generation tooling for audience-specific prose.
  • ➖ Detailed examples and rationale do not map cleanly into one structured source.
  • ➖ Introduces a build or validation step for documentation changes.
2. Implement deterministic repository linters
  • ➕ Mechanically detects binary markers, OpenIPC package patches, and unavailable commands.
  • ➕ Provides reproducible findings independent of reviewer prompt interpretation.
  • ➕ Can run directly in CI before human review.
  • ➖ Cross-repository reachability and board-specific intent require semantic context.
  • ➖ Command availability varies by defconfig and may create false positives.
  • ➖ Does not replace explanatory guidance or repository-routing decisions.

Recommendation: The PR’s synchronized policy update is appropriate for immediately closing the observed review gaps, especially where findings require repository and hardware context. As these rules grow, extract mechanically provable checks into CI and add consistency validation—or a small canonical metadata layer—without forcing the detailed audience-specific prose into one generated document.

Files changed (4) +396 / -19

Documentation (2) +237 / -10
CLAUDE.mdDocument repository ownership and new hard review boundaries +23/-3

Document repository ownership and new hard review boundaries

• Adds OpenIPC/openhisilicon and OpenIPC/sensors to the repository routing table. Summarizes the new binary, upstream patch, shipped-file, command-availability, and per-device seam requirements for contributors.

CLAUDE.md

best_practices.mdCodify board-support failures and their supported alternatives +214/-7

Codify board-support failures and their supported alternatives

• Adds detailed rules covering per-device customization seams, 'devmem', binary diff markers, vendor register provenance, SDK ownership, OpenIPC package patches, unreachable overlay files, image command availability, and majestic restarts. It also extends the hard-gate summary and permits rules derived from still-open pull requests.

best_practices.md

Other (2) +159 / -9
.pr_agent.tomlTeach the PR agent eleven board-support review rules +60/-2

Teach the PR agent eleven board-support review rules

• Expands reviewer priorities for binary detection, vendor register tables, OpenIPC package patches, per-device seams, shipped command availability, 'devmem', overlay reachability, and majestic lifecycle handling. The guidance directs findings toward the repository and customization mechanism that owns each fix.

.pr_agent.toml

pr_compliance_checklist.yamlExpand automated compliance from thirteen to sixteen gates +99/-7

Expand automated compliance from thirteen to sixteen gates

• Adds gates rejecting patches against OpenIPC-owned packages, unreachable shipped files, and commands absent from firmware images. Existing gates now detect binaries by diff marker, route board-specific values to builder seams, reject vendor-derived register tables, and require majestic restarts through its init script.

pr_compliance_checklist.yaml

@openipc-ai

Copy link
Copy Markdown
Collaborator Author

Closing immediately — this PR body and diff quote a private source tree. Reopening with that content removed.

@openipc-ai openipc-ai closed this Sep 19, 2026
@openipc-ai
openipc-ai deleted the review-rules-2446 branch September 19, 2026 06:42
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Valid package sources fail review 🐞 Bug ≡ Correctness
Description
The new reachability gate requires every added file under a package's files/ directory to be read
at an installed path, even when the file is a build-time source that has no installed path. Adding
another source like openipc_ethaddr.c, which is copied into the kernel tree and compiled there,
therefore cannot satisfy this hard compliance gate.
Code

pr_compliance_checklist.yaml[R199-201]

+      Every added file under general/overlay/ or a package's files/ directory is read at
+      its installed path by a script, init file, package, or configuration somewhere in
+      firmware, builder or majestic. Documentation and license text shipped on purpose
Evidence
The added success criterion covers every package files/ entry, while the existing NFS-root package
demonstrates that this directory contains build-only C source. Its Linux extension copies that
source into the kernel build tree, so it is compiled without ever being read from an installed
runtime path.

pr_compliance_checklist.yaml[192-205]
general/package/openipc-nfs-root/files/openipc_ethaddr.c[1-10]
general/linux/linux-ext-openipc-nfs-root.mk[8-12]
general/linux/linux-ext-openipc-nfs-root.mk[22-26]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The shipped-file reachability gate treats every file under a package's `files/` directory as a runtime file, although that directory also contains build-time sources which are compiled rather than installed at their source path.

## Fix Focus Areas
- pr_compliance_checklist.yaml[192-208]

## Recommended Fix
Limit this gate to files actually installed into the target root filesystem. Explicitly exempt source, patch, and other build-time inputs that an existing build rule consumes, while leaving runtime overlay and package payload files subject to the installed-path reachability check.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Reviewers misdiagnose missing commands 🐞 Bug ≡ Correctness
Description
The new command-availability gate says /usr/sbin/ipctool is a symlink to extutils, but neither
the overlay nor any installation rule creates that symlink. On images produced solely by this tree,
invoking ipctool fails immediately instead of reaching the documented download arm, so reviews
will attribute the failure to network timing and a floating release rather than the absent command.
Code

pr_compliance_checklist.yaml[R220-224]

+      The diff calls, from a shipped script, a command no package installs. ipctool is
+      the specific trap: general/package/ipctool/ipctool.mk installs ipcinfo and nothing
+      else, so BR2_PACKAGE_IPCTOOL=y puts no "ipctool" on the image. /usr/sbin/ipctool
+      is a symlink to extutils, which curls the tool from the ipctool repository's
+      "latest" release into /tmp on first use — an interactive convenience, and in a
Evidence
The package's sole target installation is /usr/bin/ipcinfo, and the overlay directory contains
extutils but no ipctool symlink. Although extutils has an ipctool) dispatch arm,
repository-wide references create only sensor_cli symlinks, leaving that arm unreachable under the
claimed basename.

general/package/ipctool/ipctool.mk[99-107]
general/overlay/usr/sbin/extutils[209-225]
general/package/ingenic-osdrv-t20/files/script/load_ingenic[1-10]
best_practices.md[613-622]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new guidance claims that `/usr/sbin/ipctool` resolves to `extutils`, but this repository installs only `ipcinfo` and does not create the required symlink.

## Fix Focus Areas
- pr_compliance_checklist.yaml[220-227]
- best_practices.md[613-625]
- CLAUDE.md[162-164]
- .pr_agent.toml[158-164]

## Recommended Fix
State that `ipctool` is absent from images produced by this repository and therefore fails with command-not-found. Mention the dormant `extutils` download arm only conditionally, unless the repository is also changed to create the symlink intentionally.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Patch reviews rely on a false inventory 🐞 Bug ⚙ Maintainability
Description
The new patch gate states that every existing package patch targets a third-party upstream, but
libevent-openipc fetches OpenIPC/libevent and carries a patch against that fetched source. This
false premise appears in both reviewer guidance and a hard compliance criterion, so maintainers
cannot tell whether the existing package is a grandfathered exception or the new rule was defined
from an incomplete inventory.
Code

pr_compliance_checklist.yaml[R179-182]

+    success_criteria: >
+      A new *.patch sits in a package whose *_SITE names a third-party upstream. Every
+      patch in the tree today does — ffmpeg, mbedtls, vtund, libre, siproxd, zerotier,
+      libwebsockets, f2fs-tools, webrtc-audio-processing and the Realtek drivers.
Evidence
The package definition sets its source directly to https://github.com/OpenIPC/libevent, while the
adjacent patch modifies that source's CMakeLists.txt. This directly contradicts the newly added
assertion that no package patch targets an OpenIPC-organized repository.

general/package/libevent-openipc/libevent-openipc.mk[7-22]
general/package/libevent-openipc/0001-CMakeLists-remove-epoll_pwait2-check.patch[1-12]
best_practices.md[386-400]
pr_compliance_checklist.yaml[179-188]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new guidance claims no existing package patches an OpenIPC repository, despite `libevent-openipc` carrying exactly such a patch.

## Fix Focus Areas
- pr_compliance_checklist.yaml[172-190]
- best_practices.md[386-405]
- CLAUDE.md[157-159]
- .pr_agent.toml[87-91]

## Recommended Fix
Remove the claim that every current patch targets third-party code and define the prohibition prospectively for new patches. Identify `libevent-openipc` as existing debt or migrate its CMake change into the OpenIPC repository and bump the pinned version before retaining the absolute inventory claim.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
Review mode: ⚖️ Balanced: This is a substantial review-configuration change with multiple new gates and policy interactions, so its correctness warrants a complete single-pass review despite having no camera runtime changes.

Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +199 to +201
Every added file under general/overlay/ or a package's files/ directory is read at
its installed path by a script, init file, package, or configuration somewhere in
firmware, builder or majestic. Documentation and license text shipped on purpose

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Valid package sources fail review 🐞 Bug ≡ Correctness

The new reachability gate requires every added file under a package's files/ directory to be read
at an installed path, even when the file is a build-time source that has no installed path. Adding
another source like openipc_ethaddr.c, which is copied into the kernel tree and compiled there,
therefore cannot satisfy this hard compliance gate.
Agent Prompt
## Issue description
The shipped-file reachability gate treats every file under a package's `files/` directory as a runtime file, although that directory also contains build-time sources which are compiled rather than installed at their source path.

## Fix Focus Areas
- pr_compliance_checklist.yaml[192-208]

## Recommended Fix
Limit this gate to files actually installed into the target root filesystem. Explicitly exempt source, patch, and other build-time inputs that an existing build rule consumes, while leaving runtime overlay and package payload files subject to the installed-path reachability check.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +220 to +224
The diff calls, from a shipped script, a command no package installs. ipctool is
the specific trap: general/package/ipctool/ipctool.mk installs ipcinfo and nothing
else, so BR2_PACKAGE_IPCTOOL=y puts no "ipctool" on the image. /usr/sbin/ipctool
is a symlink to extutils, which curls the tool from the ipctool repository's
"latest" release into /tmp on first use — an interactive convenience, and in a

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Reviewers misdiagnose missing commands 🐞 Bug ≡ Correctness

The new command-availability gate says /usr/sbin/ipctool is a symlink to extutils, but neither
the overlay nor any installation rule creates that symlink. On images produced solely by this tree,
invoking ipctool fails immediately instead of reaching the documented download arm, so reviews
will attribute the failure to network timing and a floating release rather than the absent command.
Agent Prompt
## Issue description
The new guidance claims that `/usr/sbin/ipctool` resolves to `extutils`, but this repository installs only `ipcinfo` and does not create the required symlink.

## Fix Focus Areas
- pr_compliance_checklist.yaml[220-227]
- best_practices.md[613-625]
- CLAUDE.md[162-164]
- .pr_agent.toml[158-164]

## Recommended Fix
State that `ipctool` is absent from images produced by this repository and therefore fails with command-not-found. Mention the dormant `extutils` download arm only conditionally, unless the repository is also changed to create the symlink intentionally.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +179 to +182
success_criteria: >
A new *.patch sits in a package whose *_SITE names a third-party upstream. Every
patch in the tree today does — ffmpeg, mbedtls, vtund, libre, siproxd, zerotier,
libwebsockets, f2fs-tools, webrtc-audio-processing and the Realtek drivers.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. Patch reviews rely on a false inventory 🐞 Bug ⚙ Maintainability

The new patch gate states that every existing package patch targets a third-party upstream, but
libevent-openipc fetches OpenIPC/libevent and carries a patch against that fetched source. This
false premise appears in both reviewer guidance and a hard compliance criterion, so maintainers
cannot tell whether the existing package is a grandfathered exception or the new rule was defined
from an incomplete inventory.
Agent Prompt
## Issue description
The new guidance claims no existing package patches an OpenIPC repository, despite `libevent-openipc` carrying exactly such a patch.

## Fix Focus Areas
- pr_compliance_checklist.yaml[172-190]
- best_practices.md[386-405]
- CLAUDE.md[157-159]
- .pr_agent.toml[87-91]

## Recommended Fix
Remove the claim that every current patch targets third-party code and define the prohibition prospectively for new patches. Identify `libevent-openipc` as existing debt or migrate its CMake change into the OpenIPC repository and bump the pinned version before retaining the absolute inventory claim.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant