Commit Graph

84 Commits

Author SHA1 Message Date
df355c53a9 tasks: decompose ADR-029/030/031/032/034/035 source sync into 17 tasks
Decompose the source-to-spec sync for the core and call crates into atomic,
dependency-ordered tasks for implementation agents:

Core (7 tasks + review):
- peer-entry-model: PeerEntry struct, AuthPolicy.peers (ADR-030 keystone)
- credential-store-trait: CredentialStore/InMemoryCredentialStore/StoreError (ADR-031/035)
- identity-store-trait: IdentityStore async write trait (ADR-035)
- config-identity-provider-peerentry: ConfigIdentityProvider PeerEntry resolution (ADR-030)
- fingerprint-normalization: ed25519:hex for raw keys across quinn/iroh (ADR-030 §6)
- three-remote-roles-docs: document ADR-034 roles and verifier selection
- review-core-sync: phase gate before call consumes new identity semantics

Call (9 tasks + review):
- retire-remote-safe: remove ADR-028 machinery, AccessControl is the gate (ADR-029 §3)
- operation-context-forwarded-for: forwarded_for field, wire-ingress only (ADR-032)
- peer-composite-env: PeerCompositeEnv, PeerId=Identity.id, remove UUID (ADR-029/030)
- operation-env-invoke-peer: invoke_peer/peer_contains/PeerRef (ADR-029 §2)
- services-list-accesscontrol-filtered: AccessControl filter, list-peers opt-in (ADR-029 §6)
- call-client-verifier-selection: TLS client-auth, verifier by PeerEntry (OQ-29, ADR-034)
- from-call-forwarded-for: populate forwarded_for, peer-keyed registration (ADR-029 §5, ADR-032)
- dispatch-peer-identity: AccessControl::check(peer_identity), PeerId from resolution (ADR-029 §3, ADR-030 §5)
- review-call-sync: phase gate for the call sync

Validated: 58 tasks, no cycles, logical topo order, two review checkpoints.
2026-06-28 21:08:41 +00:00
2fe471ad4e docs(tasks): mark call/review-completion complete with review findings
Records the conformance review for the alknet-call client/adapter
completion batch. All 14 acceptance criteria pass:

- CallClient, from_call, OperationAdapter, from_jsonschema match
  client-and-adapters.md.
- Peer-scoped default-deny (ADR-028) enforced: non-remote-safe ops return
  NOT_FOUND before capabilities are populated (the load-bearing security
  assertion, verified by three capability-exposure tests).
- Shared dispatch loop is genuinely shared (single Dispatcher; CallAdapter
  and CallClient both delegate to run_loop).
- No-env-vars invariant holds (no std::env::var reads; credentials from
  Capabilities).
- Adapter location map respected (no HTTP deps in alknet-call).
- OQ-25..28 two-way-door remainders recorded with v1 defaults.
- No spec drift requiring amendment.
- 207 lib + 2 integration tests pass; clippy + fmt clean.

This closes the call-completion batch. Unblocks every downstream consumer
(runner, container service, bilateral exchange, NAPI, agent cross-node
dispatch) and alknet-http Phase 1 (OperationAdapter trait).

Refs: tasks/call/review-completion.md
2026-06-26 13:27:08 +00:00
a3825f57cf feat(call): from_call adapter — discover + register remote ops (ADR-017 §3)
The #2 gap in alknet-call: discovers the remote peer's External operations
via services/list + services/schema and registers them in the connection's
Layer 2 overlay as FromCall-provenance leaves with forwarding handlers. The
discovery mechanism was already implemented in registry/discovery.rs;
from_call is the client-side consumer of that API.

src/client/from_call.rs:
- from_call(connection, FromCallConfig) -> Result<Vec<HandlerRegistration>,
  AdapterError>. Calls services/list then services/schema for each op,
  rebuilds OperationSpec from the schema JSON (parsing op_type, visibility,
  error_schemas, access_control), constructs a forwarding handler that calls
  the remote op via CallConnection::call(), and returns FromCall-provenance
  bundles (composition_authority: None, scoped_env: None, empty capabilities,
  remote_safe: false per ADR-028 §4).
