docs(architecture): resolve review #002 remaining Tier 4 findings
Add ADR-026 (vault key model — HD derivation) recording the foundational HD-derivation decision, 74' coin type reservation, SLIP-0010/Ed25519 default, secp256k1 feature-gating, and AES-256-GCM cipher choice. These were previously inline rationale with no ADR (W9). Extend ADR-018 with an explicit EncryptedData wire format lock — fields, encoding, and semantics are frozen; no removal without a format-version migration (W10). Resolve the remaining guard clauses and spec decisions: - W2: Capabilities must be immutable after construction (no interior mutability). Makes the Arc vs deep-copy clone semantics genuinely two-way. - W5: Published to_* specs are compatibility contracts — best-effort mappings are two-way before first publication, one-way after. Version generated specs. - W6: Salt field clarification — v2 salt is permanently unused; a future KDF is a different derivation family, not a version-indexed path; the field saves a wire-format change only. - W7: unlock_new returns Zeroizing<String> — the mnemonic is the root of trust and must not linger in freed memory. - W17: OQ-09 WASM — server-side dispatch door is honestly closed (Connection is concrete, tokio-bound), not implicitly preserved. - W18: OQ-10 git — composability fork (raw smart protocol vs call-protocol projection) is a separate decision from ERC721 scope. - W20: from_openapi must prefix imported error codes (HTTP_404) to avoid collision with protocol-level codes (NOT_FOUND). Normative rule, not naming convention. - W21: ScopedOperationEnv field is private — construction via new()/ empty(), query via allows(). Makes the future subgraph refactor non-breaking. - C13: Connection::set_identity — the endpoint does not read identity() after handle() returns (Connection is moved into the spawned task). Observability is handler-side logging. Simplest honest answer. - W1: OperationAdapter trait is async, returns Vec<HandlerRegistration>. from_call requires async discovery; ADR-022 changed the return type. - W11: CompositionAuthority::as_identity() defined — constructs a synthetic Identity (label as id, scopes, resources) not resolvable via IdentityProvider. Second Identity construction path, acknowledged. - W14: SecretKey is iroh::SecretKey (Ed25519) — consistent with the endpoint's iroh dependency. - W19: Grandchild abort propagation is inherit-by-default (option a) — invoke() with no explicit policy inherits parent's policy. ContinueRunning auto-propagates to grandchildren unless explicitly overridden.
This commit is contained in:
@@ -152,10 +152,25 @@ context.env.invoke_with_policy(
|
||||
```
|
||||
|
||||
The child's `OperationContext` carries the policy. If the child itself
|
||||
composes grandchildren, the policy propagates unless the child explicitly
|
||||
overrides it. This is consistent with the composition authority and scoped
|
||||
env propagation in ADR-022 — the parent handler decides the child's
|
||||
runtime context, including abort policy.
|
||||
composes grandchildren, the policy **propagates by inheritance** — the
|
||||
grandchild inherits the child's policy (which was the parent's policy,
|
||||
unless the parent overrode it for the child via `invoke_with_policy`).
|
||||
`ContinueRunning` does auto-propagate to grandchildren: if a parent opts
|
||||
its child into `ContinueRunning`, and the child composes grandchildren
|
||||
without explicitly overriding, the grandchildren also get
|
||||
`ContinueRunning`. This is consistent with the composition authority and
|
||||
scoped env propagation in ADR-022 — the parent handler decides the
|
||||
child's runtime context, including abort policy, and that decision
|
||||
propagates through the composition tree by default.
|
||||
|
||||
**Review #002 W19 resolution**: `invoke()` with no explicit policy
|
||||
argument inherits the parent's current policy (option a). It does **not**
|
||||
reset to `AbortDependents`. A handler that wants a child to reset to the
|
||||
default must explicitly call `invoke_with_policy(...,
|
||||
AbortPolicy::AbortDependents)`. This makes the propagation predictable:
|
||||
the policy I set for my child applies to my child's children unless they
|
||||
re-decide. The `invoke()` default in operation-registry.md
|
||||
(`abort_policy: parent.abort_policy.clone()`) is correct.
|
||||
|
||||
The `OperationEnv` trait gains an optional policy parameter. The specific
|
||||
API shape (a separate `invoke_with_policy` method, a policy field on an
|
||||
|
||||
Reference in New Issue
Block a user