Files
Claude 09d356edfb refactor: fold contextvm and cordn into quartz
Both were Gradle modules on reasoning that does not survive examination.

`:cordn`'s stated reason was circular: "the coordinator client needs
`:contextvm`, and quartz cannot depend on it without a cycle" -- true, but only
because `:contextvm` had been put outside quartz first. A consequence of an
earlier choice was written down as if it were a constraint.

`:contextvm`'s reason was "a peer of `:quic`". That analogy does not hold.
`:quic` is a transport library with no Nostr in it at all -- which is exactly
why it is a module. ContextVM is nothing but Nostr: kind 25910 events, NIP-59
gift wraps, relay subscriptions. Its build file also claimed quartz's
serialization dependency was not transitive, which only mattered across a
boundary the same decision had created; quartz has had
kotlinx-serialization-json all along.

What actually governs is the precedent already in the tree. `marmot/` is 18,876
LOC of non-NIP protocol family living inside quartz with its own MIP spec
series -- the same shape as cordn and three times the size of both modules
combined. `concord/` is another, `buzz/` a third. CLAUDE.md's own rule is that
quartz holds implementations of Nostr specifications, and CEPs are to ContextVM
what NIPs are to Nostr core.

So: `quartz/…/contextvm/` and `quartz/…/cordn/`, as the plan said in the first
place. Two build files and two settings entries deleted.

Two things got better rather than just tidier:

- **Both now build for every quartz target**, iOS and linuxX64 included.
  Neither had a single platform-specific file, so as jvm+android modules they
  were narrower than the code required. Verified with
  `compileCommonMainKotlinMetadata`, which type-checks commonMain against the
  intersection of all declared targets.
- **The crypto-dependent tests moved from `jvmTest` to `jvmAndroidTest`**,
  where quartz keeps the rest of its secp256k1 tests, so they now run on the
  Android host too instead of the JVM alone.

`:quartz:jvmTest` 5086 -> 5330, exactly the 174 + 70 that moved, none lost. The
ts-mls interop gate still passes all ten checks after the move.

`:quartz:testAndroidHostTest` has four failures in `NostrServerTest` and
`LiveNegentropyIndexStoreTest`. They are pre-existing and unrelated -- relay
server and SQLite store -- confirmed by stashing this change and reproducing
them identically at the parent commit.

CLAUDE.md now records the placement rule, so the next protocol does not have to
rediscover it: a protocol over Nostr is a quartz package, not a module;
`quic`/`nestsClient`/`marmotQuic` are modules because they carry no Nostr.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012BfD4txdnsaPRXmNXbup9n
2026-09-18 20:58:23 +00:00
..