Commit graph

1,282 commits

Author SHA1 Message Date
Meta Vens
4f632fbf46 Drive the hop-subscription test through the database write path
Batch commits on the cache do not reach the database's change stream, so the subscriber's citers were written with database.PutAsync; the variant goes in through UpsertVariantAsync. On the previous source the second subscriber stops receiving after the variant exists (red); it now keeps receiving.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 08:42:32 +02:00
Meta Vens
b572823d0d Refuse variants after the selection is applied, and never tell a subscriber about the removal of one it was only refused
The selection paths (SelectPage, SelectAll) refused every stored variant before the selection ran, so once any variant existed a hop-bearing subscription threw out of its change handler and went silent. They now refuse only a variant the selection selects; the subscription server delivers that as a typed error and keeps its projection. The database server no longer sends removed for a key the subscriber only ever received as an error. A flatten racing the delivery check is recorded in a comment.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 08:28:24 +02:00
Meta Vens
354f9743e6 Refuse a plain write that shares a variant's indexed value; a flush sheds overrides the type lacks
The index rule is about the commit's result, so it now runs for every commit that changes an indexed value: a plain record landing on a value a variant of the post-commit set holds is refused naming both keys and the index (the held index is never trusted; a plain write had already overwritten it). Plain-vs-plain is untouched. A variant sheds overrides of slots its type lacks when it is flushed, as a plain record sheds the member, and the load's report names the slot when the schema itself never had it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 08:28:24 +02:00
Meta Vens
5d6847e220 Align the C1 tests with the unique-index rule and fix the live-subscription fixture
Hand-written and directory-store variants now override their indexed value or
name as the rules require; the subscription test writes its variant through a
committed batch so the file holds it, subscribes by key, and reports what it
saw when it times out.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 07:04:01 +02:00
Meta Vens
2845d3591b Regenerate the C1 variant vector: the variant overrides its indexed code
The unique-index rule refuses a variant that inherits its base's [CultIndex]
value, so the vector's laser-big now carries a code override. Written by the
code under test through the production path; the other runtimes still refuse
it by version and by the laser-big key.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 06:59:29 +02:00
Meta Vens
c66d79e248 Variant overrides follow the plain-record outcome; bad writes and shared indexes are refused
F3: an override drifts exactly as the same member would on a plain record. A
slot the type dropped is ignored and reported by the store's schema resolution
(LastSchemaMigrationReports), the one surface a plain record uses; a value that
no longer decodes refuses the load, naming the variant and member. The second
report surface (VariantMigrationReports, the per-variant report map, the
catalog slot-name plumbing) is deleted.

F4: an override for a slot the type does not have, or a value that does not
decode as the member, is refused at write. Drift is for type changes after the
fact, not for bad writes. F5: two overrides of one slot are refused.

F2: a variant that shares an indexed value with another record is refused,
naming both keys and the index (the R6 rule extended to [CultIndex]); plain
record duplicate handling is unchanged.

F7: a flatten now resolves against the same batch, so a base edited in that
batch is in the flattened record; and the directory store refuses to load a
variant page as it refuses to write one.

The C1 vector's big variant now overrides its indexed code, as the unique-index
rule requires.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 06:58:51 +02:00
Meta Vens
cdb8ee5dcc CultNet refuses a variant on both live-change paths, loudly, by key
A load or write that landed a variant reached CultNet subscribers as a plain
"added" record carrying the full resolved payload; a later base edit published
only the base, so the subscriber's copy of the variant went stale. Under Q6
CultNet carries no variants until its own cut. Both live paths now refuse a
change whose key holds a variant, after selection and authorization match, and
send the matching subscriber a CultNetErrorMessage naming the variant and its
base. Refused loudly rather than omitted: an omission is a silent hole in the
subscriber's view, and the snapshot path already refuses by throwing.

