Agent Sessions

Start a Claude or Codex session with the same instructions and build tools. Each task gets its own branch and checkout.

Prepare the environment

A Linux checkout, outside /tmp, needs the Rust pinned by rust-toolchain.toml, with rustfmt and clippy, a C compiler, Git, curl, shellcheck, bubblewrap and OpenSSH's server; musl-tools and the Rust musl target for the sandbox's release checks. JavaScript folders need Node 20.9 or newer and their own lock file. If the image has a read-only home directory, set CARGO_HOME, RUSTUP_HOME and npm's cache to writable directories in the environment configuration. The host supplies network access, its proxy and CA trust, and GitHub authorization.

What the sandbox's tests need

Link's sandbox on Linux stands on two things the machine provides: bubblewrap and Landlock.

Bubblewrap

Bubblewrap, with unprivileged user namespaces, makes every sandbox: its own view of the files, network and processes. Without it, the sandbox's tests skip, or fail with LNK_REQUIRE_SANDBOX=1. Install bubblewrap, or use an environment that allows user namespaces.

Landlock

Landlock (Linux 5.13 and newer, enabled) enforces finite executable allowlists, including a spec without [commands], which grants no programs. Without it, executable enforcement checks skip, saying why; unrestricted file and network checks, invalid specs and unsupported-policy refusal still run. Landlock is the kernel's: a container shares its host kernel, so it can't add it.

LNK_REQUIRE_SANDBOX=1

With LNK_REQUIRE_SANDBOX=1, tests fail if any required enforcement is unavailable, including ruleset installation after a successful probe. Never use a failing sandbox probe to claim a full test pass: this variable makes missing sandbox coverage fail.

What each test proves

Tests of file and network confinement use allow = ["*"] when they do not check executable restrictions; this is still a confined process. Executable tests require evidence from a running sandbox, since a refused launch does not prove kernel enforcement. Full sandbox coverage needs a Landlock-capable Linux machine or CI as well as an environment without it.

A client's own sandbox

If only the client's command sandbox blocks the probe, use that client's supported permission mechanism for sandbox tests.

OpenSSH's configuration

OpenSSH's ssh refuses a configuration (~/.ssh/config) owned by another user or writable by others, so the tests that run it need the image's to be the user's own and not writable by others.

Start a session

Codex reads the root and folder AGENTS.md files. Claude reads the same instructions through each CLAUDE.md's @AGENTS.md import. Framework-managed blocks in AGENTS.md stay intact.

Its task and its PR

Give the session a specific task and its completion criteria, a base branch, and a branch name of its own. It pushes at every natural point and opens a draft PR early, so the latest code is always on the branch.

When the work is complete

It marks the PR ready for review, brings in the latest base once and pushes, then runs the checks in Before you push once, and ticks the PR's first box, FULL CHECK, when they pass. Then it stops watching the PR, unless its next work waits on the merge: the maintainer merges. Work PRs into dev receive no CI, so these local checks are the proof.

Write a skill

A skill is a folder in .agents/skills/ holding a SKILL.md and any pages it links. Every session starts with each skill's description in its context, and reads the rest only when it loads the skill, so the description is paid for in every session and decides whether it's used.

The description

It says in one sentence what the skill holds, then when to load it, by the action or the user's words that call for it: "Load it before adding or upgrading any dependency". It holds no rules, and stays under about 250 characters.

The body

It opens with what the skill is for, then only what its task needs, linking a page for any fact a page already holds. Detail only some uses need, such as one role's rules, is a page beside SKILL.md that the body links, read only by that use.

What stays in AGENTS.md

A rule every task needs stays in AGENTS.md. One only some tasks need moves to a skill, leaving a line in AGENTS.md that names the skill when missing it would be costly.

Use separate worktrees

Each simultaneous task gets a branch and a checkout of its own.

git worktree add -b work/example .agents/worktrees/example origin/dev
cd .agents/worktrees/example
# After committing and pushing the task, from the main checkout
git worktree remove .agents/worktrees/example

Use a separate branch and checkout for each simultaneous task. Put manual worktrees under .agents/worktrees/, outside /tmp; Claude's native .claude/worktrees/ remains ignored too. Each worktree builds from cold. Never share one mutable checkout or build folder between unrelated worktrees.

Cloud authentication

Ordinary development uses tests and fakes, without cloud credentials. A session that makes real boxes signs the cloud CLIs in itself, from keys its environment holds; nothing in this repository holds or loads one.