Files
doos/AGENTS.md
T

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)

  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/check-docs.sh (the release script does too: every document must link to every other, every relative link must resolve).
  5. Run scripts/release.sh <patch|minor|major> "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.
  6. Verify live: run build/doos once against the real thing (the e2e suite does this).
  7. 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.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.