Skip to content

Batch 2026-10-05 (big): 30 PRs combined - #2085

Merged
joepio merged 94 commits into
developfrom
batch/2026-10-05-big
Oct 6, 2026
Merged

joepio merged 94 commits into
developfrom
batch/2026-10-05-big

Conversation

@joepio

@joepio joepio commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Before: about 30 open PRs waited separately, each needing its own run and its own rebase after every merge.

After: one tested commit. Batch 2 (#1948 link device to account, #1953 one profile form, #1956 faster branch runs, #1971 E2E encrypted conversations, #1972 passkey ceremony header, #2035 Flutter account package, #2053 cheap canvas undo, #2056 atomic.place tab title, #2057 table resource cell, #2058 small table fixes, #2061 storage map) plus #2072 (Sync page cloud ladder), #2073 (several served-domain suffixes), #2074 (one sign-in), #2077 (smaller chat messages), #2078 (bring-along e2e fix), #2079 (inline row data loss), #2080 (Retry-After), #2070, #2071, #2066, #2067, #2068, #1969, #1887, #1897 and #1920.

Left out because they conflict in logic with something in here: #2065 and #1892 (both rewrite the Sync page that #2072 also changed), #1531 and #1885 (Rust conflicts), #1870 (MCP, own run), and #1971 stays at the batch-2 version.

How: merged into batch 2, catalogs re-extracted with wuchale, tsc, pnpm run -r lint and cargo clippy clean. Paired saas lock branch of the same name. Note on #2077: it compresses stored values; old rows stay readable but a downgrade cannot read compressed rows.

Michiel de Jong and others added 30 commits September 29, 2026 23:34
)

A local query returns JSON-AD without snapshots, so the resources it hydrates
get a Loro doc rebuilt from values: new ops by a new peer, none of the
history. Two things followed.

- `addResource` wrote that doc back to the local database, replacing the
  history the query had just read its values from.
