438 Commits

Author SHA1 Message Date
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
d904dfc243 docs(reviews): add post-implementation sanity check #004
28-task implementation review across alknet-vault, alknet-core, alknet-call.
Zero critical findings; 4 warnings (W1: AbortCascade implemented but never
invoked by CallAdapter; W2: endpoint hard-codes tls_client_fingerprint=None;
W3: Mnemonic Debug leaks seed phrase; W4: ApiKeyEntry missing resources
field); 5 suggestions. Build clean, 332 tests pass, default clippy clean.
2026-06-23 22:13:20 +00:00
2c83e31e38 tasks: mark call/review-call completed — all 28 tasks done 2026-06-23 15:55:56 +00:00
4696c9a304 docs(call): record review-call pass — implementation conforms to spec (task: call/review-call)
Review of alknet-call crate against operation-registry.md, call-protocol.md,
and ADRs 005/012/014/015/016/017/022/023/024. All registry types, protocol types,
security constraints, and pattern consistency checks conformant. No source
deviations found. 159 tests pass; build/clippy/fmt/test clean.

Refs: docs/architecture/crates/call/README.md
2026-06-23 15:55:33 +00:00
23b76a240a docs(call): record review-call pass — implementation conforms to registry/protocol/ADR spec
call/review-call verified the alknet-call crate against operation-registry.md,
call-protocol.md, and ADRs 005/012/014/015/016/017/022/023/024. All
registry types, protocol types, security constraints (Capabilities
non-serializable/zeroized/immutable, metadata non-propagation, internal
ops -> NOT_FOUND, reachability bounds, UUID v4 request IDs), and pattern
consistency (OperationEnv trait, CompositeOperationEnv contains-probe,
authority switch, deadline inheritance) are conformant. 159 tests green;
build/clippy(fmt check) clean. No source changes required.
2026-06-23 15:55:10 +00:00
93589d4f52 tasks: mark call/protocol/abort-cascade completed 2026-06-23 15:50:38 +00:00
8aa384ccfa feat(call): implement abort cascade for nested calls (ADR-016) (task: call/protocol/abort-cascade)
Implement AbortCascade in protocol/abort.rs per ADR-016: PendingEntry stores
parent_request_id (Call & Subscribe) and a started flag for tree indexing.
AbortCascade::cascade_abort walks the call tree by parent_request_id and aborts
descendants per AbortPolicy (AbortDependents aborts all; ContinueRunning aborts
only unstarted via mark_started()). Returns sorted list of aborted IDs; unknown
root silently discarded. 20 unit tests covering depth-3 cascade, mixed
Call/Subscribe, determinism, both policies.

Refs: docs/architecture/crates/call/call-protocol.md
Implements: ADR-016
2026-06-23 15:50:05 +00:00
3317bc8d1a feat(call): implement abort cascade for nested calls (ADR-016) (task: call/protocol/abort-cascade)
- PendingEntry stores parent_request_id (Call and Subscribe) and started flag
  for abort-cascade tree indexing
- register_call/register_subscribe accept optional parent_request_id
- AbortCascade::cascade_abort walks the call tree by parent_request_id and
  aborts descendants per AbortPolicy (AbortDependents: all; ContinueRunning:
  unstarted only). Returns sorted list of aborted request IDs
- call.aborted for unknown request_id silently discarded (empty result)
- Composed child request_ids stay internal (not sent as call.requested)
- mark_started() tracks dispatch state for ContinueRunning decisions
- 20 unit tests covering AbortDependents/ContinueRunning, depth-3 tree,
  unknown root, mixed Call/Subscribe, determinism
2026-06-23 15:49:07 +00:00
bea19de3cf tasks: mark call/protocol/call-adapter completed 2026-06-23 15:39:54 +00:00
2ff09a728c feat(call): implement CallAdapter — ProtocolHandler for alknet/call (task: call/protocol/call-adapter)
Implement CallAdapter in protocol/adapter.rs: ProtocolHandler for ALPN
alknet/call with stream handling, per-request identity resolution (auth_token
overrides connection identity, falls back on failure), root context construction
(internal:false, deadline, capabilities+scoped_env from registration bundle),
env composition (CompositeOperationEnv with Layer 0 base + Layer 2 connection
overlay + optional Layer 1 session overlay), operationId leading slash stripped,
ResponseEnvelope→EventEnvelope conversion, PendingRequestMap sweeper, connection
drop fails all pending. SessionOverlaySource trait. 22 unit tests.

