Merge 69bd45ff made GameCult.Caching.MessagePack reference CultMath
(PackageId GameCult.Math), so its nuspec depends on GameCult.Math 0.2.4.
The packer's hand-written project list never packed it, and GameCult.Math
is not on nuget.org, so every clean consumer of the local feed failed
restore with NU1101. That is the Eve surface consumer smoke in the
"one-command multiplayer onboarding" jobs, red on both OSes since then.
The packer now walks ProjectReference from the public roots (GameCult.Mesh,
GameCult.Networking.WebSockets) and packs the whole closure. The expected
package names come from MSBuild's PackageId and Version for each project,
since GameCult.Math carries its own identity.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
F1: acknowledged sequences above a gap still count until the lowest
advances, in Rust, TS, Python and C#. Rust direct send purges expired
packets before the window check. Soul passes: F1 held; batch 2 held with
13 own mutants killed and interop 27/27 (ack1d-interop:2). Only docs
differ from the verified tree. Follow-up: cultmesh-rs Cargo.lock stale.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cultnet.error.v0 contract is not decodable across runtimes, and the
interop CI lane has been red for 40 main runs. Cut 0 unblocks the lane;
Q1, Q2, Q3 and Q8 must be ruled before Cut 1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Admission in Rust, C#, TypeScript and Python goes through one predicate,
window_admits: the 32-packet slot, a sequence at most 1,023 above the lowest
unacked one, and at most 4 MiB of payload above it. With nothing pending any
packet is admissible. Admission is FIFO: nothing overtakes a queued packet.
The single-packet send refuses on the same predicate instead of queueing a
packet and then reporting that it produced none. The receive window is stated
in docs/cultnet-transport-parity.md. Kotlin trails (Cut K3).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Maps the four 2026-09-30 rulings. Cut 2 merges only with Cut F (Soul:
expiring reliable sets pin the bound). Adds Cut D (a failed send to one
peer no longer aborts a document server poll) and C# Cut 2c. Opens
Q-A7, Q-A8, Q-A9; Q-A7 and Q-A9 block Cut F.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Applies the Q-A1/Q-A2 rulings (one public meaning: Acknowledged means
delivered). Adds Cut 1b (every session ending drops what it owed; flush is
bound to its session) and Cut 1c (how a new generation is recognised,
blocked on new Q-A6). Probes at 3bf1c0c reproduce G1, G1b, G2 and G3 in
all four runtimes. Kotlin trails as Cut K pending Q-A5.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the pass 4 probes, the journal-floor rule, and the re-taken Cuts 4-6, salvage and ledger.
Records Q-P5 A: a primary that cannot log a committed change throws CultNetShardLogException.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Imagination pass 1. Probes found acknowledged ordered frames lost in live
sessions in every runtime; the map derives Delivered at the sender from a
correct receiver watermark. Operator questions Q-A1..Q-A5 open.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Imagination rebuilt the writer-thread scheduler Soul pass 3 proposed: it
deadlocks exactly as bcae483 did (deleted in 4562340). The map keeps per-writer
delivery, validates getters before minting, isolates observers, and moves the
shard log onto a gate-held journal. Q-P1..Q-P4 open.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Re-anchored to current main and Aetheria fire-control-12. Grouping gets its own
[CultInspectorGroupBy] attribute; CultIndex stays unique. Sequenced with variants
C2a/C2b/C3 into one joint release (cultlib 1.0.61, Studio 1.5.0); Aetheria
annotations fold into variants C4. Q6 and Q7 open.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The map carried only on codex/studio-grouping moves to main. The operator
ruled Q2 A, Q3 A, Q4 A on 2026-09-30. Q5 is overtaken: one Studio release
with variants C3. A refresh pass is due before Hands.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A variant record (v2 store, slot 4 [baseKey, overrides], empty payload)
holds top-level Set overrides and is resolved in the admitting hold.
Readers see complete documents. A base edit re-resolves dependents in the
same commit. Rulings honoured: Q1 a plain Upsert at a variant key is
refused; Q4 an override follows the plain-record outcome (a dropped slot
soft-drifts and is shed, an undecodable value refuses); Q5 the v2 header
only with variants; Q6 the directory store and CultNet refuse variants
(after selection, typed, subscriptions withdrawn). Self's defaults:
invalid overrides are refused at write; R6 is extended to indexes (no
variant shares an indexed value with another record). The held index is
truthful (value to holders, smallest key wins among plain duplicates).
A conditional merge onto disk is judged on the merged set.
Soul made five passes. The held index keeping one key per value caused
three rounds of store-bricking findings until the owner was fixed.
Caching 249, Networking 293, Mesh 262, cross-runtime interop 36/36.
Follow-ups: TS/Python plain-duplicate parity, a subscription id on
per-change refusals, a removal-order test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
C#, TypeScript, Python, Rust and CultMesh refuse an unknown
cultcache.store.* header and a fifth record slot, naming the version or the
key and schemaId. The silent slot-skipping and C#'s ignored header are
deleted, and CultMesh's second record decoder is gone. Shared vectors are in
tests/vectors/document-variants-c0/. v1 stores stay byte-identical. At base,
the single-file commit's read-modify-write rewrote a v2 store as v1, which
lost data; it now refuses.
Soul passed it. Cross-runtime interop was run and passes. Three C#
Caching tests fail on Linux at both base and tip: they are Windows
share-mode tests (a FileShare.Read handle blocking delete/replace), which
cannot pass on Linux.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A variant record stores [baseKey, overrides[]] in record slot 4 and an empty
payload; the cache resolves it against its base inside the hold that admits it or
any record on its base chain, and re-resolves dependents in the same Apply, so a
base change reaches its variants with contiguous sequences and no stamp. Plain
Upsert at a variant key is refused (Flatten is the explicit way); cycle, missing
base, different concrete type, evicted base with survivors and a name that
shadows the base are refused naming the keys. Overrides of a dropped slot or an
undecodable value are ignored with a warning and reported as compatible drift.
The store writes cultcache.store.v2 only when it holds a variant and reads v1 and
v2. The codec pair CultInspectorModel took becomes CultCodec, shared with the
cache, which needs it to clone documents and overlay override values. The
directory store, CultMesh single-file reads and CultNet row building refuse a
variant by name until their own cuts.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The Rust runtime gains the reference's content chunk messages on the raw
path, CultMeshCdnArtifactManifest with wire-ordered metadata,
normalize_hash, pack_content, validate_manifest,
answer_content_chunk_request (every bad request is answered, byte
identical to the reference server) and fetch_content (one owner of
receiving-side verification; refuses zero-size floods and unnormalised
hashes before any request). Vectors run both ways between C# and Rust.
The operator ruled Q-BP1 A: chunks travel on the session already held.
This is the explicit Rust content path until an authenticated connector
exists.
Soul passed it after two fix batches. cultnet-rs: content 24, cultnet 53,
rudp 7, lib 110. cargo-mutants on content.rs misses 0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>