# I built an AI assistant that keeps working after the chat ends

> Source: <https://shotah.github.io/gantree/>
> Published: 2026-08-29 04:24:17+00:00

The product is the crane

# A long-horizon harness you run. Not a plugin pack inside someone else’s.

Most things branded “harness engineering” are skills, agents, and slash
commands that sit inside Claude Code or Copilot. That is a wrapper around
a host you do not own. The host still holds context, tools, and whether
the trajectory finishes.

[ai-gantry](https://github.com/shotah/ai-gantry) is the
runtime: one Distroless Go process, one persona, one OpenAI-compat model,
memory you can `sqlite3`

, chat that dials out. Gantree is the
shipping yard those cranes live in — a board for an operator, never a hop
in a chat turn.

- gantry
- The rigid frame that holds and positions tools. The frame does nothing by itself; the tools and the memory do the work.

- gantree
- The shipping yard those cranes live in. Files and Docker. Pull, don’t punch.

The difference

## A harness is a process. A marketplace is a costume.

### What this stack is

- A binary you run. Aims, personality, and work still exist on Thursday.
- The model is a socket — Ollama, Gemini, ChatGPT, Grok. Swap it. The loop stays.
- MCP listed in
`mcp.toml`

is the grant. Omit it and it does not exist.
- Outbound chat (Telegram, Discord, Slack).
**No open ports. Ever.**
- Independent lookups fan out in one round; the next round uses the results. Garmin → sheet → Strava is one thread.

### What it is not

- A Claude Code or Copilot plugin marketplace with “harness” in the README.
- Prompts, skills, and sub-agents that still live in someone else’s context window.
- A chatbot that dies when the window gets expensive, then
`/new`

lobotomizes it.
- A dashboard or gateway in the token path so every message pays a platform tax.
- MkDocs around a wrapper. Documentation is not a runtime.

The crane

## ai-gantry holds the person. The yard does not talk.

One process. One persona. Chat stays Telegram. Health is an exit code, not a
port. Mid-chain does not die on a typo — the loop was hardened on the 7–12B
class, then pointed at Flash when you want the trajectory now.

```
static binary + persona + mcp.toml + any OpenAI-compat LLM  →  outbound chat
```

Want a bot tonight? Stay here. Open the board, build a crane — this yard
pulls `shotah/ai-gantry`

, writes the files, recreates. You do not
need the other checkout to stand one up.

The yard

## Operate named pets. Never sit in the turn.

Gantree is the operator plane: board, doctor, grants, logs, spend. It reads
Docker and files after the fact. If a chart would make the harness slower,
the chart is wrong. Agents open zero inbound ports. Only this UI is
reachable, and only through a path you chose.

```
browser  →  gantree (localhost | Tailscale | tunnel)
                                                 gantry  gantry  gantry
```

Hello

## Docker on the same Linux host. Node 22. First boot is /setup.

```
git clone https://github.com/shotah/gantree.git
cd gantree
cp gantree.toml.example gantree.toml
npm install
npm run build
npm start                 # http://127.0.0.1:3000
```

Open the board. Build a crane. Grant a tool. Message it on your phone.
The UI never sits in a chat turn. Home Mini vs cloud VM:
[install](docs/install.html).

Operator docs

## The board, the door, the files.

**Install** Home Mini or cloud VM. Same console. Zero inbound agent ports.
**Console** Board, grants, doctor, avatars. Chat stays Telegram.
**Operators** Setup, login, profile, roles on a handful of people.
**Headless** Attach existing dirs, tunnels, the gotchas.
**Architecture** Why Vinext on the Docker host, and why the yard pulls.
**Security** The door: bind, passphrases, sessions. Not a reason to open WAN 3000.
**Custom MCP** Your binary, still a [[server]] in that crane’s mcp.toml.
**ai-gantry** Design, features, MCP — the harness repo.
