feat(FN-3707): implement mesh auth snapshot replication across core, engine
The merge delivers two major features: mesh auth snapshot synchronization across nodes (FN-3707 steps 2/4/5, including core types, central-core plumbing, peer-exchange updates, and settings/node sync route helpers) and a bundled roadmap plugin with chat UX improvements (FN-3162, FN-3756, FN-3771, FN Fusion-Task-Id: FN-3707
This commit is contained in:
@@ -244,7 +244,7 @@ Lifecycle contract (`types.ts` `isValidApprovalRequestTransition`):
|
||||
- `ActivityLogSnapshot` (`entries`)
|
||||
- `RunAuditSnapshot` (`entries`)
|
||||
- `ProjectSettingsSnapshot` (`global`, `projects`)
|
||||
- `AuthMaterialSnapshot` (`providerAuth`)
|
||||
- `AuthMaterialSnapshot` (`providerAuth`, with API-key and OAuth credential shapes)
|
||||
|
||||
Intentional exclusions from shared snapshots:
|
||||
- Task/agent blob contents (`PROMPT.md`, task document bodies, attachment bytes, JSONL run logs)
|
||||
@@ -799,10 +799,10 @@ The client treats mapping persistence as part of onboarding success. If mapping
|
||||
| POST | `/api/nodes/:id/settings/push` | Push local settings to a remote node. |
|
||||
| POST | `/api/nodes/:id/settings/pull` | Pull settings from a remote node. |
|
||||
| GET | `/api/nodes/:id/settings/sync-status` | Get sync status and diff summary. |
|
||||
| POST | `/api/nodes/:id/auth/sync` | Sync model auth credentials. |
|
||||
| POST | `/api/nodes/:id/auth/sync` | Sync model auth snapshots (push/pull, checksum/version validated). |
|
||||
| POST | `/api/settings/sync-receive` | Receive pushed settings (inbound). |
|
||||
| POST | `/api/settings/auth-receive` | Receive auth credentials (inbound). |
|
||||
| GET | `/api/settings/auth-export` | Export local auth credentials. |
|
||||
| POST | `/api/settings/auth-receive` | Receive `AuthMaterialSnapshot` and persist via auth storage. |
|
||||
| GET | `/api/settings/auth-export` | Export local `AuthMaterialSnapshot`. |
|
||||
| GET | `/api/update-check` | Read cached/TTL-guarded npm update status for `@runfusion/fusion` (respects `updateCheckEnabled`). |
|
||||
| POST | `/api/update-check/refresh` | Clear cached update data and force a fresh npm update check. |
|
||||
| GET | `/api/updates/check` | Perform an on-demand npm registry check for the latest `@runfusion/fusion` version (no cache). |
|
||||
|
||||
@@ -71,7 +71,7 @@ Defaults from `DEFAULT_GLOBAL_SETTINGS`; key scope from `GLOBAL_SETTINGS_KEYS`.
|
||||
| `daemonPort` | `number` | `4040` | Port for daemon/serve mode binding. |
|
||||
| `daemonHost` | `string` | `"127.0.0.1"` | Host for daemon/serve mode binding. Defaults to localhost only; pass `"0.0.0.0"` to expose on all interfaces. |
|
||||
| `settingsSyncEnabled` | `boolean` | `false` | Enable automatic settings synchronization between nodes. |
|
||||
| `settingsSyncAuth` | `boolean` | `false` | Include model auth credentials in settings sync operations. |
|
||||
| `settingsSyncAuth` | `boolean` | `false` | Include auth-material snapshots (`sharedState.authMaterial` and auth sync endpoints) when settings sync is enabled. Ignored when `settingsSyncEnabled` is `false`. |
|
||||
| `settingsSyncInterval` | `number` | `900000` | Automatic sync interval in ms. Valid values: `300000`, `900000`, `1800000`, `3600000`. |
|
||||
| `settingsSyncConflictResolution` | `"last-write-wins" \| "always-ask" \| "keep-local" \| "keep-remote"` | `"last-write-wins"` | Conflict strategy for divergent synced settings. |
|
||||
| `dashboardCurrentNodeId` | `string` | `undefined` | Currently selected dashboard node ID. Restores the last-viewed node on fresh browser/PWA sessions. `undefined` means viewing the local node. |
|
||||
|
||||
@@ -46,7 +46,7 @@ This document is the canonical contract for Fusion multi-leader mesh replication
|
||||
| Agent definitions/configuration | Strongly coordinated | Durable config replicated; runtime process handles excluded |
|
||||
| Agent runtime state (heartbeat ticks, local process internals, worktree paths) | Node-local only | Exposed as local telemetry, not global truth |
|
||||
| Project settings | Strongly coordinated | Existing settings payloads remain canonical payload shape |
|
||||
| Auth material / provider credentials | Queued-for-later (secured transport only) | Explicit auth channel; never merged as ordinary settings data |
|
||||
| Auth material / provider credentials | Queued-for-later (secured transport only) | Explicit auth snapshot channel (`sharedState.authMaterial`); never merged as ordinary settings payload |
|
||||
| Execution runs / live activity streams | Node-local + queued summary | Live events local; durable run outcomes appended later |
|
||||
| Audit / event streams (`activityLog`, `runAuditEvents`) | Append-only replicated | Immutable event replication with origin metadata |
|
||||
| Filesystem blobs (`.fusion/tasks/*` prompts/logs/attachments) | Queued-for-later | Metadata in replicated records, blob transfer out-of-band |
|
||||
@@ -73,6 +73,23 @@ Every replicated record uses:
|
||||
|
||||
`PeerSyncRequest` / `PeerSyncResponse` remain mesh exchange carriers. v1 envelopes are payloads exchanged through current mesh sync infrastructure and follow-on sync endpoints.
|
||||
|
||||
### Auth snapshot contract (v1)
|
||||
|
||||
Auth replication uses `AuthMaterialSnapshot` (`version`, `exportedAt`, `checksum`, `payload`) with:
|
||||
- `payload.providerAuth: Record<string, ProviderAuthEntry>`
|
||||
- `ProviderAuthEntry.type`: `api_key | oauth`
|
||||
- `api_key` fields: `key`
|
||||
- `oauth` fields: `accessToken`, `refreshToken`, `expires`, optional `accountId`
|
||||
|
||||
Transport paths:
|
||||
- Mesh shared-state channel: `POST /api/mesh/sync` (`sharedState.authMaterial`)
|
||||
- Explicit node auth channel: `POST /api/nodes/:id/auth/sync` and inbound `POST /api/settings/auth-receive` / `GET /api/settings/auth-export`
|
||||
|
||||
Security/redaction rules:
|
||||
- Auth snapshots are only exchanged over API-key-authenticated node links.
|
||||
- Raw secrets (`key`, `accessToken`, `refreshToken`, bearer headers) MUST NOT be logged.
|
||||
- Route diagnostics may emit provider names/counts only.
|
||||
|
||||
## 7. Quorum and acknowledgements
|
||||
|
||||
For `strong` writes:
|
||||
|
||||
Reference in New Issue
Block a user