CultLib/scripts
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Meta Vens 00f4c02dd7 CultNet selection cut1, commit 4: the parity vectors, and the ruling this branch landed under
Two things landed on this branch while commit 3 was in flight, both addressed
here rather than left for the vectors to paper over:

**Self's ruling, 2026-09-22 (commit 2 fix batch, 568e8e3/021e3f1): empty
lists, blank entries, and v0's own cleaning.** Rust already refused an empty
schemas/keys list (inherited from before the ruling); it now also matches
the reference's three further decisions exactly, not just in spirit:

- The door's refusal field is the plain list name ("schemas"/"keys"), not an
  indexed "schemas[i]" - selection::validate's SelectionInvalid.field now
  matches CultNetSelectionInvalidException("schemas", schema, ...) literally,
  because the parity vectors compare this string across runtimes.
- snapshot_query.rs's lower_v0_list now deduplicates a mixed list the same
  way CultNetV0SelectionLowering.Lower does (Distinct(StringComparer.Ordinal)
  - order-preserving, first occurrence wins), not just blank-filters it.
  A new test (serve_read_only_raw_snapshot_lowers_an_empty_or_blank_v0_schema_list_to_no_filter,
  extended) pins the dedup case directly.
- Two mutation entries (RS-EmptySchemas-Revert, RS-EmptyKeys-Revert) added
  for the door's original empty-list refusal, which had tests but no
  mutation coverage before this commit.

**S12: the two-way parity vectors**, contracts/cultnet/interop/selection-vectors.{cs,rs}-written.json,
eight vectors each: the six evaluated selections from commit 3 (any_of+ge
conjunction, descending+limit, gt boundary, cited exists true/false, three
rows sharing one index value) plus two door-refusal vectors added for this
ruling - `refuses_empty_schemas_list` (schemas: []) and `refuses_blank_key_entry`
(keys: ["a-eq", "   "]) - which decode their selection bytes and assert
`validate`/`Validate` refuses at exactly the named field, never evaluating.
The blank-key vector could not be generated before this commit: the door
rule it exercises did not exist in the reference until 568e8e3 landed.
`cites`-based hop vectors are deliberately absent (documented in both test
files): MatchesCitation compares Citation.Target.SchemaId against the
reference's real SHA-256 schema id exactly, with no SchemaName fallback,
and this fixture pair has no way to agree on that hash across runtimes;
`cited` (role/existence, matched by record key alone) is the hop direction
both sides can cross-check, so incoming_exists_true/incoming_negation carry
that coverage instead. Both reader tests pass:
SelectionVectorsWrittenByRustDecodeAndEvaluateIdenticallyInTheReference (C#)
and selection_vectors_written_by_the_reference_decode_and_evaluate_identically_in_rust
(Rust), each judging the other runtime's file.

**The remaining mutation matrix.** Of the coordinator's named set (S1, S2,
S6, S9-S15, S17, S20, S23): S1 was already covered (RS-EmptySchemas/Keys,
RS-BlankSchema/Key); S2 (any_of matches membership, RS-S2-Revert) and S6
(cites.role filters the hop, RS-S6-Revert) are newly covered - S6 needed a
new fixture (cites_role_excludes_a_second_reference_at_the_same_target)
because base_rows()'s citer-1 only ever carries one reference, so a mutant
dropping the role filter had nothing else to wrongly match and survived
against the original hops_one_edge_by_declared_role test; that finding is
recorded in-line as a comment, not silently swapped for an easier mutant.
S9-S15 (subscription reconcile, v0-lowering-of-subscribe) do not apply:
D7 - no Rust caller subscribes in this cut, so there is no subscription
client to mutate. S17 (inherited alias reaches every leaf) does not apply
either: Rust's toy Row/RowSet has no inheritance to begin with - both
leaves in the fixture declare "mass" independently, which is the Rust
spelling of the same guarantee, already exercised throughout the suite
without a dedicated mutant (there is no shared base-type discovery path to
revert). S20 (edges only for a hopping selection) was investigated and
found structurally vacuous in Rust as built: `edges` is only ever populated
inside the cites/cited branches, so a mutant on the has_hop() gate cannot
produce a different observable result for a non-hopping selection - no
entry added; a real gap would need the evaluator's structure to change
first. S23 (matches every row sharing an index value, never a cache's
unique-index winner) has no revertable bug surface: Rust's Row/RowSet
never had a unique-index map to begin with (D7), so this is pinned by
construction, not by a mutation-testable rule; matches_every_row_sharing_an_index_value
still exists as a positive test naming it.

**A pre-existing, unrelated flaky test, found and worked around, not
fixed.** tests/cultnet.rs's reactive_document_coalesces_direct_same_schema_alias_member_writes
fails consistently when the mutation harness runs the full tests/cultnet.rs
binary (both default-parallel and RUST_TEST_THREADS=1), but passes 5/5 in
isolation and passes in a plain `cargo test -p cultnet-rs` run - state
pollution from another test in that binary under the harness's specific
invocation path, not a race this campaign's code participates in (nothing
here touches reactive_document machinery). RS-V0Lowering-Revert's Command
is narrowed to `cargo test --test cultnet serve_read_only_raw_snapshot`
(filtering both M0 and the entry's own run to this campaign's test) so the
suite does not depend on that unrelated test's health; the flake itself is
reported here as a finding, not patched.

