hatchery-harness-engine 0.2.4

Pure, prepare-then-accept state machine for the hatchery harness task/run/delivery kernel
Documentation

hatchery

hatchery is the product: a complete, open-source kit for running and orchestrating CLI coding-agent sessions (Claude Code, Codex, Kimi, Grok) on machines you control. Everything an operator needs ships inside it:

  • hatchery-node — the machine-side daemon: PTY/inline provider sessions (transport from gate4agent 0.5, which stays a thin byte transport), an embedded m4a messenger mailbox, the local browser machine (dig2browser), session restore, kernel WireGuard to C2, and the memory tool agents can ask for.
  • hatchery-c2 — the public-edge relay: nodes call home over WireGuard, HQ talks only to C2.
  • hatchery-server — the core-side host for subservices: harness and observation, the m4a key vault, and memory4agent started on demand.
  • HQ side: harness, observation, TUI/bidi clients (web-session first, GUI later).

m4a (messenger), memory4agent and gate4agent are dependencies inside the kit, not separate products you must assemble. Providers never see hatchery: from inside a session it looks like the provider CLI plus a few ordinary tools.

Everything is configurable (local process, service, Docker, QEMU, VPS) with addresses, keys and tokens from the environment only; no domain, IP or key is compiled in. Each crate has a deploy/ kit; the kits are tuned for a fast deploy of a two-host server (core + edge) and for nodes on personal machines. Step-by-step guides live in the documentation repository under docs/hatchery/handoffs/ (server layout, local node on Linux/macOS/Windows, E2E evidence).

Layers

