# Desktop Helper Pairing — draft set > **DRAFT ARTIFACTS.** This folder is design-time scaffolding for pairing the > Peach browser extension (Solid.js + TypeScript) with the `peach-sync` desktop > helper, then syncing the vault to it over the LAN. Nothing here is wired into > the build. On apply, follow `INTEGRATION-CONTRACT.md` and then the whole folder > can be removed (use `trash`, never `rm`). ## What this is A six-change plan, each pinned to verified source in both repos (`peach-browser` and `peach-sync`): 1. **Change 1** — send `vault_id` in the `PAIR_IDENTITY` frame so the helper records which vault it paired to. 2. **Change 2** — `"desktop"` DeviceType (**already present** — no-op). 3. **Change 3** — background code-pairing client (`desktop-pairing.ts`). 4. **Change 4** — popup pairing UI (`DesktopPairingFlow.tsx`). 5. **Change 5** — handshake-free subnet port probe for the pairing port. 6. **Change 6** — include `"desktop"` peers in sync sessions (**one-line filter widening** — not a no-op as first assumed; see below). ## Corrected premises vs the original brief The brief was written before reading the source. These premises were wrong and are corrected throughout the draft set (binding pin: `_GROUND-TRUTH.md`): | Brief said | Reality (verified) | | --- | --- | | Add `"desktop"` to `DeviceType` in `src/shared/types.ts` | `"desktop"` already in `src/shared/sync-types.ts:11`; `types.ts` has no `DeviceType`. **Change 2 is a no-op.** | | Helper acks with `PEACH_HELLO_OK` | It's **`PEACH_HELLO_ACK`** (`pairing.zig:40`). No `_OK` frame exists. | | Helper sends `PEACH_HELLO_ERROR` on wrong code | **No error frame.** Wrong/expired code → silent socket close + code rotation (`pairing.zig:117,119-125`). | | (implied) browser is NK responder | For desktop pairing the **browser is the NK initiator** (`pairing.zig:153-154`) — opposite of the audio-chirp flow. | | React, hooks, `PeachField`, `OutlinedTextField` | Repo is **Solid.js**. No `PeachField` component — it's a ``. Tests use `renderView`, not `@solidjs/testing-library`. | | Bump 4.0.1 → 4.0.2 | Dev is **already 4.0.2**. Integration bumps **4.0.2 → 4.0.3**. | | Sync port assumption | Sync server is **8765** (Noise XX); pairing server is **49142** (Noise NK). Both verified. | | Change 6 just works | Runner/coordinator are generic, **but** `sync-trigger.ts:104` filters to `android|ios` only — desktop must be **added** to that one filter. | | `derivePairingSas` (lowercase) | Existing export is `derivePairingSAS` (capital). Reuse it. | | SAS KAT `0fbab8cd… → 895245` | **Correct** — confirmed against `pairing.zig:275-279`. | | `{ accept: true }` on confirm | Canonical payload is `{ confirmed: boolean }` (03 + 04). | ## Reading order 1. `_GROUND-TRUTH.md` — the binding wire contract. Read first. 2. `01-vault-id-in-pair-identity.md` 3. `02-desktop-device-type.md` (no-op verification) 4. `05-subnet-probe.md` (Change 3 depends on it) 5. `03-desktop-pairing-handler.md` 6. `04-desktop-pairing-ui.md` 7. `06-sync-coordinator-desktop.md` 8. `tests/` — the four companion spec files (26 specs total). 9. `INTEGRATION-CONTRACT.md` — the authoritative apply plan (file map, order, message contract, TODOs, version, quality bar). Read last, follow on apply.