<!-- skill: Syncthing Mesh | version: 1.0.0 | description: Device IDs, folder types, ignores, versioning and relays | category: System & Productivity -->
## Instructions
- Device IDs: QR or 56-char code (Actions → Show ID) per node; introduce A↔B both directions (pending prompt Accept on each); name devices (`laptop`, `pi-nas`) so prompts are human-readable.
- Folder types: Send & Receive (default 2-way), Send Only (source of truth, e.g. photos export), Receive Only (backup target — local changes revert); one type per folder per device, mismatch intentionally (source Send Only → backup Receive Only).
- Ignore patterns (`.stignore`): OS junk (`(?d).DS_Store`, `Thumbs.db`, `desktop.ini`), editors (`(?d).vscode`, `*.swp`, `*~`), builds (`(?d)node_modules`, `(?d)__pycache__`, `(?d).git` if repos sync via git not syncthing), caches (`(?d).cache`).
- Versioning: staggered (keep 30d/10 versions) for docs, trash-can (30d) for media drops; versioning lives on Receive nodes; never version the Send-Only source and the backup identically (waste).
- Relay/BT note: relays (`relay://`) + global discovery on for roaming/laptops, off + static `tcp://192.168.1.x:22000` for pure-LAN boxes (faster, private); `sync-protocol` listen `quic://:22000, tcp://:22000`.
- Introducer + auto-accept: hub node as Introducer shares new devices/folders automatically; auto-accept path `~/Sync/{{folderLabel}}`; use only inside trusted family mesh, never with acquaintances.
- Conflicts: `sync-conflict-*.ext` files mean both sides edited offline — diff, keep winner, delete loser; `Receive Only → Revert Local Changes` after backup verification, not before.
- GUI + API: `:8384` per node, GUI user+password + HTTPS on exposed hosts, API key for scripts (`curl -H "X-API-Key: $KEY" localhost:8384/rest/system/status`); Uptime Kuma on `/rest/system/ping`.
- Untrusted (encrypted) nodes: VPS relay stores encrypted shards (`untrusted` flag at add time, password on trusted side); VPS never sees plaintext; test decrypt-restore before trusting it.
- Performance: `fsWatcherEnabled`, 1h full scans, `maxConcurrentWrites=2` on SD/Pi, database on SSD (`-home` flag); 1M-file folders need 4GB RAM — split folders first.
- Pairing order: hub (always-on NAS/Pi) first, then leaves; share folder from hub with leaves one at a time; pause-then-share avoids initial conflict storms on 100GB imports.
- Deletion discipline: deletions sync — archive via versioning or move-out, never delete-to-test; `Receive Encrypted` + `trashcan` on offsite so fat-finger deletes are recoverable 30d.
## Examples
- Add node: copy ID → Add Remote Device → share `Docs` → Accept on other side → both `Up to Date`.
- Backup target: NAS folder `Photos-backup` type Receive Only + staggered 60d; laptop `Photos` Send & Receive.
- Static LAN: peer addr `tcp://192.168.1.21:22000, quic://192.168.1.21:22000` on both, disable relays.
- API check: `curl -s -H "X-API-Key: $KEY" localhost:8384/rest/db/status?folder=docs | jq .state`.
## Workflows
1. Hub up: install → GUI auth → ID note → folders create.
2. Leaf join: install → add hub ID (both sides) → accept folder → initial scan.
3. Tune: type per node → .stignore → versioning → introducer/auto-accept.
4. Roam: relays on for laptops, static LAN for servers, untrusted VPS for offsite.
5. Audit monthly: `Out of Sync` list → conflicts resolved → versioning size → backup verify.
## Templates
```stignore
# .stignore — paste per folder, adapt last block
(?d).DS_Store
(?d)Thumbs.db
(?d)desktop.ini
*.swp
*~
(?d).vscode
(?d)__pycache__
(?d)node_modules
(?d).cache
(?d)Cache
// per-folder extras:
// photos: *.tmp, *.lrdata
// docs: none — sync everything
```
```bash
# install + enable (Debian/Pi)
sudo apt install -y syncthing
sudo systemctl enable --now syncthing@casper
systemctl --user enable --now syncthing  # alt: user unit
# GUI: http://localhost:8384 → Settings → GUI user/pass
```
```bash
# health script (cron every 15m + healthchecks)
KEY="APIKEY"; for f in docs photos; do
 s=$(curl -s -H "X-API-Key: $KEY" "localhost:8384/rest/db/status?folder=$f" | jq -r .state)
 [ "$s" = idle ] || echo "syncthing $f state=$s"
done
```
```xml
<!-- untrusted VPS folder stanza (concept: set at Add Folder time) -->
<!-- type=receiveencrypted, password set on trusted GUI, device id=vps -->
<!-- never flip an existing plain folder to encrypted — create new -->
```
## Tools
- Syncthing 1.27+ all nodes, GUI `:8384`, `syncthing cli` (v1.20+), `jq` for API checks.
- `stignore` tester in GUI (Edit Folder → Ignore Patterns → test path); File Versioning Trashcan/Staggered built-in.
## Advanced
- CLI: `syncthing cli devices list`, `syncthing cli folders list`, `syncthing cli config devices add --device-id X`; script onboarding of 10 leaves.
- Conflicts at scale: `find ~/Sync -name "*sync-conflict*"` weekly cron → report; `Receive Only` nodes auto-revert after review.
- Bandwidth: rate-limit guests (`maxSendKbps`) on metered links, unlimited LAN; `pullers=4` on fast NAS, `1` on Pi Zero.
- Troubleshooting: stuck syncing 99% → ignores differ per side (unify) or case-only rename on Windows (rename twice); relay slow → static tcp:// LAN addr; database corrupt → `--reset-database` (rescan, IDs kept); permission denied → `ignorePerms` on FAT/exFAT mounts.
## Documentation
- In-GUI Help + Docs link.
- https://docs.syncthing.net/
- https://docs.syncthing.net/users/ignoring.html + versioning + untrusted guide
