Skip to content

refactor(native): layer sqlbuild-python modules and add the sqlbuild-host crate - #1178

Merged
kvlonge merged 10 commits into
mainfrom
refactor/split-sqlbuild-python-1
Oct 20, 2026
Merged

kvlonge merged 10 commits into
mainfrom
refactor/split-sqlbuild-python-1

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Why

sqlbuild-python holds about 190k lines in one crate whose modules form one import cycle, so every change rebuilds all of it and nothing can move into smaller crates. These are the first steps of CHI-610: put every module in a layer, remove the cycles and start the plain-Rust crates. No behaviour changes.

Changes

  • New repo fensu rule XSB075 orders the binding helper modules in layers (infra, front, project, plan | compile, output, commands, registry) and faults on upward imports; the budget is now 0.
  • Shared helpers moved below their users; records getter dispatch and compiled-project attach functions are registered per area at startup instead of imported centrally; compiled_project split into project data, views and input loops.
  • New plain-Rust crate sqlbuild-host: host entry catalogue, compile timing collector, compile diagnostic sink contract and executor result types, implemented by sqlbuild-python.
  • XSB072/073/075 classify test files by location, not a test_ file name; four source files that were skipped are now counted (pending budgets).

Verification

  • make check-ci (fensu 0 faults, clippy -D warnings), compiler differential 373/373, focused CLI, compiled-project, native-path and fensu rule tests.
  • Native module import time unchanged (~24 ms).
  • Independent review of every moved function, registration order and the host indirection: no findings.

Add XSB075, which assigns every bindings/_helpers module a layer that
follows the planned crate split and reports imports that point to a
higher or sibling layer. Today's upward imports are recorded as
per-file pending budgets that may only go down.
…use them

Move the Python call helpers to boundary, the per-compile collectors to a
new compile_context module, model reads and explicit references to the
project modules, project configuration and SQL value helpers to
discovery and authored_values, and the progress reporters to
build_progress. Paths change only; behaviour is unchanged. The XSB075
upward-import budgets fall from 501 in 219 files to 174 in 79 files.
…ycles

Each module that defines native pyclasses now lists its getter readers in
its own `getters::GETTERS` table, and registration installs the tables and
the record behaviours, so `records` no longer imports the view modules.

The other upward references that closed cycles move to the layer that owns
them: delta-compile slots and coverage into `compile_context`, lineage facts
and call arguments below the records, config classes into `model_config`,
relation keys and reference rows into the compiled project, and the
project's attachment rows and settings into `attachment_inputs`, with the
attachment runs installed by the compile layer behind the unchanged Python
methods.

No file-level module reference closes a cycle across XSB075 layers any
more; the XSB075 budget drops from 174 to 101 references.
…ut loops

`compiled_project` keeps the project data: the native project, its
attachment rows and settings, reference rows, schema facts and values.
The Python views and their records move to `compiled_views`, and the model
loop with the loops that attach sources, functions, SQL tests, scenarios
and audits moves to `input_loops`, which XSB075 now maps to the compile
layer as whole modules instead of per-file overrides.

Registration order, Python classes and behaviour are unchanged.
…rd references

Mixed areas now map their files to the layer each belongs to: small value,
progress, event and host helpers to `infra`, configuration resolution to
`front`, analysis catalogues, selection, scopes and SQL test fixture
planning (shared by planning and compile) to `project`, and the
compile-and-plan pipeline, static command context and command entry points
to `commands`.

Where a file straddled two layers, the straddling items move:
`run_compile_pipeline` to `compile_driver::plan_pipeline`,
`compile_static_command_context` to `compile_driver::static_context`, the
Python node identity to discovery, the test label to the result text, the
SQL test chain names to the plan driver, and Recall installs its writer
class for provider discovery instead of discovery importing it.

The XSB075 budget drops from 101 references to none.
`sqlbuild-host` is plain Rust below every crate that crosses into Python.
It holds the catalogue of `sqlbuild._native_host` entries (moved from
`native_host`) with the `HostEntries` trait that resolves them, the
per-thread compile timing collector with a `ProcessClock` trait, the
`CompileDiagnosticSink` trait, and the executor result types that mirror
the Python result dataclasses and string enums.

`sqlbuild-python` implements the traits: `native_host::host` resolves
entries through `PythonHost`, compile CPU timings read
`time.process_time_ns` through `PythonProcessClock`, and
`report_compile_diagnostic` reports through `PythonCompileDiagnostics`.
The executor result types have no conversion yet; a repository test keeps
their fields and enum values equal to the Python definitions until the
output step converts results once at the executor edge.

The crate joins the native layer order after `sqlbuild-config`, the
module path check scans its source, and `crates/README.md` describes it.
…name

XSB072, XSB073 and XSB075 skipped every bindings file whose name starts
with `test_`, so source files such as `sql_test_command/test_command.rs`
were never checked. Test code is now told apart only by where the crates
put it: files under a `tests` directory, `tests.rs` module roots, and the
trailing `#[cfg(test)]` module.

Four files become visible. Their existing crossings and Python-typed
fields are recorded as pending budgets: 186 crossings and 13 fields. None
of them imports upward.
@kvlonge
kvlonge enabled auto-merge (squash) October 20, 2026 13:20
@kvlonge
kvlonge merged commit 58e5ce8 into main Oct 20, 2026
44 checks passed
@kvlonge
kvlonge deleted the refactor/split-sqlbuild-python-1 branch October 20, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant