Skip to content

feat(phase-24): bug fixes & test infrastructure#361

Merged
FSM1 merged 24 commits into
mainfrom
feat/phase-24-bug-fixes-test-infrastructure
Mar 26, 2026
Merged

feat(phase-24): bug fixes & test infrastructure#361
FSM1 merged 24 commits into
mainfrom
feat/phase-24-bug-fixes-test-infrastructure

Conversation

@FSM1

@FSM1 FSM1 commented Mar 25, 2026

Copy link
Copy Markdown
Owner

Summary

  • Bug fix: Bin IPNS 404loadBin now auto-repairs missing IPNS records via publishWithVerify (publish + resolve-back verification with exponential backoff)
  • Bug fix: Device registry format error — Added v2 schema with lenient v1 migration (fills empty ipHash with zero placeholder), strict v2 validation, and SHA-256 ipHash computation in useAuth
  • Load tests: Headless sdk-core workloads — 3 new scenarios (upload pipeline, IPNS contention, folder read) calling sdk-core directly for bottleneck isolation, plus 401 interceptor with token refresh coalescing in client pool
  • Recovery tool simplification — Removed dead export file recovery mode (322 fewer lines), streamlined to 2-step IPFS-direct v2 blob path with Playwright E2E test
  • Code quality — Post-execution /simplify review fixed: publish-once-verify-retry pattern, computeIpHash reuse, validateRegistryShape dedup, buffer cleanup, pre-existing type error in byo-file-workload.ts

Test plan

  • @cipherbox/core — 171/171 tests pass (including 8 new registry v1→v2 migration tests)
  • @cipherbox/sdk — 69/69 unit tests pass (including 4 new bin auto-repair + publishWithVerify retry tests)
  • @cipherbox/crypto — 138/138 tests pass
  • @cipherbox/sdk-core — 88/88 tests pass
  • Regression gate — all prior-phase test suites pass
  • GSD verifier — 5/5 must-haves verified (BUGFIX-01, BUGFIX-02, TEST-01, TEST-02, TEST-03)
  • recovery.spec.ts E2E — requires API + IPFS running locally
  • Load test scenarios — require API + IPFS running locally

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Headless SDK load-test harness for IPNS, upload, and folder-read benchmarking.
    • Streamlined recovery tool UI into a simpler 2‑step Setup + Recover flow.
  • Bug Fixes

    • Bin IPNS auto-repair with publish-and-verify to recover missing records.
    • Device registry v2 rollout with migration handling from v1 and stricter v2 validation.
  • Tests

    • Playwright E2E for recovery workflow and multiple Vitest load scenarios with shared 401 refresh.
  • Documentation

    • Updated device registry schema/docs and Phase 24 planning/verification artifacts.

FSM1 and others added 18 commits March 25, 2026 23:01
Entire-Checkpoint: 0e18909127ac
Entire-Checkpoint: 91206e852405
Entire-Checkpoint: ec369f57c490
Entire-Checkpoint: 720d72c3e359
Entire-Checkpoint: 910fde1575a2
…t-pool

- Add createSdkContext() that builds SdkContext with axios 401 interceptor
- Add reAuthenticate() helper for /auth/test-login token refresh
- Shared refreshPromise coalesces concurrent 401 re-auth requests
- Include THROTTLE_BYPASS header support for rate limit bypass
- loadBin now auto-repairs when resolveIpnsRecord returns null by publishing
  empty bin metadata with sequenceNumber 1 (was silently returning 0)
- saveBinMetadata uses publishWithVerify for all bin IPNS publishes with
  resolve-back verification and exponential backoff retry (3 attempts)
