flake-verbs
flake-verbs
Flake-Struktur-Verben, einmal als typisierte verbspec-Spezifikationen verfasst und auf CLI, MCP, Anthropic-Tool-Nutzung und OpenAPI projiziert.
flake-verbs beantwortet zwei Fragen, für die man bisher eine Flake von Hand lesen musste:
Verb | Frage |
| Welche meiner Inputs wird überhaupt tatsächlich verwendet? |
| Wie weit ist jeder gesperrte Input von seinem Upstream abgedriftet — und lässt er sich überhaupt noch abrufen? |
Ausführung
bun install
bun run src/cli.ts inputs ~/.config/home-manager
bun run src/cli.ts input-drift ~/.config/home-manager --problemsOnly
bun run src/cli.ts --mcp-tools # the agent-facing surface, derivedBeide Verben erwarten die Flake-Wurzel als positionales Argument (Standard: .) und geben JSON aus; die CLI rendert eine Textansicht, jede andere Oberfläche verbraucht output.
Related MCP server: mcp-supply-guard
inputs — Verwendung vs. Erwähnung
Die naive Variante dazu ist grep <input-name> *.nix, und sie meldet, dass jeder Input verwendet wird. Drei Dinge erwähnen einen Input, ohne ihm tatsächlich zu abhängen:
die
outputs = { a, b, … }:-Parameterliste, die jeden Input benenntKommentare
Pfad- und Stringliterale —
./programs/lnzr.nix,"lnzr/.gewand"
String-Interpolationen sind die Ausnahme und müssen den Filter überleben, denn "${dx-compose}/pfad/zu/module" ist ein echter Verweis. Diese Asymmetrie ist der Grund, warum das kein grep sein kann.
Der Scan folgt außerdem den _module.args-Aliassen. Eine Flike, die synoptic = config._module.args.synoptic-github bindet, nutzt den Input unter einem ganz anderen Begriff — und wird genau das übersehen, wird ein echter Eingang entfernt.
Die drei Befunde
referenced und unused bedeuten genau das, was sie sagen. module-import-only ist die interessante Fall und wird bewusst nicht „unused“ genannt: Ein Home-Manager-Modul kann vollständig tragend sein (das Modul setzt selbst die Konfiguration) oder völlig wirkungslos (jede Option hat standardmäßig false, und nichts aktiviert sie).
Mit --deep (standardmäßig an) schafft das Verb dort Klarheit, wo es kann: Es löst den Input über nix flake archive zu seinem Store-Pfad auf, liest das importierte Modul, ermittelt den Options-Namespace, den es deklariert, und prüft, ob irgendetwas in der verbrauchenden Flats denselben setzt. So wird aus einem Achselzucken eine Tatsache:
DEAD dx-compose github:bdelanghe/dx-compose
imports a module declaring programs.devcontainers-cli, which nothing in this flake setsWo es den Namespace nicht auflösen kann, bleibt es bei module-import-only, statt zu raten. Ein falsch gemeldtes unused ist eine teurer Fehler — es löscht einen funktionierenden Input — und so fällt jeder Schritt auf „dann sollte ein Mensch hinsehen" zurück.
input-drift — der, der sich selbst dafür bezahlt
behind ist ganz normal und kein Fehler. Zwei Status sind:
unportable— einpath:-Input. Nix liest Pfad-Inputs zur Auswertungszeit von der Platte; ein Sperr, die ein auf ein Verzeichnis zeigt, das es nur auf der Autorenmaschine existiert, macht die Flake überall sonst unauswertbar. Das ist eine Bootstrap-Sackgasse, die völlig unsichtbar bleibt, bis man auf einer zweiten Maschine bauen will.orphaned— die gesperrte Revision trägt Commits, die nicht auf dem Default-Branch des Remotes liegen, oder von denen der Remote noch nie gehört hat. Der Commit existiert nur in einem lokalen Checkout: ungepushte Arbeit, die ein Rebuild der Maschine stillschweigend verwirft.
Beide Fälle liefern einen Exit-Code ungleich null und machen das Werkzeug zum CI-Gate. behind tut das nicht.
Upstream-Abfragen laufen über gh api, so dass private Inputs ohne externes Token bleiben.
Warum es das gibt
Nach einem echten Verlust geschrieben. Eine home-manager-Flake trug vier path:-Inputs, die unter ~/.local zeigten; auf einer frischen Maschine ließ sich die Flake überhaupt nicht auswerten. Als man sie wieder auf GitHub zeigte, sah man: Einer davon, lnzr, hatte einen lokalen Checkout drei Monate vorn gegenüber seinem upstream main — Arbeit, die nirgendwo sonst existierte und mit der alten Platte verloren ging.
Die Lock-Datei hatte beide Fakten die ganze Zeit festgehalten. Nichts konnte sie abfragen.
Einschränkungen, die man weiter wissen sollte
Der Referenz-Scan ist: textuell und keine Auswertung. Er liest die
.nix-Quellen; er wertet die Flake nicht aus, so dass ein Input, der nur über generierte oder dynamisch konstruierte Attributpfade erreicht, übersehen werden kann.--deeperkennt die Idiomecfg = config.<ns>undoptions.<ns>. Ein anders geschriebenes Modul fällt aufmodule-import-onlyzurück.input-driftprüft nurgithub:-Inputs gegen ihren Upstream.git:- undtarball:-Inputs meldenunknownauch falsche Antwort.Es werden nur direkte Inputs untersucht. Ein transiter Input ist die Wahl eines anderen; dessen Prüfung gehört in dessen eigenes Repository.
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted code graph over MCP: exact callers, dependencies, and cross-repo blast radius for AI agents.
Render, verify, describe, and safely edit Mermaid diagrams through MCP.
Free MCP tools: the only MCP linter, health checks, cost estimation, and trust evaluation.
Statically audits MCP tool surfaces for token cost, schema quality, and design issues.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables MCP-compatible clients to inspect Next.js codebases, analyze App Router and Pages Router structure, discover API routes, and audit build performance through controlled tools.8 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables supply-chain integrity for MCP tools by locking tool-definition hashes after review and detecting added, removed, modified, or risky tool definitions.MIT
- FlicenseNot gradedqualityBmaintenanceEnables MCP-compatible clients to audit asynchronous control flow, identifying unawaited promises and race conditions through deterministic AST and taint flow analysis.8-
- FlicenseNot gradedqualityBmaintenanceEnables whole-program callgraph reachability analysis to locate dead functions and stale flags, and integrates with MCP-compliant clients for automated code review, breaking-change audits, and CI/CD workflow pruning.8-