Tests: cultnet-rs 174 passed, 0 failed (default parallel run).
GameCult.Networking.Tests 196 passed, 1 skipped (WriteSelectionVectors,
env-gated), 0 failed.

Mutation harness: 24 entries (was 22 in commit 3; +RS-S2-Revert, +RS-S6-Revert;
RS-BlankSchema/BlankKey and RS-V0Lowering-Revert's anchors and field-name
assertions updated to match the landed fix batch's exact spelling), all
KILLED, M0 green.

Negative grep: `rg -n "untagged" packages/cultnet-rs/src packages/cultcache-rs/src` empty.

Structural delta, this commit only: 6 files changed, +108/-23 (selection.rs
+15/-9 field-name fix; snapshot_query.rs +25/-14 dedup; tests/cultnet.rs +21
dedup test; tests/selection.rs +35/-2 S6 fixture and field-name fixes;
scripts/mutate-cultnet-selection-rust.entries.ps1 +33/-4 two new entries
plus three corrected anchors/commands; SelectionParityVectorTests.cs +2/-1
field name), plus the two committed vector JSON files (~90 lines each, new).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-22 06:55:52 +02:00
..
build-quic-native.ps1 Correct stale Schannel/40,448-byte claims, ship OpenSSL's license notice 2026-09-17 19:49:14 +02:00
build-quic-native.sh Give the bridge a Linux build the deploy host's own distribution can produce 2026-09-16 21:04:14 +02:00
build-unity-package.ps1 Write and enforce the semver policy, per operator ruling on 1.0.60 2026-09-17 22:03:22 +02:00
check-changelog-semver.mjs Write and enforce the semver policy, per operator ruling on 1.0.60 2026-09-17 22:03:22 +02:00
check-changelog-semver.test.mjs Write and enforce the semver policy, per operator ruling on 1.0.60 2026-09-17 22:03:22 +02:00
measure-reactive-document-performance.mjs Measure reactive performance across runtimes 2026-08-18 03:08:01 +02:00
measure-reactive-document-performance.ps1 Split the Python runtime into cultcache-py, cultnet-py, cultmesh-py 2026-09-10 13:10:47 +02:00
mutate-cultmesh.mjs Say what the restore digest is, since it is not an identity 2026-09-17 03:11:05 +02:00
mutate-cultnet-selection-caching.entries.ps1 CultNet selection cut1, commit 2f: the Q-J fix (canonical decimal numbers) 2026-09-22 04:18:22 +02:00
mutate-cultnet-selection-fixbatch2.entries.ps1 CultNet selection cut1, commit 2 fix batch: door, shard-via-evaluator, Mesh v0 refusal, dead Reconcile code, mutation harness crash handling 2026-09-22 06:13:15 +02:00
mutate-cultnet-selection-mesh.entries.ps1 CultNet selection cut1, commit 2 fix batch: door, shard-via-evaluator, Mesh v0 refusal, dead Reconcile code, mutation harness crash handling 2026-09-22 06:13:15 +02:00
mutate-cultnet-selection-networking.entries.ps1 CultNet selection cut1, commit 2 fix batch: door, shard-via-evaluator, Mesh v0 refusal, dead Reconcile code, mutation harness crash handling 2026-09-22 06:13:15 +02:00
mutate-cultnet-selection-rust.entries.ps1 CultNet selection cut1, commit 4: the parity vectors, and the ruling this branch landed under 2026-09-22 06:55:52 +02:00
mutate-dotnet.ps1 CultNet selection cut1, commit 2 fix batch: door, shard-via-evaluator, Mesh v0 refusal, dead Reconcile code, mutation harness crash handling 2026-09-22 06:13:15 +02:00
pack-nuget.ps1 Delete the CultCache MessagePack source generator 2026-09-13 23:38:08 +02:00
quic-native-linux-dev.Dockerfile Offer the container line to both shells, and name the short-path requirement 2026-09-17 02:44:47 +02:00
run-typescript-workspaces.mjs Run the TypeScript workspaces by the name cultcache-ts actually has 2026-09-16 20:19:49 +02:00
sign-cultmesh-authority-vectors.mjs Pin the TypeScript-signed direction of the authority parity check 2026-09-16 16:27:06 +02:00
test-typescript-package-closure.mjs Let the verse catalog schema say what the reference emits 2026-09-10 13:55:46 +02:00
verify-caching-unity-release.ps1 Write and enforce the semver policy, per operator ruling on 1.0.60 2026-09-17 22:03:22 +02:00
verify-eve-browser-network.mjs Let the browser sample read the provider's advertisement 2026-09-10 13:55:46 +02:00
verify-eve-getting-started.ps1 Ship authenticated remote transports in Unity package 2026-08-18 20:23:27 +02:00
verify-eve-two-runtime-sample.ps1 Retain native clients across provider routes 2026-08-18 03:34:59 +02:00
verify-reactive-document-scaling.ps1 Split the Python runtime into cultcache-py, cultnet-py, cultmesh-py 2026-09-10 13:10:47 +02:00
write-cultmesh-realtime-frame-vectors.mjs Encode a CultMesh realtime frame in TypeScript 2026-09-16 19:20:41 +02:00