Skip to content

feat: integrate web client with node/v3 read and write runtime#588

Open
FSM1 wants to merge 200 commits into
mainfrom
feat/web-client-runtime-integration
Open

feat: integrate web client with node/v3 read and write runtime#588
FSM1 wants to merge 200 commits into
mainfrom
feat/web-client-runtime-integration

Conversation

@FSM1

@FSM1 FSM1 commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Phase 68.1 — Web Client Runtime Integration

Wires the v2.0 web app onto the node/v3 read + write chain (sealed nodes, the
WriteChildRef write plane, the AAD triad) so the full tests/web-e2e Playwright
suite passes against a real client → API → IPNS round-trip. Closes the phase's
WEB-01..04 success criteria.

Verification

  • Goal verification: passed — 5/5 roadmap success criteria (SC#5 carries two
    recorded human-approved deferral overrides).
  • Security audit: SECURED — 107/107 declared threats verified closed, 0 open.
  • Nyquist validation: compliant, 0 gaps.
  • SDK E2E gate: 100/101 (the one failure is tee-republish's local-TEE-stack env
    timeout, unrelated to this branch and pre-existing).
  • Unit suites: sdk-core 341 passed, sdk 293 passed, web 56 passed.

Write-plane correctness (the core of this phase)

The v2 → v3 cutover left a family of write-plane clobber bugs where a fresh device
or a concurrent writer could publish a record that silently erased another writer's
write capability. This branch fixes them and adds permanent regression coverage:

  • Cold-load writeKey recovery; batch uploads now insert WriteChildRefs (every
    web-uploaded file was previously un-editable); write shares are actually writable;
    moveItem re-homes the write link across folders (fixes the reported
    move-then-edit failure).
  • createFolder now rejects duplicate sibling names, matching uploadFile — the
    cutover had dropped this check for folders only.
  • CAS-merge write-body clobber (found during ship, confirmed real): on a 409,
    publishWithCas merged only the read-body and resealed the write-body with the
    stale writeChildren, dropping a concurrent writer's WriteChildRef. Now
    decodeRemote unseals the remote write-body and merge unions writeChildren by
    childId. Covered by concurrent-operations E2E.

SDK E2E coverage restored

The 11 D-01 stub-era quarantined suites are un-quarantined and modernized to the v3
contracts (read plane keyed by ipnsName, current share/invite DTOs, seq baseline 1),
restoring full cross-package publish/resolve coverage.

Review + hardening (this ship pass)

  • Removed dead post-cutover code across web and sdk-core.
  • CodeRabbit findings triaged and fixed: redactKeyPreview no longer renders raw
    private-key bytes; several key buffers zeroed on all failure paths (D-09);
    fail-closed grant handling in ShareDialog; stale-sequence guard on folder.store's
    fast path; file-node input validation; two bin-durability ordering fixes.

Deferred follow-ups (todos filed under .planning/todos/pending/)

  • Port the standalone recovery tool to v3, and rotation-durability SC-4 (the two
    approved verification overrides).
  • getWriteBodyParams transient-resolve-miss could seal an empty write-body — needs
    a holistic fail-open/fail-closed decision (flagged, not one-sidedly flipped).
  • Delete paths retain the removed child's WriteChildRef (write-chain growth; the
    68.1-02 write-link removal).
  • Restore-to-different-parent write re-homing; encryptedIpnsPrivateKey terminology
    rename; the sdk-e2e quarantine sweep; the pre-existing (non-CI) ipns.service.test
    mock gap.

Known non-blocking

  • Nested write-share up/breadcrumb restore (Greptile, deferred with a todo):
    navigating root → A → B and then going UP to A restores A without its per-depth
    write key (only the share root's writeKey is re-derived), so a write from that
    restored intermediate level fails at write-body unseal. Not data loss or a
    security hole — the write throws, and re-navigating from the share root restores
    write capability. The fix touches the writeKey lifecycle + zeroization and needs
    navigate-up-then-write e2e coverage, so it's tracked as a follow-up rather than an
    unverified tail-of-ship change.
  • tee-republish E2E requires the local TEE stack; its failure is environmental and
    identical on main.
  • apps/web unit tests are not run by CI (web is gated by web-e2e); a pre-existing
    broken ipns.service.test.ts mock is filed as a todo, not fixed here (out of
    scope, non-gating).

Test plan

  • pnpm --filter @cipherbox/sdk-e2e test → 100/101 (tee env only)
  • sdk-core / sdk / web unit suites green
  • sdk / sdk-core / web typechecks clean against rebuilt dists
  • CI (web-e2e, unit coverage, security gate, release preview) — pending on this PR

🤖 Generated with Claude Code

FSM1 and others added 30 commits July 2, 2026 14:05
Entire-Checkpoint: 47c7d1c18846
Entire-Checkpoint: b8f805f2a240
…lan 14)

