Per-crate summary
The
crates/
directory in the repo. Linked diagram is in the
architecture overview.
sextant-core
Section titled “sextant-core”The type definitions every other crate depends on. Rule, Finding,
Report, Verdict, Severity, Category, Scope, EvaluatorSpec,
the Evaluator trait, the BaselineDelta and PrReport types for
regression mode, plus a few helpers like SeverityCounts and
VerdictThresholds. No I/O dependencies. That guarantee is what
lets the crate stay stable while the surface crates churn — and makes
it cheap to test.
sextant-config
Section titled “sextant-config”Reads .sextant/config.toml into typed structs and merges with
defaults. Returns the resolved config the engine runs with. Also
hosts the hardcoded skip list (generated artifacts: Cargo.lock,
target/, node_modules/, .git/, …) — every crate that walks
files asks this crate which paths to skip. The list is not
user-configurable.
sextant-rules
Section titled “sextant-rules”Rule discovery, evaluators, and the vendor pack plumbing. Three layered concerns:
- Discovery & schema. Parses YAML frontmatter + markdown body
via
gray_matter, validates against the rule schema, returnsParsedRulevalues. Walks three sources: built-ins (embedded viarust-embed), repo-local rules under.sextant/rules/**/*.md(excludingvendor/), and vendor packs (one directory per pack undervendor/). The three-tier merge enforces vendor immutability — a repo rule that shadows a vendor id is a hard error. - Evaluators. Four kinds:
builtin(Rust impls of the seven shipped rules),regex(line-by-line text),ast(tree-sitter query with optional ancestor-skip), andllm(judge-driven). - Vendor pack lifecycle.
fetcher.rsparses pack specs and clones from GitHub viagit2(or copies from afile:path) into a hashed staging dir.lock.rsreads, writes, and verifies.sextant/rules.lock, the SHA-256 record that gates every grade.
sextant-diff
Section titled “sextant-diff”Git diff acquisition via git2. Resolves base refs (merge-base with
origin/main, falling back to HEAD~1). Walks blob contents — no
git checkout required, so the working tree stays at the head
commit. Returns the changed files and per-file line ranges that
diff-mode and PR-mode grading need.
sextant-lang
Section titled “sextant-lang”Tree-sitter parsers and queries for Rust, Python, Go, Java, TypeScript, TSX, JavaScript. Provides cached parsers (one per language, reused across files) and the captured-name queries built-in evaluators use to find functions, types, etc. Adding a language is isolated to this crate.
sextant-judge
Section titled “sextant-judge”LLM-as-judge providers and cache. Wraps Anthropic and OpenAI HTTP
APIs (via reqwest), enforces tool-use schemas so LLM responses are
well-typed Findings, and caches by BLAKE3 hash of (file content, rule id, rule body, model). The cache makes repeat grades of
unchanged files free.
sextant-engine
Section titled “sextant-engine”Grading orchestration. Public API:
grade(cwd, GradeMode) -> Reportgrade_pr(cwd, DiffOptions, PrOptions) -> PrReportlist_rules(cwd) -> Vec<RuleSummary>explain_rule(cwd, id) -> Option<RuleSummary>load_config(cwd) -> Config
That’s the whole engine API. Both binaries call into exactly these functions; the rest is wire-format wrapping. The engine’s job is to load config + rules, acquire files, run evaluators, build a report — no command-line parsing, no JSON-RPC framing, no markdown rendering.
sextant-cli
Section titled “sextant-cli”The sextant binary. Wraps the engine with clap argument parsing
and one render module per output format (human, json, markdown,
sarif, review-json). Subcommands: grade, rules (with
list / explain / check / add / update / remove), and
init. The rules add-family subcommands delegate to
sextant-rules::fetcher and sextant-rules::lock — the binary
itself doesn’t open sockets or write hashes. Tests are largely
snapshot-based via insta.
sextant-mcp
Section titled “sextant-mcp”The sextant-mcp binary. JSON-RPC 2.0 server — stdio by default,
HTTP via axum when --http <addr> is passed. Five tools:
grade_diff, grade_files, list_rules, explain_rule,
get_config. Each tool dispatches to one engine entry point and
wraps the result in the MCP content envelope. Logging goes to
stderr; stdout is reserved for the protocol stream.
See also
Section titled “See also”- Architecture overview — dependency graph and motivation.
- Data model — types exchanged between crates.
Cargo.toml— the canonical workspace definition.