Part 07 — Capability Negotiation Architecture

Reusable P2P Communication Platform

Status: Architecture specification
Part: 07 of 24
Primary language: Rust
Primary goals: safe protocol compatibility, feature discovery, version negotiation, transport/media/file/DTN capability exchange, downgrade resistance, efficient session setup, cross-platform interoperability, reusable across messaging/files/calls/emergency/ERP/custom products


1. Purpose

A reusable communication platform cannot assume every peer has the same:

  • application version
  • protocol version
  • transport support
  • media codecs
  • hardware capabilities
  • file-transfer features
  • DTN features
  • storage limits
  • background capabilities
  • security algorithms
  • device class
  • platform restrictions

Two peers must first answer:

What do you support?
What do I support?
What is mutually usable?
What is required?
What must be rejected?
What may safely degrade?

This is the responsibility of the capability negotiation subsystem.

Its purpose is to create a verified, bounded, versioned capability contract for every authenticated session and every reusable extension.


2. Fundamental Rule

Do not use:

if app_version >= X

as a substitute for capability negotiation.

Do not infer:

Android = H.264
Desktop = AV1 software
Iroh = files

Instead:

Authenticated Peer
      ↓
Capability Advertisement
      ↓
Version / Policy Filtering
      ↓
Mutual Capability Set
      ↓
Per-Extension Negotiation
      ↓
Session Capability Contract

The rest of the platform consumes the negotiated result.


3. Architectural Position

Transport Connected
      ↓
Identity Authentication
      ↓
Core Protocol Handshake
      ↓
Capability Negotiation
      ↓
Extension Activation
      ↓
Messaging / Files / Calls / DTN / Custom

Capability negotiation depends on:

Part 01 — Protocol Extension System
Part 02 — Multi-Device Identity

and feeds:

Part 03 — Routing
Part 05 — Files
Part 06 — DTN
media/calls
UI

4. Capability Categories

Capabilities should be grouped into domains.

Recommended categories:

Core Protocol
Security
Transport
Messaging
Files
Groups
Presence
DTN
Media
Platform
Device Resources
Application Extensions

Do not create one unstructured giant map.


5. Capability Identifier

Use stable typed IDs.

#![allow(unused)]
fn main() {
pub struct CapabilityId {
    pub namespace: CapabilityNamespace,
    pub code: u32,
}
}

Example canonical names:

core.protocol.v1
files.resume
files.parallel_chunks
dtn.spray_wait
media.video.av1.software
media.video.h264.hardware
platform.wifi_aware

Wire representation can be compact numeric IDs after namespace agreement.


6. Capability Namespace

#![allow(unused)]
fn main() {
pub enum CapabilityNamespace {
    Core,
    Security,
    Transport,
    Messaging,
    Files,
    Groups,
    Presence,
    Dtn,
    Media,
    Platform,
    Resource,
    Application(NamespaceId),
}
}

This prevents collisions and supports third-party extensions.


7. Capability Descriptor

#![allow(unused)]
fn main() {
pub struct CapabilityDescriptor {
    pub id: CapabilityId,
    pub version: CapabilityVersion,
    pub requirement: CapabilityRequirement,
    pub parameters: CapabilityParameters,
    pub stability: CapabilityStability,
}
}

8. Required vs Optional

#![allow(unused)]
fn main() {
pub enum CapabilityRequirement {
    Required,
    Optional,
}
}

Required means:

this operation/extension cannot work safely without it

Optional means:

use if mutually supported

Unknown required capability:

negotiation failure

Unknown optional capability:

ignore safely

9. Capability Versioning

A capability may have its own version:

#![allow(unused)]
fn main() {
pub struct CapabilityVersion {
    pub major: u16,
    pub minor: u16,
}
}

Do not make all feature evolution depend only on application version.


10. Protocol Version vs Capability Version

Separate:

files/1 protocol

from:

files.resume capability v2

This lets a stable protocol major gain backward-compatible features.


11. Parameterized Capabilities

Some capabilities need parameters.

Example:

files.max_chunk_size = 4 MiB
files.max_parallel = 8
media.max_video_width = 3840
dtn.max_bundle_size = 1 MiB

Use typed bounded parameter structures.

Do not use:

HashMap<String, String>

for core behavior.


12. Capability Parameters

Conceptually:

#![allow(unused)]
fn main() {
pub enum CapabilityParameters {
    None,
    U32(u32),
    U64(u64),
    RangeU32 { min: u32, max: u32 },
    BitSet(CapabilityBits),
    Bytes(BoundedBytes),
}
}

Prefer domain-specific structs for complex capability groups.


13. Capability Advertisement

Each peer sends an authenticated advertisement.