Checker BLOCKER: resolveKinds (kind cache, plan 04) was never called on any
folder-load/navigation path, leaving the cache empty so every child defaulted
to folder and files were never recognized. Add plan 68.1-14 (wave 4, depends_on
01/04/05) invoking resolveKinds on owned (useFolderNavigation + folder.store)
and shared (useSharedNavigationActions + useSharedNavigation) render paths.
Plan 13 depends_on gains 68.1-14; noted per-wave smoke pass as future work.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Entire-Checkpoint: 8533336e3176
…ptyRootNode

- updateFolderMetadataAndPublish must seal a real write-body (ipnsPrivateKey +
  writeChildren) when writeKey is supplied, RED against current stub behavior
- publishEmptyRootNode helper does not exist yet in sdk-core vault module

Entire-Checkpoint: cbc0276c9637
- updateFolderMetadataAndPublish gains writeKey/writeChildren params; seals a
  real write-body (ipnsPrivateKey + writeChildren) when writeKey is supplied,
  preserving the zero-writeKey legacy path when it is omitted (D-03)
- Add publishEmptyRootNode to sdk-core vault module: publishes a new user's
  empty kind:root Node at IPNS sequence 1n with a write-body carrying the
  root ipnsPrivateKey, templated on createSubfolder's TEE-enrollment guards
- Export publishEmptyRootNode from the sdk-core barrel

Entire-Checkpoint: 29de6a54b46e
- FolderState gains writeKey; CipherBoxClientConfig gains optional rootWriteKey
  (self-bootstrap requires both rootIpnsKeypair and rootWriteKey; matches the
  existing rootIpnsKeypair optionality since host wiring lands in Phase 68.1-03)
- ensureFolderLoaded seeds the root FolderState from config and DFS-walks the
  write chain (SealedChildRef.readKeySealed + WriteChildRef.writeKeySealed) to
  recover each subfolder's readKey/writeKey/ipnsPrivateKey, registering every
  visited folder into folderTree (early exit on match); returns null on any
  structurally-unresolvable hop, matching requireFolder's existing fallback
- Crypto/AEAD failures (T-68.1-01-02/03) propagate as throws rather than being
  swallowed, mirroring navigateReadChain's fail-closed contract
- FolderTree now defensively copies + zeroes writeKey alongside folderKey
- registerFolder/loadFolder accept an optional writeKey (zero-fallback legacy
  path); fixed test fixtures (helpers.ts, bin.test.ts) broken by the new
  required FolderState.writeKey field

Entire-Checkpoint: 7b6f74a043fb
…d publishes

- Add CipherBoxClient.getWriteBodyParams: sources the folder's current
  writeChildren from in-memory metadata.writeBody when present, else unseals
  the on-wire node once per operation; legacy zero-fallback writeKey yields a
  write-body-less publish identical to pre-D-03 behavior
- Thread writeKey/writeChildren at every owned updateFolderMetadataAndPublish
  call site: renameItem, moveItem source+dest, deleteItem, uploadFile,
  uploadFiles batch
- Mirror the helper in bin/index.ts for addToBin and restoreFromBin publishes
  since the actual publish calls live there, not in client.ts
- This plan only PRESERVES existing writeChildren verbatim; WriteChildRef
  insertion/removal is owned by 68.1-02 and 68.1-07/09
- helpers.ts setupFolder fixture uses the zero writeKey legacy path so
  existing unit tests keep their no-network publish behavior

Entire-Checkpoint: f3d8b5c3bbf3
Mints a subfolder Node with its own write-body (ipnsPrivateKey +
empty writeChildren), publishes at seq 1n, then inserts a
SealedChildRef into the parent read-body and a WriteChildRef into
the parent write-body and republishes the parent. Adapts the
createSharedSubfolder build-path to the owned (non-share) write
chain and registers the new child in folderTree so it is
immediately usable without a reload.

Entire-Checkpoint: d97ed8ef3542
collectRemovedItemIpnsNames and collectBinEntryIpnsNames now walk a
removed item's subtree via the read-chain (resolveIpnsRecord +
fetchFromIpfs + unsealChildReadKey/unsealNode), sharing a bounded
DFS helper (collectDescendantIpnsNames, capped at
UNENROLL_COLLECT_CONCURRENCY) that returns every descendant IPNS
name for unenroll/unpin. An unreadable descendant is logged and
skipped (best-effort) rather than thrown, so empty-bin unpin never
wedges. collectRemovedItemIpnsNames now takes the parent readKey to
recover the removed item's own readKey from its SealedChildRef.