One direction of wrapping: providers → node → c2 → harness → client app. Providers, the node and the c2 live in gate4agent (see Built on below); the harness, the observation side and the client app are hatchery-* in this repository. Crate names below are prefixed hatchery- unless noted.

  • Providers — blackbox vendor CLIs (Claude Code, Codex, Kimi, Grok) wrapped by the transport core in gate4agent: root crate gate4agent, gate4agent-pty, -types, -adapters, -provider-ports, -catalog, -engine, -kernel, -handle, -tool-protocol, -tool-engine, -shell-history, -shell-capabilities, -shell-hooks, -shell-managed-hooks, -shell-one-shot, -shell-native, -runtime-native. Not part of this repository — consumed from crates.io (see Built on).
  • Observation — read-only monitoring facts projected from provider sessions, never prompts/transcripts/credentials: -observation-protocol, -observation-api, -observation-engine, -observation-store, -observation-service. The node names no observation type: the projection from the node's own control events, agent-stream Blocked chunks and record history summaries is hatchery_observation_engine::node_projection.
  • Node — wraps providers on one machine: PTY/inline sessions, the file browser, local git, worktrees. gate4agent's: gate4agent-node-protocol, gate4agent-node-wire, gate4agent-node (bin gate4agent-node).
  • C2 — relays any number of nodes to their clients and routes commands (spawn, session control) down to nodes. gate4agent's: gate4agent-c2-protocol, gate4agent-c2-client (bin gate4agent-c2ctl), gate4agent-c2 (bin gate4agent-c2).
  • Harness — the stateful backend behind one app-facing protocol: task kanban over SQLite, session extraction/continuation, delivery of skills/plugins/MCP config, an operator surface: -harness-protocol, -harness-engine, -harness-service (bin hatchery-harness), -harness-api, -harness-client (bin hatchery-harnessctl), -harness-mcp (bin hatchery-harness-mcp), -harness-delivery, -harness-light (stateless, serves the same operator wire straight over c2 with no task kernel behind it).
  • Client — crates/hatchery-tui (root workspace member): bins hatchery-tui (against a durable harness) and hatchery-tui-light (hosts hatchery-harness-light in-process). Neither app speaks c2 itself.
  • Arcade — crates/hatchery-arcade/{engine,games/*,sweep,preview,bench} as root workspace members (hatchery-arcade-*); hatchery-owned, not g4a.
  • Build stamp — gate4agent-build-stamp (in gate4agent): a git content-hash of that repository's working tree, carried by every wire handshake instead of a hand-typed protocol version number. hatchery's binaries carry it through gate4agent-node-protocol.

Pipe and env-var names above still carry the gate4agent-/GATE4AGENT_ prefix inherited from the repository this stack was split out of — a later step (§11.4 / brand Step 4b) renames those hatchery-side runtime identifiers. TUI binaries are already hatchery-tui / hatchery-tui-light. Full ledger: hatchery-websession-docs plans/harness-mcp-bin-env-domain-rename-2026-10-02.md and STATUS.md.

Runtime Current Deferred target / note
Helper bin hatchery-harness-mcp done wave C
Harness / ctl bins hatchery-harness, hatchery-harnessctl done wave C
Session MCP env HATCHERY_HARNESS_SESSION_* already final
Legacy direct MCP env GATE4AGENT_HARNESS_READ_* rename or retire; scrubbed on product spawn
Operator / TUI env GATE4AGENT_HARNESS_*, GATE4AGENT_TUI_* HATCHERY_*
Node / C2 tokens & pipes GATE4AGENT_NODE_*, GATE4AGENT_C2_*, gate4agent-node / -c2 keep (g4a-owned; not hatchery rename)
Capability harness-mcp-read-proxy-v1 keep (C2 negotiate)

Repository layout

Everything in this repository lives under crates/: harness, observation, TUI, and arcade. Node and C2 are not in-tree — hatchery pins the published gate4agent-* crates from crates.io (currently 0.4.8). A sibling gate4agent checkout is no longer required to build hatchery.

Local path overrides (for co-developing against an unreleased g4a tip) are optional and belong in a personal [patch.crates-io] — not in tip Cargo.toml.

crates/hatchery-tui and the hatchery-arcade-* crates are members of the root workspace (see The TUI's uzor dependency below). There is no nested [workspace] under crates/.

Local endpoints

Layer Local pipe API
Node \\.\pipe\gate4agent-node (Unix: local socket) 127.0.0.1:18310
C2 \\.\pipe\gate4agent-c2 (Unix: local socket) 127.0.0.1:18320
Harness — operator surface on 127.0.0.1:18330

The harness does not share the primary c2 — it connects out through a second c2 instance of its own, on pipe gate4agent-c2-harness with API 127.0.0.1:18321. A live stack is therefore four processes: node, two c2, harness. Bring one up without that second instance and the harness fails at startup with a bare connect error.

Only node's 18310 and c2's 18320 are compiled-in defaults. 18321 and 18330 are conventions passed on the command line (--api-listen, --read-bind), so grepping the source for them finds nothing.

All of it is loopback/local-only; nothing here is reachable off the host by default.

Credentials

Env vars only — never pass a token as argv, never commit a value:

  • GATE4AGENT_NODE_TOKEN, or GATE4AGENT_NODE_TOKEN_<NORMALIZED_ID> for a per-node override (id uppercased, non-alphanumeric characters replaced with _)
  • GATE4AGENT_C2_TOKEN
  • GATE4AGENT_HARNESS_OPERATOR_TOKEN

Tests

Windows PTY/session-touching tests in the node/c2/harness crates run only through the headless test supervisor — gate4agent-testkit's windows-headless-supervisor binary (from the gate4agent-testkit crates.io crate / its source tree). It suppresses Windows fault dialogs and enforces a hard per-test timeout that plain cargo test cannot:

..\gate4agent\target\release\windows-headless-supervisor.exe <timeout_ms> <ABS path to test exe> --exact <test_fn>

All builds share the workspace's own root target/. A per-run --target-dir is a full copy of the dependency build and they pile up fast; when two builds overlap, Cargo's build lock simply makes the second wait. Tests gated by require_windows_headless_supervisor_for_test() reject themselves outright if run any other way.

The TUI's uzor dependency

crates/hatchery-tui depends on the uzor-tui crate from crates.io (the uzor UI framework, maintained by the same owner). It pulls from crates.io, not a sibling checkout, so it adds no repository requirement beyond the one every hatchery-* crate already has (gate4agent crates.io pins, see Built on). The status bar's pet overlay links in-tree crates/hatchery-arcade (engine + pet-bastion). Arcade is part of hatchery, not a gate4agent sibling and not part of g4a; packages are hatchery-arcade-* and live in the root workspace.

Built on

  • gate4agent — providers, node daemon, and C2 this HQ talks to: spawning/streaming CLI agents over PTY/pipe/ACP, plus the node/C2 wire. Tip pins crates.io 0.4.8 (see Repository layout); a sibling checkout is optional for local co-dev via [patch.crates-io] only.
  • mail4agent — agent mail as its own service, local API on 127.0.0.1:18301. The harness keeps no mailbox of its own.

License

MIT