Clone this repository
For self-hosted knots, clone URLs may differ based on your setup.
Download tar.gz
- Fix W3C DID Document parsing in discover_pds (was using PLC operation
format; plc.directory returns W3C format with different field names
and structure)
- Add protected resource metadata discovery (RFC 9728) so auth server
discovery works with Bluesky's entryway architecture
- Add DPoP nonce retry for PAR requests (bsky.social requires nonce
even for PAR)
- Add relay route GET /oauth/client-metadata.json serving AT Protocol
OAuth client metadata with dynamic client_id from public_url config
- Make wallet client_id dynamic (derived from configured relay URL)
instead of hardcoded, enabling external auth server compatibility
- Add tauri-plugin-log for iOS logging (tracing bridge via log feature)
- Add comprehensive tracing to entire claim flow (resolve, PDS auth,
verification, submission)
- Fix Secure Enclave key lookup in recovery.rs (use Reference::Key
pattern match instead of nonexistent as_sec_key method)
- Remove all 27 AC references from doc comments, test names, and assertion messages per CLAUDE.md convention
- Rename AC-prefixed tests to behavior-descriptive names:
- test_ac7_1_build_op_diff_includes_fork_cid -> test_build_op_diff_includes_fork_cid
- test_ac7_2_build_op_diff_restores_keys_and_services -> test_build_op_diff_restores_keys_and_services
- test_ac7_3_build_recovery_override_signs_with_device_key -> test_build_recovery_override_signs_with_device_key
- test_ac7_4_signed_recovery_op_serializes_camel_case -> test_signed_recovery_op_serializes_camel_case
- test_ac7_4_submit_recovery_override -> test_submit_recovery_override
- Delete two duplicate tests:
- test_ac7_5_recovery_window_rejects_expired (duplicate of test_check_recovery_window_expired)
- test_ac7_7_fork_point_with_multiple_unauthorized_ops (duplicate of test_find_fork_point_multiple_unauthorized_ops_in_sequence)
- Fix error variant mapping: store_plc_log and store_did_doc Keychain errors now map to RecoveryError::SigningFailed (not NetworkError)
- Add tracing::debug in find_fork_point error branch for better diagnostics
- All tests pass (14 passed, 2 ignored); no clippy warnings
- Add default cases to both error switch statements (onMount and handleSubmit) to catch any new RecoveryError codes and prevent silent error swallowing. Uses type assertion (as { message?: string }) to avoid TypeScript 'never' type issue after exhaustive case handling.
- Add submitting = false before onsuccess() in handleSubmit success path to ensure the button state is properly reset, matching the error path behavior.
- Reduce timer interval from 60000ms to 15000ms in onMount for more accurate countdown display on recovery deadline, balancing accuracy with performance.
- test_ac7_3_build_recovery_override_signs_with_device_key: Replace hardcoded timestamps with dynamic values using Utc::now(). Use (Utc::now() - Duration::hours(2)).to_rfc3339() for genesis and (Utc::now() - Duration::hours(1)).to_rfc3339() for the unauthorized op, ensuring timestamps remain within the 72-hour recovery window.
- test_ac7_3_build_recovery_override_signs_with_device_key: Fix add_identity failure by calling remove_identity first to clean up stale Keychain state, then expect() on add_identity to properly propagate errors instead of silently discarding them.
- test_ac7_4_submit_recovery_override: Apply same timestamp fix as test_ac7_3.
- test_ac7_4_submit_recovery_override: Apply same add_identity cleanup as test_ac7_3.
Root causes:
- Hardcoded timestamps from 2026-03-29 are now >72 hours old, exceeding the recovery window and failing check_recovery_window().
- Silently discarding add_identity errors masked Keychain stale state from prior test runs, causing cascading failures in device key lookup.
- C1+I1: Add build_recovery_override integration test verifying AC7.3 signing with device key.
This test sets up an identity with IdentityStore, generates real keys and signed operations,
starts a httpmock::MockServer serving an audit log with genesis + unauthorized op,
calls build_recovery_override with PdsClient pointed at the mock server,
and verifies the returned SignedRecoveryOp can be verified with device key (AC7.3),
includes the fork point CID as prev (AC7.1), and contains fork-point rotation keys (AC7.2).
Test is #[ignore] to skip in sandboxed environments as it requires socket binding.
- C2: Add clear documentation comment to test_ac7_4_submit_recovery_override explaining:
- This test requires the --ignored flag to run
- It requires socket binding which is blocked in sandboxed environments
- Provides exact cargo test command for running it
- M1: Remove vestigial #[allow(dead_code)] annotations from find_fork_point and check_recovery_window.
Both functions are actively called by build_recovery_override and do not need the annotation.
- M2: Fix error messages to clearly indicate Keychain failures vs network errors:
- Change "Failed to update cached log" to "Failed to cache updated PLC log in Keychain"
- Change "Failed to update cached DID doc" to "Failed to cache updated DID document in Keychain"
These changes clarify that storage failures are Keychain operations, not network operations.
Complete the CLAUDE.md updates that were partially done in Phase 4:
- Add recovery_override to +page.svelte navigation flow description
- Document AlertDetailScreen's new onoverride callback prop
- Document RecoveryOverrideScreen component props and behavior
- Add PdsClient accessor methods (plc_directory_url, client) to API docs
- Add recovery_state to AppState field list
- Add chrono workspace dependency and plc.directory GET /{did} endpoint
- Update plc.directory endpoint descriptions to include recovery flows
- Bump freshness dates to 2026-03-31