@aws-mdaa/agent-rulesTool-agnostic AI agent steering rules for MDAA. Author each rule once under
the repo-root agent_rules/<name>.md directory and project a thin,
tool-specific wrapper into every supported assistant's expected layout.
MDAA contributors and downstream consumers use a mix of AI coding assistants: Kiro, Claude Code, GitHub Copilot, Cursor, Windsurf. Each tool reads rules from a different path with a different frontmatter dialect. Maintaining a full copy of every rule per tool causes drift. This package keeps the canonical content in one place and emits per-tool projections deterministically.
Projections contain only tool-specific frontmatter plus a reference back to the canonical source — no rule body is duplicated. Editing a rule's content does not change any projection; only changing its scope, globs, description, or tool list does.
The canonical rules live at the repo root (agent_rules/), so they can be
copied wholesale into consumer projects (e.g. by mdaa init) with their
repo-root-relative references intact. The tooling that projects them lives in
this package.
agent_rules/ # canonical rules at repo root: frontmatter + body
├── review-compliance.md
├── developer-coding-standards.md
├── user-config-authoring.md
└── ...
packages/utilities/agent-rules/
├── lib/ # TypeScript source
│ ├── types.ts
│ ├── manifest.ts # frontmatter parser + validator, rulesForTool()
│ ├── source-loader.ts # auto-discovers agent_rules/*.md, parses frontmatter
│ ├── include-resolver.ts
│ ├── projectors/ # one file per supported tool
│ ├── projector.ts # writes projections, prunes stale files
│ └── run-projections.ts # build entry point
├── test/ # jest unit + integration tests
└── README.md
There is no manifest.yaml and no CLI. Rules are auto-discovered from the
repo-root agent_rules/ directory and metadata is read from each file's
frontmatter.
Rule file stems are prefixed by audience:
| Prefix | Audience |
|---|---|
review- |
Consumed by the CI review agents |
developer- |
Guidance for developers working in the repo |
user- |
Guidance for end-users configuring/deploying MDAA |
Each rule is a Markdown file under agent_rules/<name>.md with tool-agnostic
YAML frontmatter followed by the body:
---
scope: fileMatch # always | auto | manual | fileMatch
description: ... # optional; one-line summary surfaced by auto-loaders
globs: # required when scope: fileMatch
- 'packages/**/*.ts'
tools: # optional; defaults to all supported tools
- kiro
---
# Rule Title
Body content...
The frontmatter is tool-agnostic. The projector translates it into each tool's
native dialect (scope: manual → Kiro inclusion: manual, Cursor
alwaysApply: false, Windsurf trigger: manual, etc.).
Rule bodies may use the Kiro #[[file:RELATIVE_PATH]] directive to reference
sibling repo files (e.g. CONTRIBUTING.md); Kiro resolves these at runtime.
| Scope | Behavior |
|---|---|
always |
Loaded into every agent session unconditionally |
auto |
Loaded automatically by tools that support description-based activation; degrades to manual elsewhere |
manual |
Loaded only when explicitly referenced |
fileMatch |
Loaded when the agent operates on files matching globs |
Set tools: [kiro] on a rule that only makes sense in one host. For example,
review-preamble.md is restricted to Kiro because the MDAA review-agent
infrastructure (scripts/review/lib/kiro_integration.py) consumes it directly.
| Tool | Output path | Reference style |
|---|---|---|
| Kiro | .kiro/steering/<name>.md |
#[[file:...]] include directive |
| Claude Code | CLAUDE.md (always rules), .claude/rules/<name>.md (others) |
Markdown link to canonical source |
| GitHub Copilot | .github/copilot-instructions.md (always), .github/instructions/<name>.instructions.md |
Markdown link; applyTo for fileMatch |
| Cursor | .cursor/rules/<name>.mdc |
@-mention; alwaysApply + globs |
| Windsurf | .windsurf/rules/<name>.md |
@-mention; trigger: frontmatter |
Each projected file references the canonical body at
agent_rules/<name>.md rather than inlining it.
# From this package directory
npm run build # tsc + regenerate all projections
# From the repo root
npx nx build @aws-mdaa/agent-rules
run-projections.ts is invoked automatically as part of npm run build. It is
idempotent: files whose contents already match are not rewritten, and stale
files in each tool's output directory (e.g. a rule that was renamed or removed)
are pruned automatically.
import { loadSources, projectKiro, projectClaude, project } from '@aws-mdaa/agent-rules';
const sources = loadSources(); // auto-discovers agent_rules/*.md
const kiro = projectKiro(sources.rules); // ProjectionResult
const claude = projectClaude(sources.rules);
project({ consumerRoot: process.cwd() }); // write all projections
The full type surface lives in lib/index.ts.
agent_rules/<name>.md (frontmatter and/or body).npm run build to regenerate projections.Because content changes don't alter the thin projections, most content-only edits regenerate nothing — only scope/glob/description/tool changes do.
Never edit the projected files directly (
.kiro/steering/,.claude/rules/,.cursor/rules/,.github/instructions/,.windsurf/rules/,CLAUDE.md). They are generated and carry an auto-generated banner. Edits will be overwritten on the next build.
A developer must be fully set up immediately after checkout, with no extra
build step. Committing the projections means every tool works on clone. The
projections are marked linguist-generated in .gitattributes so they
auto-collapse in MR diffs.
The MDAA review-agent infrastructure additionally has hard dependencies on the canonical sources:
scripts/review/lib/kiro_integration.py reads review-preamble.md directly
(it does not resolve Kiro includes, so it reads the canonical source, not the
.kiro/steering/ wrapper).#[[file:agent_rules/<rule>.md]] directive resolved
at runtime._steering_link() in scripts/review/lib/thread_lifecycle.py builds GitLab
URLs to the canonical sources for MR review threads.test/byte-equivalence.test.ts asserts that every checked-in projection
matches what the projector produces and that no stale/unprojected files
remain in .kiro/steering/.Apache-2.0 — see the repository LICENSE.