Skip to main content
Glama
bdelanghe

flake-verbs

by bdelanghe

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

inputs

Welche meiner Inputs wird überhaupt tatsächlich verwendet?

input-drift

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, derived

Beide 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 benennt

  • Kommentare

  • 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 sets

Wo 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 — ein path:-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.

  • --deep erkennt die Idiome cfg = config.<ns> und options.<ns>. Ein anders geschriebenes Modul fällt auf module-import-only zurück.

  • input-drift prüft nur github:-Inputs gegen ihren Upstream. git:- und tarball:-Inputs melden unknown auch 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.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables 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 npm
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables supply-chain integrity for MCP tools by locking tool-definition hashes after review and detecting added, removed, modified, or risky tool definitions.
    MIT