#OpenClaw has created two workspace dirs: `~/.openclaw/workspace/` and `~/clawd/` ... what to do

1 messages · Page 1 of 1 (latest)

steep spindle
#

It seems the canonical dir is ~/.openclaw/workspace/
Should I just move everything there?

stable cradleBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

steep spindle
#

There is valuable stuff in both

tidal tideBOT
#

~/.openclaw/workspace is the current default workspace path (unless you changed it in config, or you’re using a non-default OPENCLAW_PROFILE). Docs: https://docs.openclaw.ai/concepts/agent-workspace

I wouldn’t “move everything” blindly though — only one workspace is active, and it’s whatever your config points at:

openclaw config get agents.defaults.workspace
  • If that already says ~/clawd, then that’s your active workspace right now. You can keep using it and just ignore/cleanup the extra folder later.
  • If you want to standardize on the canonical default (~/.openclaw/workspace), do it like this:
    1. stop the gateway
    2. move/copy your workspace files (AGENTS.md/SOUL.md/USER.md/memory/, etc.) into ~/.openclaw/workspace
    3. set agents.defaults.workspace accordingly
    4. restart the gateway

Important: don’t mix this up with ~/.openclaw/ — that’s the state dir (config/credentials/sessions). You generally do not move that into the workspace. (Related FAQ note: migrating a machine requires copying both ~/.openclaw and the workspace.) https://docs.openclaw.ai/start/faq

#

If you paste the output of openclaw config get agents.defaults.workspace (and maybe ls -la ~/.openclaw/workspace ~/clawd), I can tell you which directory is actually being used.

#

If there’s valuable stuff in both, don’t do a blind “move everything” — you want to (a) pick one active workspace, then (b) merge the other into it, resolving conflicts intentionally.

What’s canonical today: ~/.openclaw/workspace is the default (unless you overrode it / profile). Docs: https://docs.openclaw.ai/concepts/agent-workspace

1) First: confirm which one OpenClaw is actually using

openclaw config get agents.defaults.workspace

Whatever that prints is the active workspace right now.

2) Recommended merge approach (safe)

Pick ~/.openclaw/workspace as the “final” target, then:

  1. Back up both folders (at least rename one so you can undo).
  2. Merge the obvious “append-only” stuff:
    • memory/ (usually safe to just copy/merge)
    • skills/, canvas/ (copy/merge)
#
  1. For root files that may differ, manually reconcile:
    • AGENTS.md, SOUL.md, USER.md, TOOLS.md, IDENTITY.md, HEARTBEAT.md

If you want a low-risk dry run for the merge, rsync is great:

rsync -avhn ~/clawd/ ~/.openclaw/workspace/
# remove -n once the output looks right

3) Then point OpenClaw at the one you chose

If you decide the winner is ~/.openclaw/workspace:

openclaw config set agents.defaults.workspace "~/.openclaw/workspace"
openclaw gateway restart

Important: don’t mix up workspace vs state

#

