Skip to content

Harborline-Software/coordination

Repository files navigation

Harborline-Software Coordinator

Filesystem-based coordination layer for multiple Claude Code sessions working across sibling repos on the same workstation — and across SSH-reachable hosts. Sessions write Markdown "beacons" into a shared inbox/; peer sessions read them on each loop iteration and respond by writing their own beacons or resolving via mv into _archive/.

This repo bundles three pieces:

  • sync-coordination.py — bidirectional Mac ↔ Windows sync of inbox/ and _archive/ via SSH + scp. Archive-presence is canonical (a file in _archive/ on either side wins).
  • Harborline-Software.10s.sh — SwiftBar menubar plugin to toggle sync state, start/stop local services (Bridge / Galley / Anchor), and open logs / folders. Refreshes every 10 s.
  • com.sunfish.coordination-sync.plist.template — macOS LaunchAgent that fires the sync script every 60 s while a .sync-active flag file exists. Silently no-ops when paused.

Originally built for the Sunfish multi-session naval-org (CO → XO → {COB, dev, po-win, PAO → Yeoman}), but the protocol is generic — fork and customize the sender list / service surface.

Quick start

git clone <this-repo> coordination
cd coordination
brew install --cask swiftbar    # one-time; the menubar host
./install.sh                    # writes the LaunchAgent + symlinks the SwiftBar plugin + loads launchd
open -a SwiftBar                # first launch — pick ~/Library/Application Support/SwiftBar/Plugins when asked
touch .sync-active              # arm the sync (or click "Enable sync" in the menubar)

The menubar will show 🚩 (active) or 🏳️ (paused). Click for the full control panel.

Configuration

Defaults assume the repo lives next to Sunfish/ and galley/ checkouts. Override via env vars:

Variable Default Used by
COORD_MAC_DIR Script's own directory sync-coordination.py
COORD_WIN_HOST winhub sync-coordination.py (SSH alias for the Windows host)
COORD_WIN_DIR C:/projects/Harborline-Software/coordination sync-coordination.py
SUNFISH_DIR <repo>/../Sunfish menubar plugin
GALLEY_DIR <repo>/../galley menubar plugin

For env-var overrides on the LaunchAgent side, add them to the rendered ~/Library/LaunchAgents/com.sunfish.coordination-sync.plist under the EnvironmentVariables dict.

Layout

coordination/
├── README.md                                   # this file
├── LICENSE                                     # MIT
├── install.sh                                  # local installer (LaunchAgent + SwiftBar plugin)
├── sync-coordination.py                        # bidirectional sync engine
├── Harborline-Software.10s.sh                      # SwiftBar menubar plugin (refresh: 10s)
├── com.sunfish.coordination-sync.plist.template  # LaunchAgent template (paths substituted by install.sh)
├── inbox/                                      # active beacons — sessions read every loop iteration
│   └── .gitkeep                                # contents are .gitignored (private session state)
└── _archive/                                   # resolved beacons (plain `mv` from inbox/ to here)
    └── .gitkeep

Sessions and prefixes

Naval-org chart: CO (Chris, BDFL) → XO (Sunfish research) → {COB (sunfish-PM, code), dev (galley primary + Sunfish overflow, Mac-side), po-win (Windows-side implementations + GPU host), PAO (book editor) → Yeoman (book technical writer)}.

Filename convention: {sender}-{type}-YYYY-MM-DDTHH-MMZ-{slug}.md

Sender Sessions Cross-repo writes
cob sunfish-PM cob-idle-*.md, cob-question-*.md (when blocked on XO)
dev galley senior developer (Mac-side) — Opus 4.7 + xhigh, used sparingly dev-question-*.md (architecture halt), dev-status-*.md, dev-idle-*.md, dev-resumed-*.md. Primary scope: galley/. Secondary: Sunfish overflow when COB asks or CO directs. Agent definition: .claude/agents/dev.md.
po-win Windows-side senior developer — Opus 4.7 + xhigh, used sparingly. Runs on the Windows host (desktop-umt08rn / winhub over Tailscale; RTX 4070 Ti). po-win-question-*.md, po-win-status-*.md, po-win-idle-*.md, po-win-resumed-*.md. Owns: galley services/python-workers/, apps/api/ (Windows GPU surface), apps/desktop/src-tauri/ Windows targets (x64 + ARM64), Windows-side plugin manifests, MAUI Anchor Win10/11 target (consulted by cob). Agent definition: .claude/agents/po-win.md.
pao book editor pao-question-*.md (cross-repo Sunfish-architecture questions; book-internal directives stay in the-inverted-stack/.pao-inbox/)
yeoman book technical writer yeoman-*.md only as PAO-bypass fallback when PAO is offline AND a critical Sunfish question can't wait
xo Sunfish research xo-directive-*.md, xo-ruling-*.md, xo-idle-*.md (writing to any session, including dev and po-win)

Body: 3-line YAML frontmatter (type, workstream-or-chapter, last-pr) + ≤2 lines context + ≤2 lines "what would unblock me."

Read protocol