Tests: a real load through a real RUDP subscription never delivers the variant
as a record and delivers the typed error; the database server's change builder
refuses the same change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 06:58:51 +02:00
Meta Vens
de65c82768 Merge remote-tracking branch 'origin/main' into hands/variants-c1 2026-09-29 06:48:32 +02:00
Meta Vens
5e521c832d Merge small follow-ups: Windows-only share-mode tests, a fixture generator spec
The three Caching tests that hold a FileShare.Read handle and expect a
delete or replace to fail are marked [Platform("Win")]. They cannot pass
on Linux, where unlink and rename ignore open handles. The Idunn runtime
fixture generator takes its sets as flags or @file response files, so a
consumer such as StreamPixels no longer patches CultLib's example.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 05:12:15 +02:00
Meta Vens
c3add7dd1b Idunn runtime fixture generator takes its specification as input
The four hard-coded sets become flags, with @file response-file splicing.
A consumer keeps its own .args file instead of committing a patch against
the example. fixture.args carries CultLib own sets; the README documents
the flags. Committed fixture bytes are unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 04:30:40 +02:00
Meta Vens
136adce9ff Prove TypeScript, Python and Rust refuse the C#-written variant store by name
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 04:21:59 +02:00
Meta Vens
b93934f6b4 Pin the variant rules a mutant survived or that lost their only test
Reader refusals (v1 header over a variant, payload on a variant, unknown op), a
load that finds a variant flattened by another writer, a re-resolution reaching a
read-only cache, a base removed in the same batch as its new variant, and
plain-record-to-variant refused without the name rule masking it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 04:21:59 +02:00
Meta Vens
33664434f9 Drop the unreachable single-record CultMesh variant refusal; tolerate duplicate catalog slots
A variant needs its base beside it, so a single-record store can never hold one:
that overload's refusal could not fire. SlotNames no longer throws on a catalog
that repeats a slot.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 04:21:58 +02:00
Meta Vens
1ddf6e0d56 Mark the three share-mode tests Windows-only
They hold a FileShare.Read handle and expect a delete or replace to fail;
Linux unlink and rename ignore open handles, so they can never pass there and
showed as three standing failures. [Platform("Win")] reports them skipped with
a reason on Linux and keeps them running on Windows. No Linux failure injection
exists: the store names its temp file with a fresh GUID and the suite is
likely root in the verify container, so read-only directories do not fail.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 04:17:31 +02:00
Meta Vens
fc78b9ad2b Test the C# variant path and add the C#-written variant store as a shared vector
VariantTests drive the cache batch API and the real single-file store. The C1
vector was written by the code under test through that path; C# reads it and
rewrites it byte for byte, and the other runtimes' tests read the same bytes next.
The C0 tests that expected C# to refuse a v2 store now expect what C1 does with
it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:52:35 +02:00
Meta Vens
e382bb4e20 Merge variants C0: every reader refuses what C1 will write, by name
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>
2026-09-29 03:52:07 +02:00
Meta Vens
dbc87b9447 C# core: variant records, top-level Set overrides, resolution in the admitting hold
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>
2026-09-29 03:51:53 +02:00
Meta Vens
6251cbcd37 Merge BP-1: the content plane in cultnet-rs
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>
2026-09-29 03:31:20 +02:00
Meta Vens
5b538aaf07 Answer chunk requests whose string fields are nil
A C# caller that leaves ChunkHash, MessageId or RecordKey null writes msgpack nil; the
reference reads it back as null, treats it as blank and answers found:false. Rust now
decodes nil as blank in content chunk requests, so those requests are answered with the
reference bytes instead of dropped. Three nil vectors from the reference server are
judged by decoding them in Rust. Record two content-plane limits in the parity scope.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:29:41 +02:00
Meta Vens
30ee8b97ab Merge route continuity C1: local route proof in the TypeScript Idunn runtime
The runtime splits into a signer (load, sign, answer a route challenge
locally, no Odin, no network) and an optional Odin presence publisher for
CultMesh-aware services. The signer owns health (reportHealth, starting at
warming), records every warming it signs as a lease target, allows one
signer per frozen authority, and ships a subpath export that does not
load the publisher. Rust judges TS output: committed vectors from
examples/idunn_runtime_fixture.rs, verified by the Rust authenticator and
correlator, including a stateful lease-bound set.

Soul passed it after two fix batches. cultnet-ts has 113/113 tests on
node:24. StreamPixels' web and service call sites move in C2.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 03:27:19 +02:00
Meta Vens
5ed9dbbcb8 cultnet-ts: stop exporting signIdunnRuntimePresence; document two limits
The function took state and lease digest from the caller, so anyone holding the
authority could sign active without reportHealth or assertWriteLease. It is now
private to the signer. Test: the subpath and root do not expose it. Docs:
waitForWriteLease throws out of publish if health is already non-warming;
MAX_RECENT_WARMING_PROOFS=64 is a recorded limit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:26:10 +02:00
Meta Vens
7584a5c08a Merge remote-tracking branch 'origin/main' into hands/variants-c1 2026-09-29 03:20:38 +02:00
Meta Vens
a5edd976d0 Sweep Q3 into C4: no per-type opt-in
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 03:20:30 +02:00
Meta Vens
4cdc8864a2 Sweep Q3 (ids everywhere, minted on load) into the C2 spec
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 03:20:11 +02:00
Meta Vens
addaf10c22 Sweep the Q4 reversal into the C1 spec: overrides soft-drift
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 03:19:42 +02:00
Meta Vens
322b7c815a cultnet-ts test: read the signed document, not the SignedRuntimePresence wrapper
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:15:40 +02:00
Meta Vens
06d250070a cultnet-ts: add an idunn-runtime subpath export that does not load dgram
`cultnet-ts/idunn-runtime` exposes the signer and loader alone. Web apps import
it instead of the package root, which also carries the Odin publisher and
node:dgram. The root export is unchanged. Test loads both under a stubbed
dgram: the subpath loads, the root fails.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:13:37 +02:00
Meta Vens
67b8ae3eda cultnet-ts: freeze the Idunn authority and allow one signer per authority
The loaded authority is deeply frozen (bind, health contract, Expected,
Activation, identities), so a caller cannot steer what the signer signs; the
typed Buffers that could not be frozen are dropped (Expected canonical bytes,
Activation public key kept as hex only for the load-time comparison). A second
createIdunnRuntimeSigner on the same authority throws, so two signers cannot
emit sequence 1 under one runtimeInstanceId.

