BETA.md
Rama main · réplica de lectura del repositorio original.
# Synara Beta
Synara Beta is a packaged prerelease flavor of the desktop app. It is a separate
application that installs and updates side-by-side with stable Synara, and it never
shares stable's data directory or update feed.
## Synara Remote early access
Remote .39 fixes photo/file transfers from a controlling desktop to a connected computer. Uploads and cancellation retain their original owner; image previews, fullscreen and downloads use the authenticated controlling window. Expired or lost image grants recover once without changing row geometry; persistent failures keep Retry. This desktop update preserves data and pairings and requires no hosted API or companion release.
Remote .38 brings Pin, Archive and Done/Undo to connected-computer rows in Activity, Priority and the sidebar. Hover or keyboard focus replaces the remote marker with the same controls used locally; Undo stays visible in the controlling window and targets the original computer. This desktop-only change preserves pairings and does not require an API or iPhone/iPad update.
Remote .36 shows each subagent's existing provider model and explicitly selected effort directly in active and completed dock rows. Missing values stay hidden, and existing task controls are unchanged. This desktop update does not change the API, connector or provider runtime and does not update the iPhone or iPad app.
Remote .35 retains eligible local Markdown images privately with completed replies and adds Retry for failed previews. The host resolves relative paths and registered worktrees; file grants remain confined to the requested file. An image missing before it could be retained still needs the original file restored. Universal TestFlight build 159 includes the matching image recovery and SVG retry fixes, and removes an unsupported prewarm request that could disconnect hosts. Update desktop and mobile separately.
Remote .35 bundles cloudflared 2026.10.3 for the [eMudhra certificate trust fix](https://blog.cloudflare.com/emudhra-certificate-compromise/). Updating Homebrew alone does not replace the helper inside Synara Remote. The app's declared minimum remains macOS 13; the vendor connector executable declares macOS 15, as the previous bundled version also did. Connector operation on macOS 13–14 remains unqualified; do not disable TLS verification or lower the executable's metadata to work around this.
Remote .32 adds guarded recovery for blocked Claude deliveries. Use Stop before Unblock when the runtime still needs to retire; a Stop request alone does not confirm cleanup. Restarted hosts distinguish inherited deliveries from locally adopted runtimes. Uncertain messages are never automatically replayed. The matching iPhone/iPad recovery controls require TestFlight build 156 or newer; update each app separately.
Remote .20 and universal iOS/iPadOS build 141 align resource validation with phone-created thread identifiers. Update both ends for attachment and voice transfers; old hosts reject those identifiers. Existing pairing, authorization and upload-size limits remain in force.
**Synara Remote** is a separate tester app, not a rename of Synara Beta.
Its `remote` flavor uses `com.emanueledipietro.synara.remote`, the
`synara-remote://app` renderer, `~/.synara-remote` data and the `synara-remote`
Electron profile. An explicit `SYNARA_REMOTE_HOME` may override its home;
inherited `SYNARA_HOME` and `SYNARA_BETA_HOME` cannot redirect it.
`vX.Y.Z-remote.N` selects the `remote` updater lane. Remote accepts only Remote
updates, never replaces Stable/Beta, never becomes GitHub Latest and does not
publish the CLI. From Remote .14, distribution targets macOS Apple Silicon,
Windows x64 and Linux x64. Windows has its own NSIS registration, and Linux
uses `synara-remote` for its executable and window class. It uses
the existing Synara artwork; Beta's blue artwork remains specific to Beta.
Remote enables the existing non-Stable feature gates and runs diagnostics with
`flavor: "remote"`, without raw crash dumps. It starts with its own local data:
no Stable/Beta import or Try Beta installation/removal action runs from Remote.
Signing in to the same account preserves access to account-owned cloud data and paired computers;
local conversations remain owned by their original app home.
Remote .14 also supplies its hosted account API on a normal launch; no shell
environment setup is needed. An explicit `SYNARA_ACCOUNT_URL` still overrides
that default. Saved account sessions retain their original issuer. The release
qualifies startup without inheriting the operator's account URL. The hosted API's
`REMOTE_BETA_ACCESS_ENABLED=true` setting opens beta enrollment to all authenticated
accounts, with host ownership, registered device proof and pairing consent still
required. Private deployments leave it unset/`false` and enroll selected users.
Remote .15 restores GitHub alongside Google, Apple and email sign-in. GitHub is
configured in the hosted WorkOS Production environment. The provider configuration
and Chromium sign-in UI tests pass; the real production GitHub consent/callback
has not been verified. Remote also
enables the profile/usage sync path without an operator flag; an explicit
`SYNARA_ACCOUNT_PROFILE_SYNC=0` still disables it. Stable was blocked at that
release; its later profile promotion is described below. Generic/Beta builds
retain their existing opt-in. Product analytics were
separate and off by default in Remote .15; the later Remote default is described
under [Diagnostics](#diagnostics).
Remote .15 retries temporary enrollment refusals without permanently disabling the host or revoking approved devices. Opening a populated remote home no longer constructs an empty chat ID. An update cannot distinguish a previously revoked pairing from deliberate revocation: pair that device normally again if needed; never restore trust by editing the database. The Remote updater prepares downloads in the background and installs only through its normal restart action.
Remote .16 extends that recovery to temporary proof rejection and API/proxy failures. Ownership denials close admission immediately, but only repeated denials spanning five minutes permanently retire local trust. A successful authorization snapshot resets that confirmation window. Source-launched Remote/Beta use separate development bundle identities; installed identities, homes and feeds are unchanged.
Signing out preserves that local database. Signing in as another account on the
same installation does not create a separate local history: the account profile
and saved Inbox stay account-scoped, but usage sync backfills the installation's
history for the newly signed-in account. Per-account local conversation ownership
is not implemented; do not use account switching as local history isolation.
## The short version
- **One branch.** Every PR merges into `main` as usual. There is no Beta branch.
The release tag decides which app gets built from `main`:
- `vX.Y.Z` builds **Synara** (Stable).
- `vX.Y.Z-beta.N` builds **Synara Beta**.
- **Beta is named after the next Stable.** After `v0.9.2` ships, the next Beta is
`v0.9.3-beta.1`, then `v0.9.3-beta.2`, and so on until `v0.9.3` ships. Never tag
`v0.9.2-beta.1` after `v0.9.2`: it sorts older than the Stable it follows.
- **Two separate apps.** Synara and Synara Beta install side by side, with separate
data (`~/.synara` and `~/.synara-beta`) and separate update feeds. A Beta update is
never offered to Stable, and the other way round.
- **Data only copies Stable → Beta.** Settings > Try Beta copies the user's Stable
data into Beta. Nothing is ever copied back: "Switch back to Synara" reopens
Stable with the data it already had.
- **Beta-only features** stay out of Stable through one list,
`BETA_ONLY_FEATURES` in `packages/shared/src/betaFeatures.ts`. The code ships in
both apps; Stable just switches listed features off. Remove the entry to promote
a feature to Stable. See [Beta-only features](#beta-only-features).
- **Diagnostics run in Beta and Remote, never Stable.** Beta sends technical-only error
categories, numeric frames, release health and fixed health counts. No flavor
uploads raw crash dumps or work content. Remote adds product usage by default with a
Settings switch to stop both. Stable sends no release diagnostics; its product
analytics require opt-in. See [Diagnostics](#diagnostics).
### Release order
1. Merge the PRs for the release into `main`.
2. If Windows is shipping unsigned, set the repo variable
`SYNARA_ALLOW_UNSIGNED_WINDOWS_RELEASE` to the Stable version (for example
`0.9.2`), then tag and publish `v0.9.2`.
3. Set the variable to the Beta version (`0.9.3-beta.1`), prepare its version
commit on top of the Stable commit, then tag and publish `v0.9.3-beta.1`.
With `SYNARA_AUTO_BETA=1` this version commit and tag are created automatically
after the Stable publish. Do not push Beta package versions onto `main`.
4. More Betas (`beta.2`, `beta.3`, …) can follow from newer `main` commits at any
time. Stable only moves when a `vX.Y.Z` tag is cut.
The rest of this file is the detailed reference.
## Identity
- App name: `Synara Beta`
- Bundle ID: `com.emanueledipietro.synara.beta`
- Desktop origin: `synara-beta://app`
- Synara data: `~/.synara-beta`
- Electron profile: `synara-beta`
- Executable: `synara-beta` (Linux AppImage bundle), `Synara Beta.app`, `Synara Beta.exe`
- Windows installer GUID: `a8e63b48-d4f3-4db5-9e12-368107afe65d` (separate Add/Remove
Programs entry; the stable GUID is unchanged)
## App icon choices
**Settings → Appearance → App icon** offers Default, Icon, Dark, and Beta on
macOS. Windows and Linux offer Default, Icon, and Beta; Dark is macOS-only.
Default is the white Synara artwork, Dark is black, Icon is the landscape artwork,
and Beta is the blue Beta artwork. A fresh Beta profile and Reset to defaults use
Beta; a saved choice is preserved.
On macOS 26, Beta uses the app's appearance-aware bundle icon. Earlier macOS
versions use its PNG artwork. Explicit Default and the other bitmap choices are
also written to the macOS app bundle so they survive quitting the app.
Stable keeps its existing picker choices. It does not offer Beta, and a stored
Beta preference remains inactive without being erased.
## How it differs from Canary
Canary is a local source build managed by `bun run canary:*` scripts and updates only
through those scripts. Beta is a packaged release artifact: it is built, signed, and
published by the same release workflow as stable, and it updates through
`electron-updater` like the production app.
## Update channel isolation
- Stable builds follow the `synara` updater channel with `allowPrerelease=false` and
only ever read the repository's GitHub Latest release.
- Beta builds follow the `beta` updater channel with `allowPrerelease=true`.
electron-updater's GitHub provider reads the releases atom feed and takes the
newest release that is not tagged for a custom channel — so if a stable
release is newer than the latest beta tag, beta installs see "no update"
until the next beta release is cut. Always cut a new beta right after each
stable release.
- Beta releases carry `beta-mac.yml`, `beta.yml`, and `beta-linux.yml`
manifests. The `latest-*.yml` files are uploaded on beta releases too, but
they are inert there: stable installs only read them from the Latest
release, which beta tags never become. A beta release can never be offered
to a stable install, and a stable release never carries beta manifests.
- The desktop additionally gate-checks every candidate's version against its
lane (`isUpdateVersionAllowedForFlavor`): beta installs accept only
`*-beta.*` versions and production installs accept only stable versions.
This matters because electron-updater's GitHub provider falls back to
`latest-mac.yml` when the channel manifest is absent — without the gate, a
beta install could be offered a stable build, and installing it would
silently swap the app to the other flavor and home directory. Crossing lanes
always happens by installing the other app, never by update.
- `allowDowngrade` stays `false` on both trains; moving back to stable happens
by opening the stable app (see [Leaving beta](#leaving-beta)), never by update.
- Pending-update caches are scoped per flavor (`~/Library/Caches/synara-desktop-beta-updater`
on macOS), so a downloaded beta update never collides with stable's pending
update state.
## Cutting a beta release
Beta releases ride the same `release.yml` workflow. The lane is selected entirely by
the tag shape: a version whose first prerelease identifier is `beta` resolves to the
beta channel and the beta desktop flavor. The `remote` identifier selects
Synara Remote as described above; other suffixes keep today's behavior.
1. Select the target `main` commit and inspect its CI results. Finalize the release
notes and documentation, then prepare the Beta version on top of that commit
in an isolated checkout. Release preflight
(`scripts/verify-release-source-provenance.ts`) requires the four release
`package.json` versions to equal the tag version, but beta version commits
never land on `main`, so `main` keeps the stable version:
- `git switch --detach upstream/main`
- `node scripts/update-release-package-versions.ts X.Y.Z-beta.N`
- Use the next Stable base `X.Y.Z`, ahead of the latest published Stable, so
the Beta sorts after the currently installed release.
- `N` starts at `1` and increments per beta cut on the same base version.
2. Follow the [release checklist](docs/release.md#4-ongoing-release-checklist):
complete the required local checks after the version, lockfile and notes are
final; resolve the Beta update policy and set the exact Windows unsigned
exception when needed; then commit, tag and push only the tag. The tag workflow
supplies the final full workspace test suite and desktop build on that exact
Beta candidate:
- `git tag vX.Y.Z-beta.N` and `git push upstream vX.Y.Z-beta.N`
- An ordinary Beta uses this one publication run. Full build-only qualification
followed by a tag build is not required; use a scoped build-only stage only
when diagnosing a native or packaging change.
- Native packaging and qualification share one runner and can overlap the
quality/server-test gates once preflight and prepared inputs pass. GitHub
and npm publication depend directly on all quality/server-test gates and
native success; Beta still never publishes npm `latest`.
3. The workflow publishes a GitHub **prerelease** named `Synara vX.Y.Z-beta.N` with
beta installers, `beta-*.yml` manifests, and blockmaps. It is never marked Latest,
never bumps package versions on `main`, and never publishes the npm `latest`
dist-tag.
4. For a failure on the same source SHA, resume the existing run with
`gh run rerun RUN_ID --failed` as described in
[release recovery](docs/release.md#resume-a-failed-release). A first successful
native attempt creates no checkpoint. After a failure with validated provenance,
the workflow rechecks integrity before retaining a candidate for 30 days; a
retry in that same run/SHA can restore it and skip packaging. Corruption or
artifact API errors fail closed; missing/expired candidates require rebuild.
A crash/cancellation that prevents checkpoint upload, or a notarization failure
before validated provenance, cannot recover from the old runner's local files.
Do not dispatch a duplicate publication run. A manual publication dispatch on an existing tag
is an alternative trigger when no tag-triggered run is being used:
`gh workflow run release.yml --ref vX.Y.Z-beta.N -f version=X.Y.Z-beta.N -f publish_release=true`.
Publishing from a branch ref is refused by preflight; a new source SHA requires
a newly verified candidate rather than relabeling earlier artifacts.
5. Always cut a new beta right after each stable release. The GitHub provider
picks the newest non-custom-channel release in the feed, so a newer stable
tag shadows every older beta until a fresh beta prerelease out-sorts it.
With the repository variable `SYNARA_AUTO_BETA=1`, the release workflow does
this automatically after each stable publish: it tags a version commit made
on top of the stable commit as `vX.Y.(Z+1)-beta.1` (skipped when any beta
for that base already exists, or when the release just published is not the
highest stable tag — a re-release of an old line does not cut a beta).
Later betas on the same base stay manual.
### Signing
Beta builds use the same signing setup as stable. Publishing requires the macOS
signing/notarization secrets, and Windows uses Azure Trusted Signing or the same
version-scoped unsigned exception (`SYNARA_ALLOW_UNSIGNED_WINDOWS_RELEASE` set to the
exact `X.Y.Z-beta.N` version without the `v`). The exception matches one exact
version, so the automatic post-stable beta needs Azure signing or the variable
set to that beta version, otherwise its Windows build blocks publication.
## Building a beta artifact locally
```bash
bun run dist:desktop:artifact -- --platform mac --target dmg --arch arm64 --flavor beta
```
`--flavor` accepts `production` (default), `canary`, `cua`, `beta`, or `remote`, and the
`SYNARA_DESKTOP_FLAVOR` env var is equivalent. The packaged `package.json` embeds the
resolved flavor (`synaraDesktopFlavor`), so a packaged build cannot silently lose its
identity at runtime; on packaged builds the embedded value wins over the env var.
## Joining beta from stable
The stable app offers a one-click handoff under **Settings → General → Synara Beta**:
- **Install Synara Beta** (macOS) downloads the newest `v*-beta.N` release's
`beta-mac.yml`, picks the zip for the current architecture, verifies its
sha512, unpacks it with `ditto`, checks the bundle id is
`com.emanueledipietro.synara.beta`, and verifies the code signature is valid
and signed by the same team id as the running app (`codesign --verify
--deep --strict` plus a `TeamIdentifier` match; skipped when the running
build is itself unsigned). Only then is `Synara Beta.app` moved into
`/Applications` — then opened. On other platforms the card opens the public
download page instead.
- **Copy my data and open** installs first when needed, then writes a marker at
`~/.synara-beta/import-requested.json` and launches the beta app. On its next
startup the beta server consumes the marker, snapshots stable's database,
copies settings and provider secrets, then deletes the marker. The button
first confirms that this replaces existing Beta chats, projects, and settings;
work created only in Beta will be lost, while Stable remains unchanged. The snapshot
uses `VACUUM INTO` when the source is quiescent; while stable is running it
holds `state.sqlite` under `PRAGMA locking_mode = EXCLUSIVE`, so the importer
falls back to a file-level copy of the database and its WAL, retried until no
checkpoint or WAL restart landed mid-copy (it fails rather than import a torn
pair), and vacuums that staged copy into a checkpointed snapshot. Either way
the result is a consistent point-in-time copy and the outcome is written to
`~/.synara-beta/import-result.json` so the stable settings card can report
success or the failure reason. The importer stages every file first, rejects
symbolic links in copied state, and rolls back normal filesystem commit errors
rather than reporting success with only part of the state copied.
- Only a packaged beta (`SYNARA_DESKTOP_BUNDLE_ID` is the beta bundle id)
consumes the marker, and only from stable's data folder (`SYNARA_STABLE_HOME`
handed over by stable, else `~/.synara`). A stray marker in any other home
is ignored.
- If stable's database has migrations newer than the installed beta knows, the
import fails with "Update Synara Beta" instead of leaving beta unable to
start. Any leftover beta `state.sqlite-wal`/`-shm`/`-journal` is removed
before the snapshot is swapped in, so an old WAL cannot replay over it.
- **Open Beta** launches the installed beta app without touching data.
- The import button is disabled while a beta server is running so an in-flight
beta never reads a half-written snapshot; quit beta first, then import.
- Launch/import are refused unless the running app is a production-flavor build.
- On macOS the beta app is spawned by executable path
(`Synara Beta.app/Contents/MacOS/Synara Beta`) with a sanitized environment:
stable's `SYNARA_HOME`, `SYNARA_DESKTOP_SMOKE_USER_DATA`, and server auth
variables are stripped, and beta gets `SYNARA_BETA_HOME` (plus
`SYNARA_DESKTOP_SMOKE_USER_DATA` when `SYNARA_BETA_USER_DATA` is set).
The marker format lives in `packages/shared/src/betaChannel.ts`
(`BetaImportRequest`, `BetaImportResult`); the desktop side is
`apps/desktop/src/betaChannel.ts`, the download/install flow is
`apps/desktop/src/betaInstaller.ts`, and the consuming import is
`apps/server/src/betaImport.ts`.
### Local demo
Everything about the install location and data home can be redirected with
environment variables, so a demo never touches a real `~/.synara`,
`~/Library/Application Support/synara`, or `/Applications`:
- `SYNARA_BETA_FEED_URL` — base URL serving `beta-mac.yml` and the files it
lists (for example a local static server). Without it, the newest GitHub
`v*-beta.N` release is used.
- `SYNARA_BETA_INSTALL_DIR` — directory the app bundle is moved into and
probed in first (default `/Applications`).
- `SYNARA_BETA_HOME` — overrides `~/.synara-beta` everywhere it is resolved:
stable's import marker path, the beta app's own base dir, and the
running-server probe.
- `SYNARA_BETA_USER_DATA` — Electron `userData` dir handed to the launched
beta (only honored on the beta and cua flavors and source builds).
- `SYNARA_HOME` / `HOME` — stable's data dir (beta ignores `SYNARA_HOME`, so a
globally exported value can never point beta at stable's data) and the
`userData` base, respectively; overriding `HOME` isolates the Electron profile exactly like
`scripts/verify-packaged-desktop-startup.ts` does.
The import copies settings, provider secrets, and a database snapshot. It never
copies logs, diagnostics queues, runtime files, other import markers, database
sidecars (`state.sqlite-wal`/`-shm`/`-journal`), or `*.lifecycle-lock`
directories — a leaked lock directory would make beta refuse to start while the
stable process is alive. Nothing is ever written into the stable home: the
marker and the result both live in the beta home.
## Leaving beta
Beta shows **Switch back to Synara** under **Settings → General**. It opens
stable and quits beta; on macOS it can also move `Synara Beta.app` to the Trash
(checked by default). Stable was never changed by the switch, so it opens with
the chats and settings it had before.
- Beta data is never copied back. Beta can carry database migrations and data
for features stable does not have yet, so a copy could fail or corrupt
stable's `state.sqlite`. The dialog says so plainly. `~/.synara-beta` is
kept, so reinstalling beta picks up where the user left off.
- Stable is found through `SYNARA_STABLE_EXECUTABLE`, which stable sets on the
beta it launches (with `SYNARA_STABLE_HOME` for its data dir), then through
`/Applications/Synara.app`, `~/Applications/Synara.app`, or the stable NSIS
uninstall key on Windows. When none is found the card offers the stable
download page instead.
- Stable is spawned with beta's per-process overrides stripped
(`SYNARA_DESKTOP_SMOKE_USER_DATA`, server auth variables) and `SYNARA_HOME`
restored from `SYNARA_STABLE_HOME` when stable handed one over. An already
running stable just comes to the front through its single-instance lock.
- The Trash step only runs for a packaged bundle named `Synara Beta.app`, so a
source or dev build can never trash Electron itself.
## Beta-only features
`packages/shared/src/betaFeatures.ts` holds `BETA_ONLY_FEATURES`, the single
list of features that ship in Beta but not in Stable. `isBetaFeatureEnabled`
turns a listed feature off only for the `production` desktop flavor; Beta, Remote,
Cua, Canary, development, and non-desktop hosts keep it.
To put a feature behind the list:
- Add its key to `BETA_ONLY_FEATURES`.
- Gate it on the server, which is authoritative: resolve the host flavor with
`desktopFlavorFromBundleId(process.env[SYNARA_DESKTOP_BUNDLE_ID_ENV])` and
refuse the capability there, not just in the UI.
- Hide it on the web with a constant built from
`desktopFlavorFromProtocol(window.location.protocol, import.meta.env.DEV)` —
hide entry points rather than disabling them, and coerce any persisted or
replayed value to off so stale state cannot re-arm the feature.
- Keep any migrations or persisted fields additive and inert on Stable; a
user's stored preference must survive a Beta → Stable round trip untouched.
Promote a feature to Stable by deleting its entry; every gate resolves itself.
Connectors (`mcp-connectors`) are available in Stable and Beta: Settings → Connectors,
RPCs, OAuth callbacks, proxy routes and saved connectors use the same shared policy.
Each app reads only the `mcp-connectors` secret in its own data home.
See [Connectors](docs/mcp-connectors.md).
The native editor (`native-editor`) is available in Stable and Beta: the same Code OSS
editing engine behind file editors, editable diffs and editable previews, TypeScript language
service and JavaScript debugger. Both apps expose the `editor.*` RPCs and the editor commands
in the Shortcuts sheet and Settings → Keybindings. Existing document ownership, save/conflict
handling and large-preview fallbacks remain unchanged.
See [Native editor intelligence](docs/editor/intelligence.md).
HTML visuals execute only in the desktop apps (Stable and Beta), where native subframe navigation is blocked.
HTTP-hosted clients retain native component visuals but never execute HTML. The trusted
bootstrap removes WebRTC capabilities before page scripts and stops parsing if that boundary
cannot be enforced. HTML messages cannot open external URLs through the host.
The list is currently empty. Account profiles, saved Inbox history, MCP Connectors
and the native editor are available in Stable and Beta. Remote connections use
their separate runtime activation policy.
Diagnostics follow their separate [sender policy](#diagnostics).
Inline visuals are available in Stable and Beta:
the `synara_show_visual` agent tool, its transcript rows, and the `orchestration.getInlineVisual`
read all use the shared policy. Both native component specs and sandboxed HTML retain their
existing rendering and interactions. Nothing is migrated; each app keeps visual documents
under its own attachments directory, without importing Beta data into Stable.
Hubs, Tasks, Inbox, Auto-fix CI, Oh My Pi, the rail sidebar layout, and message
trail sound are available in both apps.
Hubs became available in Stable 1.0.2. The same shared policy enables the Hub
APIs, Library, coordinator wakes, monitoring, check-ins, completion evaluations,
and web entry points in Stable and Beta. Existing saved Hubs in the current
app's data home remain Hubs; this promotion does not import Beta data into
Stable. Each app retains its own identity, data home, and update feed. Diagnostics
remain limited to Beta and Remote and are independent of this feature list.
Tasks and its delegation APIs are available in Stable and Beta. Tasks takes
Kanban's navigation slot and preserves its saved order and visibility; its
List / Kanban switch keeps the board accessible. A client connected to an older
server that refuses Tasks returns to Kanban.
Inbox and its `stats.getRecap` RPC are available in Stable and Beta. Stable shows
chat attention, running and finished work, review requests, and the activity recap.
The to-do list, quick-add, delegation card, and **All tasks** link appear only where
Tasks is available, including Stable and Beta.
`accountInbox` is the account-saved Inbox history. In Stable, Beta and Remote, a signed-in computer
automatically saves account/workspace-owned daily snapshots, including project names,
and catches up its local history; **Save privately** requests an immediate update. Saved
history can be read from the account API while its source computers are offline and
survives source removal. Deleting a recap prevents automatic re-creation; an explicit
Save can restore it. This history is separate from public profile publication
and aggregate usage sync.
Stable and Remote enable account profiles and aggregate usage sync for signed-in
accounts by default; `SYNARA_ACCOUNT_PROFILE_SYNC=0` disables the feature. Beta and
generic builds retain the server opt-in `SYNARA_ACCOUNT_PROFILE_SYNC=1`. The UI reads
the server capability. New profiles remain private; publication is a separate
explicit choice and the account API enforces Alto access when configured.
See the [profiles trial guide](apps/profiles/README.md).
`pull-request-auto-fix` enables the opt-in **Auto-fix CI** action in a pull
request's menu. The server watches checks for an enabled PR and can ask its
linked agent chat to address failures in both Stable and Beta. It keeps the chat
permissions and retry limits, and waits for active work, approvals, and questions.
This does not enable automatic merging.
Message trail sound is opt-in under **Settings → Chat → Message trail sound**
on macOS desktop in both Stable and Beta. It follows system audio (macOS 14.2+),
the microphone, or both. The desktop IPC handler refuses other platforms,
and the web hides the selector on hosts without a supported desktop bridge.
Only loudness levels are sent to the trail, and the reader stops when the
visible trail no longer subscribes. First use can request macOS audio access.
## Diagnostics
Beta builds ship always-on technical diagnostics — fixed crash/error categories plus fixed
health counts (projects and active threads) — while stable
builds never enable the Beta diagnostics sender. Stable and Beta separately offer
default-off product analytics through Settings → General → Privacy.
Synara Remote shares usage and diagnostics by default: the same technical-only diagnostic events
and product events such as daily activity, feature use,
connection, pairing and turn outcomes with a fixed failure category. **Share usage
and diagnostics** in Settings → General → Privacy turns both off and clears unsent
events. Chats, prompts, replies, files, credentials, log excerpts and raw memory are never
part of telemetry, including Beta diagnostics. Product identifiers are random per
installation and unrelated to login or billing. See
[diagnostics.md](docs/diagnostics.md) for exactly what is collected, what usage
counters exclude, and how the Cloudflare ingest works.
## Data
Without an explicit import, beta starts with an empty `~/.synara-beta` home. It
does not copy, share, or migrate stable (`~/.synara`) or Canary
(`~/.synara-canary`) data on its own. Both apps can run at the same time: the
server binds an ephemeral port, single-instance locks are scoped per Electron
`userData`, and provider secrets are file-scoped inside each home.