Entire-Checkpoint: 6f1e48046410
Content self-seal (phase 65) removes re-encrypt-on-move: a file
node's readKey is sealed under the parent's read-chain, so moving a
file across folders is a pure child-ref re-seal under the dest
parent's write-body, not a separate per-IPNS re-encrypt step. No
production callers import reencryptFileMetadataForFolderChange; the
only references are vi.mock() factories in three already-quarantined
legacy test files (pre-node/v3 FolderEntry/FilePointer types),
unaffected at runtime since vi.mock virtualizes the module path.

Entire-Checkpoint: 1efa6e5fd8a6
- New-user login branch publishes an empty kind:root Node via sdk-core
  publishEmptyRootNode at sequenceNumber 1n, registers the vault with
  the zero-crypto v2 API schema (ownerPublicKey + rootIpnsName only),
  and sets vault keys -- replacing the phase-63 throwing stub
- Both new-user and existing-user branches now feed rootWriteKey
  through to CipherBoxClientConfig so ensureFolderLoaded can recover
  the full write chain from root

Entire-Checkpoint: 4fa07782c100
- navigateToShare/navigateToSubfolder walk the Node v3 read-chain: ECIES
  unwrap readDescriptorRef for the share root, unsealChildReadKey (parent
  mirror generation) per subfolder hop, unsealNode to render children
- navigateUp/navigateToBreadcrumb restore prior levels from the in-memory
  nav stack with no network round-trip, re-seeding the SDK sharedFolderTree
  and zeroing discarded folderKeys
- downloadSharedFile walks the full grant-to-leaf chain via sdk-core's
  navigateReadChain and decrypts with the raw fileKey (base64 iv); handles
  behind-retry/revoked without throwing
- single-file shares (root kind file) switch to currentView file so the
  existing SharedFileBrowser effect downloads via the empty-path root-is-leaf
  case
- bridges the hex-encoded readDescriptorRef API contract into
  navigateReadChain's base64 contract; folder-ipns write keys still resolved
  via the existing per-share key fan-out

Entire-Checkpoint: 49728b53c7d7
Entire-Metadata-Task: none
Entire-Checkpoint: 96152c1e5bab
RED phase: createFileMetadata builds+seals a v3 file Node under fresh
readKey/writeKey, embeds sequenceNumber 1n in the built (not-yet-published)
IPNS record, and ECIES-wraps the file ipnsPrivateKey under a TEE public key
only when teeKeys is supplied (fail-closed otherwise).

Entire-Checkpoint: b68332e60d36
GREEN phase: createFileMetadata mints fileReadKey/fileWriteKey/Ed25519
keypair, builds+seals a v3 file Node, uploads it, and builds (without
publishing) the file's first IPNS record at sequenceNumber 1n for the
caller to batch-publish. upload/index.ts now threads the raw fileKey +
iv into createFileMetadata and surfaces fileNodeId/fileReadKey/
fileWriteKey on UploadResult (additive).

Deviation (Rule 1): updated upload.test.ts mocks/assertions that
hard-coded the retired fileKeyEncrypted/fileIv (hex) contract.

Entire-Checkpoint: fe120ce26003
…leContent

RED phase: resolveFileMetadata round-trips content published by
createFileMetadata (and fails closed when the IPNS record is missing);
downloadFileContent decrypts raw-fileKey content (base64 iv) for both
GCM and CTR.

Entire-Checkpoint: 7e293969a792
GREEN phase: resolveFileMetadata resolves the file IPNS name, fetches
the PublishedNode, and unseals content under the file readKey
(read-only, fails closed when the record is missing or the node is not
kind:'file'). downloadFileContent fetches a CID and decrypts with the
raw fileKey + base64 iv (GCM/CTR), mirroring the web layer's
downloadSharedFile pattern.

Entire-Checkpoint: f88062c6b322
…n file wrappers

RED phase: updateFileMetadata pushes the superseded content into version
history (capped at maxVersionsPerFile, returns prunedCids) and preserves
id/generation/createdAt on republish; addFileToFolder/addFilesToFolder
seal file read+write child refs into the parent and batch-publish the
file record(s); replaceFileInFolder publishes only the file IPNS record.

Entire-Checkpoint: e9dee7609765
GREEN phase: updateFileMetadata rebuilds the file Node preserving
id/generation/createdAt, optionally folds the superseded content
descriptor into version history (capped via capVersions, an adapter
over the existing mergeVersions utility), and republishes directly at
fileSequenceNumber+1 (single-shot, no CAS retry). registration.ts
addFileToFolder/addFilesToFolder seal file read+write child refs into
the parent (write-body-aware per 68.1-01) and batch-publish the file
record(s); replaceFileInFolder delegates to updateFileMetadata
(publishes only the file IPNS record, parent untouched).

