cultmesh-portability.yml gains 'Verify the content vectors with the C# reference' (CultMeshContentVectorTests), the first
CI run of the C#/Rust content parity and of the TypeScript manifest vectors. The README describes what cultnet-ts/content
owns and how the ts-written file is regenerated.
Builds. Co-Authored-By below.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One browser-safe module owns the manifest and chunk-ref shapes, their MessagePack form (positional ten-array, metadata as
ordered entries, duplicate keys and unsafe integers refused, payload depth through cultcache-ts's own checkPayloadDepth),
normalizeHash/parseSha256Hex, both record-key grammars (StableToken per UTF-16 unit), WebCrypto sha256Hex and packContent.
cultcache-ts/document re-exports checkPayloadDepth. scripts/write-cultmesh-content-vectors.mjs writes the TypeScript
manifest vectors for the C# reference to judge.
Builds. Co-Authored-By below.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
contracts/cultmesh/cdn-record-key-vectors.json is written by the reference under CULTNET_WRITE_VECTORS=1 (19 artifact
keys, 7 chunk keys; ids as UTF-16 unit arrays so a lone surrogate survives). The judge compares text with line endings
normalised so a Windows checkout and a Linux one agree.
Builds. Co-Authored-By below.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
WriteContentVectors also writes contracts/cultmesh/cdn-record-key-vectors.json, every key derived by the public
CreateRecordKey of the reference. CommittedRecordKeyVectorsEqualAFreshDerivation and
TypeScriptManifestVectorsMatchTheReference judge the committed files; a missing file fails.
Builds. The two new tests are red until the vector files they read are committed (next commits).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Selection is by name, so a non-site 128 array is legitimate output. The shape check is a function and the array-128 variant passes it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SPIRV-Cross names the macro from the SpecId and offers no option to rename it, so the SpecId is CultMath's own
('CMS1'); partition.py reads it from spvedit.py.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
wrappers.py compiles the library with CULTMATH_MAX_SITES defined as a sentinel no shader file spells, so the three
site arrays get an array length id of their own and spvedit.py converts exactly that constant to the overridable
specialization constant (default from the HLSL guard). A library array of literal length 128 keeps its own id and
stays a plain constant. build-glsl.sh gains the pipeline function and scratch variants: a macro outside a declarator,
a folded expression reaching the capacity id, and a non-site float4 x[128] parameter that a consumer's override must
not resize. The [128] shape arm goes: a non-site 128 array is legitimate output.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Kills the surviving Stryker mutant in Fields.IndexOf's case-insensitive loop and covers its not-found return.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cultmath-unity [Unreleased] and cultlib [Unreleased] carry the Breaking entries; no version bump, no tag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fields takes an optional legacy name per field, matched on read only and mapped to the same index as the current name, so a legacy and a current name in one object are the same property and the duplicate rules decide (refused when AllowDuplicateProperties is false, last wins otherwise). Writing never emits a legacy name. MessagePack bytes are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Written by CULTMATH_WRITE_GLSL=1 on Yggdrasil (sdk:10.0) at d605c70b; sha256 21eef3c38cc609909444c906a1ef965f01b541f2301023a722e64ecc4c846387. glsl-parity.json and device-bounds-lavapipe.txt are untouched by the regeneration.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SPIRV-Cross renames members matching GLSL builtins, so the source names change. Resolver and JSON writer accessors follow the members; the wire (positional MessagePack, JSON keys) is untouched in this commit. The committed GLSL is stale until its regeneration commit, so CommittedGlslEqualsLowering fails here.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two encodings with keys cos/sin, produced by CultMathJson at base (Yggdrasil scratch run, sha256 2903179720e2a2c974a3c64efea4ee95dec823943dd67f50df01adf650823e1a).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CultMath shaders: cultmath_power_border, cultmath_lattice_cell_distance and
cultmath_weighted_lattice_cells over a fixed-capacity site array
(CULTMATH_MAX_SITES, overridable). Spec cultmath-tapes:cut_spec:cut-shader-lattice-loop.r1,
report h1, Soul s1 holds.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
CULTMATH_MAX_SITES defaults to 128 under #ifndef. The consumer-written ring-loop and border-loop comment recipes are deleted. The C# mirror takes the array as T[]; the span twins live in SiteArrays; the GLSL lowering keeps the capacity macro; gen.py learns the array leaf; the smooth-step family gains its cap-point draw; CULTMATH_WRITE_GLSL refuses non-Linux.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>