showcase · tier 4 · research
Release train
Tests, lint and audit run in parallel. Only if all three are green does a human sign the GO; then it holds for the window, ships, and verifies prod reports the new version.
The whole file
13 tasks · 10 waves · the plan falls out of the bindings, nothing is scheduled by hand.
t4-release-train.nika.yamlsource
nika: v1workflow: id: release-train description: "parallel gates → human GO → hold until the window → ship · verify · record"vars: version: type: string required: true description: "The version to ship (e.g. 1.4.0)" window: "2026-07-28T09:00:00Z"secrets: team_webhook: source: env key: TEAM_WEBHOOK_URL egress: # sanction the on_finally ping · the secret IS the URL - to: "nika:notify" host_from_self: truetasks: t0: invoke: tool: "nika:date" args: { op: now } # ── the gate wave · all three run in parallel ── tests: exec: command: ["cargo", "test", "--workspace", "--quiet"] capture: structured timeout: "15m" lint: exec: command: ["cargo", "clippy", "--workspace", "--all-targets", "--", "-D", "warnings"] capture: structured timeout: "10m" audit: exec: command: ["cargo", "audit"] capture: structured timeout: "5m" retry: max_attempts: 2 # advisory DB fetch can flake gates_green: with: all_green: ${{ tasks.tests.output.exit_code == 0 && tasks.lint.output.exit_code == 0 && tasks.audit.output.exit_code == 0 }} # three value edges · one boundary expression invoke: tool: "nika:assert" args: condition: "${{ with.all_green }}" message: "A release gate is RED: the train does not depart" gate_time: with: t0: ${{ tasks.t0.output }} after: gates_green: succeeded # state, no data · the timing is only worth taking on a green board invoke: tool: "nika:date" args: op: diff start: "${{ with.t0 }}" end: "now" unit: minutes # ── the human signs the departure ── conductor: with: gate_time: ${{ tasks.gate_time.output }} invoke: tool: "nika:prompt" args: message: "Gates GREEN in ${{ with.gate_time }} min. Ship ${{ vars.version }} in the ${{ vars.window }} window?" default: false approved: with: signed: ${{ tasks.conductor.output == true }} # the signature check crosses as ONE boundary expression invoke: tool: "nika:assert" args: condition: "${{ with.signed }}" message: "Departure not signed: train cancelled" # ── hold until the window · absolute time, not a sleep ── hold: after: approved: succeeded invoke: tool: "nika:wait" args: until: "${{ vars.window }}" timeout: "48h" ship: after: hold: succeeded exec: command: ["./scripts/release.sh", "${{ vars.version }}"] # argv: the interpolation cannot break out capture: structured timeout: "30m" verify: after: ship: succeeded invoke: tool: "nika:fetch" args: url: "https://api.example.com/v1/version" mode: jq jq: ".version" retry: max_attempts: 5 backoff_strategy: exponential backoff_ms: 5000 live: with: version_live: ${{ tasks.verify.output == vars.version }} # the whole check crosses as ONE boundary expression invoke: tool: "nika:assert" args: condition: "${{ with.version_live }}" message: "Prod does not report the shipped version: investigate before announcing" # the always-pattern · `after: {live: terminal}` admits every settled # state · this task runs whether `live` succeeded, failed, or was # cancelled by an upstream abort · a record that must land on EVERY # outcome is a terminal task, not a cleanup hook (03 §on_finally). record: after: live: terminal with: outcome: ${{ tasks.live.status }} # observe the departure verdict · same pass-set as the after edge invoke: tool: "nika:emit" args: event_type: "release.train.departed" payload: version: "${{ vars.version }}" status: "${{ with.outcome }}" on_finally: - invoke: tool: "nika:notify" args: channel: webhook target: "${{ secrets.team_webhook }}" message: "Release train ${{ vars.version }} · ${{ with.outcome }}" severity: infooutputs: shipped: ${{ tasks.verify.output }}nika inspect · engine 0.105.0 · vendored graph, never re-derived
13 declared edges · 10 waves · the plan falls out of the bindings