#![allow(unused)]
fn main() {
pub struct CapabilityAdvertisement {
    pub device_id: DeviceId,
    pub account_generation: u64,
    pub core_protocols: Vec<ProtocolSupport>,
    pub extensions: Vec<ExtensionCapabilitySet>,
    pub security: SecurityCapabilities,
    pub transport: TransportCapabilitiesSummary,
    pub platform: PlatformCapabilitiesSummary,
    pub resources: ResourceCapabilities,
    pub issued_at: Timestamp,
    pub nonce: HandshakeNonce,
}
}

The advertisement is bound to the authenticated session transcript.


14. Authentication Binding

Capabilities must not be accepted before peer identity is authenticated.

Otherwise attacker could advertise:

fake codec
fake protocol
fake relay
fake device features

Handshake binding should include:

peer identity
session transcript
capability advertisement hash

15. Replay Resistance

Capability advertisements must be freshness-bound.

Use:

session nonce
transcript hash
short lifetime

Do not accept old signed capability sets as current runtime truth.


16. Device Certificate vs Runtime Capability

Part 02 device certificate may contain durable capability classes.

Example:

headless
relay
link authority

Runtime negotiation contains ephemeral/current capabilities:

Wi-Fi enabled
AV1 encoder currently available
storage quota
battery policy

Do not confuse them.


17. Durable vs Ephemeral Capabilities

#![allow(unused)]
fn main() {
pub enum CapabilityLifetime {
    IdentityBound,
    SessionBound,
    Dynamic,
}
}

Examples:

Device role → IdentityBound
files.resume support → SessionBound
battery available → Dynamic
Wi-Fi enabled → Dynamic

18. Negotiation Output

#![allow(unused)]
fn main() {
pub struct NegotiatedCapabilities {
    pub core: NegotiatedCore,
    pub extensions: HashMap<ProtocolId, NegotiatedExtensionCapabilities>,
    pub security: NegotiatedSecurity,
    pub transport: NegotiatedTransportHints,
    pub media: NegotiatedMedia,
    pub limits: NegotiatedLimits,
}
}

This object is immutable for the session generation.

Dynamic changes create updates/versioned snapshots.


19. Intersection Rule

For simple Boolean capabilities:

negotiated = local ∩ remote

For ranges:

negotiated range = overlap(local, remote)

For maximum limits:

effective max = min(local_max, remote_max, policy_max)

For security:

effective = strongest mutually supported and locally permitted

Do not always use simple intersection.


20. Policy Filter

Negotiation is:

local support
∩
remote support
∩
local security policy
∩
application policy
∩
runtime platform availability

A capability can be supported by code but disabled by policy.


21. Hard Policy

Examples:

minimum protocol version
disallow insecure algorithm
forbid public relay
max accepted file size

Hard policy cannot be overridden by peer advertisement.


22. User Policy

Examples:

disable read receipts
disable nearby forwarding
disable mobile-data files
disable H.265 due compatibility concerns

User policy changes effective capabilities.


23. Application Policy

ERP example:

files required
DTN disabled
messaging optional

Emergency app:

DTN required
nearby required where platform supports

24. Negotiation State Machine

TransportConnected
       ↓
IdentityAuthenticated
       ↓
CapabilitiesOffered
       ↓
CapabilitiesReceived
       ↓
Validate
       ↓
Intersect
       ↓
PolicyFilter
       ↓
RequiredCheck
       ↓
Confirmed
       ↓
Active

Failure states:

VersionMismatch
RequiredCapabilityMissing
SecurityPolicyFailure
MalformedAdvertisement
DowngradeDetected

25. Two-Phase Confirmation

For security-sensitive negotiations:

Offer
 ↓
Selection
 ↓
Confirmation hash

Both peers confirm the same negotiated capability set.

This prevents ambiguity.


26. Negotiation Transcript Hash

Canonical encode:

local advertisement
remote advertisement
selected capabilities
session nonce

Then derive:

NegotiationHash

Both peers verify equality.


27. Canonical Encoding

Capability ordering must be canonical before hashing.

Example:

sort by namespace + code + version

Do not hash arbitrary HashMap iteration order.


28. Downgrade Attacks

An attacker may attempt to remove strong features from negotiation.

Example:

both peers support strong algorithm
attacker forces weaker

Mitigations:

  • authenticated transcript
  • minimum local policy
  • remembered peer security baseline where appropriate
  • explicit downgrade detection

29. Security Capability Negotiation

Examples:

signature schemes
AEAD schemes
KDF versions
session protocol versions
group security versions

Security selection must use:

strongest mutually supported
+
locally allowed

not peer-preferred order alone.


30. Algorithm Agility

Represent algorithms by IDs.

