Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add commands/dwarvesf/dwarves-kit/assigngit clone --depth 1 https://github.com/dwarvesf/dwarves-kitWhat it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00034 | $0.04721 |
| Opus 5 | $0.00017 | $0.02361 |
| Sonnet 5 | $0.00007 | $0.00944 |
| Haiku 4.5 | $0.00003 | $0.00472 |
Grade A, and why
assign scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 196 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Self-intro (AGENTS.md "Self-intro" convention): open your first reply with exactly one banner line, [kit:assign] Turn a backlog item into a scoped goal draft and route it into the right lane., then proceed.
You are a goal dispatcher. Turn a committed backlog item into a runnable goal draft and hand it to the right lane. You do NOT implement anything; you set up the goal and route.
Process
Step 1: Resolve the argument (two shapes)
$ARGUMENTS is one of two shapes. Trim it, then branch:
- ID shape: the trimmed argument matches
^ID-[0-9]+$. Take the ID-first path below (Step 1b onward), unchanged. This is the path that has always existed. - Freeform shape: anything else (intent text like "apply SDD to X" or a vague brief). Take the freeform path in Step 1a, which crystallizes the intent into an ID + BACKLOG row first, then rejoins the ID-first tail at Step 4.
A future third intake shape (e.g. an imported issue) is another branch of this same resolver, not a new command. The resolver is the only place that decides ID vs freeform; everything downstream is shared.
Step 1a: Freeform path (delegate, gate, sanitize, allocate, write)
When the argument is freeform intent (does NOT match ^ID-[0-9]+$), run these ordered steps. /assign stays a light mutator-dispatcher (SPEC-006): it does NOT run a multi-turn interview itself. Two invariants govern this path, and both come before any file is written:
- approve-before-allocate: pause for human approval of the crystallized objective BEFORE allocating an ID. A vague brief never auto-creates a row (DEC-002).
- row-before-draft: write the BACKLOG Active-queue row before the goal draft, so ID traceability exists first (the row before draft order is the invariant; never write a
.claude/goals/draft for an un-rowed intent).
- Delegate crystallize to
/kit:think. Hand the freeform intent to/kit:think(the 6-forcing-questions idea challenger). It runs the interview and returns a crystallized objective + a lane./assigndoes NOT embed that interview (DEC-003); it only consumes/think's result. If the intent is too vague to name an outcome,/thinkloops; do not allocate anything until it converges. - Approval gate (approve-before-allocate). Present the crystallized objective and pause for explicit human approval. Until the human approves, allocate nothing and write nothing. This is the gate that keeps half-baked rows out of the queue.
- Dedup by slug. Derive the slug from the approved objective (per the sanitize rule in Step 1a.4). If a
.claude/goals/<slug>.mddraft or a BACKLOG row with that slug already exists, surface it instead of allocating a second ID (filesystem-is-truth idempotency, SPEC-005). On a near-match slug, ask rather than silently merge or duplicate. - Sanitize (DEC-004). Before the freeform text touches any file, sanitize it:
- Table cells: escape
|(write it as\|) and replace newlines with spaces in every BACKLOG row cell, so a freeform string cannot break the_meta/BACKLOG.mdpipe table. - Slug: reduce the derived slug to
[a-z0-9-]+only. Lowercase, replace spaces with-, then strip/,.., and anything outside[a-z0-9-], so the slug cannot traverse out of.claude/goals/. The kebab convention is unchanged; it is just hardened to[a-z0-9-]+.
- Table cells: escape
- Atomic allocate + write the row (DEC-005, row-before-draft). Allocate the next
ID-NNNby re-reading the current max ID in_meta/BACKLOG.mdActive queue in the same step that writes the row (do not cache a max read earlier). The new ID ismax + 1, zero-padded. Append a sanitized Active-queue row withStatus: queuedandSource: freeform intake (<YYYY-MM-DD>), filling Title / Target artifact / Lane from the crystallized objective +/think's lane. After writing, re-read the queue and check no two rows share the new ID; if a collision exists (a concurrent allocation picked the samemax + 1), fail loud and tell the operator to re-run, rather than leaving two rows with one ID. This mirrors the existing SPEC/ADR dup-number guard. - Rejoin the ID-first tail. With the row written and the ID allocated, proceed exactly as for an
ID-NNN: Step 4 (draft write), Step 5 (lane + activator), Step 6 (status + hand-off). The freeform path adds no new tail; it reuses the ID path's.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 2d ago First seen · 196 lines · 34 tokens per session scan A dbfff03d1213
assign is a command published in the GitHub repository dwarvesf/dwarves-kit (11 stars, last pushed 2d ago), licensed MIT. It adds 34 tokens to every session and 4,721 once invoked, about $0.0002 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other commands, from other repositories
OPSX: Archive
Archive a completed change in the experimental workflow.
OPSX: Explore
Enter explore mode - think through ideas, investigate problems, clarify requirements.
OPSX: Propose
Propose a new change - create it and generate all artifacts in one step.
OPSX: Sync
Sync delta specs from a change to main specs.
OPSX: Apply
Implement tasks from an OpenSpec change (Experimental).
OPSX: Update
Update a change - revise existing planning artifacts and keep them coherent (Experimental).