Hatch: multi-agent harness design docs#1
Merged
Conversation
Hatch is overclaud's multi-agent upgrade — a harness that coordinates multiple coding agents (Claude Code, Codex, Kiro, Antigravity) on one repo with role assignment, an Agile-style workflow, token-tiered context, a single-source-of-truth compiler, file-based async coordination, and an audit ledger. overclaud's single-agent optimizer becomes the Claude compiler backend within Hatch. Adds hatch/ design set: README, docs/00-08 (vision, architecture, roles, coordination protocol, context+compiler, workflow, governance, orchestrator, roadmap), and spec/ schemas (registry, ticket, ledger). Modeled on a human Agile squad; staged Phase 1 (convention) -> 2 (CLI) -> 3 (full orchestrator). Links Hatch from the root README.
- Knowledge Base (kb/): shared, read+write memory store for all agents, distinct from SSOT (config-in) and ledger (events-out). Three-store knowledge model; KB->SSOT promotion at retro. New docs/09-knowledge-base.md. - Roles are per-project user config, not hard-coded: registry.yaml lives in each project's .hatch/; standard roles are a starter template. - Workflow as editable template: lanes/transitions/gates/ceremonies defined in workflow.yaml (scrum/kanban/spec-first/lite); redesignable per project. New spec/workflow.schema.md. - Update README, architecture (7 pillars + kb/ + workflow.yaml), roles, context-compiler (SSOT vs KB), workflow, vision, roadmap, registry spec, DoD.
Phase 1+2 of the Hatch design, in Go (single binary): - model + filesystem-as-database store (board, ledger, KB) with markdown frontmatter parsing - `hatch init`: scaffold a .hatch/ workspace from embedded templates with 4 workflow templates (scrum/kanban/spec-first/lite) - `hatch compile`: SSOT -> per-agent surfaces (CLAUDE.md, AGENTS.md, GEMINI.md, .kiro/steering) with L0/L1/L2 layering + manifest stale detection (`--check` for CI). Surface table derived from researched agent CLI docs (docs/10-agent-adapters.md) - workflow engine: transition authorisation, gate evaluation (command/checklist/required-field/policy/human), no-self-review, dependency gating, append-only ledger - commands: init, compile, validate, status, standup, gate, ticket (new/claim/move/show), kb (add/query/index) - unit + integration tests, Makefile, GitHub Actions CI https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
The bare `hatch` ignore pattern matched the cmd/hatch source directory, so main.go was never committed and CI `make build` failed. Anchor the binary ignore patterns instead. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- adapter layer building native headless invocations per agent kind (claude -p / codex exec / gemini -p / kiro-cli chat --no-interactive), with capability flags from registry sandbox/approval hints; kiro/ antigravity/manual fall back to handoff when no headless contract - orchestrator.Run/Execute: spawn agent, stream output, record ledger; --dry-run prints the invocation without executing - git worktree isolation helper for per-ticket runs - CLI: `hatch run`, `hatch plan`, `hatch watch`, plus `hatch board` Bubble Tea TUI dashboard (brand colors) - adapter unit tests (no real agent needed) https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- `hatch sync`: reconcile ticket status with lane (--fix), rebuild KB index, report compile staleness - `hatch hook install`: write a pre-commit hook running validate + compile --check Completes the Phase 2 automation backlog. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Three views: system architecture, ticket workflow state machine, and a ticket-lifecycle sequence. Mermaid renders on GitHub; PNGs in docs/assets. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- three new workflow templates covering product-development lifecycle styles: dual-track (discovery∥delivery), shape-up (pitch→bet→build), stage-gate (phased requirements→design→build→test→release). Now 7 templates total; all validated by a new scaffold test - architecture-diagram.md: lead with plaintext ASCII (arch + workflow + lifecycle), keep Mermaid for GitHub; drop the rendered PNGs - TUI: replace palette with neutral colors - docs (05-workflow, workflow schema, README) list all templates https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Agents now talk to each other directly (more than task-only orchestrators like Paperclip), always on the record: - bus: append-only, file-based message store. A conversation file = a channel/DM; replies (--reply-to) form threads within it - @mention: @agent / @ROLE in a message body auto-routes to that teammate's inbox (Slack-style tagging) - inbox = Slack-style notifications (DMs + @mentions + broadcast), with a per-agent read cursor; channels are browsed via `hatch channel show` - synchronous ask/reply: orchestrator relays a question to another agent and records the reply - convene: bounded multi-agent meeting; agents take turns by role, can emit DECISION: to converge - commands: msg, channel (ls/show), inbox, thread, ask, convene - docs/11-communication.md; reconcile coordination-protocol (dialogue via bus vs state via board/ledger) https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Refine the read model so agents don't process every message: - subscriptions: `hatch channel join/leave/members` — per-agent channel membership (scope, stored in .hatch/bus/.members.json) - search/recall: `hatch search <query> [--agent --channel --from --type --limit --all]` — load only relevant messages into context, newest first and capped; defaults to the agent's subscribed channels. This is L2 on-demand for conversation, not a firehose - inbox stays the must-act subset (DM + @mention + broadcast) - bus.Search + subscription store, with tests; docs/11 read-model section https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
`hatch run` now prepends an agent's unread inbox + a ticket-relevant conversation recall to its prompt (like a teammate checking Slack before starting), then marks the inbox read. Token-bounded: recall is scoped to the agent's subscribed channels, token-matched and capped; --no-catch-up opts out. - orchestrator.commContext + Run wiring; RunOptions.SkipComms - bus.Search upgraded to token (OR) matching ranked by tokens matched, so recall works on multi-word queries like a ticket title - tests for comm context + token search; docs/11 "read the room" section https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Make Hatch behave like a human squad's rhythm, not just a task queue: - ceremonies: `hatch ceremony standup` (per-agent ledger digest + blockers, posts #standup), `retro` (cycle summary + KB→SSOT promotion candidates, --write), `planning` (spawn Conductor). New ledger parser + ceremony pkg - escalation/on-call: `hatch escalate <ticket>` (ledger + #escalations, tags the target) and automatic escalation when a ticket fails a gate >=2 times; target from registry policy.escalate_to → conductor → human:lead - decision→ADR: convene turns starting with DECISION: are recorded as accepted ADRs in kb/decisions/ (new decide pkg) - store.KB.NextID extracted; tests for ceremony/decide/escalate; docs/12 https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
`hatch pair <ticket> --driver A --navigator B [--rounds N] [--claim]`: two agents work one ticket like pair programming — the driver implements a small step each round (seeing the navigator's latest feedback), the navigator reviews that turn and suggests the next; both turns recorded in a pair-<ticket> bus thread. Navigator can emit READY to end early. driver != navigator enforced. --dry-run shows the turn structure. orchestrator pair prompt builders + tests; docs/12 pairing section. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- presence pkg + presence.json: per-agent status (available/busy/paused/ offline) + note, Slack-style. `hatch presence` shows status+WIP load; `hatch presence set <agent> --status --note` - pickAgent is now capacity-aware: skips paused/offline agents and prefers the least-loaded under-WIP candidate, so run/watch route to whoever's free — like a lead assigning work - presence test https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- `hatch ceremony demo`: showcase work in terminal lanes, posts to #demo - `hatch ceremony grooming`: flag under-specified backlog tickets (missing role/priority/acceptance, leftover TODO); non-zero exit if any need work - ceremony.Demo/Grooming + tests https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- `hatch mob <ticket> --agents a,b,c --rounds N`: 3+ agents on one ticket with a rotating driver each round, the rest navigate; ends early when a majority of navigators signal READY - convene `--decider <agent>`: if no DECISION is reached after the rounds, the decider makes the final call (recorded as an ADR). convene also stops as soon as a decision is reached https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- oncall pkg + oncall.json: `hatch oncall` (show), `oncall set --rotation`, `oncall rotate` (announces in #oncall). Escalation now targets the current on-call first, then policy.escalate_to → conductor → human:lead - `incident` workflow template (detected→triage→mitigating→resolved→ postmortem) with fix-verified + postmortem-written gates; now 8 templates - docs/12 sections for on-call/incident/presence/mob; tests for oncall + on-call-aware escalation target https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
…ence Brainstorm + design (not yet implemented) for the open operational items, framed for a Founder/CEO/CTO running the squad: - docs/13-management.md: metrics derived from the ledger (cycle time, throughput, rework, gate pass rate); workload view; performance scorecards (with an honest Goodhart caveat); budget & "salary" = per-agent budget with cost capture, hard caps and auto-pause that reuses presence; stakeholder status report - docs/14-org-and-cadence.md: org chart + delegation-of-authority in the registry (escalation up the reporting line), external/cross-team dependencies, heartbeat/cadence via a stateless `hatch tick` for cron/CI, plus estimate/spike notes and a suggested implementation order https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
docs/overview.md — one-page big picture with ✓ built vs ◇ designed: the layered system map, CLI command index by area, an end-to-end "a day in the squad" flow, and the human-squad analogue table. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
…sions - docs/15-obsidian-kb.md: use an Obsidian vault as the primary KB via CLI (vault-as-files; wikilinks/tags/frontmatter/MOC/Dataview compatibility; graph-aware recall; obsidian:// + optional Local REST API), with native MD as fallback. Honest caveat: Obsidian has no official CLI - docs/16-document-templates.md: doc-type → framework → template system (ADR/MADR, RFC, PRD, design, EARS requirements, SRE postmortem, runbook, Diátaxis, Keep a Changelog…), `hatch doc new/lint`, user-overridable like workflow templates; spec-lint can gate DoD - docs/17-pre-implementation.md: decisions to settle before building the rest (cost capture, secrets/redaction, concurrency, bus parser, mock agent for e2e, Obsidian vault location), with a suggested build order https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Per the settled pre-implementation decisions: - mock agent: `cmd/hatch-mock` + `kind: mock` adapter — a deterministic stand-in agent so execute/relay/pair/convene/run are testable end-to-end without a live agent CLI. New e2e test really spawns a process and asserts prompt pass-through, output capture and ledger entries. Makefile builds it. - bus parser robustness: a line is only a message heading when it starts with "## <timestamp> · …", so Markdown "## Section" inside a message body is no longer mis-split. Regression test added. - record decisions (mock=yes, vault=both/in-repo default, cost/secrets= minimal but secrets env-only) in docs/17. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Per the minimal cost decision (track, no enforcement): - ledger entries carry cost_usd/tokens; orchestrator scrapes usage from agent output (provider-agnostic regex; estimates USD from rate_per_mtok when only tokens are given). hatch-mock emits fake usage for e2e. - store.ScanCosts parses the ledger; `hatch cost <ticket>` sums a ticket, `hatch budget` shows per-agent + team spend vs budget_usd/team_budget_usd (warns at 80%, never blocks) - registry: agent budget_usd/rate_per_mtok + policy.team_budget_usd - usage parsing test; verified e2e with the mock agent https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- metrics pkg: parse ledger into per-agent scorecards (claims, done, reviews, gate-fails, escalations, cost/tokens) + team throughput and avg cycle time (first claim → done). Nothing tracked separately. - store.Ledger.Entries(): full ledger parser reused by metrics - `hatch workload`: presence + WIP + done + idle/overloaded flags - `hatch perf [agent]`: scorecard, with the Goodhart caveat printed - metrics test https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- docs pkg + 5 default templates (adr/MADR, design, postmortem/SRE,
rfc, prd) shipped via scaffold into .hatch/templates/docs/, user-editable
- `hatch doc types` lists type→framework→required sections
- `hatch doc new <type> --title` scaffolds (substitutes {{title}}, seeds
required frontmatter: date/status/id)
- `hatch doc lint <file>|--all` checks required sections + frontmatter per
the document's declared doc-type; non-zero exit on problems (DoD-gate-able)
- docs round-trip test
https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
docs/18: two distinct things to observe — squad state (board/ledger/bus, Hatch renders) vs live per-agent output (a stream). Two non-exclusive layers: (A) a single-process Bubble Tea mission-control TUI with internal panes (no deps, works over SSH/remote), and (B) optional tmux/Zellij driver (`--mux`) giving each spawned agent a real pane. Both build on a per-run transcript (.hatch/runs/) + `hatch logs --follow`; remote/CI observes via transcripts + artifacts. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- registry `kb:` block (mode native|obsidian, vault path, wikilinks); KB store gains a configurable vault Root (in-repo default, external vault supported) + wikilink-aware index - `hatch kb link/backlinks/graph/open`: link notes (related), compute backlinks + link graph (from related + [[wikilinks]] in bodies), emit obsidian:// URI. Index renders [[wikilinks]] when enabled - verified e2e: link → backlinks/graph, wikilink index, URI https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- orchestrator writes raw stdout+stderr of each run to .hatch/runs/<ticket>/<ts>-<agent>.log (in addition to terminal + ledger summary + cost) - `hatch logs <ticket>` prints the latest transcript; --follow tails live (kubectl-logs style), --all prints every run. This is the substrate the TUI's live-output panes read. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
`hatch board` is now a Bubble Tea dashboard with three panes in one process: BOARD (selectable tickets per lane), LIVE (tails the selected ticket's run transcript — live agent output), and ACTIVITY (ledger feed). Auto-refreshes every second. Keys: tab switches pane, ↑/↓ move/scroll, f follow a ticket's output, r launch a capacity-aware run on the selected ticket (control from the TUI), g refresh, q quit. No tmux needed; the optional tmux/Zellij multi-pane driver remains future work (docs/18). https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
`./scripts/onboard.sh` (or `make onboard`): verifies Go, builds hatch + hatch-mock, optionally `--install`s them on PATH, and spins up a demo workspace in .hatch-demo (mock agent wired in) that seeds a ticket, runs it, and shows board/logs/cost/perf — so you can try Hatch locally with no real agent CLI. Flags: --install, --no-demo, --demo DIR. README quick-start updated; .hatch-demo gitignored. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- registry roles gain reports_to + authority (can_approve, budget_authority_usd, decision_scope); validated (unknown parent + reporting cycles). `hatch org` prints the tree + authority matrix. - escalation climbs the org chart: EscalateTargetForRole resolves on-call → manager of the ticket's role → policy → conductor → human:lead - tickets gain blocked_by_external (what/owner/eta/status); claim is blocked while any are open; `hatch ticket extdep <id> --add/--resolve`; `hatch status` surfaces them as risk - org-escalation test https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
A second TUI alongside `hatch board`: CHANNELS list + live messages pane (auto-refresh, scrollable) + compose line (press i, Enter to send; @mentions auto-tag). Posts as --as identity (default human:operator). This is the "Slack window" for the squad's bus; docs/11 + overview + README updated. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
`hatch board` now shows BOARD + LIVE (run transcript) + ACTIVITY (ledger) + CHAT (the communication bus) in one process. Keys: tab switch pane, ↑/↓ move/scroll, f follow ticket, r run, c cycle channel, i compose+send (@mentions auto-tag), g refresh, q quit. `hatch chat` stays as a focused chat-only view. Docs/overview/README updated. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Security: - Fix path traversal: paths.SafeSegment sanitizes any string used as a path segment; Runs()/run transcripts no longer let `hatch logs ../../x` (or a crafted ticket/agent id) escape .hatch. Tests added. - hatch validate now rejects unsafe ticket ids (chars outside [A-Za-z0-9._-]), which also keeps branches/worktrees/transcript paths safe. Test added. - Document trust boundaries in SECURITY.md: gate commands (sh -c from workflow.yaml), agent exec (no shell — args passed directly), credentials (env-only, never persisted), transcript capture caveat, path safety. Open-source standards: - Add CODE_OF_CONDUCT.md (Contributor Covenant 2.1) - CONTRIBUTING.md: add a Hatch (Go) dev + PR-standards section - SECURITY.md: add a Hatch section + reporting channel Audit notes (no code change needed): agent spawning uses exec without a shell; no secrets in code/config (grep-clean); credentials read from env at spawn; ledger appends are mutex-serialized for parallel runs. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Invert dependencies at the key infrastructure seams so the use-case core depends on ports, not concrete infra: - gate.Runner port + ShellRunner adapter; Evaluator injects it. Command execution is now swappable/testable (fake-runner test added). Package-level Evaluate/EvaluateAll stay as thin wrappers over the Default evaluator. - wf engine depends on wf.Board / wf.Ledger interfaces instead of *store.Board / *store.Ledger; `internal/wf` no longer imports `internal/store`. Escalate takes the board via the port (no internal store construction). - ARCHITECTURE.md documents the layering (domain → use cases → ports → adapters → driving adapters), the dependency rule, and the deliberate Lean non-ports (filesystem-as-DB is the product). All 18 packages pass; orchestrator.Adapter (+mock) already realised ports & adapters at the agent boundary. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Central ports package for the use-case layer (Board/Ledger/Bus/OnCall) with compile-time assertions that store/bus/oncall adapters satisfy them. Bus gains Notify + CatchUp (read-the-room formatting moved into the adapter). Additive only; no behavior change yet. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
wf is now an Engine struct holding port.Board/Ledger/Bus/OnCall; Move and Escalate are methods. The engine core imports no infrastructure (no store, bus, or oncall) — only port + model + config + gate. The CLI composition root (engineFor) wires concrete adapters. Tests use the same wiring. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
…dary - orchestrator is now an Orchestrator struct holding port.Ledger + port.Bus; Run/Execute are methods. Catch-up formatting moved into the bus adapter (port.Bus.CatchUp). The CLI/TUI composition root (orch(ws)) injects adapters. - metrics.Compute now takes port.Ledger. - internal/port gains Bus.CatchUp/MarkRead; bus implements them. - ARCHITECTURE.md: ports now live in internal/port; document the deliberate Lean line — command/mutating use cases (wf, orchestrator, gate) go through ports; read-only reporting projections (ceremony, report/cost/budget views) are composed at the root rather than leaking bus.Message into a port. All 18 packages pass; wf and orchestrator cores import no infrastructure. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- move the messaging value types (Message, SearchOpts, message kinds) into
the domain (internal/model); bus re-exports them as type aliases so call
sites are unchanged. Ports can now return domain types with no adapter leak.
- port.Bus gains Search; new port.KB (List). store/bus satisfy them (asserted).
- ceremony is now a Service{port.Board, Ledger, Bus, KB}; metrics already on
port.Ledger. The entire use-case layer (wf, orchestrator, gate, metrics,
ceremony) imports only port + model + config — no store/bus.
- composition root gains ceremonyService(ws); ARCHITECTURE.md updated.
All 18 packages pass; onboard e2e green.
https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
…onal - new `agy` adapter (Google Antigravity CLI, successor to Gemini CLI): `agy -p … --output-format json [-m] [--approval-mode/--yolo] [--sandbox]`, surface GEMINI.md. Now the default in the scaffolded registry; `kind: gemini` kept for the legacy Gemini CLI. - doctor no longer scans credential folders (security). It checks auth by running the CLI's own non-mutating command (e.g. `codex login status`) or an agent-configured `auth_check`, or honours an env key; otherwise reports "?". Agent CLIs are not mandatory — readiness needs only ≥1 present; missing CLIs are shown, not failed. - model.Agent.auth_check; envForKind adds ANTIGRAVITY_API_KEY. - docs 10/19 updated (agy default, OAuth login, optional CLIs). https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
… docs Researched each agent CLI's official docs for a non-interactive auth-status command (doctor runs it; never scans credential files): - claude → `claude auth status` (exit 0/1, JSON) - codex → `codex login status` (exit 0/1) - kiro → `kiro-cli whoami` (exit 0 = authed) - gemini (legacy) → no command; env-only - agy → no auth-status command and no API-key env (OAuth/keyring only) → doctor reports "?" rather than guessing Correct the agy adapter to the real flags (README/CHANGELOG): `-p`, `-m`, `--dangerously-skip-permissions` (former --yolo), `--sandbox`; drop the nonexistent `--output-format json`; note upstream #76 (stdout dropped on non-TTY). Remove the unconfirmed ANTIGRAVITY_API_KEY. docs/10 + 19 updated. Verified live: `hatch doctor` actually runs `claude auth status` (exit 0) on the installed claude CLI → ✓; absent CLIs show ?/✗ correctly. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- delete geminiAdapter + its registry/surface/doctor entries and the gemini test; agy (Antigravity CLI) is the only supported Google agent. The GEMINI.md compile surface stays (agy reads GEMINI.md/AGENTS.md). - scrub gemini agent-kind references in docs/README/comments → agy. 18 packages pass; agy dry-run = `agy -p <prompt>` (verified). https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
The demo previously rewrote `kind: codex` → `kind: mock`, which made `hatch doctor` show codex as "mock" and confused real-vs-demo. Now onboard inserts a dedicated `mock` agent (id: mock) and runs the demo with `--agent mock`, leaving the real agents (claude/codex/agy/kiro) exactly as scaffolded — so doctor reflects the real CLIs. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
…rst) docs/20: correct the core direction. Hatch was built as an orchestrator that DRIVES agents and as the entrypoint TUI; the right model is the inverse — the coding agent is the entrypoint and drives itself; Hatch is the shared comms+memory it reaches via an MCP server (embedded harness). Chat is both the communication channel and the backlog (thread = task); `hatch board`/`chat` are read-only views. Documents what went wrong, what survives (bus/KB/ledger/clean arch/compile-repurposed), the MCP-vs-skill-vs-plugin analysis (MCP primary, all four agents support it), a proposed MCP tool surface, and a phased plan with an open decision on how aggressively to retire the operator features. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Introduce `hatch mcp --as <agent>`, a stdio MCP server that exposes the shared chat bus and knowledge base as tools so any MCP-capable coding agent (Claude Code, Codex, agy, Kiro) can drive itself against the same comms + memory. This is the first step of the embedded-harness pivot (docs/20): the coding agent is the entrypoint; Hatch is the shared layer it reaches into. Chat doubles as the backlog — a thread is a task. Tools: whoami, chat_open, chat_post, chat_read, chat_inbox, chat_search, chat_channels, kb_add, kb_search. Posts are attributed to the --as identity, so each agent runs its own instance. Verified in-process via the SDK in-memory transport (round-trip, cross-agent @mention inbox, KB add/search). https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Repurpose `hatch compile` for the embedded-harness model (docs/20 step 2). Instead of operator instructions, each agent's surface now carries the protocol it self-follows: - Workflow rendered as prose (stages, who-does-what, gates, ceremonies) from workflow.yaml — guidance, not a Go engine. - Chat protocol: Slack-style etiquette over the Hatch MCP server (open a thread per task, brief in-thread, @mention, inbox, search, kb). - Definition of Done: a self-check derived from workflow command-gates + policy (no-self-review / human-merge) the agent runs before reporting. - Orchestrator block on the lead agent's surface only (the conductor). And it registers the `hatch mcp --as <agent>` server with each agent: merges into repo-local `.mcp.json` (Claude) and `.kiro/settings/mcp.json` (Kiro) preserving existing servers; writes paste-ready snippets under .hatch/mcp/ for Codex and agy whose configs live outside the repo. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Step 3 of the embedded-harness pivot (docs/20): a loadable/installable Claude Code plugin under hatch/plugin/ that wires Hatch into Claude: - .mcp.json launches `hatch mcp` (the shared chat + KB tools). - skills/hatch-chat teaches the squad etiquette (thread = task, @mention, recall-before-rederive, DoD self-check). - /hatch slash command syncs with the squad (inbox + open threads). - marketplace.json at repo root so `/plugin install hatch@hatch` works. To make the plugin workspace-agnostic, `hatch mcp` now resolves its identity when --as is omitted: $HATCH_AGENT, else the first claude-kind agent in the registry. So the plugin needs no per-project config. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Steps 4-5 of the embedded-harness pivot (docs/20). Hatch no longer drives agents or enforces workflow in code; the coding agent drives itself through the MCP server, and Hatch is comms + memory + read-only views. Read-only views: - Rewrote the board TUI as mission control over THREADS (chat = tasks) + CHAT + ACTIVITY (ledger). Dropped the orchestrator LIVE pane, ticket lanes, presence, run-control and message composing. - Made the chat TUI a pure viewer (no compose/post). - Rewrote `status` to summarize chat threads + roster instead of board lanes/tickets. Archived behind the `hatch_legacy` build tag (recoverable, excluded from the default binary): run/plan/watch/tick, the orchestrator, the workflow engine (gate/escalate/ticket), ceremonies, ask/convene, pair/mob, presence, oncall, cost/budget, workload/perf, report. Default `hatch` keeps init/compile/validate/status/kb/board/chat/sync/hook/msg/channel/ inbox/thread/search/doc/logs/org/doctor/mcp. root.go registers the lean set and calls addLegacyCommands, which is a no-op by default and wires the archived commands under -tags hatch_legacy. Updated onboard.sh to demo the new flow; split the integration test into a default (embedded-harness) flow and the legacy one. Both build tags build, vet and test green. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
The read-only TUI rewrite removed the last textinput usage, so clipboard is no longer needed; `go mod tidy` prunes it (fixes the CI tidiness check). Also mark docs/20 roadmap steps 1-6 complete. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Reframe the README away from the pre-pivot orchestrator story: Hatch is an embedded harness (shared chat = comms + backlog, KB, over MCP) that agents drive themselves through — not a tool that spawns/drives agents. Correct the CLI section to the actual default command set, mark the self-driving operator as archived behind -tags hatch_legacy, and note that docs 00-19 describe the original design while doc 20 is current. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Replace the pre-pivot overview (orchestrator spawning agents, workflow engine enforcing gates, board as control panel, management dashboard) with the current model: agents are the entrypoint and self-drive, reaching the shared chat (= comms + backlog, thread = task) and KB via the hatch MCP server; compile emits protocol prose + MCP registration; board/chat/status are read-only; the self-driving operator is archived behind -tags hatch_legacy. Adds a doc-20-wins banner. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
- Redraw docs/architecture-diagram.md for the embedded-harness model: SSOT → compile → per-agent surfaces (protocol prose) + MCP registration; agents are the entrypoint and self-drive, reaching the shared chat (= comms + backlog, thread = task) + KB + ledger via the hatch MCP server; read-only observe layer; archived-operator note. Replaces the old orchestrator-spawn / workflow-engine diagrams. Plaintext-first plus refreshed Mermaid. Adds a task-as-thread lifecycle and an inter-agent message-round diagram. - README: add a step-by-step 'Cài đặt & Onboarding (user mới)' section (prerequisites → install hatch → init → compile → optional Claude plugin → work & observe), with the correct module path and the demo fallback for environments without a real agent CLI. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Add per-client MCP wiring so any of the four CLIs can be the orchestrator, not just Claude. `hatch init --client <x>` scaffolds (or reuses) the workspace, compiles, then registers the hatch MCP server where that client actually reads it — using the agent's own identity (--as <id> from registry.yaml): - cc → project .mcp.json + prints the /plugin marketplace install steps - codex → shells out to `codex mcp add hatch -- hatch mcp --as codex` (Codex owns ~/.codex/config.toml); falls back to printing the snippet - agy → merges the HOME-level ~/.gemini/config/mcp_config.json that the Antigravity CLI loads, plus a .agents/ workspace copy - kiro → .kiro/settings/mcp.json Works in-place on an existing .hatch; --dry-run previews without writing. /root-level writes happen only on the explicit --client invocation and merge-preserve other servers. README onboarding updated. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Antigravity CLI loads MCP servers ONLY from a HOME-level mcp_config.json (a separate file, not inline in settings like legacy Gemini CLI). Current runtime path is ~/.gemini/config/mcp_config.json; older installs use ~/.gemini/antigravity-cli/mcp_config.json (now a symlink). Project-local .antigravitycli/mcp_config.json is detected but silently ignored (google-antigravity/antigravity-cli#60). Fixes for --client agy: - Write ~/.gemini/config/mcp_config.json (current), and also the legacy ~/.gemini/antigravity-cli/mcp_config.json only when that dir already exists and isn't a symlink (covers pre-migration installs). - Drop the bogus .agents/mcp_config.json workspace write (wrong path AND ignored by the runtime); print a note that project-local isn't loaded. - Fix the compile-generated agy snippet that pointed at the legacy ~/.gemini/settings.json. README updated. Verified against issue #60 and Antigravity CLI docs (Arm Learning Paths, Google Cloud Community). https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Workspace resolution is now layered: a local .hatch (nearest ancestor of cwd) overrides the global ~/.hatch, which is the default used in every repo. `hatch init` creates the global ~/.hatch; `hatch init --local` creates a project .hatch that overrides it. $HATCH_HOME relocates the global root (and sandboxes tests). - paths: GlobalRoot(), FindLocal() (local-only), Find() now falls back to the global workspace when there's no local one. - config.Workspace gains OutputRoot/Out(): compiled surfaces + MCP registration always target the working repo (cwd), even when the SSOT is the global ~/.hatch — so the repo gets its CLAUDE.md/.mcp.json while the repo is NOT polluted with a stray .hatch. compile + --client honor it. - compile keeps codex/agy snippets with the SSOT (.hatch/mcp/) instead of scattering them into the working repo. - loadWorkspace does the local→global resolution for all commands. Also rename the onboarding demo dir .hatch-demo → demo-workspace (it was a throwaway sandbox, confusingly named like .hatch) and make the demo use --local. Tests cover local-overrides-global and the not-found fallback. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
A practical bring-up doc: what Hatch is post-pivot, build/test/run (both build tags), current state, what must be verified locally (real MCP handshake with claude/codex/agy/kiro, codex mcp add, agy runtime path, doctor), architecture pointers, known limitations, and git conventions. https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
fioenix
added a commit
that referenced
this pull request
Jun 23, 2026
Addresses the changes-requested review on PR #2: - [#1] daemon: replace (not merge) the wake-policy Working snapshot each tick, so a finished runner stops debouncing future wakes (agents no longer go silent). - [#2] slack: guard the threadmap with a mutex — the Socket Mode consumer and the mirror ticker share it (was an unsynchronised map → data race). - [#3] slack: config/help/spec now point at .hatch/run/slack/config.json (drifted after the runtime-dir move). - [#4] daemon: persist the processed cursor (.hatch/run/daemon.cursor) so a restart resumes instead of replaying the whole backlog. - [#5] daemon: on a failed Wake, requeue the payload before clearing the working flag — a spawn/resume error is retried next tick, not dropped. pending is now mutex-guarded for the dispatch goroutines. Added Wait() for graceful drain. - [#6] slack: persist the mirror cursor in the threadmap, so a bridge restart does not re-post history. - [#7] roster + session: serialize read-modify-write with a package mutex and per-pid temp files (concurrent runners no longer clobber/lose updates). - [#8] slack: optional BossUserID (HATCH_SLACK_BOSS_USER) — when set, only the boss's Slack user may drive the squad; empty = single-tenant. Deferred (documented): per-thread coalescing/dispatch (#9) stays with the parallelism work. lint + test green; -race clean on daemon/slack/session/roster. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fioenix
added a commit
that referenced
this pull request
Jun 23, 2026
Addresses the changes-requested review on PR #2: - [#1] daemon: replace (not merge) the wake-policy Working snapshot each tick, so a finished runner stops debouncing future wakes (agents no longer go silent). - [#2] slack: guard the threadmap with a mutex — the Socket Mode consumer and the mirror ticker share it (was an unsynchronised map → data race). - [#3] slack: config/help/spec now point at .hatch/run/slack/config.json (drifted after the runtime-dir move). - [#4] daemon: persist the processed cursor (.hatch/run/daemon.cursor) so a restart resumes instead of replaying the whole backlog. - [#5] daemon: on a failed Wake, requeue the payload before clearing the working flag — a spawn/resume error is retried next tick, not dropped. pending is now mutex-guarded for the dispatch goroutines. Added Wait() for graceful drain. - [#6] slack: persist the mirror cursor in the threadmap, so a bridge restart does not re-post history. - [#7] roster + session: serialize read-modify-write with a package mutex and per-pid temp files (concurrent runners no longer clobber/lose updates). - [#8] slack: optional BossUserID (HATCH_SLACK_BOSS_USER) — when set, only the boss's Slack user may drive the squad; empty = single-tenant. Deferred (documented): per-thread coalescing/dispatch (#9) stays with the parallelism work. lint + test green; -race clean on daemon/slack/session/roster. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hatch — bản nâng cấp đa-agent của overclaud
Bộ thiết kế (design docs) cho Hatch: harness điều phối nhiều coding agent (Claude Code, Codex, Kiro, Antigravity) trên cùng một repo, tối ưu token, theo quy trình kiểu Agile. Đây là bản nâng cấp của chính overclaud — overclaud single-agent trở thành compiler backend cho Claude bên trong Hatch. Sản phẩm thuộc hệ sinh thái Finolabs.
Xương sống thiết kế
Mô phỏng một squad Agile người: nhiều tác nhân thông minh, không chung bộ nhớ, phối hợp qua artifact ngoài (board + ledger), bất đồng bộ. Điều phối Hybrid: Conductor (CC) lập kế hoạch & chia ticket; workers tự claim và phối hợp async.
Sáu trụ
CLAUDE.md/AGENTS.md/.kiro/steering/per-agent (hết drift).registry.yaml.Nội dung
hatch/README.md— tổng quanhatch/docs/00-08— vision, architecture, roles, coordination protocol, context+compiler, workflow, governance, orchestrator, roadmaphatch/spec/— schemaregistry/ticket/ledgerREADME.md— link tới HatchLộ trình (3 phase)
hatch compile/status/gate/sync)hatch runspawn agent vào worktree riêng — "nở agent")https://claude.ai/code/session_01LJ6kqJhxDKCymkFoLTTFqQ
Generated by Claude Code