#![allow(unused)]
fn main() {
pub struct AlgorithmId(u16);
}

Do not bake algorithm names into every public type if future migration matters.


31. Minimum Security Floor

Local policy:

MinimumSecurityProfile::Modern

can reject older capability sets.

Backward compatibility must never override unacceptable security.


32. Remembered Security Baseline

For previously verified contacts, optionally remember:

highest previously observed security generation

If a future session unexpectedly drops below it:

DowngradeSuspected

Do not auto-reject all capability loss; device/platform changes can be legitimate.

Use policy.


33. Extension Capability Negotiation

Each protocol extension from Part 01 owns its capability schema.

Example:

messaging/1
  text
  reply
  edit
  reactions
  read_receipts

Negotiation should be delegated to extension-specific logic.


34. Extension Negotiator Trait

#![allow(unused)]
fn main() {
pub trait ExtensionNegotiator {
    fn advertise(&self) -> ExtensionCapabilitySet;

    fn negotiate(
        &self,
        remote: &ExtensionCapabilitySet,
        policy: &CapabilityPolicy,
    ) -> Result<NegotiatedExtensionCapabilities, CapabilityError>;
}
}

35. File Capabilities

Example:

files/1
├── fixed_chunking
├── resume
├── parallel_chunks
├── ciphertext_addressing
├── partial_read
├── multi_source
└── max_chunk_size

Part 05 consumes the negotiated set.


36. File Limit Negotiation

Sender:

max chunk = 4 MiB

Receiver:

max chunk = 1 MiB

Effective:

1 MiB

Local policy may reduce further.


37. DTN Capabilities

Example:

dtn/1
├── direct_only
├── relay_ack
├── spray_wait
├── gateway_handoff
├── blob_chunk
├── local_broadcast
└── max_bundle_size

Part 06 uses only negotiated features.


38. Transport Capabilities

Transport-level:

reliable_stream
datagram
local_discovery
relay
multipath
store_and_forward

These describe current session/adapter abilities.

Routing uses them.


39. Platform Capabilities

Examples:

Bluetooth LE
Bluetooth Classic
Wi-Fi Direct
Wi-Fi Aware
background nearby
hardware secure store
camera
microphone
PiP

Do not expose raw Android/iOS API details to upper layers.


40. Media Capabilities

For calls:

Audio:
  Opus

Video:
  AV1 software
  AV1 hardware
  H.264 hardware
  H.265 hardware

Also parameters:

encode
decode
max resolution
max fps
bit depth
hardware/software

41. Media Capability Type

#![allow(unused)]
fn main() {
pub struct VideoCodecCapability {
    pub codec: VideoCodec,
    pub direction: CodecDirection,
    pub implementation: CodecImplementation,
    pub max_width: u32,
    pub max_height: u32,
    pub max_fps: u16,
    pub profiles: CodecProfileSet,
}
}

42. Codec Selection

Selection policy may prioritize:

compatibility
hardware efficiency
quality
battery
CPU

Example Android:

AV1 HW if both support and efficient
else H.265 if policy allows
else H.264

Desktop software-only policy may differ.


43. Codec Negotiation Is Not Routing

Capability negotiation decides:

what can be encoded/decoded

Routing decides:

which network path carries media

Keep them separate.


44. Codec Runtime Failure

A capability can be negotiated but fail at runtime.

Example:

broken vendor MediaCodec

Media subsystem reports:

capability degraded

and renegotiates or falls back.

Capability advertisement is not an infallible guarantee.


45. Dynamic Capability Update

Support runtime update:

camera permission revoked
Bluetooth disabled
Wi-Fi becomes available
hardware codec unavailable due thermal issue

Do not restart whole identity session unnecessarily.


46. Capability Epoch

#![allow(unused)]
fn main() {
pub struct CapabilityEpoch(u64);
}

Every dynamic capability update increments local epoch.

Peer can detect stale updates.


47. Capability Update Message

#![allow(unused)]
fn main() {
pub struct CapabilityUpdate {
    pub epoch: CapabilityEpoch,
    pub changed: Vec<CapabilityDelta>,
    pub transcript_binding: SessionBinding,
}
}

Keep updates bounded.


48. Full Snapshot vs Delta

Initial handshake:

full capability snapshot

Runtime:

delta

If peer detects missed delta:

request full snapshot

49. Capability Cache

Cache negotiated peer capabilities for UX/performance hints.

Store:

peer/device
capability set hash
observed_at
session generation

But cache is not authoritative for new sessions.


50. Cache Uses

Useful for:

  • pre-disable unsupported UI actions
  • estimate route options
  • avoid unnecessary offers
  • prepare call UI

Always revalidate on authenticated session.


51. Capability Staleness

Cached capability should have:

fresh
stale
unknown

Do not present stale support as guaranteed.


52. Peer Upgrade

If peer upgrades:

new capability epoch

future sessions negotiate more features automatically.

No central server migration required.


53. Peer Downgrade

If peer intentionally disables feature:

capability disappears

Application should degrade gracefully.

Example:

edit no longer supported

Disable edit UI for that peer/session.


54. Required Capability per Operation

Even inside active session, an operation may require capability.

Example:

send edited message
requires messaging.edit

Before send:

check negotiated capability

Do not assume extension presence implies every feature.


55. Operation Capability Requirement

#![allow(unused)]
fn main() {
pub struct OperationCapabilityRequirement {
    pub extension: ProtocolId,
    pub required: CapabilitySet,
}
}

Routing/application validates before work begins.


56. Capability-Based UI

UI consumes a simplified view model:

CanSendFiles
CanVideoCall
CanUseNearby
CanResumeTransfer

It should not parse raw protocol capabilities.


57. UI Capability Adapter

#![allow(unused)]
fn main() {
pub struct UiCapabilities {
    pub can_message: bool,
    pub can_send_file: bool,
    pub can_audio_call: bool,
    pub can_video_call: bool,
    pub can_dtn: bool,
}
}

Derived from negotiated capability state.


58. Unknown UI Capability

If peer state unknown:

action may remain available

and negotiation can happen on demand.

Do not over-disable based on stale cache.


59. Lazy Extension Negotiation

Some heavy extensions can negotiate only when needed.

Example:

calls

Core session advertises:

calls extension supported

Detailed codec negotiation occurs when call starts.


60. Hierarchical Negotiation

Recommended:

Core session
 ↓
extension support
 ↓
feature subset
 ↓
operation-specific parameters

Do not send huge codec/file capability payload on every connection if unused.


61. Capability Advertisement Size

Bound:

max capabilities
max parameters
max bytes

A peer must not force huge negotiation payloads.


62. Compact Encoding

Use numeric IDs and bitsets for common capabilities.

Example:

MessagingCapabilityBits
FilesCapabilityBits

This reduces handshake size.


63. Bitset Evolution

Reserve bits carefully.

Unknown bits:

ignored if optional

Do not reuse removed bits.


64. Sparse Custom Capabilities

Third-party/custom extensions may use:

bounded sorted vector of IDs

rather than allocating giant bitsets.


65. Capability Registry

Maintain registry:

#![allow(unused)]
fn main() {
pub struct CapabilityRegistry {
    descriptors: HashMap<CapabilityId, CapabilityDefinition>,
}
}

The registry provides:

  • canonical names
  • validation
  • version semantics
  • parameter codec
  • security classification

No global singleton required.


66. Capability Definition

#![allow(unused)]
fn main() {
pub struct CapabilityDefinition {
    pub id: CapabilityId,
    pub name: &'static str,
    pub max_version: CapabilityVersion,
    pub parameter_schema: ParameterSchema,
    pub security_class: SecurityClass,
}
}

67. Security Class

#![allow(unused)]
fn main() {
pub enum SecurityClass {
    Informational,
    Functional,
    SecuritySensitive,
    Critical,
}
}

Unknown critical capability behavior should be conservative.


68. Mandatory Unknown Critical Capability

If remote marks:

unknown critical capability required

reject that extension/session operation.

Never silently ignore.


69. Capability Dependency

Some capabilities depend on others.

Example:

files.parallel_chunks
requires files.chunking

Model:

#![allow(unused)]
fn main() {
pub struct CapabilityDependency {
    pub capability: CapabilityId,
    pub requires: CapabilitySet,
}
}

Validation must reject inconsistent advertisement.


70. Capability Conflict

Some are mutually exclusive.

Example:

compression mode A
compression mode B

Negotiator selects one or fails according to rules.


71. Preference Ordering

For selectable modes:

local preference
remote support
policy

Example codec preference.

Do not let peer alone choose mode.


72. Negotiation Determinism

Given same:

local set
remote set
policy

both peers should derive same result.

This simplifies testing and transcript confirmation.


73. Selection Function

Prefer pure:

#![allow(unused)]
fn main() {
fn negotiate(
    local: &CapabilitySet,
    remote: &CapabilitySet,
    policy: &CapabilityPolicy,
) -> Result<NegotiatedCapabilities, CapabilityError>
}

No network side effects.


74. Canonical Preference Rule

For choices such as algorithm/codec:

filter unsafe
find mutual
rank by local policy
tie-break canonically

Both sides should reach same choice if symmetric agreement required.


75. Asymmetric Capabilities

Some capabilities differ by direction.

Example:

can_encode AV1
can_decode AV1

Do not represent as one Boolean.