Refs: docs/architecture/crates/call/call-protocol.md
Implements: ADR-002, ADR-012, ADR-014, ADR-015, ADR-017, ADR-022, ADR-024
2026-06-23 15:39:28 +00:00
fc9f93e893 feat(call): implement CallAdapter (ProtocolHandler for alknet/call) with stream handling, identity resolution, root context construction (task: call/protocol/call-adapter)
- CallAdapter struct with registry, identity_provider, session_source, default_timeout (30s)
- new(), with_session_source(), with_timeout() constructors
- SessionOverlaySource trait defined (overlay_for) for agent-crate integration
- ProtocolHandler::alpn() returns b"alknet/call"
- handle() sets connection identity from AuthContext, spawns accept_bi loop,
  reads EventEnvelope frames via FrameFramedReader, dispatches call.requested
  to the operation registry, writes ResponseEnvelope as EventEnvelope via
  FrameFramedWriter
- Per-request identity resolution: AuthContext.identity used by default,
  auth_token in payload overrides via IdentityProvider::resolve_from_token();
  resolution failure falls back to connection-level identity
- build_root_context sets internal: false, deadline (now + default_timeout),
  capabilities and scoped_env from registration bundle, parent_request_id: None
- compose_root_env builds CompositeOperationEnv (Layer 0 curated base +
  Layer 2 connection overlay + optional Layer 1 session overlay)
- operationId leading slash stripped before registry lookup
- ResponseEnvelope -> EventEnvelope conversion (Ok -> call.responded,
  Err -> call.error)
- PendingRequestMap sweeper runs every 10s, evicts expired wire entries
- Connection drop: fail_all pending with INTERNAL "connection closed",
  return Ok(())
- Stream reset: FrameFramedReader error closes stream; other streams unaffected
- Handler panic: stream task isolated via tokio::spawn, sweep cleans entry
- Tests: alpn, constructors, slash strip, identity resolution (override/fallback),
  root context (internal=false, deadline, capabilities, scoped_env), env
  composition (layers aggregate, session overlay), dispatch round-trip,
  internal op from wire -> NOT_FOUND, ACL denied -> FORBIDDEN, auth_token
  overrides connection identity, unknown op -> NOT_FOUND, no-slash resolution,
  ResponseEnvelope -> EventEnvelope conversions
2026-06-23 15:38:50 +00:00
0d0f0f8da6 tasks: mark core/review-core completed 2026-06-23 15:33:16 +00:00
061069910b fix(core): gate RawKey TLS helpers on quinn+iroh for clean iroh-only builds (task: core/review-core)
Review of alknet-core found one issue: RawKeyCertResolver/Ed25519SigningKey/
std::path::Path were gated on #[cfg(feature = "iroh")] but only used in the
quinn TLS path — caused clippy -D warnings failures on iroh-only builds.
Re-gated to #[cfg(all(feature = "quinn", feature = "iroh"))]. All 4 feature
combinations now pass clippy -D warnings; 55 tests pass.

Review confirmed: all core types, config, auth, and endpoint implementations
are spec-conformant.
2026-06-23 15:32:23 +00:00
4774364c72 fix(core): gate RawKey TLS helpers on quinn+iroh for clean iroh-only builds (task: core/review-core)
The RawKeyCertResolver, Ed25519SigningKey, and std::path::Path imports
were gated on #[cfg(feature = "iroh")] but are only used in the quinn
TLS server-config path (build_rustls_server_config RawKey arm). With
iroh-only builds (--no-default-features --features iroh), these became
dead code and triggered clippy -D warnings failures.

Re-gated to #[cfg(all(feature = "quinn", feature = "iroh"))] so they
only compile when both features are active (the combination that
actually uses raw-key TLS via quinn). std::path::Path is now
#[cfg(feature = "quinn")] since it is only used by quinn's
load_cert_chain/load_private_key helpers.

