salmon
Yet another approach to xyz-dependencies: express provisioning, CI/CD and
general infrastructure operations as DAGs of idempotent operations (“ops”),
with uniform up/down/check semantics whether a node is as small as
“create a file” or as large as “turn a server up”. Run a graph once, or keep
it converged and supervised with a long-running run serve.
my-salmon config <seed-args...> | my-salmon run up # converge the graph
my-salmon config <seed-args...> | my-salmon run down # tear it down
my-salmon config <seed-args...> | my-salmon run tree # print the dependency tree
my-salmon run serve --http /run/salmon.sock # keep converging, tend the nodes, serve a web UI
Provisioning tooling tends to force a choice between one-off scripts (highly tunable, don’t compose) and do-everything tools (powerful, but their behaviour and their configuration become inseparable). Salmon’s bet: both are the same problem at different scales if operations are represented as an inspectable dependency graph rather than a flat ordered script — with the graph itself given real up/down/check semantics, so it converges to a target state (and back) instead of just running once.
The code is on GitHub at
lucasdicioccio/salmon. It is a
Haskell cabal multi-package project: salmon-core (the graph model, no IO),
salmon-ops (the builtin nodes and the drivers, one-shot and serve),
salmon-ops-recipes (opinionated compositions) and salmon-apps (the
binaries).
What it looks like
run serve --http serves a web page over the same socket as its API: the
live graph, one box per node with its wanted direction, convergence and
last check, and a command line at the bottom that speaks the same input
language as the terminal. This is the repository’s own fixture binary,
salmon-ops-serve-fixture, with three seeds declared up:

Clicking a node opens its panel: help, paths, dependencies and dependants, the last check, the node’s own output ring (here a managed process that was just spawned), and the actions the input language offers on it:

Explore
- Getting started — build it, run the tests, and the seed → directive → ops protocol every salmon binary speaks.
- The model —
Graph,OpGraph,Track,Eval: why “create a file” and “turn a server up” are one type. - Writing ops — the cookbook for declaring and testing nodes, and the patterns that recur across recipes.
run serve— convergence, supervision, the HTTP API, the web UI, pull mode and the status sink.- A Postgres pair — a primary that is a declaration, not a discovery: switchover, refused failovers, rejoins.
- Builtins, recipes and binaries — every node module, recipe and shipped binary, one line each.
- Guides and Specs — the documentation and the design sketches, each spec headed by what of it has shipped.