Skip to content

[Master] Weasel 9.0 #263

@jeremydmiller

Description

@jeremydmiller

Status: in-flight (foundation + AOT + intra-Weasel dedupe done; cross-product dedupe rows + hot-path migration pending)
Target version: Weasel 9.0
Milestone: 9.0
Part of [Master] Critter Stack 2026 (JasperFx/jasperfx#217).
Pillars: cold-start (JasperFx/jasperfx#212), AOT compliance (JasperFx/jasperfx#213), dedupe Marten ↔ Polecat (JasperFx/jasperfx#214).

Weasel is the database-manipulation substrate of the Critter Stack — schema migrations, DDL diffing, command-execution primitives. Per pillar #214 Rule 2: anything that touches databases and is currently duplicated between Marten and Polecat lands here. Weasel 9.0's job is to be the canonical home for that surface so Marten 9 and Polecat 4 stop carrying parallel copies.

This is a foundation release. Greenfield Weasel features wait for 9.x.

Goals for 9.0

  1. Canonical home for database-manipulation logic shared by Marten and Polecat. No piece of DDL/migration/storage logic exists in both products with non-trivial divergence.
  2. AOT-clean. IsAotCompatible=true on Weasel.Core (and the database-specific Weasel.* projects where feasible); reflective surfaces annotated.
  3. Cold-start friendly. Audit per-call generic instantiation and reflective discovery in command-building / DDL-diff hot paths.
  4. Build against JasperFx 2.0. Same TFM list (net9.0;net10.0), same IsAotCompatible posture.

Out of scope for Weasel 9.0

  • New database backends. Existing backends (Postgres, SQL Server, Oracle, MySQL, SQLite, EF Core adapter) are kept; new ones wait for 9.x.
  • Migrating logic into Weasel that doesn't touch databases (those go to JasperFx.Events per Rule 1).

✅ Already shipped

Weasel is on the 9.0.0-alpha.5 line. Foundation work, AOT readiness, and the intra-Weasel consolidation pass are complete; what remains is cross-product dedupe row migrations and the hot-path GenericFactoryCache pass.


What's left

Dedupe (JasperFx/jasperfx#214) — Weasel as canonical home for database concerns

Per pillar #214 Rule 2, the following are scoped to land or be confirmed here. The actual content is iterative — items move from Marten → Weasel.Core → Polecat as the audit deliverable runs, rather than being a fixed up-front list.

  • Audit deliverable: list every database-manipulation abstraction currently in both Marten and Polecat, classify under Rule 2, identify which side is the canonical starting point (Rule 3 says favor Marten). Output: a per-row migration plan filed as sub-issues here.
  • IStorageOperation migration — explicit example from the pillar. Move from Marten to Weasel.Core; verify Marten 9 and Polecat 4 both build against the consolidated abstraction. First concrete row of the audit.
  • Schema migration / DDL diffing review — the original Weasel charter. Verify there is no Polecat-side fork that needs collapsing into Weasel.Core.
  • Database-related enums duplicated across Marten and Polecat — sweep + relocate to Weasel.Core (per Rule 4 + Rule 2).

Intra-Weasel duplication (5-provider audit)

A separate axis from the Marten ↔ Polecat dedupe pillar above: inside Weasel itself, the 5 database-provider projects (PostgreSQL, SQL Server, Oracle, MySQL, SQLite) re-implement Table, TableColumn, IndexDefinition, ForeignKey, TableDelta, Migrator, Sequence, Function, and View side-by-side with ~85% structural overlap. The fluent API for configuring tables has also drifted (the same identity-column concept is spelled Serial() / AutoNumber() / AutoIncrement() depending on the provider). 9.0 is the only window where we can fix these breaking-change-style.

AOT (JasperFx/jasperfx#213)

  • IsAotCompatible=true on Weasel.Core.csproj once the project builds against JasperFx 2.0 + JasperFx.Events 2.0.
  • Audit reflective call sites in Weasel.Core (DDL builders, command construction, type/column mapping) — annotate or migrate. (Weasel.Core reflective surface verified clean; PR weasel#263: Add Weasel.Core.AotSmoke + per-provider IsAotCompatible audit #283 smoke-test now gates regressions.)
  • For database-specific Weasel.* projects (Postgresql, SqlServer, Oracle, MySql, Sqlite, EntityFrameworkCore): evaluate per-project AOT-cleanness. Some ADO.NET providers are AOT-hostile; in those cases annotate the Weasel wrapper rather than chase upstream. (PR weasel#263: Add Weasel.Core.AotSmoke + per-provider IsAotCompatible audit #283 / commit 5844c9f — added Weasel.Core.AotSmoke + per-provider audit table.)

Cold-start (JasperFx/jasperfx#212)

  • Audit per-call MakeGenericType / Activator.CreateInstance in DDL-build and command-construction hot paths; migrate to GenericFactoryCache or source-generator equivalents where the call site has a hot path.

Foundation work

  • Bump to JasperFx 2.0 + JasperFx.Events 2.0 (lockstep). (Directory.Packages.props: JasperFx 2.0.0-alpha.11, JasperFx.Events 2.0.0-alpha.4 — both on the 2.0 alpha line.)
  • TFM alignment: drop net8.0 (if present in any sub-project), confirm net9.0;net10.0 across the solution. Will add net11.0 when JasperFx does. (All packaged Weasel.* projects on net9.0;net10.0.)
  • Version bump to 9.0.0-alpha.1 on all packaged Weasel.* projects. (Currently on 9.0.0-alpha.5 per 4b79da4.)
  • Existing 1.x → 8.x → 9.0 migration notes: weasel has accumulated several major versions of patches; consolidate into a single 9.0 migration document. (docs/migration-guide.md — PR Add Weasel 8 → 9 migration guide #276 / commit dd1c81a.)

Existing open issues to land in 9.0 (initial sweep — not exhaustive)


Cross-product dependencies

Open design questions

  • Does Weasel 9.0 ship before Marten 9 / Polecat 4 (as the substrate they consume), or does the iterative dedupe pass mean Weasel cuts an alpha → Marten 9 alpha consumes it → Weasel finalizes → Marten / Polecat ship together? Lean toward the latter — Weasel's stability is gated on the downstream consumers validating each migrated row.

Explicitly out of scope for Weasel 9.0

  • Adding logic that has nothing to do with databases. That belongs in JasperFx.Events per Rule 1.

Linked implementation work

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions