Repository navigation
v0.6.1
Changelog
All notable changes to this project will be documented in this file.
[0.6.1] - 2026-10-14
π Features
- (46-02) Async query path end to end β AsyncEngine, AsyncSemolinaCursor, create_async_engine
- (46-02) Complete the async cursor result surface and cover close ordering
- (46-04) Add separate async engine registry with async-aware reset
- (46-04) Add _Query.aexecute and export the async surface (ASYNC-02)
- (47-01) Measure one DuckDB decimal metric end to end
- (47-02) Widen the DuckDB probe to every field and name the disagreements
- (47-02) Measure the downstream Decimal consumers instead of assuming them
- (47-03) Probe Snowflake and Databricks result schemas from copied cassettes
- (47-03) Add the Snowflake and Databricks rows, driver capability, and evidence limits
- (48-01) DuckDB DECIMAL maps to decimal.Decimal; metrics annotate T | None
- (48-01) Preserve the raw warehouse type in generated source (D-03)
- (48-03) Apply the Decimal policy to Snowflake and Databricks (TYPE-03)
- (48-03) Concrete types for every category-1 map gap (TYPE-05)
- (48-03) Add the public semolina.JsonValue type alias (TYPE-06)
- (48-03) Map VARIANT to the JsonValue union (TYPE-06)
- (48-04) Promote probe_schema and ProbeResult into src/semolina/codegen/probe.py
- (48-04) Arrow_type_to_python β the Arrow-to-annotation mapper (TYPE-07)
- (48-05) Read a committed model's annotations without importing it
- (48-05) Compare committed annotations against the probed result schema
- (48-05) Wire semolina codegen --check --model with exit code 5
- (49-01) .into(DTO) on the sync cursor with a structural schema pre-check
- (49-02) Iter_into β check at the call, produce lazily
- (49-05) Fetch_df and fetch_polars, guarded for what each actually imports
- (49-06) Async into and iter_into on AsyncSemolinaCursor
- (49-06) Async fetch_df / fetch_polars, and the four async guards
- (49) Respect hand-authored coercions β gate the type check on validate=False
- (50-02) Generate a typed Pydantic DTO from a query's probed result schema
- (50-03) Per-class provenance and deferred annotations in generated DTOs
- (50-06) Add the codegen-dto command and its exit-code epilog
- (codegen-dto) Generate a DTO from a view, or from pyproject.toml
- (codegen-dto) Add --check, so a committed DTO can be verified in CI
- (config) Build, register and scope an engine in one call
- Support model inheritance and abstract=True bases (52-06)
π Bug Fixes
- (46) Let aclose() own the reader fetch_record_batch() hands out
- (46) Stop async iteration cleanly on an already-drained stream
- (46) Report a failed check-in as a ResourceWarning (WR-01)
- (46) Guard the undocumented AsyncPool inner-pool access (WR-05)
- (46) Clear both registries in a finally so reset() cannot strand them (WR-04)
- (46) Bump duckdb to 1.5.5 for semantic_views 0.12.0, closing the ASYNC-06 gap
- (47) WR-01 resolve the type-fidelity artifact through milestone archival
- (47) WR-02 escape table cells so a pipe cannot misalign the circularity guard
- (47) WR-03 refuse an empty field request instead of emitting a trailing comma
- (48-01) Refuse DuckDB container types before stripping type parameters
- (48-02) Render date, datetime and Decimal SQL literals (DBX-04)
- (48) CR-01 render drift-report cells as Text so rich cannot parse them as markup
- (48) CR-02 route every semantic_view() name through one shared SQL escaper
- (48) CR-03 emit warehouse metadata as pre-quoted Python literals in generated models
- (48) WR-01 compare the field role and the resolved column, not the annotation alone
- (48) WR-02 guard fetch_record_batch by proxying its reader, not refusing the call
- (48) WR-03 move probe setup inside the try that promises a fallback, not a crash
- (48) WR-04 pair each probed schema with its own route and label unprobed rows
- (48) WR-06 tell a duplicated result column apart from an absent one
- (48) IN-01 resolve run-end-encoded columns through their value type
- (48) IN-02 anchor the Snowflake cassette path on the test file, not the cwd
- (49-07) Make [arrowmodel] extra compose semolina[pyarrow]
- (49) Make [pandas] extra compose semolina[pyarrow]
- (50-01) Derive a metric's result-column name from the dialect
- (50-02) A provenance header can no longer name a backend that did not answer
- (50-06) Unbreak just docs-build on the dto_codegen module docstring
- (50) CR-01 validate the generated class name as a Python identifier
- (50) Upper-case inside the quotes in SnowflakeDialect.metric_result_column_name
- (50) Map a driver connection failure onto exit 4 in both codegen commands
- (48) Annotate Databricks decimal and interval as the driver returns (GREEN)
- (49) CR-01 accept every column key arrowmodel would, not just the first
- (49) WR-01 refuse AliasChoices / AliasPath at the pre-check
- (49) WR-02 refuse alias_generator by name, and document all three constructs
- (49) WR-03 normalise a creation-time OSError in sync iter_into
- (49) WR-04 close the three holes in the narrowed content fence
- (49) WR-05 make the path fence runnable, and fatal, in CI
- (49) IN-01 give the missing-column line its own sentence
- (49) IN-02 treat a duplicated result column as unresolvable, as the converter does
- (49) IN-04 list the arrowmodel and pydantic errors, and close the None-description hole
- (49) IN-06 spell DEFAULT_BASE_REF as the full 40-character SHA
- (codegen) Let a generated DTO be built from its field names
- (engines) Drop the registry name only while it still points at this engine
- (codegen) Refuse a leading-underscore field name with the way out
- (scope-fence) Skip the base-ref premise check outside CI, fail it inside
- (release) Compare the wheel's version to the tag as PEP 440, not as a string
- (results) Make Row copyable, hashable and a real Mapping
- (query) Compare OrderTerm and query by field identity, not by predicate
- In_() owns its values, engines validate, no duplicate columns (52-03)
- Cursor parity β safe close, one read per cursor, pyarrow guards (52-04)
- Refuse a timestamp column into a date field on the fast path (52-05)
- Keep a removed field removed down an inheritance chain (52-06)
- (release) Grant the CI call the permissions ci.yml requests
π Refactor
- (47) IN-01 delete the unused collect_rows() aggregator
- (48) WR-01 give FieldCheckRow a detail column for non-annotation drift
- (50) WR-02 drop render_dtos' unreachable
commandparameter - (codegen) Derive the Arrow annotation from the runtime type
π Documentation
- (planning) Backlog todo β reduce register()/create_engine() redundancy
- (planning) Refresh async todo with ADBC GIL-release findings
- (planning) Async machinery belongs in adbc-poolhouse, not Semolina
- (planning) Anyio posture for Semolina async layer
- (planning) Async unblocked β adbc-poolhouse 1.5.0 ships the async stack
- (planning) Backlog todo β arrowmodel typed-DTO integration + scrutiny
- (planning) Research todo β warehouse type fidelity for field typing
- (planning) Record untyped-fallback policy on type-fidelity todo
- (planning) Untypeable-case taxonomy + VARIANT->JsonValue decision
- (planning) Probe mechanics + timing model on type-fidelity todo
- Start milestone v0.7 Async & Typed Results
- Define milestone v0.7 requirements
- Create milestone v0.7 roadmap (5 phases)
- Tag 5 pending todos with resolves_phase after milestone v0.7 roadmap
- Archive v0.5/v0.6 phase directories to milestones/v0.6-phases
- (planning) Phase 46 context β async engine architecture decisions
- (46) Research async query surface domain
- (46) Add validation strategy
- (46) Create phase plan β 7 plans, 5 waves, tracer-first async query surface
- (46) Add pattern map
- (46) Create phase plan
- (46-01) Complete async packaging and Posture A lint plan
- (46-02) Complete async engine and cursor plan
- (46-03) Complete async cassette replay spike plan
- (46-04) Complete async registry & query entry point plan
- (46-06) Document async endpoints and async row streaming
- (46-06) Document the async extra and the async engine surface
- (46-06) Complete async documentation plan
- (46-05) Complete cancellation proof and loop-matrix gate plan
- (46-07) Record the phase gate result and close phase 46
- (46) Correct the claim that a pre-cancelled aexecute proves check-in
- (46) Tear the test fixture down with engine.dispose()
- (46) Name the real adbc-poolhouse floor, 1.6.2
- (46) Correct STATE.md β phase 46 is executed, not complete
- (46) Plan 46-08 β gap closure for the unwritten cancellation docs
- (46) Record gap-closure planning and correct stale STATE.md narrative
- (46-08) Document timing out a slow query on the async path
- (46-08) Document client disconnects and cancelling a stream mid-iteration
- (46-08) Complete cancellation-docs gap-closure plan
- (phase-46) Complete phase execution
- (phase-46) Close resolved todos and evolve PROJECT.md
- (phase-46) Correct plan count on the ROADMAP checkbox line
- (47) Create phase plan
- (47) Record planning completion and pattern map
- (47-01) Complete type-fidelity probe tracer plan
- (47-02) Complete named-disagreements plan
- (47-03) Complete the Snowflake, Databricks, and driver-capability plan
- (47-04) Explain warehouse type fidelity and why money is a Decimal
- (47-04) Complete the type-mapping decision doc plan
- (phase-47) Complete phase execution
- (48) Create phase plan β 6 plans across 4 waves
- (48) Create phase plan
- (48-01) Complete type map tracer & renderer seams plan
- (48-02) Complete databricks date/datetime/Decimal literals plan
- (48-03) Complete type map implementation plan
- (48-04) Complete probe promotion and arrow map plan
- (48-05) Complete the codegen --check plan
- (48-06) Replace the type-fidelity note Phase 48 falsified
- (48-06) Document codegen --check and correct the VARIANT claim
- (48-06) Complete documentation realignment and phase gate plan
- (48) WR-05 correct exit code 2 in both places and document the new report rows
- (49) Reword DTO-05 - pydantic is already a base dependency via adbc-poolhouse
- (state) Record phase 49 context session
- (49) Create phase plan β 7 plans, 4 waves
- (49) Create phase plan
- (49-01) Complete .into(DTO) tracer plan
- (49-03) Complete polars measurement and A3 closure plan
- (49-02) Complete iter_into plan
- (49-04) Complete packaging contract plan
- (49-05) Complete fetch_df and fetch_polars plan
- (49-06) Record plan 06 state, roadmap progress and requirements
- (49-07) Add the typed-results how-to with a worked BI example
- (49-07) Point arrow-output, streaming and installation at the new surface
- (49-07) Explain what the DTO schema check promises, retire two todos
- (49-07) Record plan 07 state, roadmap progress and requirements
- (49) Tick DTO-03/DTO-04 and persist human verification items as UAT
- (roadmap) Bind Phase 50 codegen to the decimal annotation constraint
- (50) Create phase plan
- (50) Create phase plan
- Checkpoint in-progress documentation rewrite
- (50-01) Complete Databricks metric result-column fix plan
- (50-02) Complete the DTO codegen tracer plan
- (50-03) Complete the measured per-backend alias plan
- (50-04) Complete the DTO-08 type-check proof plan
- (50-04) Record the third DTO-08 decision in STATE
- (50-05) Complete the refused-ExecuteSchema plan
- (50-06) Complete the DTO codegen CLI plan
- (50-07) Add the DTO codegen how-to page
- (50-07) Bring three pages into agreement with the shipped CLI
- (50-07) Complete the DTO codegen docs plan
- (50-08) Set requirement statuses from measurement and route R-04
- (50-08) Close phase 50 state and roadmap
- (50) IN-01 state the --name identifier constraint
- (50) Apply the Databricks consequence chain from live measurement
- (50) Correct the Snowflake alias claim the live probe falsified
- (50) Extract Phase 50 learnings
- Settle R-04 β COUNT metrics keep
| None, on a rationale that holds - (48) Record the Databricks type measurements and their consequences
- (48) Driver v0.1.3 changes nothing β record it, and the route it exposed
- Reword TYPE-03 β each backend's decimal follows its own driver
- Document the two new codegen-dto routes
- Correct the Databricks decimal claim, and the --view route's limits
- Give every warehouse-synced tab-set a DuckDB tab, and fix the Snowflake ones
- Explain AGG() vs MEASURE(), and route the landing page to Explanation
- (web-api) Show the typed response, not just warn about dict(row)
- Settle on Oxford -ize across source docstrings and tests
- (49) WR-06 state what the Databricks extra actually installs
- (49) WR-07 say that validate= is per-call, not per-field
- (49) WR-08 correct the shared-stream rule against measurement
- (49) IN-05 scope the no-Python-dictionaries claim to the default path
- (49) IN-03 explain the enum refusal and the validate=True remedy
- (49) IN-07 show aclosing for an async iter_into loop that may break
- (49) Correct the fetchone() -> None claim in the drained-stream rule
- (49) List TestDuplicateResultColumns in the test module's index
- Fix seven claims the pages got wrong, measured against the code
- Say how filter values reach the warehouse, and stop promising row.country
- Rebalance the set, consolidate the how-to guides, teach register=
- Correct the Snowflake codegen note and close the landing page's cursor
- (planning) Add the 2026-09-06 codebase review and a draft v0.8 Hardening milestone
- (planning) Fold the codebase-review fixes into v0.7 as Phases 51-57
- (planning) Close Phase 51 with its summary and evidence
- (planning) Record what PR #41 proved about the Phase 51 gates
- (planning) Record the review finding and the artifact evidence in the Phase 51 summary
- (planning) Add test suite review
- (planning) Insert Phase 52.1 Test Suite Soundness
- (planning) 52-03 complete; CORE-05, CORE-06, CORE-10 met
- (planning) 52-04 complete; CORE-07, CORE-08, CORE-09, CORE-12 met
- (planning) 52-05 complete; CORE-11 met
- (planning) Phase 52 complete; CORE-04 met, 52-SUMMARY.md
- (planning) Widen Phase 55 to --check accuracy, with alternatives (D9)
- (planning) Add static-analysis libraries to the --check alternatives
- (planning) Record the PR #43 review follow-up in 52-SUMMARY.md
- Point repo and docs URLs at the s-layer org
π§ͺ Testing
- (46-01) Add the ASYNC-04 packaging test, CI no-anyio smoke, and floor amendments
- (46-02) Prove the loop stays free and two queries run concurrently
- (46-03) Add replay-only async engine fixtures and named cassettes
- (46-03) Replay copied cassettes through the async path (D-16 spike)
- (46-05) Enforce the asyncio/Trio loop matrix structurally (ASYNC-05)
- (46-05) Prove cancellation reaches the driver and the pool recovers (ASYNC-06)
- (46) Failing tests for the fetch_record_batch() pool-slot leak
- (46) Failing tests for OSError escaping post-drain async iteration
- (46) Cover aexecute's check-in arm with tests that can fail
- (46) Failing test β aclose() leaks a pool slot silently (WR-01)
- (46) Failing tests β private _pool access breaks bare (WR-05)
- (46) Promote _sales_query to a shared conftest fixture
- (46) Failing tests β reset() strands its registries when teardown raises (WR-04)
- (47-01) Assert the DuckDB decimal canary by value
- (47-01) Guard the committed artifact against staleness and circularity
- (47-02) Assert each named disagreement on its exact Arrow type literal
- (47-03) Check the replayed schemas against a raw Arrow read of the same cassettes
- (48-01) Failing test β a list of DECIMAL must not annotate as decimal.Decimal
- (48-01) Re-point Phase 47's canary, regenerate its artifact, arm the scope fence
- (48-02) Add failing date/datetime/Decimal literal tests for DBX-04
- (48-03) Add failing Decimal-policy tests for Snowflake and Databricks
- (48-03) Add failing tests for the category-1 map gaps and Databricks interval
- (48-03) Prove the annotation contract by measurement, not by inspection
- (48-03) Add failing VARIANT -> JsonValue mapper and renderer tests
- (48-04) Add failing circularity guard for the promoted probe
- (48) CR-01 reproduce Rich markup mangling and crash in the drift report
- (48) CR-02 reproduce unescaped catalogue names inside semantic_view() literals
- (48) CR-02 assert on tokens outside string literals, not substring counts
- (48) CR-03 reproduce catalogue metadata injecting Python into a generated model
- (48) WR-01 reproduce a role change and a stale source= reporting as match
- (48) WR-02 reproduce the unguarded fetch_record_batch route and exercise the fallback
- (48) WR-03 reproduce probe setup escaping the fallback as an uncaught ValueError
- (48) WR-04 reproduce the carried-forward route and the borrowed route on absent fields
- (48) WR-06 reproduce a duplicated result column reporting as an absent one
- (48) IN-01 reproduce run-end-encoded columns falling through to Any
- (49-03) Measure polars for real and regenerate the type-fidelity artifact
- (49-02) Pin the pre-check's full rule set on both sides of its boundary
- (49-04) Assert the extras contract and lazy-import discipline
- (49-05) Prove the dataframe returns live and every guard's install command
- (49-06) Two-backend async DTO module, plus the async RESULT-01/02 groups
- (50-01) Reproduce the Databricks metric candidate miss
- (50-02) Pin D-02 β projection-only, and its param-free consequence
- (50-03) Pin the measured per-backend alias on all six cells
- (50-04) Prove the generated DTO passes stock strict, measured not asserted
- (50-04) Prove .into(GeneratedDTO) types as list[GeneratedDTO]
- (50-05) A refused ExecuteSchema still yields a working DTO
- (50-05) A failed probe and an unbindable alias both raise
- (50-06) Cover the codegen-dto CLI through CliRunner
- (50) CR-01 reproduce the --name class-name injection
- (50) Reproduce G-50-2 β Snowflake upper-cases inside the result-column quotes
- (50) Reproduce the UAT-7 gap β a connection failure escapes as a raw traceback
- (48) Pin Databricks decimal and interval to the measured value (RED)
- (49) CR-01 lock in that populate_by_name adds a second column key
- (49) WR-01 require the pre-check to refuse AliasChoices / AliasPath
- (49) WR-02 require the pre-check to name alias_generator
- (49) WR-03 require sync iter_into to normalise a creation-time OSError
- (49) WR-04 point the scope fence at three bypasses it lets through
- (49) WR-05 require the path fence to fail, not skip, when CI cannot run it
- (49) IN-01 require the missing-column line to deny the column
- (49) IN-02 pin a duplicated result column against the converter
- (49) IN-04 require ALIAS-03 to hold on a None description too
- (codegen) Pin that a generated DTO accepts its own field names
- (engines) Pin that a replacement engine survives the scope exit
- (codegen) Pin that a leading-underscore field name is refused
- (scope-fence) Pin the base-ref premise check to the fence's own skip policy
- (results) Pin the Row semantics a result object needs
- (query) Pin OrderTerm and query equality to field identity
- Delete tests/unit/test_scope_fence.py
- Make the tests that could not fail able to fail (52.1-01)
- Replace the tests that read the repository (52.1-02)
- Delete tests of other code and replace mirror tests (52.1-03)
- Suite hygiene and plain-language docstrings (52.1-04)
- Test the builder through its public surface (52.1-05)
- Pin in_(), empty-query engine calls and duplicate columns (52-03, red)
- Pin cursor parity β close safety, one read per cursor, guards (52-04, red)
- Pin timestamp-into-date as a strict xfail (52-05)
- Pin model inheritance and abstract bases (52-06, red)
- A field removed by a subclass must stay removed below it (52-06, red)
βοΈ Miscellaneous Tasks
- (release) Create GitHub release with artifacts and changelog
- (dependabot) Ignore duckdb bumps (version-locked to semantic_views)
- (46-01) Bump adbc-poolhouse floor to 1.6.1 and declare the async extra
- (46-01) Arm the TID251 Posture A lint gate over src/semolina
- (46) Bump adbc-poolhouse floor to 1.6.2 to unblock ASYNC-06
- (48) Mark phase complete - TYPE-05 Databricks interval accepted as tracked limitation
- (49-01) Declare pyarrow/pandas/polars/arrowmodel extras and regenerate lock
- (49-04) Prove DTO-05 against real clean venvs
- (50) Close Phase 50 UAT in STATE, consume the handoff artifacts
- (doc-writer) Refresh audit artifacts
- (doc-writer) Refresh gap, editor and persona reports
- Bump duckdb pin 1.5.3 -> 1.5.5
- Regenerate the type-fidelity artifact for the current extension build
- (release) Gate a tag on version agreement and a CI run against it
- Run on pull requests, enforce a coverage floor, build docs, widen the matrix
- (dev) Make
just testrun CI's suite, align the ruff pin, document maintenance - (release) 0.6.1