pipelines API or CLI before the Routines feature was finalized. TL;DR: nothing breaks. The user-facing label changed from “Pipeline” to “Routine”, but every backend identifier — table, package, route paths, journal types, WS event types, command-line aliases — stays the same. Existing scripts, agents, and saved pipelines keep working.
What changed
User-facing label: Pipeline → Routine
What stays the same (backwards-compatible)
The naming split mirrors GitHub’s pattern: their underlying table is
issue_events but the UI says “Issues”. Backend stability + user-facing rename, no breaking change.What’s new beyond the rename
Beyond the rename itself, the same release shipped the following net-new capabilities:Triggers
- Cron schedules — recurring auto-fire on cron expression. New tables:
pipeline_schedules(v80). New CLI:crewship routine schedules .... - Webhooks — token-addressed event triggers with optional HMAC signing, per-token rate limiting. New tables:
pipeline_webhooks(v82),pipeline_run_idempotency(v81). New CLI:crewship routine webhooks ....
Versioning
- Immutable history + rollback — every save creates a new
pipeline_versionsrow (v79).crewship routine versions <slug>,crewship routine rollback <slug> --to N.
Step types
- 6 step types instead of MVP’s 2:
agent_run,call_pipeline,http,code,wait,transform. See Step types reference. - DAG with
needs[]— independent steps execute in parallel. - Conditional
if— any step can carry a template-rendered boolean to skip itself.
HITL
- Waitpoints — DB-backed approval primitive (v79).
waitstep ofkind: approvalparks the run goroutine on a token; approve via CLI (crewship routine waitpoints approve <token>), UI inbox, or API.
UX
/routinespage — dedicated full-management surface as a clone of/orchestration. Three-column layout with filter sidebar, 4 main tabs, and a 7-tab detail panel.- + New routine dialog — JSON DSL editor with 3 starter templates and Test & Save flow.
- Live waterfall — Runs sub-tab subscribes to step-level WebSocket events.
Tooling
crewship routine validate file.json— offline DSL parse + validate, exit 0/1 for CI gates.crewship routine watch <slug>— live event stream, ANSI-coloured by default,--jsonfor jq pipelines.crewship routine logs <run_id> --slug X— one-shot post-mortem dump for a specific run.crewship routine doctor <slug>— preflight ✓/⚠/✗ checklist that catches blind alleys (missing crew provisioning, agent slug typo, missing credential, contradictory validation gate, cost cap too tight) beforerun. CI-friendly via-f json+ non-zero exit on any FAIL.crewship routine bench <slug>— N-runs variance characterisation: pass-rate + cost mean/p95/max + duration p50/p95/max + fail-reason breakdown. Headline verdict (PRODUCTION_READY/FLAKY/UNRELIABLE/BROKEN).crewship routine records <slug>— list runs from the indexedpipeline_runsprojection (v83). Filterable by status, much faster thanrunsfor large run history.crewship eval scenarios/eval compare/eval baseline— cross-tier consistency suite for routines whose slug starts witheval-. Save baselines locally, diff in CI on every PR. See eval CLI.--tier-overrideflag onroutine run(and onbench,eval scenarios,eval compare,eval baseline) — force everyagent_runstep onto a specific tier without DSL changes. Step-levelmodel_overridestill wins.- JSON Schema at
schemas/routine.v1.json— IDE autocomplete + inline validation when authoring DSL files.
Security
- HMAC
save_token—/test_runreturns a signed token bound to (workspace, definition_hash, user_id, ts)./saveverifies the token instead of trustinglast_test_run_atbody claims. Closes the test-gate spoofing surface flagged in the original review. - CheckRedirect on HTTP step — egress allowlist re-validated on every 3xx hop, blocking SSRF via redirect chains.
- JOIN on workspace_id in agent slug resolution — eliminates cross-workspace agent execution surface.
Migration paths
”I’m using the CLI”
Nothing to change.pipeline is a cobra alias on the top-level command, so crewship pipeline X works for every subcommand — including the new ones (schedules / webhooks / waitpoints / validate / watch / logs / records / doctor / bench). crewship pipeline list and crewship routine list are identical. Recommended: switch your scripts to routine for forward-consistency, but nothing forces it.
”I’m using the API”
Nothing to change. All/api/v1/.../pipelines/* route paths are unchanged. The new endpoints (/api/v1/workspaces/{ws}/pipelines/save for UI authoring + /api/v1/workspaces/{ws}/pipeline-schedules, /api/v1/workspaces/{ws}/pipeline-webhooks etc.) are additive.
The /test_run response now includes a save_token field (omitempty); legacy clients that ignore unknown fields see no change.
”My agents author pipelines via the sidecar”
Nothing to change. The sidecarlocalhost:9119/pipelines/* paths are unchanged. The agent system prompt now says [AVAILABLE ROUTINES] instead of [AVAILABLE PIPELINES], but agents read the bracket label as a section header, not a method name — they still POST to /pipelines/save and /pipelines/{slug}/run.
”I have a saved bundle export from before the rename”
Bundles are forward-compatible. The export format (crewship-pipeline-bundle/v1) is unchanged. Re-import works: crewship routine import bundle.json. The bundle filename format changed (pipeline-<slug>-bundle.json → routine-<slug>-bundle.json) but the filename has no semantic meaning — only the JSON shape inside matters.
Database migrations
Five migrations land in this release:
All migrations apply automatically on first boot of a server with the new binary. Backup integrity is preserved —
crewship backup create includes the new tables. Rollback path: restore.go for v78 returns nil (data-bearing tables can’t be partial-rolled-back); for downstream rollback use the archive snapshot from before the upgrade.
Tier override behavior change
Routines whose steps declarecomplexity: "fast" (or any other tier) now actually pin the agent’s CLI to the resolved model (claude --model claude-haiku-4-5-20251001). Previously the override was silently dropped and the agent’s default model ran every step.
Before (silent drop): a routine with complexity: "fast" on Tomas (default model: Sonnet) ran on Sonnet at ~$0.06/run.
After (override honored): same routine runs on Haiku at ~$0.003/run. ~20× cheaper, ~3× faster.
Cost dashboards may show a step-down in pipeline-attributed LLM cost after this release. That’s the expected behaviour finally landing — not a metering glitch.
CodeRabbit-flagged fixes carried forward
The original PR review flagged 23 inline issues. The vast majority were addressed in the original7715ee7 sweep; the remaining items shipped with this release. See the CHANGELOG for the full list.
Highlights for security/stability-conscious users:
- DAG completion bookkeeping — failed steps no longer mark
completed=true(would have let downstream branches advance with empty inputs) - Waitpoint lost-wakeup race — listener pre-registration eliminates the timing window
- Webhook rate-limiter — counter increment now atomic under mutex
- Idempotency stale-row — sweep failure no longer leaks dead
run_ids through subsequent reads - SSRF via redirect — already covered above
- Cross-workspace agent execution — already covered above
- Template validation breadth — bad templates in HTTP/Wait/Code/Transform/If fields now reject at save instead of crashing at runtime