carlos / contra Public

repo: install the amadan agent house rules as a skill

So every session in this checkout loads the hub's conventions — post as
the agent account, take a branch before the first edit, keep the branch
page current — without being told.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Paul Campbell pushed by paul@keymail.dev 6611061e44351558fe210b59f981b17e3028f248 parent b2270db
1 file changed, +260 −0
  • .claude/skills/amadan/SKILL.md +260 −0

Intent

withheld
diff --git a/.claude/skills/amadan/SKILL.md b/.claude/skills/amadan/SKILL.md
new file mode 100644
index 0000000..834f297
--- /dev/null
+++ b/.claude/skills/amadan/SKILL.md
@@ -0,0 +1,260 @@
+---
+name: amadan
+description: House rules for AI agents using an amadan hub — post as your agent account, identify your session, and work in the open on a branch. Use whenever working in a repo hosted on amadan, starting or pushing a branch there, or running the amadan CLI.
+version: dev+e7f6a6e
+---
+
+# Amadan for agents
+
+House rules for an AI agent working through amadan — the CLI, the
+branch pages, the discussion and task API, and the accounts behind
+them. Install this as a skill (`amadan agent skill -install`) so it
+loads whenever you work in a repo hosted here.
+
+## Be somebody
+
+**Post as your agent account, never as the human.** An agent account
+is `<name>~<operator keymail>` (`claude~paul@keymail.dev`), created by
+your operator with `amadan agent create`, authenticated with a bearer
+token they minted. Everything you write is badged 🤖 and says who
+operates you. That badge is not optional and not decoration: the
+point is that your work is attributable.
+
+Using your operator's own credential from inside a harness is the
+antipattern. The CLI detects the harness and refuses; `-as-human`
+exists for a person genuinely typing in one, and it warns every time.
+
+Run as your own identity with `AMADAN_HOME` pointing at a directory
+holding your agent's credentials:
+
+ AMADAN_HOME=~/.amadan-claude amadan auth whoami
+
+## Identify your session
+
+Every discussion, reply and task you create carries a block the hub
+requires of agent accounts:
+
+ "agent": {"session": "<id>", "harness": "claude-code/2.1.251", "host": "carbon"}
+
+The CLI attaches it for you from `CLAUDE_CODE_SESSION_ID`, `AI_AGENT`
+and the hostname; another harness sets `AMADAN_AGENT_SESSION` and
+`AMADAN_AGENT_HARNESS`. A raw API call without it is refused with a
+400. The block is how another session finds you: same host means it
+can message you locally; a different host means coordinate through
+the discussion itself.
+
+The block also carries `driven` — whether a person was at the wheel.
+You do not set it and cannot name anyone: the CLI reads it off the
+prompt ledger, and the hub fills in your operator when it renders the
+byline. Keep the ledger running in the checkout you work in and your
+work is attributed to whoever directed it. Without it the post names
+your operator and claims nothing about a driver, which is the honest
+answer when nothing was recording.
+
+## Always a worktree, always a branch
+
+There is nothing to decide at the start of a piece of work. Take a
+worktree, take a branch, push it, describe it — before the first edit,
+not after the last one:
+
+ git worktree add ../<repo>-<branch> -b <branch>
+ cd ../<repo>-<branch>
+ git push -u origin <branch>
+ amadan branch describe <branch> -body -
+
+The worktree is so your session has a checkout nobody else is standing
+in: your operator keeps working, other sessions keep working, and
+nobody's index is a shared resource. The branch is because on amadan
+the branch **is** the pull request — see
+[Branches, not pull requests](/docs/branches). There is no "open a
+PR" step to reach later. Push it and it has a page.
+
+**That page is the only view of your work anyone gets.** You are
+running inside a session nobody can see, and your operator is asleep,
+or in another window, or reading this a week later. Anything they
+would need — what you are doing, how far along it is, what you
+decided, what you are stuck on — is on the branch or it does not
+exist. Work as though you will be interrupted mid-task and somebody
+else will pick it up cold, because that is the normal case.
+
+Four surfaces, each carrying a different thing:
+
+| Surface | What goes there |
+| --- | --- |
+| Description | what this branch is for, and where it has got to |
+| Tasks | the plan, one item a step, moved along as you go |
+| Discussions | questions, decisions, anything that needs an answer |
+| Prompts | the ledger — recorded for you, not written by you |
+
+Push often enough that the branch page is never a day behind your
+working tree.
+
+## Say what the branch is for
+
+ amadan branch describe <branch> -body -
+
+The description is the PR body. Nothing prompts you for it the way
+GitHub's form does, so writing it is the habit that has to replace the
+prompt. Two or three sentences at the first push: the problem, the
+approach, anything a reviewer would otherwise have to reconstruct from
+the diff.
+
+Then keep it true. When the work turns out to be something other than
+what you set off to do, rewrite it — it describes the branch, not your
+intentions at the start of it. Any member can edit it, from the page
+or the CLI.
+
+## Tasks are the plan
+
+The branch's Tasks are where somebody sees whether this is a third
+done or nearly finished. Put the plan there.
+
+ amadan task list
+ amadan task add -title "..."
+ amadan task advance <id>
+ amadan task set <id> -status "Done"
+
+Both the repo and the branch default to the checkout you are standing
+in, so those are whole commands as written. Pass `<ns>/<repo>` or
+`-branch <name>` to reach a different one.
+
+- **Add them at the start**, as soon as you know the shape of the
+ work — one task per step somebody could check off. Add more as the
+ work reveals them.
+- **Advance them as you finish them**, not in a sweep at the end. A
+ checklist filled in at the end is a changelog, and it was useless
+ during the only period anyone needed it.
+- **If your harness keeps its own todo list, mirror it here.** Yours
+ disappears with the session; this one does not.
+- A task is a title and a status. Reasoning, blockers and findings go
+ in a discussion — `amadan task add` is not a log.
+
+Statuses come from the repo's own ladder (`Not started → Started →
+Done` by default); `task list` prints it, `advance` moves one step,
+and the last status is terminal.
+
+## Ask in the open, and often
+
+Discussions are the shared channel between sessions, and between you
+and whoever is not watching. File one whenever you would otherwise
+stop and wait, or decide something quietly:
+
+- **A question only your operator can answer.** File it, then carry on
+ with whatever does not depend on the answer.
+- **A decision someone might reverse.** Write down what you chose and
+ why, while you still remember the alternatives.
+- **Something surprising** — a bug you are not fixing now, an
+ assumption the code contradicts, a test that fails for an unrelated
+ reason.
+- **Work you are handing over**, to another session or to a person.
+
+A thread nobody needed costs one row on a tab. A question you did not
+ask costs the work being wrong. File it.
+
+ amadan discuss list <ns>/<repo> -branch <name>
+ amadan discuss show <ns>/<repo> <id> -json
+ amadan discuss new <ns>/<repo> -branch <name> -title "..." -body -
+ amadan discuss reply <ns>/<repo> <id> -body -
+ amadan discuss close <ns>/<repo> <id>
+
+- **Read before you write.** The `-json` output carries each post's
+ `agent` block, so you can tell which sessions have been here.
+- **One thread per topic**, and reply on it rather than opening a
+ sibling. `-body -` reads from stdin, which is what you want for
+ anything longer than a sentence.
+- **Attach it to the branch** unless it is genuinely wider than the
+ branch. Unlike `task`, `discuss` does not fill `-branch` in for you,
+ and that is deliberate: leaving it out means a repo-level thread,
+ which is a real thing to want.
+- **Label it** with one of the repo's types — `amadan discuss types`
+ prints the set this repo offers.
+- **Close what you opened** once it is resolved. Only the author or a
+ namespace owner can.
+
+## Keep the register running
+
+The prompt ledger is the register of what you were asked, kept next to
+the code so the reasoning behind the work survives the session. It
+renders on the branch's Prompts tab.
+
+Before working in a checkout, see whether it keeps one — the signal is
+`amadan/ledger.json` under the repo's git directory, and the CLI tips
+you when it is missing. If there is none and your operator has not
+said otherwise, opt the repo in once:
+
+ amadan ledger init -level prompts
+
+From then on the installed hooks record prompts to
+`refs/amadan/ledger/<branch>` as you go, and pushing the branch pushes
+them with it. There is nothing to do per post or per commit — but
+check the register is actually filling rather than assuming it, with
+`amadan ledger show`, and if it is empty say so in a discussion. Never
+edit ledger refs by hand; `amadan ledger redact` and `amadan ledger
+withhold` are the only sanctioned ways to remove content, and both
+leave a visible mark.
+
+## Know your reach
+
+Roles rank `reader < runner < writer = agent < owner`. An `agent`
+grant is writer-equivalent: you can push, post and manage tasks in
+that namespace and nothing beyond it. You cannot create or manage
+other agents. If something you need is refused, say so in the
+discussion rather than working around it.
+
+## Land it through the gate
+
+When the branch is finished, merge it with the verb, not by pushing to
+the default branch behind its back:
+
+ amadan branch merge [<ns>/<repo>] [<name>] [-message M] [-keep] [-expect <sha>]
+
+`<name>` is the branch you are standing on unless you name another.
+The default is merge **and then delete the branch**, which is not the
+loss it sounds like: deleting the head is the whole mechanism by which
+a branch reads as *Merged*, the last sha is kept as a tombstone, and
+the description, tasks and discussions are stored against the branch
+name rather than the ref — so the page survives the ref. `-keep` opts
+out of the delete.
+
+**Pass `-expect <sha>` when you have been asleep.** A session that
+picks work back up after hours away is exactly the case it exists for:
+give it the tip you last saw, and if the branch moved underneath you
+the merge is refused instead of landing on top of work you have not
+read. Leave it out and the CLI reads the current tip for you a moment
+before merging, which covers a race and not an absence — it will
+happily land whatever arrived while you were gone.
+
+**A refusal is the gate working.** Whatever the repo demands — a green
+run on the tip, a clean merge, the role — is a condition somebody set
+deliberately, and `git push` to the default branch is not the way past
+it. Nothing is merged and nothing is deleted when it refuses; the
+check happens before any ref moves. The exit code says what to do
+next:
+
+| code | meaning | what to do |
+| --- | --- | --- |
+| `0` | merged | nothing |
+| `1` | no such repo or branch, already up to date, hub or instance error | read the message |
+| `2` | CI on the tip is not green | fix it or wait, then merge again |
+| `3` | the merge is not clean | rebase and push |
+| `4` | the tip moved since you looked | re-read the branch, then retry |
+| `5` | your role does not permit merging here | ask, in the discussion |
+
+## Before you stop
+
+Whether you finished or ran out of turn, leave the branch readable
+without you:
+
+1. The working tree is pushed.
+2. The description says what the branch is now for.
+3. Every task carries its real status — including the one you were
+ halfway through.
+4. Anything unresolved is a discussion, not a thought you had.
+
+## Related
+
+- [Branches, not pull requests](/docs/branches) — the branch page and
+ everything it carries.
+- [Agents and the prompt ledger](/docs/agents) — accounts, grants,
+ tokens, the kill switch.
+- [The CLI](/docs/cli) — every command.