Rules

Atomic, normative rules that the ops-core resolver injects into agent context for code generation. Each file holds one rule with an ID, the archetypes it applies to, and the mechanism that enforces it. Everything else in the vault (references, patterns, research) is guidance for people and is never injected.

Decisions behind these rules are recorded in Code Generation Decisions. The human-readable package contract they derive from is Package Conventions.

Current rules

IDRuleArchetypesSeverityCore
STD-TS-001Strict compiler baselineA7BLOCKno
STD-TS-002NodeNext for Node-run codeA4, A7, A8, A14, A17BLOCKyes
STD-TS-003Bundler for bundled appsA9, A10, A11, A12, A20, A22BLOCKyes
STD-TS-004Explicit exported typesA4, A7, A8BLOCKyes
STD-TS-005No any, no suppressionA4, A7, A8BLOCKyes
STD-TS-006Error handling by kindA7ADVISORYyes
STD-TS-007Canonical Result typeA7ADVISORYyes
STD-PKG-001Zero runtime dependenciesA7BLOCKyes
STD-PKG-002ESM-only manifestA7ADVISORYno
STD-PKG-003Named exports via indexA7BLOCKyes
STD-PKG-004No top-level side effectsA7ADVISORYyes
STD-PKG-005Never mutate inputsA7ADVISORYyes
STD-TOOL-001ESLint flat config onlyall TypeScript and JS archetypesBLOCKno
STD-TOOL-002npm with a lockfileA7BLOCKno
STD-TEST-001Unit and acceptance layoutA7BLOCKyes
STD-TEST-002Requirement-tagged testsA7BLOCKyes
STD-TEST-003Inject randomness and timeA7WARNyes

Core rules are injected for every task in a matching archetype. The others cover protected config files that agents cannot edit; the resolver adds them only when a task names them in its rules field, for example a kernel or scaffold task.

How a rule is used

  1. The owner commits a task file whose vault_commit pins this vault and whose rules field names any extra rule IDs (CGD-09).
  2. The ops-core resolver builds or reads the bundle for that commit and selects core rules for the target repo’s archetype, plus the named rules.
  3. Only the Rule, Do, Don’t and Exceptions sections are injected. Rationale and Related stay in the vault for people.
  4. CI records which rules were injected, so review can tell whether a failure came from the rule or from the agent.

Rule file format

Rules live in obsidian/rules/<domain>/<ID>-<slug>.md, with domains typescript (STD-TS), package (STD-PKG), testing (STD-TEST) and tooling (STD-TOOL).

Frontmatter fields:

FieldMeaning
idSTD-<DOMAIN>-NNN, never reused
typeAlways rule
statusdraft, active or deprecated; only active rules are bundled
applies_toarchetypes (build plan IDs; A15 does not exist) and languages
coretrue to inject for every task in a matching archetype
severityBLOCK or WARN need an active mechanical check; ADVISORY is review-only (CGD-08)
enforcementList of { kind, ref }; add planned: true for checks not built yet
decisionsCGD IDs this rule implements
last_verifiedDate the rule was last checked against its enforcement and sources

Enforcement kinds: eslint (rule name, optional options), tsconfig (compiler option, optional value), bp (A7 Delta banned pattern), semgrep (A7 Delta rule ID), policy (A7 checker control), preflight (preflight step), review (stage S1 to S3), script (must be planned until a runner exists).

Body sections, in order: ## Rule (80 words or fewer, no code), ## Do, ## Don't, optional ## Exceptions, ## Rationale, ## Related. Headings stop at H3. At least two wikilinks.

Validation

npm run validate:rules                                  # Validate every rule
npm run validate:rules -- --bundle dist/rules.json      # Validate, then write the pinned bundle

The validator checks every enforcement reference against the real ESLint, TypeScript and A7 Delta catalogs, so an invented rule name fails. It typechecks and lints each Do snippet and confirms each Don’t snippet is caught by one of the rule’s own checks. A fence written as ```ts nocheck skips compile and lint for snippets that import other modules. Don’t snippets whose only checks are policy, Semgrep or review cannot be replayed and are counted as unverified.

4 items under this folder.