Skip to content

feat: add opt-in SQBRPYTHON rules for project Python - #1487

Merged
chio-labs-delivery[bot] merged 24 commits into
mainfrom
feat/sqbrpython-rules
Nov 15, 2026
Merged

chio-labs-delivery[bot] merged 24 commits into
mainfrom
feat/sqbrpython-rules

Conversation

@kvlonge

@kvlonge kvlonge commented Nov 14, 2026

Copy link
Copy Markdown
Contributor

Why

Project Python (python/, hooks, providers) had no Rules coverage, so layout drift, missing annotations and dead code went unchecked. Fensu already implements these checks as core rules.

Changes

  • New opt-in SQBRPYTHON family: Fensu's core Python rules under SQLBuild codes, plus two python/ layout rules (001, 002). Thresholds are whole-number options in [rules.rule_options].
  • It runs only when a selector names SQBRPYTHON or one of its codes; SQBR alone leaves it out. 306 (unreachable definitions) and 507 need their exact code.
  • Findings use project-relative 1-based positions and the normal exceptions, ignores and stale checks.
  • 306 treats node decorators (including @audit_factory), code outside python/, and imports through folders without __init__.py as reachable.
  • Per-file cache (python.json), keyed on the file, the Python rules and options, and the project answers it read. Python settings never change the model-rule cache key.
  • Docs: new Python rules page; selection, caching and Python nodes pages updated.

Verification

  • Rust tests: selection, cache (edit, option, import target, new subdomain, Windows paths), positions, and a scaling guard (4,000 modules, 12,000 findings, under 5 s).
  • CLI integration tests on DuckShop fixtures: findings, SQBR exclusion, exceptions, options, rules run vs compile, cache sequence.
  • One review and a follow-up; each fix has a test that fails without it.
  • DuckShop, default selection, vs 0.226.0, same machine, 3 alternating runs, load 1.2/8 cores, medians: wall 1.74 vs 1.76 s, CPU 4.22 vs 4.12 s, 0 diagnostics both. Peak RSS 286 vs 306 MiB matches the fast-profile build (older fast main build: 312 MiB).
  • make check-ci passes.

DuckShop: new edge_cases/python_rules/{conforming,violations} fixtures with expected findings; the conforming one covers audit factories and namespace imports.

Depend on fensu-facts and fensu-native 0.30.0 without their Python
bindings and add the Python rule family to the catalogue: two SQLBuild
layout rules and 62 Fensu core rules in bands by Fensu family. The
family runs only when a selector names SQBRPYTHON or one of its codes,
so selecting SQBR does not turn on Python linting. Evaluation follows.
…n rules

Add an integer built-in option kind with a minimum, shown by sqb rules
show and returned as RuleOption.integer by the Python catalogue, and
declare each Python rule's Fensu thresholds with Fensu's defaults.
…t Python rules

When a selected rule reads Python, the rules request now carries every
supported project Python file with the digest of its bytes, plus the
interpreter version, so the memo, speculation and delta compiles see a
Python edit. Without a Python rule selected no Python file is read.
…core rules

Each project Python file is placed the way Fensu places files: files under
python/ belong to the runtime package imported as python, with domains
directly below it; other supported files sit under their own folder and run
only the file-local rules. A unit's main.py is an entry and main module.

Fensu decides which file runs project-, scope- and package-wide rules, its
project questions are answered from one walk of the project, and node
functions and everything outside python/ count as loaded for reachability.
Findings keep Fensu's text, move to 1-based character columns, and rules for
the python/ package never report outside it. A file the parser rejects fails
the run. Python rules no longer make model rules read every model or change
the model cache key.
… named

SQBRPYTHON001 reports modules directly under python/ and node-kind or role
folders at its root; SQBRPYTHON002 reports generic package names such as
common/ or shared/ anywhere under python/, except utils/ at its root. Each
folder is reported once, on its __init__.py or else its first file.
…ject answers are unchanged

The Python rules keep their findings per file in python.json beside the
bulk rules cache. An entry holds while the file's bytes, its rules and
thresholds, the ruleset and the Python version are the same, and the
project questions its rules asked, such as whether an imported module
exists, still have the same answers. Rules that read the whole project
also key on every Python source. A speculative evaluation holds this
write with the bulk cache write until it is published.
… unit tests

The compiler differential E2E only runs in the merge queue, so a discovery
code without a corpus case surfaced there first. This check reads the
declared cases without compiling them, so it fails on the pull request.
…le definitions

Each package file's context carried every loaded definition whenever a
project-wide Python rule ran, so evaluation grew with files times
definitions. A guard now bounds 4000 modules with 12000 findings.
…inputs

Naming one Python code next to SQBR no longer selects every default Python
rule. Layout rules that read folders now answer their cached queries from
project-relative paths, so adding a subdomain re-checks the package.
Python selectors and options no longer change the model-rule cache key,
and the Python cache key covers only the Python rules and their options.
…RPYTHON306

Functions decorated with @audit_factory are loaded by SQLBuild, and
imports through python/ folders without __init__.py resolve, so neither
is reported as unreachable. The finding's remediation no longer points at
a setting SQLBuild does not have.
…caches see layout changes

Fensu spells planned query paths with /, while a Windows project directory
uses backslashes, so the paths stayed absolute and folder answers never
changed. A query for the project directory itself now uses the index's
root path.
…st outgrows it

rules list now prints more than CPython's 8 KiB stdout buffer, so it fails
its write instead of dropping the final flush. build --help stays between
4 and 8 KiB and does not grow with the rule catalogue.
@chio-labs-delivery
chio-labs-delivery Bot added this pull request to the merge queue Nov 14, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 14, 2026
The dense and varied compile guards assert that their fixture selects
every built-in rule. The SQBRPYTHON rules are only selected by name, so
the fixture now names them, and the cold guard counts one rule-cache
miss per project Python file.
… a near-limit budget

The 4000-module unreachable-definitions case ran at about 5.2 s against
its 5 s budget on the debug test profile, and at 2000 modules the code it
guards against fits well inside the budget. The case now times 500 and
2000 modules in five interleaved pairs and bounds the median ratio at
6.5: the current code measures 4.9 to 5.7 and the earlier per-file
context copy 7.4 to 8.7. The default-rules case keeps its absolute
budget, and both scaling tests take a shared lock so they never time
each other's work.
…ble definition

Without a result check the ratio guard would pass if SQBRPYTHON306 stopped
walking this project, because both runs would get cheaper together. The
large run must report each unit's function and the shared helper.
@chio-labs-delivery
chio-labs-delivery Bot added this pull request to the merge queue Nov 14, 2026
…hon rules

The dense fixture now selects the SQBRPYTHON rules by name. The delta
compile project reuses it, but its cases author minimal custom-rule and
factory modules that those rules reject, so the stored compile failed its
Rules and one edit no longer found the selection it rewrites. The delta
project now swaps back to its previous selection.
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 14, 2026
@kvlonge kvlonge added the full-verify Run the full Verify matrix on this pull request label Nov 14, 2026 — with Amp for GitHub
@chio-labs-delivery
chio-labs-delivery Bot added this pull request to the merge queue Nov 14, 2026
Merged via the queue into main with commit 0592ea7 Nov 15, 2026
92 of 94 checks passed
@chio-labs-delivery
chio-labs-delivery Bot deleted the feat/sqbrpython-rules branch November 15, 2026 00:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

full-verify Run the full Verify matrix on this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant