distribute-tokens
${var} — Phase + target selector. Grammar:
[plan:|all:][dry-run:]<target>
- `` (empty) /
<label>/dry-run:<label>→ send phase: distribute a list frommemory/distributions.yml(empty = first list). [default — no prefix]plan:/plan:<week>/plan:dry-run/plan:dry-run:<week>→ plan phase only: compute rewards from the repo's merged PRs and write the list intomemory/distributions.yml.all:/all:<week>/all:dry-run/all:dry-run:<week>→ plan then send in one run.
<label>is a distribution-list label (e.g.contributors-2026-W17).<week>is an ISO week (2026-W17); empty<week>= most recent completed ISO week.dry-run:previews without side effects (no yml/state writes in plan; no transfers in send).
Why this design
This skill owns the whole contributor flywheel: who deserves what (plan) and moving the money (send). It is split into two phases that can run independently or chained.
Plan phase — the wiring the project was missing. Merged PRs already name the people moving the project, but shipped work had no path to a wallet credit. The plan phase is that wiring: it ranks contributors by the PRs they merged in the target week (straight from the GitHub API), prices each eligible contributor against a tier table, and writes a labelled list into memory/distributions.yml — the exact file the send phase reads. Keeping a human-visible diff on memory/distributions.yml between plan and execution is the cheapest possible audit trail when real money is involved: the plan lands in git, and the operator (or all: mode, or a chained step) runs the send next.
Send phase — this moves real money. The biggest failure mode is double-sending (re-runs, retries after partial failures, day-rollover bypass of "skip if today" logic) or sending into a black hole (no preflight balance, deprecated API path, missing handle resolution). The send phase therefore: