Trill

CI that runs on your laptop first.

One Rust binary. Full pipeline locally with the same semantics as the managed cloud — DAG, approvals, typed outputs. See every run before you ship it.

Local-first

Rehearse the whole pipeline. Then git push.

Every Trill workflow runs the same way on your machine as it does on the managed cloud at app.trill.build. The binary ships the scheduler, the DAG resolver, the approval loop, and the typed-output templating. No daemons. No Docker. No yak shaving.

$ trill run ci.yaml
 checkout     (3.2s)
 install      (18s)
 lint         (12s)
 test         (running…)
 build
 deploy       awaiting approval
 smoke
			

Same DAG. Same approvals. Same typed outputs. Then git push with confidence.

Structured approvals

Approval steps are typed forms, not yes/no buttons.

Ask for the environment, the timeout, a reason. The answers land in steps.approve.outputs and flow forward through your templates — no out-of-band config, no "set an env var in the other system," no copy-paste from Slack.

- name: approve
  type: approval
  prompt: "Deploy to production?"
  fields:
    - name: environment
      type: select
      options: [staging, production]
    - name: dry_run
      type: checkbox
    - name: timeout_minutes
      type: number
      min: 1
      max: 60
				
Action Required
Blocked until a decision is made.

Deploy to production?

Approve Reject

The answer to environment is now {{ jobs.deploy.outputs.environment }} for every downstream job.

Timeline-first

You're staring at a wall clock, not a tree.

Every run renders on a shared time axis. Parallelism and bottlenecks are visible at a glance. No expanding trees to find the slow job.

Typed outputs

Jobs return values. Values flow downstream.

Steps emit JSON via $STEP_OUTPUT_FILE. Templates pick values up with {{ steps.x.outputs.y }}. Your pipeline is data, not text.

DAG-native

Dependencies are declared, not scripted.

A job declares depends_on; the scheduler handles the rest. Parallel siblings run in parallel. Skipped jobs skip their transitive dependents.

Your agents, your hardware

The executor is on your machine. Always.

The managed plane at app.trill.build schedules. Your agent — laptop, home server, build box — claims jobs and runs them locally. Your source, your secrets, your network. Nothing leaves your infrastructure.

The loop

From laptop to cloud in one push.

Write

Describe your pipeline in trill.yaml. Jobs, steps, approvals, typed outputs.

Rehearse locally

trill run executes the whole thing on your laptop. Approval prompts in the TUI. Outputs pass through exactly like they will in the cloud.

Push

Commit the YAML, push. The managed cloud runs the same workflow with the same semantics — now visible to your whole team, with approval forms in the browser and full run history.

No environment parity issues. No "works on my machine." Because this is your machine.