- Updated tests: auto-repair returns sequenceNumber 1 and calls publish
- New tests: publishWithVerify retries on verify failure, auto-repair
  calls saveBinMetadata which uses publishWithVerify

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add sdk-core-workload.ts with IPNS publish, upload pipeline, folder read workloads
- Add sdk-upload-pipeline.test.ts measuring encrypt + pin + IPNS publish latency
- Add sdk-ipns-contention.test.ts measuring IPNS publish/resolve under concurrent load
- Add sdk-folder-read.test.ts measuring IPNS resolve + IPFS fetch + decrypt latency
- All scenarios use sdk-core directly without CipherBoxClient overhead
- All scenarios use MetricsCollector + expectThresholdsPassed harness
- Remove export file recovery mode (radio buttons, file upload, JSON paste)
- Consolidate 4-step flow into 2-step flow (Setup + Recover)
- Move gateway inputs into Step 1 alongside private key input
- Remove dead CSS classes (recovery-method, method-panel, migrated-notice, or-divider, file input styles)
- Remove export-related JavaScript (parseExportFile, file upload handlers, method toggle)
- Add data-testid attributes for Playwright E2E testing
- Preserve all v2 blob recovery logic unchanged

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 24-02-SUMMARY.md with execution results and deviation documentation
- Update STATE.md with plan progress and metrics
- Update ROADMAP.md with phase 24 plan progress
- Mark TEST-01 and TEST-03 requirements complete
- Create recovery.spec.ts that seeds a real vault with an uploaded file via SDK test harness
- Navigate to recovery.html, enter private key and localhost gateway URLs
- Verify progress log shows the uploaded file name after recovery completes
- Verify download button becomes visible on successful recovery
- Proper cleanup: destroy client, zero key material, delete test account
- Add @cipherbox/sdk to web-e2e devDependencies for test harness import

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ipHash

- validateDeviceRegistry now accepts v1 and v2: v1 migrated to v2 with
  lenient ipHash (empty string -> zero placeholder), v2 validated strictly
- DeviceRegistryVersion type added ('v1' | 'v2') and exported from barrels
- useAuth.ts computes SHA-256 hash of '0.0.0.0' for ipHash instead of ''
- device-registry.service.ts creates new registries as v2 from the start
- METADATA_SCHEMAS.md updated with v2 version history per evolution protocol
- Tests: v1 empty ipHash migration, v1 valid ipHash preservation, v2 strict
  validation rejects empty/invalid, round-trip tests updated for v2 output

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 5ccd2201275a
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 6e43032c9a7f
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: b0d0a05f9718
Entire-Checkpoint: d3b097785131
- publishWithVerify: publish once, retry only verification (was re-publishing on every attempt)
- useAuth ipHash: use existing computeIpHash() instead of inline SHA-256
- registry schema: extract validateRegistryShape() to deduplicate v1/v2 validation
- load test workload: clear plaintext buffer after upload (security hygiene)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 37a5c20d356d
…-block access

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 99ffacf26a3a
@coderabbitai

coderabbitai Bot commented Mar 25, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@FSM1 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 17 minutes and 52 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8edf2ba0-d359-45b8-bc7c-11c176f18596

📥 Commits

Reviewing files that changed from the base of the PR and between 35e3a51 and 113e25d.

