| new file mode 100644 |
| index 0000000..3669e3e |
| --- /dev/null |
| +++ b/.agents/skills/amadan/SKILL.md |
| @@ -0,0 +1,301 @@ |
| +--- |
| +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+662bffb |
| +--- |
| + |
| +# 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" |
| + amadan task set <id> -title "..." |
| + |
| +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. |
| +- **Correct a task when the decision behind it changes.** `task set |
| + <id> -title "..."` rewrites it. You are told to put the plan up |
| + early, which means your early tasks are the ones most likely to |
| + describe something that was later rejected — and a task left |
| + describing a rejected design, sitting at Done, reads as a |
| + contradiction rather than as history. |
| +- 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. |
| + |
| +### Take work before you start it |
| + |
| +You cannot see the other sessions. Another agent, started an hour ago |
| +on another machine, may already be building the thread you just picked |
| +— and neither of you will find out until there are two branches doing |
| +the same thing. So say what you are taking: |
| + |
| + amadan discuss list <ns>/<repo> -unclaimed |
| + amadan discuss claim <ns>/<repo> <id> |
| + amadan discuss release <ns>/<repo> <id> |
| + |
| +`-unclaimed` is the question worth asking first: *what is free to |
| +start?* `claim` refuses if somebody already holds the item and tells |
| +you who, so a refusal is information rather than a dead end — pick |
| +something else, or ask them. |
| + |
| +Release what you are not working on any more. Nothing expires a claim, |
| +so an item you took and abandoned stays taken until a person notices; |
| +`discuss list` shows each claim's age, which is the only clue anyone |
| +gets. An owner can break a claim a dead session left behind. |
| + |
| +### Say what has to happen first |
| + |
| +If you find that one item cannot start until another lands, record it |
| +rather than writing it in a body somebody has to read: |
| + |
| + amadan discuss block <ns>/<repo> 7 -on 6 |
| + amadan discuss list <ns>/<repo> -unclaimed -ready |
| + |
| +That last line is the one to reach for at the start of an unattended |
| +session: **what can I start that nobody else is on and nothing is |
| +holding up?** Closing a blocker frees what waited on it, so the queue |
| +stays true without anybody maintaining it. |
| + |
| +## 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. |