Monorepo Federation
Home GitHub

Monorepo Federation

Part VI: Enterprise · Chapter 18

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.

Root draft/graph/ schema.yaml · codebase-memory-mcp engine (live) auth-service/ draft/ architecture.md graph/root-link.json ↑ billing-service/ draft/ architecture.md graph/root-link.json ↑ api-gateway/ draft/ architecture.md graph/root-link.json ↑ /draft:init (scope-aware) root-link.json in each module points to the root graph
Monorepo federation via scope-aware /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:

  1. Builds the root knowledge graph (or refreshes it if it already exists).
  2. Builds the module-level snapshot for the current sub-module.
  3. Writes draft/graph/root-link.json inside 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-mcp engine (159 languages, 100% local). It is never a committed snapshot — it is always a live query.
  • Each module's root-link.json is 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 own architecture.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:

LayerLocationContainsPurpose
Rootdraft/ at repo rootRoot 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.jsonPer-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:

FlagWhat it doesWhen to use it
--module-onlyBuilds only the current module's snapshot; does not touch the root graphWhen 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 filesAfter 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:

  1. Run /draft:init at the repo root — this establishes the root graph and generates the system-level context files.
  2. For each service you are actively working on, run /draft:init from inside that service directory. Draft automatically writes root-link.json and connects the module to the root graph.
  3. 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.
No Aggregation Command Needed

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.

When to Re-Init

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.