76. Direction

#![allow(unused)]
fn main() {
pub enum CapabilityDirection {
    Send,
    Receive,
    Both,
}
}

Useful for:

  • codecs
  • file upload/download limits
  • relay capability
  • call media

77. Device-Specific Capabilities

Part 02 allows multiple devices.

Account-level capability must be derived from device set.

Example:

Bob account:
Phone can video
Laptop cannot

Call routing targets the capable device.

Do not flatten all devices into one Boolean permanently.


78. Account Capability View

A convenience derived view may say:

Account has at least one video-capable device

but routing still resolves actual device.


79. Route Integration

Part 03 can filter candidates based on required capability.

Example:

file transfer requires files/1

Candidate session without it:

invalid for operation

80. DTN Integration

DTN forwarding peer may support:

relay small bundles
blob chunks
gateway handoff

Negotiated capability determines which bundle classes can be exchanged.


81. File Integration

Part 05 uses:

chunk size
parallelism
resume
partial transfer

from negotiated file capability contract.


82. Offline Event Log Integration

Part 04 may persist:

meaningful peer capability generation

as cache/projection if useful.

Do not permanently journal every ephemeral capability fluctuation.


83. Capability Snapshot Persistence

Store:

last_verified_peer_capabilities

as cache.

Mark with:

observed session
timestamp
hash

84. No Capability Trust from Server Alone

A directory server may publish:

peer capability hint

Use only as hint.

Final capability contract comes from authenticated peer negotiation.


85. Relay Capability Advertisement

A relay may advertise:

max bundle
gateway
storage class

Routing/DTN uses as hints.

Do not trust self-reported capacity for security-sensitive decisions.


86. Capability Attestation

Optional platform attestation can prove some hardware/platform properties.

It is supplemental.

Do not make capability negotiation depend on remote attestation for normal use.


87. Resource Capabilities

Examples:

max concurrent transfers
max inbound file size
max relay bytes
max active streams

These are negotiated limits, not promises of permanent capacity.


88. Dynamic Resource Limits

At runtime:

storage pressure
battery
memory

can reduce effective limits.

Capability update may advertise changed capacity class.


89. Coarse Resource Classes

Prefer:

Low
Normal
High

for sensitive/battery-related hints rather than exact values when privacy matters.


90. Capability Privacy

Capability sets can fingerprint devices.

Minimize exposure.

Do not advertise exact:

model
GPU
codec vendor
RAM
battery %

unless necessary.


91. Privacy Profiles

Possible:

Minimal
Standard
Diagnostic

Normal peers receive only required feature capabilities.

Detailed hardware capability is available only when needed.


92. Progressive Disclosure

Initial handshake:

supports media

Call setup:

detailed codec capabilities

File transfer setup:

detailed transfer limits

This reduces metadata leakage and handshake size.


93. Capability Fingerprinting Risk

A rare combination such as:

exact codec profile
exact max resolution
exact Bluetooth feature

may identify device class.

Document this risk.


94. Capability Hash

Store canonical capability set hash:

#![allow(unused)]
fn main() {
pub struct CapabilitySetHash([u8; 32]);
}

Useful for:

  • cache validation
  • delta detection
  • transcript binding

95. Delta Update

old hash
new hash
changed capabilities

Peer verifies expected previous epoch/hash.

This prevents applying delta to wrong base.


96. Missed Update Recovery

If peer sees unexpected epoch:

request full capability snapshot

Do not attempt to infer missing deltas.


97. Session Reconnect

On reconnect:

new authenticated negotiation

Cached hash may let peers shortcut if both explicitly support safe resume.

Start without shortcut initially.


98. Session Resumption Optimization

Future:

capability hash unchanged
+
session resumption authenticated

can avoid sending full sets.

But correctness first.


99. Interoperability

Stable capability IDs and semantics allow non-Rust implementations later.

Do not rely on:

Rust enum memory layout
usize
HashMap order

Wire representation must be explicit.


100. Postcard Use

Postcard is suitable for compact capability structures.

Rules:

  • fixed-width protocol-relevant integers
  • bounded vectors
  • versioned schemas
  • canonical ordering before transcript hash
  • no unbounded recursive structures

101. Wire Structure

Potential:

#![allow(unused)]
fn main() {
pub struct CapabilityAdvertisementV1 {
    pub core_version: u16,
    pub extension_sets: Vec<ExtensionCapabilitiesV1>,
    pub security: SecurityCapabilitiesV1,
    pub summary: CapabilitySummaryV1,
}
}

Detailed optional negotiation follows extension open.


102. Capability Summary

Compact initial summary can use:

extension IDs
major versions
feature-group bits

Then request detail lazily.


103. Negotiation Error Model