Tests: stateful set pinned against Rust (warming, active, degraded), lease
accepted for a route-answered warming, refused for another warming and another
target, one signer per authority, frozen authority.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:13:28 +02:00
Meta Vens
8072314b7c cultnet-ts: the Idunn signer owns the reported health and warming proofs
The signer holds the last reported health, starting at warming, and gains
reportHealth(state). sign(detail), answerRouteObservation(request) and the Odin
publisher's publish(detail) no longer take a state, so the route answer and the
Odin publish cannot disagree and a fresh signer cannot answer active. Every
warming presence the signer signs becomes a valid write-lease target; the
publisher's recordPublishedWarming is deleted. Tests now assert every committed
stateless vector, dead ones included.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:11:48 +02:00
Meta Vens
4ec75eec18 cultnet-ts: regenerate Idunn runtime fixtures with the stateful lease-bound set
Output of the Rust generator (3c9ce38) on Yggdrasil. Every set is re-enrolled, so
all bytes change; adds service-stateful with lease.cc, the two wrong leases and
the warming/active/degraded vectors.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:10:55 +02:00
Meta Vens
3c9ce3823c cultnet-rs fixture example: add a lease-bound stateful Idunn set
Adds `service-stateful` (streampixels-service shape, state lineage set,
write_lease_required) with a Rust-issued lease.cc, warming/active/degraded
vectors bound to it, and two wrong leases (other warming digest, other target).
Each vector still passes authenticate + correlate before it is written.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 03:05:12 +02:00
Meta Vens
a7eb9967e9 Pin the metadata decode message so the last content.rs mutant is caught
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:59:59 +02:00
Meta Vens
66bd07b941 Pin the legacy-layout and missing-header refusals
The legacy catalog layout reaches CultMesh's fallback reader, and a nil header
was the only defaulted header; each gets one vector or test. The C# store
tests catch the refusal where the store attaches.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:35:57 +02:00
Meta Vens
36aa8d8791 Rust: drain the header peek so rmp-serde accepts the array
The peek left snapshot slots unread and rmp-serde refused the length
mismatch, so every store fell through to the legacy decode.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:34:11 +02:00
Meta Vens
dc9162f85d Correct the content-plane parity claim for metadata order and bad requests
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:12:44 +02:00
Meta Vens
16432d4b1e Fix the BP-1 findings in the cultnet-rs content plane
A hostile manifest of empty chunks no longer becomes a request flood: fetch_content
refuses a zero-size chunk beside other chunks, and settles the content hash and every
chunk hash (normalised, non-empty) before the first request.

Every bad chunk request is now answered found:false in the reference handler's
validation order, never refused at decode. validate_message no longer refuses content
chunk requests or responses, so a blank message id or hash, a prefix-only hash and a
negative size reach answer_content_chunk_request. The answer follows the reference's
double normalisation (handler, then CreateRecordKey), which fixes the prefix-only
hash spelling to ArgumentException on 'chunkHash'. The cs vectors gain nine
reference-server answers (blank and whitespace id, blank, whitespace and prefix-only
hash, negative size, record-key case, blank record key, double prefix) and a
metadata-order manifest; Rust answers all of them byte-identically.

Manifest metadata is Vec<(String, String)> in wire order and refuses a duplicate key,
replacing the BTreeMap that re-sorted keys.

Tests pin the surviving mutants: unusable chunk sizes, the payload-length and
claimed-size halves of the chunk check, stable sort at equal offsets, the normalised
hash and canonical key actually sent, and the kind/mime defaults never trimming.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:12:43 +02:00
Meta Vens
795fd1023c cultnet-ts: split Idunn authority from the Odin publisher; answer route challenges locally
idunn-runtime-authority.ts now loads and signs only: no Odin endpoint, no Odin
dependency check, no RUDP. createIdunnRuntimeSigner signs presence and answers
Idunn's route challenge with answerRouteObservation(request, state), a
synchronous local signature in the state the app reports. The RUDP publisher
moves to idunn-odin-presence-publisher.ts for services that declare
odin.verse-rendezvous, and keeps the Expected-endpoint check.

