Skip to content

docs(cross-device-sync): add boss-link sync and remote control design - #1

Merged
GQAdonis merged 1 commit into
mainfrom
docs/webrtc-sync-design
Sep 26, 2026
Merged

GQAdonis merged 1 commit into
mainfrom
docs/webrtc-sync-design

Conversation

@GQAdonis

Copy link
Copy Markdown

Summary

  • Adds docs/webrtc/: research report and design for boss-link, a shared Rust core that keeps one person's data in sync across The Boss desktop and the-boss-mobile and lets any device control executors (desktops / headless nodes) from anywhere.
  • Transport: iroh 1.x (QUIC, hole punching, self-hosted relays); WebRTC kept as a later option behind the transport seam.
  • Control: existing upstream agent.* / configuration.* JSON-RPC methods carried in signed envelopes verified by the Rust core (roster, time, replay, grants, local policy, hardware step-up, home epoch).
  • Sync: per-field LWW with hybrid logical clocks and per-origin change cursors, home-authoritative messages, transactional outbox and projection through each app's data layer; canonical entity mapping for both schemas; protected (execution-relevant) fields become locally approved proposals.
  • Includes per-platform implementation plans, phased roadmap with operator decisions (OD-0…OD-6), sources, and the record of three adversarial review rounds (final security gate: PASS).
  • The directory is byte-identical in Prometheus-AGS/cherry-studio-app and Prometheus-AGS/the-boss so agents in either repo can implement their half against the other.

Documentation only — no code changes.

Test plan

  • Mobile: pnpm docs:check-links passes
  • Both copies verified identical (diff -rq)
  • Remote CI green

🤖 Generated with Claude Code

Research report and design for syncing one person's data across the
the-boss-mobile and The Boss desktop apps and controlling any executor
from any device: iroh transport, signed device roster, command envelopes,
per-field LWW sync with a transactional outbox, canonical entity mapping,
per-platform implementation plans, roadmap, and three rounds of
adversarial review. The same docs/webrtc directory is mirrored in
Prometheus-AGS/the-boss.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@GQAdonis
GQAdonis marked this pull request as ready for review September 26, 2026 08:50
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-26T08:52:20.729894Z 38bd4e2 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 38bd4e2dd1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +84 to +88
entries after that point. **`DeviceRevoked` entries are never invalidated:** any valid ADK-signed
`DeviceRevoked` found at or after the superseded position (including on a branch learned later from a peer
that was unreachable during recovery) is carried forward by the new admin as a new `DeviceRevoked`, and every
device applies it on sight even before it is carried forward.
- After `AdminReplaced`, nothing signed by the old ADK is accepted except `DeviceRevoked`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Stop accepting revocations from the replaced admin key

When recovery is triggered because the old ADK was lost or compromised, these rules continue accepting every DeviceRevoked signed by that old key indefinitely. An attacker holding it can therefore sign fresh revocations after AdminReplaced—including revoking the replacement admin or all remaining devices—and every peer is required to apply them on sight. Preserve previously issued revocations using a bounded cutoff or entries committed before replacement, but reject new signatures from the old ADK.

Useful? React with 👍 / 👎.

Comment on lines +197 to +202
5. `msg_id` not in the journal. The journal keeps entries for 24 h (≥ maximum lifetime + skew). A duplicate
returns the stored result.
6. Grant and local policy permit the method.
7. Step-up present and valid when required (high-risk approvals, `exec.shell`, `secrets`, `control.unlock`).
8. For session-targeted methods, `home_epoch` matches the session's current epoch (§7.3).
9. Hand the RPC to the host; journal the result.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Make command execution durable before invoking the host

For non-idempotent RPCs such as agent.messages.send, session creation, and jobs.run, a utility-process or app crash after the host commits the operation but before step 9 journals its result leaves msg_id absent from the journal. Retrying the envelope then passes the duplicate check and executes the operation again, contradicting the architecture's exactly-once guarantee. Persist an in-progress/idempotency record before handing the request to the host and provide a durable way to resolve recovery after an ambiguous host commit.

Useful? React with 👍 / 👎.

Comment thread docs/webrtc/data-sync.md
Comment on lines +121 to +122
- Bookkeeping: each app keeps `sync_field_state(entity_type, entity_id, field, hlc)` (or equivalent) so the
projector never overwrites a local field whose HLC is newer (for example a local edit not yet drained).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fence projections while a local edit is still in the outbox

The stated bookkeeping cannot protect the cited undrained-edit case: the core assigns the edit's HLC only when it drains the outbox, while the same-transaction outbox schema stores only local_rev and the projector compares only sync_field_state.hlc. If an older remote projection arrives between the local commit and drain, it can overwrite the local database value before that value has an HLC in sync_field_state; depending on how changed_fields_json is materialized, the edit is then either lost or leaves the app database inconsistent with sync.db. The design needs to reserve/store the local HLC transactionally or explicitly defer projection for fields with pending local revisions.

Useful? React with 👍 / 👎.

Comment on lines +143 to +144
| JobRun (`id`, `schedule_id`, `executor_device`, `row_rev`, `type`, `status`, `scheduled_at`, `started_at`, `finished_at`, `output`, `error`) | R (executor) | `job` (read-only replicas of remote runs, `executable_here = false`) | `job` |
| Queue, attempt, idempotency, cancel flags, timeouts | — | local-only | local-only |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include required mobile job data in the canonical projection

The proposed JobRun mapping cannot be inserted into the current mobile job table: src/backend/data/db/schemas/job.ts requires a non-null input value with no database default, but the canonical row omits input and declares unlisted columns local-only. Consequently every remote job-run projection either violates the constraint or invents an unspecified value. Add the required field to the canonical model or define a deterministic projection value for mobile replicas.

Useful? React with 👍 / 👎.

@GQAdonis
GQAdonis merged commit 95e8051 into main Sep 26, 2026
6 checks passed
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