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/exampleUse 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.