- FromCallConfig { namespace_prefix: Option<String>, operation_filter:
  Option<HashSet<String>> } with builder methods.
- v1 defaults (two-way doors recorded in client-and-adapters.md):
  - error-on-collision (DC-3/OQ-28): applying the (possibly empty) prefix
    produces a name already seen -> AdapterError::Conflict, not silent
    overwrite.
  - auto-on-reconnect (DC-2/OQ-27): the overlay is per-connection (Layer 2,
    ADR-024), so re-import on reconnect is naturally scoped; the assembly
    layer calls from_call immediately after connect().
- Forwarding handler captures an Arc<CallConnection> and, on invocation,
  calls the remote op and returns its ResponseEnvelope. The
  parent_request_id participates in the cross-node abort cascade
  (ADR-016 §6) — if the parent is aborted, the cascade reaches this handler
  which sends call.aborted to the remote node; cross-node abort is
  transparent.
- Trust is transitive (recorded in spec): a from_call-imported op executes
  the remote node's code; scoped_env bounds which ops are reachable, not
  what they do.

OperationContext.internal is now pub (was pub(crate)) so downstream
consumers (assembly layer, integration tests) can construct contexts for
overlay-env dispatch.

Tests (207 lib + 2 integration):
- Unit: rebuild_spec name/prefix/op_type/visibility/error_schemas/acl;
  unknown op_type -> SchemaParse; missing op_type -> SchemaParse;
  FromCallConfig builder; from_call against a mock connection returns
  DiscoveryFailed (no transport); FromCall provenance + leaf fields + remote_safe false.
- Integration (tests/two_node_call.rs): from_call over a real QUIC loopback
  — CallClient connects, from_call discovers server/echo, registers the
  bundle in the overlay, and the forwarding handler round-trips an input
  through the overlay env to the remote op and back.

clippy + fmt + test all green.

Refs: tasks/call/client/from-call.md
Refs: docs/architecture/decisions/017-call-protocol-client-and-adapter-contract.md §3, §6
Refs: docs/architecture/crates/call/client-and-adapters.md §from_call
2026-06-26 13:25:13 +00:00
4bf897f5ab feat(call): CallClient + shared dispatch loop + peer-scoped default-deny (ADR-017, ADR-028)
The #1 gap in alknet-call: the outbound connection opener. Every downstream
consumer (runner, container service, bilateral exchange, NAPI, agent
cross-node dispatch) is blocked on it.

Shared dispatch loop (ADR-017 §1 — the architectural commitment that keeps
CallClient from becoming a parallel protocol implementation):
- Extracts the accept-path dispatch (sweeper, accept_bi loop, handle_stream,
  dispatch_requested, build_root_context, compose_root_env, fail_all on
  close) out of CallAdapter into a new protocol/dispatch.rs Dispatcher struct.
  Both CallAdapter::handle and CallClient::connect produce a CallConnection
  and hand it to Dispatcher::run_loop — the loop is genuinely shared
  (refactored, not duplicated).
