5.4 KiB
AGENTS.md
Docs: README · SPEC · ARCHITECTURE · RESEARCH · COMPARISON · AGENTS · CHANGELOG
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. Design notes: ARCHITECTURE. Measurements and gaps: RESEARCH. Positioning against other tools: COMPARISON. Usage: README. History: CHANGELOG.
Mandatory release workflow (every change, same session)
- Make the change. Smallest diff that does what was asked.
- Update docs in the same change (see the table below).
- 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.
- Run
scripts/check-docs.sh(the release script does too: every document must link to every other, every relative link must resolve). - Run
scripts/release.sh <patch|minor|major> "imperative commit subject". It bumpsVERSION, builds, runstests/run.sh, commits all changes, and creates the annotated tagvX.Y.Z. It aborts on any build or test failure. - Verify live: run
build/doosonce against the real thing (the e2e suite does this). - 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 |
| A feature, limit or measurement that appears in the comparison tables | COMPARISON.md (tables, the gaps list, the conclusion) |
| A new or renamed markdown file | scripts/check-docs.sh DOCS list, the nav line (**Docs:**) of every document, README.md Project docs |
| 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.hppand listed inSPEC.md. - No unbounded loops, sizes or recursion. Add a cap when you add a loop.
- Destructive operations: dry-run by default,
--yesto 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 tempDOOS_HOME; never point tests at the user's real store. - Build:
cmake -S . -B build && cmake --build build. - Requirements: Linux >= 5.11,
slirp4netnsfor the default network mode.