- The drive sync after a reload sends deltas from the version vectors the
  local database reported. None of them can apply to a rebuilt doc, so each
  parked as an incomplete import and waited on a full snapshot from the
  server. In the atomic-plugins money e2e the app a table offers sat under
  that repair past the ten seconds the test waited for it in "+ Add view"
  (#1846).

Now the store records which docs were rebuilt without history, does not
write them back, and replays an unappliable delta on the local database's
snapshot, which is by construction the base the server diffed against. The
server is asked only when that fails.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI run 36636664834 on candidate17b failed the delete resource @smoke
e2e with an unexpected browser warning:

  [Store] failed to recover missing state for <child>: Resource not found

After the reload, a sync delta for the nested folder parks as incomplete
and the store repairs it. With #1920 the repair first waits on the local
database, then asks the server; by then the test has deleted the parent,
the server cascaded to the child, and the server's not-found is correct.
The store warned and called failResource, which puts an errored copy of
a deleted resource back. Locally: 1 of 3 runs failed with #1920, 0 of 6
without it, 0 of 6 with this fix.

The repair now checks whether the subject was destroyed (or has a
destroy in flight): it skips the server fetch then, and a failure after
the delete is logged as info, without failResource. Unit tests in
sync-delta-local-base.test.ts cover both.

(cherry picked from commit 06c6e1b)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signup, the Share dialog and the invite accept card each had their own
name and picture form. They now share ProfileForm. The invite's
'Agent created!' dialog reuses the signup SecretStep, so the secret is
shown and confirmed the same way everywhere.
…ate cargo build-dir

scripts/run-branch.sh builds and serves any branch in its own worktree and
target dir (optionally behind a cloudflared https tunnel for phones and
tablets). build.rs now decides whether to rebuild the frontend from a content
hash instead of mtimes, so a fresh checkout or branch switch with identical
sources no longer pays minutes for a rebuild, and prints a line on the
terminal before the silent step. The wasm-pack cargo gets a private
CARGO_BUILD_BUILD_DIR: a global build-dir is shared by every cargo and one
running cargo run made every other build block silently at 0% CPU.
Portal consent and the integration proxy need to know which account an
agent belongs to. The only link so far was a sync enrollment, which needs
a drive and a paid plan or an invite, so a Free account was never
recognised. atomic-saas now links an agent to an account without a drive
(#138); this is the app's side of it.

Once the identity reconcile gate has settled on the identity the account
uses, it links that identity in the background, next to the device
directory: GET /api/agent-link, and when the account has no link or
another agent's, a challenge from POST /api/agent-link/challenge, signed
with createAuthentication like the enrollment proof, sent back to
POST /api/agent-link. One attempt per account and identity per session,
and it never throws.

Keys are compared in any spelling (both base64 alphabets, padded or not),
because the control plane answers the canonical unpadded base64url. An
account service without agent links, an unconfirmed email and an identity
linked to another account are left alone. A refused proof or a challenge
for another agent is reported to Sentry, since only a bug produces either.
Builds without an account service make no requests.
A checkbox sits left of each row number (on hover, always on touch). Once a row is ticked every row shows one and the toolbar next to the filter button shows the count with a delete button. Undo restores the whole batch.
Right-click a row's number for its resource menu. Right-clicking inside a shift+click or drag selection opens a menu that clears the values, sets one value in all of them, or deletes the rows they touch (one undo step). View tabs can be dragged to reorder them.
…r error toasts, fix stale rows after deleting a typed row
…ders in the account menu; undo the top bar change
Two people can message each other in a conversation only they can read.
The server that hosts it stores ciphertext; it still checks every write,
because the rights and signatures it needs stay readable.

- atomic_lib::conversation: an agent's X25519 encryption key, derived from
  its vault proof so every device has the same one; a keyring with one key
  per epoch, wrapped to each member; sealing and opening messages, bound to
  the conversation; report-by-reveal of a single message key. WASM exports
  for the browser.
- Ontology `conversations`: Conversation, SealedMessage, encryptionKey,
  conversationKeys, sealed, conversations.
- GET /conversations lists the conversations on the server the requester
  is in, so the other person finds one they did not start.
- A conversation is its own drive with read + append for its members and
  no writer, so nobody can change what someone else said.
- App: Messages section in the sidebar, "Message" on every avatar, a New
  message dialog, and the conversation page, which opens each message
  before ChatView shows it. Store.subscribeLive (as in #1949) keeps the
  conversation live. The app publishes the agent's key at start.
The managed passkey calls relied on a ceremony cookie that a linked device never keeps, so its finish call failed. The start response now carries the ceremony id and the finish call returns it in X-Passkey-Ceremony. The portal still reads the cookie when the header is absent.
Undo drained and rewrote every stroke in the Loro list and then serialized
up to 400 full stroke snapshots to localStorage, synchronously, per press.
replaceListItems now deletes and inserts only the changed middle of the
list, and the canvas writes its undo history once things settle (and on
pagehide / close).
The hosted distribution (VITE_ATOMIC_HOSTED_DISTRIBUTION) is called
atomic.place in the tab, description, splash caption, PWA manifest and
user-facing copy; a build from source keeps the neutral name AtomicServer.
Settings, account, sync and the other app pages now get their own title
(for example Settings · atomic.place) instead of the bare product name.
A pasted atomic:, did:ad: or http(s) subject is now a pick of its own, and
the agents with direct rights on the drive are offered next to the search
results, since their data is not in the drive and search never finds them.
Shows what the vault's storage is made of and how much can be freed, keeping
the part held only for undo separate and behind its own explicit button.
GET /drive-usage/breakdown returns every resource in a drive with its edit
history and file bytes. The app draws them as a squarified treemap with
drill-down and a sorted list, reachable from the sync page.
# Conflicts:
#	browser/CHANGELOG.md
# Conflicts:
#	CHANGELOG.md
#	browser/CHANGELOG.md
#	browser/data-browser/src/locales/de.po
#	browser/data-browser/src/locales/en.po
#	browser/data-browser/src/locales/es.po
#	browser/data-browser/src/locales/fr.po
# Conflicts:
#	browser/data-browser/src/locales/de.po
#	browser/data-browser/src/locales/en.po
#	browser/data-browser/src/locales/es.po
#	browser/data-browser/src/locales/fr.po
# Conflicts:
#	browser/data-browser/src/locales/de.po
#	browser/data-browser/src/locales/en.po
#	browser/data-browser/src/locales/es.po
#	browser/data-browser/src/locales/fr.po
joepio and others added 22 commits October 5, 2026 20:27
The recovery row now only shows when recovery needs you; once signed in,
the email lives in the account header.
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