Two thousand and twenty-one packages carried more than one spec across this
estate — eslint alone in a hundred and four forms — and a package resolved twice
is two copies at run time, which is how react-hook-form came to report "two
different types with this name" from files nobody had edited. None do now.
The number lives in the catalog: a manifest names the package, the workspace
names the version. Where a manifest cannot reach a catalog it still carries the
one version, because the table is the source either way.
Co-authored-by: Hanzo Dev <[email protected]>
A version written into a manifest is written into every manifest that wants it,
which is how eslint came to exist in a hundred and four forms across this estate
and how a package came to resolve twice at run time. The catalog moves the number
out of the manifest: a manifest names the package, the workspace names the
version.
Four are held below their latest because the newer release cannot be used, and
the reason is recorded rather than the version alone: @noble/hashes 2 renamed
every subpath the web3 stack imports, @splinetool/runtime 2 depends on a package
that was never published, @dynamic-labs 5.4.1 the same, and react-resizable-panels
3 points its types condition at the bundle.
Co-authored-by: Hanzo Dev <[email protected]>
The previous "full PQ" claims for Python and TS were tested only within
each language. This commit proves the wire bytes actually match Go.
What was wrong:
Both Python and TS were calling ml_dsa65.sign(secretKey, message)
WITHOUT the FIPS 204 ctx parameter, while Go was calling
DSAPriv.SignCtx(rand, digest, []byte("lux.zwing.v1")). The signed
messages diverged → handshake verify failed across language pairs.
Fix:
Python: ML_DSA_65.sign(sk, digest, ctx=ZWING_DOMAIN) and matching
verify with ctx=ZWING_DOMAIN.
TS: ml_dsa65.sign(digest, sk, { context: ZWING_DOMAIN }) and
matching verify { context: ZWING_DOMAIN }.
Real interop tests added:
cmd/zwing-test-server/main.go — minimal Go server: prints listen
addr + identity hex on stdout,
accepts ONE handshake, echoes one
payload, exits.
py/test_interop_go.py — Python client connects via TCP,
runs run_initiator + Channel echo
against the live Go server.
js/interop_go.test.ts — TS client over node:net.Socket
runs runInitiator + Channel echo
against the live Go server.
Both interop tests pass:
Python ↔ Go: Ran 1 test (and 43 within-Python tests)
TypeScript ↔ Go: 1 interop test passes alongside 32 within-TS tests
Wire-byte compatibility now PROVEN end-to-end for X-Wing KEM, hybrid
identity (Ed25519 + ML-DSA-65 with lux.zwing.v1 ctx), HKDF channel
keys, and ChaCha20-Poly1305 records across Go ↔ Python ↔ TypeScript.
Add canonical Python and TypeScript ports of the IETF X-Wing combiner
under py/ and js/ inside this repo. Both implement
shared_secret = SHA3-256("\./X-Wing" || ss_M || ss_X || ct_X || pk_X)
byte-for-byte and pin the same KAT as the Go (kat_test.go) and Rust
(zap-protocol/zap zap::zwing) ports:
inputs: ssM=0x01..x32, ssX=0x02..x32, ctX=0x03..x32, pkX=0x04..x32
output: 72df2088314a73de80c21d9593f13fcd5629c800c70b1507f0dd918fde5fe4ed
Layout:
py/ pyproject.toml + zwing.py + test_zwing.py (stdlib hashlib)
js/ package.json + zwing.ts + zwing.test.ts (@noble/hashes ^2.2.0)
Z-Wing now has 4 byte-compatible implementations under one canonical
roof (luxfi/zwing). The Rust port lives at zap-protocol/zap as
zap::zwing because that's the canonical Rust home for the schema +
runtime. All four pin the same hex.