- CallAdapter keeps its public API and test-facing wrappers (pub(crate),
  #[cfg(test)]-gated) that delegate to the Dispatcher.

Peer-scoped default-deny (ADR-028 — the one-way-door security dimension):
- RemoteFilter { trusted_peer: bool } on the Dispatcher. In default-deny
  mode (CallClient::new), an incoming call to an op with remote_safe: false
  returns NOT_FOUND *before* any capability material reaches the handler —
  a remote peer's call must not populate OperationContext.capabilities from
  the local registration bundle unless the op is explicitly remote-safe
  (ADR-028 Context). Trusted-peer mode (CallClient::trusted_peer, explicit
  opt-in) bypasses the filter.
- The accept path (CallAdapter) uses RemoteFilter::trusted() by convention: a
  direct QUIC client is not a filtered CallClient peer in the ADR-028 sense.
- OperationRegistry::list_operations_peer_scoped(trusted_peer) +
  services_list_handler_peer_scoped for the CallClient's services/list
  serving path (ADR-028 Assumption 2: a peer should not see ops it cannot
  call, so discovery and dispatch filters agree).

CallClient (src/client/call_client.rs):
- CallClient { registry, identity_provider, trusted_peer: bool }.
- new() default-deny; trusted_peer() explicit opt-in (ADR-028 §3).
- connect(addr, CallCredentials) dials QUIC on ALPN alknet/call (quinn
  feature), spawns Dispatcher::run_loop, returns a live CallConnection.
- spawn_dispatch(connection) shared path for connect + tests.
- CallCredentials { tls_identity, auth_token, remote_identity } — all from
  Capabilities (ADR-014), never env vars (no-env-vars invariant). v1
  connects without client-auth TLS identity (server uses
  AcceptAnyCertVerifier); RawKey client-auth is a two-way-door remainder.
- RemoteIdentity { fingerprint } — concrete shape is a two-way door (OQ-25
  remainder); the one-way constraint is it comes from Capabilities.
- ClientError { Transport, TlsSetup, ConnectionClosed }.
- CallConnection is now Clone (shares the inner Arcs) so connect can hand
  the caller a live clone while the dispatcher task keeps its clone.

Tests (199 lib + 1 integration):
- Unit: default-deny NOT_FOUND for non-remote-safe; remote_safe dispatches;
  trusted-peer dispatches all External; default-deny does NOT populate
  capabilities (the load-bearing security assertion — verified by a handler
  that inspects context.capabilities and the fact that the handler is never
  reached for non-remote-safe ops); remote_safe op populates capabilities;
  services/list peer-scoped hide/trusted variants; CallClient constructors;
  CallCredentials builder; Send+Sync.
- Integration (tests/two_node_call.rs): real QUIC loopback — CallAdapter
  server (self-signed cert via rcgen) accepts, CallClient connects,
  client.call() round-trips to server/echo. Proves the connect path +
  shared dispatch loop work end-to-end.

clippy + fmt + test all green.

Refs: tasks/call/client/call-client.md
Refs: docs/architecture/decisions/017-call-protocol-client-and-adapter-contract.md §1, §2, §7
Refs: docs/architecture/decisions/028-callclient-peer-scoped-registry-filtering.md
Refs: docs/architecture/crates/call/client-and-adapters.md
2026-06-26 13:19:15 +00:00
1e5f94b06b feat(call): OperationAdapter trait + AdapterError + from_jsonschema (ADR-017 §5)
- client module: defines the async OperationAdapter trait
  (import() -> Result<Vec<HandlerRegistration>, AdapterError>) and the
  #[non_exhaustive] AdapterError enum (string-message payloads: DiscoveryFailed,
  SchemaParse, Transport, Unauthorized, Conflict). The trait lives in alknet-call
  where the types live; implementations live with their transport deps.
- from_jsonschema: schema-only registration producing a FromJsonSchema-provenance
  HandlerRegistration with no real handler (placeholder errors if invoked),
  None authority/scoped_env, empty capabilities, remote_safe false (ADR-028 §4).
  Implements OperationAdapter; malformed (non-object) schema returns
  AdapterError::SchemaParse. No network I/O.
- Re-exported from lib.rs.
- Tests: trait compiles for Ok and Err adapters; from_jsonschema bundle shape;
  placeholder handler errors; OperationAdapter import Ok + SchemaParse paths.
  All 178+N tests pass, clippy + fmt clean.

Unblocks alknet-http Phase 1 (from_openapi/from_mcp adapter implementations).

Refs: tasks/call/client/operation-adapter-trait.md, tasks/call/client/from-jsonschema.md
Refs: docs/architecture/decisions/017-call-protocol-client-and-adapter-contract.md §5
Refs: docs/architecture/crates/call/client-and-adapters.md
2026-06-26 12:56:28 +00:00
e4a25947d6 feat(call): remote_safe field on HandlerRegistration (ADR-028)
Adds the v1 data shape for peer-scoped default-deny registry filtering,
the one-way-door piece of the call-completion batch (ADR-028):

- HandlerRegistration gains pub remote_safe: bool, defaulting false across
  all provenance (Local, Session, FromOpenAPI, FromMCP, FromCall,
  FromJsonSchema) per ADR-028 §4. HandlerRegistration::new() keeps its
  existing 6-arg signature (defaults remote_safe: false), so all current
  call sites compile unchanged.
- Chainable HandlerRegistration::remote_safe(bool) setter + a
  OperationRegistryBuilder::remote_safe() helper that marks the
  most-recently-registered op (tracked via last_name, not HashMap
  iteration order which is unspecified).
- Field is data-only here — the filtering behavior (dispatch path +
  services/list hide) is wired in call/client/call-client, not this task.
  services/list is unchanged.
- Tests: default false, setter flips field, all six provenance variants
  default false, builder setter marks last op, existing call sites
  unchanged. 178 tests pass, clippy clean.

Refs: tasks/call/registry/remote-safe-marking.md
Refs: docs/architecture/decisions/028-callclient-peer-scoped-registry-filtering.md
2026-06-26 12:51:18 +00:00
2649e068e5 docs(arch): call-completion — ADR-028 peer-scoped filtering + client-and-adapters spec + tasks
Resolves the four gap-analysis decisions (DC-1..4) blocking the alknet-call
client/adapter surface specced in ADR-017:

- ADR-028 (new): locks the one-way door for DC-1 — CallClient registry is
  default-deny (remote_safe: bool on HandlerRegistration, default false across
  all provenance); share-global is an explicit trusted-peer opt-in; filtering
  is a dispatch-time read over the single Layer-0 registry, not a copy.
- client-and-adapters.md (new spec): operationally fills the gap ADR-017 left
  to implementation — CallClient, from_call, from_jsonschema, OperationAdapter
  trait, adapter location map, no-env-vars invariant, exchange-of-operations
  pattern. Keeps call-protocol.md and operation-registry.md under the
  700-line split threshold.
- ADR-017 amended: records DC-2/3/4 v1 defaults (auto-on-reconnect,
  error-on-collision, Result error type) and points DC-1 at ADR-028.
- OQ-25..28 (new): two-way-door remainders (remote_safe shape, AdapterError
  variants, re-import trigger, namespace collision) with v1 defaults recorded.
- Index/cross-ref updates across READMEs and the two existing call specs.

Tasks: 6 task files under tasks/call/ decomposing the completion work along
the gap-analysis priority order — remote-safe-marking (one-way door, first)
→ call-client (phase-risk) → from-call → operation-adapter-trait →
from-jsonschema (parallel with call-client) → review-completion. Graph
validated with taskgraph; parallelism designed in (from-jsonschema runs
concurrent with call-client/from-call once the trait lands).
2026-06-26 12:25:13 +00:00
00edfc0889 feat(core): ADR-027 — RawKey decoupling, client cert request, ACME integration
Three tasks implementing ADR-027:

1. core/rawkey-decouple-from-iroh: TlsIdentity::RawKey now uses
   Ed25519SecretKey (alknet-core-owned wrapper over ed25519_dalek)
   instead of iroh::SecretKey. RawKeyCertResolver and Ed25519SigningKey
   un-gated from #[cfg(all(quinn, iroh))] to #[cfg(quinn)] only.
   Quinn-only builds (default) now support RFC 7250 raw-key identity.
   iroh transport converts via iroh::SecretKey::from_bytes.

2. core/endpoint-request-client-cert: replaced with_no_client_auth()
   with AcceptAnyCertVerifier — a custom ClientCertVerifier that
   requests client certs but doesn't require them or verify against
   a CA. alknet's identity model is fingerprint-based (the
   authorized_fingerprints set is the trust anchor), not PKI-based.
   Peer certs are extracted at the TLS layer for fingerprinting;
   peers without certs connect normally.

3. core/acme-integration: TlsIdentity::Acme variant (domains,
   cache_dir, directory, contact) + AcmeDirectory enum. TlsSetup
   two-phase construction: synchronous for X509/RawKey/SelfSigned,
   async for Acme (spawns AcmeState event loop, builds ServerConfig
   with ResolvesServerCertAcme). acme-tls/1 ALPN added when ACME is
   active; dispatch_quinn guard closes challenge connections
   gracefully (challenge is TLS-layer-handled). acme feature gate
   keeps rustls-acme out of non-ACME builds.

