diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md deleted file mode 100644 index 193935f3e6..0000000000 --- a/.github/copilot-instructions.md +++ /dev/null @@ -1,53 +0,0 @@ -# systemd AI Coding Agent Instructions - -## Project Overview - -systemd is a system and service manager for Linux, written in C (GNU17 with extensions). The project is built with Meson and consists of ~140 components including PID 1, journald, udevd, networkd, and many other system daemons. - -## Key Files & Directories - -Always include the following files in the context: - -- [code organization details](../docs/ARCHITECTURE.md) -- [development workflow deep dive](../docs/HACKING.md) -- [full style guide](../docs/CODING_STYLE.md) - -Include any other files from the [documentation](../docs) in the context as needed based on whether you think it might be helpful to solve your current task or help to review the current PR. - -## Build + Test instructions - -**CRITICAL: Read and follow these instructions exactly.** - -- **NEVER** compile individual files or targets. **ALWAYS** run `mkosi -f box meson compile -C build` to build the entire project. Meson handles incremental compilation automatically. -- **NEVER** run `meson compile` followed by `meson test` as separate steps. **ALWAYS** run `mkosi -f box meson test -C build -v ` directly. Meson will automatically rebuild any required targets before running tests. -- **NEVER** invent your own build commands or try to optimize the build process. -- **NEVER** use `head`, `tail`, or pipe (`|`) the output of build or test commands. Always let the full output display. This is critical for diagnosing build and test failures. -- When asked to build and test code changes: - - **CORRECT**: Run `mkosi -f box -- meson test -C build -v ` (this builds and runs tests in one command) - - **WRONG**: Run `mkosi -f box -- meson compile -C build` followed by `mkosi -f box -- meson test -C build -v ` - - **WRONG**: Run `mkosi -f box -- meson compile -C build src/core/systemd` or similar individual target compilation - - **WRONG**: Run `mkosi -f box -- meson test -C build -v 2>&1 | tail -100` or similar piped commands - -## Pull Request review instructions - -- Focus on making sure the coding style is followed as documented in `docs/CODING_STYLE.md` -- Only leave comments for logic issues if you are very confident in your deduction -- Frame comments as questions -- Always consider you may be wrong -- Do not argue with contributors, assume they are right unless you are very confident in your deduction -- Be extremely thorough. Every single separate coding style violation should be reported - -## Testing Expectations - -- Unit tests for self contained functions with few dependencies -- Integration tests for system-level functionality -- CI must pass (build + unit + integration tests) -- Code coverage tracked via Coveralls - -## Integration with Development Tools - -- **clangd**: Use `mkosi.clangd` script to start a C/C++ LSP server for navigating C source and header files. Run `mkosi -f box -- meson setup build && mkosi -f box -- meson compile -C build gensources` first to prepare the environment. - -## AI Contribution Disclosure - -Per project policy: If you use AI code generation tools, you **must disclose** this in commit messages and PR descriptions. All AI-generated output requires thorough human review before submission. diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 0000000000..79762a5d7c --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,62 @@ +# Integrates Claude Code as an AI assistant for issues and pull requests. +# Mention @claude in any issue comment, PR review comment, or PR review to +# interact with it, or assign the "claude" user to an issue. Claude +# authenticates via AWS Bedrock using OIDC — no long-lived API keys required. + +name: Claude Code + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + +jobs: + claude: + runs-on: ubuntu-latest + + if: | + github.repository_owner == 'systemd' && + ((github.event_name == 'issue_comment' && + contains(github.event.comment.body, '@claude') && + contains(fromJSON('["MEMBER","OWNER","COLLABORATOR"]'), github.event.comment.author_association)) || + (github.event_name == 'pull_request_review_comment' && + contains(github.event.comment.body, '@claude') && + contains(fromJSON('["MEMBER","OWNER","COLLABORATOR"]'), github.event.comment.author_association)) || + (github.event_name == 'pull_request_review' && + contains(github.event.review.body, '@claude') && + contains(fromJSON('["MEMBER","OWNER","COLLABORATOR"]'), github.event.review.author_association)) || + (github.event_name == 'issues' && + github.event.action == 'assigned' && + github.event.assignee.login == 'claude')) + + permissions: + contents: read # Read repository contents + issues: write # Post comments on issues + pull-requests: write # Post comments and reviews on PRs + id-token: write # Authenticate with AWS via OIDC + actions: read # Access workflow run metadata + + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + fetch-depth: 1 + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 + with: + role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_ROLE_NAME }} + role-session-name: GitHubActions-Claude-${{ github.run_id }} + aws-region: us-east-1 + + - name: Run Claude Code + uses: anthropics/claude-code-action@1fc90f3ed982521116d8ff6d85b948c9b12cae3e + with: + use_bedrock: "true" + github_token: ${{ secrets.GITHUB_TOKEN }} + claude_args: | + --model us.anthropic.claude-opus-4-6-v1 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000000..6d57417555 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,171 @@ +# AGENTS.md + +This file provides guidance to AI coding agents when working with code in this repository. + +## Project Overview + +systemd is a system and service manager for Linux, written in C (GNU17 with extensions). The project is built with Meson and consists of ~140 components including PID 1, journald, udevd, networkd, and many other system daemons. + +## Key Documentation + +Always consult these files as needed: + +- `docs/ARCHITECTURE.md` — code organization and component relationships +- `docs/HACKING.md` — development workflow with mkosi +- `docs/CODING_STYLE.md` — full style guide (must-read before writing code) +- `docs/CONTRIBUTING.md` — contribution guidelines and PR workflow + +## Build and Test Commands + +**CRITICAL: Read and follow these instructions exactly.** + +- **NEVER** compile individual files or targets. **ALWAYS** run `mkosi -f box -- meson compile -C build` to build the entire project. Meson handles incremental compilation automatically. +- **NEVER** run `meson compile` followed by `meson test` as separate steps. **ALWAYS** run `mkosi -f box -- meson test -C build -v ` directly. Meson will automatically rebuild any required targets before running tests. +- **NEVER** invent your own build commands or try to optimize the build process. +- **NEVER** use `head`, `tail`, or pipe (`|`) the output of build or test commands. Always let the full output display. This is critical for diagnosing build and test failures. + +```sh +# Initial setup (one-time) +mkosi -f genkey +mkosi -f box -- meson setup build + +# Build everything +mkosi -f box -- meson compile -C build + +# Run a specific unit test (also rebuilds as needed) +mkosi -f box -- meson test -C build -v + +# Run all unit tests +mkosi -f box -- meson test -C build --print-errorlogs -q + +# Build and boot an OS image for integration testing +mkosi -f box -- meson compile -C build mkosi +mkosi boot # nspawn +mkosi vm # qemu +``` + +- **CORRECT**: `mkosi -f box -- meson test -C build -v ` +- **WRONG**: Separate compile then test steps +- **WRONG**: `mkosi -f box -- meson compile -C build src/core/systemd` (individual target) +- **WRONG**: `mkosi -f box -- meson test -C build -v 2>&1 | tail -100` (piped output) + +## Code Architecture + +### Shared Code Dependency Hierarchy (strict layering) + +``` +src/fundamental/ → no dependencies (used in EFI + userspace) + ↑ +src/basic/ → depends only on fundamental (userspace only) + ↑ +src/libsystemd/ → depends on basic + fundamental (public libsystemd.so) + ↑ +src/shared/ → depends on all above (libsystemd-shared-.so) + ↑ +src// → individual daemons and tools +``` + +Code should be linked as few times as possible. Place shared code at the lowest possible layer. + +### Key Components + +- `src/core/` — PID 1 service manager (system and user instances). Uses `systemd-executor` for process spawning via `posix_spawn()` to avoid fork+exec pitfalls. +- `src/udev/` — udev daemon and udevadm tool +- `src/journal/` — journald logging daemon +- `src/network/` — networkd network manager +- `src/resolve/` — resolved DNS resolver +- `src/login/` — logind session manager +- `src/boot/` — systemd-boot EFI bootloader +- `src/systemctl/`, `src/journalctl/`, `src/analyze/` — CLI tools + +### Unit Settings Implementation + +Adding a new unit setting requires changes in various places: +1. `src/core/load-fragment-gperf.gperf.in` + `src/core/load-fragment.c` — unit file parsing +1. `src/core/dbus-*.c` — D-Bus interface +1. `src/core/varlink-*.c` — Varlink interface +1. `src/shared/bus-unit-util.c` — client-side parsing for systemctl/systemd-run +1. `test/fuzz/fuzz-unit-file/` — add to fuzz corpus + +### Tests + +- **Unit tests**: `src/test/` — match source files (e.g., `src/test/test-path-util.c` tests `src/basic/path-util.c`). Use assertion macros from `tests.h` (`ASSERT_GE()`, `ASSERT_OK()`, `ASSERT_OK_ERRNO()` for glibc calls). +- **Fuzzers**: `src/fuzz/` for basic/shared code; next to component code otherwise. Input samples in `test/fuzz/`. +- **Integration tests**: `test/TEST-*` directories, run via systemd-nspawn or qemu. + +## Coding Style (Essential Rules) + +The full style guide is in `docs/CODING_STYLE.md`. Key rules: + +### Formatting +- 8-space indent (no tabs) for C; 4-space for shell scripts; 2-space for man pages (XML) +- ~109 character line limit +- Opening brace on same line: `void foo() {` +- Function parameters with double indent (16 spaces) when broken across lines +- Single-line `if` blocks without braces +- `/* comments */` for committed code; `//` reserved for temporary debug comments +- Pointer in return types: `const char* foo()` (star with type) +- Pointer in parameters: `const char *input` (star with name) +- Casts: `(const char*) s` (space before `s`, not after `*`) + +### Naming and Structure +- Structs: `PascalCase`; variables/functions: `snake_case` +- Return parameters prefixed `ret_` (success) or `reterr_` (failure) +- Command-line globals prefixed `arg_` +- Enum flags: use `1 << N` expressions, aligned vertically +- Non-flag enums: include `_FOO_MAX` and `_FOO_INVALID = -EINVAL` sentinels +- Commit messages: prefix with component name (e.g., `journal: `, `nspawn: `) + +### Error Handling +- Return negative errno values: `return -EINVAL` +- Use `RET_NERRNO()` to convert libc-style returns +- Combined log+return: `return log_error_errno(r, "Failed to ...: %m")` +- Use `SYNTHETIC_ERRNO()` for errors not from a called function +- Cast ignored errors to void: `(void) unlink("/foo/bar")` +- Always check OOM; use `log_oom()` in program code + +### Header Files +- Keep headers lean — prefer implementations in `.c` files +- Include the appropriate forward declaration header (`basic-forward.h`, `sd-forward.h`, `shared-forward.h`) instead of pulling in full headers +- Order: external headers (`<>`), then `sd-*` headers, then internal headers, alphabetically within each group +- No circular header dependencies + +### Memory and Types +- Use `_cleanup_free_` and friends for automatic cleanup +- Use `alloca_safe()`, `strdupa_safe()` instead of raw `alloca()`, `strdupa()` +- Never use `off_t`; use `uint64_t` instead +- Use `unsigned` not `unsigned int`; `uint8_t` for bytes, not `char` + +### Functions to Avoid +- `memset` → use `memzero()` or `zero()` +- `strcmp`/`strncmp` → use `streq()` / `strneq()` +- `strtol`/`atoi` → use `safe_atoli()`, `safe_atou32()`, etc. +- `basename`/`dirname` → use `path_extract_filename()` / `path_extract_directory()` +- `fgets` → use `read_line()` +- `exit()` → use `return` from main or `_exit()` in forked children +- `dup()` → use `fcntl(fd, F_DUPFD_CLOEXEC, 3)` +- `htonl`/`htons` → use `htobe32()` / `htobe16()` + +### File Descriptors +- Always use `O_CLOEXEC` / `SOCK_CLOEXEC` / `MSG_CMSG_CLOEXEC` / ... + +### Logging +- Library code (`src/basic/`, `src/shared/`): never log (except `LOG_DEBUG`) +- "Logging" functions log errors themselves; "non-logging" functions expect callers to log +- Non-fatal warnings: suffix with `, ignoring: %m"` or similar + +### Integration Tests +- Never use `grep -q` in pipelines; use `grep >/dev/null` instead (avoids `SIGPIPE`) + +## Pull Request Review Instructions + +- Focus on coding style compliance from `docs/CODING_STYLE.md` +- Only leave comments for logic issues if you are very confident in your deduction +- Frame comments as questions +- Always consider you may be wrong +- Do not argue with contributors; assume they are right unless you are very confident +- Be extremely thorough — every single coding style violation should be reported + +## AI Contribution Disclosure + +Per project policy: if you use AI code generation tools, you **must disclose** this in commit messages by adding e.g. `Co-developed-by: Claude `. All AI-generated output requires thorough human review before submission. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000000..47dc3e3d86 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +AGENTS.md \ No newline at end of file