Verified: cargo clippy passes with -D warnings across all four feature
combinations (none, quinn, iroh, quinn+iroh). cargo test --all-features
passes 55 tests. cargo fmt --check clean.
2026-06-23 15:31:42 +00:00
60556bbe0c tasks: mark core/endpoint and call/protocol/call-connection completed 2026-06-23 15:18:56 +00:00
c68050ae0f feat(call): implement CallConnection with imported-ops overlay and call/subscribe/abort (task: call/protocol/call-connection)
Implement CallConnection in protocol/connection.rs with Layer 2 imported-ops
overlay (Arc<RwLock<HashMap>>), register_imported/register_imported_all,
overlay_env() returning an OperationEnv that dispatches to imported ops,
and call()/subscribe()/abort() methods that open a stream, send call.requested,
register in PendingRequestMap, spawn a stream reader, and correlate responses
by ID. Connection drop drops the overlay. Exposed MockConnection +
Connection::from_mock in alknet-core for cross-crate testing. 9 new connection
tests (102 total in alknet-call).

Refs: docs/architecture/crates/call/call-protocol.md
Implements: ADR-012, ADR-017, ADR-024
2026-06-23 15:17:55 +00:00
7b92749acd tasks: mark core/endpoint completed 2026-06-23 15:16:33 +00:00
ddc6c07fea feat(call): implement CallConnection with imported-ops overlay (Layer 2) and call/subscribe/abort methods
Implements CallConnection in src/protocol/connection.rs representing an
established alknet/call connection (either direction). Holds the Layer 2
imported-ops overlay (ADR-024) as Arc<RwLock<HashMap>>.

- register_imported / register_imported_all add to the connection overlay
- overlay_env returns an OperationEnv dispatching to imported ops; contains()
  returns true only for ops in the overlay
- call() opens a stream, sends call.requested, registers in PendingRequestMap,
  spawns a stream reader, resolves on first call.responded
- subscribe() sends call.requested and yields call.responded until
  call.completed/call.aborted via a SubscriptionStream wrapping the mpsc receiver
- abort() sends call.aborted for the request ID and removes the pending entry
- connection drop drops the overlay (no explicit deregistration needed)

Exposes MockConnection trait and Connection::from_mock in alknet-core so
cross-crate tests can construct mock connections without real QUIC. Removes
two unused test helpers in env.rs that triggered dead-code warnings under
-D warnings. Adds parking_lot dep for the overlay RwLock and pending Mutex.

9 new connection tests (102 total in alknet-call). Clippy clean.
2026-06-23 15:16:10 +00:00
79bc6ffb31 feat(core): implement AlknetEndpoint, HandlerRegistry, accept loops, TLS identity, graceful shutdown (task: core/endpoint)
Implement the ALPN router and endpoint in endpoint.rs: AlknetEndpoint with
quinn+iroh accept loops (both feature-gated, both Option), HandlerRegistry
(new/register/get/alpn_strings with panic-on-duplicate), dispatch via
tokio::spawn by ALPN, AuthContext construction from connection
(alpn/remote_addr/fingerprint/identity), TLS identity modes (RawKey RFC 7250
via on-the-fly cert resolver, X509 from files, SelfSigned via rcgen),
EndpointError enum, graceful shutdown with drain timeout + force close.
ACME deferred as TODO per task spec. 55 tests (--all-features), 52 (default),
47 (no-default); clippy clean across all 3 feature combos.

Refs: docs/architecture/crates/core/endpoint.md
Implements: ADR-010
2026-06-23 15:14:26 +00:00
8d056a2b59 feat(core): implement AlknetEndpoint, HandlerRegistry, accept loops (quinn + iroh), TLS identity (RawKey/X509/SelfSigned), and graceful shutdown (task: core/endpoint) 2026-06-23 15:12:14 +00:00
3484373d84 tasks: mark call/registry/service-discovery completed 2026-06-23 14:55:42 +00:00
8cc16de9f0 feat(call): implement services/list and services/schema built-in operations (task: call/registry/service-discovery)
Implement services/list and services/schema in registry/discovery.rs: spec
constructors, factory handlers taking Arc<OperationRegistry>, JSON serialization
of OperationSpec (incl. error_schemas per ADR-023), leading-slash normalization
for services/schema, NOT_FOUND for unknown ops, INVALID_INPUT for missing name.
Both registered as Local provenance with empty authority/env/caps and empty
AccessControl.

Refs: docs/architecture/crates/call/operation-registry.md
Implements: ADR-023
2026-06-23 14:55:09 +00:00
bb4e32e849 feat(call): implement services/list and services/schema built-in operations (task: call/registry/service-discovery) 2026-06-23 14:54:17 +00:00
4f10af2295 tasks: mark call/registry/operation-env completed 2026-06-23 14:53:42 +00:00
99ef22db3e feat(call): implement LocalOperationEnv and CompositeOperationEnv (task: call/registry/operation-env)
Implement LocalOperationEnv (Layer 0 — Arc<OperationRegistry>, reachability check,
authority switch, fresh metadata, inherited deadline/env) and CompositeOperationEnv
(session → connection → base overlay dispatch via contains() probe per ADR-024).
ScopedOperationEnv checked before overlay dispatch. 13 new env tests (93 total).

Refs: docs/architecture/crates/call/operation-registry.md
Implements: ADR-024
2026-06-23 14:53:05 +00:00
7e824af022 feat(call): implement LocalOperationEnv and CompositeOperationEnv (task: call/registry/operation-env)
Expand the minimal OperationEnv trait from the operation-context task with
concrete dispatch implementations per ADR-024:

- LocalOperationEnv (Layer 0): wraps Arc<OperationRegistry>. invoke_with_policy
  runs the scoped_env reachability check (ADR-015/022), looks up the
  registration, then constructs a child OperationContext with internal: true,
  identity = parent.handler_identity.as_identity() (the ADR-015 authority
  switch), fresh metadata (HashMap::new() — ADR-014 security constraint, no
  parent metadata propagation), inherited deadline (parent.deadline, not a
  fresh 30s), inherited env (parent.env.clone() — Arc::clone per ADR-024), and
  the child's own composition_authority + scoped_env from its registration.
  contains() uses the default impl (returns true — curated registry contains
  everything it can dispatch).