Workspace: build/test/clippy green across all 3 feature configs
(quinn-only, quinn+iroh, quinn+acme, all-features). 331 tests, 0
failures, 0 warnings.
2026-06-24 20:29:43 +00:00
d94d7a132a docs(adr-027): TLS identity redesign — ACME + RawKey decoupling
ADR-027 resolves the architectural gap surfaced when ACME integration
became a concrete target:

1. TlsIdentity::Acme variant — static config data (domains, cache_dir,
   directory, contact) with async AcmeState constructed at endpoint
   setup via two-phase TlsSetup (not stuffed into the Clone-able enum).

2. TlsIdentity::RawKey decoupled from the iroh feature — uses
   Ed25519SecretKey (alknet-core-owned wrapper over ed25519_dalek)
   instead of iroh::SecretKey. Raw-key TLS identity (RFC 7250, the
   default for most alknet nodes) now works in quinn-only builds.
   iroh transport converts via SecretKey::from_bytes.

3. ACME feature-gated behind new acme feature (rustls-acme optional
   dep). Non-ACME builds don't compile it.

4. dispatch_quinn guard for acme-tls/1 challenge connections — TLS-ALPN-01
   is handled at the rustls cert resolver layer during the handshake;
   the guard closes challenge connections gracefully instead of logging
   a misleading "no handler" warning.

Research confirmed QUIC (quinn) handles ACME challenges differently than
TCP (reverse-proxy): quinn gives no ClientHello peek hook, but the
challenge is fully answered at the cert resolution step before the
connection surfaces to the application. No handler registration needed.

Spec updates: config.md, endpoint.md, open-questions.md (OQ-12),
overview.md + README.md (ADR index), ADR-010 (cross-ref).

Tasks: core/rawkey-decouple-from-iroh (gen 1, no deps),
core/acme-integration (gen 2, depends on rawkey). Graph: 36 tasks.
2026-06-24 12:29:24 +00:00
97216764ea fix: resolve review #004 findings W1-W4 + close review gate
W1 (call/protocol/abort-cascade-wiring): wire AbortCascade into
CallAdapter handle_stream for EVENT_ABORTED. Cascades with
AbortPolicy::AbortDependents, aborts root, no descendant frames on
wire (ADR-016 Decision 2). Two integration tests added.