#![allow(unused)]
fn main() {
pub enum CapabilityError {
    Malformed,
    UnsupportedCoreVersion,
    RequiredCapabilityMissing,
    VersionMismatch,
    SecurityPolicyFailure,
    InconsistentDependency,
    DowngradeSuspected,
    LimitExceeded,
    TranscriptMismatch,
}
}

104. User-Visible Mapping

Normal UI should show:

File transfer unsupported
Video calling unavailable
Nearby forwarding unavailable

not:

Capability 0x0421 missing

Diagnostics can expose technical detail.


105. Required Capability Failure

Example:

files-only app
requires files/1
peer lacks files/1

Connection core may remain alive, but file operation fails cleanly.

Do not necessarily tear down entire session.


106. Security Failure

If required security capability fails:

terminate trusted session

This is different from optional feature mismatch.


107. Extension Isolation

One failed extension negotiation should not necessarily break unrelated extensions.

Example:

calls unsupported
messaging works
files work

108. Capability Lifecycle

Unknown
 ↓
Advertised
 ↓
Negotiating
 ↓
Negotiated
 ↓
Active
 ↓
Updated
 ↓
Invalidated

109. Invalidation

Invalidate capability contract when:

identity changes
session reauth
device revoked
protocol reset
critical update mismatch

110. Runtime Capability Failure

If a feature fails repeatedly:

mark degraded locally

Optionally send update.

Example:

hardware AV1 encoder broken
→ remove encode capability for current session

111. Capability Health

#![allow(unused)]
fn main() {
pub enum CapabilityHealth {
    Available,
    Degraded,
    TemporarilyUnavailable,
    DisabledByPolicy,
}
}

Do not conflate support with current health.


112. Capability Query API

#![allow(unused)]
fn main() {
let caps = client.capabilities(peer).await?;

if caps.supports(FILE_RESUME) {
    ...
}
}

Provide higher-level helpers too.


113. Operation Guard API

#![allow(unused)]
fn main() {
client
    .require_capabilities(peer, OperationKind::VideoCall)
    .await?;
}

This can return structured fallback info.


114. Fallback Suggestions

Example:

Video unsupported
Audio supported

Capability engine can produce:

#![allow(unused)]
fn main() {
FallbackPlan::AudioOnly
}

or data used by call layer.


115. File Fallback

Example:

parallel unsupported
resume supported

File engine uses:

single-stream resumable transfer

116. DTN Fallback

Example:

blob-chunk relay unsupported
small inline bundles supported

Then:

send text/SOS
defer large file

117. Routing Fallback

Example:

Wi-Fi Direct unsupported
Bluetooth supported

Routing adapts automatically.


118. Capability Negotiation for Custom Apps

ERP extension:

com.example.erp/approval/1

can register:

approval-v2
attachments
offline-signature

without modifying core negotiation logic.


119. Third-Party Capability Registry

Namespaced capability IDs prevent collision.

Core may reserve:

0x0000_0000..0x0FFF_FFFF

and application namespaces map separately.

Exact scheme should be documented.


120. Capability Documentation

Every stable capability should document:

canonical name
ID
version
parameters
dependencies
security class
default policy
wire behavior
fallback behavior

121. Generated Docs

Registry metadata can generate:

capability matrix
protocol compatibility table

for developers.


122. Compatibility Matrix

Example:

Peer A       Peer B       Result
messaging/1  messaging/1  works
files/1      none         messaging only
AV1 HW       H264 HW      H264
DTN spray    DTN direct   direct-only DTN

123. Golden Tests

Store stable negotiation cases.

Example:

local set
remote set
policy
expected negotiated set

These prevent accidental behavior changes.


124. Property Tests

Invariants:

negotiated capability is supported by both peers
hard policy is never violated
required missing capability never becomes active
result is deterministic
effective max never exceeds either peer max

125. Fuzzing

Fuzz:

capability advertisement
parameter decoding
dependency graphs
delta updates
canonical ordering
transcript hash inputs

Bound allocations.


126. Downgrade Tests

Simulate attacker stripping:

strong security capability

Negotiation must detect transcript mismatch or policy failure.


127. Malformed Capability Tests

Examples:

duplicate IDs with conflicting versions
invalid range
cyclic dependency
too many entries
oversized parameter
unknown required critical

Reject deterministically.


128. Large Capability Set Test

Third-party ecosystem may grow.

Ensure:

bounded
fast
canonical

negotiation with hundreds of capabilities.

Do not design for millions.


129. Performance

Capability negotiation occurs per session/extension open, not per packet.

Optimize for:

small wire size
fast validation
deterministic selection
cacheable result

Do not micro-optimize at expense of clarity/security.


