Skip to content
Open the dashboard
Developer docs

The rule format

Developers

A standard is one YAML file. This page lists every field it can have, with its type, whether it is required, its default, and every allowed value. The same format is used by the CLI, by the packs, and by the dashboard, which edits the same documents. The format is defined in the open-source repository, in packages/spec.

Where Used by
.groundrule/standards/*.yaml in a repository That repository. The standards setting in the configuration changes the pattern; the default is standards/**/*.yaml inside .groundrule/.
A pack, such as groundrule:packs/security-baseline Every repository whose config extends it. See Packs reference.
A folder or pack in another Git repository Repositories that extend github:owner/repo//path@ref.
Your workspace on Groundrule Every connected repository. Standards you create in the dashboard use this format too, and the editor has a YAML view. See Write a standard.

One file holds one standard. Files ending in .sample, such as the EXAMPLE-001.yaml.sample that init writes, are not loaded.

Seven fields are required: apiVersion, kind, metadata.id, metadata.title, metadata.type, spec.severity and spec.requirement. This is the smallest valid standard:

apiVersion: groundrule.dev/v1alpha1
kind: Standard
metadata:
id: ACME-001
title: Use the shared HTTP client
type: requirement
spec:
severity: warning
requirement: Use @acme/http-client for every outbound HTTP call.

With no checks, it is guidance: it reaches agent files, and check reports it as guidance only.

Field Type Required Value
apiVersion string Yes Always groundrule.dev/v1alpha1, the version of the format.
kind string Yes Always Standard.
metadata object Yes Identity and ownership. See metadata.
spec object Yes The rule itself. See spec.

Every object in the format is strict: an unknown key is an error. A typo such as sevrity: fails with spec.sevrity: Unrecognized key: "sevrity", pointing at the file, line and column. The one exception is a check, which takes options for its evaluator.

Field Type Required Default Description
id string Yes A unique, stable identifier. See IDs.
title string Yes One line, 1 to 120 characters. Shown everywhere the rule is listed.
type enum Yes What kind of rule it is. See Types.
status enum No active Where the standard is in its life. See Statuses.
version integer No 1 1 or more. Bump it on every change in meaning. Findings record the version they were checked against.
owner string No Who owns and can change the standard, for example team:security-engineering. Free text.
category string No A free-form grouping, for example security or data. Used to group rules, and added as a tag in SARIF output.
labels list of strings No Extra labels for your own use.

An ID is an uppercase prefix, optional uppercase segments, a dash, and a number: AUTH-017, DATA-021, AI-003, CLAIMS-API-001. The exact pattern is ^[A-Z][A-Z0-9]*(?:-[A-Z][A-Z0-9]*)*-[0-9]+$.

  • A wrong ID fails with Standard IDs look like AUTH-017: an uppercase prefix, a dash, and a number.
  • Two standards with the same ID in one repository are an error: Duplicate standard ACME-004; also defined in …. Use config overrides to change an inherited standard.
  • In a connected repository, an ID that is also an organization rule is ignored with a warning: ACME-004 is also an organization rule; the organization's version applies. Give this one a new ID.

Don’t reuse an ID for a different rule. Overrides, exceptions, findings and fingerprints all refer to it.

The type says what kind of rule it is. It doesn’t change how checks run.

