Part of #131. Depends on 3a-3c. Closes the confidence loop: validate the whole encrypted CRDT sharing lifecycle in remote CI.
Scope
- Key-mode compose: clients get Ed25519 identities; daemon seeded with their pubkeys (encryption requires key auth).
- Encrypted scenario
.scm: share → (kb-set-encryption e2e) → join → approve → ≥2 members edit → wait-for-content converge (content-barrier polling, no fixed sleeps).
- Security-negative oracle: mount the daemon's data dir read-only; grep its store/WAL and logs for a per-run plaintext canary ⇒ ABSENT. Positive control: the same canary PRESENT in each member's buffer (silent content-drop fails loudly). Assert the
kbc: op-log carries the Encryption::E2e flag + a wrapped_key op.
- Replace the stale Makefile
ci-docker-e2e SKIP stub; make collab / docker e2e a required check.
Acceptance tests
- The encrypted scenario converges across ≥2 members; daemon store/WAL/logs contain only ciphertext (canary absent), members' buffers contain it (present).
- A deliberately-injected regression (push plaintext instead of sealing) turns the gate RED.
- Existing unencrypted convergence scenarios still pass (regression).
Part of #131. Depends on 3a-3c. Closes the confidence loop: validate the whole encrypted CRDT sharing lifecycle in remote CI.
Scope
.scm: share →(kb-set-encryption e2e)→ join → approve → ≥2 members edit →wait-for-contentconverge (content-barrier polling, no fixed sleeps).kbc:op-log carries theEncryption::E2eflag + awrapped_keyop.ci-docker-e2eSKIP stub; makecollab / docker e2ea required check.Acceptance tests