CultLib/scripts
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Meta Vens 9a4c9396b4 Stop the realtime decoder handing back a view of its own frame
Two mutants the cut-2 pass recorded as equivalent were not. Both notes were
reasoning, and both were wrong in the same way: they argued from the shape of
the code instead of trying the input that breaks it.

The decoder's length refusal reads `payloadLength < 0 || expected !== length`.
The note said the first clause could never fire on its own, because a negative
payload length makes the sum smaller than the frame. It does not: the sum also
carries the three identity lengths, and a negative payload cancels against
them. A 37-byte frame declaring `channelLength=65535, payloadLength=-65535`
sums to exactly 37, matches its own byte length, and without the clause decodes
to three blank identities and an empty payload where `CultMeshRealtimeWireProtocol`
refuses it. Two smaller spellings do the same, `ch=1, pl=-1` over 37 bytes and
`ch=2, pl=-1` over 38. No test covered that shape; one does now, and the
mutation is listed and killed rather than excused.

The payload copy was worse, because the fix and the bug looked identical. The
decoder used `bytes.slice(...)`, which copies a `Uint8Array` — and the existing
test passes one, so it was green — but Node's `Buffer` overrides `slice` with
an alias of `subarray`. A `Buffer` is what a socket read hands a Node caller,
which is exactly how the QUIC plane in cut 4 will reach this function, so every
decoded payload would have been a live view of a frame buffer the transport is
free to reuse.

`Uint8Array.prototype.slice.call(bytes, ...)` was the obvious repair and does
copy, but `%TypedArray%.prototype.slice` takes its result constructor from
`@@species`, and `Buffer`'s is `FastBuffer`: the payload then comes back a
`Buffer` from a `Buffer` frame and a `Uint8Array` from a `Uint8Array` one, so
the same frame compares equal or unequal under `deepStrictEqual` depending on
how it arrived. `new Uint8Array(bytes.subarray(...))` copies and is one type on
both. Three mutations now guard the line — return a view, return a `Buffer`
view, return a species-typed copy — and the first two die only on their own
input type.

Mutation runner: 75 mutations, 75 killed, 0 survivors, three green controls.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 20:20:16 +02:00
..
build-quic-native.ps1 Recover authority-bound CultMesh and atomic generations 2026-08-26 19:01:24 +02:00
build-unity-package.ps1 Release CultLib Unity 1.0.57 with deterministic plugin assemblies 2026-09-14 15:18:42 +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 Stop the realtime decoder handing back a view of its own frame 2026-09-16 20:20:16 +02:00
pack-nuget.ps1 Delete the CultCache MessagePack source generator 2026-09-13 23:38:08 +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-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