How does an AI agent find a project's conventions?
An agent runs in its home while CLAUDE.md sits in the checkout. The sub-run starts inside the project and pays for it with executable repo content.
A project writes its rules down in several places in the repository. CLAUDE.md says which command runs the tests. Under .claude/agents sit the project's subagents, next to them its skills and commands.
Open a terminal in the repository and all of it applies automatically.
An agent working alone at night opens no terminal. Its run starts in the task's scratch directory (/home/agent/scratch/<task-id>), and HOME points at /home/agent.
The source code sits elsewhere: into ~/repos/<project>-<ref>/ the GitLab plugin's checkout action unpacks it. Claude Code, however, looks for project memory relative to the working directory. From the home an agent sees none of that.
That costs twice over. On every heartbeat run the agent re-derives the project structure, with a fresh process and a capped turn budget. And the project's conventions have no effect on the result.
On Hacker News the question shows up in its everyday form. Under a thread about AI usage patterns in software teams, lukebitts wrote in August 2026 that following the codebase's conventions is rule number one in the team's claude.md, and that the model still needs reminding regularly.
The sub-run starts inside the checkout, with a frame and a budget of its own
RunSpec therefore separates working directory and home: WorkDir sets the subprocess's directory, HomeDir stays HOME.
On that separation the sub-run builds. It is a nested run of the same Claude Code adapter in the same sandbox, starting in the checkout, where it finds the project's harness in full. Through the dev:agent action the agent kicks it off, and the daemon executes it.
What covey adds to the prompt stays terse, so that the project's rules dominate. Three things the frame names. Target systems are out, pushing is out, and local commits in the checkout are fine. The frame asks for build and tests before anything is reported finished. The last message is the report: the cause, the changed places as file and line, the verification commands with their result, and what stayed open.
For the actual work the turn budget is larger. Without a value of its own a sub-run gets 60 turns and at most 200, while 30 is the default for the outer run.
The outer agent talks, the inner one programs
The division of roles is the core. Triage, communication, the commit, the merge request and memory stay with the outer run. The sub-run understands the code, changes it and verifies it with build and tests.
No target system is within its reach. COVEY_ACTION_PORT is missing from its environment, which puts ticket system and mail out of reach.
Out of that environment stay the daemon's own variables too. COVEY_WS_URL and COVEY_DAEMON_TOKEN would allow a WebSocket of one's own to the control plane, and with it a path to the credential broker, so the adapter filters them out. Afterwards the daemon fetches the file list with git calls, and those run the same way.
What comes back is a difference against a commit
With the upstream state as a baseline commit, the checkout creates a git repository and marks it with the tag covey-baseline. Against that commit the sub-run reports its work back, as changed_files and deleted. Those two lists are exactly what the outer agent's commit action expects.
Measurement runs against a commit rather than a snapshot taken earlier. The sub-agent may commit locally in the checkout, and many projects demand that in their CLAUDE.md. After a local commit git status shows nothing any more. Cumulative is what the lists therefore are: they describe the whole state against upstream, including an earlier sub-run's work on the same task.
But at most one sub-run runs per checkout. A second order in the same directory is refused while the first works, with the note to read its report. Orders in two different directories keep running alongside each other.
In the recording the sub-run stays a block of its own
The sub-run's lines flow into the same recording as the outer run's. Each line carries an extra key (covey_sub_agent) with the directory and an identifier for the run. Everything under one identifier the timeline folds into a single block: checkout, assignment, status, tool calls, turns, duration and cost in the header.
Cost travels the same path, and therefore through the same budget check. The cap gets coarser. Claude Code delivers total_cost_usd only with the result event, that is after up to 200 turns of the sub-run. A sub-run cannot get around the budget, though it can overshoot.
Repo content becomes code that runs
The price sits in the same place as the benefit. Auto-discovery is what makes the sub-run useful, and it loads executable configuration from the repository: hooks, MCP server definitions, skills, subagents. Together with --dangerously-skip-permissions that means repo content is code that runs in the sandbox. The outer run in the home never did that.
So target systems stay cleanly out of reach. Three things stay within reach: the brokered LLM key, the network within the egress allowlist, and the agent's home with its wiki working copy and the other checkouts.
In July 2026 a report about a take-home interview project with malware in its git hook reached 482 points on Hacker News. In the thread Groxx notes that a clone is harmless in itself (git hooks are not installed automatically) and wishes for a review requirement on hooks and executable configuration before they are run.
The sub-run does exactly the opposite, by design.
For repositories of your own organisation that is the right trade. For a foreign one the sub-run belongs behind an approval requirement or a ban through the guard rule on dev:agent, with the egress allowlist drawn tight. Today a finer switch is missing, one that loads the harness without hooks and MCP.