Commit graph CultLib/packages/cultcache-rs
Author SHA1 Message Date
Meta Vens
a056918be6 CHANGELOGs list the measured public surface against 2.0.1 (apicompat strict): members on their owning types, Id members in Mesh, Networking and Geometry, Rust SchemaConflictError, cultnet-rs register
The Unity list no longer calls MarkFlushSucceeded removed and places HeaderFor and the CacheBackingStore members where apicompat finds them. cultnet-rs gains a CHANGELOG. The store-composition contract moves DecodeDocument to the codec and states that a call's registry serves that call only. Docs only.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-23 01:44:57 +02:00
Meta Vens
f54472e5fe Merge origin/main (cultcache-rs 0.3.1, the whole-store writer fix) into the C2a landing branch
The stamp functions (Rust refuse_unread_format, TS refuseUnreadFormat) are the single owner of the stamp rule, accept v1 and v3, and are called only from the one reader every whole-store write runs under the lock. The fix's header peek (TS refuseUnreadStoreBytes, peekHeader) is deleted. Its tests that v3 is refused and that a stampless file is healed are dropped; the reversal is a Breaking line in the Rust and TS CHANGELOGs. The 0xff-after-stamp test now runs over v1 and v3.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-23 00:44:59 +02:00
Meta Vens
388e2eaa25 CHANGELOGs: every public break since cultlib-unity-v2.0.0, the unity package releases as 3.0.0
Owns finding c2a-public-breaks-not-in-changelog. Leaf changelogs gain v3 read and write and element ids carried; cultcache-rs gets its first changelog (the whole-store writer fix is not on main, so no 0.3.1 section).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 23:57:37 +02:00
Meta Vens
6c9e4aa509 cultcache-rs: one grown decoder setup for every decode of stored bytes
store_header and decode_grown both run through grown(); the copied maybe_grow and red-zone setup is deleted. Owns finding store-header-second-grown-decoder.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 23:53:11 +02:00
Meta Vens
6809e74137 cultcache-rs 0.3.1: push_all reads the store stamp under the lock and refuses a format it does not read
One owner of the stamp rule, refuse_unread_format, serves read_all_unlocked and push_all. A file push_all cannot read is written as before. Builds.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 22:26:00 +02:00
Meta Vens
4adcc21674 cultcache-rs, cultcache-ts tests: a whole-store write refuses a format it does not read (red)
Both new tests fail at this commit; it builds. Vector copied byte-identical from C2a (blob 9fc9b64f).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 22:22:05 +02:00
Meta Vens
c14b2c65d1 Land fixes: stamp judged before the body, deep stores on the grown stack, ported tests refuse by their typed errors
Stamp rule runs on slot 0 before the body is scanned (JudgeStamp). DescribeHeader names a v<N> header that carries a suffix. Rust store_header walks on the grown stack. Drift tests declare Wide's id compatible (ownership by declaration). Mesh write-guard tests expect the typed refusals.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 20:49:43 +02:00
Meta Vens
f2b3569822 Merge main at cultlib-unity-v2.0.0 (42dce361) into C2a: one owner per collision
Identity: C2a's StoredSchemaId/StoredVersion owns; main's PersistedSchemaId, PersistedIdentity and both MarkWritten are deleted. Stamp rule: ReadStore judges the stamp before the body. Flush over damage refuses (merge-r1-precedence). Mesh single-file writes route through SingleFileMessagePackBackingStore. TS: store-file.ts commits, C2a's header handling kept. Rust: C2a's readable_store_format in front of the grown decoder. Build not yet verified at this commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 20:35:33 +02:00
Meta Vens
3cd9880c04 interop peers: hold-lock mode in the C# peer and the Rust example
Each holds <file>.lock by its own runtime's protocol (share-none open; fs2 exclusive),
prints {"held":true}, sleeps --ms, releases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 14:50:19 +02:00
Meta Vens
7ab3092550 cultcache-rs tests: a field name is kept only when it looks like one
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:31:34 +02:00
Meta Vens
c0a2b890f6 cultcache-rs: the decode door names a missing or duplicated field and never quotes a value
describe_decode_error keeps serde's own value-free texts for missing and
duplicate fields (static names from the type), maps unknown-variant and
invalid-type to kind descriptions, and leaves everything else opaque.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:22:22 +02:00
Meta Vens
9d2b64bd88 cultcache-rs docs: Windows line names the revision of the run it describes
The decode_stack Windows run is at 10a39dac (tests unchanged since 4b55c7d3);
the head after this commit awaits a Soul rerun.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 21:19:19 +02:00
Meta Vens
10a39dac98 cultcache-rs docs: debug floor stated for a plain caller; first-frame sentences removed; Windows line names its run
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 21:19:13 +02:00
Meta Vens
4b55c7d30b decode_stack tests: store reads and the outer check pinned at release-reachable sizes
Legacy and v1 reads on 64 KiB, redb pull_all and compare-and-swap on 104 KiB,
and one Largest level on 88 KiB, the sizes where a plain from_slice or a missing
outer maybe_grow dies in release as well as debug.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 20:57:59 +02:00
Meta Vens
dbafbf52bc cultcache-rs docs: state the decoder's fixed stack floor, record the Windows run
The README and decode_payload claimed the calling thread needs only its own
frames. Measured, the door has a payload-independent floor (release 56 KiB vs
16 for a same-signature non-decoding function; debug 104 vs 88). Say so, and
replace "Windows not yet verified" with the one by-hand Starfire run of
decode_stack on x86_64-pc-windows-msvc.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 20:57:58 +02:00
Meta Vens
6afa8ed9c4 cultcache-py, -rs and -ts: unit-arm tests assert against the bytes the C# reference wrote
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 20:33:24 +02:00
Meta Vens
74ecbb2e0c decode_stack tests: the at-bound union fixture is allowed its large variant
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 20:22:34 +02:00
Meta Vens
b43c4dfc98 decode_stack tests: v1 snapshot and redb reads through the grown decoder
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 20:08:16 +02:00
Meta Vens
57243090ec MAX_RECORD_INLINE_BYTES doctests: serde-able fixtures, positive twins of each refusal
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 20:02:52 +02:00
Meta Vens
f7c0902d8d decode_stack tests: box the decoded result on the small thread, measured thread sizes; doctest fixture serde-able
Measured on Yggdrasil: the decode needs 56 KiB (Wide32) and 80 KiB (Largest) in
debug on a thread that returns a bool; returning the record through
std::thread's own frames adds several copies of it, so the tests box it and
size threads at 96 KiB and from 160 KiB.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 19:56:57 +02:00
Meta Vens
95b98e588b cultcache-rs README: security model without the wasm claim, the record bound, build dependencies
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 19:48:58 +02:00
Meta Vens
40a089ff9a decode_stack tests: shallow depths, 64 KiB door, largest record on every thread size, legacy envelope
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 19:48:58 +02:00
Meta Vens
fc630d3b85 cultcache-rs 0.3.0: one grown decoder for stored bytes, derives refuse records over 16 KiB
decode_grown checks the stack before any frame that holds T, then serde_stacker
at every container; decode_payload walks the nesting bound and calls it; the
legacy envelope array, redb reads and v1 snapshots decode through it too.
Red zone 512 KiB against MAX_RECORD_INLINE_BYTES = 16 KiB, which the
DatabaseEntry, CultSlots and CultUnion derives assert at compile time.
cultcache-rs-derive 0.2.0.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 19:48:57 +02:00
Meta Vens
bd27f7a34b Union parity: the unknown-arm-list case carries its Pending id; rust and ts keep unit-arm codec tests on a separate union
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 19:46:22 +02:00
Meta Vens
e0747912c6 cultcache-rs and cultcache-py union parity tests: golden models carry element ids
Wrap and the Outcome arms gain id slots (unit arms become one-slot id records);
the Python unit-arm codec behaviour is kept on a separate unit union.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 19:43:28 +02:00
Meta Vens
3b83cb6c08 Merge origin/main into hands/variants-c2a-main (main-into-c2a)
Sixteen conflicted files resolved by the spec's rule: main owns payload
ownership, bounds and the Clock seam; C2a owns persistence semantics and exact
binding. MintStoredAt is internal static (previous, now); the cache and the
store pass their cache's Clock. Package versions are main's. The cultmesh-ts
payload-parse acceptance and its test are deleted under retire-schema-alias;
peer snapshot reads take the schema's own id, else an id the definition lists
as compatible. The held firstRecordAtKey fallback is removed: main's handles
take definitions only, so nothing could reach it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 04:06:41 +02:00
Meta Vens
2505c0c45f decode_stack test: repeat_n for the clippy lint
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 02:55:21 +02:00
Meta Vens
d3f8dea75a cultcache-rs: decode_payload grows its stack through serde_stacker
A payload inside the 256 nesting bound no longer depends on the caller's
thread stack: the rmp-serde deserializer runs under serde_stacker with a
256 KiB red zone and 2 MiB segments. Adds tests/decode_stack.rs (child
process per test, sized decode thread) and renames the 2 MiB union_parity
stack test to a 1 MiB pin.

