Repository navigation
test: the EF family's probes run one check per obligation - #56
Merged
Merged
Conversation
E01 to E16 ran as one check named `claim`, so no listed obligation of an EF claim earned credit and every per-obligation seed of theirs could only be missed. Each probe now runs one Row.Check per obligation its row's axes select, named by the claim's obligation id and given its baseline: the wrapped twin under plain EF (Twin), the documented refusal (E05), memory (E05, E06, E13), or the docs sentence where it is the only baseline (E04's char and Guid defaults, E06, E07, E08, E09, E10, E11, E12). No outcome note key is called any more. Where a side throws, EfSides decides: both alike is inconclusive (uncited), the twin alone is inconclusive, the value object alone or both differently is a violation. NoOperator (E05) and E12's uncited inapplicable became inconclusive; E16's both-refuse expected refusal too. E01 applies a length or a precision to every wrapped type, as configured, where it substituted `none` and so compared nothing for facet-kept. Four obligations for rows no obligation selected, each with its seed: E04 not-on-efs-list and own-configuration-wins, E12 underlying-type-does-not-reach, E13 contains. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…meOffset, TimeSpan or ulong E02's 12 rows over those types under where-value-compare and order-by failed on both sides, the wrapped twin under plain EF included: ">=" is "could not be translated" (InvalidOperationException) and ORDER BY a NotSupportedException. Triage 2: a framework behaviour, pinned. EF's "Query limitations" page lists decimal beside them, which EF Core 10 compares and orders; the test holds that as the control. The Facts project gains the Microsoft.EntityFrameworkCore.Sqlite reference for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…able, citing KB-039 Each of E02's four obligations declares shape.wrapped DateTimeOffset, TimeSpan or ulong with ef.query where-value-compare or order-by inapplicable (fact:KB-039). The excuse depends on the axes alone, so it is a declaration (#50), not code: the six pairs are wanted by no obligation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 17, 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.
WS2 step 4, the EF family: every probe whose claim's first surface is ef (E01 to E16) runs one
Row.Checkper obligation its row's axes select, named by the claim's obligation id and given its baseline. No EF probe or harness file calls an outcome note key any more.prober statusshows 0 uncredited for all 16 EF claims, where every one of their 44 listed obligations was uncredited before, and 48 of 48 seeds are caught, each by the check of its own obligation. No row that passed before fails now.What changed
claims.jsonlists them. Checked mechanically over the replay's evidence: for all 852 rows, the checks that ran are exactly the obligations the row's axes select (0 mismatches).Baseline.Twin(the wrapped twin's context under plain EF against the value object's underUseTypeKit()): E01, E02, E03, E04, E12'svalue-object-type-reaches, E14, E15, E16.Baseline.Refusal: E05's comparison, ordering,Min/Maxand query filter.Baseline.Model(memory): E05's equality and.Valueorder, E06's value-object equality, E13.Baseline.Docswhere the sentence is the only baseline: E04's char and Guid defaults (README#keys), E06's "could not be translated" (README#queries), E07 (#closed-sets), E08 (docs/ef-core.md#option-and-result, withRefusalNamesTheType), E09 (#an-option-for-nothing-found), E10 (docs/ef-core.md#reading-back-without-validation, withStoredFactoryReadUnvalidated), E11 (#setup), E12's new obligation.column-type/nullablecompare the model and the script with the configured facet's own fields masked;facet-keptcompares those fields (and the script for a column type).column-not-castcompares the SQL.stored-as-namecovers a table's stored text and the member read back;in-collections-and-jsoncovers the stored JSON of a collection or JSON column.model-failschecks the refusal and its type;error-says-sochecks that the message names the type.reads-without-create,Revalidate()torevalidate-finds.EfSides(harness/EfHarness.cs) decides how a two-sided check ends when a side threw. Neither threw: compare. Only the value object threw: violation. Both threw with one exception type: inconclusive (uncited). Both threw with different types: violation. Only the twin threw: inconclusive.none, sofacet-keptcompared nothing on 82 rows and 42 pairs could never be covered. All 82 now compare equal to the twin. E01's pairs went from 372/414 to 414/414.NoteKeysis untouched. The pass keys the EF probes used stay asc.Note, andComparednotes say what each check compared.Commits:
66dc2d7the conversion;e0f9a63KB-039;845e1c0E02's declaration;5e7884arelease/2.2.0 merged in (WS2b: a cited fact is executable, fixtures beside fact tests, seeds by footprint #55).Obligation decisions: four obligations added
Some rows selected no listed obligation. As #54 did for C11 and C17, they get an obligation quoted from the claim's own source, each with its seed:
not-on-efs-listint,long,short,sbyte,uint,ulongandushort, and notbyte."shape.wrappedstring,ef.key-configdefaultown-configuration-winsshape.wrappedchar, Guid, string;ef.key-configValueGeneratedOnAdd, ValueGeneratedNeveron-adddefect (a char or Guid key forced never generated as an explicit configuration)underlying-type-does-not-reachconfigurationBuilder.Properties<decimal>().HavePrecision(18, 2)reachesdecimalproperties, and not anAmountthat wraps one."ef.convention-typeunderlyingModelConfiguration) to a value-object propertycontainsef.querycontainsContainsof a value object asfalseBefore and after, per probe
f8993e3, replayed with footprints from an empty state in a detached checkout of its own (16 passed).5e7884a,replay --family ef(16 passed).Row.Checkcounts as one check. "Rows passing" is whatRec.Runpasses.column-typepass 139;facet-keptpass 132;nullablepass 36column-not-castinapplicable 12, pass 203;get-valueinapplicable 2, pass 75;valueinapplicable 6, pass 68;value-or-nullinapplicable 4, pass 60keyspass 35;nullable-propertiespass 35;stored-as-underlyingpass 107byte-not-generatedpass 4;char-key-yourspass 1;generated-on-addpass 12;guid-key-yourspass 1;not-on-efs-listpass 1;own-configuration-winspass 9comparisonpass 30;equality-allowedpass 6;min-maxpass 12;orderingpass 24;query-filterpass 12;value-order-allowedpass 6value-not-translatedpass 5;value-object-comparisonpass 7in-collections-and-jsonpass 2;non-member-throwspass 3;stored-as-namepass 3;unknown-name-throwspass 3error-says-sopass 20;model-failspass 20element-at-skipspass 3;first-reads-one-rowpass 9;single-asks-for-twopass 6reads-without-createpass 30;revalidate-findspass 30order-does-not-matterpass 14underlying-type-does-not-reachpass 7;value-object-type-reachespass 5containspass 5;element-valuepass 5tpc-assign-on-sqlitepass 3;tph-tpt-rootpass 6as-for-primitivespass 8column-typepass 5;conversionpass 5;neverpass 5;on-addpass 5;optionalpass 5No row regained and none lost. Before, every row but E02's 12 already passed as a row, and those 12 still earn nothing: they were
expected-refusal(uncitedboth-threw) and are nowinapplicable, declared from KB-039. The conversion changes what each passing row credits: the obligations it serves, and E01's facet pairs.E02's 6 uncovered pairs were uncovered before too (Noticed, below).
Seeds
prober seeds --probe Pfor each of the 16 probes, one at a time:66dc2d7;5e7884a, after its declaration and the merge.The merge changed nothing under
src/ortools/probe, so the 15 earlier runs stand.48 seeds, 48 caught, each by the check of its own obligation (the detail's example names it), the four new ones included.
seeds output
Findings of this step, triaged
DateTimeOffset,TimeSpanorulongunderwhere-value-compareororder-by. Before, these were uncitedboth-threw; after the conversion's first replay,inconclusive: both sides refuse the query alike.>=raisesInvalidOperationException"could not be translated", andORDER BYraisesNotSupportedException"SQLite does not support expressions of type 'X' in ORDER BY clauses".design/knowledge/KB-039-…, testtest/CodoMetis.TypeKit.Facts/KB039.cs, 10 cases). EF Core 10's SQLite provider neither compares nor orders those three types, and translates their equality.decimal, which EF 10 compares and orders; the test holds that as the control.shape.wrapped∈ {DateTimeOffset, TimeSpan, ulong} ×ef.query∈ {where-value-compare, order-by} inapplicable,cite: fact:KB-039.universecounts the 6 pairs as wanted by no obligation.HasColumnType), in the firsttry: triage 1, my harness.facet-keptcompared the create script without theAUTOINCREMENTstrip thatcolumn-typeapplies for the documented char/Guid generation. Fixed before the commit: both checks share the normalised script.Uncited excuses
Each outcome note the EF family called, and what it is now:
both-threw(E01, E02, E03, E13; E10's model step; E16'sexpected-refusal"both refuse the model") is nowEfSides: compared by exception type, inconclusive when alike, a violation when not.5e7884a.plain-refused(E01, E02, E03, E10's twin write) is now inconclusive, uncited: no twin to compare with. No row reached it.no-operator(E05) is now inconclusive, uncited. Decision 57's value objects all have the generated operators. No row reached it.Outcome("inapplicable"), a facet that changes nothing on the plain type even after the fallback facet, is now inconclusive, uncited. No row reached it.Entries added
design/knowledge/README.md, andtest:pointing atKB039.cs.docs-query check: 0 problems in 726 links, 512 ids, 8 fact citations and 39 facts.test/CodoMetis.TypeKit.Facts/CodoMetis.TypeKit.Facts.csprojgained one line,<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" />, for KB039. It merged cleanly beside WS2b: a cited fact is executable, fixtures beside fact tests, seeds by footprint #55's fixture item. Nothing else under that project changed.char-key-not-generatedandguid-key-not-generated.Declared applicability (#50)
EfSides' outcomes;Verdicts
All through
build-verdict test --project Pat5e7884a:TYPEKIT_PG.ProbeCiteTestsandProbeNoteKeyTestsare among them; theNotefloor of 100 holds.Noticed, not changed
ef.query=where-value-compare×shape.wrapped∈ {string, Uri, enum, flags-enum, bool}. The probe substituteswhere-equalswhere the wrapped type has no>=, so no row can credit them: an exclusion candidate.shape.site=nested-two-levels×DateTimeOffset, covered only by declared rows.rows --claimprints agroup-byrow that would cover it.🤖 Generated with Claude Code