sdk-core uploadFile/createFileMetadata/updateFileMetadata/registration
wrappers are now fully implemented — sdkCore.uploadFile no longer
throws.

Deviation (Rule 1): quarantined file.test.ts's legacy CAS+merge
describe.skip block now fails typecheck against the new concrete
updateFileMetadata signature (NodeContent/UpdateFileContentParams vs
the old unknown/unknown stub params); added @ts-nocheck matching the
existing folder.test.ts precedent for the same situation.

Fixed test fixtures in file-node.test.ts to use valid UUID node ids
(buildNodeAad requires parseable UUIDs) — surfaced only once real
sealNode/sealChildReadKey calls executed in Task 3's GREEN phase.

Entire-Checkpoint: c16fa402e0ca
Resolves the file node's readKey/writeKey/ipnsPrivateKey by walking the
parent shared folder's write-body (WriteChildRef matched by UUID), falling
back to getFileIpnsKeyFn only when no write link is recorded. Forwards
originalCreatedAt/originalVersions from the unsealed current file Node and
delegates to shareOps.updateSharedFile. Emits a file-only sharedFolder:updated
mirroring refreshSharedFolder. Derived keys are zeroed in finally (D-09).

Also ignores *.tsbuildinfo (tsc -b build artifact).

Entire-Checkpoint: 7afb6964a66b
…hain

Resolves the destination folder's read/write keys from share_keys (folder +
folder-ipns entries, ECIES-unwrapped via vaultPrivateKey), loads fresh dest
children via loadFolderMetadata (A1, never cached), and resolves the moved
child's UUID/kind/generation/readKey by unsealing the item's PublishedNode
through the source folderKey. Delegates to shareOps.moveInSharedFolder
(dest-before-src publish) and adopts only the SOURCE result. T-49-01
write-capability guard throws before any publish if either share_keys entry
is absent; derived dest/child keys are zeroed in finally, vaultPrivateKey is
never zeroed (D-09).

Extracted buildSharedWriteContextWithOverrides from
buildSharedWriteContextFromState so both the current shared-folder state and
a one-off destination context share the same addToIpfsFn/publishNodeFn seams.

Entire-Checkpoint: 60d1c705f4c2
…wrappers plan

Entire-Checkpoint: d8a0dfce25d4
…rite handlers

- renameItemHandler routes through client.renameInSharedFolder
- deleteItemHandler resolves childNodeId via PublishedNode envelope (NODE-03
  plaintext id) before calling client.deleteFromSharedFolder, which fails
  closed on a missing childNodeId (T-68.1-10-01)
- updateSharedFileHandler calls client.updateSharedFile directly (bypassing
  runWrite) so it throws on error, matching the file editor caller contract;
  getFileIpnsKeyFn falls back to share_keys keyType file-ipns
- All three read nothing back -- sharedFolder:updated is the sole ref writer
FSM1 added 12 commits July 3, 2026 19:01
…1-33

Rescores the phase 5/5 passed: both round-3 open items are fixed and
independently corroborated — writable-shares 10.3 (68.1-32
updateSharedSingleFile + web wiring, 5/5 unit re-run, green in-suite in
two full runs) and 10.4 (68.1-33 hybrid resolve-before-insert across
all three owner projection sinks, 11/11 unit re-run, green in-suite).
Closing full-suite artifact e2e-close-post33.txt is 2/205/2 with the
failure set exactly equal to the two human-approved deferrals (recovery
v2-tool port, rotation SC-4 API architecture), now recorded as
frontmatter overrides; the rotation in-suite setup failure is isolated
to hook flake via e2e-rotation-rerun.txt.

Entire-Checkpoint: b210411d5149
Un-quarantine the D-01 stub-era suites (folder-crud, file-operations,
batch-upload, bin-operations, share-operations, invite-link, ipns-consistency,
concurrent-operations, data-integrity, vault-lifecycle, error-cases) and
modernize them to the node/v3 contracts: read plane keyed by ipnsName, current
share/invite DTOs, removal of the redundant registerFolder that zeroed writeKeys,
and seq baseline 1. 100/101 pass (tee-republish remains a local-TEE-env failure).

Entire-Checkpoint: 9442ad88f927
…inputs

