feat(dummies): add DifferentFrom/Except exclusions to AnyString#283
Merged
Conversation
AnyString was the only scalar builder without exclusion constraints, forcing hand-rolled retry loops for the common "a value different from the one I already hold" case. Add DifferentFrom(string) and Except(params string[]), the exclusion pair every other scalar builder already exposes, and declare them in the per-TFM public-API baselines. Strings are not ordinal-mapped, so an exclusion cannot be built into the constructive layout the way it is for numerics. It is met instead by a bounded redraw of the layout (expected collisions are ~0 for any non-trivial shape) — the same bounded escape distinct collections use to skip a duplicate. An exclusion tight enough to leave the shape unsatisfiable surfaces at generation as a seed-bearing AnyGenerationException, never as an unbounded loop; this is documented as the one case where a string generator that exists may still fail to generate. OneOf stays terminal (it returns AnyStringOneOf) and cannot combine with an exclusion. Refs: #224
Reefact
force-pushed
the
claude/issue-224-discussion-tjw4sk
branch
from
July 22, 2026 06:16
e4cee7c to
efe4cf4
Compare
Record the decision behind #224 (English canonical plus French translation, indexed): AnyString exclusions are met by a bounded redraw and an unsatisfiable exclusion fails at generation with a seed-bearing error, the one departure from the constructive "built to satisfy" rule for scalars. Sibling to ADR-0013. Accepted by the maintainer. Refs: #224
Reefact
force-pushed
the
claude/issue-224-discussion-tjw4sk
branch
from
July 22, 2026 06:24
efe4cf4 to
5b17aa9
Compare
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.
Summary
AnyStringwas the only scalar builder without exclusion constraints. This addsDifferentFrom(string)andExcept(params string[]), closing the last gap in the scalar exclusion matrix and serving the common "a value different from the one I already hold, same shape" dummy-string need. (OneOfalready shipped as a terminal generator, so it is not re-added here.)Type of change
Changes
AnyString.DifferentFrom(string)andAnyString.Except(params string[])(empty string is a valid value to exclude; anullelement is not).StringSpecwith an accumulating, ordinal-deduplicated exclusion set. Generation stays constructive; when exclusions are present it takes a bounded redraw of the layout, and an exclusion that leaves the shape unsatisfiable fails atGenerate()with a seed-bearingAnyGenerationException— mirroring the distinct-collection escape (ADR-0013), never an unbounded loop.OneOfstays terminal (returnsAnyStringOneOf) and cannot combine with an exclusion.Dummies/PublicAPI/{netstandard2.0,net8.0}/PublicAPI.Unshipped.txt).SurfaceParityTestsalgebra table (addsExcept/DifferentFromforAnyString) and its stale comment.StringSpecdoc to record the one deferred-failure carve-out.Testing
dotnet build FirstClassErrors.sln— succeeds (also verified in CI-equivalent mode:-c Releasewith the warnings-as-errors ratchet, so the public-API analyzer RS0016/RS0017 pass;Dummiesbuilds fornetstandard2.0andnet8.0).dotnet test FirstClassErrors.sln— full solution green (Dummies.UnitTests includes 8 new tests for exclusions; nothing else regressed).FirstClassErrors.Analyzers.UnitTests).dotnet pack Dummies— package validation passes.Documentation
StringSpec).doc/updated (Dummies NuGet readme; ADR-0033 EN + FR).doc/handwritten/for-users/README.fr.md) updated if user-facing behavior changedThe only user-facing doc affected is the Dummies NuGet readme, which is English-only (no
.fr.mdcounterpart);ArbitraryTestValues.*does not enumerate the string vocabulary or the "never filter" invariant, so it needed no change. The ADR carries its French translation per the ADR conventions.Architecture decisions
ADR-0033 records that string exclusions are met by a bounded redraw and that an unsatisfiable exclusion is deferred to a seed-bearing generation failure — the one departure from the constructive "built to satisfy" rule for scalars, sibling to ADR-0013. Drafted as
Proposedand accepted by the maintainer (@Reefact) in this PR. (Renumbered from 0032 after #223 landed its own ADR-0032 on main; this branch is up to date with main.)Related issues
Closes #224
🤖 Generated with Claude Code
https://claude.ai/code/session_01MvjmrU4bRweSaj2SriJAdS