Skip to content

fix(onboard): store an added agent when it connects; update dependencies - #266

Merged
stormer78 merged 2 commits into
mainfrom
fix/onboard-commit-before-encrypt
Sep 21, 2026
Merged

stormer78 merged 2 commits into
mainfrom
fix/onboard-commit-before-encrypt

Conversation

@stormer78

Copy link
Copy Markdown
Contributor

Adding a second trust agent looked like it worked, but the agent never showed up in the popup's list of VTAs. It happened twice in a row.

Cause

From the setup page's + Connect another trust agent, a successful connect put the connection in component state and saved it only when the operator clicked Encrypt or Skip on the "Wallet onboarded ✓" screen. That screen reads as the end, so people closed the tab there. By then:

  • the agent had already written the ACL entry;
  • the offscreen document had already stored the holder key;
  • the wallet had not recorded the agent.

Fix

  • Store on connect. OnboardView saves the connection as soon as connect succeeds. The encrypt prompt is now an optional step that only re-wraps the key; leaving it closes the add-another panel. The key can still be encrypted later from the plaintext banner.
  • Reload the store when another page writes it. Each extension page loaded the persisted pnm-connection/v3 map once, and every write replaced the whole blob. A page loaded before another page added an agent would write its old map back over it. The store now reloads when storage.onChanged reports a write from another page. Its own writes are recognised and skipped, and hydrate doesn't persist, so this can't loop.
  • Keep homeContext / agentScope through a transport refresh. The popup rebuilt the connection from a hand-picked list that left both out, so any transport change erased them and the setup page then said "not recorded". withRefreshedTransports (store.ts) replaces only the three transport members.

Dependencies

  • @openvtc/trust-tasks ^0.19.14 → ^0.19.17, at the root and in core.
  • @types/chrome ^0.2.2 → ^0.3.0 (extension). No code changes were needed.
  • In the pwa: @tanstack/react-query ^5.103.2, lucide-react ^1.47.0, react-router-dom ^7.18.4.
  • The lockfile is refreshed within existing ranges (rolldown, rollup, @types/node, among others).
  • The @swc override stays at ~1.15.47; the plugin break it guards against is still unfixed.

Checks

  • Cold npm run cleannpm run lintnpm run buildnpm test: 1550 passed, 0 failed.
  • Every CI assertion on dist/ passes locally: the single-bundle worker and console, the admin, seeds and persona guards, the Web Store zip, and pinned commits.
  • New tests: connection-store-sync.test.mts (2 tests), plus one rendered test in onboard-scope.render.test.mts. All 3 fail on main and pass here.

Pre-merge checklist (vti-stack-development-guide §9)

  • No new bare fetch(); all clients have finite timeouts (R1.2): no network code touched
  • No lock held across a network await (R1.3): n/a
  • No local state committed before its remote effect (R2.1): the connection is now saved after the agent and offscreen report success, which is the point of the fix
  • Every retry is bounded + backed off (R1.4): n/a
  • Accept/poll/listen loops survive transient errors (R1.5): n/a
  • Acks/deletes happen only after durable handoff (R1.6): inbound path not touched
  • New/changed wire types (R3.*): none
  • Config absence = most restrictive (R5.*): n/a
  • Logs/status claim only what was verified (R6.*): "Wallet onboarded ✓" is now true when it is shown
  • "Process dies on the next line" answered for every mutation touched (R2.1): closing the page at any point after connect leaves a stored, working (unencrypted) connection
  • No deviations from the guide

Signed-off-by: Glenn Gore glenn.g@affinidi.com

… encrypt prompt is left

Adding a second agent from the setup page's "+ Connect another trust
agent" looked like it worked and left the list unchanged. A successful
connect held the connection in component state until the operator
clicked Encrypt or Skip on the "Wallet onboarded" screen. That screen
reads as the end, so people closed the tab there. The agent kept the
ACL entry and the offscreen document kept the holder key, but the
wallet never recorded the agent.

OnboardView now commits the connection as soon as connect succeeds. The
encrypt prompt is an optional follow-up that only re-wraps the key.
Leaving it closes the add-another panel. The key can still be encrypted
later from the plaintext banner.

Two related ways the connection map lost data:

- Each extension page hydrated the persisted map once and wrote the
  whole blob back on every change. A page loaded before another page
  added an agent wrote its stale map over the new one. The store now
  rehydrates when storage.onChanged reports another page's write. Its
  own writes are recognised and skipped.
- The popup's transport refresh rebuilt the connection from a hand-picked
  list that omitted homeContext and agentScope. Any transport drift erased
  them, and the setup page then said "not recorded".
  withRefreshedTransports (store.ts) replaces only the three transport
  members.

Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
- @openvtc/trust-tasks ^0.19.14 -> ^0.19.17 (root and core)
- @types/chrome ^0.2.2 -> ^0.3.0 (extension)
- @tanstack/react-query ^5.101.2 -> ^5.103.2, lucide-react ^1.45.0 ->
  ^1.47.0, react-router-dom ^7.18.1 -> ^7.18.4 (pwa)
- lockfile refreshed within existing ranges (rolldown, rollup,
  @types/node and others)

The @swc/core and @swc/wasm override stays at ~1.15.47. The
vite-plugin-top-level-await break it guards against is not fixed.

Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
@stormer78
stormer78 merged commit 9643c57 into main Sep 21, 2026
4 checks passed
@stormer78
stormer78 deleted the fix/onboard-commit-before-encrypt branch September 21, 2026 17:53
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