⛔ Files ignored due to path filters (1)
  • packages/api-client/CHANGELOG.md is excluded by !packages/api-client/**
📒 Files selected for processing (25)
  • .planning/REQUIREMENTS.md
  • .planning/ROADMAP.md
  • .planning/STATE.md
  • .planning/phases/25-desktop-enhancements/25-01-PLAN.md
  • .planning/phases/25-desktop-enhancements/25-02-PLAN.md
  • .planning/phases/25-desktop-enhancements/25-03-PLAN.md
  • .planning/phases/25-desktop-enhancements/25-03-SUMMARY.md
  • .planning/phases/25-desktop-enhancements/25-RESEARCH.md
  • .planning/phases/25-desktop-enhancements/25-VALIDATION.md
  • .planning/phases/25-desktop-enhancements/25-VERIFICATION.md
  • CHANGELOG.md
  • apps/desktop/src-tauri/tauri.conf.json
  • apps/web/public/recovery.html
  • crates/api-client/CHANGELOG.md
  • crates/core/CHANGELOG.md
  • crates/crypto/CHANGELOG.md
  • crates/fuse/CHANGELOG.md
  • crates/sdk/CHANGELOG.md
  • packages/core/CHANGELOG.md
  • packages/crypto/CHANGELOG.md
  • packages/sdk-core/CHANGELOG.md
  • packages/sdk/CHANGELOG.md
  • packages/sdk/src/__tests__/integration.test.ts
  • tests/load/src/workloads/byo-file-workload.ts
  • tests/web-e2e/package.json

Walkthrough

Phase 24 marks completion of bug fixes and test-infrastructure work: adds bin IPNS publish+verify and auto-repair, introduces device registry v1→v2 validation/migration and exports, adds headless sdk-core load workloads with 401 refresh handling, simplifies the web recovery UI to IPFS-direct v2, and adds Playwright E2E and Vitest load tests.

Changes

Cohort / File(s) Summary
Phase 24 Planning & Docs
.planning/PROJECT.md, .planning/REQUIREMENTS.md, .planning/ROADMAP.md, .planning/STATE.md, .planning/phases/24-bug-fixes-test-infrastructure/*
Updates project metadata, marks Phase 24 complete, checks BUGFIX/TEST items, and adds context/research/plan/validation/verification summaries for Phase 24.
Bin IPNS Auto-Repair & Verify
packages/sdk/src/bin/index.ts, packages/sdk/src/__tests__/bin.test.ts
Adds publishWithVerify (publish → resolve verification with backoff/retries) and changes loadBin to auto-publish an empty bin (sequenceNumber 1) when IPNS is missing; updates tests to assert publish/verify behavior and new sequence numbers.
Device Registry v1↔v2 Migration & Types
packages/core/src/registry/schema.ts, packages/core/src/registry/types.ts, packages/core/src/__tests__/registry.test.ts
Introduces `DeviceRegistryVersion = 'v1'
Core Exports
packages/core/src/index.ts, packages/core/src/registry/index.ts
Re-exports DeviceRegistryVersion from registry module and from core barrel export.
Auth / Device Info Changes
apps/web/src/hooks/useAuth.ts, apps/web/src/services/device-registry.service.ts
useAuth now computes deviceInfo.ipHash via computeIpHash('0.0.0.0') instead of ''; initial registry default version changed to 'v2' when creating a first-device registry.
Recovery Tool Simplification
apps/web/public/recovery.html
Removes export-file recovery mode and multi-step UI; consolidates to 2-step Setup+Recover flow, removes export parsing handlers, and adds test attributes for E2E.
Metadata Schema Docs
docs/METADATA_SCHEMAS.md
Updates DeviceRegistry docs to describe v1/v2, migration semantics, and correct source paths (packages/core).
Headless SDK-Core Load Tests & Helpers
tests/load/src/harness/client-pool.ts, tests/load/src/workloads/sdk-core-workload.ts, tests/load/src/workloads/byo-file-workload.ts
Adds createSdkContext(pc) factory with axios-backed SdkContext and coalescing 401 refresh flow; new sdk-core workload module with prepareSdkClient and three workload runners; hoists cleanup-scoped variables in BYO workload.
Load Test Scenarios
tests/load/src/scenarios/sdk-upload-pipeline.test.ts, tests/load/src/scenarios/sdk-ipns-contention.test.ts, tests/load/src/scenarios/sdk-folder-read.test.ts
Adds three Vitest scenario tests that run headless sdk-core workloads across pooled clients, aggregate metrics, and assert p95/error thresholds.
Recovery E2E
tests/web-e2e/tests/recovery.spec.ts, tests/web-e2e/package.json
Adds Playwright E2E that seeds a test vault via SDK and validates recovery.html finds the uploaded file; adds @cipherbox/sdk as a devDependency.

Sequence Diagram(s)

sequenceDiagram
    participant LoadTest as Load Test Scenario
    participant PoolClient as Pool Client
    participant SdkContext as SDK Context
    participant SdkCore as SDK Core
    participant IpnsGateway as IPNS Gateway
    LoadTest->>PoolClient: createClientPool()
    PoolClient->>SdkContext: createSdkContext(pc)
    SdkContext->>SdkCore: invoke sdk-core APIs (with dynamic token)
    loop workload cycles
        SdkCore->>IpnsGateway: createAndPublishIpnsRecord(...)
        IpnsGateway-->>SdkCore: publish ack
        SdkCore->>IpnsGateway: resolveIpnsRecord(ipnsName)
        alt resolve succeeds
            SdkCore-->>PoolClient: measure success
        else resolve fails
            SdkCore->>IpnsGateway: retry resolve (backoff) [publishWithVerify]
            SdkCore-->>PoolClient: measure eventual outcome
        end
    end
    LoadTest->>PoolClient: aggregateAndReport()
Loading
sequenceDiagram
    participant App as Web App
    participant DevRegistry as Device Registry Service
    participant Core as Core Registry Schema
    participant Ipns as IPNS Storage
    App->>DevRegistry: initializeOrSyncRegistry()
    DevRegistry->>Ipns: try resolve registry via IPNS
    alt registry missing
        DevRegistry->>Core: create initial registry (version: 'v2')
        DevRegistry->>Ipns: encrypt+publish registry
    else registry found (v1)
        DevRegistry->>Core: validateDeviceRegistry(v1)
        Core-->>DevRegistry: migrate to v2 (empty ipHash -> zero placeholder)
    end
    App->>DevRegistry: register device with computed ipHash
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(phase-24): bug fixes & test infrastructure' clearly summarizes the main changes across the PR, which includes bin IPNS auto-repair, device registry v1/v2 migration, headless load tests, and recovery tool updates.
Docstring Coverage ✅ Passed Docstring coverage is 94.74% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/phase-24-bug-fixes-test-infrastructure

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

TypeScript doesn't propagate type narrowing across function boundaries,
so obj.devices remains 'unknown' after validateRegistryShape validates it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: a3348518d54f

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
apps/web/public/recovery.html (1)

1102-1104: Consider clearer error message for base64 fallback removal.

The nested try/catch for base64 parsing appears vestigial since the subtitle now states "Private key (hex)" and the regex on line 1099 only matches hex. The base64 fallback silently fails and shows a generic error message.

Since the UI explicitly requests hex input, consider simplifying to hex-only parsing with a clearer error:

♻️ Suggested simplification
-        if (/^(0x)?[0-9a-fA-F]{64}$/.test(keyText)) {
-          privateKeyBytes = hexToBytes(keyText);
-        } else {
-          try { privateKeyBytes = hexToBytes(keyText); }
-          catch { try { privateKeyBytes = base64ToBytes(keyText); }
-          catch { showError(1, 'Could not parse private key. Provide 32 bytes as 64 hex characters.'); return; } }
-        }
+        try {
+          privateKeyBytes = hexToBytes(keyText);
+        } catch {
+          showError(1, 'Invalid private key format. Provide 32 bytes as 64 hex characters (with optional 0x prefix).');
+          return;
+        }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/public/recovery.html` around lines 1102 - 1104, Remove the vestigial
base64 fallback and make the error explicit: replace the nested try/catch that
attempts base64ToBytes with a single attempt to parse hex via hexToBytes
(operating on keyText -> privateKeyBytes) and on failure call showError with a
clear message like "Could not parse private key: expected 32 bytes as 64 hex
characters (hex only)". Ensure references to hexToBytes, privateKeyBytes,
keyText and showError are updated so only hex parsing is attempted.
tests/web-e2e/tests/recovery.spec.ts (1)

63-70: Consider using environment variables for gateway URLs.

The gateway URLs are hardcoded to http://localhost:8080. Per the Playwright config context (snippet 2), other tests may use different gateway configurations. Consider extracting these to environment variables for consistency:

+const IPFS_GATEWAY = process.env.IPFS_GATEWAY ?? 'http://localhost:8080';
+const IPNS_GATEWAY = process.env.IPNS_GATEWAY ?? 'http://localhost:8080';
+
 // Set gateway URLs to localhost (Kubo + API)
 await page.locator('[data-testid="recovery-ipfs-gateway"]').clear();
-await page.locator('[data-testid="recovery-ipfs-gateway"]').fill('http://localhost:8080');
+await page.locator('[data-testid="recovery-ipfs-gateway"]').fill(IPFS_GATEWAY);

 await page.locator('[data-testid="recovery-ipns-gateway"]').clear();
-await page.locator('[data-testid="recovery-ipns-gateway"]').fill('http://localhost:8080');
+await page.locator('[data-testid="recovery-ipns-gateway"]').fill(IPNS_GATEWAY);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/web-e2e/tests/recovery.spec.ts` around lines 63 - 70, Replace the
hardcoded gateway URLs with environment-driven values: read
RECOVERY_IPFS_GATEWAY and RECOVERY_IPNS_GATEWAY (with a fallback to
'http://localhost:8080') and use those when filling the
page.locator('[data-testid="recovery-ipfs-gateway"]') and
page.locator('[data-testid="recovery-ipns-gateway"]') fields in recovery.spec.ts
so the test respects Playwright/test config or CI-provided overrides.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/__tests__/registry.test.ts`:
- Around line 99-110: The test's round-trip currently only asserts version,
device count, one deviceId and sequenceNumber; update it to assert the entire
devices array and other top-level fields are preserved during v1->v2 migration:
after calling encryptRegistry/encryptRegistry (encryptRegistry, decryptRegistry,
generateTestKeypair, createTestRegistry), assert decrypted.version === 'v2' but
assert decrypted.devices deep-equals registry.devices (including publicKey,
status, timestamps, ipHash and any other device fields) and that all other
top-level fields (e.g., sequenceNumber and any metadata) match the original
registry; this ensures only version is changed and no device data is lost.

In `@packages/core/src/registry/schema.ts`:
- Around line 74-80: The current mapping for devices aggressively replaces any
malformed ipHash with the zero placeholder; limit the auto-heal to only the
legacy empty-string case: inside the devices mapping (the code that calls
validateDeviceEntryBase and computes ipHash on each DeviceEntry), if d.ipHash
=== '' set ipHash to '0'.repeat(64); else require ipHash to be 64 hex chars
(HEX_REGEX and length check) and if it fails throw/propagate a validation error
(do not silently replace). Keep validateDeviceEntryBase call and preserve the
DeviceEntry spread logic, but change the conditional logic that sets ipHash
accordingly.

In `@packages/sdk/src/bin/index.ts`:
- Around line 188-202: The auto-repair path publishes an empty bin whenever
loadBinMetadataInternal returns null, which can conflate true "IPNS not found"
with transient failures (e.g., BAD_GATEWAY) from resolveIpnsRecord and cause
data loss; change the logic so loadBinMetadataInternal (or resolveIpnsRecord)
returns a distinguishable result or throws a typed error for transient failures,
and only call deriveBinIpnsKeypair + saveBinMetadata to create an empty
RecycleBinMetadata (using BIN_METADATA_VERSION and sequenceNumber:1) when you
have a definitive "not found" result; for transient/errors propagate the error
(or abort the auto-repair) and emit a clear warning log mentioning the operation
(loadBinMetadataInternal / resolveIpnsRecord) so callers can retry instead of
silently overwriting existing bin data.

---

Nitpick comments:
In `@apps/web/public/recovery.html`:
- Around line 1102-1104: Remove the vestigial base64 fallback and make the error
explicit: replace the nested try/catch that attempts base64ToBytes with a single
attempt to parse hex via hexToBytes (operating on keyText -> privateKeyBytes)
and on failure call showError with a clear message like "Could not parse private
key: expected 32 bytes as 64 hex characters (hex only)". Ensure references to
hexToBytes, privateKeyBytes, keyText and showError are updated so only hex
parsing is attempted.

In `@tests/web-e2e/tests/recovery.spec.ts`:
- Around line 63-70: Replace the hardcoded gateway URLs with environment-driven
values: read RECOVERY_IPFS_GATEWAY and RECOVERY_IPNS_GATEWAY (with a fallback to
'http://localhost:8080') and use those when filling the
page.locator('[data-testid="recovery-ipfs-gateway"]') and
page.locator('[data-testid="recovery-ipns-gateway"]') fields in recovery.spec.ts
so the test respects Playwright/test config or CI-provided overrides.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a6ceaa05-9674-4c20-8d38-216822995159

📥 Commits

Reviewing files that changed from the base of the PR and between 6dcbad0 and f9b4426.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !**/pnpm-lock.yaml
📒 Files selected for processing (33)
  • .planning/PROJECT.md
  • .planning/REQUIREMENTS.md
  • .planning/ROADMAP.md
  • .planning/STATE.md
  • .planning/phases/24-bug-fixes-test-infrastructure/24-01-PLAN.md
  • .planning/phases/24-bug-fixes-test-infrastructure/24-01-SUMMARY.md
  • .planning/phases/24-bug-fixes-test-infrastructure/24-02-PLAN.md
  • .planning/phases/24-bug-fixes-test-infrastructure/24-02-SUMMARY.md
  • .planning/phases/24-bug-fixes-test-infrastructure/24-03-PLAN.md
  • .planning/phases/24-bug-fixes-test-infrastructure/24-03-SUMMARY.md
  • .planning/phases/24-bug-fixes-test-infrastructure/24-CONTEXT.md
  • .planning/phases/24-bug-fixes-test-infrastructure/24-RESEARCH.md
  • .planning/phases/24-bug-fixes-test-infrastructure/24-VALIDATION.md
  • .planning/phases/24-bug-fixes-test-infrastructure/24-VERIFICATION.md
  • apps/web/public/recovery.html
  • apps/web/src/hooks/useAuth.ts
  • apps/web/src/services/device-registry.service.ts
  • docs/METADATA_SCHEMAS.md
  • packages/core/src/__tests__/registry.test.ts
  • packages/core/src/index.ts
  • packages/core/src/registry/index.ts
  • packages/core/src/registry/schema.ts
  • packages/core/src/registry/types.ts
  • packages/sdk/src/__tests__/bin.test.ts
  • packages/sdk/src/bin/index.ts
  • tests/load/src/harness/client-pool.ts
  • tests/load/src/scenarios/sdk-folder-read.test.ts
  • tests/load/src/scenarios/sdk-ipns-contention.test.ts
  • tests/load/src/scenarios/sdk-upload-pipeline.test.ts
  • tests/load/src/workloads/byo-file-workload.ts
  • tests/load/src/workloads/sdk-core-workload.ts
  • tests/web-e2e/package.json
  • tests/web-e2e/tests/recovery.spec.ts

Comment thread packages/core/src/__tests__/registry.test.ts
Comment thread packages/core/src/registry/schema.ts
Comment thread packages/sdk/src/bin/index.ts
@codecov

codecov Bot commented Mar 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.23810% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.56%. Comparing base (2bf8f4b) to head (113e25d).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
packages/core/src/registry/schema.ts 95.23% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main     #361       +/-   ##
===========================================
+ Coverage   59.45%   69.56%   +10.10%     
===========================================
  Files         126      105       -21     
  Lines        9213     6243     -2970     
  Branches      894      894               
===========================================
- Hits         5478     4343     -1135     
+ Misses       3530     1695     -1835     
  Partials      205      205               
Flag Coverage Δ
api 83.65% <95.23%> (ø)
api-client 83.65% <95.23%> (ø)
core 83.65% <95.23%> (ø)
crypto 83.65% <95.23%> (ø)
desktop 14.98% <ø> (-16.23%) ⬇️
sdk 83.65% <95.23%> (ø)
sdk-core 83.65% <95.23%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/core/src/registry/schema.ts 81.19% <95.23%> (ø)

... and 34 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

- Strengthen registry round-trip test assertions (toEqual full devices array)
- Tighten v1->v2 migration: only auto-heal empty ipHash, reject other malformed values
- Add warning log when bin auto-repair triggers for observability

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: ce99f1a94aea
Comment thread packages/sdk/src/bin/index.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses two user-facing bugs (bin IPNS 404s and device registry format errors) while expanding the test infrastructure with headless sdk-core load scenarios and a Playwright E2E test for the simplified vault recovery tool.

