mirror of
https://github.com/logos-co/logos-test-modules.git
synced 2026-08-31 12:11:12 +00:00
* test(conformance): the LIDL optional contract, as cases, before the implementation
`?T` is declared by every contract and read by no generator, in any language.
This writes down what it must mean, as 17 cells in the full_api_ext table plus
the contract delta on both ext providers, so the implementation has a target
instead of a behaviour to bless.
The contract these cells encode:
* `?T` is TWO-state — a value of T, or empty — never three-state. Forced by
"one LIDL type maps to one type per language": every target has exactly one
empty inhabitant (None / nullopt / invalid QVariant / undefined).
* Omitted and explicit-null are the SAME state on DECODE and DIFFERENT on
ENCODE. Empty is spelled by OMITTING the key in a NAMED slot (a record
field) and by null in a POSITIONAL one (arg, return) — a positional slot has
no key to omit and the arity must never change. The round trip is therefore
CANONICALISING, not identity, and several expectations here are deliberately
not the argument echoed back.
* A present-but-wrong-typed value in an optional slot is STILL AN ERROR.
Optional widens the domain by exactly one inhabitant; it does not disable
type checking. `hostile/Optional/scalar/wrong-type` is the cell that stops
`?T` = `any` from passing, which is what all three backends do today.
* The two spellings the spec binds to one meaning (`? name: T` and `name: ?T`)
must emit identical code. Both are in the contract on purpose: today they do
not even agree at runtime — the field flag is checked against the base type,
the type kind falls to `Ty::Any` and is not checked at all.
Both ext providers are authored AT THE TARGET, which means neither compiles
until the generator work lands, and the ext check is red at build time until
then. That is recorded in known-ext.json (OPT0) rather than hidden: a fixture
written against the current behaviour cannot be the thing the fix is measured
against. Every cell that cannot pass is registered (OPT1: optionality is
unimplemented; OPT2: an empty optional in a positional slot is unspeakable on a
wire where null already means METHOD_FAILED, and the py driver cannot send a
top-level null at all), so the suite is honestly red now and reports xpass —
which fails the run — the day the generators are right.
The registry entries record what was MEASURED about the generators by executing
them: --header-to-lidl silently derives `any` from std::optional, the cdylib
gate rejects `?T` outright, and the emitted record codec ignores the field flag
in both directions.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore: re-pin logos-module-builder for the optional SDK stack
Carries logos-lidl#7, logos-protocol#37, logos-rust-sdk#31, logos-cpp-sdk#125
and the two module-builder re-pins (#177, #178) that make them reachable.
Both ext providers now BUILD, which is what OPT0 recorded as impossible:
nix build .#test_fullapi_ext_cpp -> exit 0 (was: undefined template
Codec<std::optional<std::string>>)
nix build .#test_fullapi_ext_rust -> exit 0
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* conformance: OPT1/OPT2 must declare which consumers they were measured on
run_matrix.py refuses to start otherwise:
known.json xfail entry 'OPT1' has no `consumers`; an xfail must state which
surfaces it was measured on
The entries were written while the ext providers could not build (OPT0), so
the driver had never reached them to reject them. Both are measured on the py
consumer, which is the only driver the ext table has.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* conformance: OPT1 is closed — measured, not assumed
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>