A composable, inheritance-based template library that an LLM agent can
use to draft a project context file (CLAUDE.md or AGENTS.md) for
any type of project — from a static portfolio to a Python SDK to a
React SPA. Output quality depends on the model and context window.
Designed to be agent-agnostic: works with Claude Code, Codex CLI, Devin, Cursor, or any agent that reads a Markdown context file.
Inspired by SOLID principles: each template has a single responsibility, is open for extension, and can be composed without modification.
Reusable building blocks covering one concern each. Apply to every project regardless of stack. Never used directly — always composed into a higher layer.
CI and security tool mappings specific to a hosting platform. Orthogonal to the stack choice — a Python project on GitHub and a Python project on GitLab use the same tools; only the CI config and SAST tool differ.
Concerns that apply to all frontend projects but not to backend or library projects. Extend base templates. Never used directly by a project.
Concerns shared by all backend services but not by frontend or pure libraries. Extend base templates. Never used directly by a project.
Technology-specific rules. Each stack declares which layers it depends on.
Generated from templates/manifest.yaml — run py tools/sync.py to refresh.
base/
├── core/
│ ├── git.md # Committer identity, commits, branching, PR workflow, versioning
│ ├── docs.md # Rule language, documentation standards, ADR, diagrams, docs-as-code
│ ├── quality.md # Architecture, code style, calibration, tool trust, testing
│ ├── review.md # Peer review priority, MUST/SHOULD checklists, deviation rules
│ ├── testing.md # Test pyramid, coverage thresholds, naming conventions
│ ├── agents.md # Output structure, models (inline/reference/hybrid), formatting rules
│ ├── skills.md # Skill authoring — when to write one, frontmatter, triggering, structure, scripts
│ ├── readme.md # README structure, badges, quick start, contribution guide
│ ├── config.md # Env vars, secrets, fail-fast validation
│ ├── cli.md # Entry-point architecture - thin main(argv), shared plumbing, durable output
│ ├── examples.md # Examples directory — contents, index, offline rule, smoke job
│ └── oop.md # SOLID, OOP, GoF design patterns, AOP guidance
├── security/
│ ├── devsecops.md # SAST, SCA, SBOM, secret detection, license compliance
│ └── security.md # Application security rules — input, output, injection, auth, sessions, TLS, headers
├── workflow/
│ ├── release.md # Semver, version bump propagation, backward compat, cut-over
│ ├── issues.md # Issue templates — epic, task, bug, incident, spike
│ ├── scope.md # Scope guard, session protocol, drift prevention
│ ├── compression.md # Re-verifying summaries, tables and rollups derived from verified research
│ ├── quality-gates.md # Three-layer gate model (editor, pre-commit, CI), thresholds
│ ├── ai-workflow.md # AI-assisted development lifecycle, work item hierarchy
│ ├── 360.md # 360-degree project analysis — four stakeholder perspectives, grading
│ ├── communication.md # Communication preferences — concise output, shorthand verbs, scope-asking
│ └── two-pass-review.md # Split convention checks into mechanical (auto-fix) and contextual (over-flag, judge) passes over one catalogue
├── infra/
│ ├── cicd.md # Pipeline stages, triggers, environments, IaC, deployment
│ ├── containers.md # Dockerfile, runtime security, resource limits, Kubernetes
│ └── deployment.md # Deployment targets (cloud/hybrid/offline), certs, LB, registries, secrets
├── language/
│ ├── go.md # Per-language tool selection for Go - lint, vet, complexity, tests
│ ├── python.md # Per-language tool selection for Python - lint, types, complexity, tests
│ ├── typescript.md # Type design, naming, strictness — applies to all TypeScript projects
│ └── c.md # Per-language tool selection for C - clang-tidy, clang-format, cppcheck, ctest
└── data/
├── data-quality.md # Data sourcing, completeness, freshness, research, scoring — data-heavy projects
├── data-modeling.md # Schema design, naming, normalization, relationships, data types
├── data-governance.md # Classification, PII handling, retention, ownership, audit trail
└── data-migration.md # Versioned migrations, zero-downtime, rollback strategies
platform/
├── github.md # CodeQL, GitHub Actions, gitleaks action, push protection
├── gitlab.md # Semgrep OSS, GitLab CI/CD, gitleaks CLI
└── linear.md # Label groups, native priority, sub-issues, code-host sync
frontend/
├── ux.md # UX principles, WCAG 2.1 AA, responsive breakpoints
├── quality.md # CSS conventions, performance, SEO & analytics
└── static-site.md # Abstract SSG rules — content, assets, SEO
backend/
├── http.md # URI design, methods, headers, HATEOAS, auth, errors
├── api.md # API-first, OpenAPI, versioning, deprecation, pagination
├── database.md # Migrations, transactions, no raw SQL, connection pooling
├── caching.md # Cache-aside, TTL, invalidation, resilience, stampede
├── auth.md # Authn/authz, JWT, RBAC, sessions, API keys
├── jobs.md # Background jobs, idempotency, retry, DLQ, scheduling
├── concurrency.md # Threads vs. processes vs. async, shared state, structured concurrency
├── messaging.md # Brokers, producers, consumers, schema, DLQ, observability
├── webhooks.md # Inbound webhook intake, edge signature verification, fast-ack, retry amplification
├── edge.md # Reverse proxy / edge — TLS termination, forwarded headers, upstream routing, timeouts, edge security
├── grpc.md # Proto design, status codes, interceptors, health check
├── microservices.md # Service boundaries, inter-service comms, saga, contract testing
├── errors.md # Classification, propagation, recovery, external failures
├── features.md # Feature flags, rollout strategy, experimentation
├── observability.md # Log levels, log format, health check, error visibility
├── monitoring.md # Key metrics, thresholds, alerts, dashboards, incidents
├── quality.md # Layered architecture, security, performance, API stability
└── templating.md # Server-side rendering, partials, escaping, caching, forms, testing
stack/
├── htmx.md # HTMX 2.x, Alpine.js, SSE, OOB swaps, partial responses
├── static-site-astro.md # Islands architecture, client directives, content collections
├── static-site-tutorial.md # Multi-chapter tutorial, diagrams, CC BY-NC-SA
├── python-lib.md # Installable package or CLI tool, mypy, ruff, pytest
├── python-service.md # Generic Python web service, SQLAlchemy, Alembic
├── python-flask.md # Sync REST API, factory pattern, blueprints
├── python-fastapi.md # Async REST API, Pydantic v2, DI, OpenAPI
├── python-django.md # Full web framework, ORM, DRF, admin
├── go-lib.md # Importable library or CLI binary
├── go-service.md # Generic Go HTTP service, chi, structured logging
├── go-echo.md # REST API, Echo v4, middleware, validation
├── node-express.md # Minimal REST API, Zod validation, Supertest
├── node-nestjs.md # Modules, controllers, providers, guards, pipes, DI
├── go-grpc.md # gRPC service, bufconn, errgroup
├── python-grpc.md # gRPC service, grpcio-aio, proto design
├── nodejs-lib.md # TypeScript npm package or CLI, tsup, Vitest
└── c-embedded.md # GCC + CMake, Unity tests, HAL, binary + .a
Rendering rules for the generated output. Describes structure, model
selection (inline/reference/hybrid), and formatting constraints.
Lives in templates/base/core/agents.md alongside the other core
templates.
A single file any agent uses to ask the user the required questions before generating the output context file. Questions are grouped by concern and reference the relevant base/stack templates.
INTERVIEW.md
The context file generated for a specific project by combining interview answers + base templates + stack template + output format template.
| Agent | Output file | Location |
|---|---|---|
| Claude Code | CLAUDE.md |
project root |
| Codex CLI, Devin, Cursor, Windsurf | AGENTS.md |
project root |
Interop: AGENTS.md is read by Claude Code as a fallback when no
CLAUDE.md is present.
templates/base/core/git.md ────────────────────────────────────────────┐
templates/base/core/docs.md ───────────────────────────────────────────┤
templates/base/core/quality.md ────────────────────────────────────────┤
▼
frontend/ux.md ─────────────────────────────► frontend/static-site.md
frontend/quality.md ────────────────────────► │
▼
templates/stack/static-site-astro.md
│
+ templates/INTERVIEW.md answers
│
+ templates/base/core/agents.md rules
│
▼
CLAUDE.md
Rules:
- A stack template MUST reference which base templates it depends on
- A stack template MAY override a base rule — overrides must be explicit
- A stack template MAY add new rules not present in the base
- The agent merges base defaults + stack overrides + interview answers, then applies the output format template
Stacks compose only the modules they need — no transitive surprises. See ADR-004 for the full rationale.
The core-tier base templates apply to every project. They are declared in
templates/manifest.yaml under core: and included during
resolution — stacks do not need to list them in depends_on:
templates/base/core/quality.mdtemplates/base/core/git.mdtemplates/base/core/docs.mdtemplates/base/core/readme.mdtemplates/base/core/testing.mdtemplates/base/core/review.mdtemplates/base/core/oop.md
Measured: 45 [DEPENDS ON] tokens across 20 templates name one of these
files, and 20 manifest entries name a core id in depends_on. Declaring one
is redundant rather than forbidden — the seeding reaches the file either
way, and the directive documents a dependency a reader would otherwise
infer. Reached by the seeding alone: base-readme. A chain assembled by
walking the directives does not reach that set and reports nothing about it,
because nothing declares what is absent.
SYS-13 compares the walk the README documents against the resolver for every root, in both directions.
Some templates are project-level choices, not stack-level dependencies.
They are not referenced in any stack's depends_on chain — users
opt in via the Extras field in the declaration block or during the
interview.
Orthogonal templates include platform choices (github, gitlab),
workflow preferences (360, ai-workflow, release, deployment),
and the advanced data templates (data-governance, data-migration) —
opt-in extras no stack pulls automatically (data-quality is the only
data module reached by a chain, via python-service).
Orthogonal templates are NOT expected to appear in stack resolution.
They are resolved as their own roots instead: an orthogonal template is
guaranteed the core tier plus its own depends_on tree, and nothing
else, because the stack it is paired with is not known when it is
authored. Reachability is checked against that chain — an [EXTEND: ...]
or a prose section reference in an orthogonal template MUST resolve
there, not in some stack chain the project may never pick.
Everything else is explicit. Stacks declare what they need:
| Tier | Modules |
|---|---|
| Language | typescript |
| CI | cicd, quality-gates |
| Security (app) | security |
| Security (pipeline) | devsecops |
| Infrastructure | containers, deployment, release |
| Session | scope, issues |
| Specialized | data-quality, 360, ai-workflow |
| Platform | github, gitlab |
Two opt-in tiers are not left to whatever the dependency declarations
produce. Their membership is stated by stack category — the layer each
stack declares in the manifest — with a reason per exempt category, and a
smoke check enforces it in both directions. A stack in a governed category
resolving no member of the tier fails, and a stack declaring no category
fails rather than passing by omission.
| Tier | Exempt categories | Reason | Check |
|---|---|---|---|
| Security | library, embedded | a library is imported by a caller that owns the trust boundary; an embedded target has no HTTP surface, sessions or TLS to rule on | SYS-15 |
| Quality gates | hypermedia, embedded | both are recorded at the most constrained context tier, and admitting the tier would change which models can run the stack | SYS-18 |
Where an exemption's reason is a property recorded elsewhere in the tree,
the check asserts the reason still holds. The quality-gate exemptions are
read against tests/context-tiers.txt, so a category that later moves off
the most constrained tier stops being exempt rather than staying exempt by
omission. See ADR-044.
Membership stated as a list of stack identifiers is what this replaces: a list is correct on the day it is written and silently wrong at the next stack.
[DEPENDS ON: ...] headers MUST list direct dependencies only —
matching the manifest's depends_on for that entry. Headers MUST NOT
expand transitive dependencies.
Source of truth: templates/manifest.yaml is authoritative. When
a mismatch exists between a file header and the manifest, the manifest
wins and the file header MUST be updated. Smoke check SYS-04 validates
this contract.
The wiki (docs/wiki/) gathers human reference documentation
for projects that use the templates. It is NOT part of the
dependency graph or agent context. Parent rules files reference
the relevant wiki pages as one-line conventions.
Current wiki pages: backend.md, cicd.md, devsecops.md,
frontend.md, security.md, testing.md.
Design documents (docs/design/) are reference material about the
template library itself — not conventions for projects using it.
They cover how the library should be reasoned about, audited, and
maintained.
Current design documents:
design-notes.md— the library's design record: the customer objective, the operating model it implies, the measured technical debt and the standing risksagent-context-tradeoffs.md— how CLAUDE.md size and startup-block design affect agent latency and qualitytemplate-content-quality.md— operational companion: how to keep the template library in shape so it doesn't dilute the agent's attention, with implications for code review, smoke tests, structure audit, and 360efficacy-benchmark.md— the experiment, its rules fixed in advance, that measures whether a generated context file improves an agent's output, and the harness a template change is measured withtesting-ai-assets.md— the generic method the benchmark applies: paired old-versus-new runs, a layered and calibrated judge, and a sealed test set, for measuring any template, skill or prompt change
Resolution selects source files; project adoption selects operative rules.
The dependency graph and section overrides remain deterministic discovery
mechanisms. A consumer update does not automatically adopt new rules or create
compliance work. Apply "Adopting shared rules" in
templates/base/core/docs.md, and inline that boundary in reference/hybrid
context files. Existing adopted rules remain effective until deliberately changed.
Each base template section is tagged with a unique ID:
## Git conventions [ID: base-git]
...A stack template overrides a section by referencing its ID:
## Git conventions [OVERRIDE: base-git]
- Always test with `npm run dev` before committing ← replaces base ruleA stack template extends a section by referencing its ID:
## Git conventions [EXTEND: base-git]
- Do not commit `dist/` or `node_modules/` ← added on top of base rulesIf no override or extend is declared, the base section is used as-is.
A section header MAY combine multiple tags. The valid patterns:
## Heading
[ID: section-id]## Heading
[ID: section-id]
[DEPENDS ON: path/to/dep.md, path/to/other.md]## Heading
[ID: section-id]
[EXTEND: parent-id]## Heading
[ID: section-id]
[OVERRIDE: parent-id]Rules:
[ID:]names the section — MUST appear first when combined[DEPENDS ON:]declares file-level dependencies — metadata, not content[EXTEND:]/[OVERRIDE:]declares the relationship to a parent- A section's content starts after all tag lines
- A section is bounded by the next
[ID:]tag or end of file - A section MUST NOT be empty — at least one content line (heading, bullet, paragraph, table, or code block) MUST follow the tags
A rule that names another section in running prose — "base-quality-gates
states which categories a project MUST gate" — is not a directive and is
not resolved. It costs reach instead: the referencing file and the
referenced one sit at different depths in the graph, so the reference
reads correctly in the chains carrying both and dangles in the rest.
base-git resolves into every chain and base-examples into a subset
of them, so a reference from the first to the second is unreadable in
the rest.
State the substance inline instead. Where a cross-file reference is genuinely wanted, the declaring file MUST be present in every chain that carries the referencing one — SYS-11 checks this per chain, because the defect is invisible from either file on its own. See ADR-028 for the full rationale.
An orthogonal template is the sharpest case. It reaches a reader through
no stack chain at all, so its guaranteed context is the core tier plus
its own depends_on tree, and nothing beyond what it declares. A
reference out of that is unreadable for every project that opts in.
When multiple templates reference the same section ID, the following order applies — higher numbers win:
- Base template — the default; always the lowest precedence
- Layer template (frontend / backend) — overrides or extends the base
- Stack template — overrides or extends the layer or base
- Interview answers — the highest precedence; always win over any template
Example: templates/base/core/testing.md defines the test naming convention.
templates/stack/python-fastapi.md
extends it with a Python-specific pattern. The interview answer "use BDD-style
names" overrides both. The final output uses the interview answer.
A conflict occurs when two templates at the same layer reference the same
section ID with different directives (OVERRIDE vs EXTEND).
Rule: the more specific directive wins.
| Situation | Resolution |
|---|---|
One template EXTENDs, another OVERRIDEs the same ID |
OVERRIDE wins — it replaces the base; the EXTEND is applied on top of the overridden content |
Two templates both OVERRIDE the same ID |
Error — the agent MUST surface this conflict to the user and ask which override to apply |
Two templates both EXTEND the same ID |
Both extensions are applied; order follows the dependency declaration in the stack template |
A stack that depends on another stack MUST NOT override an ID its
dependency already overrides — that is the error above, and the chain
states no winner. The overriding section declares an [ID:] of its own,
and the next level overrides that:
frontend/static-site.md [ID: static-site-content]
stack/static-site-astro.md [ID: astro-content] [OVERRIDE: static-site-content]
stack/static-site-tutorial.md [ID: tutorial-content] [OVERRIDE: astro-content]
Each ID is overridden once, and every level stays available to a stack
that wants to specialise it. SAIT-SMK-TPL-10-001A fails a chain that
overrides one ID twice.
When a conflict cannot be resolved by the rules above, the agent must:
- Show the user both conflicting rules
- Ask which takes precedence
- Record the decision in the
[OVERRIDES]section of the interview output
The interview template groups questions by concern:
[IDENTITY] Project name, owner, URL, deployment target
[STACK] Framework, JS interactivity, CSS approach, content format
[DESIGN] Aesthetic, colours, typography
[BRAND] Tagline, tone, copy rules
[CONTENT] Sections, data files, pages
[SERVICES] Analytics, forms, third-party integrations
[BROWSERS] Supported browsers and versions
[OVERRIDES] Any base rules the user wants to change
[OUTPUT] Target AI tool and output file format
The agent asks all REQUIRED questions before generating anything. DEFAULTED sections are pre-filled from the selected base + stack templates.
- User provides
templates/INTERVIEW.mdand a stack template (e.g.templates/stack/python-fastapi.md) - Agent reads the stack template, identifies its base dependencies
- Agent loads the referenced base templates
- Agent runs the interview (REQUIRED questions only)
- Agent merges: base defaults + stack overrides + interview answers
- Agent loads the output format template for the chosen AI tool
- Agent renders and outputs the final context file
The interview instructions use neutral language ("ask the user") so any agent can follow them without tool-specific interpretation.
The current workflow (above) requires the agent to manually navigate template files. The target model replaces hand-curated file lists with a declarative header that the agent resolves at startup.
┌─────────────────────────────────────────────────┐
│ 1. SETUP (once) │
│ Agent runs INTERVIEW.md → generates │
│ CLAUDE.md with a declaration block │
├─────────────────────────────────────────────────┤
│ 2. STARTUP (every session) │
│ Agent reads CLAUDE.md → reads │
│ templates/manifest.yaml → resolves dependency chain │
├─────────────────────────────────────────────────┤
│ 3. DEVELOPMENT (during session) │
│ Full context loaded — agent applies the │
│ resolved rules without prompting │
├─────────────────────────────────────────────────┤
│ 4. UPDATE (on upstream change) │
│ git submodule update --remote │
│ Next session resolves the same chain → │
│ picks up new/changed rules on next session │
└─────────────────────────────────────────────────┘
The generated CLAUDE.md contains a machine-readable header instead of a hand-curated file list:
Stack: static-site-astro
Extras: data-quality, 360, issues, scope, review, readme
Platform: github| Field | Required | Description |
|---|---|---|
Stack |
MUST | Stack ID from manifest.yaml |
Extras |
MAY | Comma-separated base template IDs not in the stack's dependency chain |
Platform |
MAY | Platform ID (github, gitlab) |
Input: declaration block + templates/manifest.yaml.
Output: ordered list of template files to load.
1. Look up Stack ID in templates/manifest.yaml
2. Recursively resolve depends_on → collect all
transitive dependencies (depth-first, deduplicated)
3. Resolve each Extra the same way — its depends_on
tree first, then itself (skip anything already
in the resolved set)
4. Resolve the Platform template the same way (if
declared)
5. Return the ordered file list
templates/base/core/agents.md is not appended. It governs how the output
is written — structure, model selection, formatting — so it is an input to
generation, applied by whoever produces the file, not a rule file the chain
loads. The diagram above shows it in that position. A project that wants its
rules in the chain declares it as an Extra, where it resolves as its own root
like any other opt-in template.
Ordering: base → backend/frontend → stack (topological sort of
the dependency graph). Within the same depth level, order follows
the depends_on list declaration order.
py tools/resolve.py stack-astrotemplates/base/core/quality.md
templates/base/core/git.md
templates/base/core/docs.md
templates/base/core/readme.md
templates/base/core/testing.md
templates/base/core/review.md
templates/base/core/oop.md
templates/base/security/security.md
templates/frontend/ux.md
templates/frontend/quality.md
templates/frontend/static-site.md
templates/base/language/typescript.md
templates/base/core/config.md
templates/base/workflow/quality-gates.md
templates/stack/static-site-astro.md
py tools/resolve.py stack-flasktemplates/base/core/quality.md
templates/base/core/git.md
templates/base/core/docs.md
templates/base/core/readme.md
templates/base/core/testing.md
templates/base/core/review.md
templates/base/core/oop.md
templates/base/core/config.md
templates/backend/http.md
templates/backend/database.md
templates/backend/observability.md
templates/base/security/security.md
templates/base/infra/containers.md
templates/backend/quality.md
templates/backend/features.md
templates/backend/messaging.md
templates/base/infra/cicd.md
templates/base/security/devsecops.md
templates/base/data/data-modeling.md
templates/base/data/data-quality.md
templates/base/language/python.md
templates/base/core/cli.md
templates/base/workflow/quality-gates.md
templates/base/core/examples.md
templates/stack/python-lib.md
templates/stack/python-service.md
templates/stack/python-flask.md
templates/base/[concern].md # cross-cutting — applies to all projects
templates/frontend/[concern].md # frontend layer — UI projects only
templates/backend/[concern].md # backend layer — services and APIs only
templates/stack/[framework].md # concrete — extends base + frontend or backend
templates/stack/[framework]-[variant].md # variant of a framework (e.g. astro-ssr.md)
templates/base/core/agents.md # output format — structure, models, formatting rules
templates/INTERVIEW.md # orchestrator — always one file
docs/SPEC.md # this file
See GitHub milestones.