Operation Categories
This document defines the three-tier classification system for distributed operations in Aura. It specifies the ceremony contract for Category C operations, the consistency metadata types for each category, and the decision framework for categorizing new operations. The core insight is that not all operations require consensus. Many can proceed optimistically with background reconciliation.
1. Overview
Operations in Aura fall into three categories based on their effect timing and security requirements.
| Category | Name | Effect Timing | When Used |
|---|---|---|---|
| A | Optimistic | Immediate local effect | Low-risk operations within established contexts |
| B | Deferred | Pending until confirmed | Medium-risk policy/membership changes |
| C | Consensus-Gated | Blocked until ceremony completes | Cryptographic context establishment |
Agreement modes are orthogonal to categories. Operations can use provisional or soft-safe fast paths, but any durable shared state must be consensus-finalized (A3). See Consensus for the fast-path and finalization taxonomy.
1.1 Key Generation Methods
Aura separates key generation from agreement:
| Code | Method | Description |
|---|---|---|
| K1 | Single-signer | No DKG required. Local key generation. |
| K2 | Dealer-based DKG | Trusted coordinator distributes shares. |
| K3 | Consensus-finalized DKG | BFT-DKG with transcript commit. |
| DKD | Distributed key derivation | Multi-party derivation without DKG. |
1.2 Agreement Levels
| Code | Level | Description |
|---|---|---|
| A1 | Provisional | Usable immediately but not final. |
| A2 | Coordinator Soft-Safe | Bounded divergence with convergence certificate. |
| A3 | Consensus-Finalized | Unique, durable, non-forkable. |
Fast paths (A1/A2) are provisional. Durable shared state must be finalized by A3.
1.3 The Key Architectural Insight
Ceremonies establish shared cryptographic context. Operations within that context are cheap.
Ceremony (Category C) Optimistic Operations (Category A)
───────────────────── ─────────────────────────────────
• Runs once per relationship • Within established context
• Establishes ContextId + shared roots • Derive keys from context
• Creates relational context journal • Just emit CRDT facts
• All future encryption derives here • No new agreement needed
2. Category A: Optimistic Operations
Category A operations have immediate local effect via CRDT fact emission. Background sync via anti-entropy propagates facts to peers. Failure shows a status indicator but does not block functionality. Partial success is acceptable.
2.1 Examples
| Operation | Immediate Action | Background Sync | On Failure |
|---|---|---|---|
| Create channel | Show channel, enable messaging | Fact syncs to members | Show "unsynced" badge |
| Send message | Display in chat immediately | Delivery receipts | Show "undelivered" indicator |
| Add contact (within context) | Show in list | Mutual acknowledgment | Show "pending" status |
| Block contact | Hide from view immediately | Propagate to context | Already effective locally |
| Update profile | Show changes immediately | Propagate to contacts | Show sync indicator |
| React to message | Show reaction | Fact syncs | Show "pending" |
2.2 Implementation Pattern
#![allow(unused)] fn main() { async fn create_channel_optimistic(&mut self, config: ChannelConfig) -> ChannelId { let channel_id = ChannelId::derive(&config); self.emit_fact(ChatFact::ChannelCheckpoint { channel_id, epoch: 0, base_gen: 0, window: 1024, }).await; channel_id } }
This pattern emits a fact into the existing relational context journal. The channel is immediately usable. Key derivation uses KDF(ContextRoot, ChannelId, epoch).
2.3 Why This Works
Category A operations work because encryption keys already exist (derived from established context), facts are CRDTs (eventual consistency is sufficient), no coordination is needed (shared state already agreed upon), and the worst case is delay rather than a security issue.
The CRDT property is a contract on the fact family, not on transport. Each family is reduced by a pure, order-independent function of its fact set: reversible state uses the observed-remove set, multi-value register and episode patterns, writers stamp causal metadata with a logical clock, and physical time is display-only. See the canonical domain fact model in docs/105_journal.md §4.2.1.
3. Category B: Deferred Operations
Category B operations have local effect pending until agreement is reached. The UI shows intent immediately with a "pending" indicator. Operations may require approval from capability holders. Automatic rollback occurs on rejection.
3.1 Examples
| Operation | Immediate Action | Agreement Required | On Rejection |
|---|---|---|---|
| Change channel permissions | Show "pending" | Moderator approval | Revert, notify |
| Remove channel member | Show "pending removal" | Moderator consensus | Keep member |
| Transfer ownership | Show "pending transfer" | Recipient acceptance | Cancel transfer |
| Rename channel | Show "pending rename" | Member acknowledgment | Keep old name |
| Archive channel | Show "pending archive" | Moderator approval | Stay active |
3.2 Implementation Pattern
#![allow(unused)] fn main() { async fn change_permissions_deferred( &mut self, channel_id: ChannelId, changes: PermissionChanges, ) -> ProposalId { let proposal = Proposal { operation: Operation::ChangePermissions { channel_id, changes }, requires_approval_from: vec![CapabilityRequirement::Role("moderator")], threshold: ApprovalThreshold::Any, timeout_ms: 24 * 60 * 60 * 1000, }; let proposal_id = self.emit_proposal(proposal).await; proposal_id } }
This pattern creates a proposal that does not apply the effect yet. The UI shows "pending" state. The effect applies when threshold approvals are received. Auto-revert occurs on timeout or rejection.
3.3 Approval Thresholds
#![allow(unused)] fn main() { pub enum ApprovalThreshold { Any, Unanimous, Threshold { required: u32 }, Percentage { percent: u8 }, } }
Any requires any single holder of the required capability. Unanimous requires all holders to approve. Threshold requires k-of-n approval. Percentage requires a percentage of holders.
4. Category C: Consensus-Gated Operations
Category C operations do NOT proceed until a ceremony completes. Partial state would be dangerous or irrecoverable. The user must wait for confirmation. These operations use choreographic protocols with session types, executed through Aura’s Telltale runtime.
4.1 Examples
| Operation | Why Blocking Required | Risk if Optimistic |
|---|---|---|
| Add contact (new relationship) | Creates cryptographic context | No shared keys possible |
| Create group | Multi-party key agreement | Inconsistent member views |
| Add member to group | Changes group keys | Forward secrecy violation |
| Device enrollment | Key shares distributed atomically | Partial enrollment unusable |
| Guardian rotation | Key shares distributed atomically | Partial rotation unusable |
| Recovery execution | Account state replacement | Partial recovery corruption |
| OTA hard fork | Scope-bound breaking protocol change | Explicit partition or rejected incompatible sessions outside the cutover scope |
| Device revocation | Security-critical removal | Attacker acts first |
4.2 Implementation Pattern
#![allow(unused)] fn main() { async fn add_contact(&mut self, invitation: Invitation) -> Result<ContactId> { let ceremony_id = self.ceremony_executor .initiate_invitation_ceremony(invitation) .await?; loop { match self.ceremony_executor.get_status(&ceremony_id)? { CeremonyStatus::Committed => { return Ok(ContactId::from_ceremony(&ceremony_id)); } CeremonyStatus::Aborted { reason } => { return Err(AuraError::ceremony_failed(reason)); } _ => { tokio::time::sleep(POLL_INTERVAL).await; } } } } }
This pattern blocks until the ceremony completes. The user sees progress UI during execution. Context is established only on successful commit.
5. Ceremony Contract
All Category C ceremonies follow a shared contract that ensures atomic commit/abort semantics.
5.1 Ceremony Phases
-
Compute prestate: Derive a stable prestate hash from the authority/context state being modified. Include the current epoch and effective participant set.
-
Propose operation: Define the operation being performed. Compute an operation hash bound to the proposal parameters.
-
Enter pending epoch: Generate new key material at a pending epoch without invalidating the old epoch. Store metadata for commit or rollback.
-
Collect responses: Send invitations/requests to participants. Participants respond using their full runtimes. Responses must be authenticated and recorded as facts.
-
Commit or abort: If acceptance/threshold conditions are met, commit the pending epoch and emit resulting facts. Otherwise abort, emit an abort fact with a reason, and leave the prior epoch active.
5.2 Ceremony Properties
All Category C ceremonies implement:
-
Prestate Binding:
CeremonyId = H(prestate_hash, operation_hash, nonce)prevents concurrent ceremonies on same state and ensures exactly-once semantics. -
Atomic Commit/Abort: Either fully committed or no effect. No partial state possible.
-
Epoch Isolation: Uncommitted key packages are inert. No explicit rollback needed on abort.
-
Session Types: Protocol compliance enforced at compile time via choreographic projection and enforced at runtime via Telltale adapter/VM execution.
5.3 Per-Ceremony Policy Matrix
Authority and Device Ceremonies
| Ceremony | Key Gen | Agreement | Fallback | Notes |
|---|---|---|---|---|
| Authority bootstrap | K1 | A3 | None | Local, immediate |
| Device enrollment | K2 | A1→A2→A3 | A1/A2 | Provisional → soft-safe → finalize |
| Device MFA rotation | K3 | A2→A3 | A2 | Consensus-finalized keys |
| Device removal | K3 | A2→A3 | A2 | Remove via rotation |
Guardian Ceremonies
| Ceremony | Key Gen | Agreement | Fallback | Notes |
|---|---|---|---|---|
| Guardian setup/rotation | K3 | A2→A3 | A2 | Consensus-finalized for durability |
| Recovery approval | A2→A3 | A2 | Soft-safe approvals → consensus | |
| Recovery execution | A2→A3 | A2 | Consensus-finalized commit |
Channel and Group Ceremonies
| Ceremony | Key Gen | Agreement | Fallback | Notes |
|---|---|---|---|---|
| AMP channel epoch bump | A1→A2→A3 | A1/A2 | Proposed → cert → commit | |
| AMP channel bootstrap | A1→A2→A3 | A1/A2 | Provisional → group key rotation | |
| Group/Block creation | K3 | A1→A2→A3 | A1/A2 | Provisional bootstrap → consensus |
| Rendezvous secure-channel | A1→A2→A3 | A1/A2 | Provisional → consensus |
Other Ceremonies
| Ceremony | Key Gen | Agreement | Fallback | Notes |
|---|---|---|---|---|
| Invitation (contact/channel/guardian) | A3 | None | Consensus-finalized only | |
| OTA activation | A2→A3 | A2 | Threshold-signed → consensus | |
| DKD ceremony | DKD | A2→A3 | A2 | Multi-party derivation → commit |
5.4 Bootstrap Exception
When creating a new group/channel before the group key ceremony completes, Aura allows a bootstrap epoch using a trusted-dealer key (K2/A1). The dealer distributes a bootstrap key with the channel invite, enabling immediate encrypted messaging. This is explicitly provisional and superseded by the consensus-finalized group key (K3/A3) once the ceremony completes.
5.5 AMP Channel Epoch Transition Refinement
AMP channel epoch transitions use the existing A1 -> A2 -> A3 agreement ladder with an AMP-specific live-state rule. This rule applies only to AMP channel epoch and membership state inside a relational context. It does not weaken authority-root membership, account commitment trees, guardian rotation, or recovery execution.
For a channel transition:
A1 observedmeans a syntactically valid successor proposal exists as a journal fact, but it has no live operational authority.A2Livemeans exactly one unsuppressed AMP-certified successor exists for the parent epoch and deterministic reduction exposes that successor as the live epoch for AMP send and receive policy.A3Finalizedmeans consensus-backed commit facts durably finalize a successor. The normal path finalizes the sametransition_idpreviously exposed asA2Live.
A2Live is operationally authoritative but non-durable. It may drive live AMP traffic before full A3 finalization, but durable shared state still requires the A3 consensus boundary described in Consensus.
Every AMP transition fact binds a canonical transition_id, a typed digest over:
context_idchannel_idparent_epochparent_commitmentsuccessor_epochsuccessor_commitmentmembership_commitmenttransition_policy
Proposals, A2 certificates, A3 commits, aborts, conflicts, and supersessions refer to the same transition only when this full identity matches. A different successor for the same parent is a conflicting transition.
The reducer states for a parent transition group are:
| State | Meaning |
|---|---|
Observed | Proposal facts exist, but no live certificate is valid. |
A2Live | Exactly one valid unsuppressed AMP certificate selects a successor. |
A2Conflict | Conflicting valid certificates or unresolved equivocation evidence suppress live exposure. |
A3Finalized | Consensus-backed commit finalizes one successor. |
A3Conflict | Conflicting durable commit evidence suppresses live exposure. |
Aborted | Explicit abort evidence invalidates the proposal for live use. |
Superseded | Authorized supersession replaces an earlier transition path. |
The reducer must never choose between conflicting valid A2 certificates by arrival order, local preference, wall-clock time, or deterministic tie-breaking. If facts do not prove a single winner, no live successor is exposed.
AMP transition policies distinguish additive and non-removal transitions from subtractive, removal, revocation, and emergency transitions. Additive transitions may permit bounded dual-epoch receive overlap. Subtractive and emergency transitions require stricter old-epoch acceptance so removed or suspected participants do not retain indefinite send authority.
Emergency AMP transitions are channel-scoped control-plane transitions:
EmergencyQuarantineTransitionexcludes a suspect from the successor epoch, cuts new sends over immediately, minimizes old-epoch receive grace, and rotates or erases old secret material aggressively.EmergencyCryptoshredTransitionuses the strongest channel-scoped bar and destroys ordinary pre-emergency readable state at theA2Livecutover boundary.
Emergency channel facts do not automatically remove authority-root membership or suspend recovery/governance rights. Those require separate authority-scoped governance facts and their own thresholds.
6. Consistency Metadata
Each operation category has a purpose-built status type for tracking consistency.
6.1 Core Types
#![allow(unused)] fn main() { pub enum Agreement { Provisional, SoftSafe { cert: Option<ConvergenceCert> }, Finalized { consensus_id: ConsensusId }, } pub enum Propagation { Local, Syncing { peers_reached: u16, peers_known: u16 }, Complete, Failed { retry_at: PhysicalTime, retry_count: u32, error: String }, } pub struct Acknowledgment { pub acked_by: Vec<AckRecord>, } }
Agreement indicates the finalization level (A1/A2/A3). Propagation tracks anti-entropy sync status. Acknowledgment tracks explicit per-peer delivery confirmation.
6.2 Category A: OptimisticStatus
#![allow(unused)] fn main() { pub struct OptimisticStatus { pub agreement: Agreement, pub propagation: Propagation, pub acknowledgment: Option<Acknowledgment>, } }
Use cases include send message, create channel, update profile, and react to message.
UI patterns:
◐Sending: propagation == Local✓Sent: propagation == Complete✓✓Delivered: acknowledgment.count() >= expected.len()◆Finalized: agreement == Finalized
6.3 Category B: DeferredStatus
#![allow(unused)] fn main() { pub struct DeferredStatus { pub proposal_id: ProposalId, pub state: ProposalState, pub approvals: ApprovalProgress, pub applied_agreement: Option<Agreement>, pub expires_at: PhysicalTime, } pub enum ProposalState { Pending, Approved, Rejected { reason: String, by: AuthorityId }, Expired, Superseded { by: ProposalId }, } }
Use cases include change permissions, remove member, transfer ownership, and archive channel.
6.4 Category C: CeremonyStatus
#![allow(unused)] fn main() { pub struct CeremonyStatus { pub ceremony_id: CeremonyId, pub state: CeremonyState, pub responses: Vec<ParticipantResponse>, pub prestate_hash: Hash32, pub committed_agreement: Option<Agreement>, } pub enum CeremonyState { Preparing, PendingEpoch { pending_epoch: Epoch, required_responses: u16, received_responses: u16 }, Committing, Committed { consensus_id: ConsensusId, committed_at: PhysicalTime }, Aborted { reason: CeremonyFailureReason, aborted_at: PhysicalTime }, Superseded { by: CeremonyId, reason: SupersessionReason }, } pub enum CeremonyFailureReason { Rejected, Cancelled, TimedOut, ChoreographyFailed, RuntimeFailed, Superseded, } }
Use cases include add contact, create group, guardian rotation, device enrollment, and recovery.
When a ceremony commits successfully, committed_agreement is set to Agreement::Finalized with the consensus ID, indicating A3 durability.
An issued invitation or enrollment code is the terminal result of code issuance, not the terminal result of the ceremony it starts. Enrollment completion has a separate operation instance linked to the ceremony ID. The initiator and invitee derive completion from the same authoritative ceremony outcome. A completion instance has exactly one terminal result: committed, cancelled, rejected, or timed out. The first terminal result is stable under duplicate, late, and replayed messages; a conflicting later result cannot replace it. Failure and cancellation carry stable, typed reasons independently of display text. An unauthenticated response cannot terminate a valid ceremony.
An enrollment request must match the issued invitation's subject authority, invitation, ceremony, target device and pending epoch. Successful confirmation must identify that same invitation and ceremony, explicitly establish enrollment, and carry the expected resulting epoch. A mismatch is a typed failure rather than an observation of completion. Matching message contents alone does not establish authentication or commit provenance.
Enrollment setup statements bind the exporting authority, physical device, request nonce, bounded validity interval, signing epoch, signing mode, threshold policy and public key package in a dedicated canonical signing transcript. Possession verification requires the proof's epoch and package to match that statement and produces sealed, non-deserializable evidence. This evidence certifies possession of the embedded key only. Association with the intended physical device requires explicit user transfer or an independently authenticated binding; decoding or self-certification cannot establish that association.
The initiator retains the selected setup statement and digest with its subject, ceremony, pending epoch and physical initiator before admitting response owners. Enrollment acceptance requires proof under that retained provisional package, epoch, mode and signer policy. A missing verifier record, unknown record version, corrupt binding or response-supplied substitute key cannot count a participant. The setup expiry gates issuance; an admitted response remains subject to the invitation and ceremony deadline. Persisted verifier selection alone does not prove baseline authentication, authenticated refusal, nonce consumption, first-decision persistence or atomic activation.
Issuance reserves its invitation identity before fact preparation or delivery. The reservation has one physical issuer and is consumed by the preparation owner. The complete signed payload binds that identity before publication; later payload repair cannot change an already committed invitation. Invalid or overflowing expiration fails before preparation mutates authoritative state.
A signed setup admission includes the setup nonce/digest, both device identities, subject and provisional authority, invitation/ceremony, pending epoch, manifest digest and exact-parent verifier inventory digest. Its expected verification key comes from the independently pinned manifest inventory at the exact prestate; the pending enrollment package and the receipt's embedded key are insufficient. Signature-only evidence remains separate from authenticated admission provenance. An invitee response owner requires that provenance and locally owned admission and revocation state before selecting a retained historical signing share.
6.5 Unified Consistency Type
For cross-category queries and generic handling:
#![allow(unused)] fn main() { pub struct Consistency { pub category: OperationCategory, pub agreement: Agreement, pub propagation: Propagation, pub acknowledgment: Option<Acknowledgment>, } pub enum OperationCategory { Optimistic, Deferred { proposal_id: ProposalId }, Ceremony { ceremony_id: CeremonyId }, } }
7. Ceremony Supersession
When a new ceremony replaces an old one, Aura emits explicit supersession facts that propagate via anti-entropy.
7.1 Supersession Reasons
#![allow(unused)] fn main() { pub enum SupersessionReason { PrestateStale, NewerRequest, ExplicitCancel, Timeout, Precedence, } }
PrestateStale indicates the prestate changed while the ceremony was pending. NewerRequest indicates an explicit newer request from the same initiator. ExplicitCancel indicates manual cancellation by an authorized participant. Timeout indicates the ceremony exceeded its validity window. Precedence indicates a concurrent ceremony won via conflict resolution.
7.2 Supersession Facts
Each ceremony fact enum includes a CeremonySuperseded variant:
#![allow(unused)] fn main() { CeremonySuperseded { superseded_ceremony_id: String, superseding_ceremony_id: String, reason: String, trace_id: Option<String>, timestamp_ms: u64, } }
7.3 CeremonyTracker API
The CeremonyTracker in aura-agent maintains supersession records for auditability:
| Method | Purpose |
|---|---|
supersede(old_id, new_id, reason) | Record a supersession event |
check_supersession_candidates(prestate_hash, op_type) | Find stale ceremonies |
get_supersession_chain(ceremony_id) | Get full supersession history |
is_superseded(ceremony_id) | Check if ceremony was replaced |
Supersession facts propagate via the existing anti-entropy mechanism. Peers receiving a CeremonySuperseded fact update their local ceremony state accordingly.
8. Decision Tree
Use this tree to categorize new operations:
Does this operation establish or modify cryptographic relationships?
│
├─ YES: Does the user need to wait for completion?
│ │
│ ├─ YES (new context, key changes) → Category C (Blocking Ceremony)
│ │ Examples: add contact, create group, guardian rotation
│ │
│ └─ NO (removal from existing context) → Category B (Deferred)
│ Examples: remove from group (epoch rotation in background)
│
└─ NO: Does this affect other users' access or policies?
│
├─ YES: Is this high-security or irreversible?
│ │
│ ├─ YES → Category B (Deferred)
│ │ Examples: transfer ownership, delete channel, kick member
│ │
│ └─ NO → Category A (Optimistic)
│ Examples: pin message, update topic
│
└─ NO → Category A (Optimistic)
Examples: send message, create channel, block contact
9. UI Feedback Patterns
9.1 Category A: Instant Result with Sync Indicator
┌───────────────────────────────────┐
│ You: Hello everyone! ◆ ✓✓ │ ← Finalized + Delivered
│ You: Check this out ✓✓ │ ← Delivered (not yet finalized)
│ You: Another thought ✓ │ ← Sent
│ You: New idea ◐ │ ← Sending
└───────────────────────────────────┘
Effect already applied. Indicators show delivery status (◐ → ✓ → ✓✓ → ✓✓ blue) and finalization (◆ appears when A3 consensus achieved).
9.2 Category B: Pending Indicator
┌─────────────────────────────────────────────────────────────────────┐
│ Channel: #project │
├─────────────────────────────────────────────────────────────────────┤
│ Pending: Remove Carol (waiting for Bob to confirm) │
├─────────────────────────────────────────────────────────────────────┤
│ Members: │
│ Alice (moderator) ✓ │
│ Bob (moderator) ✓ │
│ Carol ✓ ← Still has access until confirmed │
└─────────────────────────────────────────────────────────────────────┘
Proposal shown. Effect NOT applied yet.
9.3 Category C: Blocking Wait
┌─────────────────────────────────────────────────────────────────────┐
│ Adding Bob to group... │
│ │
│ ✓ Invitation sent │
│ ✓ Bob accepted │
│ ◐ Deriving group keys... │
│ ○ Ready │
│ │
│ [Cancel] │
└─────────────────────────────────────────────────────────────────────┘
User waits. Cannot proceed until ceremony completes.
10. Effect Policy Configuration
Operations use configurable policies that reference the capability system:
#![allow(unused)] fn main() { pub struct EffectPolicy { pub operation: OperationType, pub timing: EffectTiming, pub security_level: SecurityLevel, } pub enum EffectTiming { Immediate, Deferred { requires_approval_from: Vec<CapabilityRequirement>, timeout_ms: u64, threshold: ApprovalThreshold, }, Blocking { ceremony: CeremonyType, }, } }
10.1 Context-Specific Overrides
Contexts can override default policies:
#![allow(unused)] fn main() { // Strict security channel: unanimous moderator approval for kicks channel.set_effect_policy(RemoveFromChannel, EffectTiming::Deferred { requires_approval_from: vec![CapabilityRequirement::Role("moderator")], timeout_ms: 48 * 60 * 60 * 1000, threshold: ApprovalThreshold::Unanimous, }); // Casual channel: any moderator can kick immediately channel.set_effect_policy(RemoveFromChannel, EffectTiming::Immediate); }
11. Full Operation Matrix
| Operation | Category | Effect Timing | Security | Notes |
|---|---|---|---|---|
| Within Established Context | ||||
| Send message | A | Immediate | Low | Keys already derived |
| Create channel | A | Immediate | Low | Just facts into context |
| Update topic | A | Immediate | Low | CRDT, last-write-wins |
| React to message | A | Immediate | Low | Local expression |
| Local Authority | ||||
| Block contact | A | Immediate | Low | Your decision |
| Mute channel | A | Immediate | Low | Local preference |
| Policy Changes | ||||
| Change permissions | B | Deferred | Medium | Others affected |
| Kick from channel | B | Deferred | Medium | Affects access |
| Archive channel | B | Deferred | Low-Med | Reversible |
| High Risk | ||||
| Transfer ownership | B | Deferred | High | Irreversible |
| Delete channel | B | Deferred | High | Data loss |
| Remove from context | B | Deferred | High | Affects encryption |
| Cryptographic | ||||
| Add contact | C | Blocking | Critical | Creates context |
| Create group | C | Blocking | Critical | Multi-party keys |
| Add group member | C | Blocking | Critical | Changes group keys |
| Device enrollment | C | Blocking | Critical | DeviceEnrollment choreography |
| Guardian rotation | C | Blocking | Critical | Key shares |
| Recovery execution | C | Blocking | Critical | Account state |
| Device revocation | C | Blocking | Critical | Security response |
12. Common Mistakes to Avoid
Mistake 1: Making Everything Category C
Wrong: "Adding a channel member requires ceremony"
Right: If the member is already in the relational context, it is Category A. Just emit a fact. Only if they need to join the context first is it Category C.
Mistake 2: Forgetting Context Existence
Wrong: Trying to create a channel before establishing relationship
Right: Contact invitation (Category C) must complete before any channel operations (Category A) are possible.
Mistake 3: Optimistic Key Operations
Wrong: "User can start using new guardians while ceremony runs"
Right: Guardian changes affect key shares. Partial state means unusable keys. Must be Category C.
Mistake 4: Blocking on Low-Risk Operations
Wrong: "Wait for all members to confirm before showing channel"
Right: Channel creation is optimistic. Show immediately, sync status later.
See Also
- Consensus for fast path and fallback consensus
- Journal for fact semantics and reduction flows
- Aura Messaging Protocol (AMP) for channel encryption and key derivation
- Relational Contexts for context vs channel distinction
- MPST and Choreography for session types in Category C
- Transport and Information Flow for sync status tracking
- Effect System for effect policies
Enrollment manifest ownership
Exporting setup or manifest transfer material is read-only with respect to enrollment business state. Invitation reservation and pending generation ownership precede key writes; signed manifest retention precedes invitation publication. Import admission requires the app-issued explicit transfer selection and produces a runtime-private, non-deserializable witness. The bootstrap session consumes that witness without changing global transport identity or durable membership. Enrollment acceptance and activation require their separate verified response and registered generation permissions.
The app owns the complete manifest-pin, import, acceptance, and convergence lifecycle under one ImportDeviceEnrollmentCode operation. Frontends transfer submission ownership before the first awaited workflow step. Missing transfer input is a typed terminal failure before import mutation. Browser persistence consumes only the app-issued completed enrollment result after acceptance and adoption; received authority/device identifiers cannot stage that result.
Enrollment invitee adoption is the application of an authenticated committed ceremony result. Its local persistence and signing-context activation consume runtime-owned durable confirmation evidence for the exact imported generation. They are not independent agreement operations, and local accepted status or receipt locator fields do not authorize adoption. Generic key-rotation commit is not an alternate enrollment activation path.
Enrollment initiation under an active quorum
Preparing an enrollment signing intent retains the original issuer allocation and establishes neither enrollment success nor local signing consent. Each active physical participant independently approves the exact manifest, public transport commitment, initial Request, issuer return mailbox statement and finite negative terminal policy under its current authenticated policy. Resuming that allocation may produce a pending enrollment code only after the four initiation signatures verify. The policy is conditional consent, not a fifth initiation signature. A later Failed control also requires the original protected first negative decision and retained participant custody. Committed control, durable membership and invitee activation retain their separate agreement and evidence requirements.