Monorepo Federation
4 min read
Draft has no separate index command. Monorepo support is built directly into /draft:init, which is scope-aware and root-first. Run it at the repo root to build the whole-repo knowledge graph. Run it inside any sub-module and it resolves the repo root automatically, builds that module's graph snapshot, and writes a draft/graph/root-link.json pointing up to the root graph — so any module has full cross-module understanding without any extra commands.
/draft:init: each sub-module's draft/graph/root-link.json points up to the root knowledge graph, giving every module full cross-module understanding without a separate aggregation command.How Scope-Aware Init Works
When you run /draft:init inside a sub-module directory, Draft does not stop at that directory. It resolves the repository root by walking ancestor directories until it finds either an existing draft/ directory or the git toplevel. It then:
- Builds the root knowledge graph (or refreshes it if it already exists).
- Builds the module-level snapshot for the current sub-module.
- Writes
draft/graph/root-link.jsoninside the sub-module, pointing to the root graph path.
The result: any AI session started inside auth-service/ loads both the auth-service context and the cross-module knowledge graph at the root. Cross-service questions — which services share PostgreSQL, what breaks if the auth API changes, what the billing service depends on — are answered from the live root graph without any manual aggregation step.
Federation = The Root-Link Mechanism
Federation in Draft is not a separate aggregation command. It is a structural property of how /draft:init writes artifacts:
- The root graph (at the repo root) is the whole-repo knowledge graph queried live from the
codebase-memory-mcpengine (159 languages, 100% local). It is never a committed snapshot — it is always a live query. - Each module's
root-link.jsonis a pointer file (a few bytes) that tells Draft where the root graph lives relative to this module. This is what enables cross-module queries from within any sub-directory. - The module-level
draft/directory contains the module's ownarchitecture.md,.ai-context.md, and.ai-profile.md— scoped to that service's code.
Root-Level vs. Service-Level Context
After running /draft:init at the root and in each service, the monorepo has two layers of context:
| Layer | Location | Contains | Purpose |
|---|---|---|---|
| Root | draft/ at repo root | Root architecture.md, .ai-context.md, .ai-profile.md, live graph (engine) | Cross-service decisions, system topology, organizational standards |
| Module | <service>/draft/ | Service-specific architecture, product, tech-stack, tracks, guardrails, graph/root-link.json | Per-service implementation, feature work within a service |
When working within a single service, the AI loads that service's context plus follows root-link.json to also load root-level context for cross-service awareness. When making cross-service decisions — adding a new API dependency, changing a shared schema, planning a migration — the AI queries the root graph directly.
Flags for Monorepo Workflows
/draft:init supports two flags that are especially useful in monorepos:
| Flag | What it does | When to use it |
|---|---|---|
--module-only | Builds only the current module's snapshot; does not touch the root graph | When the root graph is already current and you only need to update a single service |
--graph-only | (Re)builds graph memory without regenerating markdown context files | After large merges or refactors where the graph may have drifted but the narrative docs are still accurate |
Onboarding a Monorepo Incrementally
You do not need to initialize every service at once. The recommended sequence:
- Run
/draft:initat the repo root — this establishes the root graph and generates the system-level context files. - For each service you are actively working on, run
/draft:initfrom inside that service directory. Draft automatically writesroot-link.jsonand connects the module to the root graph. - Services you have not initialized yet are invisible to the per-module context but still visible to the root graph (since the engine indexes the full codebase). Module-level docs for those services simply do not exist yet.
Draft's monorepo support requires no extra command beyond /draft:init. There is no /draft:index, no separate aggregation step, and no maintenance burden to keep a root index in sync. The knowledge graph engine handles cross-module queries live. The root-link.json pointer is the entire federation mechanism.
Cross-Module Queries via /draft:graph
Once the root graph is established, use /draft:graph for live cross-module queries:
/draft:graph --mode hotspots # Most-changed files across the whole repo
/draft:graph --mode impact --file auth-service/pkg/jwt.go # What breaks if this changes?
These queries run against the live codebase-memory-mcp engine and do not require any pre-committed graph data. Results reflect the current state of your working tree.
Run /draft:init refresh (or --graph-only) after significant structural changes: new services added, major refactors, shared library API changes. For day-to-day feature work, the existing graph stays accurate enough. The engine queries your live codebase, so hotspot and impact queries are always current.