Deleted: the TS capability-minimum refusal (the Rust correlation records the
typed disagreement), latestPresenceDocument, the forced "active", and the
publisher's redundant health-contract and bind checks. Route validation now
accepts http, tcp and rudp as Rust does; the machine-id falls back to
/var/lib/dbus/machine-id. Tests run against the Rust-written fixtures.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:05:14 +02:00
Meta Vens
6b107c1adc cultnet-ts: Rust-generated Idunn runtime fixtures
Expected, Activation, identities and signed presence vectors from the cultnet-rs
example; the README says how to regenerate them.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:05:14 +02:00
Meta Vens
95f04c1efb Rust: name the record and the version when a store is refused
PersistedRecord refuses a fifth slot naming its key and schema id, and an
unknown cultcache.store.* header no longer falls through to the legacy
envelope decode that hid the cause.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:04:34 +02:00
Meta Vens
c8777fe08d Python: refuse unknown store headers and extra record slots by name
Delete the raw_record[:4] slice and the legacy-envelope fallthrough for
unknown cultcache.store.* headers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:04:34 +02:00
Meta Vens
569d668141 TypeScript: refuse unknown store headers and extra record slots by name
The store reader and the inspector share one header and record-slot rule;
an unknown cultcache.store.* header no longer falls through to the legacy
envelope decoder.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:04:34 +02:00
Meta Vens
98ed042fcc C#: refuse unknown store headers and extra record slots by name
Delete the trailing Skip loop in the record reader, the ?? v1 header default,
and the mesh reader's copy of the record decoder. The single-file store and
CultMesh single-file reads accept cultcache.store.v1 only. Persistence-format
and parity docs state the rule.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:04:33 +02:00
Meta Vens
2cb694d612 Pin the C0 refusal vectors shared by every runtime
An unknown store header, a record slot beyond four with a full payload, the
v2 variant record C1 will write, and a v1 store written by the base-commit
Python writer. Every runtime's tests read these bytes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 02:04:33 +02:00
Meta Vens
69a21bb057 Record the operator's rulings on document variants Q1-Q7
Q3 is ids everywhere, minted on load (not opt-in). Q4 is soft drift for
dangling overrides, which supersedes one of the target's refusals. The
others were ruled as recommended.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 01:55:09 +02:00
Meta Vens
9ba6ac4a2e cultnet-rs fixture example: name an Odin port a dev machine does not run
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 01:44:04 +02:00
Meta Vens
f5c597a81d cultnet-rs fixture example: remove the store lock files it leaves
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 01:40:30 +02:00
Meta Vens
1e86bf0dc3 Place the document variants target and cut map on main
The target (2026-09-17, with the operator's rulings) lived only on
codex/document-variants. The cut map is Imagination's pass of 2026-09-29.
Its operator questions Q1-Q7 are open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 01:34:42 +02:00
Meta Vens
0e7d2204cd cultnet-rs: example generating Rust-owned Idunn runtime fixtures
Real enrolled identities, a validated Expected, an Activation issued by
IdunnRuntimeActivationLaunch, bundle files through the CultCache store, and
runtime-presence vectors signed by the Rust signers and run through
authenticate/correlate before they are written. cultnet-ts tests will commit
the output.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-29 01:32:57 +02:00
Meta Vens
de57d8dc9c Merge the Idunn TypeScript runtime into main (route continuity Q6)
The operator ruled Q6 (a) on 2026-09-29: this branch lands on main before
route continuity cut C1 changes it. What lands is the ten 09-28 commits
that StreamPixels pins at 542ddd3, plus the Soul-gated fixes:
- runtime presence and daemon-health details are bounded by UTF-8 bytes
  through one helper, made well formed first, matching the Rust owner's
  len() > 512;
- the dead readAuthorityRecordBytes is deleted;
- the TypeScript packages require Node >= 20.

Soul confirmed byte-level wire parity with Idunn's Rust owners on real
Rust-written bundles, including the full write-lease flow. cultnet-ts has
90/90 tests on node:24. Capability-floor split authority, forced active
and the http-only route filter are recorded for C1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 01:21:49 +02:00
Meta Vens
0791e1b7d0 Raise the TypeScript packages' Node floor to 20
Some checks failed
CultMesh portability and performance / ubuntu-latest one-command multiplayer onboarding (push) Has been cancelled
CultMesh portability and performance / windows-latest one-command multiplayer onboarding (push) Has been cancelled
CultMesh portability and performance / ubuntu-latest reactive semantics and leases (push) Has been cancelled
CultMesh portability and performance / windows-latest reactive semantics and leases (push) Has been cancelled
The UTF-8 detail bound calls String.prototype.toWellFormed, which
Node 20 introduced. Node 18 reached end of life in April 2025, and CI
runs Node 24. All four TypeScript packages move together so the family
keeps one floor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 01:21:18 +02:00