b01ee5336a
Quartz's leaveGroup was returning `proposal.toTlsBytes()` and publishing that raw on kind:445. That's not a valid MLS message — it's just the proposal struct with no FramedContent / MlsMessage framing — and even if it parsed, mdk/openmls would only STAGE the proposal. The target never actually leaves the tree until someone commits with that proposal. MIP-03 explicitly allows non-admins to commit a SelfRemove-only commit, so amy can produce a proper committable kind:445 herself after the self-demote. Replace `selfRemove()` (returned raw bytes) with `selfRemoveCommit()` which adds the proposal to the pending set and runs the standard `commit()` path. Plumb the resulting CommitResult through MarmotManager.leaveGroup so the outer encryption uses `preCommitExporterSecret` (the epoch we're leaving, which is the one every existing member still has). This finally propagates amy's leave to B in test 11. https://claude.ai/code/session_1469d7f4-bb66-4ffa-a44d-1dfa4b526484