Commit graph CultLib/contracts
Author SHA1 Message Date
Meta Vens
1590145a81 Pin the TypeScript-signed direction of the authority parity check
`contracts/cultmesh/authority-route-vectors.json` proves C# bytes verify
in TypeScript. Nothing in the repo proved the reverse; Soul's probe did it
once in a scratch directory. It is now a committed check in the same shape,
mirrored:

- `scripts/sign-cultmesh-authority-vectors.mjs` builds the route and
  session transcripts with the shared module, signs them with fixed
  TypeScript-owned test keys over awkward inputs (a quic scheme with a
  query, three unsorted protocol ids, non-ASCII generation text, priority
  13), self-verifies, and writes
  `contracts/cultmesh/authority-route-vectors.ts-signed.json`.
- `CultMeshAuthorityProofTests.AuthorityRouteVectorsSignedByTypeScriptVerifyHere`
  reads that file with keys taken from the file, asserts the protocol ids
  are unsorted, that `Validate` and `VerifySessionProof` accept, and that
  a priority-tampered route and a replayed nonce are refused.
- The TypeScript vector test runs over both files, so a transcript change
  on the TypeScript side fails here before C# could trust a stale file.

Checked negatively: one base64 character changed in the committed
signature fails the C# test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 16:27:06 +02:00
Meta Vens
e234a64ae9 Add the shared CultMesh route verifier to cultnet-ts
Cut 1 of the TypeScript QUIC realtime plane: one TypeScript
implementation of Odin root lookup, the validity window, the canonical
route and session transcripts, P-256/P1363 verification, loopback
detection and the protected-scheme rule, published as
`cultnet-ts/authority`. Browser-safe by construction: WebCrypto,
TextEncoder, atob/btoa, URL, DataView; no node: import, and a test that
says so.

The protected-scheme rule is the C# rule (wss, https, any scheme
containing "quic") rather than wss-only, so the module is not wrong for
QUIC routes; the browser client still refuses non-ws(s) endpoints itself.

The transcript bytes are pinned by contracts/cultmesh/authority-route-
vectors.json, written by the C# reference under CULTMESH_WRITE_VECTORS=1
with fixed test keys and otherwise re-verified by both runtimes. The
vector carries a route certificate and a provider session proof.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-16 15:59:09 +02:00
Meta Vens
fcc49cffa0 Consolidate CultNet schema contracts into CultLib/contracts/cultnet
REC-032 commit 1: move the canonical 33 TS + witness-artifact-bundle
schema files (34 total) into runtime-neutral CultLib/contracts/cultnet,
move the interop-note schema (and delete the zero-consumer discovery-*
schemas per D3, tagged parked/cultnet-discovery-contracts) into
contracts/cultnet/interop, and delete the 27 C# and 24 Rust duplicate
copies after confirming byte-for-byte equivalence (only
cultnet.snapshot-request differs: TS carries shardId/shardEpoch, a
known drift already resolved in favor of the TS shape).

Rewrite every $id from https://github.com/GameCult/cultnet-ts/contracts/
and .../cultnet-ts/integration/contracts/ to
https://github.com/GameCult/CultLib/contracts/cultnet/(interop/); give
the two shard-catalog schemas URL ids per D1, replacing the bare
cultnet.shard_catalog_*.v0 identifiers; leave ghostlight.agent-state's
Ghostlight-owned $id untouched per D5.

Repoint every runtime's load path and id literal at the new location:
C# csproj EmbeddedResource + LogicalName, Rust include_str! paths,
TS contracts.ts imports + swarm-contracts manifest/tooling + package.json
files/prepack, and the id/path literals in the C#, Rust, Python and
Kotlin interop tests and peers. Python and Kotlin still build their own
schema JSON in-process (D2); only their base constants, id literals,
and (for Kotlin) contentHash literals were swapped. Every Kotlin
contentHash was recomputed from the final canonical files using the
runtime's own stable-stringify + SHA-256 function; all matched the
planner's precomputed values except cultnet.schema-catalog-response,
where the planner's proposed value did not match recomputation and the
freshly computed value was used instead.

REC-032, decisions D1/D2/D3/D5.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-13 17:27:41 +02:00