Das dumme Koordinations­tool

Tasks und Architekturentscheidungen in deinem Repo, hinter einer einzigen CLI, die jeder Coding-Agent aufrufen kann.

npm install -g @haksolot/ank
npx skills add haksolot/ank

Open Source, Apache-2.0. Linux, macOS und Windows.

Der Loop, einmal durchgespielt

~/auth-service
ank context src/auth/

CONSTRAINTS (1 active)
  ADR-06d2  Opaque sessions rather than stateless JWT

TASKS (1)
  TASK-820d  [open] Migrate auth to opaque sessions

> ank claim TASK-820d to start

ank claim 820d
claimed TASK-820d259af6a7 migrate-auth-to-opaque-sessions -> HEAD

ank context

TASK-820d  Migrate auth to opaque sessions

DONE_CRITERIA
  The auth tests pass and no reference to jwt.verify remains in src/auth/

CONSTRAINTS (1 active)
  ADR-06d2  Do not introduce self-contained JWTs for user auth. Every session goes through the Redis store.

ank log "jwt.verify removed from session.ts"
logged LOG-6b0f39d7a4c1 on TASK-820d259af6a7

ank done
running: auth-tests ... ok (0.0s)
running: no-jwt ... ok (0.0s)
proof recorded: auth-tests@94a1f671c577 -> local/e3b0c44298fc@9c45c50  (scope/18d14da584ab)
proof recorded: no-jwt@791cc818d0ad -> local/e3b0c44298fc@9c45c50  (scope/18d14da584ab)
TASK-820d259af6a7 -> done

Echte Ausgabe, aus dem Quickstart. Dessen Testsuite spielt diese Befehle bei jeder Änderung erneut gegen das Binary ab.

Läuft mit dem Agenten, den du schon nutzt

ank ist ein Kommandozeilenwerkzeug. Jeder Agent, der einen Shell-Befehl ausführen kann, kann den Loop durchlaufen, und ein Client ohne Shell erreicht dieselben Verben über MCP.

  • Claude Code
  • Codex
  • Cursor
  • OpenCode
  • Gemini CLI
  • GitHub Copilot
  • Cline
  • Amp
  • pi
  • Antigravity
  • Goose
  • Kiro
  • Roo Code
  • Kilo Code
  • Windsurf
  • Qwen Code
  • Mistral Vibe
  • OpenHands
  • Junie
  • Devin

Ein einziger Befehl installiert die Skills in alle diese Agenten, die er findet, und in rund dreißig weitere.

Dein Agent liest den Code, nicht den Thread

Ein Agent kann jede Zeile deines Codes lesen, aber nicht deinen Tracker, dein Wiki oder den Thread, in dem ihr entschieden habt, dass Sessions nie selbsttragende JWTs sein dürfen. Nichts hält die nächste Session davon ab, eins zu schreiben.

ank hält diese Entscheidungen und die Arbeit in .ank/, per Glob an den Code gebunden, den sie betreffen. Bevor er anfängt, ruft der Agent ank context src/auth/ auf, und die Regel kommt zusammen mit dem Task.

Einfache Markdown-Dateien in deinem Repository, reviewt wie jede andere Änderung. Kein Server zu betreiben: Claims sind Git-Refs.

Sechs Verben

Der ganze Loop, den ein Agent braucht. ank help listet alle anderen.

  1. ank context <path>

    Was diesen Bereich bindet und was sich übernehmen lässt. Immer der erste Aufruf.

  2. ank claim <id>

    Einen Task übernehmen und sein Kriterium einfrieren.

  3. ank show <id>

    Die Entität vollständig: Frontmatter, Body und Log.

  4. ank log "<message>"

    Was du gelernt hast, während du arbeitest. Der Eintrag verlängert den Claim.

  5. ank done

    Die deklarierten Verifier ausführen und den Nachweis festhalten.

  6. ank release --reason "<why>"

    Den Task zurückgeben, mit Begründung.

Drei Ideen darunter

Jede ist eine Eigenschaft des Tools, keine Konvention, an die du dich halten sollst.

Scope statt Hierarchie

Constraints und Arbeit sind zwei Ebenen, die nur über Globs verbunden sind. Eine Regel vom letzten Jahr bindet Arbeit, die heute entsteht, und ein Glob lässt sich gegen das Dateisystem prüfen, ein Label nicht. Kein Epic, kein Parent, kein Rollup, das man synchron halten muss.

ank new adr --title "Opaque sessions rather than stateless JWT" \
    --scope "src/auth/**" \
    --constraint "Do not introduce self-contained JWTs for user auth. Every session goes through the Redis store."
created ADR-06d29e727d24 Opaque sessions rather than stateless JWT

Das Kriterium friert beim Claim ein

Wer einen Task übernimmt, friert sein done_criteria per Hash ein, außer Reichweite dessen, der die Datei bearbeitet. Das Kriterium umzuschreiben, um sich selbst zu entblocken, entblockt nichts: ank check zeigt die Abweichung. Ein Claim pro Identität, und ein Claim ist eine Git-Ref: Greifen zwei Agents nach demselben Task, gewinnt genau einer.

ank claim 820d
claimed TASK-820d259af6a7 migrate-auth-to-opaque-sessions -> HEAD
ank claim 51c2
error[7]: human:marie holds a live claim on TASK-820d259af6a7 (expires in 30m)
  -> ank release --reason "<why>"   (a second session on this machine sets its own ANK_AGENT)

Niemand erklärt sich selbst für fertig

Ein Agent, der sein eigenes Ergebnis meldet, kann sich schlicht irren. ank done führt die Verifier selbst aus und hält fest, was wirklich gelaufen ist, gehasht. Ein Task, für den nichts auszuführen ist, verlangt einen Nachweis, den du ihm gibst, und jede Ablehnung nennt den Befehl, der sie auflöst.

ank claim 51c2
claimed TASK-51c2a0f6d418 say-in-the-readme-what-a-session-is-now -> HEAD
ank done
error[5]: proof required to move TASK-51c2a0f6d418 to done
  -> ank done --proof commit:<sha>

Was es nicht ist

  • Kein Tracker. Keine Zyklen, Schätzungen, Velocity oder Roadmap.

  • Kein Wiki. Hinein kommt nur, was für einen Agent umsetzbar oder bindend ist.

  • Keine Sicherheitsgrenze. Es schützt vor Drift, nicht vor Angreifern.

ank wird mit ank gebaut

Sein eigenes Repository läuft mit diesem Loop. Das .ank/ im Wurzelverzeichnis enthält die ADRs, an die sich sein Code hält, und die Tasks, mit denen es gebaut wurde, und die Dokumentation zitiert diese Entscheidungen per ID.

Die Version ist bewusst 0.x: Der Loop und die Exit-Codes sind spezifiziert, das Speicherformat noch nicht.

Sein .ank/ auf GitHub ansehen

ank installieren

Zwei Befehle. Linux, macOS und Windows, mit git 2.34 oder neuer.

npm install -g @haksolot/ank
npx skills add haksolot/ank