Set up repository rules

See the rules ArchDev applies to your pull requests, and add, edit, disable or revert them from the rules page or a session.

On this page

Repository rules turn your team's coding expectations into checks on pull requests. Each rule is a Markdown explanation and a matching Jev evaluation. ArchDev drafts rules from your instruction files and applies them as soon as they are drafted. You change them on the rules page, on the PR page or with archdev rules; nothing is written to your repository.

Violations appear on the archdev.ai PR page. They are advisory: ArchDev does not post them to GitHub or block merging.

See your rules

Connect your GitHub repository, then open https://archdev.ai/OWNER/REPO/rules, replacing OWNER/REPO with your repository. Repositories whose names begin with a dot, such as .github, are supported.

The page lists every rule with its status and where it came from: an instruction file, a starter rule, an edit someone made, or a rule file in your repository. Expand a rule to read its files. Edit, Disable, Enable and Revert to source change it; disabled rules are listed at the bottom. Changing a rule needs write access to the repository on GitHub.

Drafting starts right away when you add a repository to an existing GitHub App installation. For a brand-new installation, the first PR triggers the initial draft. Drafting runs nightly after that.

ArchDev drafts rules from instruction files such as AGENTS.md and CLAUDE.md. When an instruction changes, its rule is redrafted; when the instruction is removed, its rule is retired. A rule you edited keeps your edit, and the page shows that its source changed or was removed. If a repository has fewer than five rules and uses Elixir, Go, TypeScript/JavaScript, Python or Rust, ArchDev also adds starter rules. Archived repositories and forks do not receive starter rules.

Rule files committed to your repository (.md and .jev pairs under .archdev/rules/) still apply. They are read-only on the page, and a rule file outranks an ArchDev rule with the same name. To change one, edit the file in a pull request.

Configure

You can use the defaults without adding configuration. To choose which instruction files ArchDev drafts from, or which rule files it reads from your repository, commit .archdev/rules.yaml:

Code
include:
  - ".archdev/rules/**/*.jev"
exclude:
  - ".archdev/rules/retired/**"
draft_from:
  - "AGENTS.md"
  - "CLAUDE.md"
Field What it controls
include Repository-relative patterns selecting rule files committed to the repository. Defaults to .archdev/rules/**/*.jev; selecting a .jev also reads its sibling .md.
exclude Patterns removing rule files and instruction sources. Defaults to []. Excluding either sibling makes a rule pair incomplete.
draft_from Instruction sources for drafting. An explicit list replaces the defaults; [] disables instruction-file drafting, but does not disable other rules or starter rules.

adopt_to is no longer used: ArchDev does not write rule files to your repository.

The example keeps only AGENTS.md and CLAUDE.md as instruction sources. When customizing draft_from, list AGENTS.md again if you still want it read.

Without draft_from, the standard sources include root AGENTS.md, CLAUDE.md, GEMINI.md, .cursorrules, .windsurfrules, .github/copilot-instructions.md, and .cursor/rules/ Markdown and .mdc files. Nested AGENTS.md, CLAUDE.md and .cursor/rules/ patterns are also selected by default, but drafting skips nested sources.

Patterns support *, ** and ?. Use repository-relative paths; absolute paths, .., brace expansion and negated patterns are unsupported. Each include pattern must start with a literal directory, such as .archdev/rules/, rather than a repository-wide wildcard.

ArchDev drafts only root-level instruction files, .github/copilot-instructions.md and root .cursor/rules/ files. Nested instructions and custom instruction folders are not drafted, even if a draft_from pattern matches them. Collection is limited to 16 files, 128 KiB per file and 256 KiB total.

Write a rule pair

Write a rule as two files with the same filename stem. Keep them in a working directory outside your repository; archdev rules add uploads them.

This Python example checks YAML loading from external input. Save the explanation as safe-yaml.md:

Code
---
name: "Use safe YAML loading for external input"
description: "Do not construct Python objects when parsing request or uploaded YAML."
date: 2026-10-14
---

# Use safe YAML loading for external input

Use `yaml.safe_load` for request or uploaded YAML. Check changed production
code; exclude test fixtures and trusted local configuration. Report a
violation only when the diff shows external input reaching an unsafe loader.

