Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,24 @@ The rule that the **Issue URL** must belong to the same GitHub repository as the
The branch the work branches off and the pull request targets. Normally the branch checked out in the **Launch directory**; for an **Architect run** or a **Pickup run** whose command names a branch, that branch, whatever is checked out; for a **Ticket**'s **Run** in a **Spec run**, the **Spec branch**; in a **Continuation** with an open pull request, that pull request's base instead.

**Factory skills**:
The skills in `skills/`, loaded into the session as the `thirdshift` plugin: adapted copies of Matt Pocock's skills, designed to run headless with no human in the loop.
The skills in `skills/`, each named `thirdshift-<skill>` and placed in each **Run**'s worktree for its **Harness** to find: adapted copies of Matt Pocock's skills, designed to run headless with no human in the loop.
_Avoid_: the skills (ambiguous with `.claude/skills/`)

**Session prompt**:
The message thirdshift starts or resumes an agent session with. It carries the **Run**'s facts (issue, **Base branch**, **Issue branch**, pull request) and names the **Factory skills** to use. Written by thirdshift, not by a human.
_Avoid_: instructions, system prompt

**Harness**:
The headless agent CLI that runs every agent session of a **Command**: Claude Code (`claude`) or Codex (`codex`). One per Command, its child Runs and every **Resume** and **Repair** included. Chosen by the command, else the **User config**, else Claude Code.
_Avoid_: agent, provider, backend

**Model**:
The model the **Harness** runs its sessions on, such as Opus 5.5 or GPT-6.1-Sol. One per **Command**, chosen by the command, else the **User config**'s choice for that Harness, else the Harness's own default.

**Effort**:
How hard the **Model** reasons in each session, such as `high` or `max`. One per **Command**, chosen the way the Model is.
_Avoid_: reasoning level, thinking budget

**Standards finding**:
A finding from the Standards axis of a code review: the change breaks a documented coding standard or shows a baseline code smell.

Expand Down Expand Up @@ -126,7 +137,7 @@ A message thirdshift sends when a **Run**, a **Spec run** or an **Architect run*
_Avoid_: completion email, alert

**User config**:
The per-machine settings file in the user's home folder that sets thirdshift's defaults for every **Run** started on that machine, such as the **Run notification** address, whether every Run is a **Merge run**, whether a Run may start a **Base fix**, and whether a Run first brings the **Launch directory**'s checkout of the **Base branch** up to date with `origin`. With no User config, or one that says nothing about a setting, a Run does only what its command asks for.
The per-machine settings file in the user's home folder that sets thirdshift's defaults for every **Run** started on that machine, such as the **Run notification** address, whether every Run is a **Merge run**, whether a Run may start a **Base fix**, whether a Run first brings the **Launch directory**'s checkout of the **Base branch** up to date with `origin`, and the **Harness**, with a **Model** and **Effort** for each Harness. With no User config, or one that says nothing about a setting, a Run does only what its command asks for.

**Credentials**:
The per-machine secrets file next to the **User config**, readable only by its owner, that holds the Resend API key a **Run notification** is sent with. The key in the environment wins over it; it is what lets a **Run** started from cron, `nohup` or an agent's shell find the key. Only commands that send email read it, so the User config holds no secret.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Factory skills are linked into the worktree under a `thirdshift-` prefix, and Codex sessions run unsandboxed

A **Command** can now run its sessions on either **Harness**: Claude Code or Codex. Codex has nothing like `claude --plugin-dir`. It finds skills only when they are installed into `$CODEX_HOME`, or placed in a repository's `.agents/skills/`. So the **Factory skills** stop being loaded as a plugin for both harnesses. thirdshift writes the embedded skills out once per Command, links each into the Run's worktree (`.claude/skills/` for Claude, `.agents/skills/` for Codex), and keeps them out of git with a `.git/info/exclude` entry. Each skill is named `thirdshift-<skill>` in `skills/` itself (directory, frontmatter `name:`, and the skills' references to each other), so it can't collide with a repository's own skills of the same name, as this repository's `.agents/skills/code-review` would. A **Session prompt** loads its skill with the harness's sigil on its first line (`/thirdshift-implement` or `$thirdshift-implement`), and names the others in plain prose. This replaces the plugin consequence of ADR 0001.

Codex sessions, and every Resume of one, run with `--dangerously-bypass-approvals-and-sandbox`. `codex exec` never asks for approval, and on a stock Ubuntu machine its bubblewrap sandbox can't start (`kernel.apparmor_restrict_unprivileged_userns = 1`), which fails every command. A worktree's commits and pushes also need to write to the main repository's shared `.git`, outside the sandbox's writable root. The worktree is the only boundary, as it is for Claude's auto mode. Sources: `docs/research/codex-headless-harness.md`.

## Considered Options

- **A temporary `CODEX_HOME` holding the skills.** Rejected: it drops the user's `~/.codex/config.toml` and global `AGENTS.md`, breaks keyring auth, and a Resume must reuse the same home.
- **Keep the Claude plugin and link skills only for Codex.** Rejected: two mechanisms and two sets of skill names (`/thirdshift:x` and `thirdshift-x`) for the same skills.
- **Plain skill names.** Rejected: they collide with a target repository's own skills.
- **Rename the skills at write time.** Rejected: the embedded skills and the Prompts and skills page would not show the names sessions actually see.
- **`--approve-for-me` (workspace-write with an automatic reviewer).** Rejected for now: on a machine where the sandbox can't start, every command escalates. A sandboxed Codex mode, for machines where bubblewrap works, is a separate issue.

## Consequences

- `.git/info/exclude` is shared by every worktree of a repository. The `thirdshift-*` patterns are added once and left there. They are harmless.
- Each Codex session adds a permanent `trust_level = "trusted"` entry for the target repository's root to the user's `~/.codex/config.toml`.
- The user's Claude-only instructions and hooks (`~/.claude/`) don't reach Codex sessions. Codex reads `AGENTS.md`, and falls back to `CLAUDE.md` when the repository has none.
Loading
Loading