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

A hands-on ENGRAM walkthrough · July 13, 2026

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

Four 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.

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 "Audit the token-refresh endpoint for a replay window, then
           remember your finding and share_memory it to Atlas." \
  --mcp-config scout-mcp.json --strict-mcp-config \
  --permission-mode bypassPermissions \
  --allowedTools "mcp__engram__remember" "mcp__engram__share_memory" \
  --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

Inside its session each worker makes the same two calls it was asked to — first record the finding under its own identity, anchored to its project; 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"
)
share_memory(
  selector_kind="memory", selector_id="<that memory id>",
  grantee="atlas", bound_scope="project"
)

Scout and Forge do this against checkout-service; Warden against billing-service. The bound_scope="project" is the same isolation gate from tutorial 1 — each finding is lent to Atlas only within its own project.

Atlas must be a valid grantee. Agent↔agent sharing is gated: mark Atlas shareable in the Admin UI (or it will reject the workers' share_memory calls). A directory type-ahead (list_grantees) resolves "atlas" to its id.

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

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.