Skip to content

feat(huddle): multi-machine coordination — sync, fork-proof adopt, idempotent rotation (PP-lt12.38)#1621

Merged
timothyfroehlich merged 3 commits into
mainfrom
worktree-huddle-multimachine
Jul 7, 2026
Merged

feat(huddle): multi-machine coordination — sync, fork-proof adopt, idempotent rotation (PP-lt12.38)#1621
timothyfroehlich merged 3 commits into
mainfrom
worktree-huddle-multimachine

Conversation

@timothyfroehlich

Copy link
Copy Markdown
Owner

Context

The huddle coordination system was designed single-machine. Tim now runs sessions on multiple machines (Mac + Bazzite) with many concurrent sessions per machine. The huddle beads already sync via Dolt embedded + DoltHub (sync.remote in .beads/config.yaml) — the root bead, its notes pointers, dailies/monthlies, and comments all replicate via bd dolt push/pull. What was machine-local and broke across machines: the root-bead pointer, read freshness, and the rotation lock.

Plan: /home/froeht/.claude/plans/eager-sprouting-church.md (approved).

What changed

  • huddle_sync (huddle-lib.sh) — throttled, per-machine Dolt push+pull. Shared last-pull marker + non-blocking pull.lock in the state dir (which resolves identically for every worktree/session of a clone), so one sync per HUDDLE_SYNC_SECONDS (default 180) serves all sessions on the machine — not one-per-session. Wired into the session-start and poll hooks. Fully fail-open: offline/bd errors write the marker and return 0, never blocking a prompt.
  • Fork-proof discoveryhuddle_discover_root finds the existing "Huddle coordination root" epic in the synced DB. Session-start auto-adopts it (writes config.json) when config is missing instead of nagging; huddle-bootstrap.sh discovers-before-create. No more duplicate-root fork on a second machine.
  • Idempotent cross-machine rotation (huddle-rotate.sh) — pull-first (peer-already-rotated → no-op), adopt an existing Huddle daily <today> by title instead of creating a duplicate, push-after. huddle_reconcile_today deterministically collapses any residual duplicate (canonical = lowest id) at end of rotation and once per session-start; every machine picks the same winner so they converge.
  • Intentionally still machine-local: session-names.json (self-filter) and last-seen-<hash> (poll cursor) — a session lives on one machine, and a peer machine's posts must not be self-filtered on yours.

Rotation model decision

Tim chose idempotent adopt-if-exists over a bd merge-slot cross-machine mutex. The accepted residual race (two machines both create before either pushes) is cleaned deterministically by the reconcile safety-net; rotation is lazy so a transient duplicate is harmless.

Tests / verification

  • New scripts/tests/test_huddle_sync.py — 10 cases: throttle fires/skips/stale/interval-0, fail-open on push+pull error, discovery found/lowest-id/none, reconcile collapse + no-op.
  • pnpm run check green: 80 pytest + 1414 vitest, 0 new type errors, shellcheck/ruff/yaml/actionlint/zizmor clean.
  • Docs: pinpoint-huddle SKILL.md (Multi-machine section, state-file table) + design spec §14 and revised §9.4.

🤖 Generated with Claude Code

The huddle beads already sync via Dolt/DoltHub, but three mechanisms were
machine-local and broke across Tim's Mac + Bazzite: the root-bead pointer,
read freshness, and the rotation lock. This adds:

- huddle_sync: throttled, PER-MACHINE Dolt push+pull (shared last-pull marker
  + non-blocking pull.lock in the state dir), wired into the session-start and
  poll hooks. Fail-open — never blocks a prompt.
- huddle_discover_root + auto-adopt: fresh machines adopt the synced "Huddle
  coordination root" epic instead of forking a duplicate; bootstrap is now
  discover-before-create.
- Idempotent cross-machine rotation: pull-first, adopt-existing-daily-by-title,
  push-after, plus a deterministic huddle_reconcile_today dedup (canonical =
  lowest id) run at end of rotation and once per session-start.

session-names.json + last-seen cursors stay intentionally machine-local.

