Releases: false-systems/sykli-elixir
Release list
v0.9.0-rc.1
sykli 0.9.0-rc.1
Release candidate — GitHub-only prerelease. No registry publishes; binaries
below are for local testing.
The mandate release.
Schema v5 lands end to end: contracts declare who executes a task (actor)
and under what bounded authority (mandate), the engine enforces those
bounds with git-backed verification, and sykli audit judges any recorded
run against the pinned contract. Alongside it: the Sykli Workbench, a
local-first web control room for one repo.
Highlights
v5: actor + mandate, enforced
- All five SDKs emit v5 (
actor,mandate). Agent actors require a
mandate, non-emptysuccess_criteria, and non-emptyevidence_required
— a hard schema error otherwise. Gate and review tasks reject the new
fields. - The executor enforces mandates. Scope is verified with git
fingerprints (pre-existing dirty files cannot hide task writes), budgets
cap diff lines and wall clock, andcapabilities.network: falsedenies
network where the runtime supports isolation. Every executable task with
a mandate records amandate_outcome
(kept/violated/unverified/unsupported) in run history —
verification never fails open. sykli audit <run-id>. Judges a recorded run manifest: lock hash
match, success-criteria and evidence results recorded, mandate outcomes
present for agent tasks. The verdict is computed at read time against the
currentsykli.lock— re-locking a different contract flips old runs
to fail. The core lives inSykli.Services.Audit, shared by CLI and the
Workbench.
Sykli Workbench (sykli gui)
A local-first control room for one repo: contract, run graph, members,
work items, gates, evidence, activity — one screen. Bandit + Plug bound to
127.0.0.1 only; the SPA is embedded in the binary at compile time.
- Real data by default. Repo identity from git, contract from
sykli.lock/.sykli/context.json, runs and evidence from.sykli/runs/,
work items and gates from their local stores. The GUI never executes repo
code —GET /api/statecannot trigger an SDK emit.--demoserves the
showcase dataset. - Gate decisions write through. Approving a gate in the browser produces
the same.sykli/gates/<id>.jsonartifact assykli gate approve, with
member:-qualified attribution. - The v5 story rendered. Contract-declared agent actors appear as
members with their mandates; nodes show mandate outcomes; evidence rows
show the live audit verdict and a per-run mandate summary.
Fixes
- Daemon heartbeat shutdown. The final offline goodbye in
terminate/2
can no longer turn a clean stop into a crash when the transport is
already gone (e.g.:inetsstopping during VM drain). - Run lookup by id.
Sykli.RunHistory.get/2finds a run without
loading every manifest; corrupt manifests cannot hide valid runs.
Using the SDKs with this rc
This is a GitHub-only prerelease: no SDK package was pushed to any
registry (crates.io, PyPI, Hex, npm, Go module tag). Registry versions
resolve again at the stable 0.9.0 tag. Until then, depend on the tag
directly:
Rust (verified against this tag):
[dependencies]
sykli = { git = "https://github.com/false-systems/sykli", tag = "v0.9.0-rc.1" }Python:
pip install "git+https://github.com/false-systems/sykli@v0.9.0-rc.1#subdirectory=sdk/python"Elixir:
{:sykli, git: "https://github.com/false-systems/sykli.git", tag: "v0.9.0-rc.1", sparse: "sdk/elixir"}Go (the module-aware sdk/go/v… tag ships with stable releases only;
pin the release commit):
go get github.com/false-systems/sykli/sdk/go@5e0130eTypeScript: npm cannot install a subdirectory of a git repo — clone the
tag and use a local file: dependency on sdk/typescript for now.
Compatibility
- Pipelines emitting versions
"1"–"4"are unchanged."5"is emitted
automatically whenactor/mandateare used. - Run manifests gain optional
mandate_outcomeon task results; older
manifests read cleanly. - New CLI surface:
sykli audit <run-id>,sykli gui. New error codes are
cataloged indocs/error-codes.md.
Checksums
SHA256SUMS.txt is attached to this release.
v0.7.0
sykli 0.7.0
Released 2026-06-11
The hardening release.
In May, sykli ran a six-dimension audit against itself — security, determinism,
OTP correctness, eval coverage, architecture, test quality — and wrote down
everything it found. 0.7.0 ships the remediation: every security finding fixed,
the determinism contract widened and enforced, the full evaluation pyramid
wired into CI, and the black-box suite at zero known-broken cases for the
first time. The audit report is in the repo (docs/audit-2026-05-22.md);
the fixes are in this release. That's the standard going forward: claims you
can check.
Highlights
Team Mode security, end to end
The self-hosted coordinator path got the full treatment:
- No plaintext tokens. The coordinator client refuses to send the Team
Mode bearer token over plaintext HTTP to a non-loopback host. HTTPS and
loopback are unaffected;SYKLI_COORDINATOR_INSECURE=1is a loud,
explicit opt-in. - Per-team authorization. Stateless signed team tokens
(sykli coordinator mint-token --org <o> --team <t> --role <r>) scope
every coordinator read and write. A team token cannot list, read, or
mutate another team's work items, runs, gates, or sessions. - Resolved secrets are masked everywhere. Secret values resolved at
runtime — fromsecret_refs, OIDC exchange, or secret-like env keys —
are now masked in occurrence persistence, notifications, run-summary
sync, and SLSA attestations. - SSRF-guarded webhooks. Gate and notification webhook URLs are
resolved and rejected if they point at loopback, link-local (including
the cloud metadata range), or private addresses — IPv4 and IPv6, across
every resolved DNS record.
Determinism you can bank on
contract_hash now canonicalizes by recursively sorting object keys, so
semantically identical contracts hash identically across OTP versions and
map sizes. The custom NoWallClock Credo check widened from simulator
transport to every pure contract and output-shaping transform. The engine
was already deterministic — now the guards prove it stays that way.
The evaluation pyramid runs in CI
Credo, black-box CLI tests, cross-SDK conformance, and merge-to-main oracle
evals all run on every change — reproducible locally with mix verify or
make verify. Black-box expected-failure flags now require a tracking issue
URL, and with GH-4 reframed against the documented runtime trust model
(docs/runtime-trust-model.md), the suite carries no known-broken cases.
A front door
CONTRIBUTING.md documents the build, the test tiers, and the
tested-and-enforced project rules. GitHub Discussions are open. The
conformance suite makes SDK contributions verifiable by construction — a
new review primitive or a new SDK is a well-bounded first contribution.
Housekeeping that matters
The repository moved to github.com/false-systems/sykli, and as of 0.7.0
everything agrees: the Go SDK module path, install.sh, the GitHub Action,
sykli init scaffolding, docs, and error hints. Go SDK versions up to
sdk/go/v0.4.0 remain fetchable under the old path via the Go module proxy;
new versions publish under github.com/false-systems/sykli/sdk/go.
Full details in CHANGELOG.md.
v0.6.0
sykli 0.6.0
Released 2026-04-29
Local-first CI for the next generation of software developers.
This is the release that makes that one-liner mean something. The CLI looks the way the project sounds. The runtime layer is decoupled from the engine. The supply chain is signed. AI agents read your runs natively. And the foundation for replacing GitHub Actions — sykli running on your own mesh, GitHub talking to it directly — is in place.
sykli · build.exs local · 0.6.0
● test go test ./... 1.8s
● build go build ./cmd/app 912ms
● lint golangci-lint run 220ms
─ 3 passed 2.9s
Highlights
The CLI looks designed now
A full visual reset (ADR-020). One accent color, glyph-driven status, single redraw region for animations, hidden task stdout by default, one summary per run. No more "Level", no more "1L", no more debug headers. Failure mode draws a horizontal rule under the failed task and points at sykli fix for AI-readable analysis. Reference set for the aesthetic: Linear, Vercel CLI, Raycast.
Runtime decoupling — :test defaults to a Fake
The execution layer is now properly separated from the engine. Sykli.Runtime.Resolver is the single source of truth for runtime selection (priority chain: CLI flag → opts → app env → SYKLI_RUNTIME → auto-detect → Shell). Sykli.Runtime.Fake is the new in-memory deterministic runtime that :test defaults to — your unit tests no longer need Docker. New: Sykli.Runtime.Podman (rootless container parity), mix sykli.runtime.info for inspection, --runtime CLI flag, and test tiers (mix test.docker, mix test.podman, mix test.integration).
sykli fix and friends — AI-readable failures
Four new commands for AI-native CI:
sykli fix— failure analysis with source context, git provenance, and a single-line cause statement. The screenshot moment.sykli mcp— MCP server so Claude Code, Cursor, and Copilot can read your run state directly without log scraping.sykli query— structured queries against pipeline / history / health data without an LLM.sykli plan— dry-run execution planning with git-diff-driven task selection.
All --json output now flows through a shared envelope ({ok, version, data, error}) so agents parse one shape across every command.
SLSA v1.0 attestations
Every run now produces a DSSE-signed SLSA v1.0 provenance envelope. Per-run and per-task attestations. Configure signing via SYKLI_SIGNING_KEY (HMAC) or SYKLI_ATTESTATION_KEY_FILE (file-based). The supply-chain story is no longer aspirational.
GitHub-native foundation (ADR-021 Phase 1)
The first slab of the v0.7 line: sykli now ships a GitHub App, a webhook receiver (Plug + Bandit), a Checks API client, and a :webhook_receiver mesh role. A signed webhook arrives at the user's mesh, signature is verified (HMAC-SHA256, constant-time, body never logged on mismatch), the receiver opens a queued check suite. Phase 2 (pipeline dispatch from the webhook) is in progress; Phase 3 (PR-diff annotations from sykli fix) is next.
This means: in v0.7, sykli replaces GitHub Actions instead of running inside it. Local-first throughout — the receiver lives on hardware you control, never on Sykli-owned infrastructure. ADR-021 supersedes ADR-004; the in-Actions integration remains as a documented fallback.
FALSE Protocol first-class
Internal events are now Sykli.Occurrence structs end-to-end (refactor — events used to be wrapped by occurrences). New: chain_id for correlating retry chains, configurable source URI via SYKLI_SOURCE_URI, and an :errored task status distinct from :failed for infrastructure failures. :failed gets causality analysis; :errored gets infrastructure diagnostics.
Eval harness + oracle
55 ground-truth oracle cases for AI-agent CI behavior validation. Run via eval/oracle/run.sh. The full Claude Code → build → oracle → report loop is in eval/harness/run.sh for AI-agent regression testing.
Hardening
A full sweep across the security and reliability backlog:
- SEC-001..007 all closed: OIDC TLS verification, secret_refs path traversal, Docker mount containment, webhook SSRF guard, broader secret masking, OIDC-derived runtime cache keys.
- REL-002..008 closed: graceful shutdown, concurrent-run race fix, S3 cache circuit breaker, async SCM status calls, telemetry duration units, RunRegistry eviction, PubSub failure handling.
- 35+ PR review comments addressed across the release.
Breaking change
Cache fingerprint scheme now includes the repo-relative workdir. This prevents cross-project cache pollution but means .sykli/occurrence.json payloads from before 0.6.0 are not backward-compatible.
What you need to do: nothing. The first run after upgrade rebuilds local cache state automatically. Expect one cold run.
Install / upgrade
# Single binary
curl -fsSL https://raw.githubusercontent.com/false-systems/sykli/main/install.sh | bash
# Or with a specific version
curl -fsSL https://raw.githubusercontent.com/false-systems/sykli/main/install.sh | bash -s v0.6.0SDKs (all bumped to 0.6.0 in lockstep):
# Go
go get github.com/yairfalse/sykli/sdk/go@v0.6.0
# Rust
cargo add sykli@0.6.0
# TypeScript
npm install sykli@0.6.0
# Python
pip install sykli==0.6.0
# Elixir
{:sykli, "~> 0.6.0"}What's next
- Phase 2 of the GitHub-native rollout (
CODEX_PROMPT_PHASE_2.mdin the repo): webhook → mesh placement → executor → check-run lifecycle. Per-task check runs transition throughqueued→in_progress→ conclusion. - Phase 3:
sykli fixannotations rendered onto the PR diff via the Checks API's annotation surface. - Phase 4: GitHub App marketplace listing.
Thanks
To everyone who pushed back on early drafts of the visual reset, who reviewed the runtime decoupling RC.0–RC.7 chain, who pointed out the cache-fingerprint cross-project-pollution bug, and to the Codex agents that shipped the visual reset (PR #123) and the GitHub-native foundation (PR #125) cleanly.
Full changelog: see CHANGELOG.md for the comprehensive list of additions, changes, fixes, and security closures across all 142 commits.
Architectural reference: ADR-020 (positioning + visual direction), ADR-021 (GitHub-native via webhook + mesh receiver).
v0.5.2
What's Changed
- feat: BEAM-native occurrence store with triple-write persistence by @yairfalse in #93
Full Changelog: v0.5.1...v0.5.2
v0.5.1
What's Changed
- Delete comparison section from README by @yairfalse in #57
- SDK Parity: Add missing features across TypeScript, Elixir, and Rust SDKs by @yairfalse in #58
- Add --timeout flag for CI environments by @yairfalse in #60
- refactor(sdk): simplify K8s options to minimal API by @yairfalse in #61
- docs(sdk): add REFERENCE.md and language presets by @yairfalse in #62
- fix(core): improve robustness with timeouts and error handling by @yairfalse in #63
- test(executor): add opts threading tests by @yairfalse in #65
- test(security): add shell injection prevention tests by @yairfalse in #64
- feat(k8s): implement PVC creation for volumes by @yairfalse in #69
- feat(error): add Rust-quality error system with human-friendly codes by @yairfalse in #70
- refactor(core): extract Sykli.Git module for centralized git operations by @yairfalse in #71
- chore(sdk/ts): add eslint and typescript-eslint by @yairfalse in #72
- chore: remove unused root go.mod by @yairfalse in #73
- chore: align TypeScript SDK to v0.3.0 and update CHANGELOG by @yairfalse in #74
- fix: bump TypeScript SDK version to 0.3.0 by @yairfalse in #75
- fix: resolve type warning in executor module by @yairfalse in #76
- fix: remove dead code in save_run_history by @yairfalse in #77
- docs: add actual content to core README by @yairfalse in #78
- docs: mark RunHistory section as complete by @yairfalse in #79
- docs: add getting started guide by @yairfalse in #80
- chore: bump version to 0.4.0 by @yairfalse in #81
- fix: add missing properties to K8sOptions interface by @yairfalse in #83
- fix: use correct import path in Go examples by @yairfalse in #82
- feat: add AI-native features to all SDKs by @yairfalse in #84
- docs: update changelog for 0.4.0 by @yairfalse in #85
- chore: add example .sykli/ output for Go basic example by @yairfalse in #87
- feat: add Python SDK by @yairfalse in #89
- feat: capability deps, gates, OIDC exchange, merge queue detection by @yairfalse in #88
- chore: bump version to 0.5.0 by @yairfalse in #90
- fix(timeout): enforce --timeout + 77-case black-box suite by @yairfalse in #91
- feat: cross-platform verify + timeout enforcement + black-box suite by @yairfalse in #92
Full Changelog: v0.3.0...v0.5.1
v0.4.0
What's Changed
- Delete comparison section from README by @yairfalse in #57
- SDK Parity: Add missing features across TypeScript, Elixir, and Rust SDKs by @yairfalse in #58
- Add --timeout flag for CI environments by @yairfalse in #60
- refactor(sdk): simplify K8s options to minimal API by @yairfalse in #61
- docs(sdk): add REFERENCE.md and language presets by @yairfalse in #62
- fix(core): improve robustness with timeouts and error handling by @yairfalse in #63
- test(executor): add opts threading tests by @yairfalse in #65
- test(security): add shell injection prevention tests by @yairfalse in #64
- feat(k8s): implement PVC creation for volumes by @yairfalse in #69
- feat(error): add Rust-quality error system with human-friendly codes by @yairfalse in #70
- refactor(core): extract Sykli.Git module for centralized git operations by @yairfalse in #71
- chore(sdk/ts): add eslint and typescript-eslint by @yairfalse in #72
- chore: remove unused root go.mod by @yairfalse in #73
- chore: align TypeScript SDK to v0.3.0 and update CHANGELOG by @yairfalse in #74
- fix: bump TypeScript SDK version to 0.3.0 by @yairfalse in #75
- fix: resolve type warning in executor module by @yairfalse in #76
- fix: remove dead code in save_run_history by @yairfalse in #77
- docs: add actual content to core README by @yairfalse in #78
- docs: mark RunHistory section as complete by @yairfalse in #79
- docs: add getting started guide by @yairfalse in #80
- chore: bump version to 0.4.0 by @yairfalse in #81
- fix: add missing properties to K8sOptions interface by @yairfalse in #83
- fix: use correct import path in Go examples by @yairfalse in #82
- feat: add AI-native features to all SDKs by @yairfalse in #84
Full Changelog: v0.3.0...v0.4.0
v0.3.0
What's New in v0.3.0
Node Profiles & Task Placement
Tasks can now specify which nodes they should run on using label requirements:
Go SDK:
p.Task("train").
Requires("gpu").
Run("python train.py")Rust SDK:
p.task("train")
.requires(&["gpu"])
.run("python train.py");Nodes automatically expose labels for:
- OS:
darwin,linux,windows - Architecture:
arm64,amd64 - Docker:
docker(if docker is installed)
User-defined labels via:
# Environment variable
SYKLI_LABELS=gpu,team:ml sykli run
# CLI flag (daemon mode)
sykli daemon start --labels=gpu,team:mlPlacementError Diagnostics
When task placement fails, you get actionable hints:
✗ train failed: no nodes match requirements
Task requires: gpu
Available nodes: local
Nodes tried:
local → exited with code 1
Fix options:
• Add labels to a node: SYKLI_LABELS=gpu
Documentation
- ADR-018: TypeScript SDK design
- ADR-019: Schema-driven SDK code generation architecture
Full Changelog
New Features:
- Node profiles with auto-detected labels (OS, arch, docker)
- User-defined labels via
SYKLI_LABELSor--labels - Task
requires()method for node placement - NodeSelector with rich PlacementError diagnostics
Changed:
- Mesh executor uses NodeSelector for all task dispatch
v0.2.7
v0.2.6
Fixed
- Task workdir for local shell execution - The
workdirDSL option now works correctly for non-containerized tasks. Shell tasks run inpipeline_workdir + task.workdir(e.g.,workdir "core"runs commands in thecore/subdirectory).
Changed
- Sykli dogfooding pipeline (
sykli.exs) now uses portable paths forMix.install