Changes:

  • Add bin IPNS auto-repair on missing record and introduce a publish-with-verify retry pattern, with updated unit tests.
  • Introduce device registry v2 schema with lenient v1 migration + strict v2 validation; ensure new registries write v2 and ipHash is always populated.
  • Add headless sdk-core load-test workloads/scenarios and a recovery tool E2E test; simplify recovery.html to IPFS-direct-only flow.

Reviewed changes

Copilot reviewed 32 out of 34 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/web-e2e/tests/recovery.spec.ts New Playwright E2E that seeds a vault via SDK harness and validates recovery.html output.
tests/web-e2e/package.json Adds @cipherbox/sdk to support importing the SDK E2E harness.
tests/load/src/workloads/sdk-core-workload.ts New headless workload helpers calling @cipherbox/sdk-core directly.
tests/load/src/workloads/byo-file-workload.ts Fixes workload variable scoping for cid/pinSize.
tests/load/src/scenarios/sdk-upload-pipeline.test.ts New headless upload pipeline load scenario with thresholds.
tests/load/src/scenarios/sdk-ipns-contention.test.ts New headless IPNS publish/resolve contention scenario with thresholds.
tests/load/src/scenarios/sdk-folder-read.test.ts New headless folder read-path scenario with thresholds.
tests/load/src/harness/client-pool.ts Adds createSdkContext() + reactive 401 refresh via /auth/test-login with refresh coalescing.
pnpm-lock.yaml Lockfile update for new workspace dependency.
packages/sdk/src/bin/index.ts Adds publishWithVerify() and auto-repair path in loadBin().
packages/sdk/src/tests/bin.test.ts Updates/adds unit tests for auto-repair + verify retry behavior.
packages/core/src/registry/types.ts Introduces DeviceRegistryVersion and updates registry typing for v1/v2.
packages/core/src/registry/schema.ts Adds v1→v2 migration + strict v2 validation logic.
packages/core/src/registry/index.ts Re-exports DeviceRegistryVersion.
packages/core/src/index.ts Re-exports DeviceRegistryVersion from the top-level barrel.
packages/core/src/tests/registry.test.ts Adds tests covering migration, strict v2 validation, and version handling.
docs/METADATA_SCHEMAS.md Updates DeviceRegistry docs to v1/v2 and documents version history.
apps/web/src/services/device-registry.service.ts Ensures newly created registries use version: 'v2'.
apps/web/src/hooks/useAuth.ts Computes and supplies an ipHash instead of an empty string.
apps/web/public/recovery.html Removes export-based recovery; consolidates to 2-step IPFS-direct recovery flow + testids.
.planning/phases/24-bug-fixes-test-infrastructure/24-VERIFICATION.md Adds Phase 24 verification report.
.planning/phases/24-bug-fixes-test-infrastructure/24-VALIDATION.md Adds Phase 24 validation strategy doc.
.planning/phases/24-bug-fixes-test-infrastructure/24-RESEARCH.md Adds Phase 24 research notes and rationale.
.planning/phases/24-bug-fixes-test-infrastructure/24-CONTEXT.md Adds Phase 24 context and decisions.
.planning/phases/24-bug-fixes-test-infrastructure/24-03-SUMMARY.md Plan 03 execution summary (recovery tool + E2E).
.planning/phases/24-bug-fixes-test-infrastructure/24-03-PLAN.md Plan 03 execution plan document.
.planning/phases/24-bug-fixes-test-infrastructure/24-02-SUMMARY.md Plan 02 execution summary (headless load tests + auth refresh).
.planning/phases/24-bug-fixes-test-infrastructure/24-02-PLAN.md Plan 02 execution plan document.
.planning/phases/24-bug-fixes-test-infrastructure/24-01-SUMMARY.md Plan 01 execution summary (bin + registry fixes).
.planning/phases/24-bug-fixes-test-infrastructure/24-01-PLAN.md Plan 01 execution plan document.
.planning/STATE.md Updates current project state to Phase 24 execution progress.
.planning/ROADMAP.md Marks Phase 24 complete and adds Phase 24 plan references.
.planning/REQUIREMENTS.md Marks Phase 24 requirements as completed.
.planning/PROJECT.md Updates “Last updated” text to reflect Phase 24 completion.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment thread apps/web/public/recovery.html Outdated
Comment thread tests/load/src/workloads/byo-file-workload.ts Outdated
Comment thread .planning/ROADMAP.md Outdated
Comment thread .planning/ROADMAP.md Outdated
FSM1 and others added 2 commits March 26, 2026 00:45
loadBin now auto-repairs by publishing an empty bin (sequenceNumber: 1)
instead of returning in-memory-only state (sequenceNumber: 0).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 2bfacfc945f8
- Remove vestigial base64 key parsing from recovery.html (hex-only for v2)
- Use `string | undefined` instead of definite assignment for cid/pinSize
- Mark phase 24 plan checkboxes as complete in ROADMAP.md
- Fix phase 24 progress table column alignment

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 321fdd002bac

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/sdk/src/bin/index.ts`:
- Around line 188-206: The integration test assertion for the auto-repair
behavior expects sequenceNumber 0 but the code (auto-publishing an empty bin via
deriveBinIpnsKeypair + saveBinMetadata which creates RecycleBinMetadata with
sequenceNumber: 1 and BIN_METADATA_VERSION) returns sequenceNumber 1; update the
integration test to assert expect(binState.sequenceNumber).toBe(1) so it matches
the implemented auto-repair behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 974d4c3a-10e0-4b67-82f7-916df753e8b6

📥 Commits

Reviewing files that changed from the base of the PR and between f9b4426 and 35e3a51.

📒 Files selected for processing (4)
  • packages/core/src/__tests__/registry.test.ts
  • packages/core/src/registry/schema.ts
  • packages/sdk/src/bin/index.ts
  • tests/sdk-e2e/src/suites/bin-operations.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/src/tests/registry.test.ts

Comment thread packages/sdk/src/bin/index.ts
FSM1 and others added 2 commits March 26, 2026 00:58
…es-test-infrastructure

# Conflicts:
#	.planning/PROJECT.md
#	.planning/REQUIREMENTS.md
#	.planning/ROADMAP.md
#	.planning/STATE.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: ad04870d8620
@FSM1 FSM1 enabled auto-merge (squash) March 26, 2026 00:00
@FSM1 FSM1 merged commit 2f1f93b into main Mar 26, 2026
25 checks passed
@FSM1 FSM1 deleted the feat/phase-24-bug-fixes-test-infrastructure branch March 27, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants