/follower-onboard — connect a follower-consumer (v1 data-only)
🧒 When reporting to the operator, end with a child-simple "In plain words" recap (memory
eli5-always). Reports TO the operator only — never inside the package files.
Single command to build + deliver a follower onboarding package. Drives the tested generator over the master template. Full state + every decision + the gotchas = memory [[machine-migration]] (READ it first each run — the project is live, this is where the hard-won traps live).
The v1 shape (decided 2026-06-24, do NOT re-litigate)
A follower = a reading room for data. The hub SYNCS DATA the follower READS; it NEVER pushes executable code.
| Folder | Follower-side type | Why |
|---|---|---|
Owner-Knowledge (vault, Bible) |
Receive-Only | reads the Second Brain |
claude-home (CLAUDE.md + commands) |
Receive-Only | the canon — whitelist .stignore blocks hooks/secrets/scripts |
claude-memory |
Receive-Only | "one shared memory" |
claude-imports |
Receive-Only | scripts (code only, big data ignored) |
claude-skills |
Receive-Only | uses all skills |
_machine-bus |
sendreceive (tiny, versioned) | the ONLY 2-way folder (mailbox) |
ALL data folders RECEIVE-ONLY (skills too). A sendreceive skills/vault share from a follower is a DATA-LOSS VECTOR — a follower's empty folder can propagate deletions cluster-wide (it wiped the hub's skills 2026-06-24). Contributions (skills + vault notes) go via the moderated _transit channel (vault-proposals/<name>/, canon-proposals/), hub folds them in — NOT direct sync.
NO hub-pushed hooks / settings.json in v1. A follower's stock Claude CORRECTLY refuses to let a remote machine push executable hooks/** (a backdoor); a pasted "authorization" is not sufficient proof. So the hub pushes zero remote-exec. The inbox-robot is the one exception BY KIND — MANDATORY on every machine (operator's order, 2026-06-25), but installed LOCALLY by the follower's own Claude with the operator's explicit consent. A local scheduled task the operator sets up ≠ a hub push, so it is NOT the backdoor the no-hooks rule blocks. It rides the _machine-bus (the only sendreceive folder). Install via bootstrap STEP 8/9 (INBOX-ROBOT-LAUNCHER.md in _transit). The v1/v2 axis is about DATA-scope (v2 adds the Telegram-leads connector), NOT about the robot — the robot is baseline-mandatory, orthogonal to v1/v2.
Step 0 — CONSENT + QUICK WIN + PITCH (before any technical step; house rule reglament-onboarding-pitch-vtoroy-mozg)
The order: (1) a mini-consent of 4 questions (what · where · who can see it · how to delete it); (2) a quick win on the user's real life — save one useful thing and show it coming back; (3) a 7-point pitch in plain words; (4) the first save with a receipt. In the follower's intro CLAUDE.md, add the operational block "keeper of memory" + a memory check at the end of the session (wording lives in the house rule). At the 1-2 week check-in, look for 3 activation signals; zero signals → the pitch did not land, repeat it through a new quick win. Canon: reglament-onboarding-pitch-vtoroy-mozg.
Step 1 — RECALL (don't duplicate)
Read memory [[machine-migration]] §FOLLOWER-LITE + §v1 DATA-ONLY + the SKILLS-WIPE incident. Confirm the hub's safety nets are still on (see Step 6).
Step 2 — The operator's name in all grammatical forms + Latin
The generator swaps the template operator name for the target one across every declension of the local language, including all-caps forms in non-Latin scripts (a case-insensitive grep cannot fold those). Supply the Latin spelling plus each inflected form the language needs; if the name does not inflect, pass the same form for each. Unsure about the forms → ask the operator.
Step 3 — Generate
python "%WORKDIR%\migration-prep\gen_follower_package.py" \
--latin <Latin> --nom <form1> --gen <form2> --dat <form3> --acc <form4> --ins <form5>
Writes migration-prep\<latin>-follower\, verifies 0 residual leaks (Unicode-correct, ABORTS on any), builds the zip, creates vault-proposals\<latin>\. Hand the operator the v1 data-only Windows/Mac bootstrap (BOOTSTRAP-PROMPT-<NAME>-v1-data.md) — the autonomous prompt their Claude runs. Also bundle follower-kit-v1\syncthing_follower_watchdog.ps1 + install_follower_watchdog.ps1.
Step 3b — ⭐ A PERSONAL KIT instead of handing over the owner's CLAUDE.md (2026-07-27)
⛔ Never give a new person the owner's personal CLAUDE.md: it carries his paths to secrets, his chat IDs, the layout of his personal disks, and ~90% of the rules are not about this person at all (verified: 22 hits from the leak scan).
Build a kit along two axes instead — person × node:
python ~/.claude/scripts/persona_build.py --person <key> --node <node code>
- Add a new person to
~/.claude/canon/people.jsonfirst (copy the_templateblock; themay_*permissions are strictlytrue/false, with the reasoning in<field>_note). - Add a new node to
~/.claude/canon/node_caps.json(copy_template); an unknown node gets_default= minimum rights. - The builder blocks delivery on its own if the safety floor is incomplete or anything personal leaked through; check a finished kit with
--check <folder>(exit 0 = good, 2 = only half of it was checked). - The shared law (
canon/CORE.md+canon/FLOOR.md) is byte-identical everywhere — only the owner edits it, and it is receive-only on followers.
Step 4 — Deliver
⚠️ NOT via Gmail — Gmail scans archives and BLOCKS scripts (.ps1/.py) → the whole email bounces (caught 2026-06-24). Use Telegram send_file or SendUserFile. Caption: "paste BOOTSTRAP-...-v1-data.md into your Claude Code, one message."
Step 5 — Hub-side share (REST works; on-disk key hWPF… in config.xml)
Add the follower device + share the 6 folders. Auto-discovery (/rest/cluster/pending) is 404 in Syncthing v2.1.1 → instead read DeviceRejected events to find a follower's DeviceID. Use the follower's CURRENT device ID (it changes after a Syncthing reinstall — a "one folder empty, others fine" symptom = device-ID drift on THAT share).
Step 6 — Safety nets (verify ON before any follower joins)
- Syncthing versioning on every synced folder (skills=simple keep10, memory=trashcan, vault=staggered, home/imports=trashcan) → deletions recoverable from
.stversions. - git backup INITIALIZED + committing — FIRST run
powershell "$env:USERPROFILE\.claude\scripts\claude_git_backup_setup.ps1"(idempotent: git-inits skills/memory/scheduled-tasks/_config-backup/scripts/hooks + sets a per-repo identity + a global git identity). This is mandatory: a present-but-inert "Claude Config Git Snapshot" task commits NOTHING if the repos were nevergit init-ed — exactly how the hub sat unprotected until the 2026-06-24 skills wipe (only a stale manual mirror saved it). THEN verify the 15-min "Claude Config Git Snapshot" task exists and actually commits (path-agnosticclaude_git_snapshot.ps1, uses$env:USERPROFILE). Canon: [[claude-skills-git-backup]] + [[config-safety-backup-and-migration-check]]. - Followers Receive-Only (Step shape) — the deletion vector removed.
The follower-side GOTCHAS (from a real follower onboard, 2026-06-24 — put them in the bootstrap so they're handled)
.stfoldermarker missing after changing a folder's path → create the marker dir +POST /rest/db/scan.- Receive-only phantom deletions — changing an RO folder to a new empty path marks files as "local deletions" and Syncthing STOPS pulling (
need=0,local=0,global>0). Fix:POST /rest/db/revert?folder=<id>→ discards phantom changes, re-pulls from hub. - ★ Sandbox-Syncthing eviction (the big one) — every Claude Code restart launches a SANDBOXED Syncthing inside
…\Packages\Claude_*\LocalCache\Local\Syncthing\with a sandbox config (no hub device, wrong REST key → CSRF + 0 connections). It grabs port 8384 and evicts the correct daemon → sync silently stalls. **Fix = the follower watchdog** (follower-kit-v1\syncthing_follower_watchdog.ps1+install_follower_watchdog.ps1): every 10 min it checks REST-key + hub-connected; if wrong/dead, kills all syncthing.exe and relaunches with explicit--home=%LOCALAPPDATA%\Syncthing. INSTALL IT as part of every follower onboard. - Battery-friendly scheduled tasks — on a laptop a task without
-AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailablesitsState=Queuedand never runs. The install script already sets these. - session_archive on RO-vault follower — its default catalog path is inside the (RO) vault → won't sync up. Run with
SESSION_ARCHIVE_OUT=<synced-bus>\_session-archive-inbound\<machine>.
Step 6b — Tailscale join (MANDATORY for EVERY peer; gap caught 2026-07-16)
Every peer in the fleet must be on the tailnet (owner = owner.calendar@example.com, login = Google SSO). Without it there is no direct access (SSH/RDP to the hub are open ONLY from 100.64.0.0/10) — Syncthing and the messaging bus work without the tailnet, so the hole is NOT visible in day-to-day work (that is how one Mac lived off-network unnoticed until 2026-07-16). Steps: (1) install Tailscale (Windows: winget/installer; Mac: .pkg — ⚠️ needs the operator's admin password/Touch ID, a headless session will stall — ask for the operator's hands IMMEDIATELY, not at the end); (2) tailscale up → Google SSO as the owner account (password in the secrets store); (3) verify FROM THE HUB: tailscale status shows the node. The registry of expected nodes = ~/.claude/scripts/tailnet_expected.json (hub) — ADD the new node there; the nightly watchdog tailnet_guard.py shouts into the bus about missing ones. Canon: memory [[all-peers-in-tailnet]].
Step 7 — Register + report
_machine-bus\machines.json(rolefollower-consumer), memoryuser-registry+session-machine-tagging(+ per-machine default operator, see the house rule reglament-pomechat-mashinu §default operator PER MACHINE).- Report to the operator post-hoc (what onboarded, what's pending).
Hard "never"
NEVER ship claude-secrets/claude-config/.claude.json/connectors. Canon never edited by followers → canon-proposals\. Vault never directly written by followers → vault-proposals\<name>\. Headless claude -p on a follower = subscription/OAuth (set "ANTHROPIC_API_KEY="). .ps1 ASCII-only (PS 5.1 mangles non-Latin scripts).
Don't duplicate
/migrate = full HUB move (different job). /inbox = the bus the (mandatory, locally-installed) inbox-robot rides. One markdown procedure + one tested generator + the kit scripts — no server, no DB.
Like this skill? It is one of 100 in second-brain-starter-kit: the second brain we built for ourselves and run every day at Palo Alto AI Research Lab. Install the whole set with npx skills add tonydzi/second-brain-starter-kit. Everything is open source and free, so take what you need.
Flagships worth a look on their own: secondop-panel (a second opinion from a panel of external models), claude-memory-tidy (stop your agent's memory from rotting), telegram-mcp-kit (your own Telegram over MCP in about 15 minutes).
Author: Anton Dziatkovskii, Palo Alto AI Research Lab. Telegram @tonydzi - WhatsApp +1 341 222 9178 - X @Tony_Stef_
Engineers: want to test-drive this setup? Message me. I hand out free starter seeds to engineers who test and report back, and custom skill requests are welcome.