Scattered across N repos
Architecture lives one place, API contracts another, runbooks a third. Search is brittle, link-rot is rampant, ownership is unclear.
__
__ _ ___ ____ ___ / /____ ____
/ ' \/ _ `/ -_|_-</ __/ -_) __/
/_/_/_/\_,_/\__/___/\__/\__/_/ · living specs · v0.1.0 ·
Maester is a Node CLI for aggregating documentation from many Git repositories into one central knowledge home — a citadel — so humans and AI agents can reason over your whole system from a single, current corpus.
The problem
Across services and packages, the documentation that matters lives in the repos that own it — where it’s easy for humans to miss and impossible for an AI agent to reliably find.
Architecture lives one place, API contracts another, runbooks a third. Search is brittle, link-rot is rampant, ownership is unclear.
Copy-paste portals drift the day they’re built. Engineers update READMEs; the portal keeps showing last year’s reality.
Every prompt rediscovers the codebase. Coding agents guess at conventions, miss decisions, and ship plausible nonsense.
The model
Source repositories declare what they publish. One central repository pulls them together. A maester can live where the source lives — or travel from the citadel to a repo that hasn’t adopted one yet.
maester
A maester is a publish list — a small maester.yaml that says which files in a repository are worth aggregating.
It can be defined two ways:
maester.yaml at the repo root and the citadel
consumes whatever it declares.
citadel.yaml with an
includes list. The maester travels to the repo; the
repo doesn’t change.
# maester.yaml — in the source repo schemaVersion: 1 documents: - path: README.md - path: docs/adr/*.md - path: docs/runbooks/**/*.md
citadel
A citadel is the aggregator: a repository with a
citadel.yaml that lists every source — resident or
travelling — and a <baseDir>/ tree where their
content materialises on sync.
# citadel.yaml schemaVersion: 1 baseDir: context sources: - name: design-system url: github.com/org/design-system - name: astro-docs url: github.com/withastro/docs includes: - src/content/docs/**/*.mdx
The flow
Each maester declares its publish surface in its own repo. The
citadel decides which sources to pull and where to put them.
Re-run maester sync any time to refresh.
Supercharge AI workflows
AI coding tools are powerful — but only as good as the context you give them. A citadel is a single, current, structured corpus your agents can actually read.
01
Point Claude Code, Cursor, Codex, or Antigravity at
citadel/ and the agent inherits architecture decisions,
API contracts, and runbooks from every repo at once — not just the
one it’s editing.
02
Every directory carries a .maester-source.json marker —
source URL, ref, commit SHA, sync time. When an agent quotes a doc,
you can trace it back to its origin.
03
Run maester sync before any agent session — or wire it
into CI. The corpus reflects the actual current state of every
source, not last quarter’s snapshot.
04
Either the source publishes its own maester.yaml, or
your citadel sends a traveling maester to do the publishing
in its stead. Agents see the deliberately curated surface — not the
noise of a full clone.
Add rate limiting to the billing webhook handler.
I’ll add a token-bucket middleware. Where do you want the limits configured?
agent doesn’t know your platform’s standard middleware, env-var conventions, or ADR-014 on retry policy. It guesses.
Add rate limiting to the billing webhook handler.
Reading citadel/platform-runbooks/middleware.md and
citadel/architecture-notes/adr-014-retry.md…
Using @platform/limiter at 100 req/min per
tenant, matching ADR-014. Env var:
BILLING_WEBHOOK_RPS. Adding the runbook
entry too.
agent reads the citadel and applies the system’s actual conventions.
Optional · ships with the CLI
An installable agent skill that turns your citadel into a first-class
context surface for whichever coding agent you run. It teaches the
agent where the citadel lives, prefers canon files over
draft, and runs maester status before
substantial reads so it never answers from a stale corpus.
Supported agents
AGENTS.md agentThe CLI surface
citadel.yaml. maester.yaml. --json. Global flags
--verbose · raise log detail --quiet · errors only --json · one JSON object per line, for CI & agents --no-color · pure monochrome --theme=light · accent swaps for light terminal themes Resident or traveling
Same publish contract, same destination, same provenance. The difference is where the maester is defined — at the source, or at the citadel.
For repos you maintain. The source publishes its own
maester.yaml and your citadel consumes whatever it
declares — full stop.
maester.yaml at the source repo root
For repos you don’t control — vendor specs, third-party docs, public
projects. Declare an includes list on the source entry
in your citadel.yaml; the remote needs nothing.
includes on the source entry in
citadel.yaml Quick start
Same command in the aggregator repo and in any repo that should publish to it — it detects the context and writes the right config.
$ npx baller-maester init # in the citadel → writes citadel.yaml # in a source → writes maester.yaml
From the citadel, any time you want a fresh snapshot.
$ maester sync ✓ 5 sources · 68 docs · 0 errors
· Node 24+ · works in Claude Code, Cursor, Codex, Antigravity, Open Code