Source: ADR-023 §Status + §Decision part 1 ("unpredictable-token hardening" and "epoch not persisted across remove/re-add — monotonicity is the documented hardening follow-up"). Two independent hardening passes on the already-shipped epoch-fenced rebase.
Part A — daemon-issued unpredictable epoch token
The epoch fence currently uses a predictable monotonic counter (next_epoch = prev_epoch + 1, shared/sync/src/kb.rs:1014-1018). This kills the honest + naive-malicious cascade but not a sophisticated client that pre-computes derive(fp, E+1) and authors viewer-era ops under the future editor epoch (the "pre-rotation attack"). Fix: epoch token must be daemon-issued and unpredictable (random nonce / state-hash the client cannot precompute). Enforcement lives at daemon/src/collab_handler.rs:1757+ (epoch_of → derive_kb_client_id).
Part B — persist member epoch across remove/re-add
Today a removed member's epoch resets; re-adding starts fresh, breaking strict monotonicity (shared/sync/src/kb.rs:1012-1013). Persist the epoch (tombstone / retained-epoch store survived in the kbc: collection) so it keeps advancing across remove/re-add.
Current state — not started (core fence is done)
Both are explicitly deferred hardening on top of ADR-023 (shipped). Must preserve epoch-0 back-compat (T1–T7 flows).
Pointers
shared/sync/src/kb.rs (next_epoch, derive_kb_client_id, MEMBER_EPOCH_KEY, member-entry storage ~:978-1026), daemon/src/collab_handler.rs:1757-1779.
Size: M. The research-grade causal-hash-DAG alternative (ADR-023 §"Why not capability-signed operations") is a separate long-horizon item, intentionally left in the ADR.
🤖 Filed from the static-docs deferred-work sweep — moving documented future-work into trackable items.
Source: ADR-023 §Status + §Decision part 1 ("unpredictable-token hardening" and "epoch not persisted across remove/re-add — monotonicity is the documented hardening follow-up"). Two independent hardening passes on the already-shipped epoch-fenced rebase.
Part A — daemon-issued unpredictable epoch token
The epoch fence currently uses a predictable monotonic counter (
next_epoch = prev_epoch + 1,shared/sync/src/kb.rs:1014-1018). This kills the honest + naive-malicious cascade but not a sophisticated client that pre-computesderive(fp, E+1)and authors viewer-era ops under the future editor epoch (the "pre-rotation attack"). Fix: epoch token must be daemon-issued and unpredictable (random nonce / state-hash the client cannot precompute). Enforcement lives atdaemon/src/collab_handler.rs:1757+(epoch_of→derive_kb_client_id).Part B — persist member epoch across remove/re-add
Today a removed member's epoch resets; re-adding starts fresh, breaking strict monotonicity (
shared/sync/src/kb.rs:1012-1013). Persist the epoch (tombstone / retained-epoch store survived in thekbc:collection) so it keeps advancing across remove/re-add.Current state — not started (core fence is done)
Both are explicitly deferred hardening on top of ADR-023 (shipped). Must preserve epoch-0 back-compat (T1–T7 flows).
Pointers
shared/sync/src/kb.rs(next_epoch,derive_kb_client_id,MEMBER_EPOCH_KEY, member-entry storage ~:978-1026),daemon/src/collab_handler.rs:1757-1779.Size: M. The research-grade causal-hash-DAG alternative (ADR-023 §"Why not capability-signed operations") is a separate long-horizon item, intentionally left in the ADR.
🤖 Filed from the static-docs deferred-work sweep — moving documented future-work into trackable items.