Value Use it for
guidance Advice and conventions.
requirement Something that must be true, such as “Validate every request against a schema”.
prohibition Something that must never happen, such as “No private keys in the repository”.
invariant A property that must always hold.
approved-tech A library, tool or service to use.
forbidden-tech A library, tool or service not to use, such as “Do not add axios”.
process The shape of a change, such as “Schema changes include a migration”.
repository What the repository contains, such as “Commit a dependency lockfile”.
agent-instruction How coding agents should work, such as “Ask before destructive operations”.
Value In agent files Checked Notes
draft No No Being written. groundrule standards lists it as (draft). In a connected workspace, scan --upload tests drafts so you see their evidence before publishing.
active Yes Yes The default.
deprecated Yes Yes Still in effect, on its way out.
retired No No Kept for history.
Field Type Required Default Description
severity enum Yes How much a violation matters. See Severities.
requirement string Yes What must, or must not, be true. Be specific. This is the text agents read unless you set agent.summary.
scope object No {} (everywhere) Where the standard applies. See scope.
intent string No Why the standard exists, in one or two lines. Shown as Why by explain and in the dashboard.
rationale string No Longer background: trade-offs and history.
examples object No Code that follows and breaks the rule. See examples.
remediation string No How to fix a violation. Shown with every finding, unless the check gives its own fix.
agent object No { instruction: true } How the standard reaches coding agents. See agent.
checks list No [] Automated checks. Empty means guidance only. See checks.
exceptions object No The policy for exceptions to this standard. See exceptions.
references list No Links to ADRs, docs, incidents, or catalog entries such as CWE-798. See references.
compliance list No Compliance controls this standard supports. See compliance.
applicability object No Which repositories the standard is relevant to, for recommendations. See applicability.
quality object No The expected noise of the checks, for people adopting it. See quality.
rollout object No The recommended starting stage. See rollout.

Long text fields read best as YAML folded blocks (>), which join lines with spaces:

requirement: >
Never import stripe outside src/payments/gateway.ts. Call the gateway's
functions, such as createPaymentIntent, instead.

From least to most severe:

Value Meaning
info Context only.
advisory A recommendation that doesn’t block.
warning Visible; needs acknowledgment.
blocker Fails the check.

Whether a finding fails check also depends on enforcement.failOn (default blocker) and, in a connected workspace, on the rule’s stage. See Configuration and Rollout stages.

Every field narrows where the standard applies. A field you leave out doesn’t restrict anything, so an empty scope applies everywhere.

Field Type Applies at Description
paths list of globs File The files the standard applies to, for example src/**.
exclude list of globs File Files excluded even when paths matches them, for example src/payments/gateway.ts.
languages list of strings Repository For example java, typescript.
frameworks list of strings Repository For example spring-boot, react.
tags list of strings Repository Tags the repository declares in its config, for example multi-tenant.
repositories list of globs Repository Repository names, for example backend-*.

Two levels decide where a standard applies:

  1. Repository level. languages, frameworks, tags and repositories decide whether the standard applies to the repository at all. One match in each list you set is enough. Values are compared without regard to case. A standard that doesn’t apply is left out of agent files and shows as (not applicable here) in groundrule standards.
  2. File level. paths and exclude decide which files the standard’s checks read. A Java standard still sees pom.xml if its paths include it.

Globs match paths relative to the repository root, with / separators. ** matches any number of folders, and dot files are matched too.

The CLI detects languages from file extensions:

Language Extensions
typescript .ts, .tsx, .mts, .cts
javascript .js, .jsx, .mjs, .cjs
java .java
kotlin .kt, .kts
scala .scala
python .py
go .go
rust .rs
ruby .rb
php .php
csharp .cs
swift .swift
c .c, .h
cpp .cc, .cpp, .hpp
terraform .tf
vue, svelte .vue, .svelte

It detects frameworks from manifests:

Framework Detected when
react, nextjs, vue, svelte, angular, express, fastify, nestjs, hono package.json declares react, next, vue, svelte, @angular/core, express, fastify, @nestjs/core or hono as a dependency, dev dependency or peer dependency.
spring-boot, quarkus, micronaut pom.xml, build.gradle or build.gradle.kts mentions spring-boot, io.quarkus or io.micronaut.
django, flask, fastapi pyproject.toml or a requirements*.txt file lists them.

Tags aren’t detected. You declare them in the repository’s config, under tags.

Field Type Description
approved list of examples Code that follows the rule.
forbidden list of examples Code that breaks it.

Each example is either a plain string or an object:

Field Type Required Description
code string Yes The code.
language string No The language, for syntax highlighting, for example ts or java.
note string No One short remark, such as Trusts a client-supplied role.
examples:
approved:
- code: import { createPaymentIntent } from "../payments/gateway";
language: ts
forbidden:
- code: import Stripe from "stripe";
language: ts
note: Direct Stripe import
- "new Stripe(process.env.STRIPE_KEY)"

Agent files show only the first approved and the first forbidden example. explain and the dashboard show all of them. See Agent instruction files.

Field Type Default Description
instruction boolean true Include this standard in generated agent files (AGENTS.md, CLAUDE.md, Cursor, Copilot). Set false for a rule that only CI should check.
summary string One or two sentences written for an agent. Defaults to the requirement. Also used by the MCP server’s list_standards.

Write summary when the requirement is long or written for reviewers:

agent:
summary: >
In Dockerfiles, pin every FROM image to an explicit version tag or digest;
never use :latest or an untagged image.

A list of automated checks. Each one names an evaluator. Every other key is an option for that evaluator.

Field Type Required Description
evaluator string Yes Which evaluator runs the check: regex, files, dependencies, change-set, semgrep, or llm (not yet available). Lowercase.
minConfidence enum No Findings below this confidence are reported as concerns, not violations. One of low, medium, high, certain.
other keys Options for the evaluator, validated by it.

A standard can have several checks. Its findings are the findings of all of them. Every evaluator and option is in Checks.

checks:
- evaluator: regex
pattern: '\bfrom\s+["'']stripe["'']'
message: Stripe imported outside the payments gateway

Each finding has a confidence, from least to most sure: low, medium, high, certain. The regex, files, dependencies and change-set evaluators always report certain. semgrep reports high. A violation below a check’s minConfidence becomes a concern: it is shown as possible (?) and never fails check.

Who may grant exceptions to this standard, and for how long.

Field Type Default Description
allowed boolean true Whether exceptions are allowed.
approvers list of strings Who may approve exceptions, for example team:security-engineering.
maxDurationDays integer The longest an exception may last, in days.

groundrule explain shows the policy, for example “Approved by team:security-engineering, for up to 90 days.” The CLI doesn’t enforce it yet: review exceptions against it in your pull requests.

A list. Each entry is a URL, or an object:

Field Type Description
id string An identifier in a public catalog, up to 64 characters, for example CWE-798 or OWASP-A02:2021.
title string Up to 200 characters.
url URL A link.

An object needs an id, a url, or both (A reference needs an id, a url, or both). For CWE-<number> IDs without a URL, the CLI links to the CWE page.

references:
- { id: CWE-798, title: Use of Hard-coded Credentials }
- https://docs.docker.com/build/building/best-practices/

A list of controls the standard supports. A mapping means that following the standard contributes evidence for the control. It never satisfies the control alone.

Field Type Required Description
framework string Yes The framework ID: lowercase letters, digits and dashes.
controls list of strings Yes At least one control ID within the framework, each up to 64 characters, for example CC6.1 or 8.28.

Known framework IDs:

ID Framework
soc2 SOC 2 (Trust Services Criteria)
iso-27001 ISO/IEC 27001:2022 Annex A
owasp-asvs OWASP Application Security Verification Standard 4.0
pci-dss PCI DSS v4.0
hipaa HIPAA Security Rule (45 CFR 164)
nist-ssdf NIST Secure Software Development Framework (SP 800-218)

Other IDs are accepted and shown as written.

compliance:
- { framework: soc2, controls: [CC6.1] }
- { framework: iso-27001, controls: ["8.24", "5.17"] }

Quote control IDs that YAML would read as numbers, such as "8.24".

Which repositories the standard is relevant to, used to recommend it. Unlike scope, applicability never limits where an adopted standard is checked. Every field widens relevance. When all are left out, the standard is relevant to any repository its scope fits.

Field Type Description
languages list of strings For example java, typescript.
frameworks list of strings For example spring-boot, react.
files list of globs Files whose presence makes it relevant, for example **/pom.xml.
dependencies list of strings Package names whose presence makes it relevant, for example react.

What people adopting the standard can expect from its checks.

Field Type Required Description
noise enum Yes The expected false-positive rate on typical repositories.
knownFalsePositives list of strings No Situations where the check flags correct code, and how to scope them out.
Noise Meaning Shown in the dashboard as
low Findings are almost always real. Low noise
medium Occasional false positives. Medium noise
high Expect to tune scope or exclusions. High noise

explain lists each known false positive under Adopting it.

Field Type Required Description
recommendedStage enum Yes The stage to start at when adopting this standard.

