;; __NAME__'s LogOp union — the one wire surface this app owns.
;;
;; Everything else on the wire comes from the shared rooms core
;; (`ardegazu.rooms.lib.*`, compiled off the classpath out of
;; ardegazu-rooms-kit): the relay frames, the sealed hello, the presence
;; beacons, the at-rest envelope. The core seals and replicates your ops as
;; OPAQUE payloads and never inspects them, so this union is yours to define and
;; the sanctioned divergence point of the rooms line.
;;
;; Documentation only, exactly as the kit's own lib/protocol.cljs is: the
;; TypeScript original was a `.d.ts`-shaped module that compiled to `export {}`,
;; and CLJS has nowhere to put the types either. The value of the file is that
;; the shapes are written down in ONE place next to the code that builds them.
;;
;; Two rules the core does enforce on whatever you put here, and both have
;; shipped bugs in this suite (dev/docs/CLJS.md):
;;
;; - KEY ORDER IS THE WIRE. Every op is `js/JSON.stringify`'d before it is
;; sealed, so its key order is part of the bytes a peer verifies. Build ops
;; with `ardegazu.rooms.js/ordered` (sequential `unchecked-set`) — never
;; `#js {}` or `js-obj`, which silently switch to hash order at nine pairs.
;; Count the keys in a new op BEFORE you write its builder, not after.
;; - A VALIDATOR IS THE CONTRACT. Receive-side checks use the JS forms
;; (`js/Array.isArray`, `(identical? "string" (js* "typeof ~{}" x))`,
;; `=== null`), and an op that does not validate is DROPPED, not repaired.
;;
;; Pin every op with a byte-exact golden vector in `test/vectors/` the moment
;; you have more than one appender (see client/test/README.md).
;;
;; The scaffold's demo store rides chat's op so it runs day zero:
;;
;; {t:"chat", ts, name, text, thread?}
;;
;; Replace it. Your APP-SALT (config.cljs) already makes your rooms unreachable
;; from chat's, whatever the op shapes are — the salt is the separation, not the
;; op union.
(ns __NAME__.lib.protocol)