# AGENTS.md Rules for any AI agent (or human) changing this repository. The user's global rules also apply; this file adds the project-specific ones. Keep this file current: it is part of every release. ## Project in one paragraph `doos` is a user-level container tool in C++20. `attach` builds a user + mount + pid + uts + ipc (+ net) namespace set, overlays either the host's `/usr`, `/opt` (host mode) or an extracted image (image mode) with a per-container upper dir, pivots into it and runs a command. Networking is slirp4netns or pasta, ids are mapped through newuidmap when possible, cgroup v2 limits and a watchdog enforce `--memory --pids --cpus --size`, capabilities and seccomp confine the command. No root at runtime. Authoritative behavior: `SPEC.md`. Design notes: `docs/ARCHITECTURE.md`. Measurements and gaps: `docs/RESEARCH.md`. ## Mandatory release workflow (every change, same session) 1. Make the change. Smallest diff that does what was asked. 2. Update docs in the same change (see the table below). 3. Pick the bump: - `patch`: bug fix, docs, tests, tooling, no behavior change for users. - `minor`: new or changed user-visible behavior (flag, command, mount, limit). - `major`: breaking change to CLI, state layout, or container compatibility. 4. Run `scripts/release.sh "imperative commit subject"`. It bumps `VERSION`, builds, runs `tests/run.sh`, commits all changes, and creates the annotated tag `vX.Y.Z`. It aborts on any build or test failure. 5. Verify live: run `build/doos` once against the real thing (the e2e suite does this). 6. Report honestly what passed and what did not. Do not push unless the user asks. Never hand-edit `VERSION` or create tags manually. Never skip the tests to release. ## Docs that must be updated with the code | If you change | Update | |---|---| | CLI commands, flags, output | `README.md`, `SPEC.md` (CLI), `src/cli.cpp` usage text | | Limits or constants in `src/spec.hpp` | `SPEC.md` limits/layout tables (both must match) | | Mounts, namespaces, isolation | `SPEC.md`, `docs/ARCHITECTURE.md`, `docs/RESEARCH.md` host safety section | | Networking | `SPEC.md`, `docs/RESEARCH.md` networking table | | Source files added/removed/renamed | `docs/ARCHITECTURE.md` file map, `CMakeLists.txt`, this file | | A new measurement | `docs/RESEARCH.md` with machine, kernel, and what was run | | A new known gap or a closed gap | `docs/RESEARCH.md` gaps list and `README.md` | | These workflow rules | this file | | Image catalog, sources, verification, pinned keys | `SPEC.md` Images, `README.md`, `docs/RESEARCH.md` | | Seccomp list, capability set, `/etc` allowlist | `SPEC.md` Hardening and filesystem, `README.md`, `docs/RESEARCH.md` | | Limits, cgroup layout | `SPEC.md` Resource limits, `docs/ARCHITECTURE.md` | | Anything above, in every release | `README.md` version line and `CHANGELOG.md` entry | Docs describe what the system does today. No roadmap text. A gap is listed next to what would close it. A number in the docs needs a run behind it, else say it is unmeasured. ## Changelog Every release adds a `CHANGELOG.md` entry (newest first): version, date, bullets of what changed for users. The release script does not write it; write it before running the script. ## Code rules - C++20, extremely object oriented: one class per responsibility (see file map). - Every limit is a named constant in `src/spec.hpp` and listed in `SPEC.md`. - No unbounded loops, sizes or recursion. Add a cap when you add a loop. - Destructive operations: dry-run by default, `--yes` to act, scoped to the store. - Fail loudly with a clear message. Never swallow an error that leaves state half-built. - Match surrounding style. No new dependencies without a stated reason. - Never use em dashes (U+2014) anywhere. The release script rejects them. - Output must stay readable on a narrow terminal. ## Testing `tests/run.sh [path/to/doos]` runs the real path: real overlayfs, namespaces, slirp4netns, filesystem, real downloads of the Alpine and Ubuntu images, real apt/apk installs, the size freeze (about 4 minutes in total, needs network, `pasta`, `gpg` and cgroup v2 delegation). Add a case for every behavior change. A green run is required before release. On Ubuntu 24.04+ the AppArmor profile in `apparmor/doos` must be installed once for the binary being tested (`doos apparmor`; needs sudo, ask the user, do not do it yourself). ## Environment notes - State dir: `$DOOS_HOME`, else `$XDG_DATA_HOME/doos`, else `~/.local/share/doos`. Tests use a temp `DOOS_HOME`; never point tests at the user's real store. - Build: `cmake -S . -B build && cmake --build build`. - Requirements: Linux >= 5.11, `slirp4netns` for the default network mode.