- CompositeOperationEnv (per-call, ADR-024): composes session (Layer 1),
  connection (Layer 2), and base (Layer 0) trait objects. invoke_with_policy
  runs the same reachability check, then probes overlays in order via
  contains() (the overlay-dispatch contract from review #003 C9), dispatching
  to the first overlay that contains the op. contains() aggregates all layers.

The trait-object design is load-bearing: making OperationEnv concrete would
close the session-overlay and connection-overlay patterns. Same integration-
point pattern as IdentityProvider (ADR-004).

Tests cover: allowed/disallowed reachability, internal-flag propagation,
authority switch (child identity = parent handler_identity), fresh metadata,
inherited deadline, composite session-overlay dispatch, composite fall-through
to base, composite connection-overlay dispatch when session lacks op, and
composite contains aggregation.
2026-06-23 14:51:48 +00:00
31fd8a73ac tasks: mark call/registry/handler-registration completed 2026-06-23 14:42:01 +00:00
3aae9d1323 feat(call): implement handler registration and operation registry (task: call/registry/handler-registration)
Implement Handler, HandlerRegistration, OperationProvenance, OperationRegistry
(register/registration/invoke/list_operations), and OperationRegistryBuilder
(new/with_local/with_leaf/with_leaf_provenance/with/build) in registry/registration.rs.
invoke enforces visibility (Internal from wire → NOT_FOUND), ACL with authority
switch (internal: true → handler_identity.as_identity(), internal: false → caller
identity), and handler dispatch. 21 unit tests.

Refs: docs/architecture/crates/call/operation-registry.md
Implements: ADR-015, ADR-022, ADR-024
2026-06-23 14:40:50 +00:00
7345ef5442 Implement handler registration and operation registry
Implements the dispatch core for the call protocol per ADR-022 and ADR-024:

- Handler async closure type alias returning ResponseEnvelope
- HandlerRegistration bundle: spec, handler, provenance, composition
  authority, scoped env, capabilities
- OperationProvenance enum with all 6 variants (Local, FromOpenAPI,
  FromMCP, FromCall, FromJsonSchema, Session)
- OperationRegistry with register/registration/invoke/list_operations
- invoke flow: visibility check (Internal from wire -> NOT_FOUND),
  ACL with authority switch (internal: true -> handler_identity,
  internal: false -> caller identity), handler dispatch
- OperationRegistryBuilder with new/with_local/with_leaf/with_leaf_provenance/with/build
- make_handler helper for boxing async handlers
- 21 unit tests covering invoke, visibility, ACL authority switch,
  builder provenance, and lookup behavior
2026-06-23 14:40:13 +00:00
c2c88833db tasks: mark call/registry/operation-context completed 2026-06-23 14:30:37 +00:00
fbc30d281e feat(call): implement OperationContext, AbortPolicy, CompositionAuthority, ScopedOperationEnv (task: call/registry/operation-context)
Implement operation context types in registry/context.rs: OperationContext (10
fields, internal pub(crate) + is_internal()), AbortPolicy (AbortDependents
default), CompositionAuthority (none/new/as_identity for ACL), ScopedOperationEnv
(empty/new/allows), generate_request_id (UUID v4). Added minimal OperationEnv
trait in registry/env.rs (invoke/invoke_with_policy/contains) so the env field
compiles — operation-env task will expand with LocalOperationEnv and
CompositeOperationEnv. 37 unit tests.

Refs: docs/architecture/crates/call/operation-registry.md
Implements: ADR-015, ADR-022, ADR-024
2026-06-23 14:29:18 +00:00
3b9c480dad Implement OperationContext, AbortPolicy, CompositionAuthority, ScopedOperationEnv
Implements the operation context types in registry/context.rs (ADR-015,
ADR-022, ADR-024): OperationContext with all 10 fields (internal is
pub(crate) for writes, read via is_internal()), AbortPolicy enum with
AbortDependents default, CompositionAuthority with synthetic Identity
projection for ACL, ScopedOperationEnv reachability set, and
generate_request_id() (UUID v4). Adds a minimal OperationEnv trait
forward-declaration in registry/env.rs so the context env field compiles;
the operation-env task will expand it.
2026-06-23 14:27:46 +00:00
de91f3bdb0 tasks: mark call/protocol/pending-request-map completed 2026-06-23 14:25:58 +00:00
f92e7af13f feat(call): implement PendingRequestMap for call correlation (task: call/protocol/pending-request-map)
Implement PendingRequestMap in protocol/pending.rs with Call (oneshot) and
Subscribe (mpsc) entries, ID-based correlation (ADR-012), timeout-based eviction,
fail_all for connection close, and silent discard of unknown request IDs. 17 unit
tests.

Refs: docs/architecture/crates/call/call-protocol.md
Implements: ADR-012
2026-06-23 14:24:44 +00:00
e63a36ede0 Implement PendingRequestMap for call protocol
Correlates call.responded events back to call.requested by request ID
(stream-agnostic per ADR-012). Manages Call (oneshot) and Subscribe
(mpsc) entries with timeout-based eviction and fail_all on connection
close. Unknown request IDs are silently discarded.
2026-06-23 14:23:49 +00:00
dabb0d8b68 tasks: mark vault/spec-sync-remove-drift completed 2026-06-23 14:17:39 +00:00
d0f633c71d docs(vault): remove drift tracking artifacts, bump vault docs to stable (task: vault/spec-sync-remove-drift)
Remove the Known Source Drift table from vault/README.md. Remove all 'known
drift'/'current source uses X' prose from Security Constraints in README,
encryption.md, service.md (constraint statements preserved). Remove stale
ADR-025/postcard notes in protocol.md. Bump all 5 vault doc frontmatter to
status: stable. Update architecture/README.md vault doc statuses to stable
and Current State to remove 'pending ADR-025/026 refactor' language.

Refs: docs/architecture/crates/vault/README.md (drift cleanup)
2026-06-23 14:17:10 +00:00
482901db74 tasks: mark core/config completed 2026-06-23 14:16:38 +00:00
323ee85d40 docs(vault): remove drift tracking artifacts, bump vault docs to stable
The vault spec-to-implementation sync is complete. Remove the drift
tracking tools that were only needed during sync:

- Remove the Known Source Drift table from vault/README.md
- Remove 'known drift' / 'current source uses X' prose from Security
  Constraints sections in vault/README.md, encryption.md, and service.md.
  The permanent constraint statements (OsRng for IVs, zeroized drop,
  no unwrap, etc.) are preserved.
- Remove the drift paragraph in encryption.md Key Versioning.
- Remove stale 'to be updated per ADR-025' / 'postcard tests to be
  removed' notes in protocol.md References.
- Bump status: draft -> stable in the frontmatter of all vault docs
  (README, mnemonic-derivation, encryption, service, protocol).
- Update architecture/README.md: vault doc status entries to stable,
  Current State paragraph reflects vault implementation complete (no
  'pending ADR-025/026 refactor' language).
2026-06-23 14:15:13 +00:00
da5646bf46 feat(core): implement StaticConfig, DynamicConfig, AuthPolicy, ApiKeyEntry, RateLimitConfig, ConfigReloadHandle, TlsIdentity, ConfigError (task: core/config)
Implement all configuration types in config.rs: StaticConfig (drain_timeout=2s
default), TlsIdentity (X509/RawKey[iroh-gated]/SelfSigned), DynamicConfig
(Clone/Debug/Default, ArcSwap-reloadable), AuthPolicy (String fingerprints, no
russh), ApiKeyEntry (5 fields), RateLimitConfig (100/5 defaults),
ConfigReloadHandle (reload/dynamic via ArcSwap), ConfigError (thiserror, all
variants). iroh_relay and RawKey feature-gated to iroh. 14 unit tests.

Refs: docs/architecture/crates/core/config.md
Implements: ADR-003, ADR-010

# Conflicts:
#	crates/alknet-core/src/config.rs
2026-06-23 14:14:51 +00:00
e98cfa77d8 Implement core/config: StaticConfig, DynamicConfig, AuthPolicy, ApiKeyEntry, RateLimitConfig, ConfigReloadHandle, TlsIdentity, ConfigError
- StaticConfig: immutable startup config (listen_addr, tls_identity, iroh_relay, drain_timeout=2s)
- TlsIdentity enum: X509, RawKey (iroh feature-gated), SelfSigned
- DynamicConfig: hot-reloadable via ArcSwap (auth + rate_limits), derives Clone/Debug/Default
- AuthPolicy: authorized_fingerprints (HashSet<String>), api_keys (Vec<ApiKeyEntry>) — no russh dep
- ApiKeyEntry: prefix/hash/scopes/description/expires_at
- RateLimitConfig: max_connections_per_ip=100, max_auth_attempts=5
- ConfigReloadHandle: reload() atomic swap, dynamic() load_full
- ConfigError: thiserror enum with all variants

14 unit tests covering defaults, construction, atomic reload swap, and error displays.
2026-06-23 14:11:07 +00:00
b93a85a280 tasks: mark vault/review-vault-sync and core/auth completed 2026-06-23 14:10:54 +00:00
a4b4d89d8f feat(core): implement AuthContext, Identity, AuthToken, IdentityProvider, ConfigIdentityProvider (task: core/auth)
Implement authentication types in auth.rs: AuthContext (Clone, 4 fields),
Identity (Clone, PartialEq), AuthToken, IdentityProvider trait (resolve_from_
fingerprint + resolve_from_token), ConfigIdentityProvider (reads from
ArcSwap<DynamicConfig> on every call — hot-reloadable). Fingerprint resolution
via authorized_fingerprints HashSet, token resolution via alk_ prefix + SHA-256
hash + expiry check. Also implemented minimal config.rs types (DynamicConfig,
AuthPolicy, ApiKeyEntry, RateLimitConfig, ConfigReloadHandle) needed by auth —
aligned with architecture docs for the parallel core/config task to extend.

27 unit tests pass; clippy clean.

Refs: docs/architecture/crates/core/auth.md
Implements: ADR-004, ADR-011
2026-06-23 14:10:06 +00:00
d7d879a3fa vault: spec-conformance fixes from review (task: vault/review-vault-sync)
Review of vault crate against all architecture specs. Fixed 5 deviations:
1. EncryptionKey: removed Clone (now move-only per spec), added redacting Debug
2. EncryptionKey::new made private (cfg(test)), added pub(crate) key_bytes()
3. encrypt/decrypt made pub(crate) per encryption.md, low-level crypto tests
   moved from integration to unit tests
4. CachedKey refactored to wrap DerivedKey with cached_at/last_accessed fields
   per service.md, with key_type()/private_key()/public_key() accessors
5. Mnemonic::to_seed() unwrap() eliminated by storing validated Bip39Mnemonic
   (enabled bip39 zeroize feature for proper zeroization)

All 10 drift items verified resolved. 105 tests pass; clippy clean.

Refs: docs/architecture/crates/vault/README.md (review checklist)
2026-06-23 14:09:36 +00:00
20b5c640ec tasks: mark call/protocol/wire-types completed 2026-06-23 14:08:50 +00:00
8dc842b1f4 feat(core): implement AuthContext, Identity, AuthToken, IdentityProvider, ConfigIdentityProvider (task: core/auth)
- auth.rs: Identity, AuthContext, AuthToken, IdentityProvider trait, ConfigIdentityProvider
- ConfigIdentityProvider reads from ArcSwap<DynamicConfig> on every call (hot-reloadable)
- Fingerprint resolution via authorized_fingerprints; token resolution via alk_ prefix + SHA-256 hash + expiry check
- config.rs: minimal DynamicConfig, AuthPolicy (with resolve methods), ApiKeyEntry, RateLimitConfig, ConfigReloadHandle required by auth
- Unit tests: fingerprint resolution (known/unknown/empty), token resolution (valid/expired/unknown/wrong-hash/non-alk), config reload changes results immediately
- Add sha2, hex deps to alknet-core
2026-06-23 14:08:33 +00:00
55404e52a3 feat(call): implement wire protocol types and framing (task: call/protocol/wire-types)
Implement EventEnvelope, ResponseEnvelope, CallError, FrameError, and
FrameFramedReader/FrameFramedWriter with 4-byte big-endian length-prefixed JSON
framing in protocol/wire.rs. Added ResponseEnvelope helpers (ok/error/not_found/
forbidden) and ResponseEnvelope→EventEnvelope conversion. 20 unit tests.

Refs: docs/architecture/crates/call/call-protocol.md
Implements: ADR-005, ADR-012, ADR-023
2026-06-23 14:08:03 +00:00
41f0fc7843 vault: spec-conformance fixes from review (task: vault/review-vault-sync)
- EncryptionKey: remove Clone (move-only per spec), add custom redacting
  Debug impl, make new() private (cfg(test)), add pub(crate) key_bytes()
  accessor, make encrypt/decrypt pub(crate) module-internal helpers
- CachedKey: refactor to wrap DerivedKey (per service.md) with cached_at
  and last_accessed fields; add key_type()/private_key()/public_key()
  accessors
- Mnemonic: store validated Bip39Mnemonic to eliminate unwrap() in
  to_seed(); enable bip39 zeroize feature so inner is zeroized on drop
- Fix clippy: remove unused import in drop_tracker tests, use struct
  init syntax instead of field reassignment with Default
- Move low-level EncryptionKey round-trip/wrong-key tests from
  integration tests to unit tests (encrypt/decrypt now pub(crate))
2026-06-23 14:07:24 +00:00
c9898566b9 Implement call protocol wire types and framing
Implements src/protocol/wire.rs with:
- EventEnvelope (type/id/payload, JSON wire format with leading-slash op ids)
- ResponseEnvelope and CallError (with optional typed details, ADR-023)
- ResponseEnvelope::ok/error/not_found/forbidden helpers
- ResponseEnvelope -> EventEnvelope conversion (Ok -> call.responded, Err -> call.error)
- FrameFramedReader / FrameFramedWriter: 4-byte big-endian length-prefixed JSON frames
- FrameError: Io, Json, ConnectionClosed, InvalidFrame
- 20 unit tests covering round-trip, large payloads, truncated frames, helpers

Builds on the call/crate-init skeleton. See
docs/architecture/crates/call/call-protocol.md and ADR-005/012/023.
2026-06-23 14:06:48 +00:00