docs: agent harness registration (GSTA-135)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-28 01:11:39 +00:00
1 parent 4aebb1d635
commit 7518f14ca8
8 files changed
+94 -20

No files matched your search

+3 -2
View File
@@ -2,6 +2,7 @@
# gstack-harness-ledger.sh — sourced; removes what gstack-harness registered,
# from its ledger, without bun (bin/gstack-uninstall runs it before it removes
# the checkout and the state root). Ledger format: lib/harness-register.ts.
# Callers set GSTACK_STATE_ROOT first (bin/gstack-state-root.sh).
#
# gstack_harness_unregister_ledger <ledger> remove one registration
# gstack_harness_unregister_all remove every registration under
@@ -28,7 +29,7 @@ _gstack_harness_cut_block() {
}
gstack_harness_unregister_ledger() {
local ledger="$1" root="${GSTACK_STATE_ROOT:-$HOME/.gstack}" stamp kind a b target="" dest="" pack="" backup
local ledger="$1" root="${GSTACK_STATE_ROOT:?gstack-harness-ledger: GSTACK_STATE_ROOT is not set}" stamp kind a b target="" dest="" pack="" backup
[ -f "$ledger" ] || return 0
stamp="$(date -u +%Y-%m-%dT%H-%M-%SZ)-$$"
backup="$root/backups/harness/$stamp"
@@ -54,7 +55,7 @@ gstack_harness_unregister_ledger() {
}
gstack_harness_unregister_all() {
local root="${GSTACK_STATE_ROOT:-$HOME/.gstack}" l
local root="${GSTACK_STATE_ROOT:?gstack-harness-ledger: GSTACK_STATE_ROOT is not set}" l
for l in "$root"/harness/*.ledger; do
[ -f "$l" ] || continue
gstack_harness_unregister_ledger "$l" && echo "harness: $(basename "$l" .ledger)"
+23 -10
View File
@@ -135,9 +135,11 @@ generator's exact `openai.yaml` shape, byte identity with the checkout) is
moved to `$GSTACK_STATE_ROOT/backups/host-renders/<ts>-<id>/`; every other file
stays where it is, and only directories left empty are removed. The backup's
`prune.log` lists every path. A gstack-upgrade migration runs
the same prune for an install upgraded without a setup run. Instruction-only
hosts (Hermes, OpenClaw, GBrain) are never installed by setup, so a user who
renders one by hand inside an install adds its name to the record first.
the same prune for an install upgraded without a setup run. Harness hosts
(OpenClaw, Hermes) render into a scratch directory and copy into the harness's
own folder, so they never add a render to the checkout; GBrain is never
installed by setup, so a user who renders it by hand inside an install adds its
name to the record first.
## Host tiers and capabilities
@@ -149,7 +151,7 @@ rows, host errors, and the README host matrix, all checked against
| Tier | Meaning |
|---|---|
| `full` | Installs, renders, passes the conformance kit, and has a dated certification record below. |
| `experimental` | Installs and renders and passes the conformance kit; no certification record yet. |
| `experimental` | Installs and renders and passes the conformance kit; no certification record yet. A harness host (`install.registration: 'harness'`: OpenClaw, Hermes) installs through `gstack-harness register` and is certified by `test/harness-register.test.ts` instead of the per-directory kit. |
| `instruction-only` | No install arm. `./setup --host X` prints what to copy and changes nothing. |
Rendering alone never certifies `full`.
@@ -275,13 +277,24 @@ root's extra markdown files (`ETHOS.md`, `review/*.md`) as skills, the
partial-read behavior of `view_file` on long skills, `ask_question` option
handling, and an upgrade from an existing install.
## Instruction-only hosts
## Instruction-only hosts and agent harnesses
OpenClaw, Hermes, Slate and GBrain have no install arm. Hermes stays
instruction-only until someone certifies a native install (#2826 measured one
on Hermes 0.21.0): `./setup --host hermes` prints the digest path and the
generator command, and the Hermes render writes `name: gstack-<skill>` so
Hermes, which indexes skills by frontmatter name, cannot shadow them (#2825).
Slate and GBrain have no install arm. OpenClaw and Hermes are harness hosts:
`./setup --host openclaw|hermes` (and `./setup` run inside either) calls
`bin/gstack-harness register`, which renders the host into a scratch
directory and copies it into the harness's own skills folder with an ownership
ledger (`lib/harness-register.ts`). The Hermes render writes `name:
gstack-<skill>` so Hermes, which indexes skills by frontmatter name, cannot
shadow them (#2825).
A harness that needs no render of its own (QM, dots, any other) is a row in
`TARGETS` in `lib/harness-register.ts`, not a host file: give it a mechanism,
a default destination, an inside-the-harness marker (an environment variable
the harness sets for the commands its agent runs, never a guess), a presence
check and, when it has one, the command that lists the skills it sees. Add its
reason codes to `HARNESS_CODES` with a `docs/troubleshooting.md` section, a
case to `test/harness-register.test.ts`, and a row to the table in
[hosts.md](hosts.md#agent-harnesses).
## How it works
+11 -3
View File
@@ -180,8 +180,16 @@ The agent should:
3. Add dispatch routing to AGENTS.md
4. Verify with a test spawn
For gstack developers: `./setup --host openclaw` outputs this documentation.
The actual artifacts are generated by `bun run gen:skill-docs --host openclaw`.
**Native skills or ACP.** `./setup --host openclaw` (or `./setup` run inside an
OpenClaw session) gives OpenClaw's own agent gstack's skills: one `gstack`
router skill in `$OPENCLAW_STATE_DIR/skills`, rendered with OpenClaw's tool
names and pointing at the installed gstack, so the agent runs gstack's
workflows and helpers itself. Use ACP when the work should happen in a Claude
Code session with the full install (hooks, Claude tool names); use native
skills when the OpenClaw agent should do it. Both can be installed together.
Install, verify and remove: [hosts.md](hosts.md#agent-harnesses).
The ACP artifacts in `openclaw/` are generated by `bun run gen:skill-docs --host openclaw`.
## What we don't do
@@ -190,4 +198,4 @@ The actual artifacts are generated by `bun run gen:skill-docs --host openclaw`.
- No bidirectional learnings bridge (brain repo is the knowledge store)
- No JSON schemas or protocol versioning
- No SOUL.md from gstack (OpenClaw has its own)
- No full skill porting (coding skills stay native to Claude Code)
- No hand-ported coding skills (native registration copies the generated OpenClaw render)
+3 -1
View File
@@ -261,7 +261,9 @@ keeps the lease. `bin/gstack-lease list` shows `alive|dead|stale`, and
up with the same hosts, model and browser flag (recorded in the git dir
after a successful setup) and `gstack-doctor --check` passes; a warm rerun
takes about a second. Each setup ends with its own `gstack ready (<host>)`;
the installer then prints `gstack ready (claude, codex)`.
the installer then prints `gstack ready (claude, codex)`. Both name a
`--host`, so setup's agent-harness step ([hosts.md](hosts.md#agent-harnesses))
never runs on a Capy machine.
4. `gstack-doctor --check` for the requested workflow (`--for <skill>`,
`--only <skill>`, or `--require <id,id>`; default `claude,codex,patch`),
run with the launch PATH, so the trailer certifies the Bun workflows run.
+41 -2
View File
@@ -1,11 +1,50 @@
# Running gstack on other agents
The README has the host matrix: one row per agent with its tier, install
command and first invocation. This page has the rest: OpenClaw, how a checkout
command and first invocation. This page has the rest: agent harnesses (OpenClaw,
Hermes, dots, QM, Muse Code, Grok and any other), how a checkout
decides which agents it renders for, the per-host notes, outside-review
providers, the Codex behavioral profile, model tiers, and the design binary's
models.
## Agent harnesses
Installing gstack inside an agent harness registers its skills the harness's
own way, in the same `./setup` run. `bin/gstack-harness` does the work and
`lib/harness-register.ts` holds one target per harness.
**When it is automatic.** `./setup` with no `--host` (or `--host auto`)
registers with the harness it runs inside: OpenClaw (its exec tool sets
`OPENCLAW_SHELL=exec`), Hermes (`HERMES_AGENT=true`) or a Dot (`HOME=/home/dot`
on a Dot's computer), or a harness found among setup's parent processes. It
prints every path it wrote and the command that removes them. An explicit
`--host claude` (or any other host) never writes under a harness folder.
`./setup --no-harness-auto` or `GSTACK_HARNESS_AUTO=0` turns the automatic step off.
**What it writes.** Copies in the harness's own skills folder, never edits to
`openclaw.json`, Hermes's `config.yaml` or any context file you did not name.
Every file goes into a ledger, `$GSTACK_STATE_ROOT/harness/<id>.ledger`, with
its sha256. Registering again changes only what changed; a folder or skill name
gstack did not write stops it (`HARNESS_UNOWNED_ENTRY`); `gstack-uninstall`
and `gstack-harness unregister` remove exactly the ledger's files and move any
file you edited to `$GSTACK_STATE_ROOT/backups/harness/`. `./setup
--refresh-registered` (what `/gstack-upgrade` runs) refreshes every registration.
`gstack-harness status` lists them and runs the harness's own skill list where
it has one (`visible to harness: yes`). Errors: [troubleshooting](troubleshooting.md#agent-harnesses-gstack-harness).
| Harness | What gstack registers | Install | Verify | Remove |
|---|---|---|---|---|
| OpenClaw | one `gstack` router skill (one description line in every request; its body lists every skill and its path) in `${OPENCLAW_STATE_DIR:-~/.openclaw}/skills/gstack`; `--skills all` registers every skill as its own top-level folder | `./setup --host openclaw`, or `./setup` inside OpenClaw | `openclaw skills list --json` shows `gstack` (source `openclaw-managed`, eligible) | `gstack-harness unregister openclaw` |
| Hermes | every skill, as `gstack-<skill>` in one `gstack` category, in `${HERMES_HOME:-~/.hermes}/skills/gstack` (Hermes opens only skills it has indexed) | `./setup --host hermes`, or `./setup` inside Hermes | `hermes skills list` shows the `gstack-*` skills in category `gstack` | `gstack-harness unregister hermes` |
| dots (feder-cr) | the `gstack` router in `/home/dot/skills/gstack`, which the Dot lists every turn | `./setup` on the Dot's computer, or `gstack-harness register dots` | the Dot's Skills page, or `GET /skills` | `gstack-harness unregister dots` |
| QM | an org skill pack: `github.com/garrytan/gstack` at the installed commit, every skill imported (instruction-only there: discovery, no gstack runtime) | an org admin, with `GSTACK_QM_URL` and `GSTACK_QM_ADMIN_TOKEN` set: `gstack-harness register qm --yes` | QM's skill list for the org | `gstack-harness unregister qm --remote` archives the pack; without `--remote` only the local record goes |
| Muse Code, Grok Build | nothing: both read `~/.claude/skills`, so the Claude install (`./setup`) is what they see, with Claude tool names | `./setup` | `gstack-harness status` runs `muse skills list` / `grok inspect` and reports *discovered (Claude-rendered, unverified)* | `gstack-uninstall` |
| Grok Bot, any chat-only skill library | nothing on disk | `gstack-harness register generic --print`, then paste the router and block into the app | ask it for a gstack skill | delete the pasted text |
| any other harness | the router in an Agent Skills folder you name, and/or a 600-byte routing block between `<!-- gstack:begin harness-routing -->` markers in a context file you name | `gstack-harness register generic --skills-dir <dir>` and/or `--context <file>`; `gstack-harness manifest generic` prints every skill as JSON | the harness's own skill list | `gstack-harness unregister generic` |
OpenClaw's ACP route below is unchanged: native registration gives OpenClaw's
own agent gstack's skills; ACP spawns Claude Code with the full install.
## OpenClaw
OpenClaw spawns Claude Code sessions via ACP, so every gstack skill just works
@@ -79,7 +118,7 @@ Outside reviews require the selected CLI to be installed and authenticated: Clau
## Instruction-only agents
**Instruction-only tier (any rules-reading agent — Zed, Amp, Jules, side projects):**
**Instruction-only tier (any rules-reading agent that loads no skills — Zed, Amp, Jules, side projects):**
copy the 2KB digest at [`agents-digest/gstack-AGENTS.md`](../agents-digest/gstack-AGENTS.md)
into a location your agent reads (for example, append it to your project's `AGENTS.md`).
It carries gstack's ethos, reuse ladder, and voice rules — no install required. The
+8
View File
@@ -47,6 +47,14 @@ prune-stale --repoint` removes dead gstack hook entries, re-points stale ones
at the stable install, and collapses duplicates, printing one line (and
writing a backup beside the file) only when it changed something.
## Agent harnesses
Run inside OpenClaw, Hermes or a Dot, `./setup` also registers gstack's skills
with that harness, in the harness's own skills folder, and prints every path
it wrote. It never does this when `--host` names another host. Turn it off
with `./setup --no-harness-auto` or `GSTACK_HARNESS_AUTO=0`. Per-harness
details, QM and any other harness: [hosts.md](hosts.md#agent-harnesses).
## Uninstall
See [uninstall.md](uninstall.md).
+3 -2
View File
@@ -8,7 +8,7 @@ If gstack is installed on your machine:
~/.claude/skills/gstack/bin/gstack-uninstall
```
This handles skills, symlinks, global state (`~/.gstack/`), project-local state, browse daemons, and temp files. Use `--keep-state` to preserve config and analytics. Use `--force` to skip confirmation.
This handles skills, symlinks, harness registrations (the files `gstack-harness` wrote into OpenClaw, Hermes, a Dot or another harness, from their ledgers), global state (`~/.gstack/`), project-local state, browse daemons, and temp files. Use `--keep-state` to preserve config and analytics. Use `--force` to skip confirmation.
## Option 2: Manual removal (no local repo)
@@ -49,7 +49,8 @@ rm -rf ~/.gstack
rm -rf "${CODEX_HOME:-$HOME/.codex}/skills/gstack"* 2>/dev/null
rm -rf ~/.factory/skills/gstack* 2>/dev/null
rm -rf ~/.kiro/skills/gstack* 2>/dev/null
rm -rf ~/.openclaw/skills/gstack* 2>/dev/null
rm -rf "${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/skills/gstack"* 2>/dev/null
rm -rf "${HERMES_HOME:-$HOME/.hermes}/skills/gstack" 2>/dev/null
rm -rf ~/.cursor/skills/gstack* 2>/dev/null
rm -rf ~/.config/opencode/skills/gstack* 2>/dev/null
rm -rf ~/.gemini/antigravity-cli/skills/gstack* 2>/dev/null
+2
View File
@@ -1,5 +1,7 @@
{
"newModules": [
{ "file": "lib/harness-register.ts", "movedFrom": "(new: gstack-harness registrar, GSTA-135)" },
{ "file": "lib/harness-qm.ts", "movedFrom": "(new: gstack-harness QM skill-pack target, GSTA-135)" },
{ "file": "lib/design-lint/render.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint.mjs)" },
{ "file": "lib/design-lint/render-probe.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint-render.mjs)" },
{ "file": "lib/design-lint/render-probe-space.ts", "movedFrom": "(new: the bundled design lint, GSTA-105; ported from hallmark sloplint-render.mjs)" },