Commit Graph
340 Commits
Author SHA1 Message Date
abkslmandClaude Fable 5 8776c9f333 Mesh P4 remainder: PeerClient, Mac↔Mac pairing, addresses, dedup
Completes Phase 4 of the multi-device mesh program (docs/MESH_TRANSFER.md):
a Mac now dials paired sibling Macs with the same platform-neutral SyncClient
the iPhone uses, so it is both a host to its phones and a .control-scope client
of its peers — the dependency session transfer (P5) was waiting on.

Wire (NucleicProtocol, version stays 1, additive + capability-gated):
- PeerAddresses {lanHint, tailnet, relayRoomID, updatedAt}; optional
  Hello.addresses / Welcome.addresses; ClientMsg.addressUpdate gated on new
  WireCapabilities.canUpdateAddresses; PairedDevice.addresses — all
  decode-defaulted so shipped iPhones and pre-mesh stores load unchanged.

Core (NucleicCore):
- PeerClient: serial LAN→tailnet dial over an injectable PeerDialer, capped
  backoff, live presence stream, listPeers only when advertised. MacPeerDialer
  + LANDialChannel add the outbound dial-side FrameChannel that didn't exist.
- Symmetric pairing into one PairedDeviceStore (one pasted link makes both Macs
  dialable); accepting-Mac confirm (locked decision #4); SyncHost per-deviceID
  connection dedup (keep-newest, 2s grace); AppStore lifecycle + meshPeers.

UI: "Paired Macs" section (presence/transport/revoke), paste-link pairing sheet,
QR sheet doubles as copy-link + confirm dialog.

Hardening (adversarial review, 11 defects fixed incl. two security holes):
- Mac-pairing confirm enforced on the reconnect promotion path (a phone can't
  reconnect claiming deviceKind=mac to skip the confirm).
- Existing-device hello branch requires the authenticated static key to match
  the pin (a pairing party can't claim another device's deviceID).
- startPeerClient guarded against a racing stopSyncServer; confirm timer stored
  and cancelled on resolve; pair() treats pre-welcome wireError as terminal and
  classifies decline vs unreachable; handshake deadlines; setPresence won't
  resurrect an unpaired peer; meshPeersChanged no-ops once the server is down;
  pairing UI cancels in-flight pair() on dismiss; LANDialChannel cancels on
  .failed + TCP keepalive.

Tests: 871 green (742 core + 98 protocol + 31 new) — wire codec/backcompat,
dedup, address exchange, addressUpdate, mac-confirm decline/phone-skip,
key-mismatch + promotion rejects, PeerClient pair-via-link/reconnect/listPeers
gating/unpair loopback.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-04 02:19:23 -07:00
abkslmandClaude Fable 5 7e80a45ddc Mesh + session transfer: P1 done, P2 core, P4 foundation
Multi-device mesh + session-transfer program (docs/MESH_TRANSFER.md).

P1 (multi-select connection methods, Mac): SyncTransportSet with legacy
migration; CompositeSyncListener partial-failure tolerant + per-method health;
AppStore listens on all enabled methods; HostInfo.hostID = DeviceIdentity.hostID
(key hash, not display name); Settings 3 method toggles + LAN-only recommendation
banner.

P2 core (relay hardening, security-critical, tested): nucleic-edge relayEnroll.ts
X25519 proof-of-possession enroll + server-side roomId derivation; room.ts
role-routed per-peer forwarding with deviceId-tag envelope + frame cap +
one-host-per-room eviction; host-bearer minting bound to the PoP room. Swift
cross-stack contracts pinned to test vectors: RelayEnrollment (PoP proof),
RelayEnvelope (routing tag), PairingPayload relay fields. Socket transport +
iOS un-gating remain deploy-gated.

P4 foundation (peer model + listPeers, tested): PeerTypes (PeerKind/
PeerCapabilities/PeerSummary); Hello.deviceKind+clientCaps;
WireCapabilities.canListPeers; ClientMsg.listPeers -> HostMsg.peerList;
PairedDevice.kind+capabilities (decode-defaulted); ConnectionHandler records
kind at pairing; SyncHost.connectedDeviceIDs(); AppStore.peerSummaries();
SyncClient .peerList event; iOS RemoteStore.meshPeers. PeerClient + Mac<->Mac
pairing UI remain.

All additive + capability-gated; SyncProtocol.version stays 1; pre-mesh stores
and clients unaffected. Swift 724 core + 91 protocol tests green; edge 50 green.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-04 00:39:30 -07:00
abkslmandnucleic 92a3f277c8 nvrsion: Add re-sync from dev for VERSION and adjust Appcast releases; fix permission flow by removing the “allow always” button from approval views and docs; fix build script error by removing obsolete sh dependency from Makefile.
Nucleic-Promote: 1
Co-authored-by: Nucleic <[email protected]>
2026-07-03 18:57:19 -07:00
abkslmandnucleic 2c3535c3f9 nvrsion: Add: Adjust side padding on “Update available” card in sidebar to match session entries’ padding, fix internal tester invitation workflow for rapid Canary channel releases, and create a “trusted tester” system requiring approval to join internal testing groups.
Nucleic-Promote: 1
Co-authored-by: Nucleic <[email protected]>
2026-07-03 17:40:28 -07:00
abkslmandnucleic 8f03fc35a7 nvrsion: Add deprecation warnings and updates for Hdiutil mount command; fix BUILD.md, Makefile, and related files.
Nucleic-Promote: 1
Co-authored-by: Nucleic <[email protected]>
2026-07-02 20:24:53 -07:00
abkslmandnucleic c55f7a4248 nvrsion: Add review feature access for iOS remote: Enable reviewers to test all features in App Store (or TestFlight) reviews by updating BUILD.md, docs/APP_REVIEW_NOTES.md, RemoteStore.swift, RemoteApp.swift, BuildBanner.swift, and SettingsView.swift.
Nucleic-Promote: 1
Co-authored-by: Nucleic <[email protected]>
2026-07-02 19:26:43 -07:00
abkslm 55bf269334 Merge branch 'claude/competent-pasteur-a5bb90' into HEAD 2026-07-02 17:21:39 -07:00
abkslmandClaude Fable 5 e93fc14c9b relay: host self-enrollment — no admin secret in the app; push is one toggle
The admin bearer must not ship in a distributed build, so hosts no
longer use it at all. A Mac self-enrolls with the relay on first use
(POST /v1/host/enroll) and receives its own scoped credential (only
the SHA-256 is stored server-side; the credential lives in the login
Keychain). Register and notify are now authorized per host: a host
can wake only devices it registered itself (admin remains an
operator-only override); room-registered records are owner-tagged
with the DO id and refused out-of-band. Each device record's APNS
environment now wins over the global APNS_ENV secret, so mixed
sandbox/production fleets work.

Settings ▸ Remote's section is now just "Relay" with a single
"Push notifications" toggle that takes effect immediately; the relay
URL and APNS-environment overrides appear only in local dev builds.
PushRelayConfig reduces to enabled + baseURL (built-in production
default) + apnsEnv (production default). PUSH_SETUP.md §3/§4 updated;
stale dotted-bundle-id comments in env.ts/wrangler.jsonc fixed.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-02 17:21:38 -07:00
abkslmandClaude Fable 5 1fe9d8898d mac: remove the direct APNS sender — the provider key must stay server-side
An app can't hold a secret the machine's owner can't extract (root +
debugger defeats bundling, Keychain, and obfuscation; the Secure
Enclave can't import external keys), and a leaked .p8 can push to
every user of the topic. So the push path is relay-only again: the
key lives exclusively in the relay's Worker secrets and the Mac only
asks the relay to send. Settings and PUSH_SETUP.md revert to the
relay-only form, with the rationale recorded in §4.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-02 16:30:57 -07:00
abkslm 09fb4863ae Merge branch 'claude/competent-pasteur-a5bb90' into HEAD 2026-07-02 16:30:57 -07:00
abkslmandClaude Fable 5 add50fe074 mac: direct APNS sender — the host can wake phones without the relay
Answering "can push be local when on LAN": a backgrounded iOS app can
only be woken through Apple's push service, so a LAN-only wake path
doesn't exist — but the *sender* can be this Mac. DirectAPNSSender
holds the APNS .p8 (path + Key ID + Team ID, runtime-configured like
the relay: env vars first, then the Settings-written defaults keys)
and posts the same content-free approval.pending tickle straight to
api.push.apple.com (ES256 provider JWT via CryptoKit, 40-min cache,
per-device throttle) — no Cloudflare dependency for push.

ApprovalPushing unifies the two senders; SyncHost wakes non-connected
paired devices through whichever is configured (direct wins). The
Settings ▸ Remote push section gains a sender picker with the direct
fields (.p8 chooser, Key ID, Team ID). PUSH_SETUP.md §4 rewritten as
Option A (this Mac) / Option B (relay). JWT signing verified against
the public key in tests; payload asserted byte-compatible with the
worker's apns.ts tickle.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-02 16:18:53 -07:00
abkslm 4aa4aa16ae Merge branch 'claude/competent-pasteur-a5bb90' into HEAD 2026-07-02 16:18:53 -07:00
abkslm b54419aa02 Merge branch 'claude/competent-pasteur-a5bb90' into HEAD 2026-07-02 16:09:45 -07:00
abkslmandClaude Fable 5 8c28cc9132 mac: relay push settings UI (Settings ▸ Remote); clarify runtime config in PUSH_SETUP
The relay URL / admin secret / APNS environment are runtime host
settings (PushRelayConfig.resolve reads env then UserDefaults when
the sync server starts), not build settings — and a Finder-launched
app never sees shell env. Add an "Approval push (relay)" section to
Settings ▸ Remote writing the same defaults keys, with an Apply
button that restarts remote access so changes take effect. Update
PUSH_SETUP.md §4 to point at the UI and keep the env-var form for
scripted runs.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-02 16:09:32 -07:00
abkslm c50cde6aca Merge branch 'claude/competent-pasteur-a5bb90' into HEAD 2026-07-02 16:07:16 -07:00
abkslmandClaude Fable 5 d16eb3c7a7 docs: PUSH_SETUP runbook; wire aps-environment entitlements into the build
docs/PUSH_SETUP.md lists the manual steps left to light up push /
Live Activities end-to-end: APNS key, the one-click Xcode Push
capability, Cloudflare provisioning + secrets (with the bundle-id
topic gotcha: xyz.blakeslee.nucleic-remote, not .remote), host relay
config, and the on-device verification checklist. Also adds
CODE_SIGN_ENTITLEMENTS so the existing entitlements file actually
signs into the app.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-02 16:06:33 -07:00
abkslmandClaude Fable 5 2b7290b73e sync: project quota, provider status, todo triage, and full diffs to the phone
Four Mac surfaces the iOS remote couldn't render now ride the wire,
forward-compatibly (decodeIfPresent defaults; unknown HostMsg tags
already decode to .unknown):

- DashboardSnapshot gains `usage` (WireSubscriptionUsage — the Mac's
  5-hour/weekly quota gauges) and `statusFeeds` (WireStatusFeed —
  active provider incidents); the host re-pushes the dashboard when a
  poll changes either.
- WireTodo gains `triage` (raw TriageLevel name); the phone renders
  the Mac's TriageBadge honoring the encouraging/classic label
  setting.
- ClientMsg.fetchDiff / HostMsg.sessionDiff deliver the full worktree
  patch on demand (capped at 512 KB with a truncated flag), gated on
  the new WireCapabilities.canFetchDiff so a new phone never sends it
  to an old host. iOS renders a file list + colored unified patch,
  falling back to the diffstat summary against older hosts.

Round-trip and legacy-decode tests cover the new fields; the full
suite passes apart from the pre-existing fake-backend fixture gaps
and the flaky nvrsion lock-domain test (same failure rate on the
base commit).

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-02 16:06:32 -07:00
abkslmandClaude Fable 5 6e70c99a6b docs: add CLOUD_RUNTIME.md — Nucleic Cloud runtime service plan
Plan for a paid cloud runtime: headless Linux nucleicd (ported NucleicCore)
in per-user Cloudflare Containers (not Workers for Platforms), reusing the
nucleic-edge relay; relay+push stay free, $19/mo tier, premium conveniences
that paywall no current functionality.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-02 00:38:09 -07:00
abkslmandnucleic 9cc1f07daa nvrsion: Add Canary release channel, fix truncation text wrapping, add function to use the on-device model to cross-check file permissions against commands for legitimacy, refactor chat logic to explore file permissions with on-device model validation, and adjust website/index.html to include “Iterate at the speed of thought” as a primary selling point.
Nucleic-Promote: 1
Co-authored-by: Nucleic <[email protected]>
2026-07-01 19:41:33 -07:00
abkslmandnucleic 0404147164 nvrsion: Add: Fix truncation of “Run now” button text in New idea composer, add model selector support for Claude Fable 5, refactor Project Workflow Enhancement, add Wait Button Logic, update iOS remote to match Chat Message Queue Display, block sandboxed/controlled agents from running git commands via mcp__nucleic__host_exec using container-level shims, add chat icon animation to bounce when chat is blocked for >60 seconds, add “Cmd+Shift+N” shortcut to open a floating chat composer over the window, remove “Run now” button from “New idea” composer, and shield Git command execution by scanning inside ‘-c’ strings.
Nucleic-Promote: 1
Co-authored-by: Nucleic <[email protected]>
2026-07-01 19:01:20 -07:00
abkslmandnucleic 911a426e0f Redirect Configuration
Nucleic-Session: D73FB6C0-C262-4297-A577-B37D0F149DCB
Co-authored-by: Nucleic <[email protected]>
2026-06-28 19:52:26 -07:00
abkslmandnucleic bddb019f2d Redirect Configuration
Nucleic-Session: D73FB6C0-C262-4297-A577-B37D0F149DCB
Co-authored-by: Nucleic <[email protected]>
2026-06-28 19:51:35 -07:00
abkslmandnucleic a28ed3f1b4 Redirect Configuration
Nucleic-Session: D73FB6C0-C262-4297-A577-B37D0F149DCB
Co-authored-by: Nucleic <[email protected]>
2026-06-28 19:51:22 -07:00
abkslmandnucleic e39bbaa2b3 Redirect Configuration
Nucleic-Session: D73FB6C0-C262-4297-A577-B37D0F149DCB
Co-authored-by: Nucleic <[email protected]>
2026-06-28 19:46:25 -07:00
abkslmandnucleic 119d53ebf1 Redirect Configuration
Nucleic-Session: D73FB6C0-C262-4297-A577-B37D0F149DCB
Co-authored-by: Nucleic <[email protected]>
2026-06-28 19:44:28 -07:00
abkslmandnucleic 45dbe9ea71 Redirect Configuration
Nucleic-Session: D73FB6C0-C262-4297-A577-B37D0F149DCB
Co-authored-by: Nucleic <[email protected]>
2026-06-28 19:44:04 -07:00
abkslmandnucleic f5babebaad Redirect Configuration
Nucleic-Session: D73FB6C0-C262-4297-A577-B37D0F149DCB
Co-authored-by: Nucleic <[email protected]>
2026-06-28 19:43:57 -07:00
abkslmandnucleic d93fd4077b Redirect Configuration
Nucleic-Session: D73FB6C0-C262-4297-A577-B37D0F149DCB
Co-authored-by: Nucleic <[email protected]>
2026-06-28 19:43:51 -07:00
abkslmandnucleic ae0c064972 Redirect Configuration
Nucleic-Session: D73FB6C0-C262-4297-A577-B37D0F149DCB
Co-authored-by: Nucleic <[email protected]>
2026-06-28 19:43:32 -07:00
abkslmandnucleic ca6a45b44d Version Communication Enhancement
Nucleic-Session: 1367F61F-9C84-4D8B-9ECC-01DEE9DF01E4
Co-authored-by: Nucleic <[email protected]>
2026-06-27 22:24:37 -07:00
abkslmandnucleic cae771d84b Commit Message Revision
Nucleic-Session: 37EA5099-12C5-4C33-AD88-798A5464D107
Co-authored-by: Nucleic <[email protected]>
2026-06-27 21:49:22 -07:00
abkslmandnucleic f10d2a6e26 Commit Message Revision
Nucleic-Session: 37EA5099-12C5-4C33-AD88-798A5464D107
Co-authored-by: Nucleic <[email protected]>
2026-06-27 21:49:13 -07:00
abkslmandnucleic b74100dba8 Commit Message Revision
Nucleic-Session: 37EA5099-12C5-4C33-AD88-798A5464D107
Co-authored-by: Nucleic <[email protected]>
2026-06-27 21:49:00 -07:00
abkslmandnucleic 0ae143c680 Version Promotion Logic
Nucleic-Session: C8D4A2E8-50AB-4F8B-ABFB-78AF4BAFE643
Co-authored-by: Nucleic <[email protected]>
2026-06-27 19:13:44 -07:00
abkslmandnucleic c31d77c02f Version Promotion Logic
Nucleic-Session: C8D4A2E8-50AB-4F8B-ABFB-78AF4BAFE643
Co-authored-by: Nucleic <[email protected]>
2026-06-27 19:13:35 -07:00
abkslmandnucleic a0f6e0c984 Session Command Conflict Detection
Nucleic-Session: 7B641658-B34C-4780-86B5-A4038C3749DE
Co-authored-by: Nucleic <[email protected]>
2026-06-27 17:56:30 -07:00
abkslmandnucleic b1cca25ecc Session Command Conflict Detection
Nucleic-Session: 7B641658-B34C-4780-86B5-A4038C3749DE
Co-authored-by: Nucleic <[email protected]>
2026-06-27 17:56:21 -07:00
abkslmandnucleic 5af826deb4 Session Command Conflict Detection
Nucleic-Session: 7B641658-B34C-4780-86B5-A4038C3749DE
Co-authored-by: Nucleic <[email protected]>
2026-06-27 17:39:11 -07:00
abkslm c834c23c67 Promote Chat Session Notification
Nucleic-Session: 68E3C84F-A081-45F2-9B94-0D49D06A0F51
2026-06-27 14:52:33 -07:00
abkslm 279ea38c04 Promote Chat Session Notification
Nucleic-Session: 68E3C84F-A081-45F2-9B94-0D49D06A0F51
2026-06-27 14:52:11 -07:00
abkslm 4bca5be90f Promote Chat Session Notification
Nucleic-Session: 68E3C84F-A081-45F2-9B94-0D49D06A0F51
2026-06-27 14:52:05 -07:00
abkslm 3040e74ef3 Promote Chat Session Notification
Nucleic-Session: 68E3C84F-A081-45F2-9B94-0D49D06A0F51
2026-06-27 14:51:50 -07:00
abkslm 8ef09b3318 Promote Chat Session Notification
Nucleic-Session: 68E3C84F-A081-45F2-9B94-0D49D06A0F51
2026-06-27 14:51:38 -07:00
Nucleic 4e09389984 Adjust DAI Metrics File
Nucleic-Session: E357FC5A-6454-41EE-9AA8-139CDB6779DA
2026-06-27 14:26:39 -07:00
Nucleic aea3e24dd8 Adjust DAI Metrics File
Nucleic-Session: E357FC5A-6454-41EE-9AA8-139CDB6779DA
2026-06-27 14:26:19 -07:00
Nucleic 6586fdd6c7 Adjust DAI Metrics File
Nucleic-Session: E357FC5A-6454-41EE-9AA8-139CDB6779DA
2026-06-27 14:26:10 -07:00
Nucleic 45f8732ce6 Adjust DAI Metrics File
Nucleic-Session: E357FC5A-6454-41EE-9AA8-139CDB6779DA
2026-06-27 14:26:04 -07:00
Nucleic 4de0362387 Adjust DAI Metrics File
Nucleic-Session: E357FC5A-6454-41EE-9AA8-139CDB6779DA
2026-06-27 14:25:57 -07:00
Nucleic fe4e128307 Adjust DAI Metrics File
Nucleic-Session: E357FC5A-6454-41EE-9AA8-139CDB6779DA
2026-06-27 14:25:53 -07:00
Nucleic 3002e51903 Adjust DAI Metrics File
Nucleic-Session: E357FC5A-6454-41EE-9AA8-139CDB6779DA
2026-06-27 14:25:48 -07:00