Use Groundrule without the platform
The Groundrule CLI is open source and works without an account. You pick packs, write your own standards as YAML files, and run sync and check locally and in CI. Nothing leaves your machine. This page shows the offline setup, where standards can come from, what you miss without the platform, and how to connect a repository later.
The CLI’s source is at groundrule-oss (Apache-2.0).
Set up a repository offline
Section titled “Set up a repository offline”npx @groundrule/cli init --packs security-baseline,react ✓ Created .groundrule/config.yaml Packs security-baseline, react Agents AGENTS.md, CLAUDE.md, .cursor/rules/ Detected typescript
Next 1. groundrule sync write instructions for your coding agents 2. groundrule check check your current changes 3. Add your own rules in .groundrule/standards/ (see EXAMPLE-001.yaml.sample)Without --packs, init chooses packs from the languages it detects: security-baseline always, plus typescript-node for TypeScript or JavaScript and java-spring for Java. Run npx @groundrule/cli packs to list all 13 bundled packs.
The config it writes:
# yaml-language-server: $schema=https://groundrule.dev/schemas/v1alpha1/config.schema.jsonapiVersion: groundrule.dev/v1alpha1kind: Config
# Shared standards this repository inherits. Add your organization's pack, e.g.# - github:your-org/engineering-standards//packs/backend@v1extends: - groundrule:packs/security-baseline - groundrule:packs/react
# Tags that standards can target with scope.tags, e.g. backend, multi-tenant.tags: []
# Coding-agent instruction files that `groundrule sync` keeps up to date.targets: - agents-md - claude-code - cursor
enforcement: scope: changed-lines # check what a change touches: changed-lines | changed-files | all legacy: report # existing violations: report | ignore | enforce failOn: blocker # lowest severity that fails a check: blocker | warning | noneEvery line is explained in Connect a repository.
Write the agent files and check
Section titled “Write the agent files and check”npx @groundrule/cli sync groundrule sync · 32 standards → agents-md, claude-code, cursor
+ .cursor/rules/groundrule.mdc created + AGENTS.md created ~ CLAUDE.md updated
✓ Done. Commit these files so every agent gets the same rules.npx @groundrule/cli check --all groundrule check · 32 standards · 7 files (full audit)
⚠ REACT-006 Give every img an alt attribute warning · deterministic (regex) src/components/Hero.tsx:1 <img> without an alt attribute 1: export const Hero = () => <img src="/hero.png" style={{ width: 300 }} />; → Add alt="what the image shows" for meaningful images, or alt="" if it is decorative. → groundrule explain REACT-006
Passed ✓ 17 passed ⚠ 1 warning ◇ 14 guidance · 0.0sOffline, there are no rollout stages. Every standard that applies goes into the agent files, and every check runs at the standard’s own severity. Here, 32 standards from two packs reach the agents, and 17 checks pass. To soften a rule, change its severity or turn it off in overrides (below). Commit .groundrule/ and the agent files.
Write your own standards
Section titled “Write your own standards”Put standards in .groundrule/standards/, one YAML file each. The sample init created shows the shape:
mv .groundrule/standards/EXAMPLE-001.yaml.sample .groundrule/standards/PLAT-001.yamlEdit the file: change id to PLAT-001, and write your own title, requirement, and checks. Then run sync and check. A standard with no checks is guidance: it reaches the agents but is never checked.
apiVersion: groundrule.dev/v1alpha1kind: Standardmetadata: id: PLAT-001 title: Use the shared HTTP client type: forbidden-tech owner: team:platformspec: severity: warning intent: One HTTP client means one place for retries, timeouts, and tracing. requirement: > Use our shared HTTP client for outbound calls. Do not add axios or got. remediation: Replace the dependency with the shared client. checks: - evaluator: dependencies forbid: [axios, got]Every field is in The rule format, and every check type in Checks.
Each ID must be unique. If a file reuses an ID from a pack, every command stops with “Duplicate standard <ID>; also defined in <file>. Use config overrides to change an inherited standard.”
By default, the CLI reads .groundrule/standards/**/*.yaml. Change it with standards: in the config, with globs relative to .groundrule/.
Change a pack rule: overrides
Section titled “Change a pack rule: overrides”You don’t edit a pack. You override it in the config:
overrides: TS-001: severity: advisory reason: Our CLI tools print to the console by design. REACT-002: disabled: true reason: Lists here are static and never reorder.| Field | Meaning |
|---|---|
severity |
A new severity: blocker, warning, advisory, or info. explain shows “(overridden from …)”. |
disabled |
true turns the rule off: it leaves the agent files and isn’t checked. |
reason |
Why. Shown by explain. |
An override for an ID that doesn’t exist warns “Override for unknown standard <ID>.” To excuse specific files instead of the whole repository, use a time-boxed exception. See Overrides and exceptions.
Where standards can come from: extends
Section titled “Where standards can come from: extends”extends lists sources. Three forms are supported:
| Form | Example | What it loads |
|---|---|---|
| Bundled pack | groundrule:packs/security-baseline |
A pack that ships with the CLI. |
| GitHub | github:acme/engineering-standards//packs/backend@v1 |
A folder in a GitHub repository, at a tag, branch, or commit. |
| Local path | ./shared/standards or ../platform/packs/backend |
A folder or pack file on disk, relative to .groundrule/. |
A source that is a folder with a pack.yaml loads that pack. A folder without one loads every .yaml and .yml file in it. A source that is a file must be a pack file.
Bundled packs
Section titled “Bundled packs”Bundled packs come with the CLI, so they work without a network. Their content changes only when you update the CLI. To keep everyone on the same rules, pin the CLI version (see Install the CLI). An unknown name stops with “Unknown pack “groundrule:packs/…”. Run groundrule packs to list them.”
Your organization’s packs on GitHub
Section titled “Your organization’s packs on GitHub”Share standards across repositories by keeping them in one repository, for example acme/engineering-standards, and extending it:
extends: - groundrule:packs/security-baseline - github:acme/engineering-standards//packs/backend@v1| Part | Meaning |
|---|---|
acme/engineering-standards |
The GitHub owner and repository. |
//packs/backend |
The folder inside it. Leave out //… to use the repository’s root. |
@v1 |
A tag, branch, or commit. Leave it out to use the default branch. |
How it’s fetched:
- The CLI clones it with your own
git, so private repositories work when your git can read them (SSH keys or a credential helper). The clone never prompts for a password. - Clones are cached in
~/.cache/groundrule/sources(or$XDG_CACHE_HOME/groundrule/sources). - A pinned reference (
@v1) is fetched once and reused. Runsync --refreshto fetch it again. - An unpinned reference is fetched again on every run, so it follows the default branch.
- If the fetch fails, the CLI stops with “Cannot fetch github:acme/engineering-standards@v1. Check the name, the ref, and your git access.”
Pin a tag in CI, so a change to the shared repository doesn’t change a build without a commit.
A pack folder can have its own pack.yaml:
apiVersion: groundrule.dev/v1alpha1kind: Packmetadata: id: acme-backend title: Acme backend version: 1.0.0spec: include: ["standards/**/*.yaml"] extends: - groundrule:packs/typescript-nodeinclude lists the standard files, relative to pack.yaml. extends builds on other packs, with the same forms as the config. A pack that extends itself stops with “Pack extends itself (circular extends).”
What works offline, and what doesn’t
Section titled “What works offline, and what doesn’t”| Works offline | Needs the platform |
|---|---|
init --packs, sync, sync --check, check, standards, explain, doctor, packs |
login, logout, whoami |
scan and scan --json (nothing leaves your computer) |
scan --upload |
The MCP server’s list_standards |
propose, and the MCP server’s propose_rule |
| Bundled packs, local standards, packs from GitHub, overrides, exceptions | One rulebook across every repository, edited in the dashboard |
| Rollout stages (Observe, Teach, Advise, Enforce) and promotions | |
| Teams, owners, roles, and stricter settings per team or repository | |
| The review inbox and imports from scans, documents, and pull requests | |
| Evidence across repositories | |
| AI that drafts rules for people to review |
Connect to the platform later
Section titled “Connect to the platform later”When your team adopts the platform, you keep the same commands. Only the config’s source of rules changes.
- Sign in:
npx @groundrule/cli login. - Replace the config, keeping your own standards:
npx @groundrule/cli init --org acme-payments --force. This replacesextendswithplatform: { org: acme-payments }. Re-add anytags,targets, orenforcementchanges you had made. - In the dashboard, adopt the packs you had in
extends. Recreateoverridesas rule settings for the repository or its team. - Run
npx @groundrule/cli syncand commit.
Your files in .groundrule/standards/ keep working in the connected repository. If one has the same ID as a workspace rule, the workspace’s version applies and the CLI warns. To share a local standard with every repository, write it in the dashboard instead. npx @groundrule/cli scan --upload also imports the instructions from your agent files into the workspace’s inbox.
If you leave extends or overrides in a connected config, the CLI ignores them for workspace rules and warns you.