AGPL-3.0-or-later · forever.

showcase · tier 1 · business

Price watch

Pulls one field from the shop API, compares it in CEL, pings your webhook. No model call anywhere.

Not everything needs an LLM. The engine alone is a robot you can already trust. · conformance-gated in nika-spec ↗ · re-proven at every push

The whole file

2 tasks · 2 waves · the plan falls out of the bindings, nothing is scheduled by hand.

t1-price-watch.nika.yamlsource
nika: v1workflow:  id: price-watch  description: "Watch a product price, ping me when it drops below my target"vars:  product_api: "https://api.shop.example.com/v1/products/macbook-air"  alert_below: 899secrets:  alerts_webhook:    source: env    key: ALERTS_WEBHOOK_URL    egress:                       # sanction the one send · the secret IS the URL      - to: "nika:notify"        host_from_self: truetasks:  check:    invoke:      tool: "nika:fetch"      args:        url: "${{ vars.product_api }}"        mode: jq        jq: "."    output:                           # named jq bindings over the raw response      price: ".price"      name: ".name"    on_error:      # Offline rehearsal · a sample ABOVE the target — the gate below      # stays closed and the dry run ends green with the alert skipped.      recover: { price: 949, name: "MacBook Air (offline sample)" }  alert:    with:      price: ${{ tasks.check.price }}     # value edges · the named bindings cross the boundary here      name: ${{ tasks.check.name }}    when: ${{ with.price < vars.alert_below }}    invoke:      tool: "nika:notify"      args:        channel: webhook        target: "${{ secrets.alerts_webhook }}"        message: "Price drop · ${{ with.name }} is now ${{ with.price }} (target ${{ vars.alert_below }})"        severity: infooutputs:  price: ${{ tasks.check.price }}

nika inspect · engine 0.105.0 · vendored graph, never re-derived

2 declared edges · 2 waves · the plan falls out of the bindings