From 9aa893221263a8e62af22b5d58634699c6e6b8e9 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 28 May 2026 01:45:44 +0200 Subject: [PATCH] github: add LLM review workflow and project rules Add a nightly LLM-driven PR review for the LuCI repo, calling the reusable workflow in actions-shared-workflows. The extra_repos list pre-clones LuCI's typical backends (rpcd, netifd, firewall4, ucode, uhttpd, packages, openwrt) so the routine can verify cross-repo references without re-cloning per PR. Also add .github/llm-review-rules.md with two project-specific rules the system prompt does not cover: redirecting PRs that touch out-of-tree luci-app-* packages, and checking that new UCI options have a backend consumer. Co-Authored-By: Claude Opus 4.7 (1M context) Signed-off-by: Hauke Mehrtens --- .github/llm-review-rules.md | 41 ++++++++++++++++++++++++++++++++ .github/workflows/llm-review.yml | 34 ++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 .github/llm-review-rules.md create mode 100644 .github/workflows/llm-review.yml diff --git a/.github/llm-review-rules.md b/.github/llm-review-rules.md new file mode 100644 index 0000000000..a543b90fcd --- /dev/null +++ b/.github/llm-review-rules.md @@ -0,0 +1,41 @@ +# LLM review rules — openwrt/luci + +LuCI-specific patterns to flag. The review routine reads this at +session start. General contribution rules (commit subject prefix, +Signed-off-by, real-name author, line length) live in +[`CONTRIBUTING.md`](../CONTRIBUTING.md) and are already enforced by +the formality CI bot — don't duplicate those checks. + +## Out-of-tree luci apps + +A few `luci-app-*` packages are maintained in their own repositories, +not in `openwrt/luci`. PRs that re-introduce or modify these in-tree +should be redirected upstream rather than reviewed line by line +(recurring example: PRs #8462 and #8625 against +`luci-app-https-dns-proxy`): + +- `luci-app-https-dns-proxy` --> https://github.com/mossdef-org/luci-app-https-dns-proxy + +When a PR's diff matches one of these package paths, flag it and link +the upstream repo. + +## Backend coupling across repos + +A new UCI option or service interaction in LuCI is only useful if a +backend actually reads it. Recurring failure mode (PRs #8498, #8533, +#8590): the LuCI frontend exposes an option whose name does not appear +in any backend, so the setting silently does nothing. + +When a PR adds a UCI field or RPC call, check that a consumer exists: + +- `luci-mod-network`, `luci-proto-*` --> `netifd` (and its proto + handler scripts under `/lib/netifd/proto/`) +- `luci-app-firewall` --> `firewall4` (`/usr/share/firewall4/`) +- `luci-app-` --> the `` package itself, usually in + `feeds/packages` or `feeds/routing` + +If the option name does not appear in any consumer (grep the relevant +`~/extra/-` tree), flag as "frontend-only with no backend +consumer" and ask which daemon or script reads it. When the change +depends on a not-yet-merged PR in another repo, that dependency should +be called out in the PR description. diff --git a/.github/workflows/llm-review.yml b/.github/workflows/llm-review.yml new file mode 100644 index 0000000000..3e60affab2 --- /dev/null +++ b/.github/workflows/llm-review.yml @@ -0,0 +1,34 @@ +name: LLM Review + +on: + schedule: + - cron: '0 4,16 * * *' + workflow_dispatch: + inputs: + max_prs: + description: 'Max PRs to review in this nightly run' + required: false + type: number + default: 16 + +permissions: {} + +concurrency: + group: ${{ github.workflow }}-nightly + cancel-in-progress: false + +jobs: + nightly: + if: (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.repository_owner == 'openwrt' + permissions: + pull-requests: read + uses: openwrt/actions-shared-workflows/.github/workflows/reusable_llm-nightly-digest.yml@main + with: + routine_id: ${{ vars.LLM_ROUTINE_ID_NIGHTLY }} + # LuCI PRs frequently touch backends served via rpcd/ubus, ucode + # handlers, fw4/netifd config surfaces, and packages from feeds. + # The routine clones each entry only when the diff calls for it. + extra_repos: openwrt/openwrt:main,openwrt/rpcd:master,openwrt/netifd:master,openwrt/firewall4:master,openwrt/uhttpd:master,jow-/ucode:master,openwrt/packages:master + max_prs: ${{ fromJSON(inputs.max_prs || '16') }} + secrets: + llm_routine_token: ${{ secrets.LLM_ROUTINE_TOKEN_NIGHTLY }}