docs(architecture): resolve review #002 Tiers 1-3 — mechanical and consistency fixes
Governance (Tier 2):
- Advance ADR-022 and ADR-023 from Proposed to Accepted (specs already
depend on their types as source of truth)
- Amend ADR-015: mark Decision 3 and Assumption 6 as superseded by ADR-022;
update handler_identity type to CompositionAuthority
- Amend ADR-002: note handle() signature revised by ADR-007 (BiStream → Connection)
- Amend ADR-004: note 'enrich/replace' AuthContext language superseded by
ADR-011's immutability model; update to describe set_identity on Connection
- Update main README ADR table to show ADR-022/023 as Accepted
Spec-ADR consistency (Tier 3):
- Add abort_policy: AbortPolicy field to OperationContext struct (ADR-016
Decision 6 mandated this but the spec omitted it)
- Define AbortPolicy enum (AbortDependents | ContinueRunning) with Default impl
- Add abort_policy to build_root_context and LocalOperationEnv::invoke()
- Define the OperationEnv trait explicitly with invoke() and
invoke_with_policy() methods (was referenced as 'must remain a trait'
but never defined)
- Specify From<StreamError> for HandlerError impl with exact variant mapping
- Add Connection::from_quinn() / from_iroh() constructors (was referenced
as Connection::new() but never defined)
- Remove undefined CertAuthorityEntry placeholder from AuthPolicy v1 (will
be added additively when alknet-ssh lands)
- Fix config.md key-differences table: rate limits are in DynamicConfig,
not StaticConfig
Mechanical fixes (Tier 1):
- overview.md: 'closes the QUIC stream' → 'closes the connection' (stale
from pre-ADR-007 model)
- overview.md: OQ-04 entry updated from stale 'defer to implementation'
to 'resolved: static at startup'
- mnemonic-derivation.md: remove duplicate helper functions block (incomplete
first copy, complete second copy)
- ADR-003: add iroh (feature-gated) to alknet-core dependency list, added
by ADR-010
- ADR-021: fix ambiguous 'W1 drift issue from the vault review' cross-reference
- ADR-022: rephrase FromCall 'leaf locally' to 'leaf in the local registry'
- ADR-017: add error_schemas to from_call mirror list and services/schema
step (inconsistency with ADR-023)
- ADR-016: fix self-referential citation ('ADR-016 Assumption 5' → 'Assumption 5')
- Add ScopedOperationEnv::empty(), allows(), new() and
CompositionAuthority::none(), new() impl blocks (referenced but undefined)
- Add call.completed clarification for non-subscription calls
- Add services/schema leading-slash normalization note
- Crate README ADR tables: add missing ADR-013 (call), ADR-015 (core),
ADR-006 + ADR-010 (vault)
- Vault README: add consolidated 'Known Source Drift' table tracking all
four drift items (OsRng, unwrap, CURRENT_KEY_VERSION, spawn bug) in one
place, including the two previously missing from README
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
## Status
|
||||
|
||||
Proposed
|
||||
Accepted
|
||||
|
||||
## Context
|
||||
|
||||
@@ -120,7 +120,8 @@ pub enum OperationProvenance {
|
||||
FromOpenAPI,
|
||||
/// MCP forwarding stub (from_mcp), leaf — cannot compose.
|
||||
FromMCP,
|
||||
/// QUIC forwarding stub (from_call), leaf locally — cannot compose.
|
||||
/// QUIC forwarding stub (from_call). Leaf in the local registry —
|
||||
/// forwards calls to a remote node; cannot compose locally.
|
||||
FromCall,
|
||||
/// JSON Schema definition (from_jsonschema), no handler — schema only.
|
||||
FromJsonSchema,
|
||||
@@ -134,7 +135,7 @@ pub enum OperationProvenance {
|
||||
| `Local` | Yes | Yes — scopes set by assembly layer | External or Internal (assembly declares) | Trusted code |
|
||||
| `FromOpenAPI` | No (leaf) | No | Internal | HTTP endpoint trusted; handler is a forwarding stub |
|
||||
| `FromMCP` | No (leaf) | No | Internal | MCP server trusted; handler is a forwarding stub |
|
||||
| `FromCall` | No (leaf locally) | No | Internal | Remote node trusted; handler is a forwarding stub |
|
||||
| `FromCall` | No (leaf in local registry) | No | Internal | Remote node trusted; handler is a forwarding stub |
|
||||
| `FromJsonSchema` | N/A (no handler) | No | N/A | N/A |
|
||||
| `Session` | Yes (within sandbox) | Yes — scopes set by assembly layer at sandbox creation | Internal always | Untrusted code in sandbox |
|
||||
|
||||
@@ -178,6 +179,24 @@ pub struct CompositionAuthority {
|
||||
/// handler can reach in composition.
|
||||
pub resources: HashMap<String, Vec<String>>,
|
||||
}
|
||||
|
||||
impl CompositionAuthority {
|
||||
/// `None` — for leaves that don't compose (convenience for
|
||||
/// `composition_authority: CompositionAuthority::none()`).
|
||||
pub fn none() -> Option<Self> { None }
|
||||
|
||||
/// Construct a composition authority with the given label and scopes.
|
||||
pub fn new(
|
||||
label: &str,
|
||||
scopes: impl IntoIterator<Item = String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
label: label.to_string(),
|
||||
scopes: scopes.into_iter().collect(),
|
||||
resources: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This supersedes ADR-015's Assumption 6. ADR-015's core decision (authority
|
||||
@@ -212,6 +231,23 @@ pub struct ScopedOperationEnv {
|
||||
/// parameterized-dispatch attack surface.
|
||||
pub allowed_operations: HashSet<String>,
|
||||
}
|
||||
|
||||
impl ScopedOperationEnv {
|
||||
/// Empty set — for leaves that don't compose (no reachable operations).
|
||||
pub fn empty() -> Self {
|
||||
Self { allowed_operations: HashSet::new() }
|
||||
}
|
||||
|
||||
/// Construct from an iterable of operation names.
|
||||
pub fn new(ops: impl IntoIterator<Item = String>) -> Self {
|
||||
Self { allowed_operations: ops.into_iter().collect() }
|
||||
}
|
||||
|
||||
/// Returns true if the given operation name is reachable.
|
||||
pub fn allows(&self, name: &str) -> bool {
|
||||
self.allowed_operations.contains(name)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. The registration bundle carries all three
|
||||
|
||||
Reference in New Issue
Block a user