The rule format
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 standards live
Section titled “Where standards live”| 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.
A minimal standard
Section titled “A minimal standard”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/v1alpha1kind: Standardmetadata: id: ACME-001 title: Use the shared HTTP client type: requirementspec: 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.
Top level
Section titled “Top level”| 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.
metadata
Section titled “metadata”| 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”. |
Statuses
Section titled “Statuses”| 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.Severities
Section titled “Severities”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:
- Repository level.
languages,frameworks,tagsandrepositoriesdecide 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)ingroundrule standards. - File level.
pathsandexcludedecide which files the standard’s checks read. A Java standard still seespom.xmlif itspathsinclude 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.
examples
Section titled “examples”| 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.checks
Section titled “checks”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 gatewayConfidences
Section titled “Confidences”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.
exceptions (policy)
Section titled “exceptions (policy)”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.
references
Section titled “references”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/compliance
Section titled “compliance”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".
applicability
Section titled “applicability”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. |
quality
Section titled “quality”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.
rollout
Section titled “rollout”| 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.
A complete example
Section titled “A complete example”# yaml-language-server: $schema=https://raw.githubusercontent.com/Metricall-AI-Lab/groundrule-oss/main/packages/spec/schemas/standard.schema.jsonapiVersion: groundrule.dev/v1alpha1kind: Standardmetadata: 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: adviseCheck 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.
Validation in your editor
Section titled “Validation in your editor”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.jsonYou 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.
Writing YAML that loads
Section titled “Writing YAML that loads”- Quote regular expressions with single quotes. In double quotes, YAML treats
\as an escape, and"\w"fails withInvalid 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.
Related
Section titled “Related”- Checks: every evaluator and option.
- Overrides and exceptions
- Configuration
- Write a standard in the dashboard.