Releases: ivanvyd/LakeWright.NET
Release list
v2.1.0
Security
- Dashboard marker checks now describe only marker presence. Strict embed authorization requires
an explicit tenant-to-dashboard assignment and trusted isolation evidence bound to the served
revision and definition digest. Existing constructors remain available, but strict verification
fails closed without the new evidence and assignment providers. Migrate strict integrations using
ADR 0028. - The Signalboard demo now validates antiforgery tokens on sign-in and sign-out.
Fixed
- External JSON exports parse root arrays and stream complete, ordered chunk chains. Incomplete,
truncated, malformed, and inconsistent results fail explicitly; expired external links can be
renewed before rows from that chunk are emitted. Inline materialization has a 25 MiB limit. - Statement and Genie deadlines include credentials, submission, polling, response bodies, and
export reads. Accepted Genie conversation ownership is recorded before polling; recoverable
identifiers remain available when the answer times out. - Operation dispatch uses a bounded worker pool so a held upstream poll does not serialize all
tenants. Refresh status treatsUSER_CANCELEDas cancellation and keeps unknown-state errors safe. - Candidate consumer validation rejects missing or mismatched packages instead of falling back
to a public or cached LakeWright package. CI fails when advisory scan evidence is unavailable,
and package compatibility validation again checks the current stable 2.x baseline. - Signalboard's Docker build includes its four linked public images. Authenticated navigation
reflows at narrow widths, and starting an operation provides visible status feedback.
Added
- Raw-data columns can opt into exact
BIGINTandDECIMAL(p,s)filters throughWholeNumber
andFixedPoint. ExistingNumberfilters retain approximateDOUBLEsemantics. See
numeric contracts for configuration and precision limits. - Load verification records bounded admission, completion, failure, drop, and censoring counts,
and gates generated throughput separately from completion ratio. Local network and browser
lab profiles record their conditions without claiming production capacity or field web vitals.
v2.1.0-rc.1
Security
- Dashboard marker checks now describe only marker presence. Strict embed authorization requires
an explicit tenant-to-dashboard assignment and trusted isolation evidence bound to the served
revision and definition digest. Existing constructors remain available, but strict verification
fails closed without the new evidence and assignment providers. Migrate strict integrations using
ADR 0028. - The Signalboard demo now validates antiforgery tokens on sign-in and sign-out.
Fixed
- External JSON exports parse root arrays and stream complete, ordered chunk chains. Incomplete,
truncated, malformed, and inconsistent results fail explicitly; expired external links can be
renewed before rows from that chunk are emitted. Inline materialization has a 25 MiB limit. - Statement and Genie deadlines include credentials, submission, polling, response bodies, and
export reads. Accepted Genie conversation ownership is recorded before polling; recoverable
identifiers remain available when the answer times out. - Operation dispatch uses a bounded worker pool so a held upstream poll does not serialize all
tenants. Refresh status treatsUSER_CANCELEDas cancellation and keeps unknown-state errors safe. - Candidate consumer validation rejects missing or mismatched packages instead of falling back
to a public or cached LakeWright package. CI fails when advisory scan evidence is unavailable,
and package compatibility validation again checks the current stable 2.x baseline. - Signalboard's Docker build includes its four linked public images. Authenticated navigation
reflows at narrow widths, and starting an operation provides visible status feedback.
Added
- Raw-data columns can opt into exact
BIGINTandDECIMAL(p,s)filters throughWholeNumber
andFixedPoint. ExistingNumberfilters retain approximateDOUBLEsemantics. See
numeric contracts for configuration and precision limits. - Load verification records bounded admission, completion, failure, drop, and censoring counts,
and gates generated throughput separately from completion ratio. Local network and browser
lab profiles record their conditions without claiming production capacity or field web vitals.
v2.0.0
Changed
LakeWright.Conversationsnow requires an opaque application owner key forAskAsyncand
ContinueAsync. The library records ownership only after a conversation is created, refuses
unrecorded or foreign-owner continuation and deletion before any workspace call, and exposes
owner-filteredListAsyncandDeleteAsync. Migrate every caller by passing the authenticated
application's stable opaque principal key; do not use a display name or email address. The
former overloads cannot safely infer ownership and were removed rather than silently treating
all users as one owner.
Added
-
New
LakeWright.Toolinginstalls thedotnet lakewrightcommand for offline or live dashboard
publish-gate inspection and clean net8 package-floor validation against a packed candidate. -
Generic shared-schema statement and export support is removed before the 2.0.0 release. An outer
predicate over caller-authored SQL cannot prove a projected tenant or scope key belongs to every
source row. Use schema-per-tenant contexts, or enforce a source-owned shared-schema policy outside
the generic APIs. -
New
LakeWright.HealthCheckssupplies readiness checks for the cached first OAuth token leg and
non-billable warehouse-state reads. A statement probe is excluded by default and requires a
host-providedIReadinessStatementProbe, so a health endpoint cannot accidentally wake compute. -
LakeWright startup validation now aggregates registered Databricks, Genie, and dashboard-ops
option failures into one exception with their configuration-key messages, instead of failing on
the first hosted options validator that happens to run. -
New
LakeWright.Embedding.Opsadds tenant-bound, ops-principal dashboard refresh orchestration
over Jobs API 2.2. It joins only an active run whose recorded job parameters identify the same
tenant, applies a minimum-success interval, uses opaque bucketed idempotency tokens across
replicas, invalidates stale name-to-id lookups, and refuses unrecorded or foreign run status
requests before they reach the workspace. Multi-replica applications replace the process-local
IRefreshRunOwnershipimplementation with durable storage before exposing status endpoints.
It also supplies idempotent cache busting: a successful job run stamps every draft dataset with
a stable comment, PATCHes with the dashboard ETag, and publishes only once. Publishing defaults
toembed_credentials: false; an optimistic-concurrency retry succeeds only when the same
marker is already present. -
IEmbedPreconditionis an opt-in broker seam.IDashboardPublishVerifiercompares draft and
published revision metadata with a short cache; strict served-definition verification requires
an adopter-providedIPublishedDashboardDefinitionReader, because the public Lakeview published
endpoint does not expose serialized dashboard SQL.PublishedRevisionEmbedPreconditionfails
closed when that proof is unavailable or the published definition fails the publish gate. -
IDashboardMetadataCatalogadds short-lived, host-replaceable caching for draft metadata,
published metadata, and a complete auto-paged dashboard listing. It is an operations-principal
surface for an authorized portal backend, not a browser-facing authorization mechanism. -
IWarehouseWarmerprovides an explicitly opt-in, rate-limited warehouse-start hint for a
dashboard-open signal. It is disabled by default and never executes or reads a statement. -
New
LakeWright.Databricks.RawDatasupplies declarative raw-data sources and a scoped query
service. It renders only allow-listed view and column identifiers, binds every filter and paging
value as a typed statement parameter, escapes text search wildcards, and rejects invalid input
before it can become a warehouse error. -
Raw-data CSV export now returns only a bounded inline result or an opaque, tenant-and-owner
authorized operation. Larger results stream through the existing scoped external-links poller;
a caller never receives a warehouse statement id. Text formula prefixes are neutralized in the
shared source projection so grid and CSV values agree. Multi-replica hosts replace the
process-localIRawDataExportOwnershipstore before exposing stream endpoints. -
GenieAnswerSanitizerremoves model-supplied HTML and neutralizes markdown links by default.
Hosts may opt in to exact HTTPS allow-list entries when their renderer is prepared to render
those links. -
StatementOptionsnow also governs tenant-scoped exports: an export whose initial submission is
pending polls through the same bounded terminal-state path as an interactive statement before it
begins fetching external links. -
LakeWright.Databricksnow exposes dependency-free statement duration, outcome, pending
warehouse-wait, export row, and export-byte metrics. Every tag is a low-cardinality statement
kind or outcome; no tenant identifier is emitted. -
ILakeWrightFeatureGateadds a fail-closed runtime kill switch for embedding, statements,
operations, and conversations. The default is always-on;AddLakeWrightFeatureGatein the
ASP.NET Core package binds configuration throughIOptionsMonitor, so reloads take effect
without a process restart. -
New opt-in
LakeWright.Caching.DistributedsuppliesIDistributedCacheimplementations for
workspace and viewer token caches. Keys are hashed, entries have token-derived absolute expiry
with jitter, and tenant eviction advances a shared generation marker. -
New opt-in
LakeWright.Caching.Redissupplies immutable, Redis-backed conversation ownership
across replicas. It claims a conversation withSET NX, records an owner-specific membership
set for safe listing, and hashes conversation and owner identifiers in Redis keys. -
Dashboard token minting now emits a duration histogram and cache lookup counter, plus one
Information log with dashboard id, cache states, elapsed time, and a truncated SHA-256 viewer
hash. Raw viewer identifiers and tenant identifiers are never telemetry or log fields.
v2.0.0-rc.1
Changed
LakeWright.Conversationsnow requires an opaque application owner key forAskAsyncand
ContinueAsync. The library records ownership only after a conversation is created, refuses
unrecorded or foreign-owner continuation and deletion before any workspace call, and exposes
owner-filteredListAsyncandDeleteAsync. Migrate every caller by passing the authenticated
application's stable opaque principal key; do not use a display name or email address. The
former overloads cannot safely infer ownership and were removed rather than silently treating
all users as one owner.
Added
-
New
LakeWright.Toolinginstalls thedotnet lakewrightcommand for offline or live dashboard
publish-gate inspection and clean net8 package-floor validation against a packed candidate. -
Generic shared-schema statement and export support is removed before the 2.0.0 release. An outer
predicate over caller-authored SQL cannot prove a projected tenant or scope key belongs to every
source row. Use schema-per-tenant contexts, or enforce a source-owned shared-schema policy outside
the generic APIs. -
New
LakeWright.HealthCheckssupplies readiness checks for the cached first OAuth token leg and
non-billable warehouse-state reads. A statement probe is excluded by default and requires a
host-providedIReadinessStatementProbe, so a health endpoint cannot accidentally wake compute. -
LakeWright startup validation now aggregates registered Databricks, Genie, and dashboard-ops
option failures into one exception with their configuration-key messages, instead of failing on
the first hosted options validator that happens to run. -
New
LakeWright.Embedding.Opsadds tenant-bound, ops-principal dashboard refresh orchestration
over Jobs API 2.2. It joins only an active run whose recorded job parameters identify the same
tenant, applies a minimum-success interval, uses opaque bucketed idempotency tokens across
replicas, invalidates stale name-to-id lookups, and refuses unrecorded or foreign run status
requests before they reach the workspace. Multi-replica applications replace the process-local
IRefreshRunOwnershipimplementation with durable storage before exposing status endpoints.
It also supplies idempotent cache busting: a successful job run stamps every draft dataset with
a stable comment, PATCHes with the dashboard ETag, and publishes only once. Publishing defaults
toembed_credentials: false; an optimistic-concurrency retry succeeds only when the same
marker is already present. -
IEmbedPreconditionis an opt-in broker seam.IDashboardPublishVerifiercompares draft and
published revision metadata with a short cache; strict served-definition verification requires
an adopter-providedIPublishedDashboardDefinitionReader, because the public Lakeview published
endpoint does not expose serialized dashboard SQL.PublishedRevisionEmbedPreconditionfails
closed when that proof is unavailable or the published definition fails the publish gate. -
IDashboardMetadataCatalogadds short-lived, host-replaceable caching for draft metadata,
published metadata, and a complete auto-paged dashboard listing. It is an operations-principal
surface for an authorized portal backend, not a browser-facing authorization mechanism. -
IWarehouseWarmerprovides an explicitly opt-in, rate-limited warehouse-start hint for a
dashboard-open signal. It is disabled by default and never executes or reads a statement. -
New
LakeWright.Databricks.RawDatasupplies declarative raw-data sources and a scoped query
service. It renders only allow-listed view and column identifiers, binds every filter and paging
value as a typed statement parameter, escapes text search wildcards, and rejects invalid input
before it can become a warehouse error. -
Raw-data CSV export now returns only a bounded inline result or an opaque, tenant-and-owner
authorized operation. Larger results stream through the existing scoped external-links poller;
a caller never receives a warehouse statement id. Text formula prefixes are neutralized in the
shared source projection so grid and CSV values agree. Multi-replica hosts replace the
process-localIRawDataExportOwnershipstore before exposing stream endpoints. -
GenieAnswerSanitizerremoves model-supplied HTML and neutralizes markdown links by default.
Hosts may opt in to exact HTTPS allow-list entries when their renderer is prepared to render
those links. -
StatementOptionsnow also governs tenant-scoped exports: an export whose initial submission is
pending polls through the same bounded terminal-state path as an interactive statement before it
begins fetching external links. -
LakeWright.Databricksnow exposes dependency-free statement duration, outcome, pending
warehouse-wait, export row, and export-byte metrics. Every tag is a low-cardinality statement
kind or outcome; no tenant identifier is emitted. -
ILakeWrightFeatureGateadds a fail-closed runtime kill switch for embedding, statements,
operations, and conversations. The default is always-on;AddLakeWrightFeatureGatein the
ASP.NET Core package binds configuration throughIOptionsMonitor, so reloads take effect
without a process restart. -
New opt-in
LakeWright.Caching.DistributedsuppliesIDistributedCacheimplementations for
workspace and viewer token caches. Keys are hashed, entries have token-derived absolute expiry
with jitter, and tenant eviction advances a shared generation marker. -
New opt-in
LakeWright.Caching.Redissupplies immutable, Redis-backed conversation ownership
across replicas. It claims a conversation withSET NX, records an owner-specific membership
set for safe listing, and hashes conversation and owner identifiers in Redis keys. -
Dashboard token minting now emits a duration histogram and cache lookup counter, plus one
Information log with dashboard id, cache states, elapsed time, and a truncated SHA-256 viewer
hash. Raw viewer identifiers and tenant identifiers are never telemetry or log fields.
v1.2.1
NuGet availability: NuGet accepted the 1.2.1 packages, but its catalog/index processing is still pending. Standard NuGet V3 restore is not yet available. The signed
.nupkgassets are available from this release.
Security
- Shared-schema statements and exports now apply a LakeWright-owned outer predicate on the resolved
tenant column. A raw occurrence of:tenant_idwas not sufficient evidence of isolation: an
inert expression such as:tenant_id IS NOT NULLcould return every row. Shared-schema callers
must submit a single SELECT or WITH query that projects the configured tenant column; write
statements and trailing semicolons are refused before the workspace call. AddLakeWrightTenancyno longer registers the concrete resolver type, preventing unrelated
application code from resolving a resolver that retains the tenant-context factory. The extension
now supports an explicit resolver lifetime while preserving the scoped default.
Fixed
- The net8 consumer dependency check now uses a runner-provided, fail-closed assertion instead of
silently accepting a missingrgexecutable. Dashboard inspection now returns a structured
failure for malformed dataset entries; ops-token caching is covered through two catalog pages. - Databricks credential ambiguity is checked after DI composition, so a
TokenCredentialregistered
after service-principal configuration no longer bypasses startup validation.
v1.2.0
Added
LakeWright.DatabricksandLakeWright.Conversationsnow ship net8.0 assets. The stock net8
consumer resolvesIStatementExecutorand executes a shared-schema tenant-scoped statement
against a loopback workspace, while CI verifies its package graph has no persistence dependency.
Changed
AddLakeWrightDatabricksis now theLakeWright.Databricksextension, so a worker or stock
net8 consumer does not need the ASP.NET Core package. The former static ASP.NET Core entry point
remains as an obsolete compatibility forwarder for existing compiled callers.
v1.1.2
Security
- Removed unapproved project and environment identifiers from public XML documentation, design
records, release evidence, and collaboration metadata. Added a private-denylist gate to CI and
the release workflow; releases now unpack generated NuGet packages and scan their contents before
publication.
v1.1.1
Fixed
- Billing-backed cost attribution now enforces the 31-day and one-day-future report bounds in the
public service and Databricks reader, not only at the HTTP endpoint. A process-wide configurable
concurrency gate also bounds active and queued billing statements; saturation returns the safe,
transientBILLING_BUSYcode and HTTP 503 instead of growing an unbounded queue. Server-side
submission cancellation and an uncertain-create hold prevent lost responses from silently
returning remote-capacity admission early. - Completed the durable publication record for 1.1.0 after verifying its signed tag, release
workflow, package digests, build-provenance attestations, NuGet registration and an isolated
public-package consumer.
v1.1.0
Added
- Safe monthly partitioning for
audit_events, with atomic populated-table migration,
row-for-row validation, rollback/finalization, globalAuditEvent.Iduniqueness, preserved
grants and row-security policies, and configurable retention defaulting to seven years. The
migration and recurring maintenance executable requires a distinct table-owning connection;
the application role receives no DDL. ADR 0020. - Opt-in billing cost attribution backed by Databricks
system.billing.usageand
system.billing.list_prices. Tenant-owned job runs are selected in PostgreSQL before one bounded
warehouse query; fixed SQL, bound parameters, report and price-window proration, corrections,
explicit currencies, a 500-run limit, polling deadlines and redacted upstream errors preserve
the existing tenant and HTTP boundaries. ADR 0012.
Changed
- Updated
Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCoreto 10.0.11; the
xUnit/VSTest packages to 4.0.0; Testcontainers.PostgreSql to 4.14.0; WireMock.Net to 2.15.0;
Databricks setup-cli to 1.14.1; CodeQL actions to 4.37.9; and the pinned .NET 10 SDK container
digest. All generated lock files were refreshed and the full local and hosted gates passed.
Fixed
- Documentation checks now examine tracked and non-ignored new Markdown files instead of scanning
ignored personal notes. This keeps local verification reproducible without omitting new release
documentation.
v1.0.1
Changed
- Consolidated the two internal in-memory token-cache implementations behind one canonical cache.
This removes duplicate expiry and concurrency logic without changing the public API or token
lifetime behavior (#100).
Fixed
DashboardPublishGate.InspectAllnow reports eachMarkerHit.DatasetIndexas the zero-based
index of the dataset that produced it.Inspectretains its existing public signature and
continues to report index0(#101).