Skip to content

Release v2.90.0 - #2334

Merged
vilenarios merged 433 commits into
masterfrom
release-v2.90.0
Oct 21, 2026
Merged

vilenarios merged 433 commits into
masterfrom
release-v2.90.0

Conversation

@vilenarios

@vilenarios vilenarios commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Release v2.90.0

dev → master. Version 2.90.0 (pubspec.yaml). On staging since 152041bb0. 85 PRs since 2.89.0 (#2187–#2337, five of them dependabot bumps). A minor: nothing breaks for users, and links already in the wild keep resolving.

What's new

Snapshots are now drive state artifacts, on in production. Create snapshot publishes a drive's state as one SQLite file, and a sync reads a drive's newest one before replaying its history: one discovery query per drive, and any failure falls back to the normal sync. Snapshots made by CLI 5.0.0 and core-js are readable here too. Staging has run it since 2026-10-16. configVersion goes 3 → 4 so every install picks the switches up; that reset also puts a user's chosen gateway and their auto-sync, thumbnail and snapshot-sync toggles back to the defaults, as the bump in #2200 did. (#2187, #2188, #2197, #2264, #2268, #2270, #2271, #2281, #2296, #2303, #2306, #2324, #2335)

A faster, sturdier database in the browser. The web app's local database moves from sql.js to SQLite on the browser's private file system (OPFS), run in a background worker. Each user's existing data is copied over once, on the first load after the upgrade. Reopening takes 0.08 s instead of 3.5 s, and large writes no longer freeze the page. One tab owns the database at a time, so two tabs no longer overwrite each other's saves. Browsers without OPFS fall back to IndexedDB. The old store is left in place, untouched, as the way back. Schema 29 → 30 adds one nullable column. (#2197)

Open a drive without logging in. A link on the sign-in screen takes a drive link or a drive ID, asks for the drive key if the drive is private (filled in when the link carried it), and one press opens the explorer and syncs the drive. Browsing, previews, downloads and share links work as for a shared link; anything that needs a wallet is not offered. Logging in from the top bar keeps the drive, and a private drive opened this way keeps its key after login. A typed drive key never reaches the address bar, so a reload asks for it once. A visitor's New menu says "Open another drive"; "Attach drive" stays the signed-in word. (#2333, #2337)

Previews that show their progress. A preview downloads once and streams, instead of once per refresh. It says how far it has got ("18.2 MB of 47 MB", then "Decrypting…"), and a failed download offers Try again. PDFs, private media and images over 25 MiB wait for a Preview press; public video and audio still play straight away. Closing a preview stops its download. A playing private video no longer restarts when the drive syncs. (#2238, #2242, #2243)

Search as you type. Results drop down while you type, with keyboard navigation. Search says which drives it couldn't search because they aren't synced on this device, and offers to sync them. It no longer sticks on "Searching…" or opens a folder from another drive at its root. (#2287)

A shorter upload dialog. Cost and payment come first; thumbnails, license and deployment options sit behind Options. Counts and sizes match between the confirm and progress steps, and cost reads in credits everywhere. The license step is readable, and Creative Commons no longer preselects CC0. (#2283, #2291, #2314)

Wallet-paid (AR) uploads finish. Chunks a gateway rejects are retried, and Re-Upload resends the same signed transaction rather than paying again. The app warns you to keep the tab open while a wallet-paid upload runs. Turbo uploads are unchanged. (#2266)

Shared links open where they point. A folder link opens that folder for someone who doesn't have the drive. A drive or folder link pasted into a tab already running ArDrive opens what it names, and Back and Forward follow. The private folder share dialog says the link opens the whole drive. (#2289, #2294)

Your permanence. A new panel on the profile card shows how much you have preserved, what you have spent in credits and AR, what it would cost today (to the cent under $100), and a shareable image card. Its figures are kept for the session rather than fetched on every open. (#2244, #2326, #2329, #2330)

Manifests are now "deployments". Every place a user sees the word, in all six languages; "Import from manifest" keeps its name. New deployment opens in the folder you're viewing, leaves hidden folders out, and no longer drops a file whose path collides with another. Import from manifest works through gateways that refuse its query, and its results count imported and failed files correctly. (#2317, #2313, #2265, #2237, #2319)

First syncs of older drives are much faster. GraphQL queries go out with their fragments written out. turbo-gateway took about 8 s per query over old block ranges and now takes about 0.35 s. (#2267)

Smaller things

Fixes

Behaviour changes worth knowing

  • A second tab works on a copy. Only the first tab saves to the database. Another tab opened at the same time works on an in-memory copy, and what it stores locally (sync results) is dropped when it closes. Nothing on Arweave is affected. The second tab doesn't yet say so.
  • Large previews wait to be asked. See above.
  • A failed balance fetch reads as 0 AR until the next successful refresh, rather than blocking login. AR payment is unavailable during that time.
  • Logout clears drive keys and the preview cache from memory. Keys from shared private drives used to outlive logout.
  • A visitor's drives do not outlive their visit. Drives opened without logging in are cleared from this browser the next time the app starts with no profile, so they never show for the next person, or for whoever logs in next. Logging in during the visit keeps them. (feat: open a drive from the sign-in screen without signing in #2333)
  • "Log in" for a visitor no longer logs out first. It used to clear the drive being viewed and land on the drives list; it now keeps the drive. (feat: open a drive from the sign-in screen without signing in #2333)

Known issues, not fixed here

Internal

Golden drive state fixtures and a cross test with core-js (#2297); browser e2e tooling and guide, now with a journey for opening a drive without logging in (#2276, #2285, #2308, #2328, #2332, #2336); dart format on the files this release touched (#2331); staging deploys can't be overwritten by an older one (#2273); docs (#2275, #2305); dead Jira steps removed (#2286); dependabot bumps in web-pst and deploy (#1634, #1695, #1707, #2309, #2310).

Verified

🤖 Generated with Claude Code

https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9

vilenarios and others added 30 commits October 16, 2026 14:33
_ExpiresWhenStale told a new result from the one before it by how much
time it had left. Two fresh results each have the whole four seconds left
when they are drawn on the clock tick they finished in, so after the first
had expired the second found the slot already expired and stayed hidden.
It now resets on the announcement's identity as well.

In the app every result follows a running state, which resets the slot,
so this needed a sync to start and finish within one frame. It is what
made "a second result that reads the same is shown again" flaky: on
Windows' coarse clock both results sometimes landed on one tick.

The summary's remaining time now reads clock.now() rather than
DateTime.now(): the same time in the app, and in a widget test the clock
its timers run on, so the test fails every time without the fix rather
than now and then. clock moves from a transitive to a direct dependency
(same version).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4dehHVpH2fFgzitCz1yJ6
Staging showed "Create snapshot" and "Publish Drive State" side by side,
both promising a faster drive, and the Snapshots tab listed only one of
them. Users now see one term.

- every "Create snapshot" goes through promptToCreateSnapshot, which
  makes a drive state artifact wherever publishing one is offered for
  the drive (createsDriveStateSnapshot, the same gate the nudge used)
  and the older snapshot everywhere else, as before
- the separate "Publish Drive State" items in the New menu and the drive
  menu are gone
- the creation modal, its refusals and failures say snapshot rather than
  artifact, drive state or publish; two em dashes in them are gone too
- the Snapshots tab lists the drive's artifacts beside its older
  snapshots, newest first, wherever the build reads or publishes them; a
  pending artifact shows as pending
- a published artifact is announced to the tab as pending straight away,
  even if its modal was closed during the upload

Production is unchanged: publishing and reading are off there, so every
"Create snapshot" still makes the older snapshot and the tab lists only
those. Spec and code keep the term drive state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4dehHVpH2fFgzitCz1yJ6
GraphQL queries go out with their fragments written out (8 s to 0.2 s per old-range query)
Drive state none-found log names the block it searched from
A second sync result is shown even when it reads like the first
…nings

- costs show 4 decimal places, like the balances beside them ("0.0079 AR",
  not "0.007935750989 AR"); a cost too small for that reads "< 0.0001"
- the payment line reads "Wallet balance, 1.0619 AR available" or
  "Turbo Credits, 2.0370 available" instead of "Payment Method: Wallet
  Balance: 1.0619 AR"; cost and payment lines are localized
- the upload flow's buttons and titles use title case, as most of the app's
  dialogs do (Upload, Cancel, Skip, Replace, OK, Warning)
- the problem dialog's title, text and buttons are localized; "Do Not Fix"
  is now "Close"; closing with wallet-paid files unfinished asks first,
  since they may be paid for; the file list fits its files instead of
  leaving a large empty space
- the inline warning box fills its width in every dialog

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
Drive state spec and comments match the published format
Drive state artifacts are snapshots to the user
Two pushes to dev in quick succession each ran their own deploy, and
whichever run finished last owned gh-pages. On 2026-10-16 the #2270 merge
(04be6f2) finished its tests two minutes after the #2271 merge
(08bc4e3) and overwrote it, so staging ran dev without #2271.

- staging.yaml: one concurrency group for the workflow with
  cancel-in-progress, so a newer push cancels the older run still in
  progress and the newest commit is the one deployed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4dehHVpH2fFgzitCz1yJ6
The upload sheet picked the payment method from a dropdown that showed
only the selected method's cost. It now shows both ways to pay as option
cards, in the style the Turbo top-up uses to choose how to pay.

- each card has a radio dot, the method, its balance, and on the right
  what this upload costs with it
- a balance that can't pay says so on its card ("Not enough AR, 1.0619
  available"), in the error colour on the selected card; the separate
  "Insufficient AR balance" line is no longer repeated under the cards
- the keep-this-tab-open warning is hidden while the wallet can't pay,
  since there is no upload to keep the tab open for
- the new strings are localized; the dropdown and its two strings are
  removed, and useDropdown is renamed useOptionCards
- tests for the cards, and the credits-notice tests now run against them

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
When neither Turbo Credits nor the wallet's AR could pay for an upload,
the sheet said "add Turbo credits to your profile or use AR". It now
says "You don't have enough Credits or AR for this upload. Add Credits
to upload.", with the second sentence opening the top-up as before.
Both strings are localized.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
The concurrency group orders runs by when they were queued, not by
commit, so re-running an older dev run would still publish its build
over a newer one.

- deploy-web checks dev's head through the API before publishing and
  skips the download and deploy steps, with a notice, when this run's
  commit is no longer the head. Manual runs on other refs are left as
  they were.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4dehHVpH2fFgzitCz1yJ6
ui: choose how to pay for an upload from two option cards
With a workflow-level group that cancelled in progress, re-running an
older run cancelled the run for dev's head, and the older run then
skipped publishing as stale, so nothing published dev's head.

- the staging-deploy group moves from the workflow to deploy-web, with
  cancel-in-progress off. Tests and builds run in parallel as before;
  only publishing is one at a time, and the dev-head check decides
  which run publishes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4dehHVpH2fFgzitCz1yJ6
The dispatcher keeps each direct-to-network upload's signed data items
until it succeeds, so a retry resends the same transaction. A cancelled
upload is never retried (the cancelled screen offers only OK), so its
entry is now removed when the cancel makes send fail. Other failures
still keep theirs for Re-Upload.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
- ArweaveFS.md: a Drive State section beside Snapshot, with its tags and
  envelope, pointing to the published spec in ar-io-docs and to the
  schema a reader compares
- DRIVE_STATE_ARTIFACT.md §3.3 described the JSON payload D12 replaced:
  "serialise rows", seven sections with a rows array, and a JSON
  coverage example with version 1.0. It now describes the SQLite file,
  its nine tables and the meta row
- §6 records an open question: the read gate requires the exact frozen
  schema, so a 1.x minor that adds a table needs the gate to accept
  unknown tables
- DELIVERY_PLAN.md: status as of 2026-10-17. #2197 merged, the OPFS
  worker built, the first upload done by a human, staging rollout steps,
  and spec items 2.2 to 2.7 in review as ar-io/docs #192

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4dehHVpH2fFgzitCz1yJ6
fix: a staging deploy can't be overwritten by an older one
ui: tidy the upload dialogs' amounts, buttons, problem dialog and warnings
docs: drive state docs match the shipped format and the published spec
Conflict in sync_repository.dart: dev removed syncDriveById (no callers,
and it would have reset a drive's watermark to zero), which this branch's
second commit had given the name repair. The removal is kept; the repair
still runs at the two entry points that remain, syncAllDrives and
syncSingleDrive.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4dehHVpH2fFgzitCz1yJ6
… block

the drive list kept the first drive entity transaction the gateway listed
for each drive, on each page. HEIGHT_DESC does not order transactions
inside one block, so a rename and a hide in the same block could come back
in either order, and the rename's isHidden: false brought the drive back.

- keep one transaction per drive across every page
- the newer one wins: higher block, pending above mined, then the later
  Unix-Time, the order sync already uses within a block
- a missing or malformed Unix-Time loses a tie instead of throwing
- correct two comments that described the per-page duplicates

fixes #2245

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ksUKnnC1PGwNoUh6JNwZt
A guide and tools for testing a production web build the way a user
does: headless Chromium, logged in with the team's test wallet, clicking
through dialogs, uploading, and checking screenshots and a network log.

- docs/WEB_E2E_TESTING.md: rules, one-time setup, the run steps, test
  recipes (free and blocked Turbo uploads, wallet-paid uploads through a
  fake gateway, injected failures, ar-io.dev dry-run) and known quirks
- tool/web_e2e/launch.js: keeps the browser running behind a spend guard.
  Wallet-paid uploads go to a local fake gateway (or to ar-io.dev only
  while it answers as dry-run); Turbo uploads over the free 105 KiB, and
  all top-ups, are refused. File choosers are answered from a queue, and
  the keyfile is handed over only to the login
- login.js logs in from a new profile or unlocks an existing one; the
  keyfile goes in by path and the password is typed from a local file,
  neither printed
- step.js runs one step and screenshots it
- chaos_gateway.py checks every chunk's proof as a node does;
  chaos_report.py says whether every header got all its bytes
- CLAUDE.md points agents at the guide

The keyfile and password are read from ~/.config/ardrive-e2e/env and are
never in the repo.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
…rive list

getCommitTime throws a RangeError, not a FormatException, for a value
DateTime cannot hold, and that escaped getUniqueUserDriveEntityTxs and
failed discovery for every drive in the wallet.

- catch RangeError as well as FormatException
- test a missing, non-numeric and out-of-range Unix-Time, in both orders
- reword three comments that still said the list holds several
  revisions per drive

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ksUKnnC1PGwNoUh6JNwZt
the drive page skipped a tick whose folder contents matched what was
drawn, and ignored the drive row that came with it. rename drive writes
only the drive row, so the breadcrumb kept the old name.

rename drive also leaves the root folder's own name as it was, in this
app and in core-js, so a zip of the drive or of its root folder named its
top folder after the drive's old name while the zip file itself carried
the new one.

- compare the drive row as well as the contents before skipping a tick
- name a root folder after its drive when it goes into a zip
- give the shared test folder a parent, since a folder without one is now
  treated as a root

fixes #2246

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ksUKnnC1PGwNoUh6JNwZt
on web an out-of-range DateTime throws a plain ArgumentError, not the
RangeError the vm throws, so the previous commit's guard still let it
escape and fail the drive list in the build users run.

- catch ArgumentError, which RangeError extends, so both platforms are
  covered
- run the same cases in chrome through a browser-only wrapper, since ci
  runs only @teston('browser') files in a browser
- reword the last comment that still described duplicate drive ids

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ksUKnnC1PGwNoUh6JNwZt
- the no-op check's comment claimed it skips only when nothing visible
  changed; a watermark write or a re-encrypted private key now redraws
  once, and the comment says so
- pin that cost with a test: a watermark write redraws once, and the
  same write again redraws nothing
- the root folder branch in the zip conversion is a guard, since the
  explorer does not normally pass a root folder as a folder item; say so
  in the comment and the test name

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ksUKnnC1PGwNoUh6JNwZt
"Your successfuly created a snapshot of {driveName}!" becomes "You created
a snapshot of {driveName}.", and the string's description loses its
"sucessfuly". english only; the other locales read correctly.

fixes #2247

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ksUKnnC1PGwNoUh6JNwZt
…ls closed

- the guarded Turbo hosts are read from assets/config: those of every
  flavor except development. PR previews (development config) use testnet
  Turbo services, which are free and wiped after a few days, so they are
  let through; launch.js prints both lists at start
- a guard that throws now refuses the request instead of letting it pass
- the guide says which build to test (PR preview, staging, local), what
  testnet means for payment testing (free up to 5 MiB, so the payment
  choice needs a bigger file; the test wallet has no testnet credits),
  and adds the duplicate-name dialog to the known quirks

Tested on #2274's preview: login from an empty profile, sync, a 300 KB
testnet Turbo upload going through, and the payment cards for a 6 MB
file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
- "What to test" in the guide:
  - a change is tested from a plan written from its diff (normal path,
    each state the code distinguishes, light and dark mode, plus the
    checklist journeys in the same area)
  - a 13-journey release checklist runs on staging before a production
    release
  - each bug that reaches users adds a journey to the checklist
- .claude/skills/web-e2e: `/web-e2e <PR>` tests a PR's preview and
  `/web-e2e release` runs the checklist; it checks you can run, picks
  the build, writes the plan, runs it, and reports in a fixed format
  with the spending check
- .gitignore keeps .claude/ ignored except .claude/skills/, so project
  skills are shared
- CLAUDE.md points at the skill

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
Found by a browser test of the payment cards on the PR preview.

- with the wallet card selected (the default with no credits) and
  neither balance enough, the "Add Credits to upload." link never showed:
  the AR-short branch returned first. It now gives way to the both-short
  message under the cards
- with Turbo selected and the credits short, the cards still showed the
  hard-coded "Insufficient Credit balance for purchase. Add Credits to use
  Turbo.", repeating the Turbo card. They now show only the localized
  "Add Credits to upload." link. The radio list is unchanged

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
vilenarios and others added 10 commits October 20, 2026 19:44
…e review fixes

An extension wallet whose earlier credits reading was none or zero, with
AR paid directly, lost the "Refresh credits used" button and the "as of"
note. The AR-only tile now carries both.

Also: a clock that moved backward is stale, not current; the AR count is
re-checked after a minute, not half an hour, for ten minutes after this
app spends; an open no longer joins a read that began before the last
spend; and both writers to local storage check for a logout after the
store opens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ksUKnnC1PGwNoUh6JNwZt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ksUKnnC1PGwNoUh6JNwZt
39 of the 395 Dart files changed since 2.89.0 were not dart format clean
(CI doesn't check formatting). This formats exactly those 39 and nothing
else: whitespace, wrapping and trailing newlines only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
…ches up

- the save-dialog stand-in sends the bytes as requests launch.js routes,
  not through an exposed binding: every client attached over CDP hears a
  binding call, and step.js answered it with "not exposed", so the app
  showed "File download failed" though every byte was saved
- the guide: the sync split button on a new profile, how to turn on the
  semantics tree for labels(), journey 7 at rate 1.0 then 0.3, the
  duplicate-file dialog's buttons, and copying assets/config for a WSL copy

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
Keep the refresh for extension wallets, and the other permanence cache review fixes
style: dart format the files this release touched
fix: e2e downloads finish while a step is attached
A visitor with a drive link or a Drive ID opens that drive from the landing
card. No wallet, no account, no second step. Public drives need nothing else;
a private drive opens with the drive key it was shared with. Signing in later
keeps the drive.

- landing card: one link, "Open it without signing in", opening a dialog
  that takes a Drive ID or any ArDrive link (including file links) through
  the route parser, looks the drive up, asks for a key when it is private,
  writes the drive row with no profile key and hands off to the router
- router: openDriveAsVisitor starts the drive's sync as the explorer builds
  (from the cubit factory and the route-link follower), signInKeepingDrive
  keeps the drive across login, and a private drive whose key is not in
  memory is prompted for once; cancelling lands on sign in
- carry-over: ProfileCubit awaits DriveDao.persistInMemoryDriveKeys before
  announcing the login, so a private drive opened as a visitor survives
- visitor strip above the explorer with Sign in; the top bar's Log in keeps
  the drive instead of logging out; the New button offers Open another drive
- visitor leaks closed: Create snapshot (desktop menu, Snapshots tab),
  License add/update, Your drives in the sync menu, the create-drive cards,
  private thumbnails, mobile share-to-app, new-window preview on private
  drives
- two pre-existing causes of a "Drive not synced" flash on a freshly opened
  drive: DriveDetailCubit's folder-not-found path emitted the unsynced state
  without the running-sync gate, and SyncCubit.syncMetadataOnly emitted idle
  over a running single-drive sync for a visitor
- ActivityCubit.performUninterruptableActivity is typed Future<void> and
  releases the flag in a finally

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A minor: 79 PRs since 2.89.0, all compatible. The web database moves to
SQLite on OPFS in a worker (each user's data is migrated once, on first
load, and the old store is kept), previews show progress and wait to be
asked for large files, search answers as you type, the upload dialog is
shorter, wallet-paid uploads retry and never pay twice, shared links open
where they point, and manifests are called deployments. Drive state
artifacts ship switched off in production.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
Keeps 2.90.0 in pubspec.yaml over master's 2.89.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: ardriveapp/ardrive-web/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 9a89820c-3140-4df0-9ed7-668bc7df850d

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
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

vilenarios and others added 9 commits October 20, 2026 21:30
- prod.json: enableSyncFromDriveState and enableDriveStatePublishing on, as
  staging has run them since 2026-10-16
- configVersion 3 -> 4, so users who already ran the app take the new config;
  without the bump their stored config keeps both off
- the flag rail test now expects staging and prod on, dev off

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4dehHVpH2fFgzitCz1yJ6
feat: turn drive state reading and publishing on in production
- the sync menu's build keeps its @OverRide; the helper above it is not one
- the drives cubit import is covered by blocs.dart now
- const preferences in the visitor metadata sync test

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…thing behind

From an adversarial review of this branch.

Keys and sessions:
- a link's drive key is tied to the drive the link named: selecting another
  drive drops it, and before it goes into memory it is checked against the
  drive, so a reload on drive A's link then a click on drive C no longer
  stores A's key on C's row at sign-in
- a key typed into the open-drive dialog is never written to the address bar
  (and so never into browser history); a reload asks for it once
- a start with no profile clears what an earlier visitor's session wrote:
  drive rows and their decrypted folder and file names no longer pass to the
  next visitor, or to whoever signs in next on that browser
- licensing in the details panel needs a signed-in owner; search builds its
  items as owned whatever the drive

Flow:
- a drive opened while another sync runs waits for it and syncs after,
  instead of staying unsynced
- the key prompt asks again after a new route, and a prompt that could not
  open does not use up its one try
- the dialog turns Open off the moment the drive id or key changes, keeps
  "doesn't look like a link" once said, and words a transaction link as a
  transaction, not a file

UX:
- one way to sign in: the visitor strip is gone, and the top bar's button
  is a red "Log in" (was an outlined "Login" beside a "Sign in" strip)
- a visitor's New menu says "Attach drive", as a signed-in user's does
- copy: "drive ID" mid-sentence, "without logging in"; unused strings and a
  duplicate key hint removed
- the landing link takes keyboard focus; its click is the only one counted
  as a landing-page click

Housekeeping: the analyzer issues that failed CI, sorted imports, comments
that narrated history, an unwrapped future, "Drive not synced" wording.

Tests: sign-in stores a visitor's key before ProfileLoggedIn, a start with no
profile clears visitor rows, a link key is dropped for another drive, a typed
key stays out of the url, and the dialog's three timing fixes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZiqyGae4T1gJLGGB29pR9
The details panel built the revision menu without its drive, so the
"public drives only" gate for Preview read an unknown drive as public and a
private revision still opened the transaction's encrypted bytes. The menu
now gets the drive, and Preview needs a drive known to be public.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- "Open a drive without logging in" on its own; the question above it said
  the same thing twice, and the unused string goes with it
- the link's semantics say it is a button
- clearing the drive key mid-check also ends the check, so the progress
  bar does not stay on for a key that is gone

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
feat: open a drive from the sign-in screen without signing in
Journey 15 covers the sign-in screen's "Open a drive without logging in":
a public drive by ID, a private drive by a keyed share link through the
New menu, and logging in from the explorer. It runs before journey 1, on
the fresh profile, because that is the state a visitor has.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
vilenarios and others added 2 commits October 21, 2026 15:20
docs: the release checklist opens a drive without logging in
The dialog it opens is titled "Open a drive" and the sign-in screen says
"Open a drive without logging in"; "Attach drive" is the signed-in word for
adding a drive to your own list, and stays there.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vilenarios
vilenarios merged commit 9cc6ffc into master Oct 21, 2026
1 check passed
@vilenarios
vilenarios deleted the release-v2.90.0 branch October 21, 2026 19:44
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.

1 participant