Tests: new scripts/tests/test_huddle_sync.py (10 cases: throttle math,
fail-open, discovery, reconcile). Full check green (80 pytest, 1414 vitest,
shellcheck/ruff/yaml clean). Docs: pinpoint-huddle SKILL.md + design spec §14.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 6, 2026 23:49
@vercel

vercel Bot commented Jul 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pin-point Ready Ready Preview, Comment Jul 7, 2026 2:24am

Request Review

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR upgrades the huddle coordination hooks from a single-machine model to a multi-machine model by leveraging the existing Dolt/DoltHub replication in beads, adding per-machine sync throttling, fork-proof root discovery/adoption, and idempotent rotation/dedup behavior.

Changes:

  • Added huddle_sync (throttled, per-machine bd dolt push/pull) and wired it into session-start and poll hooks to improve cross-machine freshness.
  • Implemented fork-proof root discovery/auto-adopt (huddle_discover_root) and rotation idempotency (adopt-if-exists daily/monthly by title), plus a reconcile safety-net (huddle_reconcile_today).
  • Added Python unit tests covering sync throttling/fail-open behavior, root discovery determinism, and duplicate-daily reconciliation.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
scripts/tests/test_huddle_sync.py Adds unit tests for the new multi-machine sync/discovery/reconcile helpers by stubbing bd and running functions via bash -c.
scripts/hooks/huddle-lib.sh Introduces huddle_sync, huddle_discover_root, and huddle_reconcile_today to support multi-machine coordination.
scripts/hooks/huddle-session-start.sh Runs huddle_sync at session start and auto-adopts an existing root when config.json is missing; runs reconcile safety-net once per session.
scripts/hooks/huddle-poll.sh Runs huddle_sync before reading notes/comments so polls see cross-machine updates with per-machine throttling.
scripts/hooks/huddle-rotate.sh Pulls before the date re-check, adopts existing daily/monthly by title, pushes updated pointers, and invokes reconcile safety-net.
scripts/hooks/huddle-bootstrap.sh Adds discover-and-adopt behavior to prevent cross-machine duplicate root creation.
docs/superpowers/specs/2026-05-17-huddle-system-design.md Updates the huddle design spec to document the multi-machine sync/auto-adopt/rotation model and new state files.
.agents/skills/pinpoint-huddle/SKILL.md Updates the huddle skill reference with multi-machine guidance and new state-file documentation.

Comment thread .agents/skills/pinpoint-huddle/SKILL.md Outdated
Comment thread scripts/hooks/huddle-lib.sh
Comment thread scripts/hooks/huddle-lib.sh Outdated
Comment thread scripts/hooks/huddle-rotate.sh
CI runs shellcheck 0.9.0 (exits non-zero on info-level findings that local
0.11.0 doesn't emit). Two fixes:
- huddle_reconcile_today: rewrite `[[ -n ]] && bd update || true` (SC2015) as
  an explicit if.
- huddle_sync: pass the marker/interval to the locked body via exported env
  vars instead of single-quoted `$1/$2` in `bash -c`, removing the SC2016
  trigger entirely — mirrors huddle-rotate.sh's do_rotation pattern.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ose, pull-before-reconcile

- huddle_sync: wrap bd dolt push/pull in `timeout`/`gtimeout` (cap
  $HUDDLE_SYNC_TIMEOUT, default 15s) so a hung remote is killed at the cap
  instead of stalling the hook; soften the "never blocks" comment to "bounded".
- huddle_reconcile_today: repoint today_bead.id FIRST (only close duplicates
  once bd update confirms root points at the canonical), so a failed repoint
  leaves a harmless open dup rather than a dangling pointer to a closed bead.
- huddle-rotate.sh: bd dolt pull once more before huddle_reconcile_today so the
  safety-net actually sees a peer's duplicate in the double-create race.
- SKILL.md: fix broken markdown (bold split across lines rendered as a list).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@timothyfroehlich timothyfroehlich merged commit bebde77 into main Jul 7, 2026
21 checks passed
@timothyfroehlich timothyfroehlich deleted the worktree-huddle-multimachine branch July 7, 2026 02:36
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.

2 participants