Skip to content

Commit e0ce74b

Browse files
mswilkisonclaude
andcommitted
docs(frost/roast): document quorum-gate boundary behaviour and parking scope
Review follow-ups on the verifiable-blame revision: - Fix inverted group-shape wording (51-of-100, not 100-of-51). - State explicitly that near the assumption boundary the accuser quorum needs all but 2t-n-1 honest observers (50 of 51 at the production shape), so in the high-f regime the gate is a fabrication firewall rather than a working exclusion mechanism; proof-carrying blame restores exclusion there. - Document the n-of-n edge of ExclusionAccuserQuorum (quorum 1, consistent with f = 0 under that shape's own assumption). - Make precise that silence parking keys on bundle absence: a member that submits its evidence snapshot while withholding its signing contribution is not parked by this layer; that cost is bounded by the Annex B retry budget until t-of-included finalize. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 934d1a6 commit e0ce74b

2 files changed

Lines changed: 30 additions & 3 deletions

File tree

docs/rfc/rfc-21-roast-coordinator-retry-and-transition-evidence.adoc

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,12 +348,18 @@ honest.
348348
falsely labelled silent because their contribution arrived late (or
349349
because a malicious coordinator censored it) is not permanently
350350
penalised -- they are reinstated by the very next attempt.
351+
Silence is detected as *bundle absence* (the member submitted no
352+
evidence snapshot for the transition). A member that submits its
353+
snapshot while withholding its signing contribution is therefore
354+
not parked by this policy: signing-silence is invisible to the
355+
transition layer, costs the attempt, and is bounded only by the
356+
retry budget (Annex B) until t-of-included finalize lands.
351357
. If `IncludedSet` minus exclusions drops below the threshold `t`, the
352358
coordinator returns `ErrAttemptInfeasible` and the session is
353359
declared failed for this signer set.
354360

355361
The quorum is a *derived constant* of the key-group shape -- for the
356-
production 100-of-51 group it is 50 -- so honest signers do not need
362+
production 51-of-100 group it is 50 -- so honest signers do not need
357363
to negotiate it and drift cannot desynchronise it. Sub-quorum claims
358364
are deliberately ignored rather than parked: acting on a single
359365
unverifiable claim would let one byzantine observer cost any honest
@@ -370,7 +376,14 @@ to proof-verified entries. The cost of the interim quorum policy is
370376
bounded: a fault observed by fewer than `f+1` honest members (for
371377
example a targeted, per-recipient equivocation) is not permanently
372378
excluded and instead burns retry attempts, which the serial-attempt
373-
latency analysis already budgets for.
379+
latency analysis already budgets for. Near the assumption boundary
380+
the gate is intentionally demanding -- at worst-case `f` only `t`
381+
honest observers exist, so establishment needs all but `2t-n-1` of
382+
them (50 of 51 at the production shape) to have observed the fault
383+
and landed snapshots in the bundle. In that regime the quorum acts
384+
as a fabrication firewall rather than a working exclusion mechanism;
385+
restoring per-category exclusion under heavy attack is exactly what
386+
proof-carrying blame is for.
374387

375388
=== Layer C: Retry orchestration (M7)
376389

pkg/frost/roast/next_attempt.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,23 @@ import (
3535
// against a quorum of 50, while the 49 worst-case byzantine members
3636
// can never reach 50 by fabrication.
3737
//
38+
// The gate is intentionally demanding near the assumption boundary:
39+
// at worst-case f = groupSize - threshold, only threshold honest
40+
// observers exist, so establishment needs all but 2t-n-1 of them
41+
// (50 of 51 at the production shape) to have observed the fault and
42+
// landed snapshots in the bundle. In that regime the quorum acts as
43+
// a fabrication firewall rather than a working exclusion mechanism;
44+
// real faults that fewer honest members observe burn retry attempts
45+
// instead (budgeted in RFC-21 Annex B), and proof-carrying blame
46+
// (see the roadmap in NextAttempt) is what restores per-category
47+
// exclusion there.
48+
//
3849
// A zero threshold (used by policy-only tests) or a threshold larger
3950
// than the group yields groupSize+1 -- deliberately unreachable, so no
40-
// accusation-driven action can occur without a real threshold.
51+
// accusation-driven action can occur without a real threshold. A
52+
// threshold equal to groupSize (n-of-n) yields a quorum of 1: under
53+
// that shape's own assumption every member is honest (f = 0), so a
54+
// single accusation is established by definition.
4155
func ExclusionAccuserQuorum(groupSize, threshold uint) uint {
4256
if threshold == 0 || threshold > groupSize {
4357
return groupSize + 1

0 commit comments

Comments
 (0)