Files
amethyst/cli/tests/marmot
Claude 5b1ac283d5 feat(marmot): retention UI, pinned reference engine, and a scenario-vector runner
**Disappearing messages are settable.** A picker at group creation — off, 1
hour, 1 day, 1 week — and a read-only line on the group info screen so a member
who cannot change the setting still knows their messages are on a clock. Fixed
values rather than a free-form duration: the number is committed into group
state every member's client reads, and an arbitrary one buys nothing. Creation
is the only place it can be chosen, because promoting a component to required
after epoch 0 takes two commits and that screen makes one. Until now we obeyed
a setting neither Amethyst nor `amy` could set.

**The harness tests the engine users run.** It cloned mdk master and got
whatever was tip; both shipping White Noise clients embed an immutable
MarmotKit artifact and name its `mdk-sha` in a lockfile. It now checks out that
commit, and rebuilds `wn` when the checkout moves — a pinned tree beside a
binary built from a different commit would report a version it did not test.

**A scenario-vector runner.** Their manifest marks 31 artifacts `portable`,
meaning written for one engine and meant to be replayed by another. Three are
byte fixtures we already consume; the rest are scripts. `MarmotScenarioRunner`
replays them against our own stack — publishing captured into a queue,
`deliver_all` moving it into inboxes, `tick` draining them — and checks the
expected trace. Six pass. This is a different claim from the interop harness:
that proves we can TALK to `wn` over a relay, this proves the same events land
us in the same group state.

It refuses an unimplemented step by name rather than skipping it, because a
runner that ignored steps would report a pass for a script it never executed.

That refusal immediately found something. Three vectors create a group with
several invitees, and the reference adds them all in ONE commit — epoch 1.
`MarmotManager.addMember` stages one Add per commit, so we reach epoch N. Both
are valid MLS and any peer processes either, but our traces cannot match, and
creating a group costs an extra round trip per invitee. Asserted as a named
divergence so it stays visible and fails the day batched adds land.

**Two smaller things.** `DispatchStageBenchmark` is opt-in behind
`-DrunLoadBenchmark=true`: it pushed 30k events through six variants twice
inside a `runTest` whose cutoff is one minute, so on a loaded runner it failed
having measured the machine rather than the code. And encrypted-media-v1
(`0x8008`) is closed as not-needed — required only on the Legacy profile, which
strict cutover now forbids joining, so no group that asks for it is reachable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016kCuA6tc4JQzHPCDd39GHq
2026-09-10 03:40:05 +00:00
..