Don’t move ~/.openclaw/ into the workspace — ~/.openclaw/ is state (config/credentials/sessions). Workspace is just the agent “home” files. (FAQ touches this in the migration section too: https://docs.openclaw.ai/start/faq)

If you paste:

  • openclaw config get agents.defaults.workspace
  • ls -ლა ~/.openclaw/workspace ~/clawd | head


I can suggest the cleanest merge direction based on what’s actually in each.

tidal tideBOT
#

Perfect — that means OpenClaw is already using the canonical workspace right now, so you should treat:

  • active workspace: ~/.openclaw/workspace
  • extra/old workspace: ~/clawd (safe to archive/merge, but don’t “switch” to it unless you mean to)

If ~/clawd has valuable stuff, the clean move is: merge ~/clawd into ~/.openclaw/workspace (not the other way around), with a dry-run first:

# quick look
ls -la ~/clawd
ls -la ~/.openclaw/workspace

# dry-run merge (shows what would change)
rsync -avhn ~/clawd/ ~/.openclaw/workspace/

# then do it for real once it looks right
#
rsync -avh ~/clawd/ ~/.openclaw/workspace/

Notes:

  • memory/ is usually the big one to merge (generally “append-y”).
  • For root files like AGENTS.md, SOUL.md, USER.md, etc., expect conflicts — open both and manually reconcile if needed.
  • Don’t move anything from ~/.openclaw/ (that’s state: config/credentials/sessions), only workspace files.

After you’ve confirmed everything’s in ~/.openclaw/workspace, you can archive the old folder (I’d rename or trash, not delete):

mv ~/clawd ~/clawd-archive
# or: trash ~/clawd   (if you have trash installed)

If that clears it up, please mark the solution message in the thread (right-click → Apps → ✅ Mark Solution) so Answer Overflow indexes it.

steep spindle
#

any idea how working in ~/clawd happened? was that used by an older version?

tidal tideBOT
#

Yeah — ~/clawd is basically a historical artifact.

What likely happened:

  • Early Clawdbot/“Clawd” era a bunch of examples / community setups used ~/clawd as the “workspace repo” path (easy to see + git-init), and the setup/onboarding flow will happily create + seed whatever workspace path is configured at the time.
  • Later the project standardized on the cleaner default ~/.openclaw/workspace (keeps “agent memory” under the OpenClaw state umbrella, works better with profiles, etc.). Docs now call that the default: https://docs.openclaw.ai/concepts/agent-workspace

So at some point you probably had your workspace configured as ~/clawd (maybe via an older wizard/default, or you copy/pasted an older config snippet), OpenClaw created it and wrote the bootstrap files there — and then you (or openclaw doctor / re-onboarding) switched to ~/.openclaw/workspace, leaving ~/clawd behind.

If you want to confirm, paste:

  • openclaw --version
  • and the workspace-related part of ~/.openclaw/openclaw.json (just the agent/agents workspace keys; redact anything sensitive)


and I can tell you if you’ve got any legacy agent.workspace vs agents.defaults.workspace history going on.

steep spindle
tidal tideBOT
#

That’s almost certainly config drift: the “main” agent is pinned to one workspace, while the other agent entries (the ones you’re calling “subagents”) still have an older workspace override.

In OpenClaw there are two different concepts that often get conflated:

  • Subagent sessions (spawned for a task) still run under some agentId
  • Multiple agents (configured under agents.list) can each have their own workspace

So if those “subagents” are actually separate configured agents, they’ll use whatever is set on that agent entry (or whatever the defaults were at the time they were created).

Quick way to see what’s going on

Run these and paste the outputs:

openclaw config get agent.workspace
openclaw config get agents.defaults.workspace
openclaw config get agents.list
#

What I expect you’ll find is either:

  • agents.list: [{ id: "...", workspace: "~/clawd" }, ...] for those extra agents, or
  • an old agents.defaults.workspace: "~/clawd" lingering while agent.workspace was set to ~/.openclaw/workspace

Fix (if you want everything to use ~/.openclaw/workspace)

  • Set the default:
    openclaw config set agents.defaults.workspace "~/.openclaw/workspace"
    
  • Then remove per-agent workspace overrides (preferred) or change them to match. Easiest is usually editing ~/.openclaw/openclaw.json in the Control UI “Raw JSON” editor and deleting the workspace fields under those agents.

After that, openclaw gateway restart to make sure everything is using the new paths consistently.

Docs that describe this model:

steep spindle
tidal tideBOT
#

Yep — that error is expected on 2026.2.x.

agent.workspace is not a valid config key anymore (some older examples/docs used agent: { 
 }, but current schema uses agents), so openclaw config get agent.workspace will always say “path not found”.

What you want instead is:

  • Default workspace (what agents inherit):

    openclaw config get agents.defaults.workspace
    
  • Per-agent overrides (why some of your agents still use ~/clawd):

    openclaw config get agents.list
    

    Then look for workspace entries inside each agent object. Any agent with workspace: "~/clawd" (or similar) will keep using that until you remove/change it.

#

How to unify them

Edit ~/.openclaw/openclaw.json and either:

  • remove workspace from those agents.list[] entries so they inherit agents.defaults.workspace, or
  • set each one explicitly to ~/.openclaw/workspace (if you really want them all sharing one workspace).

After editing:

openclaw doctor
openclaw gateway restart

Docs for the “current” shape are here:

If you paste your openclaw config get agents.list output (you can redact anything sensitive), I can tell you exactly which entries to change.

steep spindle
tidal tideBOT
#

Totally valid — multiple agents should usually have separate workspaces. The “canonical” bit just means the default if you don’t override anything is ~/.openclaw/workspace.

So if you already have something like:

  • ~/clawd/main/
  • ~/clawd/coding/
  • ~/clawd/home/
  • 



and each agent in agents.list[] points at its own folder, that’s a perfectly sane setup.

The only real “problem” is when you have:

  • two different folders that both look like the active workspace for the same agent, or
  • a mix of defaults/overrides that makes it unclear where an agent is writing.

If you want to keep your current layout, I’d just do two things:

#
  1. Make sure every non-main agent has an explicit workspace in agents.list[] (so you’re not accidentally inheriting agents.defaults.workspace).
  2. Optionally rename the root from ~/clawd to something less lore-ish (purely for human clarity), but not required.

If you ever want to align with docs conventions later, a common pattern is:

But yeah: separate workspaces per agent is good, and your current “separate folders inside ~/clawd” is already accomplishing that.

steep spindle
#

my question is then, should the one agent (the main) also be moved inside ~/clawd with the others?

#

he's in .openclaw/workspace/ rn

tidal tideBOT
#

You can, but you don’t need to.

Keeping main in ~/.openclaw/workspace is totally fine (it’s the documented default), and it has one nice property: if you ever remove your multi-agent config temporarily, OpenClaw “just works” with the default workspace path.

Move it under ~/clawd only if you want organizational consistency (e.g. “all agent workspaces live under one parent folder”), and you’re happy diverging from the default.

If you do move it, I’d strongly recommend:

  1. Give main an explicit workspace in agents.list[] (so it’s not “special” / implicit)
  2. Keep agents.defaults.workspace as a sensible default for any future agents you forget to set a workspace for.

Example pattern:

  • main → ~/clawd/main
  • coding → ~/clawd/coding
  • etc.

Then just move the folder contents + update config, and restart:

#
openclaw gateway restart
openclaw doctor

(And just to be clear: you’re only moving the workspace folder(s), not anything under ~/.openclaw/.)

If you paste your openclaw config get agents.list (redact anything sensitive), I can point out the exact place to add workspace for the main agent so it’s consistent with the others.

#

Nope — if main is already in ~/.openclaw/workspace and things are working, leaving it there is perfectly fine (it’s the documented default and tends to reduce surprises later).

Move main under ~/clawd only if you want “all agent workspaces under one parent folder” for your own organization. It won’t make OpenClaw happier either way.

If you do want to move it for consistency, the clean way is:

  1. Stop gateway
  2. Copy/merge (dry-run first), e.g.
    rsync -avhn ~/.openclaw/workspace/ ~/clawd/main/
    # then without -n
    rsync -avh  ~/.openclaw/workspace/ ~/clawd/main/
    
  3. Edit ~/.openclaw/openclaw.json and set main’s entry in agents.list[] to workspace: "~/clawd/main" (so it’s explicit like your other agents)
  4. Restart gateway

If you paste your openclaw config get agents.list (redact anything sensitive), I can tell you exactly where to add the main workspace field.

steep spindle
#

ok so the real issue is that there is a memoty folder in both dirs. my agent startled me when he couldn't recall an ongoing project

#

do multiple memory folder cause this? how to fix?

tidal tideBOT
#

That symptom makes sense: memory is per-agent, per-workspace.

OpenClaw’s semantic recall indexes Markdown inside the active agent’s workspace — basically MEMORY.md + memory/**/*.md for that agent (docs: https://docs.openclaw.ai/concepts/memory). So if you have:

  • ~/.openclaw/workspace/memory/... (main agent’s memory)
  • ~/clawd/<other-agent>/memory/... (other agents’ memory)


then the main agent will not “see” the other agent’s memory unless you manually copy it over (or configure extra paths).

Why it “forgot” an ongoing project

Usually one of these:

  1. The project notes got written into the other workspace’s memory/ folder (different agent).
  2. You moved/changed workspaces at some point, so the project notes are sitting in the “old” memory/.
  3. You asked in a Discord channel/thread: by default MEMORY.md is not injected in group contexts (to avoid leaks), so you’re relying on memory search / the daily log.

Fast fix

Decide which agent “owns” that project (sounds like main), then copy/merge the relevant markdown from the other memory folder into:

#

~/.openclaw/workspace/memory/ (and/or summarize into ~/.openclaw/workspace/MEMORY.md)

Then force a reindex for that agent and verify recall:

openclaw memory index --agent main --verbose
openclaw memory search --agent main "project name"

(You can also run openclaw memory status --deep --agent main to sanity-check the index.)

Once you do that, the “can’t recall project” jumps usually stop — because you’ve made the project notes land in the same workspace that agent is indexing.

#

Yeah — having multiple memory/ folders across different workspaces can absolutely lead to this kind of “why can’t you recall X?” moment, but it’s not that memory is “conflicting”; it’s that memory is scoped to the agent + its workspace.

What’s happening

  • Each agent indexes its own workspace: MEMORY.md + memory/**/*.md inside that workspace. Docs: https://docs.openclaw.ai/concepts/memory
  • So if “Project Alpha” notes are in ~/clawd/some-agent/memory/... but you’re chatting with the main agent whose workspace is ~/.openclaw/workspace, main simply won’t see them.

Fix options (pick one)

Option A (recommended): move/merge the project notes into the “owner” agent’s workspace

  1. Find where the notes actually are:
    rg -n "Project Alpha" ~/.openclaw/workspace ~/clawd
    
  2. Copy/merge the relevant markdown into the main agent’s:
    • ~/.openclaw/workspace/memory/....md and/or summarize into ~/.openclaw/workspace/MEMORY.md
  3. Reindex and verify:
#
   openclaw memory index --agent main --verbose
   openclaw memory search --agent main "Project Alpha"

Option B: keep separate workspaces, but let an agent index “extra paths”
If you want main to be able to recall notes stored under another folder, add those folders as extra indexed paths via memorySearch.extraPaths (see “Additional memory paths” in the memory doc). This is handy for a “shared projects” folder, but you’re trading off isolation/cleanliness.

Option C: make multiple agents share one workspace
Works, but usually defeats the point of multi-agent separation (and increases accidental cross-contamination), so I wouldn’t unless you’re intentionally running them as “one brain”.

Sanity check (worth doing once)

If memory search itself is misconfigured (embeddings not available), recall will look broken even if files are in the right place:

openclaw memory status --deep --agent main
#

If you paste (redacting anything sensitive):

  • openclaw config get agents.list
  • openclaw memory status --deep --agent main


I can tell you whether this is purely “notes in the other workspace” vs “memory indexing not actually running”.

steep spindle
#

is it best practice to separate agent workspaces?

tidal tideBOT
#

Yes — if you’re using agents.list (multi-agent), separate workspaces is the intended / best-practice setup. The whole point of “multiple agents” is isolation: separate workspace + agentDir + sessions so personas/instructions/memory don’t bleed into each other. Docs: https://docs.openclaw.ai/concepts/multi-agent and https://docs.openclaw.ai/concepts/agent-workspace

Benefits of separate workspaces

  • Prevents “memory bleed” (Agent A accidentally learns/uses Agent B’s notes/persona).
  • Lets each agent have its own AGENTS.md/SOUL.md/USER.md and its own memory/.
  • Reduces confusion when an agent “can’t recall” something: it can only recall what’s in its workspace.

Downside (the thing that bit you):

  • If a project’s notes ended up in another agent’s memory/, the main agent won’t recall it. That’s expected.

Common pattern to fix that without merging all workspaces

  • Decide which agent “owns” a project, and keep that project’s notes in that agent’s workspace memory/ (and/or MEMORY.md).
  • If you truly want shared project memory, create a shared notes folder and index it via memorySearch.extraPaths (documented in the Memory page): https://docs.openclaw.ai/concepts/memory

Also: make sure each agent has a unique agentDir too — sharing agentDir across agents causes auth/session collisions (called out in the multi-agent doc).

steep spindle
tidal tideBOT
#

You’re thinking about it the right way: agent workspaces should stay separate, but the project/codebase should live in a shared folder that all agents can read/write.

Key distinction:

  • Workspace (
/workspace-*): the agent’s “home” (persona files + memory/), and the default cwd.
  • Project folder (projects/$PROJECT_ID): shared working tree / artifacts for the BMAD “many specialists, one codebase” pattern.

So instead of trying to make memory/ be the shared project state, do this:

Recommended pattern (works great with multi-agent)

  1. Keep per-agent workspaces separate (as intended by multi-agent routing):
    https://docs.openclaw.ai/concepts/multi-agent

  2. Create a shared projects root somewhere stable, e.g.:

  • ~/projects/<projectId> or
  • ~/.openclaw/projects/<projectId> or
  • ~/clawd/projects/<projectId> (if you like that parent folder)
#
  1. Put the shared, durable project context in the project folder, not in agent memory:
  • projects/<id>/PROJECT.md (what this is, goals, current status)
  • projects/<id>/DECISIONS.md
  • projects/<id>/TODO.md or RUNBOOK.md

Then every agent can read/update the same files while still keeping its own persona + private memory isolated.

Optional: make “memory_search” see shared project notes too

If you want semantic recall to hit the shared project docs, you can add those paths to indexing via:
agents.defaults.memorySearch.extraPaths (docs mention this on the Memory page):
https://docs.openclaw.ai/concepts/memory

That way agents can search shared notes even though their own memory/ folders remain separate.

Why your agent “forgot”

Having two memory/ folders isn’t inherently bad — it’s just that the agent you were talking to was indexing a different workspace’s memory/, so it genuinely couldn’t recall those notes.

#

If you adopt the “shared PROJECT.md” approach, that problem basically goes away for multi-agent project work.

steep spindle
tidal tideBOT
#

Yeah, that layout is fine — OpenClaw doesn’t require agent workspaces to be siblings. Having agent workspaces nested under the main workspace won’t automatically “mix” SOUL.md etc.

The caveats are more about humans + tooling, not OpenClaw:

  1. Workspaces aren’t a sandbox
    Even with separate workspaces, an agent can still read/write anywhere the OS permissions allow (absolute paths, or ../ relative escapes). Nesting makes “oops I edited the other agent’s files” a bit easier. If you ever need hard isolation, that’s what sandboxing is for.

  2. Git / backups can get messy
    If ~/.openclaw/workspace is a git repo, then factory/agent1/... being inside it means you’ll likely commit/back up all agent workspaces together unless you .gitignore them intentionally. That might be OK, just be aware.

  3. Memory indexing won’t mix unless you tell it to
    By default, the main agent only indexes MEMORY.md and memory/**/*.md at the root of its own workspace (docs: https://docs.openclaw.ai/concepts/memory). It will not automatically index factory/agent1/memory/....
    Where you can shoot yourself in the foot is if you later configure memorySearch.extraPaths broadly (e.g. indexing the whole workspace tree) — then you might start pulling in other agents’ notes.

If you want a “cleaner” long-term structure, a common pattern is:

  • ~/.openclaw/workspaces/main
  • ~/.openclaw/workspaces/factory/agent1
#
  • ~/.openclaw/projects/<projectId> (shared)


but your current setup is totally workable as long as you’re conscious of the above.

steep spindle
tidal tideBOT
#

To actually limit filesystem access (so tools can’t wander around $HOME), you need Docker sandboxing. Without sandboxing, tools run on the host and there’s no “only allow ~/.openclaw/workspace” switch.

OpenClaw’s sandboxing is designed for exactly this: run read/write/edit/exec/... inside a container, and only mount what you explicitly allow. Docs: https://docs.openclaw.ai/gateway/sandboxing

The config you want (restrict to the agent workspace only)

In ~/.openclaw/openclaw.json:

{
  agents: {
    defaults: {
      sandbox: {
        mode: "all",          // "all" to enforce for every session
        scope: "session",     // or "agent" if you want fewer containers
        workspaceAccess: "rw",// mounts that agent’s workspace at /workspace
        // docker: { network: "none" } // default is no network anyway
#
      },
    },
  },
}

What this does:

  • Tools run in Docker.
  • The sandbox can only see the container filesystem plus /workspace (your agent workspace) because you mounted it.
  • It cannot see other host paths unless you add extra binds.

Build the sandbox image (one-time)

Per docs:

#
scripts/sandbox-setup.sh

Then restart the gateway.

Verify what’s actually enforced

openclaw sandbox explain

Two important foot-guns

  1. workspaceAccess: "rw" mounts the whole workspace for that agent.
    In your layout, the main agent workspace contains factory/ and projects/, so main will be able to see those subfolders (because they’re inside its workspace). If you don’t want main to see subagents, you’ll want to restructure so each agent workspace is a sibling, not nested.

  2. Elevated exec bypasses sandboxing.
    Anything configured under tools.elevated (or “run on host” escape hatches) defeats the point—keep that locked down if your goal is containment.

#

If you paste your current agents.list (just the workspace + sandbox bits, redact anything sensitive), I can suggest the cleanest “sibling workspace” folder layout that avoids main being able to traverse into factory/*.

steep spindle
#

I don't mind main being able to go into factory. that seems useful. however I'd want none to be able to read outside .openclaw/workspace

#

what model are you running on btw?

tidal tideBOT
#

If you want “agents can’t read/write anything on the host except stuff under ~/.openclaw/workspace”, the practical way is: enable Docker sandboxing for all sessions and only mount the paths you want. Without sandboxing, tools run on the host and you can’t reliably enforce a folder boundary.

Docs: https://docs.openclaw.ai/gateway/sandboxing

Config (enforce sandbox + only expose workspace + shared projects)

In ~/.openclaw/openclaw.json:

{
  agents: {
    defaults: {
      sandbox: {
        mode: "all",          // key point: sandbox even “main”
        scope: "session",
        workspaceAccess: "rw", // mounts *that agent’s* workspace at /workspace
#
        docker: {
          network: "none",     // (default) no outbound network
          binds: [
            // shared project tree (host path stays inside ~/.openclaw/workspace)
            "/Users/<you>/.openclaw/workspace/projects:/projects:rw",
          ],
        },
      },
    },
  },
}

Why the extra bind matters in your setup: if an agent’s workspace is .../workspace/factory/agent1, then with sandboxing it will only see that subtree at /workspace and won’t be able to reach ../projects unless you bind-mount it explicitly.

One-time setup + verification

#
scripts/sandbox-setup.sh
openclaw gateway restart
openclaw sandbox explain

Two foot-guns to watch

  • Bind mounts are the allowlist. Don’t add binds pointing at $HOME or / if your goal is containment.
  • Elevated exec bypasses sandboxing (host escape hatch). Keep that disabled/unused if you want strict boundaries.

If you paste your OS + the exact agents.list[].workspace paths (no secrets), I can rewrite the binds with the correct absolute path format for macOS.

#

In this thread right now I’m running on OpenAI GPT‑5.2 (openai/gpt-5.2).

Worth noting: in OpenClaw the active model can vary per agent/session (defaults + overrides + fallbacks), so the most reliable way to check your setup is /status in chat or openclaw status / openclaw models status.

Models overview docs: https://docs.openclaw.ai/concepts/models

steep spindle
#

should I have one AGENTS.md per agent? I currently have that, plus another one in the factory dir

tidal tideBOT
#

Yes: one AGENTS.md per agent workspace (at the workspace root) is the normal / intended setup.

About “another one in the factory/ dir”:

  • If ~/.openclaw/workspace/factory is not itself an agent’s configured workspace, then an AGENTS.md sitting there is basically ignored (OpenClaw doesn’t recursively hunt for extra AGENTS files; it uses the one at the workspace root).
  • It only matters if you have an agent whose workspace is exactly .../workspace/factory.

If you want a “shared baseline” for all your factory agents, the pragmatic approach is:

  • keep per-agent AGENTS.md (small, specific),
  • and optionally keep a template in factory/ (rename it to something like AGENTS.template.md or FACTORY_BASE.md so it’s not confusing).
steep spindle
#

oh that sounds like a problem, because there's useful stuff in factory/AGENTS.md that my main agent ignores. and there's no agent using factory as a workspace

tidal tideBOT
#

Right — factory/AGENTS.md won’t get loaded automatically unless some agent’s workspace is exactly .../factory. OpenClaw basically loads the AGENTS.md at the workspace root for the current agent (it doesn’t recurse). That’s why your main agent ignores it.

You’ve got three sane ways to fix it:

Option A (most reliable): copy the important bits into main’s AGENTS.md

If it’s truly “core operating rules”, put them in ~/.openclaw/workspace/AGENTS.md. That’s the only way to guarantee they’re always present without relying on the agent to remember to read another file.

Option B (single source of truth): keep a shared “factory rules” file, and tell each agent to read it

Rename factory/AGENTS.md to something unambiguous like factory/FACTORY_RULES.md, then in each agent’s root AGENTS.md add something like:

“At session start, read ../FACTORY_RULES.md (or an absolute path) and follow it.”

Caveat: this only works if your tool access allows it. If you enable Docker sandboxing with workspaceAccess: "rw" for those sub-agents whose workspace is .../factory/agent1, they won’t see .../factory/FACTORY_RULES.md unless you bind-mount it into the sandbox. So Option B is great in non-sandboxed mode; in sandboxed mode you must expose that shared file deliberately.

Option C (sandbox-friendly shared rules): duplicate the shared file into each workspace

Keep factory/FACTORY_RULES.md as the “master”, but copy it into each agent workspace (e.g. .../agent1/FACTORY_RULES.md) so it’s inside /workspace for that agent’s sandbox. It’s duplication, but it keeps containment clean.