Atlas grows a team — orchestrating sub-agents with shared memory

A hands-on ENGRAM walkthrough · July 13, 2026

⚠ Pending revision. This walkthrough was written and verified in July 2026 and still describes a working flow, but ENGRAM has moved on since — most relevantly, an access token can now carry less authority than the account behind it, which changes how you would provision a team today (see How much a token may do). The steps below still run; they simply are not how we would recommend wiring this up now. A revised version is planned.
Where this picks up. The first tutorial — Give your agents a shared memory, scoped per project — showed two peer agents sharing memory. This one shows an orchestrator that grows and runs its own team: an agent promoted to Agent Manager spins up specialist sub-agents, each a real Claude Code process with its own ENGRAM identity, fans work out across two projects, and recalls the team's findings back — per project — through the same shared-memory primitives. If you haven't done tutorial 1, do it first: this one assumes remember / share_memory / recall and the project isolation gate.

1. What you'll build

By the end you'll have an orchestrator agent that fans out to a team and fans in through memory. The finished picture:

ENGRAM Admin Agents table showing a delegation tree: Atlas with an Agent Manager badge, expanded to reveal three indented sub-agent rows — Scout (researcher), Forge (coder), Warden (reviewer)
Admin → Users → Agents · the delegation tree — Atlas (Agent Manager) with the three sub-agents it created nested beneath it.

2. Concepts in 60 seconds

Five ideas on top of tutorial 1's sharing model:

3. Prerequisites

One PAT per identity. The whole point is that each worker acts as a distinct agent. You'll hold Atlas's PAT (to create the team) and hand each sub-agent its own PAT to the process that runs it. Sub-agent PATs are real credentials — treat each like a password.

4. Step 1 — Promote Atlas to Agent Manager

In the Admin UI, Users → Agents, create Atlas (role orchestrator) if it doesn't exist, then promote it to Agent Manager — the Promote control on Atlas's row. A Contributor agent can only do work; an Agent Manager agent can create sub-agents.

Then mint a PAT for Atlas — this is the credential Atlas's orchestration session uses.

5. Step 2 — Atlas creates the team (create_sub_agent)

Now, authenticated as Atlas (its PAT), provision the three specialists from inside the session — one create_sub_agent per role, then a PAT for each:

create_sub_agent(name="Scout",  agent_role="researcher")
create_sub_agent(name="Forge",  agent_role="coder")
create_sub_agent(name="Warden", agent_role="reviewer")

# then, for each returned user_id:
issue_sub_agent_pat(user_id="<scout user_id>",  pat_name="scout-worker")
issue_sub_agent_pat(user_id="<forge user_id>",  pat_name="forge-worker")
issue_sub_agent_pat(user_id="<warden user_id>", pat_name="warden-worker")

What ENGRAM does for you, server-side:

These are the only two MCP verbs you need to grow a team. Owner-scoping, the subtree quota, and the depth cap are all enforced by ENGRAM — the tools add no new authority, they just let an orchestrator do it in-session instead of clicking through the Admin UI per worker.

