cd /news/ai-agents/workspace-runtime-and-directories-de… · home topics ai-agents article
[ARTICLE · art-35767] src=ffacu.dev ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Workspace, Runtime, and Directories – Designing an Agent Orchestration Library

A developer is designing an agent-orchestration library with a three-directory structure separating artifacts, secrets, and workspaces. The system uses agent identifiers with a prefix, name, and unique letter to manage branches and directories. A subcommand copies credentials from the host into a shared secrets directory for automatic authentication in containers.

read6 min views1 publishedJun 21, 2026
Workspace, Runtime, and Directories – Designing an Agent Orchestration Library
Image: source

This is the first in a series of documents where I work through the architecture of an agent-orchestration library I'm building. This first one is about the environment in which the agent runs.

The problem with one workspace is that it forces very different kinds of things to live in the same place: the code the agent works on, the artifacts it produces that I want to look at, and the secrets I hand it.

For this I defined three directories:

.artifacts/
	agents/
		<agent-id>/
	common/
.secrets/
	agents/
		<agent-id>/
	common/
.workspaces/
	<repo>--<agent-id>/

With this split each kind of thing gets treated the way it actually needs to be, and the workspace is free to be whatever the agent needs without dragging secrets and artifacts along with it. Secrets can be made read only, so the agent can use them but not modify or delete them. Artifacts live on their own, separate from the workspace, so I can track them, diff them, or look at just what the agent produced without wading through every edit it made to get there.

Having a separate secrets directory makes credential handling simple. Secrets now have a known home, getting a credential to an agent is just a matter of putting the file in the right place, and the runtime knows where to look for it.

In practice it works like this:

  • An init --copy-credentials

subcommand reads the credentials I already have on my machine, the ones each tool writes to its own spot in my home directory (~/.claude/.credentials.json

,~/.codex/auth.json

,~/.config/gh/hosts.yml

, and so on), and stages copies in the common secrets directory so they're shared across agents. - When an agent starts in a container, the image looks for credentials first in /secrets/agent

, then in/secrets/common

, and copies whatever it finds back to the path the tool expects. So authentication just happens, without me logging in inside every container I spawn.

There's also a doctor

subcommand that checks for this and tells me when something's missing, like a provider with no auth file or no GitHub PAT.

The same mechanism handles environment variables. Drop an .env

file in the secrets directory and the runtime reads it and exports the values into the agent's session.

Agent Identifiers #

I wanted a quick way to tell whether a branch or workspace is owned by an agent at all, and if so, which one.

  • constant aiagent-

: A branch or directory that starts withaiagent-

is an agent's. I can spot it at a glance, filter for it (git branch | grep aiagent-

), or clean up agent workspaces by the prefix alone, without it ever being confused with a branch a person made. - name <agent-name>

: Names are readable and you choose them, which makes them the part you actually recognize when scanning a list. But I wanted something more, like an id. - letter <agent-letter>

: unique and auto-incremented, starting froma

, and never reused. Once you passz

it rolls over toaa

,ab

, and so on. The letter does two things the name can't:- It is guaranteed unique, so it disambiguates two agents that happen to share a name. It is short, which matters once it shows up in branch names, directory names, and everywhere else an agent gets referenced.

  • Letters are handed out in order, so a higher letter means a more recently created agent.

Put together, the id is:

aiagent-<agent-name>-<agent-letter>

The same three parts name the agent's branch, with /

instead of -

, since that's how git namespaces branches:

aiagent/<agent-name>/<agent-letter>

So every agent branch lives under aiagent/

, which is what makes the "is this branch an agent's?" check trivial: it's any branch under that prefix.

Inside the agent directories the prefix is dropped, since everything there is already an agent's:

workspace:  .agents/.workspaces/<agent-name>-<agent-letter>/
artifacts:  .agents/.artifacts/agents/<agent-name>-<agent-letter>/
secrets:    .agents/.secrets/agents/<agent-name>-<agent-letter>/

The prefix only earns its place where agent work sits next to human work, like git branches. In a directory that already holds nothing but agents, aiagent-

would just be noise.

Agent Environment #

  • workspace: where the code lies
  • runtime: where the agent lies

Workspace #

The workspace is the part that makes sure there is somewhere for the agent to work. In practice that means a few steps:

  • Directories: create the workspace and wire up the artifacts and secrets directories from before.
  • Git: clone or set up a worktree, create the branch, and so on.
  • Skills wiring: skills are just files, so they get linked into the agent's environment. I'll go into this in a later document.
  • on_provision: a hook for any custom commands the user wants to run when the workspace is set up.

Step 1: Artifacts and Secrets

The artifacts and secrets live outside the workspace, in the shared .artifacts

and .secrets

trees from before. The agent needs to reach them from inside its workspace, and the way it reaches them can't depend on where it's running.

On a container I can mount the directories, so the agent sees them at a path like /artifacts

and /secrets

. On the host there's no mount. The agent would have to climb out of its own workspace with something like ../../.artifacts/...

, which is ugly, and it broke during testing. Worse, those are two different paths, so the agent would need different instructions depending on which runtime it's in.

The fix is to give the agent one fixed path that works everywhere, and put the runtime difference underneath it. During provisioning the workspace creates four symlinks at a fixed location inside the workspace:

<workspace>/.agents/
    .artifacts/
        agent/   → this agent's artifacts
        common/  → shared artifacts
    .secrets/
        agent/   → this agent's secrets
        common/  → shared secrets

Each symlink resolves differently depending on the runtime. On the host it points up to the real shared tree (<repoRoot>/.agents/.artifacts/agents/<agent-name>-<agent-letter>/

). In a container it points to the mount (/artifacts/agent

). The agent only sees the fixed path, which it gets through environment variables:

AGENTS_ARTIFACTS_DIR        = <workspace>/.agents/.artifacts/agent
AGENTS_COMMON_ARTIFACTS_DIR = <workspace>/.agents/.artifacts/common
AGENTS_SECRETS_DIR          = <workspace>/.agents/.secrets/agent
AGENTS_COMMON_SECRETS_DIR   = <workspace>/.agents/.secrets/common

So the agent reads AGENTS_ARTIFACTS_DIR

and writes there, the same way in every environment.

Step 2: Git Modes

The git step changes depending on the mode. There are four:

clone

: a full clone of the repo.worktree

: a git worktree sharing the main repo, on its own branch.self

: no separate workspace, the agent works in the current repo as is.none

: a managed directory with no git repo at all, for agents that don't need a code repository.

The environment

decides where the workspace physically lives. There are two:

filesystem

: the workspace is a directory on the hostdocker

: the code lives inside a docker volume instead.

Not every mode is valid in every environment:

env \ mode worktree clone self none
filesystem
docker ✗ (host-only) ✗ (no "self" in a container)

Runtime #

The runtime is the environment the agent process actually runs in. There are two we care to support:

  • host: the agent runs as a subprocess in the main environment.
  • container (docker): the agent runs inside a docker container.

This covers the environment: the directories that keep the agent's different concerns apart, the identifiers that make agent-owned work recognizable, and the workspace and runtime that get an agent ready to run.

The next thing is how you actually drive all this, the config that declares the agents and the commands that bring them up (agents init

, then agents provision atlas

, agents start atlas

). That's the next document.

── more in #ai-agents 4 stories · sorted by recency
── more on @github 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/workspace-runtime-an…] indexed:0 read:6min 2026-06-21 ·