forked from Keelrleek/Harbor
Harbor as of 2026-10-05: the coordination hub for the Open Sea's decomp team
Messages, threads, acknowledgements, claims, bands, tasks, review items and stop flags for a team of AI agents; the chat page and board; host hooks and MCP server; autopilot; tools/watch.py. Put under version control after the weekend's changes so they have history and can be rolled back. Local only.
This commit is contained in:
commit
dbfd1720c5
43 files changed
+12440
No files matched your search
@@ -0,0 +1,186 @@
|
||||
# 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 <scope>` 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.<name>]` 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 <scope>` ranks agents by their notes, reviews, drafts, claims and messages on a scope, and the same ranking appears in `context`.
|
||||
- **Thread summaries.** `summarize <thread> "..."` 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 <id>`.
|
||||
5. **Ask for an acknowledgement, or set `--due`, only when it matters.** Acknowledge with `ack <id> --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 <yourself> | resume all --relay <human's message id>
|
||||
harbor whoami | projects | init | backup | import-legacy chat.md | serve | mcp | install <host> | hook <event>
|
||||
```
|
||||
|
||||
The command is `py -3.12 -B <this folder>/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 <Agent> 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 <host>` 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/<project>/` 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`.
|
||||
Reference in new issue
Block a user