Skip to content

ADR-0027: nullable scalar contracts and literal Guid construction

Status: accepted. Local 2026-10-11 verification passes 618 provider unit tests, 26 relevant provider query/integration cases and all 61 selected EF specification checks, including the original Guid literal case.

FS-07 asks for nullable comparisons, missing/null property behavior, time/Guid/enum conversions, parameter coercion and negation, verified with upstream tests and generated Cypher snapshots. Existing renderer compensation must be checked against actual database results, not merely snapshots of its own implementation.

The new live oracle checks all nullable integer value pairs and Boolean/string combinations, including each comparison and its negation. An independent graph-key observation establishes the absence/null storage boundary. A separate explicit-converter fixture tests temporal normalization, Guid and Int64 enum values against CLR equality. Default temporal mappings are not introduced: the converter is part of the model contract, and arbitrary converter range/order semantics remain rejected. See the scalar guide.

The first local run passed all three GraphBridge-specific facts (150 predicate comparisons plus graph property removal) and eight of nine selected original EF facts. GuidTranslationsTestBase.New_with_constant exposed a real translation gap: pinned EF 10.0.12 retains new Guid(string-literal) as NewExpression, while its captured-value counterpart is already funcletized into a Guid parameter. Do not replace the original assertion or broadly evaluate client expressions to make it pass.

AddParameter now recognizes only the exact Guid(string) constructor with a constant string argument. It validates that literal with Guid.TryParse and places the Guid in the existing model-converted parameter pipeline. No GUID is inlined into Cypher. Malformed literals throw a value-free translation diagnostic before transport. Other constructor shapes and arbitrary evaluation remain unsupported. A focused test verifies the exact Cypher and malformed-value privacy; the unchanged original upstream case supplies live acceptance.

All 618 provider unit tests pass after this change, with zero build warnings/errors. The final live run and exact owned-fixture teardown also pass. The ledger (maintainer-local record) records FS-07 acceptance, the initial failure and its narrow fix. No hosted run was needed for this batch.