Not yet built or run at this commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 02:38:23 +02:00
Meta Vens
66eeb22052 cultcache-rs tests: drop the leftover mixed case so union_parity compiles
The previous commit's union_parity.rs did not compile (mixed_past was removed from its definition but
not from the case list). a5c0f876 does not build its tests; this commit does.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-11 17:55:19 +02:00
Meta Vens
a5c0f876de cultcache-rs: the payload nesting bound at put_raw_envelope and put_prepared_batch
Both raw write doors run the one check_payload_depth that decode_payload runs first, before any
store is touched; decode_payload is public so envelope readers elsewhere decode through the same
helper. Tests: union arms, maps and arrays at 256 and 257 through both doors, a batch that stages a
valid entry beside a deep one persists neither, the read vectors enter by a store file written
behind the cache.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-11 17:52:24 +02:00
Meta Vens
89e1755281 cultcache-rs tests: ext arm keys class as non-integer, and nil slots on a unit arm and an arm with slots
Pins ext-key-class-arity (fixext 1, timestamp, ext 8) and the nil-slot refusal at the
derive's own seam. Builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:38:20 +02:00
Meta Vens
f06cd84596 cultcache-rs: element_header owns truncation; the walk tests fill skipped bytes with array markers
Mutation survivors of the first run: the unwrap_or(usize::MAX - k) fallbacks were equivalent
mutants, so a truncated header now returns None through the one helper. Child counts and long
lengths (map16/32, array16/32, str/bin/ext 16 and 32 bit) are tested with skipped bytes that
read as containers when a skip stops short. Builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:30:10 +02:00
Meta Vens
94f61a14f6 cultcache-rs tests: a depth refusal through the cache names the entry type, not the C# type name
Builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:15:16 +02:00
Meta Vens
4482e297cf cultcache-rs tests: through_cache unwraps the stored envelope (fixes the previous commit's type error)
The previous commit does not build its union_parity test target; this one does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:14:38 +02:00
Meta Vens
066ee4e177 cultcache-rs tests: the C# bounds vectors, the write refusal, the 2 MiB stack budget and the walk
Wrap, Floor and Ceiling fixture arms; bounds-outcomes.msgpack looped through the raw decoder
for arm-key and nil-slot classes and through the cache for depth; put of the 257 chain refused
with the cache and store unchanged; 2 MiB debug thread decode/encode at 256 and refusal at 257
and 100000; iterative walk on 256 KiB; header-width and scalar-width seams; derive names D, S,
A, E, ArmKey compile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:13:50 +02:00
Meta Vens
ca6671aefb cultcache-rs: payload nesting bound through one decode, and the derive findings deferred to this cut
check_payload_depth walks MessagePack headers iteratively and refuses the first container past
MAX_PAYLOAD_DEPTH (256); decode_payload is the only payload decode (get, get_all,
get_all_with_keys, finish_prepared_entry, envelope validation), so write is refused through
finish_prepared_entry. Derive: nil arm slots refused naming union and key, ext arm keys classed
non-integer, generated generics and local items prefixed (types named D, S, A, E, ArmKey now
derive), slot keys capped at 65535 at definition, SlotRecord requires a hidden method only the
derives emit, DatabaseEntry/CultSlots expansions are functions the type/schema/generics refusals
are unit-tested through. Tests follow in the next commit; this commit builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:13:50 +02:00
Meta Vens
fb51df9d75 Union tests: the undeclared negative key assertion matches the message wording
Builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 04:39:34 +02:00
Meta Vens
c586640e81 cultcache-rs-derive: arm keys are Int32 and given once, an arm is a slots record, refusals classified like the reference
Key attributes (variant, field, entry type/schema) are refused when repeated. A CultUnion key
parses as the reference's Int32, negatives included; a key outside it is a compile error. Decode
classifies the key as the reference does: non-integer, outside Int32, undeclared (named), and a
pair of the wrong length is refused before its key is read; no value is echoed beyond the
undeclared key the reference names. The SlotRecord trait, implemented by the shared slot
generator, bounds an arm payload, so a String or Option arm is a compile error. compile_fail
fixtures use keys other than 0; the derive crate's unit tests assert each refusal's message.

Unverified: committed before the first build; the verification job runs next.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 04:37:47 +02:00
Meta Vens
e72f17421e CultSlots compile-fail docs: a field without a key, a generic struct
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 04:05:22 +02:00
Meta Vens
d73249365a Union tests: valid arm shapes in the malformed-pair fixtures, the store test pulls its backing store
Not yet run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 03:54:09 +02:00
Meta Vens
2e5fc0f7f8 Union tests: the composition body is a boxed Node, the recursive type has finite size
Not yet run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 03:52:39 +02:00
Meta Vens
2d840d5ffb cultcache-rs: CultSlots and CultUnion derives writing the reference [key, armSlots] shape
One slot generator now serves DatabaseEntry and CultSlots. CultUnion writes
[key, slots] with unit arms as [key, []] and refuses unknown keys naming the
enum and declared keys. Tests hold the runtime to tests/vectors/union-parity.

Not yet built or run: this commit may not build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 03:50:30 +02:00
Meta Vens
12805eb32f CultCache Rust: a soft push_all asks the one reader, as TypeScript's does
Absent writes, a store it reads is left byte for byte, and anything the reader refuses (an unreadable file, a dangling link) is refused. The readability manifest walk now runs a soft flush over every vector, so TypeScript and Rust are pinned by the same files.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-03 01:28:47 +02:00
Meta Vens
da2b9482e5 Rust: the rename fault fires inside replace_file_atomically, at the call a swallowed error would hide
The seam sat before the call, so a mutant that swallowed the real rename's result was invisible to it. It now makes the rename itself fail, on both platforms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:11:07 +02:00
Meta Vens
9a251fe60c Rust: one store-header reader; bin-encoded headers refused; rename fault seam and the tests the survivors asked for
store_header is the only reader of a store file's leading bytes. It returns the header slot (a MessagePack str only, never bin, as in C#, TS and Python) and separately the proof that the bytes are one whole array, so a newer store cut short after its header is still named unsupported. leading_header, read_array_header and read_string are deleted. decode_store_file takes the header the reader already found.

Vectors bin-header-v1/v3/v9 join the readability manifest as refuses x4. Tests: a rename fault step (WriteStep::Rename) shows a failed rename is NotReplaced, the store intact and no staging file left; every merging writer refuses through a dangling link; the unsupported-format refusal names v1 and v3 and echoes only ASCII-digit headers.

Not yet compiled or run at this commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:05:37 +02:00
Meta Vens
d350e150b0 Rust: bring back R1's leading-bytes readers for leading_header
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:49:01 +02:00
Meta Vens
f35867a232 Rust: a newer store cut short is still named unsupported; tests follow the single reader
R1's rule that the header alone decides an unreadable-format store (a newer store
cut short is not damaged) is kept as leading_header, asked before the whole-file
proof. A directory at the store path now stops a write at the read as an I/O
error, so the two tests that used it to reach a failed rename assert that instead,
and the two c2a header tests assert R1's UnsupportedFormat kind, not c2a's old text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:48:34 +02:00
Meta Vens
ff0251bbf8 Fix the R1 merge: close the Rust store_header visitor; a whole-store replace through a dangling link keeps replacing it
The merge left store_header's visitor unclosed (does not build). R3's pin that a
whole-store flush replaces a dangling link survives the single reader: the reader
still refuses the link as an I/O error, and the flush, which has no content to
carry from a link that holds none, writes v1 over it (Rust write_all_unlocked, TS
pushAll).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:46:39 +02:00
Meta Vens
bad511f5ac Merge CultCache R1 (f789c8d1) into C2a: one reader per runtime, R1's failure taxonomy
R1's rules win where both sides decided the same question: a zero-byte file is
not a store (refused as unreadable in every runtime), only nothing at the path is
empty, a dangling link is an I/O error, refusals never echo stored values and echo
a header only as cultcache.store.v<digits>, writes report Rejected, NotReplaced
and ReplacedNotDurable. C2a's rules win on what it added: the v3 element-id
header, variants, whole-file proof, typed unreadable errors in C#, TypeScript and
Python. Rust keeps R1's CultCacheStoreUnreadable{path, kind}; C2a's
StoreUnreadableError is deleted. The readability manifest's zero-byte row is
refuses x4.

Not yet built or tested: verification follows in the next commits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 19:41:35 +02:00
Meta Vens
a771e71bd6 Rust test: pin the cargo-mutants survivors in the catalog lay-back
- The fixture gains an older entry listing the id ahead of the one that
  owns it, and the whole-store write carries the record under the
  registered type a Rust cache's pull gives it, not the entry's name.
  Kills the own-id lookup flip and the ||-to-&& flip in the entry filter.
- A store path that cannot be read (a directory) is an error, not an empty
  store (the NotFound guard had no test).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 22:59:52 +02:00