Change the review fan-out from one subagent per commit to one subagent per
lens, each reviewing every commit through a single perspective. Four base
lenses (correctness/memory safety, lifetimes/concurrency, security, API/style)
always run; the orchestrator skims the diff and adds 1-3 PR-specific lenses
(e.g. a DNS protocol lens for resolved changes). A single generalist reviewer
tended to converge on one finding on large diffs; focused lenses dig deeper.
Commits are reviewed in chronological order via a commit-order.txt manifest,
since the SHA-named worktree dirs don't sort chronologically.
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
Bump the Bedrock model ID to us.anthropic.claude-opus-4-8 (the -v1 suffix
was dropped after 4.6), pin ANTHROPIC_DEFAULT_OPUS_MODEL so the review
subagents resolve to 4.8 as well, and switch the effort level from max to
xhigh.
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
arm64 hosts support running armv7 (armhf) binaries, so we can
cross compile and run the unit tests without performance issues.
armv7 (armhf) is a primary architecture on Ubuntu, so build
regressions block new version updates, and adding coverage
helps to avoid introducing regressions.
arm64 hosts support running armv7 (armhf) binaries, so we can
cross compile and run the unit tests without performance issues.
armv7 (armhf) is a primary architecture on Ubuntu, so build
regressions block new version updates, and adding coverage
helps to avoid introducing regressions.
This reverts commit 62e17483aa.
The failure should be caused by PATH_TEST() macro introduced by
fc7a32df38 and QMP_TEST() macro by
742733440f, and now they are dropped.
The workaround should not be necessary anymore.
lcov: ERROR: lcov: ERROR: (inconsistent) mismatched end line for test_path_exists_body at /home/runner/work/systemd/systemd/src/test/test-path.c:158: 158 -> 185 while capturing from build/mkosi.builddir/arch~rolling~x86-64/test-path.p/src_test_test-path.c.gcno
(use "lcov --ignore-errors inconsistent ..." to bypass this error)
Drop the standalone Unit-tests (musl) workflow that ran on an Alpine sandbox
spun up by jirutka/setup-alpine, and merge it into unit-tests.yml as a new
build-musl job that provisions a postmarketOS tools tree via mkosi and runs
the meson build + test suite through 'mkosi box'. postmarketOS is musl-native,
so the musl-gcc / -idirafter /usr/include wrappers the Fedora tools tree
needed are gone; the linter.yml's own musl build step also goes away since
the unit-tests workflow now covers it (and tests it).
postmarketOS doesn't ship a downstream systemd packaging spec, so the new
tools tree config in mkosi.tools.conf/mkosi.conf.d/postmarketos.conf does not
set PrepareScripts and lists build deps manually. mkosi.sync now early-exits
when PKG_SUBDIR is unset so the missing pkgenv entry doesn't trip set -u.
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
* 77fce77807 apk: Implement repository_key_fetch for the postmarketOS distribution
* 7068ed49ab postmarketos: Add ruff to tools tree
* dea4b6bfc8 Add newline when writing machine id into /etc/machine-id
* 944b775d40 tools: add libtss2-tcti-device0 to opensuse tools tree
* d856d65d3b mkosi-initrd: Also add cryptsetup-libs explicitly to the initrd
* 1cc967c5b3 mkosi-initrd: Trim orphaned GPU/audio modules, add ACPI platform attrs
* a3e95a7c29 mkosi-tools: Add fish to misc profile
* 76b02d1f84 mkosi-tools: Add jujutsu to misc profile
* 0afe4cd254 mkosi-tools: Move gh to misc profile
* 9077634bad mkosi-tools: Add cryptsetup-libs to centos/fedora/opensuse
* 82846347af box: Drop background tinting
* 3e50b97101 mkosi-tools: Add libfido2
* 78c2784827 vmspawn: Use --ephemeral rather than copy_ephemeral()
* dc801b00a3 Added second call to update kerneltype after kernel is defined
* 0c5cc04a8b vmspawn: Forward journal-remote settings to vmspawn
* 2518468c65 nspawn: Use --forward-journal instead of running journal-remote ourselves
* d2b798d00c apk: skip removal of packages that aren't installed
For some reasons, after util-linux is bumped from 2.41.4-r0 to 2.42-r0,
the 'su' command from util-linux-login seems to not correctly run commands in
https://github.com/jirutka/setup-alpine/blob/v1.4.1/alpine.sh
and causes the following spurious failure:
```
2026-05-15T21:19:15.6539432Z ##[group]Set up user runner
2026-05-15T21:19:15.6981963Z /bin/sh: line 0: ��: not found
2026-05-15T21:19:15.6982503Z /bin/sh: line 1: ␡ELF␂␁␁␃: not found
2026-05-15T21:19:15.6985788Z /bin/sh: line 10: ␒␐␆␒B␈␒�␄␒y␄␒�␁␒␞␇␒:␁␒�␃␒�␄␒@␁␒9␈␒?␆␒␚␈␒x: not found
2026-05-15T21:19:15.7010731Z /bin/sh: line 33: can't open ␂␒-␂␒�: no such file
2026-05-15T21:19:15.7016026Z /bin/sh: line 33: syntax error: unexpected word (expecting ")")
2026-05-15T21:19:15.7049583Z
2026-05-15T21:19:15.7050199Z ␛[1;31mError occurred at line 338:␛[0m
2026-05-15T21:19:15.7050830Z 335 | echo 'permit nopass keepenv $SUDO_USER' | tee /etc/doas.d/root.conf
2026-05-15T21:19:15.7051287Z 336 | fi
2026-05-15T21:19:15.7051549Z 337 | SHELL
2026-05-15T21:19:15.7052039Z ␛[1;31m> 338 | abin/"$INPUT_SHELL_NAME" --root /.setup.sh␛[0m
2026-05-15T21:19:15.7052506Z 339 |
2026-05-15T21:19:15.7052796Z 340 | rm .setup.sh
2026-05-15T21:19:15.7053172Z 341 | endgroup
2026-05-15T21:19:15.7096322Z ##[error]Error occurred at line 338: abin/"$INPUT_SHELL_NAME" --root /.setup.sh (see the job log for more information)
2026-05-15T21:19:15.7101400Z ##[error]Process completed with exit code 1.
```
Let's not install the package. It seems no command provided by the
package is used.
The cdn mirror is preferred by SUSE for clouds/CIs. There have been issues with some
mirrors, which fail to download from GHA quite often lately, so hopefully this will
make it reliable again.
Checking for pefile required that module to be made available for the
Python used to build systemd, even though it's only used at runtime,
potentially via a different Python installation.
Furthermore, Meson's Python module doesn't do the right thing when cross
compiling and looking up a Python for the host system, so this would end
up uselessly checking whether the build Python had the pefile module,
which is not needed. Even if it were made to check the host Python using
find_program, it still relies on being able to run its Python, which in
a cross scenario it probably wouldn't be able to do.
All in all, this check does more harm than good, and prevents building
ukify in valid configurations, so remove it.
Jammy's kernel is too old at this point, and doesn't even provide a
vmlinux.h, so disable the feature in the build smoketests to let us
add new features
Co-developed-by: Luca Boccassi <luca.boccassi@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
The user-facing components are the "systemd-importd.service" unit and
the "importctl" binary, so using these names makes more sense.
There _is_ a "systemd-import" binary, but it's in "/usr/lib/systemd/",
so this is a confusing name for a user-facing form.
Commit a65ebc3ff9 ("claude-review: improve review quality for large
PRs") dropped the `Claude: **<severity>**: ` prefix from posted inline
comments on the theory that Claude was also adding the severity into
`body`, producing duplicates. But nothing in the prompt or schema
actually asks the subagent to include severity in `body` — severity
is a separate structured field. The result is that inline comments
no longer show must-fix/suggestion/nit classification.
Restore the prefix in the posting step, and add an explicit instruction
to the subagent prompt telling it not to repeat severity inside `body`
so the two don't collide.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Opus 4.7 is in research preview on Bedrock and the Invoke API rejects
the beta headers Claude Code sends ("invalid beta flag"). Enable the
Mantle endpoint, which serves Claude via the native Anthropic API shape
and accepts those headers, and switch the model ID to the Mantle form
(no region prefix or version suffix).
- Use persist-credentials: false for actions/checkout, so we don't
leak the github token credentials to subsequent jobs.
- Remove one / from the Edit/Write permissions. Currently, with the
absolute path from github.workspace, we expand to three slashes while
we only need two.
Several issues were identified from analyzing logs of a large (52-commit) PR
review:
- Claude was batching multiple commits into a single review agent instead of
one per worktree. Strengthen the prompt to explicitly prohibit grouping.
- Claude was reading pr-context.json and commit messages before spawning
agents despite instructions not to, wasting time. Tighten the pre-spawn
rules to only allow listing worktrees/ and reading review-schema.json.
- Subagents were spawned with model "sonnet" instead of "opus". Add explicit
instruction to use opus.
- After agents returned, Claude spent 9 minutes re-verifying findings with
bash/grep/sed commands, duplicating the agents' work. Add instruction to
trust subagent findings and only read pr-context.json in phase 2.
- Subagents returned markdown-wrapped JSON instead of raw JSON arrays. Add
instruction requiring raw JSON output only.
- Each subagent was independently reading review-schema.json. Instead have
the main agent read it once and paste it into each subagent prompt.
- The "drop low-confidence findings" instruction was being used to justify
dropping findings that Claude itself acknowledged as valid ("solid cleanup
suggestions", "reasonable consistency improvement"). Remove the instruction.
- Simplify the deduplication instructions
- Stop adding the severity to the body in the post processing job as claude is
also adding it so they end up duplicated.
The main agent doesn't need to read pr-context.json until all
reviews have finished. This should prevent it from passing unnecessary
data from pr-context.json in the prompt to its subagents, which can just
read that file themselves when needed.
Replace claude-code-action with a direct claude CLI invocation. This
gives us explicit control over settings, permissions, and output
handling.
Other changes:
- Prepare per-commit git worktrees with pre-generated commit.patch and
commit-message.txt files, replacing the pr-review branch approach.
- Use structured JSON output (--output-format stream-json --json-schema)
instead of having Claude write review-result.json directly.
- Use jq instead of python3 for JSON prettification.
- Add timeout-minutes: 60 to the review job.
- List tool permissions explicitly instead of using a wildcard.
- Fix sandbox filesystem paths to use regular paths instead of the "//"
prefix.
The fix in 8f1751a111 made me wonder if we could automatically detect
when pointers are accessed but when this might not be safe. Systemd
is already using a lot of `assert(dst)` and this change now forces
us to use them.
So this commit (ab)uses coccinelle to flag any pointer parameter
dereference not preceded by assert(param), ASSERT_PTR(param), or an
explicit NULL check. It adds integration into meson as a new "coccinelle"
test suite (just like clang-tidy) and is run in CI. The check is not
perfect but seems a reasonable heuristic.
For this RFC commit it is scoped to a subset, it excludes 25 dirs right
now and includes around 100. About 300 warnings left. Busywork that I am
happy to do if there is agreement that it is worth it.
With this in place we would have caught the bug from 8f1751a111 in CI:
```
FAIL: check-pointer-deref.cocci found issues in systemd/src/boot:
diff -u -p systemd/src/boot/measure.c /tmp/nothing/measure.c
--- systemd/src/boot/measure.c
+++ /tmp/nothing/measure.c
@@ -312,7 +312,6 @@ EFI_STATUS tpm_log_tagged_event(
if (err != EFI_SUCCESS)
return err;
- *ret_measured = true;
return EFI_SUCCESS;
}
```
This also adds a new POINTER_MAY_BE_NULL() for the cases when the
called function will do the NULL check (like `iovec_is_set()`).
When doing large refactors or large changes the bot spams
labels left and right, making the PR unreadable. Use the
new option to limit the bot to a max of 5 file-based
labels. If more than 5 would be set, all file-based labels
are skipped.
Pass side, start_line, and start_side through to createReviewComment()
when present, enabling multi-line review comments. Update the prompt to
document all positioning fields using JSON Schema and make line required.
In https://github.com/systemd/systemd/pull/40980 claude hallucinated
and used "path" instead of "file" as the JSON key. Since "path" is
arguably more correct than "file" anyway, let's switch to that.
After analyzing all 218 CodeQL alerts across the project's history, the
workflow has not justified its CI cost:
- The most impactful query (PotentiallyDangerousFunction) was a custom
systemd-specific query that has already been replaced by clang-tidy's
bugprone-unsafe-functions check (6fb5ec3dd1).
- Of the remaining C++ queries, 6 never triggered at all
(bad-strncpy-size, unsafe-strcat, unsafe-strncat,
suspicious-pointer-scaling, suspicious-pointer-scaling-void,
inconsistent-null-check).
- Several high-value-sounding queries had extreme false positive rates:
toctou-race-condition (95% FP), use-after-free (88% FP),
cleartext-transmission (100% FP).
- Many queries that did trigger are already covered by compiler warnings
(-Wshadow, -Wformat, -Wunused-variable, -Wreturn-type,
-Wtautological-compare) or existing clang-tidy checks
(bugprone-sizeof-expression).
- Across all alerts, only 3 genuinely useful C++ fixes can be
attributed to CodeQL: 1 tainted-format-string, 2
incorrectly-checked-scanf. The rest were either false positives or
incidental fixes during refactoring that weren't prompted by CodeQL.
- The Python queries are largely superseded by ruff (already in CI) and
had an 89% false positive rate on the security-focused checks.
The workflow consumed significant CI resources (40+ minutes per run) and
the ongoing maintenance burden of triaging false positives outweighs the
marginal value of the 2-3 real findings it produced across its entire
lifetime.