Generator run in mcr.microsoft.com/dotnet/sdk:10.0; the three added rows are exceptions UriBuilder throws.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
These pin that the authority-form check is anchored at the start of the endpoint; their .NET output follows in the next commit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The owner now refuses a chunk past 2147483647, so the oversize manifest is 32768 chunks of that size (about 64 TiB) instead of one 2^53 - 1 chunk.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reader refuses a scheme without an authority form, escapes of bytes past ASCII and IPv6 literals that embed an IPv4 address; parity is tested against chunk-uri-dotnet.tsv. Wrong-bytes tests run at maxBytes equal to the size and at concurrency 1 and 32. The stall test measures settlement against a 100 ms timer and counts requests started after the failure.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The generator's run in mcr.microsoft.com/dotnet/sdk:10.0 (UriBuilder body of BuildChunkUri); 8 rows are exceptions UriBuilder throws.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A fourth fixture (escape) has a chunk recordKey of k!'()* <e-acute>%41+~. The provider's honest mount answers that one key as the canonical key
after logging the raw URL, so both consumers fetch the bytes and the log holds what each actually sent. The orchestrator asserts the C# and TS
URLs are identical and equal the RFC 3986 escaping. Deleting the reader's !'() * escape now fails test:interop.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The TS provider runs in its own process on node:https with the fixture credential. The TS reader and the C# transfer service over the unmodified HTTPS connector (CustomRootTrust, fixture certificate only) each fetch from it; the orchestrator judges URL parity, the empty chunk, corrupt-store faults and the untrusted control. test:interop is wired in cultmesh-browser and the workflow, and the cultmesh-ts step now precedes the browser step.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Self-signed P-256 pair for 127.0.0.1, CA:FALSE, serverAuth, with the openssl recipe in the README.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mutation sweep survivors: manifest-invalid causes now asserted by field and rule, escaped-unreserved and
broken-escape endpoint rows added from .NET probes, and the two {once:true} options that the finally removal
already makes redundant are deleted.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Wrong-bytes refusals at 1..4 MiB+1 for both exports and mid-manifest; the .NET URL table (accepted rows
equal, divergent rows refused); redirect, late abort, stalled fetch and unallocatable size cases; port,
trailing-empty, 2xx and multi-chunk length rows; waits are bounded and abort waits fail on timeout.
Test types adapted to C1's nullable chunk refs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
BuildChunkUri trims all leading '?' of an existing query; the reader trimmed one.
Chunk placement is by offset, so sorting the refs decided nothing and is gone;
the size guard checks sizes, which fix the offsets. New behavioural tests for
the mutation survivors: absent recordKey, fractional/infinite sizes, the
fetchVerifiedChunk byte-cap boundary, undefined crypto, error messages,
abort-listener removal.
Builds and passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reader judges received bytes: each chunk streams into its slot of a private
buffer, is cut at the first byte past its size, and is hashed; the whole body is
hashed before the buffer is returned. Length and coding headers are never read.
URLs equal the C# BuildChunkUri; concurrency 1..32, maxBytes, AbortSignal, typed
errors. Hashing, hex, keys and the loopback rule stay in cultnet-ts.
Builds and passes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DocumentPayload is an opaque object type over the same runtime Uint8Array, keyed by a string
property, and types CultCacheEnvelope.payload, CultNetRawDocumentRecord.payload and
CultMeshRealtimeFrame.payload. decodeDocumentPayload(definition, payload) and
encodeDocumentPayload(definition, value) are the only reader and writer; documentPayloadFromBytes
and documentPayloadBytes are the two named escapes at the edges where bytes enter and leave.
resolveDocumentFormatter leaves the package index. The cache, cultnet replication, the mesh read
paths, the provider command (now a CultCache document), and the browser's decodeCultNetPayload
(definition required, cultcache-ts/document entry) all go through the owner.
Compile-fail fixtures per payload-carrying package pin the type with expect-error lines.
check-typescript-tests-wired.mjs fails when a test file is run by no script; cultcache-ts now
runs dist-test/test/*.test.js, and the portability workflow runs the check and the cache suite.
Builds in every package (tsc, src and tests); the suites run once, at the end of the pass.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The two payload-decode-owner text-scan tests go, as do the string-schemaId overloads and
branches of the cultMeshDocumentFrom* functions and statics, decodeCultMeshPayload,
decodeCultNetRawDocumentPayload, toUint8Array, replication's second decodeDocumentValue, and the
undefined branch of decodeDocumentPayload. decodeDocumentPayload now requires the definition and
also runs its schema (the one reader). A publication binding names a definition, never a bare
schema id; the RUDP put handler refuses a schema with no registered definition instead of
plain-decoding it. Builds in every package; tests not yet rerun.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The guard test counted its package root from the compiled layout and failed under tsx and for a one-file src; it now walks up to
the package.json. The browser's non-messagepack refusal and the cache's codec-and-formatter refusal are pinned by message.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The RUDP put handler and the browser payload reader decoded a codec document with plain msgpack. cultcache-ts now
exports decodeDocumentPayload (definition or plain), the RUDP server reads a put through the registry's definition,
and decodeCultNetPayload takes the formatter. cultmesh-ts and cultmesh-browser no longer depend on @msgpack/msgpack:
frames and commands use cultnet-ts/wire, and a test per package scans src and the manifest. The envelope probe fixture
now runs the plain record first and last. Not yet built or tested on this commit; the verify job follows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Soul replaced the shared `isUnsignedCertificate` call in the browser's
session-acceptance check with a local empty-string comparison and every one of
the 18 browser tests still passed, because every test used an empty signature.
A whitespace signature is where the two readings part: the shared route
verifier accepts such a route as unsigned on a loopback local-development
endpoint, and an inline comparison then demands a provider proof for the
session the verifier just let through. The test now opens that session with
three spaces, U+0085 and a no-break-space/tab/newline mix as well as the empty
string, and asserts U+FEFF the other way, since it is whitespace to JavaScript
and a signature to C#.
The mutation runner grew a second target. `shared` is the one verifier, killed
by the cultnet-ts tests; `browser` is `packages/cultmesh-browser/src/index.ts`,
killed by the browser tests. A browser mutation cannot be killed by cultnet-ts
tests, so the killer is the target's own workspace, and each target carries its
own sidecar, control, sentinel and post-restore dist assertion.
Two repairs this pass earned:
- The sidecar is now removed inside the `finally`, right after the verified
restore. A throw mid-run left it behind holding the pre-run bytes, and the
next run "repaired" the file from them, silently reverting everything fixed
in between. That happened here, twice, before it was noticed.
- The NUL in the loopback pre-check's strip regex had been written as a literal
byte rather than an escape. It read the same, but git classified the file as
binary and stopped normalising its line endings, so the whole file diffed as
rewritten. Escaped, along with the ASCII host range beside it.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The browser's local-development session-proof short-circuit tested
`!route.certificate`, while the shared verifier already treated an empty or
whitespace signature as unsigned, matching C# `Verify` (`:120`). A loopback
route carrying a blank-signature certificate therefore passed the verifier
and was then refused for lacking a provider key, where C# returns
`IsLocalDevelopment` and skips the session proof.
`isUnsignedCertificate` in `cultnet-ts/authority` is now the one owner of
that reading; the verifier and the browser both call it. A browser test pins
the local-development loopback open without a provider proof, the signed
loopback certificate still demanding it, and the remote counterpart refused
in both trust modes. The mutation runner gains two predicate mutations
(whitespace treated as signed; only a missing certificate treated as
unsigned), both killed by the existing whitespace-signature test in
cultnet-ts.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>