refactor phase 0: safety net (SCC ratchet, real lint gate, CI matrix, soundness reorg) - #295
Merged
Merged
Conversation
Measures the intra-package import graph (AST-level, counting lazy function-local imports as edges) and locks in the current 23-module strongly connected component as a shrink-only allowlist. No module may join a cycle; detached modules must be removed from the allowlist. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The configured rules (E,F,I,UP,B,SIM) were never enforced (CI ran --select F,E9 only). Fix all 125 violations: import sorting, unused loop variables, contextlib.suppress, ternaries, explicit zip strict, bind the loop variable in resolve_on_join (B023), and move _reductions_for_expr below ops.py's import block (E402). Deliberate ignores, now documented in pyproject: E731/E741 (named lambdas and l/r join-predicate convention), tests get E402+B017. Dead ignores referencing unselected rules (S101, COM812, PLR2004, ANN) removed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Mechanical formatting only; ruff format --check joins CI in this branch so drift can't reaccumulate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ests - CI lint now runs the full configured ruleset plus ruff format --check (was --select F,E9 only); pre-commit's ruff hook is un-skipped and pinned to the locked ruff version - Test matrix covers Python 3.11-3.13 (full) and the no-xorq leg; pytest runs with -n auto via pytest-xdist - Weekly scheduled job runs make test IBIS_VERSION=all so upstream ibis releases can't silently break us - pytest: --strict-markers and a declared integration marker - Wheel no longer ships test suites, fixtures, or the sys.path-mutating conftest (verified: 0 test files in built wheel) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The bsl entry point is installed unconditionally but agents/cli.py imported python-dotenv (agent extra) at module level, so a plain install produced a broken command. The import is now guarded: skill management works everywhere; loading an explicit env file without the dependency raises a clear install hint. Also delete agents/chats/slack.py: unimportable dead code — it imported agents.backends.langchain.LangChainAgent, which does not exist (the real backend is LangGraphBackend with a different interface), and referenced a nonexistent [slack] extra. No referrers, no tests. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ode dirs
- RELEASE_NOTES_v0.3.12.md: one-off notes for a past release
- docs/web/bun.lockb: CI builds with npm ci + package-lock.json; the
bun lockfile was stale and misleading
- src/boring_semantic_layer/{ops,malloy}/: directories containing only
orphaned __pycache__ from deleted packages (untracked; removed from
the working tree so the names stop shadowing future modules)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The 'round N' regression files were chronological bug-fix journals; a reader (or a refactor) couldn't tell which invariant a failure guarded without opening the file. Group them under tests/soundness/ named by the invariant each pins, with a README index mapping files to the original finding IDs. Test bodies are unchanged; this also commits the previously untracked round-5 suite (12 tests, passing on main) as test_join_namespacing_and_inline_totals.py. 152 tests, all passing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
uv.lock and requirements-dev.txt regenerated after adding pytest-xdist to the test-core and dev extras; xorq's packager exports with --locked and fails on a stale lockfile (caught by test_xorq_rebuild). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
examples/{malloy_interop,nested_queries,worldcup}.py are untracked
local work that a broad 'git add -- examples' swept into the lint
commit by mistake. malloy_interop.py imports boring_semantic_layer
.malloy, which only exists on feat/malloy-interop, so 'make examples'
failed in CI. Restore all three to untracked working-tree files.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The same broad 'git add -- src' that swept the WIP examples also tracked test_soundness_round5.py at its pre-reorg path; the suite lives at soundness/test_join_namespacing_and_inline_totals.py. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Aug 18, 2026
hussainsultan
marked this pull request as ready for review
August 18, 2026 23:03
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 0 of the SCC-driven refactor plan: lock the safety net before any structural change. No compiler logic is touched; the full suite is green (1707 passed, 1 skipped, 11 xfailed).
What's in here
Import-graph SCC ratchet (
tests/test_import_graph.py)The intra-package import graph (lazy function-local imports counted as edges — they are cycle workarounds, not absences of a dependency) contains one 23-module strongly connected component:
__init__,ops,expr,query,api,serialization/*,chart/*, and more are all mutually importable. The new test snapshots that component as a shrink-only allowlist: no module may join a cycle, and modules detached by later phases must be removed from the list in the same PR. End state: an acyclic, layered module graph.Lint gate now enforces what the config claims
CI ran
ruff check --select F,E9while pyproject configuredE,F,I,UP,B,SIM. All 125 latent violations are fixed (import sorting,contextlib.suppress, unused loop vars, one B023 loop-capture binding,ops.pyE402s); CI runs the full ruleset plusruff format --check; pre-commit's ruff hook is un-skipped and pinned to the locked ruff version. Deliberate, documented ignores: E731/E741 (named lambdas and thel, rjoin-predicate convention), tests get E402 + B017 (revisit with the phase-2 exception hierarchy). One mechanicalruff formatcommit (75 files).CI matrix + faster suite
pytest -n autovia pytest-xdist;--strict-markers+ declaredintegrationmarkermake test IBIS_VERSION=allso upstream ibis releases can't silently break us between pushesPackaging fixes
bslconsole script is installed unconditionally but imported python-dotenv (agent extra) at module level — a plainpip install boring-semantic-layeryielded a broken command. The import is now guarded; skill management works everywhere, and loading an explicit env file without the dep raises a clear install hint.sys.path-mutating conftest (verified: 0 test files in the built wheel).agents/chats/slack.py: unimportable dead code (imported a nonexistentbackends.langchain.LangChainAgent, referenced a nonexistent[slack]extra, zero referrers, zero tests).Soundness suites reorganized by invariant
The chronological
test_soundness_roundNfiles were bug-fix journals — a failure didn't say which invariant it guarded. They now live undertests/soundness/, named by invariant (test_fanout_preagg_regressions,test_join_many_participation, …) with a README mapping each file to its original finding IDs and a do-not-weaken warning. Test bodies unchanged; also commits the previously untracked round-5 suite (12 passing tests). 152 tests total.Hygiene
Stale
RELEASE_NOTES_v0.3.12.mdanddocs/web/bun.lockb(CI builds with npm) removed; ghostops//malloy/bytecode-only directories purged;uv.lock/requirements-dev.txtrelocked for pytest-xdist (xorq's packager exports--locked).Verification
python3 -m pytest src/boring_semantic_layer: 1707 passed, 1 skipped, 11 xfailed, 4 xpassedruff check .andruff format --check .: cleanbslimport verified with python-dotenv absentNext phase: dead-code deletion + the four cheap edge cuts that detach the agents and chart clusters from the SCC.
🤖 Generated with Claude Code