On a 409 conflict, publishWithCas merged only the read-body and resealed the
write-body with the stale closure writeChildren, silently dropping a concurrent
writer's WriteChildRef (child stayed readable but lost write capability) — the
write-plane clobber class this milestone exists to prevent, on the concurrent
merge path. decodeRemote now unseals the remote write-body and merge unions
writeChildren by childId (add-only, remote wins). Also add length validation to
the file-node create path, and remove the dead post-cutover folder helpers
(addFileToFolder/addFilesToFolder/replaceFileInFolder) superseded by inline
client logic.

Entire-Checkpoint: 60e3ce84cd36
createFolder now rejects duplicate sibling names, matching uploadFile's contract
(the v2->v3 cutover had dropped this check for folders while files kept it).
Thread publishedWriteChildren through adoptPublishedFolderState so the in-memory
write mirror can't re-drop a merged WriteChildRef; require metadata.writeBody
before descending a cached child in dfsFindFolder; zero the file node's fileKey
after resolveFileWriteChainKeys; and order bin restoreFromBin/getWriteBodyParams
before the durable metadata write so a throw can't leave a duplicate bin entry.

Entire-Checkpoint: 3bd76e0b270e
Delete post-cutover dead code (collectChildKeys and its concurrency helpers, the
createFileMetadata/updateFileMetadata delegates, the no-op share-permission and
pending-rotation stubs, isFilePointer/setKind/withConflictRetry, the unused
shareId preview option). Security/correctness review fixes: redactKeyPreview no
longer renders raw private-key bytes (hashed device id); zero metadata.fileKey and
newFileKey on all failure paths (D-09 terminal owner); add the stale-sequence guard
to folder.store's synchronous fast-path; treat an absent writeDescriptorRef and
undefined rootGeneration as fail-closed in ShareDialog; fix the shared-root download
path double-count and the unwrap-before-try loading-stuck bug; per-row version
download spinners; wire DetailsDialog to the kind cache; fresh array ref so the
post-resolveKinds re-render fires.

Entire-Checkpoint: f7952f2db912
isCoreKitTransientFailure now briefly waits for the error banner to render
instead of a point-in-time isVisible() check that raced the alert.

Entire-Checkpoint: 269e8a89167b
Entire-Checkpoint: 717d967efaf4
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 211 files, which is 61 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e8dffa4f-63e5-4d46-84e6-7ccfb7f78403

📥 Commits

Reviewing files that changed from the base of the PR and between 1b4f68b and 3f963db.

