From 2cffbe6121d9650144ac906d7632978a6e360a52 Mon Sep 17 00:00:00 2001
From: Adan
Date: Wed, 12 Aug 2026 19:03:20 +0000
Subject: [PATCH] Make the README agent-native and ship a Claude Code skill
Lead with the agent interface (one verb, JSON, stable exit codes) and add
skills/greentree/SKILL.md, a drop-in Claude Code skill that teaches an
agent to land changes with gate instead of raw git, how to react to each
exit code, and not to re-run cached verdicts.
Co-Authored-By: Claude Fable 5
---
README.md | 29 +++++++++++++---
skills/greentree/SKILL.md | 72 +++++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 4 deletions(-)
create mode 100644 skills/greentree/SKILL.md
diff --git a/README.md b/README.md
index dd0f4b8..b5bd014 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,7 @@ and refuses to create a commit from any tree that has not passed.
+Built for coding agents: one verb, JSON on every command, stable exit codes, and a drop-in skill.
An open source primitive from reachpad · Apache-2.0 · Linux and macOS
@@ -210,15 +211,35 @@ freely with a running watcher.
### For coding agents
-The agent-facing contract is one verb and one exit-code table:
+An agent is the primary user. The whole interface an agent needs is one
+verb and one exit-code table:
```sh
-greentree gate --json -m ""
+greentree gate --json -m "" # verify, then commit the tree; idempotent
```
-[docs/AGENTS.md](docs/AGENTS.md) has the copy-paste project-instructions
+Every command takes `--json` (exactly one object on stdout) and returns a
+stable exit code, so an agent branches on the code, never on parsed text:
+`0` committed, `10` a check failed (output at `.log_tail`), `11` not
+verified yet (run `test` first), `12` unsnapshotable, `13` locked. No
+prose to interpret, no re-running "to be sure" — a cache hit proves the
+content already passed.
+
+**Drop-in skill.** [`skills/greentree/`](skills/greentree/SKILL.md) is a
+Claude Code skill that teaches an agent the workflow and the exit codes.
+Copy it into a project so the agent loads it automatically:
+
+```sh
+cp -r skills/greentree .claude/skills/
+```
+
+The skill tells the agent to land changes with `greentree gate` instead of
+raw `git commit`/`git push`, how to react to each exit code, and not to
+re-run cached verdicts.
+
+**Enforce it.** [docs/AGENTS.md](docs/AGENTS.md) has a project-instructions
snippet and a Claude Code hook that blocks `git commit`/`git push` so the
-gate is the only door.
+gate is the only door, even if the agent forgets.
### The gate before GitHub
diff --git a/skills/greentree/SKILL.md b/skills/greentree/SKILL.md
new file mode 100644
index 0000000..d6315db
--- /dev/null
+++ b/skills/greentree/SKILL.md
@@ -0,0 +1,72 @@
+---
+name: greentree
+description: Land code changes through greentree instead of raw git. Use in any repo that has a greentree.yaml or the greentree binary on PATH, whenever about to commit, push, run tests, or land a change, or when asked "is it green" / "did it pass". greentree verifies the working tree, caches the result by content, and only lets a verified tree become a commit.
+---
+
+# greentree: verify the tree before it becomes a commit
+
+greentree runs this repo's checks against the current working tree, caches
+the verdict by content (tree hash), and creates the commit from the exact
+tree that passed. Use it instead of running tests by hand and then
+`git commit`/`git push`.
+
+Applies when the repo has a `greentree.yaml`, or `greentree` is on PATH and
+`greentree status` succeeds.
+
+## Landing a change: one command
+
+```sh
+greentree gate --json -m ""
+```
+
+`gate` runs the required checks (instant when this exact content already
+passed), then commits the verified tree. It is idempotent: running it twice
+in a row is a no-op. This replaces `git add`/`git commit`/`git push`.
+
+Add `--push` to also push. Without it, `gate` commits locally only.
+
+## Branch on the exit code, never on the text
+
+| exit | meaning | do this |
+|---|---|---|
+| 0 | verified and committed | done |
+| 10 | a check failed | read `.log_tail` in the JSON, fix the code, run `gate` again |
+| 11 | tree not verified yet | run `greentree test --json`, then `gate` |
+| 12 | repo mid-merge/rebase, or a dirty submodule | resolve it, then `gate` |
+| 13 | another greentree run is in progress | wait a moment, then retry |
+| 14 | config error | read `.error`; fix `greentree.yaml` |
+| 15 | publish/push failed | read `.error` (e.g. remote rejected, no token) |
+
+## While iterating
+
+- `greentree test --json` runs the checks without committing. `.ok` is the
+ answer. Per-check detail is in `.results`.
+- `greentree status --json` answers "would a commit succeed right now?"
+ without running anything new. Read `.publishable`.
+
+## Rules that keep it correct
+
+- Do not run `git commit` or `git push` directly in a greentree repo. The
+ commit must be built from the tested tree; `gate` does that. Bypassing it
+ produces an unverified commit.
+- A cache hit is as authoritative as a fresh run. The tree hash proves the
+ content is identical, so do NOT re-run "to be sure" — that is wasted work.
+- Do not edit files while `gate` or `test` is running. If the tree changes
+ mid-run the verdict is `cancelled` (it binds to no tree) and you will
+ just rerun it. Make your edits, then run the check.
+- When a check fails (exit 10), the output is in the JSON: `.log` is the
+ full log file path, `.log_tail` is the last lines. Read it before
+ guessing at a fix.
+
+## Gate before GitHub
+
+The published commit is built from the exact verified tree, so it needs no
+re-check. If the repo enforces a `greentree/` required status, a
+plain `git push` can be made mergeable by attesting the pushed commit:
+
+```sh
+git push
+greentree attest --json # posts greentree/ on HEAD if verified
+```
+
+`gate --push` does the commit, push, and status in one step.