Adds citer-both-in-target to the shared fixture, the first row in file (and
row-order) to cite "dup-key" through Design - both leaf_a and leaf_b at that
key are in Design's declared target, unlike citer_narrow's narrow_ref above
it (only ever one in-target candidate). Adds the matching vector case to
both runtimes' case lists and regenerates both written vector files
(CULTNET_WRITE_VECTORS=1), so cross-runtime agreement on this shape is
pinned by the parity check, not just asserted per-runtime.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The fixture had zero duplicate record keys across its ten rows and no
ordinal tied across two different schemas - both shapes this fix batch's
rulings needed and neither runtime's parity vectors ever covered.
R-AF adds a "citer_narrow" schema (real SHA-256 id, computed the same way
CultDocumentRegistry does - a probe run against a type matching the
eventual C# type's exact namespace/nesting confirmed it) whose one
reference targets leaf_a only, plus rows for both shapes from Soul's
table: a lone out-of-target row at a key (refuses), and two rows sharing
a key where only one is in-target (accepts, resolving the in-target one
regardless of row order).
Also drops "targetSchema" from every reference entry: it was never
anything but documentation (SelectionParityVectorTests.BuildDocument and
cultnet-rs's build_row both already read only targetKey) and keeping a
field the wire does not actually have would contradict the rule R-AF just
established.
R-AJ adds a tied-ordinal pair across leaf_a and leaf_b, with keys chosen
opposite to the real schema ids (probed) on purpose, so a schemaId-first
order and a recordKey-first order are forced to disagree regardless of
which real id happens to sort first - see the row-tiebreak test this
enables.
selection-vectors.cs-written.json and selection-vectors.rs-written.json
are regenerated from the new fixture (CULTNET_WRITE_VECTORS=1 on both
sides) and cross-checked in both directions locally.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
share one alias rule
selection-vectors.fixture.json's "//aliases" comment still called the
two alias forms a cross-runtime defect ("no candidate string that
resolves through both"). That was true before the Rust alias port; it
is not true now. Both runtimes resolve a schema alias the same one way
(strip a trailing .vN, compare the remainder against the descriptor's
declared SchemaName): nameAlias resolves through both, and hashAlias -
kept in the fixture on purpose - is refused as unmatched by both, since
neither runtime's production call sites produce or accept it.
Prose-only change to this shared fixture file, as ruled: no vector
values, schema ids, or row data touched.
Also recorded for Self's map: cultnet-rs's alias port (R-E) does not
carry SchemaVersion or CompatibleSchemaIds - no Rust call site needs
either, so schema_alias::matches folds them away and agrees with the C#
rule only on the subset it actually uses (candidate/id/name comparison,
not version or compatibility-list matching).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reconciles the two Hands' independently-regenerated parity vectors
(Soul's whole-cut pass, F3): the C# fixture used schema *names*
("leaf_a") as literal ids, the Rust fixture used invented fake
sha256-shaped ids - every vector carrying an id failed when read by
the other runtime.
Adds contracts/cultnet/interop/selection-vectors.fixture.json: the one
row set both writers now build from, keyed by each schema's real
SHA-256 content-hash id exactly as CultDocumentRegistry computes it
(dumped via a temporary DumpFixtureSchemaIds run). Carries the rows
either runtime needs - astral/BMP-private-use keys, a float tie,
cites/cited, a cites target reached by alias - plus two DIFFERENT
alias forms, because the two runtimes' alias matchers key off
different descriptor attributes and no single candidate resolves
through both (see the fixture's "//aliases" note and the report).
Rewrites SelectionParityVectorTests.cs to load the fixture instead of
hand-building rows (BuildFixture/BuildExtendedFixture deleted), assert
the fixture's declared schema ids still match what the registry
computes (fails loudly on drift instead of silently comparing wrong
ids), and use the real schema id (not SchemaName) as a row's
cross-runtime identity. Also fixes a real bug this file carried since
before the shared fixture: both the writer and the reader compared
`evaluation.Rows.Count` (the page size) against "matched" instead of
`evaluation.TotalMatched` (the total, per R-G) - selections with a
Limit were writing/checking the wrong number. The reader now collects
every vector's mismatch instead of stopping at the first one, so a
real parity defect is reported in full.
Regenerates selection-vectors.cs-written.json from the shared fixture.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>