Writing rules
Author, scope, and maintain Apothem behavioral rules.
Rules are Markdown files in src/apothem/rules/ with .md extension.
Rule frontmatter
---
name: "..."
description: "..."
pathFilter: "" # empty string for always-on; a glob for path-filtered
alwaysApply: true # true for always-on; false for path-filtered
---Rule scopes
A rule's scope is set by two frontmatter fields, alwaysApply and
pathFilter:
alwaysApply | pathFilter | When applied |
|---|---|---|
true | "" (empty) | Always-on: every session, every file |
false | a glob like "**/*.py" | Path-filtered: only when the active file matches the glob |
Five shipped rules are always-on: agnostic-posture, authority-inquiry,
session-closure, context-management, and the rule index. An always-on rule
costs context in every session, so a new rule SHOULD be path-filtered with globs
that name the files it governs; a filter of ** alone scopes nothing, and Claude
Code loads that rule at launch like an always-on one. The
shipped corpus holds the always-on set to that list and to a byte ceiling; a
rule promoted to always-on changes both in the same change. Name each rule you
add in the rule index (apothem-rule-index), so a session on a harness that
does not scope rules by path still finds it. A companion rule
(<parent>-<aspect>) takes its parent's pathFilter, or a narrower one, so it
never loads without its parent. Do not give a rule of your own the name
apothem-rule-index: an install backs up and overwrites a rule file with that
name.
Example rule
---
name: "python-conventions"
description: "Python style conventions for this project"
pathFilter: "**/*.py"
alwaysApply: false
---
# Python conventions
- Use type annotations on all public functions.
- Maximum line length: 88 characters.
- Prefer explicit over implicit.Applying rules to harnesses
After writing a rule, update each installed harness adapter. Run
apothem harnesses list to see the installed set, then call update once per
harness:
apothem update --harness claude-code
apothem update --harness cursor --project /path/to/projectA project-scope harness needs --project on update, as in the second line;
a user-scope harness does not.
Rule validation
Run the frontmatter validator against the rule file you wrote. From an Apothem
checkout, PYTHONPATH=src makes the package importable; after a script install,
use PYTHONPATH="$HOME/.apothem/src" in its place.
PYTHONPATH=src python -m apothem.conformity.gate --check frontmatter-grep src/apothem/rules/<rule>.mdA per-write check such as frontmatter-grep takes the file to check, or
--stdin to read the content from standard input; with neither it waits for
input on standard input. A standalone check takes a root directory instead, as in
--check naming-grep ..