Skip to content

Rule

A rule is one check that Sextant runs against your code. It has an id, some metadata, and an evaluator that does the actual work.

---
id: builtin.size.fn-length
name: "Function length"
description: "Functions whose body spans more than the configured number of lines."
severity: warn
category: size
scope: file
languages: [rust, python, go, java, typescript, tsx, javascript]
evaluator:
type: builtin
name: fn_length
enabled: true
tags: [size, complexity]
---
# Function length
Long functions tend to bundle multiple responsibilities…

The frontmatter is metadata. The body is human-facing documentation — shown by sextant rules explain and the MCP explain_rule tool.

FieldTypeRequiredNotes
iddotted stringyesGlobally unique. Convention: <source>.<category>.<short-name>. Built-ins are namespaced under builtin.*; repo rules can use anything.
namestringyesHuman-readable title.
descriptionstringyesOne-liner shown in rules list output.
severityinfo | warn | erroryesSee Finding → Severity.
categoryenumyessize, complexity, duplication, tests, reliability, style, security, docs, or { custom: "<name>" }.
scopediff | file | repoyesWhat slice the evaluator sees. See Scopes.
languagesarraynoWhitelist of language tags. Empty means all languages.
evaluatorobjectyesThe check itself. See Evaluator.
enabledboolnoDefault true. Set false to ship a disabled stub (useful to override a built-in).
overridesarray of idsnoRule ids this rule replaces.
tagsarraynoFree-form labels — surfaced in JSON, used for filtering.

Rules have one of three sources, available as the source field on list_rules output:

  • builtin — embedded in the sextant binary at compile time. The seven rules in Rules catalog ship today.
  • vendor:<pack> — installed from a rule pack via sextant rules add. Lives under .sextant/rules/vendor/<pack>/, hashes recorded in .sextant/rules.lock. Vendor rules are immutable: editing or deleting a file aborts the next grade.
  • repo — markdown files in .sextant/rules/**/*.md (excluding the vendor/ subtree) of the repo being graded.

Priority on id collision is builtin → vendor → repo, in increasing order:

ConflictOutcome
Repo rule with same id as a builtinRepo wins (logged).
Vendor rule with same id as a builtinVendor wins (logged).
Repo rule with same id as a vendor ruleHard load error. Vendor rules are not shadowable.

overrides: lists in a rule’s frontmatter only flow downward — vendor packs can disable built-ins, but a repo rule can’t disable a vendor rule. The point is that pack authors’ intent survives in the codebase even when an agent tries to silence it; see Rule packs for the full integrity model.

Rule files live in .sextant/rules/<name>.md. The name of the file doesn’t matter — the loader keys off the frontmatter id. Read Authoring rules for the full schema and evaluator-specific fields. To package a set of rules for distribution, see Authoring a pack.