Every session reads coordination/inbox/*.md at session start and on every loop iteration:

ls /Users/christopherwood/Projects/Harborline-Software/coordination/inbox/*.md 2>/dev/null

Non-empty → priority above normal cadence. Resolve via answer / hand-off / ledger update / ADR amendment, then move the resolved beacon:

mv coordination/inbox/<beacon>.md coordination/_archive/

Two tiers

  • Tier 1 — book-internal (Yeoman ↔ PAO): stays in the-inverted-stack/.pao-inbox/. Includes pao-directive-*, yeoman-question-*, yeoman-resumed-* to PAO, plus subdirs _creative/, _decisions/, _editorial-reviews/, _state-snapshots/. Does NOT belong here.
  • Tier 2 — cross-repo: all other inter-session messaging (sub-XO sessions → XO, XO → book sessions, COB ↔ XO, PAO → XO). Belongs here.

Trim policy

  • _archive/*.md older than 30 days → delete (no PR — this dir is not git-tracked).
  • Active beacons in inbox/ older than 7 days unanswered → escalate to CO.

Git status

The parent Harborline-Software/ folder is not a git repo. Beacons in this directory are filesystem-coordinated only; no PR-gated archival. If audit trail is needed for a specific resolution, sessions can also git-commit a copy into Sunfish/icm/_state/ as part of the resolving PR.

Cross-host sync (Mac ↔ Windows)

When po-win is active, the Windows host has its own checkout at C:\projects\Harborline-Software\coordination\. The two coordination folders are kept in sync via coordination/sync-coordination.py (Python 3, runs on Mac, sshes to winhub).

# manual sync
python3 /Users/christopherwood/Projects/Harborline-Software/coordination/sync-coordination.py

# dry-run + verbose to inspect what would change
python3 /Users/christopherwood/Projects/Harborline-Software/coordination/sync-coordination.py --dry-run --verbose

Sync rules:

  1. A beacon present in _archive/ on EITHER side is canonical-resolved — propagate to _archive/ on the other side AND delete from inbox/ on both sides.
  2. Beacons in inbox/ on only one side get copied to the other.
  3. Filename collisions in inbox are resolved by mtime (newer wins). Beacon filenames carry UTC timestamps, so collisions only happen if both sides write to the exact same name in the same second — never in practice.
  4. README.md and other non-beacon files are not synced by this script (manually copy if needed).

Automatic run cadence (launchd on Mac): a LaunchAgent at ~/Library/LaunchAgents/com.sunfish.coordination-sync.plist runs the sync script every 60 seconds. It's controlled by a flag file:

# Enable sync (when po-win is active)
touch /Users/christopherwood/Projects/Harborline-Software/coordination/.sync-active

# Pause sync (when no Windows session is running)
rm /Users/christopherwood/Projects/Harborline-Software/coordination/.sync-active

When the flag is absent, the LaunchAgent fires every 60s but the script silently exits 0 — zero ssh / scp / launchd noise.

Other controls:

  • Inspect launchd output: tail -f coordination/.sync-stderr.log (errors), coordination/.sync-stdout.log (informational; quiet by default)
  • Manual one-shot sync: python3 coordination/sync-coordination.py [--dry-run] [-v]
  • Unload permanently: launchctl unload ~/Library/LaunchAgents/com.sunfish.coordination-sync.plist

Sessions writing beacons should leave the flag enabled for the duration of po-win activity. Mac-side sessions writing beacons get sync within 60s. The po-win session on Windows writes locally and waits up to 60s for the next periodic fire (or asks CO to run sync immediately).

Periodic git pull (added 2026-05-18)

tender-win-git-pull.ps1 runs every 10 min via Scheduled Task HarborlineTenderGitPull. Pulls fleet + coordination repos with --ff-only (skips if working tree dirty so your in-flight Windows-side edits aren't disrupted). Log: coordination/.git-pull.log.

This complements the Mac-side launchd sync timer — that handles coordination/inbox/, _archive/, heartbeats/ every 60s; this handles git-tracked surfaces (agent defs, rules, .wolf state, sync script updates themselves) every 10 min.

Menubar control (SwiftBar)

A SwiftBar plugin gives CO one-click menubar control over the sync flag. It shows:

  • Current state (🔄 active / ⏸ paused) in the menubar
  • Inbox + archive counts, last-sync line, last error
  • Toggle (Enable/Pause sync), Sync now (one-shot bypassing the flag), Clear logs
  • Open coordination folder / inbox / archive in Finder
  • LaunchAgent submenu (Load / Unload / Reload / Edit plist)

Install (one-time):

brew install --cask swiftbar     # MIT-licensed menubar plugin host
# Plugin is already symlinked at:
#   ~/Library/Application Support/SwiftBar/Plugins/Harborline-Software.10s.sh
# → /Users/christopherwood/Projects/Harborline-Software/coordination/Harborline-Software.10s.sh
open -a SwiftBar

On first launch, SwiftBar asks you to pick its plugin folder via Finder — choose ~/Library/Application Support/SwiftBar/Plugins. The menubar item refreshes every 10s.

Plugin source: coordination/Harborline-Software.10s.sh — single bash script. The .10s in the filename is the SwiftBar refresh interval. Edit + save and the menubar picks it up on next refresh.

About

Coordination — Harborline fleet inbox + sync scripts

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages