docs(arch): resolve OQ-26 (AdapterError variants) + OQ-33 (PeerId = logical id) + OQ-34 (persistent peer registry)
OQ-26 (resolved): AdapterError variants decided — DiscoveryFailed, SchemaParse, Transport, Unauthorized, SamePeerCollision (replaces flat Conflict per ADR-029 §5). #[non_exhaustive] for downstream extension. Two-way door; the initial set is the code's return type. OQ-33 (resolved): PeerId is a logical identifier, NOT Identity.id. The research's v1 default (PeerId = fingerprint) is overridden: coupling PeerId to crypto material breaks every in-flight PeerRef::Specific and every ACL entry on key rotation. v1 source is a connection-assigned UUID — a no-storage workaround that works for the immediate use case (head→workers, reconnect produces fresh PeerRef, in-flight gets NOT_FOUND which is correct). The one-way door: PeerId is logical, not crypto — this determines PeerCompositeEnv key type and PeerRef::Specific payload. The id source (UUID vs configured name vs peer registry) is the two-way-door remainder. OQ-34 (new): the storage dimension OQ-33 surfaced. The core crates are deliberately DB-free (smaller, fewer deps, simpler testing) — this served local-only state (vault, registry) well, but peer identity is the first cross-node state that wants persistence. The real solution (a persistent peer registry mapping stable logical name → current crypto material, surviving key rotation) is not a v1 blocker (UUID works), but tracked so the no-DB posture's limit is deliberate, not accidental. The storage boundary (core gets a PeerRegistry trait vs stays storage-free) is the one-way door; the backend choice is two-way. Key-rotation/ACL note: decoupling PeerId from crypto keeps the door open for ACL entries that persist across key rotation — when the peer registry is built, ACLs key on the logical name and key rotation becomes vault-only with no remote-side ACL update.
This commit is contained in:
@@ -51,13 +51,15 @@ Structured RPC over QUIC: operations, request/response, streaming subscriptions,
|
||||
| OQ-16 | Safe vault operations for call protocol exposure | resolved (ADR-014) | None exposed for now |
|
||||
| OQ-19 | Session-scoped operation registries | resolved | Agent-written operations overlaid on curated registry via `OperationEnv` trait layering. Protocol doesn't need changes; `OperationEnv` must remain a trait. Generalized by ADR-024 to cover connection-scoped overlays. |
|
||||
| OQ-25 | ~~Remote-safe marking shape~~ | **dissolved** (ADR-029) | `remote_safe`/`trusted_peer` retired; peer authorization is `AccessControl::check(peer_identity)` |
|
||||
| OQ-26 | OperationAdapter error type (AdapterError variants) | open (two-way) | `import()` returns `Result<_, AdapterError>`; variants decided in implementation |
|
||||
| OQ-26 | OperationAdapter error type (AdapterError variants) | **resolved** | `DiscoveryFailed`, `SchemaParse`, `Transport`, `Unauthorized`, `SamePeerCollision`; `#[non_exhaustive]` |
|
||||
| OQ-27 | from_call re-import trigger | open (two-way) | v1 default: auto-on-reconnect; explicit `refresh()` additive |
|
||||
| OQ-28 | from_call namespace collision | cross-peer **dissolved** (ADR-029) / same-peer stays | Cross-peer: separate sub-overlays, no collision. Same-peer: error. `namespace_prefix` is local-naming sugar |
|
||||
| OQ-29 | CallClient TLS client-auth and remote-identity verification | open (two-way) | v1 `with_no_client_auth()` + `AcceptAnyServerCertVerifier`; wiring RawKey client-auth is additive (orthogonal to ADR-029) |
|
||||
| OQ-30 | `PeerRef::Any` routing policy | open (two-way) | v1 insertion-order first-match; round-robin/least-loaded is future (ADR-029) |
|
||||
| OQ-31 | `services/list-peers` re-export semantics | open (two-way) | v1 "own ops only"; `services/list-peers` is opt-in (ADR-029) |
|
||||
| OQ-32 | Multi-hop federation | open | v1 one-hop; peer-keyed model extends without redesign; petgraph candidate (ADR-029) |
|
||||
| OQ-33 | PeerId — crypto identity vs stable logical id | **resolved** | Logical id (UUID v1), not `Identity.id`; decoupled from crypto for key-rotation-safe ACLs |
|
||||
| OQ-34 | Persistent peer registry (cross-node state storage) | open | Not a v1 blocker (UUID works); the no-DB posture's limit, tracked for deliberate future decision |
|
||||
|
||||
## Key Design Principles
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ pub struct PeerCompositeEnv {
|
||||
pub connections: HashMap<PeerId, Arc<dyn OperationEnv + Send + Sync>>, // Layer 2, peer-keyed
|
||||
connection_order: Vec<PeerId>, // insertion order for PeerRef::Any first-match
|
||||
}
|
||||
pub type PeerId = String; // = Identity.id
|
||||
pub type PeerId = String; // logical id (UUID v1), NOT Identity.id — see OQ-33
|
||||
```
|
||||
|
||||
`OperationEnv` gains a peer-routing method with a `PeerRef` selector
|
||||
@@ -608,10 +608,9 @@ See [open-questions.md](../../open-questions.md) for full details.
|
||||
- **OQ-25** (dissolved by ADR-029): `remote_safe` marking shape — moot.
|
||||
`remote_safe`/`trusted_peer` are retired; peer authorization is
|
||||
`AccessControl::check(peer_identity)`. No marking to shape.
|
||||
- **OQ-26** (open, two-way): `AdapterError` enum variants (DC-4). The
|
||||
*presence* of an error type is recorded here; the variants are
|
||||
implementation-detail. A `SamePeerCollision` variant may replace the flat
|
||||
`Conflict` variant (ADR-029 §5).
|
||||
- **OQ-26** (resolved): `AdapterError` variants — `DiscoveryFailed`,
|
||||
`SchemaParse`, `Transport`, `Unauthorized`, `SamePeerCollision`
|
||||
(replaces flat `Conflict`). `#[non_exhaustive]`.
|
||||
- **OQ-27** (open, two-way): `from_call` re-import trigger — auto-on-reconnect
|
||||
(v1 default, recorded here) vs explicit `CallConnection::refresh()`. v1 is
|
||||
auto-on-reconnect; the explicit path is additive. The overlay is now
|
||||
@@ -632,6 +631,12 @@ See [open-questions.md](../../open-questions.md) for full details.
|
||||
- **OQ-32** (open): Multi-hop federation — v1 is one-hop; the peer-keyed
|
||||
overlay model extends to multi-hop without redesign; petgraph is the
|
||||
candidate if path-finding becomes real (ADR-029 §3.7).
|
||||
- **OQ-33** (resolved): `PeerId` is a logical id (connection-assigned UUID),
|
||||
not `Identity.id` — decoupling from crypto material keeps the door open for
|
||||
key-rotation-safe ACLs. See OQ-33 in open-questions.md.
|
||||
- **OQ-34** (open): Persistent peer registry — the storage dimension OQ-33
|
||||
surfaced; not a v1 blocker (UUID works), tracked so the no-DB posture's
|
||||
limit is deliberate. See OQ-34 in open-questions.md.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
Reference in New Issue
Block a user