Run your checks. Reuse the work. Explain the result.
Sykli gives your repository one declared graph for checks, a local cache for reusable results, and a receipt for every run. Use the same commands on your laptop, in CI, or from a coding agent.
Keep Cargo, npm, Go and your shell scripts. Declare what each task reads and what it depends on; Sykli handles ordering, checks cached evidence, and records which tasks ran or reused a result. Before running anything, ask it to explain what a change affects and what the cache can supply.
One binary. Local execution. Readable CLI, structured JSON when you need it.
Install from the current source with Rust 1.85 or newer:
cargo install --git https://github.com/false-systems/sykli --branch main --locked sykliIn an existing Cargo, npm or Go repository:
sykli init # generate sykli.json and pin it in sykli.lock
sykli plan --explain # inspect selection and cache evidence
sykli run sykli.json --json > .sykli/receipt.json
sykli verify .sykli/receipt.json --contract sykli.jsoninit creates .sykli/ for local state and adds it to .gitignore. Review the
input declarations it generates, especially configuration, fixtures and files
you add later. Task execution needs Git, a POSIX sh, and your project's tools.
On Windows, Git for Windows supplies sh.
This README describes main, including plan --explain. For reproducible
installs, replace --branch main with --rev COMMIT. Tagged downloads, when
published, are listed on the releases page.
The repository includes an installer that verifies release archive checksums;
see install.sh. Installing Sykli does not install your build tools.
- See the work before running it. Explain why a task is selected, whether cache evidence is available, and which dependencies still need resolution.
- Reuse passing work. Cache keys cover the task declaration, declared input contents and execute bits, runtime fingerprint, inherited environment digests, and dependency keys. A matching entry must validate before reuse.
- Keep a record tied to the code. Each receipt binds task outcomes to the repository tree, declared inputs and contract. Verify it before relying on it.
- Give agents a concrete answer. The CLI does the querying;
--jsongives scripts and agents the same information with versioned schemas and exit codes. - Use it wherever your commands run. Local development and CI share the graph. Sykli stays a local CLI; your CI service owns runners and scheduling.
flowchart LR
graph["Declare tasks and inputs"] --> plan["Explain the plan"]
plan --> run["Run or reuse validated results"]
run --> receipt["Record a receipt"]
receipt --> verify["Verify against the current code"]
In a scratch Git repository, create two scripts and this sykli.json:
printf 'echo lint passed\n' > lint.sh
printf 'echo tests passed\n' > test.sh{
"schema": "sykli-contract.v1",
"tasks": [
{ "name": "lint", "run": "sh lint.sh", "inputs": ["lint.sh"] },
{ "name": "test", "run": "sh test.sh", "inputs": ["test.sh"], "after": ["lint"] }
]
}inputs names the files a task reads. after makes test wait for lint
and binds its cache key to that dependency. Independent tasks can run in parallel.
mkdir -p .sykli
sykli run sykli.json --json > .sykli/first.json
sykli run sykli.json --json > .sykli/second.json
sykli verify .sykli/second.json --contract sykli.jsonThe first run executes both scripts. With unchanged inputs and valid local
cache entries, the second reuses both passing results. Change test.sh and
run again: lint can be reused while test executes.
A contract declares the work. A receipt records one evaluation,
including commands, outcomes, output digests and whether results were cached.
Verify checks that the record is consistent with the current tree and contract.
Keep receipts under .sykli/ or outside the repository so they do not change
the tree they describe.
sykli plan --explain
sykli plan --changed test.sh --explain
sykli plan --changed test.sh --explain --json
sykli plan --explain --base origin/main --json
sykli plan --explain --preview --json # inspect a contract edit before re-locking--explain reads sykli.json by default. It runs no task or Rust emitter,
restores no outputs, and writes no cache entries or receipts. An explicit
JSON contract path selects another graph.
Explain also warns about changed files that no task declares as an input,
even when the selected tasks already cover the whole graph. It checks staged,
unstaged and untracked non-ignored files; --base origin/main also includes
committed changes relative to that ref. Contract and lock changes are labeled
as evaluation metadata. In Cargo-root repositories, run refuses to execute or
reuse passes when known source/configuration files or test files are missing
from every task's inputs. This checks the current Git file inventory, including
committed and new non-ignored files. Other unmapped paths remain advisory.
Selecting every task still does not prove every dependency is declared; see
the coverage limits.
| Cache state | What it tells you |
|---|---|
available |
Cached evidence and artifacts validate; execution can attempt reuse. |
missing |
No entry exists for the current content key. |
invalid |
An entry exists but its evidence or artifacts failed validation. |
deferred |
A dependency needs execution, restoration or error resolution first. |
input_error |
A declared input cannot currently be evaluated. |
--changed takes paths you supply and filters the displayed plan to
matching declared inputs and downstream tasks. It does not discover a Git diff
or restrict a later run. The full run evaluates the graph and decides reuse
from content keys and valid cache evidence.
Input declarations matter: Sykli does not observe every file or tool your commands read. Undeclared dependencies can make cached results misleading. An explanation describes the current local evidence, not a guaranteed future outcome. See the agent guide for selection reasons, JSON fields and error behavior.
After checkout and installation of Sykli and your project toolchain:
sykli run sykli.json --json > .sykli/receipt.json
sykli verify .sykli/receipt.json --contract sykli.jsonCreate .sykli/ before redirecting if this is a fresh checkout. Configure your
CI to fail on either command's nonzero exit and retain the receipt as an artifact.
The included GitHub Action handles running, verification, a job
summary and receipt upload. It also reports affected tasks on pull requests.
This repository now runs a shadow experiment on pull requests. It records changed paths, runs the full candidate graph, then compares that result with reuse proposed from a separate base-commit run. It reports agreements, disagreements, unmapped paths and potential reused task time.
All required checks still run. The experiment adds a baseline run to measure whether skipping could be justified later. It does not claim CI savings today, and matching observations do not prove that declarations are complete.
On Linux and macOS, typed production captures declared source, builds an artifact and runs required checks. A production ID lets another terminal or agent resume from the same local store.
For a Cargo binary or Go main package:
sykli init --production --smoke '"$SYKLI_INPUT_executable" --help'
sykli targets
sykli produce TARGET --stop-after build
sykli resume PRODUCTION_IDUse the discovered target name and the production ID printed by Sykli. Stopping after build returns exit 1 when checks remain. Artifact availability and completed checks are recorded separately; failed work requires an explicit retry, and an unresolved lost attempt cannot silently become a success.
See the production agent loop for preparation without execution, individual operations, bounded parallel work and diagnostics.
With an authenticated GitHub CLI (gh), collect CI and review evidence for an
exact candidate and assess requirements you declare:
sykli inspect --repo OWNER/REPO --pr NUMBER --requirements review.json
sykli assess BUNDLE --requirements review.jsonThe requirements file names exact workflow and reviewer IDs. Sykli saves the collected responses so the assessment can be replayed offline. Results explain which requirements are established, refuted or unproven, including gaps and excluded evidence. An approval of an older commit does not satisfy approval of the current candidate.
These assessments are advisory. They establish declared review-readiness
conditions, not permission to merge or deploy. inspect makes bounded,
read-only requests through gh; it does not post reviews or trigger work.
verify checks record consistency, contract identity, the repository tree and
declared inputs, then the recorded outcome. It does not authenticate the
author of a receipt or prove that the declared checks are sufficient.
verify exit code |
Meaning |
|---|---|
0 |
Receipt matches and work passed or was reused. |
1 |
The recorded work failed. |
2 |
Receipt cannot be verified. |
3 |
Tree or declared inputs changed. |
4 |
Contract or lock differs. |
Tasks receive PATH, HOME and TMPDIR, plus declared env values and named
inherit variables. Inherited values reach the task; their digests are recorded
for identity. Task output is captured, so commands remain responsible for what
they print. Sykli executes local commands with your permissions.
Machine-readable documents have versioned schemas. Incompatible changes get a new schema version; command help documents flags and exit codes.
- Agent guide: JSON queries, explanations, production and assessment.
- CI experiment: methodology, artifacts and limitations.
- Changelog: version history.
- Contributing and product boundaries.
- Security policy: report vulnerabilities privately.
Part of False Systems. Licensed under MIT.