| name | ci |
| description | Reference for the `justci` runner — how to invoke a full pipeline, a single recipe, or a platform-pinned node from a project that depends on `juspay/justci`. Trigger when the user asks to "run justci", "run the pipeline", "re-run a check", or names a specific recipe by `<recipe>@<platform>`. |
justci
justci translates a project's just recipe DAG into a process-compose pipeline and runs it. Strict-by-default: clean-tree refuse + HEAD git worktree pin + commit-status posts under <recipe>@<platform> contexts, unless you opt out with --no-strict / --no-snapshot / --no-post. Multi-platform lanes fan out via SSH. Full background in the repo README; the subcommand surface below is what you'll reach for most often.
Invoking
Always invoke via the flake — the consumer may not have justci installed on PATH:
nix run github:juspay/justci -- <subcommand> [args]
Pin to a tag (e.g. github:juspay/justci/v0.2.0) for reproducibility, or omit the ref to follow main. Every command in this skill is shown in the nix run form; substitute a pinned ref if your project requires one.
Modes
Strict by default — justci run refuses a dirty tree, snapshots HEAD via git worktree, posts commit statuses, and splits per-recipe logs into .ci/<sha>/<plat>/<recipe>.log. Three flags relax that policy:
| Flags | Tree | HEAD pin | Status posts | Use for |
|---|
| (none — default) | clean (refuses dirty) | git worktree at HEAD | posted | "real" CI runs |
--no-post | clean | git worktree at HEAD | none | non-github strict consumers, debugging strict without writing the PR's check list |
--no-snapshot (implies --no-post) | live working tree | none | none | strict-mode dev iteration where you don't want clean-tree refuse but still want SHA-keyed logs disabled |
--no-strict (meta — same as --no-snapshot --no-post) | live working tree | none | none | dev iteration; the one-flag opt-out for "just run the pipeline" |
Every mode shares the same verdict-summary at the end (── ci run summary ──) and exits non-zero if any node failed.
CI=true is no longer the gate. The env var is silently ignored — strict is the default and there is no mode-switch env var. Existing scripts that still pass CI=true keep working unchanged.
Common invocations
nix run github:juspay/justci -- run
nix run github:juspay/justci -- run --no-strict
nix run github:juspay/justci -- run --no-post
nix run github:juspay/justci -- run e2e@x86_64-linux
nix run github:juspay/justci -- run e2e
nix run github:juspay/justci -- run e2e lint
nix run github:juspay/justci -- run --platform x86_64-linux
nix run github:juspay/justci -- run --platform x86_64-linux --platform aarch64-darwin
nix run github:juspay/justci -- run --no-post --platform x86_64-linux
nix run github:juspay/justci -- run --no-deps e2e@aarch64-darwin
nix run github:juspay/justci -- run --root release-pipeline
nix run github:juspay/justci -- run --host x86_64-linux=root@lxc-foo
nix run github:juspay/justci -- run --tui
nix run github:juspay/justci -- run -- -t=false
Inspection subcommands (no side effects)
nix run github:juspay/justci -- dump-yaml
nix run github:juspay/justci -- graph
nix run github:juspay/justci -- protect --dry-run
nix run github:juspay/justci -- protect
nix run github:juspay/justci -- protect --branch develop
Live introspection (during a backgrounded run)
When justci run is in progress — typically because the agent backgrounded it (e.g. loop until /ci passes) — these subcommands report fine-grained per-node state without disturbing the run. Each resolves the socket and process-compose binary from the same source justci run itself uses, so the client version never drifts from the server.
nix run github:juspay/justci -- status
nix run github:juspay/justci -- status -o json
nix run github:juspay/justci -- monitor
nix run github:juspay/justci -- logs ci::e2e@aarch64-darwin
nix run github:juspay/justci -- logs -f ci::e2e@aarch64-darwin
If no run is in progress in this checkout, the subcommand exits non-zero with no justci run in progress in this checkout (no socket at .ci/pc.sock).
Anti-pattern: do not reach for raw process-compose
If you find yourself typing nix run nixpkgs#process-compose -- or hunting through /nix/store/...-process-compose-*/bin/ for a binary, stop — that path is not guaranteed to match the version the running pipeline uses, and the JSON shapes (e.g. process list -o json) may disagree. Always go through nix run github:juspay/justci -- {status,logs,monitor} so client and server stay version-pinned.
Decision flow
- Full canonical run? →
nix run github:juspay/justci -- run (strict by default; needs a clean tree and gh auth). Add --no-strict if you want to iterate on a dirty tree.
- Flaky check on a PR, only one lane is red? →
nix run github:juspay/justci -- run <recipe>@<platform> — same status context, overwrites the failure.
- Iterating on one recipe locally? →
nix run github:juspay/justci -- run --no-strict <recipe> (no platform pin = fans out to every pipeline platform; <recipe>@<localPlat> if you only want the local lane). --no-strict skips the clean-tree refuse so a WIP edit doesn't block you.
- Want the full DAG but only on one (or a subset of) platforms? →
nix run github:juspay/justci -- run --platform <platform> (repeatable). Slices the fanout pre-DAG, so it composes with <recipe> selectors that don't name a platform. Add --no-post to dry-run strict-mode reproducibility checks against one lane without writing the PR's checks list.
- Investigating "what would this run?" →
nix run github:juspay/justci -- dump-yaml or … -- graph.
- Setting up a new repo? → run
… -- protect --dry-run after at least one full run, verify the contexts look right, then … -- protect to lock them in.
- Checking on a backgrounded run? →
nix run github:juspay/justci -- status for a snapshot, … -- logs -f <recipe>@<platform> to follow one node, … -- monitor for the live event stream.
Hosts config
justci reads ~/.config/justci/hosts.json:
{
"x86_64-linux": "srid1",
"aarch64-darwin": "sincereintent"
}
Keys are full Nix system tuples (x86_64-linux, aarch64-linux, aarch64-darwin). Values are anything ssh knows how to dial — bare hostname, user@host, alias from ~/.ssh/config. Missing platforms silently drop from the fanout (the user opts in by adding the entry). Override per-run with --host PLATFORM=ADDR.
When NOT to use this skill
- The user is asking about justci's internals (how the YAML is shaped, what the setup node does, why
[metadata("ci")] matters) — that's a docs question, point them at the repo README.
- The user wants the runner to do something it doesn't support (parallel cross-platform within one recipe, mid-run config reload) — those are not supported today; check the README's Roadmap section.