runkernel
runkernel is a code-native Rust task graph engine for build, ops, and deployment workflows.
Instead of encoding control flow in YAML, runkernel lets a project define typed, testable workflow logic in Rust. It is currently a local, library-first engine: it runs named tasks, resolves dependencies as a DAG, executes independent branches concurrently, skips deterministic cache hits, reports structured results, emits lifecycle events, passes typed outputs between tasks, and supports rollback policies for failure handling.
Basic Example
use ;
async
Pipeline::run() returns anyhow::Result<PipelineResult>. Invalid graphs, invalid glob patterns, and setup errors return Err. Task execution failures are represented in the returned PipelineResult so callers can inspect failed, skipped, cached, cancelled, and rolled-back tasks directly.
DAG Dependencies
pipeline.add;
pipeline.add;
pipeline.add;
lint and unit-test can run concurrently. package starts only after both complete successfully or are restored from cache.
Native Rust Tasks
use ;
pipeline.add;
Native tasks can use normal Rust libraries, typed environment parsing, forwarded run arguments, and task outputs.
Caching
pipeline.add;
Cache entries are scoped by pipeline namespace under .runkernel/cache/{pipeline_hash}/. Task cache filenames use a readable sanitized task name plus a hash suffix, such as build-a31f95c02a19e0dd.json, to avoid collisions between names like foo/bar and foo_bar. Cache identity includes the pipeline name, task name, declared dependencies, shell command, explicit cache key, declared environment values, matched file paths, and file contents.
Native function tasks should use .cache_key(...), .inputs(...), or .env_vars(...) when they opt into caching because runkernel cannot hash closure logic. Cache reasons for function tasks call this out explicitly.
Outputs
pipeline.add;
pipeline.add;
Outputs are stored as JSON values and deserialized through serde. A task can only read outputs from tasks that have completed.
Rollback
use ;
let mut pipeline = new
.rollback_policy;
pipeline.add;
RollbackPolicy::FailedTaskOnly is the default for compatibility with .on_failure(...). CompletedTasksReverseOrder rolls back completed tasks with rollback handlers after a pipeline failure.
Events
use PipelineEvent;
let pipeline = new.with_callback;
Events include queued, started, cached, completed, failed, skipped, cancelled, rollback, and pipeline-finished transitions. They are intended for CLIs and UIs without stdout scraping.
Graph and Explain
let dot = pipeline.to_dot?;
let explanation = pipeline.explain_task?;
to_dot() exports the validated DAG as Graphviz DOT. explain_task() returns an inspectable summary of a task's dependencies, dependents, action kind, cache configuration, declared inputs, environment variables, shell, and rollback handler presence.
CLI
The workspace includes a CLI binary named runkernel:
runkernel.toml does not define tasks. It tells the CLI where your Rust workflow lives:
[]
= "ops"
= "ops"
= "examples/ops/Cargo.toml"
= "."
= "deploy-edge"
= "Example ops workflow"
The CLI discovers runkernel.toml by walking up from the current directory. It delegates to the configured Cargo binary with the internal __runkernel protocol for list, graph, explain, and selected task execution. Arguments after -- on runkernel run are forwarded to workflow tasks and are available through Context::args(). Workflow binaries use runkernel-cli-support::RunkernelApp to expose that protocol.
Current Limitations
- runkernel is a local library, not a distributed workflow system.
- Shell execution defaults to
sh -c; Windows shells are modeled but not broadly tested. - Cache storage is local JSON under
.runkernel/cache. - Function task cache identity never includes the closure body; use explicit keys, inputs, or environment variables to describe invalidation.
- The CLI runs Rust workflow binaries discovered through
runkernel.toml; the manifest does not define tasks. - There is no remote worker, Kubernetes, web UI, plugin system, or YAML pipeline format.
Roadmap
- Stabilize the public API and docs.
- Continue hardening deterministic caching.
- Expand structured result and event coverage.
- Improve shell stdout/stderr configuration.
- Improve workflow protocol output formats and shell stdout/stderr controls.