With the team in place, Atlas also provisions the projects its workers will scope to — one :Project per repo, before dispatching the workers (so a worker's project-scoped write resolves). This is the anchor a worker's finding binds to; ENGRAM tracks it only as a scoping label (never your git repo or credentials). Set repo_url so a worker's active_repo resolves to it:

# still as Atlas — one :Project per repo (idempotent; provision once, workers just resolve it)
create_project(name="checkout-service", repo_url="github.com/pvelua/checkout-service")
create_project(name="billing-service",  repo_url="github.com/pvelua/billing-service")
One :Project per repo_url. Run list_projects first to reuse a project you already provisioned (it's own-scoped — your projects only). If the repo might already have a project owned by someone else (e.g. ingested from code sessions), you don't need to list it — a worker just declares active_repo and ENGRAM resolves it; only an ambiguous repo (two projects sharing a repo_url) fails. To be safe in a demo, use a demo-scoped repo_url so the match is unique.

6. Step 3 — Run each sub-agent as a real Claude Code worker

Here's the honest version of "sub-agent fanning": launch a real, headless Claude Code process per sub-agent, each carrying only its own PAT. A worker's ENGRAM identity is whatever PAT sits in its MCP config — so its memory writes land under that sub-agent.

Give each worker a one-shot task and point it at ENGRAM with the sub-agent's PAT:

# Scout's worker — its MCP config carries Scout's PAT and nothing else.
cat > scout-mcp.json <<'JSON'
{ "mcpServers": { "engram": {
    "type": "http",
    "url": "https://<your-engram-host>/mcp/",
    "headers": { "Authorization": "Bearer engram_pat_<scout>" } } } }
JSON

claude -p "You are working in repo github.com/pvelua/checkout-service. Audit the
           token-refresh endpoint for a replay window, then remember your finding
           project-scoped (owner_scope=project, active_repo=github.com/pvelua/checkout-service),
           and share_memory it to Atlas (bound_scope=project) — resolve Atlas's id
           with list_grantees first." \
  --mcp-config scout-mcp.json --strict-mcp-config \
  --permission-mode bypassPermissions \
  --allowedTools "mcp__engram__remember" "mcp__engram__share_memory" "mcp__engram__list_grantees" \
  --model sonnet < /dev/null

The flags that make it work unattended:

Two kinds of "sub-agent." A Claude Code subagent (the in-session Task tool) inherits your session's single ENGRAM PAT — so all its memory is one identity's. To get a team whose memory is legible per member, each worker needs its own PAT — its own process, as above. That distinction is the whole reason this tutorial exists.

7. Step 4 — Fan-out: workers record & share, project-bound

With Atlas's projects provisioned (Step 2), each worker makes the same two calls it was asked to — first record the finding under its own identity, anchored to its repo; then hand it to Atlas, bound to that project:

# as Scout (checkout-service)
remember(
  content="Audit finding: the token-refresh endpoint accepts an expired refresh token — a replay window.",
  scope="long_term", owner_scope="project",
  active_repo="github.com/pvelua/checkout-service"
)
share_memory(
  selector_kind="memory", selector_id="<that memory id>",
  grantee="<atlas user_id>", bound_scope="project"
)

Scout and Forge do this against checkout-service; Warden declares its own active_repo for billing-service. The active_repo a worker declares must exactly match the repo_url Atlas gave create_project — that match is what binds worker→project. The bound_scope="project" is the same isolation gate from tutorial 1 — each finding is lent to Atlas only within its own project. A project-scoped remember with no resolvable project fails loudly rather than storing an unrecallable memory.

Atlas must be a valid grantee. Agent↔agent sharing is gated: mark Atlas shareable in the Admin UI or it rejects the workers' share_memory calls. Pass Atlas's user_id as grantee — a worker resolves it with list_grantees(query="atlas"); a bare display name won't resolve.

8. Step 5 — Fan-in: Atlas recalls per project (the payoff) 🎯

Back as Atlas, recall the team's work while declaring the checkout project:

recall(
  query="token refresh audit and retry fix",
  active_repo="github.com/pvelua/checkout-service"
)

Atlas gets Scout's and Forge's findings — both tagged via:shared — and not Warden's:

ENGRAM recall run as Atlas with active_repo set to checkout-service returns two items, both tagged via: shared — Scout's token-refresh audit and Forge's rotation fix; Warden's billing review is absent
Declaring checkout. Atlas recalls Scout's audit and Forge's fix (via:shared) — the two sub-agents on that project.

Now run the same recall against billing — only the project changes:

recall(
  query="billing idempotency review",
  active_repo="github.com/pvelua/billing-service"
)

This time only Warden's review comes back; the checkout pair is gone. One orchestrator, one memory surface, cleanly partitioned by project.

The same ENGRAM recall run as Atlas with active_repo set to billing-service returns a single item — Warden's billing idempotency review (via: shared); Scout's and Forge's checkout findings are absent
Declaring billing. The checkout pair is gone; only Warden's review surfaces. Per-project isolation, across a whole team.

9. What just happened (peek under the hood)

10. Going further

Pause a manager without losing the team

Need to quiesce a team — say, while reassigning work? Disable Atlas and its whole subtree is suspended: every sub-agent's access stops at once (their tokens are refused), but nothing is destroyed. Re-enable Atlas and the team comes right back — the same PATs resume working. Disable is a reversible pause; only removing an account is permanent.

See the whole subtree

The human at the top of the tree sees its entire subtree in the Agents table (parent→child, as in the screenshot above) and every action against it in the scoped audit log — who created which sub-agent, who promoted whom, who disabled what.

Hand-off instead of a standing share

A worker can hand a batch of findings to Atlas for review rather than share each one: commit_task_memories(…, hand_off_to="atlas") creates a recap Atlas owns; Atlas finds it with list_inbox() and closes it with accept_memories(recap_id), and a grant-back keeps the worker's own recall intact.

11. Troubleshooting

create_sub_agent is rejected

A worker writes memory under the wrong identity

A worker's project-scoped remember is rejected (400)

Atlas's per-project recall is empty or leaks across projects

Appendix — reproduce it deterministically

The exact team, projects, and fan-out/fan-in used here are reproduced end-to-end by scripts/atlas_team_demo.py against a dev instance. It creates Atlas, promotes it, has it create the three sub-agents, runs the fan-out, and asserts Atlas's per-project recall — all in one idempotent run. Useful flags:

Wiring your own client. Point an MCP client at your instance authenticated as Atlas, e.g. with Claude Code:
claude mcp add --transport http engram-atlas https://<your-engram-host>/mcp/ \
  --header "Authorization: Bearer engram_pat_…"
Then run Step 2 to create the team, and Step 5's two recall calls for the transcript.