Adopt JasperFx 2.39.1 and compliance wave 4 - #5176
Merged
Merged
Conversation
Bumps JasperFx, JasperFx.Events, JasperFx.Events.ComplianceTests and both source generators 2.38.0 -> 2.39.1, and enrolls the four new shared suites that shipped in it (JasperFx/jasperfx#620): - fetch_for_writing_compliance (13) - stream_read_compliance (11) - event_metadata_compliance (9) - live_aggregation_compliance (7) Marten's compliance coverage goes from 65 to 105 tests with zero capability gates. MartenComplianceFixture resolves the new ComplianceStoreConfig.EnableHeaders flag onto Events.MetadataConfig.HeadersEnabled, the same way it already resolves EnableCorrelationTracking. EventSourcingTests.csproj gains the ComplianceSourceDir switch Polecat.Tests already had: passing it swaps the published suites for a jasperfx working copy, so a wave can be validated against Marten before the JasperFx release. Without it nothing changes. The bump also carries #618, which stops ShardName discarding the tenant slot for HighWaterMark names -- a store-global high-water shard still collapses to "HighWaterMark", but a tenant-scoped one now composes to "HighWaterMark:{tenant}". That is the grammar Marten already persisted through HighWaterShardIdentity, so the runtime needed no change; the upstream fix brought ShardName into line with Marten rather than the other way round. Bug_4785's assertion encoded the old "tenant slot is always discarded" behaviour and is updated to pin both halves of the new grammar, and the HighWaterShardIdentity doc comment that described the superseded behaviour is corrected. Verified on net9.0 against the published packages: 105/105 compliance, 1667/0/7 EventSourcingTests, 280/280 DaemonTests. Closes #5137 Closes #5139 Closes #5141 Closes #5143 Refs #5118 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VpDCvJcBDZerieJB4JEHde
jeremydmiller
added a commit
that referenced
this pull request
Aug 4, 2026
…delete (#5178) Follow-up to #5176, which updated this test for #618 (ShardName no longer discards the tenant slot for HighWaterMark names) but left it in a state worth tidying. The name was the actual defect: the test was still called high_water_mark_identity_is_the_literal_constant_and_is_deletable_by_it, while the whole content of the change was that the identity is NOT always the literal constant. Anyone grepping for the contract would have been misled. It was also doing two unrelated jobs that fail for different reasons -- a JasperFx/Marten contract check on the identity grammar, and the #4785 delete behaviour. Now split: - high_water_identity_grammar_agrees_between_shard_name_and_marten (no DB) pins that ShardName composition and HighWaterShardIdentity produce the same string. Both sides have to agree exactly, because the progression SQL is keyed by string equality on name, so drift desyncs writers from readers silently rather than failing. - store_global_high_water_row_is_deletable_by_its_literal_identity keeps the original delete assertion. Plus the coverage gap the bump exposed: per-tenant high-water rows became a first-class shape and never went through the delete path. The new test uses tenant ids acme_corp and acmeXcorp, which differ in exactly one character, and that character is '_' -- a LIKE single-character wildcard in PostgreSQL. If this delete ever stopped being `where name = ?` and became a pattern match, deleting one tenant's row would silently take the other's. Verified against PostgreSQL that the LIKE form does over-match and the equality form does not, so the test discriminates rather than passing vacuously. That is not a hypothetical failure mode for this table: #5171 is exactly this bug in the per-tenant progression READ filter, which builds an unescaped `name like '%:' || tenant`. The delete path is correct today; this pins it so the two paths cannot converge on the wrong answer. Test-only. 26/26 in the file (net9.0). Refs #4785, #5171 Claude-Session: https://claude.ai/code/session_01VpDCvJcBDZerieJB4JEHde Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
jeremydmiller
added a commit
that referenced
this pull request
Aug 4, 2026
`EnableExtendedProgressionTracking` cost one pooled connection and one transaction per shard database per node every 5 seconds, on an interval no application could reach — the field was private on the daemon and no DaemonSettings knob touched it. At 512 tenant databases that is ~37 connection acquisitions per second per node purely for telemetry, against rows the progress writer is already updating. #622 (JasperFx 2.39.0, adopted on master in #5176) turned the periodic beat off by default and put it behind `DaemonSettings.ExtendedProgressionHeartbeatInterval`, which Marten already surfaces on `opts.Projections` — so the fix is in the box and nothing here changes behavior. What was missing on the Marten side is that the change is invisible from the API surface and easy to regress silently. Adds the documentation for the cost model and the knob, and three tests pinning both halves: the default leaves ordinary progress publications unwritten, a configured interval restores the periodic flush, and status transitions are written either way. Claude-Session: https://claude.ai/code/session_017CTtw2kVRSZKp1p5RTxgAy Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 5, 2026
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.
Bumps JasperFx 2.38.0 → 2.39.1 and enrolls the four compliance suites that shipped in it (JasperFx/jasperfx#620).
fetch_for_writing_compliancestream_read_complianceevent_metadata_compliancelive_aggregation_complianceMarten's compliance coverage goes 65 → 105 tests, zero capability gates. The suites were authored against Marten and Polecat working copies simultaneously, so both stores were green before the upstream PR was opened.
Verified locally on net9.0, against the published packages
DaemonTests was run deliberately rather than as a formality: 2.39.x carries four daemon-side JasperFx changes (heartbeat removal, extended-progression writer scoping, per-tenant lag reads, EventProjection teardown targets).
The one thing in here that is not routine
The bump carries #618, which stops
ShardNamediscarding the tenant slot forHighWaterMarknames. A store-global high-water shard still collapses to the literal"HighWaterMark"; a tenant-scoped one now composes to"HighWaterMark:{tenant}".That is the grammar Marten already persisted, through
HighWaterShardIdentity.StoreGlobal/PerTenant. So the upstream change broughtShardNameinto line with Marten rather than the other way round, and the runtime needed no change — I checked everyShardState.HighWaterMarkconstruction site insrc/Martento confirm the high-water row name is built from those constants and never from aShardNamector.What did need updating is
Bug_4785_delete_projection_progress_by_shard_name, whose assertion encoded the old "the tenant slot is always discarded" behaviour and failed deterministically on the bump. It now pins both halves of the new grammar, and cross-checks them against Marten's own constants so the two definitions cannot drift apart silently. TheHighWaterShardIdentitydoc comment describing the superseded behaviour is corrected in the same commit.I want to flag that explicitly rather than bury it: a test assertion changed as part of a dependency bump. It is a stale-premise fix, not a softened assertion — the test is strictly stronger now (two identity shapes pinned instead of one, tied to the product constants) — but it is the kind of change that deserves a second pair of eyes.
Also included
EventSourcingTests.csprojgains theComplianceSourceDirswitch Polecat.Tests already had:dotnet test src/EventSourcingTests/EventSourcingTests.csproj -f net9.0 \ -p:ComplianceSourceDir=/path/to/jasperfx/src/JasperFx.Events.ComplianceTestsIt swaps the published suites for a jasperfx working copy so a wave can be validated against Marten before the JasperFx release — which is what made same-day two-store verification possible for wave 4. Without the property, nothing changes.
MartenComplianceFixtureresolves the newComplianceStoreConfig.EnableHeadersflag ontoEvents.MetadataConfig.HeadersEnabled, exactly as it already resolvesEnableCorrelationTracking.Polecat's matching adoption is JasperFx/polecat#410.
🤖 Generated with Claude Code
https://claude.ai/code/session_01VpDCvJcBDZerieJB4JEHde