Step 7 - Add curated docs
Goal: capture the knowledge that is not attached to a single unit - patterns, practices, architecture, conventions - as hand-written docs that pass the same gate as generated ones.
A campaign documents your units - the services, libraries, and modules your config declares. But a lot of what an agent needs to build well is cross-cutting: a pattern your team follows, a convention you enforce, an architectural decision, a practice worth teaching. Those are curated docs, and they live in the corpus's shared/ space rather than under a source.
Curated does not mean unguarded. A curated doc passes the same eight validators as a generated one, and it is governed from birth.
Scaffold a curated doc
alloy new curated <category>/<slug><category> is a shared category (or a manifest key), and <slug> names the doc. For example:
alloy new curated conventions/error-handling
alloy new curated patterns/multi-tenancyThis scaffolds a doc that already validates: the section skeleton comes from the manifest (the category's required sections, or the default list), with one ⚠️ GAP placeholder per section, and the frontmatter carries the governance fields so the doc is governed the moment it exists.
Governance: --review-after or --referent
Every curated doc needs an owner (defaults to your git email) and one of two freshness mechanisms. They are mutually exclusive, and choosing between them is the one real decision here:
--review-after <YYYY-MM-DD>- a calendar review date. Use this when the doc has no code referent - a pure practice or philosophy that no source file governs. Defaults to today plus 180 days.bashalloy new curated practices/code-review --review-after 2026-12-31--referent <source:path>(repeatable) - names source files whose change marks the prose drifted. Use this when the doc is about specific code, so it gets its freshness fromalloy stampthe same way a generated doc does, rather than a calendar guess.bashalloy new curated patterns/outbox --referent your-repo:packages/outbox/src/index.ts
Prefer a referent wherever the doc tracks real code - a mechanical drift signal beats a calendar TTL. Reach for --review-after only where no code governs the doc.
Author, validate, stamp
The loop is the same shape as a generated doc, minus the context bundle:
# 1. Author: replace each ⚠️ GAP placeholder with real content.
# Leave a ⚠️ GAP marker anywhere you cannot yet fill honestly.
# 2. Validate:
alloy validate .alloy/corpus/shared/<category>/<slug>.md
# 3. Stamp (records freshness; for a --referent doc, records the referent drift baseline):
alloy stamp .alloy/corpus/shared/<category>/<slug>.mdstamp takes a path to a curated .md document (rather than a kind/name target), re-runs the gate, and records a referent_refs drift baseline for a referent doc so your --referent files are watched for drift from then on.
You now have a corpus
Between the campaign (step 6) and curated docs, your repo hosts a full corpus: units documented with provenance, cross-cutting knowledge captured and governed, everything through one gate. Commit the curated docs, run alloy validate .alloy/corpus once more, and you have stood Alloy up end to end.
From here, wire it into your agents - that is Integrate with agents.