Skip to content

refactor: finish moving Python logic to Rust and enforce boundary rules - #1116

Merged
kvlonge merged 48 commits into
mainfrom
feat/native-group-17
Oct 16, 2026
Merged

kvlonge merged 48 commits into
mainfrom
feat/native-group-17

Conversation

@kvlonge

@kvlonge kvlonge commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Why

Finishes the Rust-hosted port: no movable Python remains, and every Python file that stays must name one of four rules (executor/adapter runtime, user-code shim, public facade, third-party glue) and hold no logic beyond it.

Changes

  • Remaining compile, planner, scope, spec and rule shapes hosted natively; planner records moved to the shared native record mechanism.
  • Constants shared by Rust and Python are defined once in Rust and exported; Python copies and re-export shims removed.
  • Logic found in staying Python moved native: DDL cache-invalidation lexer, ingestr and dlt destinations, query-diff names, Dagster/Rivers DAG projection and default translator, microbatch projection and state SQL, state-table SQL, lifecycle validation, log routing and redaction, compute-log retention, rule hermeticity scan, rule project tree, Python-node validation and retry delays, dbt profile coercions, startup stamps.
  • Boundary check now requires a rule and evidence for every stays entry.
  • Fixes: Dagster accepts path-like arguments; console log durations never raise.

Verification

  • make test and make check-ci passed with all optional dependencies available.
  • Compiler differential: 371 projects, unchanged goldens. Planner differential: 11 projects matched the main baseline.
  • Compile outputs and exit codes match the reference on synthetic and private compile-only projects.
  • Old/new side-by-side comparisons on generated inputs for every moved area (cache invalidation, redaction, microbatch state, destinations, validation) matched apart from documented edge cases.
  • Independent review and follow-up: no blocking findings.

Constants needed by both Rust and stays Python are now defined once in
Rust and registered on sqlbuild._native; Python keeps no copy.

- Register text, integer, tuple and frozenset constants plus GRAIN_ORDER
  (built from the Rust cursor grain order) in a new exported_constants
  binding module, typed in _native.pyi.
- Consolidate duplicated Rust literals (project config file name, state
  table names, settings keys, Python node root, __init__ stem, CTE AST
  kind, custom-rule test-case threshold key, zero-day duration) into one
  definition each.
- Native code no longer reads fingerprint, output-capture or rule-engine
  constants back from Python modules.
- Delete compiler/planner, compiler/discovery, cursor_algebra,
  compiler/frontier, cost, compiler/migrations and
  runtime/execution_history constants modules and their stays entries;
  trim the remaining stays constants files to Python-only values.
- Relabel compiler/sql_analysis/constants.py as rule 4 polyglot_sql glue.
…tively

- Point importers of INTEGRATION_RESULT_PATH_ENV, INVOCATION_CONTEXT_ENV
  and SOURCE_FRESHNESS_TABLE_NAME at sqlbuild._native and remove the
  re-exports under old module paths.
- Define the source freshness columns and their state value types once in
  sqlbuild-state; the state table DDL, insert and latest-state SQL read
  them from Rust instead of a Python constants module.
- Export the diagnostic logger prefix and SQL text log field from Rust,
  which the native console formatter already used.
- Delete cli/output, compiler/source_freshness and runtime/compute_logs
  constants modules (and the then-empty packages) with their stays entries.
…e lifecycle envelopes natively

SQL log digests and record fields, LogRecordRouteFilter routing and redaction,
compute log retention, identity and severity, and lifecycle event, diagnostic
log, run bound, operation metadata, hook and producer validation now run in
Rust. The logging.Filter/Handler subclasses and public lifecycle classes keep
their signatures and call native for every decision.
The adapter-config to dlt destination mapping moves to sqlbuild-core and shares
connection setting reads with the native ingestr destinations through a new
loader_connection domain. build_dlt_destination keeps importing dlt and calling
the destination factory.
…nts in Rust

sqlbuild_sql, sqlbuild_sql_digest, sqlbuild_private_sql_record and the
SQLBuild logger root and prefix are defined once in sqlbuild-core
diagnostic_routing. Python reads the field names it still needs from
sqlbuild._native; diagnostics/constants.py keeps only the private record
marker object.
…ising

The diagnostics console formatter read sqlbuild_duration_ms as i64 for every
record, so integers above 2**63 raised OverflowError from logging. The duration
is now Python's ms / 1000, read only when sqlbuild_subject is a string, and
omitted when the quotient does not fit a float.
@kvlonge
kvlonge enabled auto-merge (squash) October 16, 2026 00:48
…tive code

The `sqb` launcher hands off to `sqlbuild.cli.entry.main.launched`, which
imported `LAUNCH_RECORD_OPTION` from `sqlbuild._native` at module import.
That loaded the extension, and its mimalloc allocator, before
`entry.main` defaulted `MIMALLOC_PURGE_DELAY`, so mimalloc kept its
default purge delay and returned far less freed memory to the OS. Dense
10000-model compiles peaked about 200-400 MiB higher.

Default the purge delay in the launched entry before importing the
native constant, and extend the fresh-process allocator entry test to
cover the launched entry.
@kvlonge
kvlonge merged commit 7795b76 into main Oct 16, 2026
40 checks passed
@kvlonge
kvlonge deleted the feat/native-group-17 branch October 16, 2026 03:00
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