These examples illustrate the rule; they are not repository incidents.

Violation:

```python
data = yaml.load(request.body, Loader=yaml.Loader)
```

Compliant:

```python
data = yaml.safe_load(request.body)
```

Save its evaluation template as safe-yaml.jev:

Code
{
  "model": "jev-latest",
  "state": {
    "diff": "REPLACE_BEFORE_USE: PR diff",
    "context": "REPLACE_BEFORE_USE: PR title, description and changed-file list"
  },
  "questions": {
    "applicable": {
      "type": "noul",
      "instructions": "Does state.diff show changed Python production code parsing YAML from request bodies or uploaded external input, using any loader? Exclude test fixtures and trusted local configuration. Judge scope only, independently of whether the loader is safe. Use state.context only to clarify scope."
    },
    "complies": {
      "type": "noul",
      "instructions": "Does the changed behavior in state.diff avoid constructing Python objects when parsing request or uploaded YAML? A visible call to yaml.unsafe_load or yaml.load with Loader or UnsafeLoader on that input violates the rule. yaml.safe_load complies. Exclude test fixtures and trusted local configuration. Use only state.diff and state.context; do not infer unchanged code. Answer yes if evidence is missing or ambiguous."
    }
  }
}

The Markdown frontmatter supplies the rule's name, description and date; the body explains the obligation, exceptions and examples. Cite real source lines when a rule comes from an instruction or correction. Label synthetic examples as illustrative.

The .jev file is JSON, with exactly the model, state and questions fields shown above. Keep the REPLACE_BEFORE_USE: placeholders in the template: the checker supplies the PR diff and context. The two noul questions ask independently whether the rule applies and whether the change complies. A safe loader is still applicable to this rule.

Add and change rules from a session

Install ArchDev and sign in, then ask Claude Code to brainstorm rules for your repository:

Paste into your agent
Help me turn this session's corrections into repository rules. Run archdev rules to see what already exists, draft Markdown/Jev pairs with specific scope and examples, and show me each one before adding it. Include only the relevant correction as evidence.

To add the example pair, replace acme/widget-api with your connected repository:

Code
archdev rules add \
  --repository acme/widget-api \
  --md-file safe-yaml.md \
  --jev-file safe-yaml.jev \
  --correction "Use safe YAML loading for request and uploaded input."

The rule is active as soon as it is added and applies from each pull request's next push. The command prints added: <name> (<rule id>) active; if a rule with the same name already exists, it is edited instead and the command prints edited: …. Keep secrets and unrelated session text out of the correction.

List the repository's rules, with each rule's id, name, status and source:

Code
archdev rules --repository acme/widget-api

Change a rule by the rl_… id from that list:

Code
archdev rules edit <rule-id> --repository acme/widget-api --md-file safe-yaml.md --jev-file safe-yaml.jev
archdev rules disable <rule-id> --repository acme/widget-api
archdev rules enable <rule-id> --repository acme/widget-api
archdev rules revert <rule-id> --repository acme/widget-api

revert drops edits and disables made through ArchDev and returns the rule to its source. An edit cannot rename a rule. Rule files from your repository, listed with source repository, cannot be changed from the CLI; edit the file in a pull request. Each command needs write access to the repository on GitHub.

Read verdicts on a change

Open your code PR on archdev.ai and confirm its current head. The checker applies the repository's current rules, plus any rule files in that PR head. A rule you add or edit applies from the next push; disabling a rule hides its violations right away.

When a rule violation is shown, expand it to inspect the explanation, cited lines and rule text. Disable on a violation turns that rule off and hides the violation; Edit changes the rule, and the new text applies from the next push. These buttons appear only on violations of ArchDev rules; to change a rule file from your repository, edit the file in a pull request. A clean, complete check may show no violation banner. Missing, partial or unavailable checks are not proof of compliance. If the rules page lists invalid rule files from your repository, fix the named path and reason; both sibling files must be present and valid.

These verdicts are separate from risk grades. They remain advisory on archdev.ai, with no GitHub comment, required check or merge block. Follow your team's review process and inspect the evidence yourself.

Check rules before you push

From your repository checkout, check the current branch's committed changes against main:

Code
archdev extract run branch.rule-verdicts main --json
archdev extract show branch.rule-verdicts main --json

Replace main with your base branch if needed. The branch must have commits beyond that base; uncommitted edits are not checked. The local checker reads rule files from the committed head, not the hosted rules you manage on archdev.ai. It runs mechanical checks and Jev evaluations, then asks a chat model to confirm model-reported violations. Results stay local; these commands do not publish a PR assessment or block a push.

run computes or reuses a result; show reads the stored result without evaluating again. With --json, a fresh run prints status, key, provenance and receipt; a cache hit prints status: "cached" and stored. show returns the verdict document inside the stored envelope's value field, alongside provenance. When multiple results are stored, show wraps the envelopes in a stored array. The document uses schema archdev.rule-verdicts.v1:

Field Contents
schema archdev.rule-verdicts.v1.
git repository, base_sha, head_sha and diff_sha256, identifying the checked diff.
rule_set files lists loaded rule paths; invalid lists objects with a path and reason.
partial Whether the check is incomplete. A partial result is not proof of compliance.
models The evaluation model selector and actual answering confirmation model, or null when unused.
usage Token counts by model, with input_tokens and output_tokens.
verdicts One entry per selected rule, with rule_id, source_file, title, check, area, verdict, applicable_probability, complies_probability, explanation, cited_lines and rule_text.

A verdict is pass, violation, not_applicable or not_evaluated; check is model or mechanical, and area is code or pr. Probabilities and explanations may be null. Citations contain path, start_line and end_line. Inspect partial, invalid rule files and unevaluated entries even when no violation appears.

Results are cached locally per repository, merge-base commit and branch-head commit. Repeating run for the same head and model selectors reuses a compatible, valid cached result without another model evaluation. A new head or changed model selectors requires a new check. To reevaluate the same head explicitly:

Code
archdev extract run branch.rule-verdicts main --force --json

Choose the local models

Set the two stages in archdev.json:

Code
{
  "rules": {
    "evaluation_model": "jev-latest",
    "model": "@rules-confirm"
  }
}

rules.evaluation_model selects the Jev evaluation model and defaults to jev-latest. rules.model selects the chat model that confirms candidate violations and defaults to @rules-confirm; it accepts a model selector or an array of selectors. These settings control local checks, not the hosted checker. User settings override project archdev.json; project archdev.local.json overrides both. The selected providers need working model access for the model-run path.

Let your coding harness judge the rules

A coding agent can judge the same frozen diff without calling the checker's evaluation or confirmation models:

Code
archdev extract brief branch.rule-verdicts main --out rule-brief

The brief writes DEFINITION.md, INPUT_SCHEMA.json, OUTPUT_SCHEMA.json, example.json and brief.json. Ask your agent to read the definition and schemas, copy input unchanged from the brief, and save rule-answer.json in this shape:

Code
{
  "input": "Replace this string with the unchanged input object from brief.json",
  "assessment": {
    "verdicts": [
      {
        "rule_id": "Replace with a rule_id from input.rules",
        "applicable": true,
        "complies": false,
        "explanation": "Explain the violation and what would fix it in at most 60 words.",
        "cited_lines": []
      }
    ]
  }
}

This is an authoring illustration, not a ready-to-submit answer. Answer every model rule in input.rules exactly once; do not answer mechanical rules, whose outcomes are already supplied. Set applicable to false outside a rule's scope; otherwise complies must be a boolean. Cite changed new-side lines for violations, using {path, start_line, end_line} objects. Leave citations empty for passes, non-applicable rules and missing description elements.

Validate and store the authored result:

Code
archdev extract finalize branch.rule-verdicts rule-answer.json --out rule-result
archdev extract show branch.rule-verdicts main --json

finalize rejects stale or changed input and missing, duplicate or unknown rule answers. It writes result.json and digest.txt, and stores the local verdict document with file-runner provenance. The document also includes input, assessment, producer, definition_digest and digest. Neither brief nor finalize calls the checker's models or publishes a hosted assessment. If the branch head changes, generate a new brief and judge it again.

Check a change before you merge · Merge and PR follow-up