⛔ Files ignored due to path filters (6)
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-32/test-failed-10.4/test-failed-1.png is excluded by !**/*.png
  • packages/api-client/openapi.json is excluded by !packages/api-client/**
  • packages/api-client/src/generated/shares/shares.ts is excluded by !**/generated/**, !**/generated/**, !packages/api-client/**
  • packages/api-client/src/models/index.ts is excluded by !packages/api-client/**
  • packages/api-client/src/models/updateGrantDto.ts is excluded by !packages/api-client/**
  • packages/api-client/src/models/updateItemNameDto.ts is excluded by !packages/api-client/**
📒 Files selected for processing (211)
  • .gitignore
  • .planning/REQUIREMENTS.md
  • .planning/ROADMAP.md
  • .planning/STATE.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-01-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-01-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-02-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-02-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-03-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-03-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-04-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-04-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-05-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-05-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-06-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-06-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-07-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-07-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-08-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-08-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-09-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-09-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-10-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-10-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-11-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-11-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-12-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-12-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-13-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-13-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-14-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-14-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-15-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-15-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-16-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-16-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-17-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-17-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-18-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-18-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-19-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-19-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-20-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-20-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-21-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-21-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-22-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-22-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-23-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-23-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-24-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-24-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-25-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-25-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-26-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-26-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-27-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-27-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-28-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-28-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-29-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-29-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-30-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-30-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-31-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-31-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-32-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-32-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-33-PLAN.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-33-SUMMARY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-CONTEXT.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-LEARNINGS.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-PATTERNS.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-RESEARCH.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-SECURITY.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-VALIDATION.md
  • .planning/phases/68.1-web-client-runtime-integration/68.1-VERIFICATION.md
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-29/confirmation-last-run.json
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-29/full-run-last-run.json
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-30/writable-shares-last-run.json
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-32/last-run.json
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-32/test-failed-10.4/error-context.md
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-32/writable-shares-run1.txt
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-32/writable-shares-run2.txt
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-33/writable-shares-run1.txt
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-final/e2e-close-post33.txt
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-final/e2e-final2.txt
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-final/e2e-final3-post32.txt
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-final/e2e-fw.txt
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-final/e2e-rerun3.txt
  • .planning/phases/68.1-web-client-runtime-integration/artifacts/68.1-final/e2e-rotation-rerun.txt
  • .planning/phases/68.1-web-client-runtime-integration/deferred-items.md
  • .planning/todos/pending/2026-07-03-consolidate-web-shared-navigation-dup.md
  • .planning/todos/pending/2026-07-03-dedupe-sdk-write-plane-helpers.md
  • .planning/todos/pending/2026-07-03-download-progress-ux-decision-usefiledownload.md
  • .planning/todos/pending/2026-07-03-drop-discarded-per-upload-ecies-wrapkey.md
  • .planning/todos/pending/2026-07-03-hoist-base64tobytes-into-crypto-package.md
  • .planning/todos/pending/2026-07-03-port-recovery-tool-to-v3-vault-format.md
  • .planning/todos/pending/2026-07-03-reenable-quarantined-sdk-e2e-suites-on-v3.md
  • .planning/todos/pending/2026-07-03-remove-legacy-moveinsharedfolder-sharekeys-branch.md
  • .planning/todos/pending/2026-07-03-restore-to-different-parent-write-rehoming.md
  • .planning/todos/pending/2026-07-03-rotation-durability-sc4-relay-replay-unreachable.md
  • .planning/todos/pending/2026-07-04-delete-should-drop-writechildref-not-just-retain.md
  • .planning/todos/pending/2026-07-04-fix-broken-ipns-service-unit-test-mock.md
  • .planning/todos/pending/2026-07-04-getwritebodyparams-transient-resolve-miss-drops-write-chain.md
  • .planning/todos/pending/2026-07-04-nested-shared-write-key-lost-on-up-breadcrumb-restore.md
  • .planning/todos/pending/2026-07-04-remove-dead-getsharekeys-folder-ipns-path.md
  • .planning/todos/pending/2026-07-04-rename-ipnsprivatekeyencrypted-to-encryptedipnsprivatekey.md
  • .planning/todos/pending/2026-07-04-shared-nav-stack-stale-children-snapshot.md
  • apps/api/src/shares/dto/index.ts
  • apps/api/src/shares/dto/update-grant.dto.ts
  • apps/api/src/shares/dto/update-item-name.dto.ts
  • apps/api/src/shares/shares.controller.spec.ts
  • apps/api/src/shares/shares.controller.ts
  • apps/api/src/shares/shares.service.spec.ts
  • apps/api/src/shares/shares.service.ts
  • apps/web/src/components/file-browser/AudioPlayerDialog.tsx
  • apps/web/src/components/file-browser/ContextMenu.tsx
  • apps/web/src/components/file-browser/DetailsDialog.tsx
  • apps/web/src/components/file-browser/FileBrowser.tsx
  • apps/web/src/components/file-browser/FileListItem.tsx
  • apps/web/src/components/file-browser/ImagePreviewDialog.tsx
  • apps/web/src/components/file-browser/PdfPreviewDialog.tsx
  • apps/web/src/components/file-browser/SelectionActionBar.tsx
  • apps/web/src/components/file-browser/ShareDialog.tsx
  • apps/web/src/components/file-browser/SharedFileBrowser.tsx
  • apps/web/src/components/file-browser/SharedFolderRow.tsx
  • apps/web/src/components/file-browser/SharedMoveDialog.tsx
  • apps/web/src/components/file-browser/TextEditorDialog.tsx
  • apps/web/src/components/file-browser/VideoPlayerDialog.tsx
  • apps/web/src/components/file-browser/details/FileDetails.tsx
  • apps/web/src/components/file-browser/details/FolderDetails.tsx
  • apps/web/src/components/file-browser/details/VersionHistory.tsx
  • apps/web/src/components/file-browser/useFileBrowserActions.ts
  • apps/web/src/hooks/folder-helpers.ts
  • apps/web/src/hooks/useAuth.ts
  • apps/web/src/hooks/useFileDownload.ts
  • apps/web/src/hooks/useFileOperations.ts
  • apps/web/src/hooks/useFilePreview.ts
  • apps/web/src/hooks/useFileSize.ts
  • apps/web/src/hooks/useFileVersions.ts
  • apps/web/src/hooks/useFolderMutations.ts
  • apps/web/src/hooks/useFolderNavigation.ts
  • apps/web/src/hooks/useMutationFailureUx.ts
  • apps/web/src/hooks/useSharedNavigation.ts
  • apps/web/src/hooks/useSharedNavigationActions.ts
  • apps/web/src/hooks/useSharedWriteOps.ts
  • apps/web/src/hooks/useStreamingPreview.ts
  • apps/web/src/lib/clear-user-stores.ts
  • apps/web/src/lib/crypto/key-wrapping.ts
  • apps/web/src/lib/kind-cache.ts
  • apps/web/src/services/__tests__/share-item-name.test.ts
  • apps/web/src/services/download.service.ts
  • apps/web/src/services/file-metadata.service.ts
  • apps/web/src/services/invite.service.ts
  • apps/web/src/services/share.service.ts
  • apps/web/src/stores/__tests__/folder.store.test.ts
  • apps/web/src/stores/folder.store.ts
  • apps/web/src/stores/share.store.ts
  • apps/web/src/utils/fileTypes.ts
  • docker/docker-compose.yml
  • packages/sdk-core/src/__tests__/file.test.ts
  • packages/sdk-core/src/__tests__/file/file-node.test.ts
  • packages/sdk-core/src/__tests__/folder.test.ts
  • packages/sdk-core/src/__tests__/folder/write-body.test.ts
  • packages/sdk-core/src/__tests__/upload.test.ts
  • packages/sdk-core/src/file/index.ts
  • packages/sdk-core/src/folder/registration.ts
  • packages/sdk-core/src/index.ts
  • packages/sdk-core/src/upload/index.ts
  • packages/sdk-core/src/vault/index.ts
  • packages/sdk/src/__tests__/bin.test.ts
  • packages/sdk/src/__tests__/client-durable-registration.test.ts
  • packages/sdk/src/__tests__/client-extended.test.ts
  • packages/sdk/src/__tests__/client-file-ops.test.ts
  • packages/sdk/src/__tests__/client-upload-concurrency.test.ts
  • packages/sdk/src/__tests__/client-write-descriptor.test.ts
  • packages/sdk/src/__tests__/client-write-plane-recovery.test.ts
  • packages/sdk/src/__tests__/enumerate-shared-subtree.test.ts
  • packages/sdk/src/__tests__/helpers.ts
  • packages/sdk/src/__tests__/move-write-link-rehoming.test.ts
  • packages/sdk/src/__tests__/resolve-shared-subfolder-write-key.test.ts
  • packages/sdk/src/__tests__/update-shared-single-file.test.ts
  • packages/sdk/src/__tests__/upload-batch.test.ts
  • packages/sdk/src/bin/index.ts
  • packages/sdk/src/client.ts
  • packages/sdk/src/reencrypt.ts
  • packages/sdk/src/share/shared-write.ts
  • packages/sdk/src/state/folder-tree.ts
  • packages/sdk/src/state/shared-folder-tree.ts
  • packages/sdk/src/types.ts
  • tests/sdk-e2e/src/fixtures/test-harness.ts
  • tests/sdk-e2e/src/helpers/assertions.ts
  • tests/sdk-e2e/src/suites/batch-upload.test.ts
  • tests/sdk-e2e/src/suites/bin-operations.test.ts
  • tests/sdk-e2e/src/suites/concurrent-operations.test.ts
  • tests/sdk-e2e/src/suites/data-integrity.test.ts
  • tests/sdk-e2e/src/suites/error-cases.test.ts
  • tests/sdk-e2e/src/suites/file-operations.test.ts
  • tests/sdk-e2e/src/suites/folder-crud.test.ts
  • tests/sdk-e2e/src/suites/invite-link.test.ts
  • tests/sdk-e2e/src/suites/ipns-consistency.test.ts
  • tests/sdk-e2e/src/suites/share-operations.test.ts
  • tests/sdk-e2e/src/suites/vault-lifecycle.test.ts
  • tests/web-e2e/tests/full-workflow.spec.ts
  • tests/web-e2e/tests/move-restore-content.spec.ts
  • tests/web-e2e/tests/rotation-durability.spec.ts
  • tests/web-e2e/tests/share-itemname-backfill.spec.ts
  • tests/web-e2e/tests/share-itemname-encrypted.spec.ts
  • tests/web-e2e/tests/sharing-workflow.spec.ts
  • tests/web-e2e/utils/wallet-login-helpers.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/web-client-runtime-integration

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.

@greptile-apps

greptile-apps Bot commented Jul 3, 2026

Copy link
Copy Markdown

Greptile Summary

This PR connects the web client to the node/v3 read and write runtime. The main changes are:

  • Web file browsing, preview, download, upload, versions, move, and bin flows now use node/v3 metadata.
  • Shared navigation and writable share operations now use descriptor refs and write-chain recovery.
  • Share grant update APIs and generated clients were updated for writable grants.
  • SDK and sdk-core write-body helpers, folder recovery, and regression tests were added.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
apps/web/src/hooks/useSharedNavigationActions.ts Shared navigation now performs node/v3 read-chain descent and seeds writable shared-folder state during fresh navigation.
apps/web/src/components/file-browser/ShareDialog.tsx Share creation and grant upgrade/downgrade now use descriptor refs and explicit grant update calls.
packages/sdk/src/client.ts The SDK client now recovers owned and shared write-chain state and preserves write-body metadata across publishes.

Reviews (3): Last reviewed commit: "docs(68.1): capture nested shared-write ..." | Re-trigger Greptile

@github-actions github-actions Bot added release:sdk-core:feat Minor version bump (new feature) for sdk-core release:sdk:feat Minor version bump (new feature) for sdk release:web:feat Minor version bump (new feature) for web release:api:feat Minor version bump (new feature) for api labels Jul 3, 2026
Comment thread apps/web/src/services/share.service.ts
Comment thread apps/web/src/hooks/useSharedNavigationActions.ts
Comment thread apps/web/src/components/file-browser/ShareDialog.tsx
@github-actions github-actions Bot added release:tee-worker:fix Patch version bump (bug fix) for tee-worker release:cipherbox-fuse:fix Patch version bump (bug fix) for cipherbox-fuse release:cipherbox-sdk:fix Patch version bump (bug fix) for cipherbox-sdk release:desktop:fix Patch version bump (bug fix) for desktop labels Jul 3, 2026
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Release Preview

Package Bump Label Source
api minor release:api:feat Direct (feat commit)
cipherbox-fuse patch release:cipherbox-fuse:fix Cascade (api minor)
cipherbox-sdk patch release:cipherbox-sdk:fix Cascade (api minor)
desktop minor release:desktop:fix Cascade (api minor)
sdk minor release:sdk:feat Direct (feat commit)
sdk-core minor release:sdk-core:feat Direct (feat commit)
tee-worker patch release:tee-worker:fix Cascade (sdk-core minor)
web minor release:web:feat Direct (feat commit)

Cascade Details

  • sdk-core minor -> tee-worker patch (direct dependency)
  • api minor -> cipherbox-fuse patch (direct dependency)
  • api minor -> cipherbox-sdk patch (direct dependency)
  • api minor -> desktop patch (direct dependency)

FSM1 added 2 commits July 4, 2026 00:57
The updateGrant controller forwards writeDescriptorRef and clearWriteDescriptor
to the service (6 args); the spec's toHaveBeenCalledWith still expected 4. Assert
the full delegation so the strict arg-count check passes.

Entire-Checkpoint: 48baec5d145d
Entire-Checkpoint: 8358cb400c89
Comment thread apps/web/src/hooks/useSharedNavigationActions.ts
Comment thread apps/web/src/hooks/useSharedNavigationActions.ts
Comment thread apps/web/src/hooks/useSharedNavigationActions.ts
@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.70%. Comparing base (1b4f68b) to head (3f963db).

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main     #588       +/-   ##
===========================================
+ Coverage   66.42%   79.70%   +13.27%     
===========================================
  Files         153      116       -37     
  Lines       12716     9734     -2982     
  Branches     1457     1599      +142     
===========================================
- Hits         8447     7758      -689     
+ Misses       4031     1734     -2297     
- Partials      238      242        +4     
Flag Coverage Δ
api 79.70% <ø> (-4.10%) ⬇️
api-client 79.70% <ø> (-4.10%) ⬇️
core 79.70% <ø> (-4.10%) ⬇️
crypto 79.70% <ø> (-4.10%) ⬇️
desktop ?
sdk 79.70% <ø> (-4.10%) ⬇️
sdk-core 79.70% <ø> (-4.10%) ⬇️

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

Files with missing lines Coverage Δ
apps/api/src/shares/shares.controller.ts 71.18% <ø> (+0.87%) ⬆️
apps/api/src/shares/shares.service.ts 97.40% <ø> (-0.04%) ⬇️
packages/sdk-core/src/folder/registration.ts 90.38% <ø> (+7.58%) ⬆️
packages/sdk/src/client.ts 67.48% <ø> (-14.54%) ⬇️
packages/sdk/src/share/shared-write.ts 84.36% <ø> (+0.12%) ⬆️
packages/sdk/src/state/folder-tree.ts 80.00% <ø> (-1.09%) ⬇️
packages/sdk/src/state/shared-folder-tree.ts 93.18% <ø> (-1.82%) ⬇️

... and 36 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:api:feat Minor version bump (new feature) for api release:cipherbox-fuse:fix Patch version bump (bug fix) for cipherbox-fuse release:cipherbox-sdk:fix Patch version bump (bug fix) for cipherbox-sdk release:desktop:fix Patch version bump (bug fix) for desktop release:sdk:feat Minor version bump (new feature) for sdk release:sdk-core:feat Minor version bump (new feature) for sdk-core release:tee-worker:fix Patch version bump (bug fix) for tee-worker release:web:feat Minor version bump (new feature) for web

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant