luplo.core.checks

Rule pack — deterministic checks over the item graph.

A check is a read-only query that produces Finding rows. Rules are intentionally narrow and SQL-only: no LLM, no external network calls. Hallucination plus compliance context is a liability, not a feature — see the roadmap page for the explicit rejection.

Each rule lives in its own file under luplo.core.checks.rules and is registered via RULES. Surface layers (CLI, MCP, HTTP) call run_checks() to run the enabled set and aggregate.

Disabling a rule per-project is opt-in: add the rule’s Rule.name to the [checks] disabled_rules list in .luplo. The rule’s code is unchanged; the runner just skips it.

Submodules

Attributes

RULES

Severity

Severity levels, ordered by decreasing blocking weight.

Classes

Finding

One hit from a rule run.

Rule

A registered check.

Functions

run_checks() → list[luplo.core.checks.types.Finding])

Run the selected rules and return their aggregated findings.

Package Contents

luplo.core.checks.RULES: dict[str, luplo.core.checks.types.Rule]
async luplo.core.checks.run_checks(conn: psycopg.AsyncConnection[Any], project_id: str, *, rule_names: collections.abc.Iterable[str] | None = None, disabled: collections.abc.Iterable[str] = ()) list[luplo.core.checks.types.Finding]

Run the selected rules and return their aggregated findings.

Parameters:
  • conn – Async psycopg connection.

  • project_id – Project scope — every rule is project-local.

  • rule_names – If given, run only these rules (by Rule.name). Unknown names raise ValidationError before any SQL runs. When None, run every registered rule.

  • disabled – Names to skip (typically from .luplo [checks] disabled_rules). Silently no-ops when a disabled name also appears in rule_names — the caller’s explicit --rule X does not override the project-level disable.

Returns:

Flat list of Finding ordered first by the rule order in luplo.core.checks.registry.RULES, then by whatever order the rule’s own SQL returned.

class luplo.core.checks.Finding

One hit from a rule run.

rule_name: str
severity: Severity
message: str
item_id: str | None = None
details: dict[str, Any]
class luplo.core.checks.Rule

A registered check.

name: str

Stable identifier used by --rule and disabled_rules.

default_severity: Severity

Severity applied to every finding this rule produces.

description: str

One-line human explanation. Shown by lp check --list.

check: collections.abc.Callable[[psycopg.AsyncConnection[Any], str], collections.abc.Awaitable[list[Finding]]]

Async callable that takes (connection, project_id) and returns findings.

luplo.core.checks.Severity

Severity levels, ordered by decreasing blocking weight.

  • error — blocks lp check exit code (non-zero on any).

  • warn — surfaced but does not block.

  • info — advisory, hidden from default CLI output.