---
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.