Organizations decide the actual stage. This is the author’s recommendation, shown as Starts at Teach in the catalog.

Stage Meaning
observe Checked silently; results are only recorded.
teach Delivered to coding agents; checks still run silently.
advise Findings are shown but never fail a check.
enforce Findings count at the standard’s severity; blockers fail the check.

Stages apply to standards in a connected workspace. Offline, every standard in effect is delivered to agents and checked. See Rollout stages.

# yaml-language-server: $schema=https://raw.githubusercontent.com/Metricall-AI-Lab/groundrule-oss/main/packages/spec/schemas/standard.schema.json
apiVersion: groundrule.dev/v1alpha1
kind: Standard
metadata:
id: ACME-004 # stable; overrides and exceptions refer to it
title: Route all Stripe calls through the gateway
type: prohibition
status: active # default
version: 2 # bumped when the meaning changed
owner: team:payments
category: payments
labels: [pci]
spec:
severity: blocker
scope:
paths: ["src/**"]
exclude: ["src/payments/gateway.ts"] # the one file allowed to import stripe
languages: [typescript]
intent: One place for retries, idempotency keys, and audit logging of payments.
rationale: >
Two incidents in 2026 came from direct Stripe calls that skipped idempotency
keys and charged customers twice.
requirement: >
Never import stripe outside src/payments/gateway.ts. Call the gateway's
functions, such as createPaymentIntent, instead.
remediation: Import from src/payments/gateway.ts and call its functions.
examples:
approved:
- code: import { createPaymentIntent } from "../payments/gateway";
language: ts
forbidden:
- code: import Stripe from "stripe";
language: ts
note: Direct Stripe import
agent:
instruction: true # default
summary: >
Only src/payments/gateway.ts may import stripe. Everywhere else, call the
gateway's functions.
checks:
- evaluator: regex
pattern: '\bfrom\s+["'']stripe["'']' # single quotes: no escape processing
message: Stripe imported outside the payments gateway
exceptions:
approvers: [team:payments]
maxDurationDays: 90
references:
- https://docs.stripe.com/api/idempotent_requests
compliance:
- { framework: soc2, controls: [CC8.1] }
quality:
noise: low
knownFalsePositives:
- Test helpers that build Stripe fixtures. Add them to scope.exclude.
rollout:
recommendedStage: advise

Check it with npx @groundrule/cli explain ACME-004, which prints every section as the CLI understood it. npx @groundrule/cli doctor validates every standard in the repository.

JSON Schemas for every document kind are generated from the format and published in the open-source repository under packages/spec/schemas:

Document Schema file
Standard standard.schema.json
Config (.groundrule/config.yaml) config.schema.json
Exception list (.groundrule/exceptions.yaml) exception-list.schema.json
Pack (pack.yaml) pack.schema.json
Any of the above groundrule-document.schema.json
A finding finding.schema.json
A scan report scan-report.schema.json

Editors with the YAML language server (VS Code with the Red Hat YAML extension, JetBrains IDEs) read a comment on the first line:

# yaml-language-server: $schema=https://raw.githubusercontent.com/Metricall-AI-Lab/groundrule-oss/main/packages/spec/schemas/standard.schema.json

You then get completion, descriptions on hover, and errors for unknown keys and wrong values as you type.

The schema can’t validate a check’s options, because they depend on the evaluator. The CLI validates them when it loads the standard, for example: spec.checks[0].pattern: Enter a regular expression.

  • Quote regular expressions with single quotes. In double quotes, YAML treats \ as an escape, and "\w" fails with Invalid escape sequence \w. In single quotes, backslashes are literal; write a single quote as two ('').
  • Quote values YAML would change, such as control IDs like "8.24", dates, and strings starting with *, &, !, { or [.
  • Use folded blocks (>) for long text. They join lines with spaces.
  • Each key once. A repeated key is an error.

Every error names the file, line and column, and the field:

✕ .groundrule/standards/ACME-005.yaml:12:22 Invalid escape sequence \w
✕ .groundrule/standards/ACME-005.yaml:11:3 spec.sevrity: Unrecognized key: "sevrity"

A standard with an error stops sync, check and standards with exit code 2 until you fix it.