130. Memory Bounds

Limit:

max extension count
max capabilities per extension
max parameter bytes
max nested depth

131. Logging

Log:

peer device id hash/redacted
extension
selected versions
feature count
failure reason

Do not log sensitive hardware fingerprint detail by default.


132. Diagnostics

Advanced diagnostics can show:

Core protocol: 1
Messaging: v1
  reply=yes
  edit=no

Files: v1
  resume=yes
  parallel=4
  max chunk=1 MiB

Media:
  AV1 decode software
  H264 encode hardware

DTN:
  spray-wait=yes
  max bundle=64 KiB

133. UI Simplicity

Normal UI should summarize:

Can send files
Can video call
Nearby relay supported

Capability internals belong in developer/security screens.


134. Storage Schema

Optional cache tables:

peer_capability_snapshots
peer_capability_hashes
capability_observed_at

Do not persist session secrets here.


135. Cache Invalidation

Invalidate on:

device certificate change
account generation change
protocol upgrade
session reauthentication
explicit peer update

136. Multi-Device Capability View

For an account:

Phone:
video yes
DTN yes

Laptop:
video no
files yes

Application query should be able to ask:

which devices satisfy Operation X?

137. Device Selection Query

#![allow(unused)]
fn main() {
let devices = capabilities
    .devices_supporting(account, OperationKind::VideoCall)
    .await?;
}

Routing then selects reachable device.


138. Capability-Based Fan-Out

Messaging may fan out to all devices supporting:

messaging/1

File transfer may target only devices supporting:

files/1

139. Headless Device Capabilities

Headless node can advertise:

DTN relay
files
gateway

without:

calls
UI
camera

This is expected, not exceptional.


140. Emergency Node Capabilities

Emergency relay may advertise:

high relay class
authority alert forwarding
Wi-Fi bridge
Iroh gateway

through bounded coarse capabilities.


141. Capability Negotiation and Resource Limits

Part 08 will enforce runtime limits.

Negotiated values are upper contracts.

Actual scheduler may use less.

Example:

max parallel = 8 negotiated
current battery policy = 2

142. Capability Negotiation and Crash Recovery

After restart:

capability cache may help UX

but new network session must reauthenticate and renegotiate.

Do not restore stale session capability contract as authoritative.


143. Capability Negotiation and Relay Infrastructure

Part 11 relay servers may advertise:

relay protocol version
max session class
regional support

but application-level capabilities remain peer-to-peer authenticated.


144. Capability Negotiation and Multipath

Part 12 can negotiate:

multipath supported
max concurrent paths
chunk striping support

without changing core handshake semantics.


145. Capability Negotiation and Battery Scheduling

Part 13 may dynamically reduce:

relay capacity
background transfer capacity

through capability health/updates.


146. Capability Negotiation and Proximity

Part 14 can advertise coarse proximity transports:

BLE
Wi-Fi Direct
Wi-Fi Aware

Detailed hardware fingerprint should remain hidden until needed.


147. Capability Negotiation and QR/NFC

Part 15 bootstrap payload can include:

core protocol versions
minimal capability summary

to avoid attempting impossible link flows.

Full negotiation still occurs after authenticated session.


148. Capability Negotiation and Daemon

Part 16 daemon exposes capabilities through stable IPC API.

GUI/CLI should not directly inspect hardware adapters.


149. Capability Negotiation and Emergency Priority

Part 17 can negotiate:

critical relay support
authority alert version
broadcast class

with authorization rules.


150. Capability Negotiation and Diagnostics

Part 18 can visualize:

which path/feature unavailable because capability missing

This is crucial for support.


151. Capability Negotiation and FFI

Part 19 should expose a simplified stable capability query API.

Do not expose internal Rust registry pointers across FFI.


152. Capability Negotiation and Embedded Linux

Part 20 embedded nodes may advertise minimal subsets.

The protocol should handle small constrained peers cleanly.


153. Capability Negotiation and WASM

Part 21 WASM components can reuse:

capability types
selection logic
codec

without transport-specific runtime.


154. Capability Negotiation and Third-Party Extensions

Part 22 directly depends on namespaced capability registration.

Custom extensions can define their own capability IDs and parameter codecs.


155. Capability Negotiation and Interoperability Suite

Part 23 should test:

capability advertisement
required/optional behavior
version mismatch
unknown capability
downgrade detection

across implementations.


156. Capability Negotiation and Plugin Ecosystem

Part 24 plugin/module system can register capability schemas through controlled API.

Plugins must not overwrite existing IDs.


157. Public API Surface

Suggested:

#![allow(unused)]
fn main() {
CapabilityClient
CapabilityRegistry
NegotiatedCapabilities
CapabilityPolicy
CapabilityQuery
}

Keep low-level wire negotiation internal.


158. Suggested Crate Structure

crates/comm-capability/
├── src/
│   ├── lib.rs
│   ├── id.rs
│   ├── namespace.rs
│   ├── descriptor.rs
│   ├── set.rs
│   ├── parameter.rs
│   ├── registry.rs
│   ├── advertisement.rs
│   ├── negotiate.rs
│   ├── policy.rs
│   ├── security.rs
│   ├── cache.rs
│   ├── update.rs
│   ├── diagnostics.rs
│   └── error.rs
└── Cargo.toml

Potential protocol module:

comm-capability-protocol

if wire concerns grow.


159. Error Model

#![allow(unused)]
fn main() {
pub enum CapabilityNegotiationError {
    UnsupportedCore,
    MissingRequired,
    VersionMismatch,
    SecurityPolicy,
    Malformed,
    DependencyViolation,
    Conflict,
    LimitExceeded,
    DowngradeSuspected,
    TranscriptMismatch,
    Cancelled,
}
}

Use typed errors.


160. Initial Production Scope

Implement first:

core protocol version negotiation
extension support advertisement
required vs optional capabilities
typed file capability parameters
typed DTN capability parameters
basic media codec capability
security algorithm negotiation
canonical capability hashing
two-phase confirmation
capability cache
runtime capability updates

Defer initially:

complex attestation
dynamic remote plugin capability code
automatic capability learning
large metadata-rich hardware profiles

161. Implementation Phases

Phase 1 — Core Types

CapabilityId
CapabilityVersion
CapabilitySet
CapabilityRegistry

Phase 2 — Handshake

advertise
validate
intersect
confirm

Phase 3 — Extension Integration

messaging
files
DTN

Phase 4 — Security

algorithm selection
minimum policy
downgrade detection
transcript hash

Phase 5 — Media/Platform

codec
Bluetooth/Wi-Fi
resource summaries

Phase 6 — Dynamic Updates

epoch
delta
full resync

Phase 7 — Hardening

fuzzing
property tests
golden cases
interoperability tests

162. Definition of Done

Part 07 is complete when:

  • peers do not rely on app version to infer feature support
  • capability advertisements are authenticated
  • required and optional capabilities behave differently
  • unknown optional capabilities do not break compatibility
  • unknown required capabilities fail safely
  • version ranges negotiate deterministically
  • security capabilities respect a minimum local security floor
  • downgrade attempts are detectable
  • file transfer negotiates chunk/resume/parallel limits
  • DTN negotiates relay/bundle capabilities
  • media negotiates codec direction and implementation
  • device-specific capability differences are preserved
  • routing can filter paths by required capabilities
  • capability cache is treated only as a hint
  • dynamic capability updates are versioned
  • capability payload sizes are bounded
  • canonical transcript hashing exists
  • Dioxus consumes simplified derived capability state
  • custom third-party namespaces can register capabilities safely
  • property/fuzz/golden/interoperability tests exist

163. Relationship to Earlier Parts

Part 07 builds directly on:

01 — Protocol Extension System
02 — Multi-Device Identity
03 — Transport & Routing Policy Engine
04 — Offline Event Log
05 — Robust File / Blob Subsystem
06 — DTN / Store-Carry-Forward

It prepares the platform for:

08 — Resource Limits & Backpressure
09 — Crash Recovery
10 — Protocol Fuzzing & Test Suite
11 — Relay / Self-Hosted Infrastructure
12 — Multipath Networking
13 — Battery-Aware Scheduling
14 — Proximity Abstraction
15 — QR / NFC Bootstrap Pairing
16 — Daemon & Headless Runtime
17 — Emergency Priority Architecture
18 — Network Diagnostics & Path Visualization
19 — C ABI / FFI
20 — Embedded Linux Node
21 — WASM-Compatible Components
22 — Third-Party Protocol Extensions
23 — External Interoperability Suite
24 — Plugin / Module Ecosystem

164. Final Principle

The capability system should let two completely different peers safely discover the strongest mutually compatible behavior.

Example:

Alice Android
  messaging v1
  files resume+parallel
  AV1 HW
  H264 HW
  DTN spray-wait
  Wi-Fi Aware

Bob Linux
  messaging v1
  files resume
  AV1 software
  no H264 hardware
  DTN direct-only
  LAN

The negotiated result may become:

Messaging:
  v1

Files:
  resume
  single-path/single-parallel subset

Video:
  AV1

DTN:
  direct-only common subset

Neither peer needs to know the other's implementation details.

They only need a verified, versioned contract describing what they can safely do together.

That is what makes the communication platform interoperable, evolvable, modular, and production-ready across different devices, products, and future protocol generations.