W2 (core/endpoint-client-fingerprint): extract TLS client cert
fingerprint in dispatch_quinn (SHA256:<hex> of leaf cert DER via
peer_identity) and dispatch_iroh (ed25519:<hex> of peer NodeId).
Fingerprint format documented in auth.md. Server config change
(with_no_client_auth → request-but-don't-require) deferred to new
follow-up task core/endpoint-request-client-cert.

W3 (vault/mnemonic-debug-redaction): replace Mnemonic derive(Debug)
with manual redacting impl (phrase: "[REDACTED]"). Seed confirmed
no Debug impl. Redaction test added.

W4 (core/auth-apikey-resources): Option B — drop entry.resources from
spec. External identities (token/fingerprint) grant scopes only;
resource-scoped ACLs are composition-internal (ADR-015/022). auth.md
corrected + limitation documented. Two tests confirm empty resources.

review-post-impl-fixes: all 4 verified, workspace green (326 tests,
0 failures, 0 clippy warnings). Review #004 status → resolved.

Graph: 34 tasks, 12 gens.
2026-06-24 11:00:54 +00:00
d149932e2a tasks: decompose review #004 findings into 4 fix tasks + review gate
W1 (call/protocol/abort-cascade-wiring): wire AbortCascade into CallAdapter
handle_stream for EVENT_ABORTED. W2 (core/endpoint-client-fingerprint):
extract TLS client cert fingerprint in dispatch_quinn/dispatch_iroh.
W3 (vault/mnemonic-debug-redaction): replace Mnemonic derive(Debug) with
redacting impl. W4 (core/auth-apikey-resources, level: research): decide
whether ApiKeyEntry should carry resources, then implement or drop from
spec. review-post-impl-fixes gates on all four. Graph: 33 tasks, 12 gens.
2026-06-24 10:02:03 +00:00
2c83e31e38 tasks: mark call/review-call completed — all 28 tasks done 2026-06-23 15:55:56 +00:00
93589d4f52 tasks: mark call/protocol/abort-cascade completed 2026-06-23 15:50:38 +00:00
bea19de3cf tasks: mark call/protocol/call-adapter completed 2026-06-23 15:39:54 +00:00
0d0f0f8da6 tasks: mark core/review-core completed 2026-06-23 15:33:16 +00:00
60556bbe0c tasks: mark core/endpoint and call/protocol/call-connection completed 2026-06-23 15:18:56 +00:00
7b92749acd tasks: mark core/endpoint completed 2026-06-23 15:16:33 +00:00
3484373d84 tasks: mark call/registry/service-discovery completed 2026-06-23 14:55:42 +00:00
4f10af2295 tasks: mark call/registry/operation-env completed 2026-06-23 14:53:42 +00:00
31fd8a73ac tasks: mark call/registry/handler-registration completed 2026-06-23 14:42:01 +00:00
c2c88833db tasks: mark call/registry/operation-context completed 2026-06-23 14:30:37 +00:00
de91f3bdb0 tasks: mark call/protocol/pending-request-map completed 2026-06-23 14:25:58 +00:00
dabb0d8b68 tasks: mark vault/spec-sync-remove-drift completed 2026-06-23 14:17:39 +00:00
482901db74 tasks: mark core/config completed 2026-06-23 14:16:38 +00:00
b93a85a280 tasks: mark vault/review-vault-sync and core/auth completed 2026-06-23 14:10:54 +00:00
20b5c640ec tasks: mark call/protocol/wire-types completed 2026-06-23 14:08:50 +00:00
e0ccdc28ac tasks: mark call/registry/operation-spec completed 2026-06-23 14:06:26 +00:00
669feab741 tasks: mark core/core-types completed 2026-06-23 13:54:28 +00:00
016c30691d tasks: mark call/crate-init completed 2026-06-23 13:47:49 +00:00
968e3a09ee tasks: mark vault/key-versioning-rotation completed 2026-06-23 13:39:37 +00:00
25327b41d4 tasks: mark vault/remove-password-derivation, vault/unlock-new-zeroizing-return, vault/poisoned-lock-recovery completed 2026-06-23 13:36:49 +00:00
1ac5585f84 tasks: mark vault/derivedkey-serialization completed 2026-06-23 13:32:35 +00:00
4078a8d8d5 tasks: mark vault/irpc-removal completed 2026-06-23 13:23:05 +00:00
e9d8896309 tasks: mark vault/cache-zeroization-test completed 2026-06-23 13:19:48 +00:00
ff50ccea09 tasks: mark core/crate-init completed 2026-06-23 13:14:06 +00:00
6056492128 tasks: mark vault/osrng-iv-generation completed 2026-06-23 13:12:10 +00:00
098fd8b9b9 tasks: decompose vault, core, call crates into 28 atomic implementation tasks
Break down the three initial crates (alknet-vault, alknet-core, alknet-call)
into dependency-ordered task files for implementation agents.

Structure:
- tasks/vault/ (10 tasks) — drift fixes from ADR-025/026 refactor, review,
  spec sync. Vault is independent and can run fully in parallel with core/call.
- tasks/core/ (6 tasks) — crate init, core types, config, auth, endpoint,
  review. Core is foundational; call depends on it.
- tasks/call/ (12 tasks) — split into registry/ and protocol/ topic subdirs
  reflecting the two subsystems. CallAdapter is the merge point.

Key decisions:
- Drifts 3+9+10 grouped as one task (key-versioning-rotation) — the complete
  ADR-021 rotation feature that doesn't compile in pieces
- Reviews injected at end of each crate phase (vault, core, call)
- Vault spec-sync task removes the drift table and bumps doc status to stable
- ACME deferred in core/endpoint (noted as TODO; X509 manual certs for now)
- OperationEnv kept as a trait (load-bearing for ADR-024 layering)

Validated: 28 tasks, no cycles, 11 generations of parallel work.
Critical path runs through call (11 tasks). Vault completes by generation 4.
6 high-risk tasks identified (21%): irpc-removal, endpoint, operation-context,
operation-env, call-adapter, abort-cascade.
2026-06-23 12:41:47 +00:00
b5a4600d74 greenfield: clean slate for ALPN-as-service pivot
Delete old source crates (alknet-core, alknet, alknet-napi), old
architecture docs (ADRs, specs, open questions), old research docs
(phase2, event-sourcing, feasibility, etc.), old tasks, and obsolete
reference material (gitserver/MPL, honker, nats, rustfs, polyglot,
keystone, distributed-identity).

Keep: alknet-secret (standalone, compiles), pivot docs, iroh and ssh
references, rudolfs reference (MIT/Apache, fork candidate), ops docs,
sdd_process.md, and licenses.

Previous implementation preserved at /workspace/@alkdev/alknet-main/
for reference during porting.

Workspace compiles: cargo check + 14 tests pass for alknet-secret.
2026-06-15 12:08:08 +00:00
bdb0b604e9 fix(secret): carry BIP39 passphrase in Unlock protocol variant
The Unlock variant had a single  field used as the
mnemonic, with no way to convey the BIP39 password extension (25th word).
The actor handler silently passed  for the passphrase, making it
impossible to unlock with a BIP39 passphrase via irpc.

Split into  +  to match
the spec and SecretServiceHandle::unlock() signature.
2026-06-10 09:26:17 +00:00
bda18f6bef docs(architecture): sync secret-service spec with implementation and add unlock-passphrase-gap task
Update secret-service.md to reflect the actual alknet-secret implementation:
- Fix dependency names/versions: secp256k1 (not libsecp256k1), version 0.29,
  add tokio/irpc-derive/hmac/rand, use workspace refs
- Add SecretServiceActor and CacheConfig to public API
- Add ethereum.rs module to crate structure, fix test_vectors.rs filename
- DerivedKey is move-only (not Clone), matching the stronger security impl
- Update BIP39 pseudocode to actual derive_path_from_seed() API
- Document derive_password_string() convenience method
- Document SecretServiceActor::spawn() in irpc integration model
- Update Unlock variant to target state: { mnemonic, passphrase: Option }
- Add implementation gap note pointing to unlock-passphrase-gap task

Add tasks/integration/phase3/secret-service/unlock-passphrase-gap.md:
- Fix Unlock protocol variant to carry both mnemonic and BIP39 passphrase
- Currently the irpc message only has passphrase: String (used as mnemonic)
- The handle supports both parameters but the protocol can't convey them
2026-06-10 09:18:59 +00:00
e827e7d61f chore: update task review-alknet-secret-spec-conformance status to completed 2026-06-10 07:44:13 +00:00
1942e2c2cb chore: update task irpc-secret-protocol-integration status to completed 2026-06-10 07:43:02 +00:00
47968ee48d chore: update task key-caching-ttl status to completed 2026-06-10 07:33:15 +00:00
2d5113cc1f chore: update task secp256k1-ethereum-derivation status to completed 2026-06-10 07:30:36 +00:00
fb77338ace chore: update task derive-password-implementation status to completed 2026-06-10 07:29:06 +00:00
7bf0538416 chore: update task crypto-test-vectors status to completed 2026-06-10 07:05:25 +00:00
31936ef008 chore: update task derivedkey-zeroize-security status to completed 2026-06-10 06:17:15 +00:00
74a9dafb57 chore: update task encryption-salt-kdf status to completed 2026-06-10 06:11:30 +00:00
c88e97d7d5 chore: update task spec-update-secret-service status to completed 2026-06-10 06:08:57 +00:00
83ea66b5d1 chore: prep Phase 3 tasks and workspace for alknet-secret development
- Add irpc (0.16) and irpc-derive (0.16) as workspace dependencies
- Add irpc, irpc-derive, and secp256k1 (optional) to alknet-secret Cargo.toml
- Clarify encryption-salt-kdf task: Option B (document salt as reserved) is the
  chosen path per spec update, removing Option A acceptance criteria
- Update irpc-secret-protocol-integration task with concrete irpc crate details:
  real crate on crates.io v0.16, #[rpc_requests] macro, workspace config,
  AuthProtocol pattern reference, DerivedKey serialization considerations
- Fix secp256k1-ethereum-derivation task: correct crate name is secp256k1
  (not libsecp256k1), add version pin 0.29
2026-06-10 05:57:27 +00:00