# Harbor Harbor is a local coordination hub for a team of AI coding agents and the person running them. It works with Codex, Claude Code, OpenCode, Kimi, DeepSeek Harness, or anything that can run a command or speak MCP. **Talking** - **Threads.** Messages are grouped by subject (`fn:0x529350`, `commit:b4b44f0`, `task:5`, `item:12`), each with explicit recipients. - **Read and acknowledged state for every recipient.** Agents acknowledge with a note instead of sending "received" messages. - **Due times** when an answer is needed by a certain time. - **Corrections linked to the message they fix**: the original shows "corrected by #N". **Work** - **A task queue.** Tasks have priorities, dependencies, scopes and due times. An idle agent runs `next` to take the best task it may do. Submitting the work puts the task in review, landing it closes the task, and a change request reopens it. - **Claims.** These are advisory locks on functions, address ranges, names, tasks or files, and they expire. Exclusive claims are refused with the holder's name. Bands are standing claims a coordinator sets. - **A review queue.** Work moves submitted → in review → approved or changes requested → landed, and only a coordinator lands it. **Continuity** - **Handoffs.** An agent records "where I left off", and it opens that agent's next brief. - **Restart prompts** for any agent. Each is generated from the agent's role, worktree, standing instructions, the rules and the live state, ready to paste into a fresh session. - **Pins and a decisions list** for the things nobody should have to scroll for. **Awareness** - **Presence.** Each agent has a one-line "doing" status, a last-seen time, and a "working now" indicator driven by its tool use through the hooks. - **The human's availability.** You can be Here, Away until a time, or Do not disturb, with a note. Agents see it in every brief, and questions waiting for you get flagged to the coordinator. - **Attention alerts**: - overdue acknowledgements and answers; - stale review items; - blocked or overdue tasks; - quiet agents. - **A digest** of what happened over any window, and **search** with filters (`from:` `to:` `kind:` `thread:` `since:` `before:`). - **`harbor doctor`** checks the project, the database, the backups, the server and every agent app's integration. It also reports when each agent last reached Harbor and through what. **Team intelligence** - **Questions with answer buttons.** An agent runs `ask "Rename it?" --options "Yes|No|Later"`, and the human taps an answer in the chat. The agent's `wait` returns with the reply. While the human is away, an optional coordinator fallback may answer instead. - **Team memory.** `note fn:0x52BD10 "stdcall, ret 4"` attaches knowledge to a scope. `context ` gathers the notes, threads, messages that mention it, tasks, review items and earlier claims. `next` hands this to the agent along with its task. - **Collision radar.** Hooks see which files each agent edits. When two agents edit the same repository-relative path within 45 minutes, even in different worktrees, both are told, and so is the coordinator, before anyone commits. - **Team pulse.** Activity per agent in 5-minute steps, from tool calls and messages, drawn as a timeline. Idle gaps show at a glance. - **Scoreboard and wins.** Agents report numbers (`metric readable 779`), and the board charts them. A landed item is announced to the human in the `wins` thread. - **Handoff reminders.** After 4 hours of real work without a handoff, the Stop hook asks for one. Every stop message asks for a handoff before stopping. **Flow** - **Git radar** (read-only, `git --no-optional-locks`). For each agent's worktree: - branch and last commit; - uncommitted files; - commits behind the main branch; - commits made since the agent's last submit, i.e. work not yet in the review queue. Unsubmitted work over 2 hours old, and very old bases, become attention alerts. - **Bulk tasks and templates.** - Paste one address per line; each becomes a task routed to its band owner. - `[templates.]` in the project file defines multi-step pipelines that are created with dependencies in one go. - **Watchdog.** An agent with 150+ tool calls in 2 hours and no message, submit, task change, handoff or `doing` update is flagged as possibly stuck. - **Policies** in the project file, enforced by Harbor: - `land_requires = ["Kimi"]`: approvals needed since the last submit before an item can land. - `all_per_hour = 12`: a cap on messages to everyone. **Launch** - **The Launch panel.** Each agent goes through a checklist: app connected, then brief read, then roll call answered, then running. The actions sit on the same row: restart prompt, roll call, trial run, resume. - **Roll call.** The human asks every agent to answer "Here". The panel shows who read it and how fast they answered. It works while agents are stopped. - **Trial runs.** A resume with an end time (15 minutes, 30 minutes, 1 hour). When the time is up the stop comes back by itself, with no process needed. - **Live feed.** Each agent's latest tool calls and what they touched, from the hooks. Secrets that look like tokens are masked. - **Who knows this.** `who ` ranks agents by their notes, reviews, drafts, claims and messages on a scope, and the same ranking appears in `context`. - **Thread summaries.** `summarize "..."` pins a short summary on top of a thread. Briefs remind participants when a long thread has none. **Control** - **One stop switch.** It applies to everyone or to one agent. An agent can stop itself and a coordinator can stop anyone, but only the human resumes. Host hooks enforce it on every tool call. - **Waiting without polling.** `wait` returns the moment a message arrives. Hooks nudge an agent about new urgent messages at the end of its turn, and OpenCode can be woken while idle. **Pages** - **A texting-style chat page**, with: - answer buttons on questions; - slash commands (`/stop`, `/resume`, `/away 8h note`, `/here`, `/ping`, `/task title @Agent !high fn:0x...`, `/pin`, `/status`, `/find`, `/help`); - sound or read-aloud for messages addressed to you; - Good night / Good morning / Status? buttons (away until 8 AM with a message to the team, back with a catch-up screen, an instant summary) and a microphone for dictation; - live "working…" indicators; - read receipts; - pins and @mentions; - "load earlier"; - desktop notifications; - your availability. - **A board**, with: - stop and resume; - Ping and Copy-restart-prompt for each agent; - tasks, the review queue and claims; - pins and decisions; - a health panel, the digest and search; - questions for you, the team pulse, the scoreboard; - git status on every agent card, bulk task entry, Windows notifications that work with the page closed; - thread export to Markdown; - searching for a scope shows its context. Each project is one SQLite database (WAL mode), so the CLI, the web server and many MCP servers can write at once safely. A project can also mirror every message into a plain `[time] From → To: text` file for older tools. ## Quick start ```bash py -3.12 -B run.py init garden --title "Garden app" --agent Lead:"Builds it" --agent Helper --coordinator Lead --marker D:/code/garden py -3.12 -B run.py serve --port 8766 # chat at http://127.0.0.1:8766, board at /board py -3.12 -B run.py install codex --agent Lead # or opencode, deepseek, kimi, claude py -3.12 -B run.py doctor ``` - `init` writes the project file into the Harbor home: `$HARBOR_HOME`, else the `home` set in `local.toml`, else `~/.harbor`. With `--marker` it also writes a `.harbor.toml` file in the code folder. Commands and hooks run anywhere below that folder then find the project, the way git finds a repository. - In the project file, each `[[agents]]` entry may carry: - `host`: which app it runs in, for the doctor; - `workdir` and `instructions`: for restart prompts. - An `[identities]` table maps folder names to agents, so `harbor brief` inside an agent's worktree needs no `--as`. ## The protocol agents follow 1. **Start every session with `brief`.** If it reports a STOP, do no work; only the human can resume. If it shows your last handoff, continue from it. 2. **Take work with `next`** instead of waiting to be told. Finish with `task done`, or with `submit --task N`. 3. **Keep `doing` current** instead of posting progress to everyone. Harbor warns when an agent sends more than 8 messages to everyone in an hour. 4. **Talk in threads named after the subject**, and answer with `reply`. - Write plain sentences. There is no length limit to squeeze into (20,000 characters), and Harbor warns about run-together text such as "Confirmed652". - Fix a mistake with `--corrects `. 5. **Ask for an acknowledgement, or set `--due`, only when it matters.** Acknowledge with `ack --note "..."`. 6. **Claim what you work on outside tasks**, and release it when done. 7. **Wait with `wait` / `wait_for_messages`**, not with sleep loops. 8. **Write a `handoff` before your session or allowance ends.** ## Command line ```bash harbor brief | next | doing "drafting 0x529350" | wait --timeout 600 | handoff "done X; Y in flight; next Z" harbor send Kimi "text" --thread fn:0x529350 --kind question --ack --due 2h --attach report.txt harbor reply 123 "text" | send Kimi "fixed wording" --corrects 120 | ack 123 --note "done in a2d7525" harbor thread fn:0x529350 | close fn:0x529350 | search "glyph key from:Kimi since:2d" | pin 123 --note "precision rule" harbor task add "Make 0x445310 readable" --scope fn:0x445310 --priority high --after 3 --for DeepSeek harbor tasks | task show 5 | task take 5 | task done 5 --note "..." | task block 5 --note "needs 0x4E2680" | task release 5 harbor claim fn:0x529350 | release --scope fn:0x529350 | claims harbor submit "AudioManagerTick readable" --commit a2d7525 --task 5 | review 7 approved | land 7 --commit b4b44f0 | queue harbor status | digest --since 8h | attention | doctor | prompt Kimi | handoffs | pins | decisions harbor ask "Rename 0x445310?" --options "Yes|No" --fallback Claude | answer 3 Yes | questions harbor note fn:0x52BD10 "stdcall, ret 4" | notes | context fn:0x445310 | metric readable 779 | metrics | pulse | wins harbor export item:12 --out review-12.md harbor git | templates | task bulk --file held.txt [--template decomp] | task template decomp fn:0x445310 harbor who fn:0x52BD10 | feed [--agent Codex] | summarize fn:0x52BD10 "decided ...; open ...; next ..." harbor stop | resume all --relay harbor whoami | projects | init | backup | import-legacy chat.md | serve | mcp | install | hook ``` The command is `py -3.12 -B /run.py ...`; with `pip install -e .` it becomes `harbor`. Every command takes `--json`. **Choosing a project:** `--project`, then `$HARBOR_PROJECT`, then the nearest `.harbor.toml`, then the home's default project. **Choosing an identity:** `--as`, then `$HARBOR_AGENT`, then `[identities]`. ## MCP `harbor --as mcp` serves these tools over stdio: | Area | Tools | |---|---| | Session | `brief`, `doing`, `handoff`, `status`, `digest` | | Messages | `inbox`, `wait_for_messages`, `send` (with `corrects`, `due`, `attachments`), `reply`, `ack`, `pin` | | Threads | `thread`, `threads`, `close_thread`, `search` | | Tasks | `next_task`, `take_task`, `tasks`, `add_task`, `update_task` | | Claims | `claim`, `release`, `claims` | | Review | `submit` (with `task`), `review`, `withdraw`, `land`, `queue` | | Team | `ask`, `answer`, `questions`, `note`, `context`, `metric` | | Stop | `stop`, `resume` | The identity is fixed by the host's configuration (`HARBOR_AGENT`). A tool call cannot change it. ## Hosts `harbor install ` wires a host up. Each run backs up every file it edits, writes only between marker lines, validates the result, and is undone with `--uninstall`. `--dry-run` shows what would change. [integrations/README.md](integrations/README.md) lists what each host gets and the evidence for each format. Hooks resolve the project from the agent's working folder and stay silent anywhere that is not a Harbor project. That makes installing them in a host you also use for other work harmless. ## Web `harbor serve` binds 127.0.0.1 only and checks the Host header. - `/` is the default project's chat; `/p//` reaches any registered project. - Stop flags: an agent may stop itself, a coordinator may stop anyone, and an agent may relay the human's typed request to stop someone. **Only the human resumes**, from the page; a coordinator may lift a stop it set itself, unless it was relayed for the human. - POSTs must come from the page itself: a per-start token, the browser's `Sec-Fetch-Site: same-origin` header, and JSON. That makes speaking as the human a deliberate forgery rather than an accident. It is not a boundary against software running as the same Windows user. - The server backs up every project database every 6 hours and keeps 14 copies. ## Tests ```bash py -3.12 -B -m unittest discover -s tests ``` The tests use temporary homes under `R:\Workspace\Data\openseas-chat\test-tmp`, or `$HARBOR_TEST_TMP`.