Skip to content

Dummies: run the contract suite on the .NET Framework 4.7.2 floor and assert cross-TFM seed equality#279

Merged
Reefact merged 3 commits into
mainfrom
claude/issue-215-discussion-9j47us
Jul 21, 2026
Merged

Dummies: run the contract suite on the .NET Framework 4.7.2 floor and assert cross-TFM seed equality#279
Reefact merged 3 commits into
mainfrom
claude/issue-215-discussion-9j47us

Conversation

@Reefact

@Reefact Reefact commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Summary

Close the two gaps issue #215 identifies in how Dummies' netstandard2.0 asset is verified: its own contract suite never ran on the .NET Framework floor (only transitively, through FirstClassErrors' job), and same-seed-same-values across the two packaged assets (netstandard2.0 vs net8.0) was asserted nowhere. Both are now continuously checked in CI, per ADR-0022's "verified, not merely asserted" principle.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring
  • Analyzer / diagnostic change
  • Tests
  • Documentation
  • Build / CI / tooling

Changes

  • Cross-TFM seed equality in the packaged-asset guard (tools/dummies-check): each consumer leg emits a one-line SEEDBATCH= banner (a seeded batch drawn from the common surface); dummies.yml compares the net8.0 and net6.0 legs byte-for-byte and fails closed on divergence or a missing banner.
  • Broadened the guard's smoke: SeedBatch and RunSmoke now cover OrNull, ArrayOf/SequenceOf, PairOf/TripleOf, StringMatching and enum draws — generators the packaged-asset guard never touched — so they ride the cross-asset comparison too.
  • Dummies' contract suite on the net472 floor: Dummies.UnitTests imports build/Net472TestFloor.props and is added to the framework-floor loop in ci.yml (enumerating comment updated).
  • Conditioned out the .NET 8+ surface the netstandard2.0 asset does not carry: AnyModernTypeTests, CrossEngineReachabilityTests and ContinuousExclusionNudgeTests are excluded on net472 (saturated with the DateOnly/TimeOnly/Int128/UInt128/Half generators and with Math.BitIncrement/MathF/BitConverter.Half, netstandard2.1+ helpers absent from net472); isolated modern draws in SeedReproducibilityTests and AnyCollectionTests use #if NET8_0_OR_GREATER.
  • Package README (Dummies/README.nuget.md) now states the .NET Framework 4.7.2+ floor.

Testing

  • dotnet build FirstClassErrors.sln — succeeded, 0 warnings / 0 errors.
  • dotnet test FirstClassErrors.sln — not run wholesale; ran the affected suites instead (below).
  • Analyzer tests pass (FirstClassErrors.Analyzers.UnitTests) — not applicable (no analyzer change).

Ran locally:

  • dotnet test Dummies.UnitTests (net10.0) — 376 passed, 0 failed.
  • dotnet build Dummies.UnitTests -f net472 -p:EnableNet472Floor=true — compiles clean (0/0); Dummies resolves to the netstandard2.0 asset.
  • tools/dummies-check both legs (net8.0 + net6.0) — produced an identical SEEDBATCH sequence with RESULT=PASS; the compare step was exercised on tampered and missing banners and correctly went red.

Not run locally: the net472 test execution (no .NET Framework runtime on the Linux box) — the framework-floor job on windows-latest runs it. All .Message assertions in the floored suites target Dummies' own exception strings, not BCL messages, so the framework-message divergence class does not apply.

Documentation

  • Public API / error documentation updated
  • README / doc/ updated — Dummies/README.nuget.md states the .NET Framework floor.
  • French translation (doc/handwritten/for-users/README.fr.md) updated if user-facing behavior changed — not required (no user-facing behavior change; a package-README precision).
  • No documentation change required

Architecture decisions

  • No architectural decision in this pull request

This implements existing ADR-0022 (floor the library on .NET Framework 4.7.2) for Dummies; it records no new decision. The cross-version seed-stability policy the audit floats (§7.3 — "promise within a version, disclaim across") is deliberately left out of scope: the check here asserts cross-asset equality, not a frozen cross-version contract.

Related issues

Closes #215


Generated by Claude Code

claude added 3 commits July 21, 2026 20:39
The Dummies packaged-asset guard (tools/dummies-check) proved asset
SELECTION and per-asset reproducibility, but never compared the two
shipped assets against each other: each leg replayed its own seed in its
own process, so a seed-sequence divergence between the net8.0 and
netstandard2.0 assets would leave both legs green and reach NuGet unseen.

Emit the seeded common-surface batch as a one-line SEEDBATCH banner from
each consumer leg, then compare the net8.0 and net6.0 legs byte-for-byte
in dummies.yml. new Random(seed) keeps the legacy algorithm on modern
.NET, so the two assets should agree seed-for-seed; the check makes that
silent assumption a contract and fails closed on a missing banner.

Broaden SeedBatch and the smoke to cover the common generators the guard
never touched -- OrNull, ArrayOf/SequenceOf, PairOf/TripleOf,
StringMatching and enum draws -- so they ride the cross-asset comparison
too. Every part renders to printable ASCII, keeping the banner grep-safe.

Refs: #215
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KjV7imhqhLeUr6vZscTSHh
Dummies.UnitTests targeted net10.0 only, so Dummies' own contract suite
(conflict detection, regex oracle, distinctness gating, seed
reproducibility) never ran on the netstandard2.0 asset that .NET
Framework consumers load -- it was exercised there only transitively,
through FirstClassErrors' floor job. ADR-0022 asks for a floor that is
continuously verified, not merely asserted.

Import build/Net472TestFloor.props (as the FirstClassErrors library test
projects do) so the suite gains a net472 leg under EnableNet472Floor, and
add Dummies.UnitTests to the framework-floor loop in ci.yml.

Condition out the .NET 8+ surface the netstandard2.0 asset does not carry.
AnyModernTypeTests, CrossEngineReachabilityTests and
ContinuousExclusionNudgeTests are excluded wholesale: they are saturated
with the DateOnly/TimeOnly/Int128/UInt128/Half generators and with
Math.BitIncrement/MathF/BitConverter.Half (netstandard2.1+ helpers absent
from net472) used to build adjacent-value fixtures, and they guard
modern-.NET reachability and nudge behavior that is runtime-invariant. The
isolated modern draws in SeedReproducibilityTests and AnyCollectionTests
are guarded with #if NET8_0_OR_GREATER. net10 keeps all tests green;
net472 compiles clean and the framework-floor job runs it on Windows.

Refs: #215
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KjV7imhqhLeUr6vZscTSHh
The FirstClassErrors package README states its .NET Framework 4.7.2+
support; the Dummies README named only netstandard2.0 and net8.0, leaving
the floor to inference. State it explicitly now that Dummies' own suite
verifies it on the net472 floor in CI.

Refs: #215
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KjV7imhqhLeUr6vZscTSHh
@Reefact
Reefact force-pushed the claude/issue-215-discussion-9j47us branch from a6e3146 to 67f6795 Compare July 21, 2026 20:41
@Reefact
Reefact merged commit 4d572f0 into main Jul 21, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dummies: run the test suite on the .NET Framework 4.7.2 floor and assert cross-TFM seed equality

2 participants