Proposal 018: Layered capability_limited Participant Restrictions¶
Context¶
The current Node runtime already uses capability_limited as a peer-quality
state when a remote peer is missing required transport capabilities. That solves
one narrow networking problem, but it does not yet define how participant-level
sanctions should work above transport.
This leaves an architectural gap:
- soft degradation is underspecified,
- hard operation blocks are ad hoc,
- and the system lacks one auditable artifact binding sanctions to a concrete participant subject, author, and expiry.
The gap matters because Orbiplex explicitly rejects both extremes:
- a harmless soft downgrade that leaves every privileged operation effectively available,
- and an opaque binary kill switch that collapses all escalation into permanent exclusion.
Goals¶
- freeze a participant-scoped artifact for layered restriction state,
- keep soft degradation separate from hard blocked operations,
- preserve a non-blockable minimum participation floor,
- define the first minimal Node enforcement hooks without overloading the transport governor,
- and keep the blocked-operation namespace open for later growth.
Non-Goals¶
- This proposal does not redefine transport-layer capability advertisement.
- This proposal does not make
capability_limiteda permanent exclusion state. - This proposal does not yet define a global sanction registry or federation-wide propagation rail.
- This proposal does not yet standardize graduated time-based soft degradation curves.
Decision¶
Orbiplex should model participant-scoped limited participation through one layered artifact:
participant-capability-limits.v1
The artifact represents one participant-level state:
status = capability_limited
That state always carries a soft layer:
soft.priority-factorsoft.rate-limit-factor
and may additionally carry a hard layer:
hard.blocked-operationshard.reason/refhard.decision/authorhard.expires-at
The hard layer is therefore:
- explicit,
- authored,
- bounded in time,
- and narrower than full removal from the network.
Proposed Model¶
1. Separation of Layers¶
capability_limited is a composite state, not a single switch.
- The
softlayer adds friction. - The
hardlayer removes selected operational permissions.
This lets the system degrade participation without collapsing immediately into ban semantics.
2. Scope¶
The first artifact is participant-scoped:
participant/id = participant:did:key:...
This is deliberate. The participant is the right MVP target for service-facing
restrictions such as procurement/offer or endorsement/emit.
The proposal does not yet extend the same artifact family to org or pod-user.
3. Soft Layer¶
The MVP soft layer freezes two factors:
priority-factorrate-limit-factor
Both are normalized to (0.0, 1.0], where 1.0 means no degradation.
The first Node runtime SHOULD consume priority-factor on procurement ranking
and SHOULD consume rate-limit-factor through a small deterministic per-participant
operation cooldown hook for the first admitted daemon operations.
4. Hard Layer¶
The MVP hard layer is an open namespace of blocked operations rather than a closed enum of privilege names.
Examples:
procurement/offernym/issueendorsement/emitrelay/servearbitration/participate
This keeps operation semantics above the transport layer and avoids confusing blocked service permissions with handshake-time advertised capabilities.
5. Protected Operations¶
Some operations remain outside the admissible hard-block set in MVP:
core/messagingkeepalivedispute/fileubc/claimsignal-marker/send
These form the minimum floor of continued presence, communication, and appeal.
6. Relationship to Existing Peer Governor State¶
This proposal complements the existing peer-quality downgrade path.
- peer governor state remains transport- and session-facing,
- participant restriction state remains actor- and operation-facing.
The two MAY correlate in later policy, but they are not the same layer and should not be collapsed into one mutable flag.
First Runtime Hooks¶
The first Node runtime rollout should stay small but real:
- reject
procurement/requestwhen the asking participant is hard-blocked for that operation, - reject
procurement/offerwhen the responder participant is hard-blocked for that operation, - reject
response/deliverwhen the responding participant is hard-blocked for that operation, - reject
procurement/contract-acceptwhen the asking participant is hard-blocked for that operation, - reject
response/acceptwhen the asking participant is hard-blocked for that operation, - reject
response/rejectwhen the asking participant is hard-blocked for that operation, - apply
soft.priority-factoras a deterministic procurement-ranking penalty, - apply
soft.rate-limit-factoras a deterministic per-participant cooldown on currently admitted daemon operations such asprocurement/request,procurement/offer,procurement/contract-accept,response/deliver,response/accept,response/reject, andsignal-marker/send, - keep
signal-marker/sendexplicitly admissible as a protected-floor operation even when the participant is otherwise limited, - expose participant-side
response/acceptandresponse/rejectthrough a dedicated participant-scoped daemon control contract instead of reusing operator action endpoints.
Discovery visibility, broader operation coverage, and richer graduated governor policies remain deferred to later work.
Trade-offs¶
Benefits¶
- sanctions become auditable rather than folkloric,
- hard blocks become narrow and time-bounded,
- the project preserves a protected minimum participation floor,
- runtime policy can grow incrementally without redesigning identifiers.
Costs¶
- one more artifact family to keep in sync across docs and runtime,
- temporary asymmetry where soft factors are frozen before every soft hook is equally mature,
- a new distinction operators must understand between peer downgrade and participant restriction.
Risks¶
- if the blocked-operation namespace drifts semantically, enforcement becomes confusing,
- if protected operations are not frozen early, ad hoc sanctions may overreach,
- if soft factors are not consumed by real runtime hooks, the artifact becomes a paper tiger.
Open Questions¶
- When should
rate-limit-factorbecome a generic per-operation governor hook rather than a stored-but-lightly-used field? - Should the first cooldown grain stay at
(participant, operation), or move later toward(participant, operation, question)for multi-contract concurrency? - Which artifact should carry later review history: this restriction record directly, or a separate review/case family?
- Should
orgeventually use a sibling artifact or the same family withsubject/kind? - Which operation ids should be elevated into a more formal registry first?
Next Actions¶
- Add
participant-capability-limits.v1to the synchronized contract mirror. - Add Node-side import validation for that artifact.
- Wire the first procurement and messaging hooks against the new artifact.
- Revisit generic rate limiting only after the operation-facing governor layer is ready.
- Keep launcher-facing participant lifecycle decisions on a distinct control surface from infrastructure-operator actions.