AGPL-3.0-or-later · forever.

showcase · tier 2 · content

Transcript show-notes

One bounded infer extracts chapters, quotes and summary as schema-typed data; jq and write render the page.

Episode recorded → notes publishable, for the price of exactly one model call. · conformance-gated in nika-spec ↗ · re-proven at every push

The whole file

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

t2-transcript-shownotes.nika.yamlsource
nika: v1workflow:  id: transcript-shownotes  description: "Raw transcript → typed show-notes (chapters · quotes · summary) · one bounded infer"model: ollama/llama3.2:3b # local · zero key · deliberately NOT the qwen3.5 convention: a thinking model can burn max_tokens in its think block before the JSON (engine#428) — schema showcases pick a non-thinking modelvars:  transcript: "./data/transcript.txt"permits:  exec: false  fs:    read: ["data/**"]    write: ["out/**"]  tools: ["nika:read", "nika:jq", "nika:write"]tasks:  raw:    invoke:      tool: "nika:read"      args: { path: "${{ vars.transcript }}" }  # ONE bounded model call · the schema is the contract, not a suggestion.  notes:    with:      raw: ${{ tasks.raw.output }}    infer:      prompt: |        Turn this transcript into show-notes. Ground every chapter title        and quote in the text — invent nothing.        Transcript ·        ${{ with.raw }}      max_tokens: 800      schema:        type: object        additionalProperties: false # a deterministic shape across providers (the checker's strictness hint)        required: [summary, chapters, quotes]        properties:          summary: { type: string }          chapters:            type: array            items:              type: object              additionalProperties: false              required: [title, gist]              properties:                title: { type: string }                gist: { type: string }          quotes:            type: array            items: { type: string }  # Typed JSON → markdown lines · mechanical, zero second model call.  sections:    with:      notes: ${{ tasks.notes.output }}    invoke:      tool: "nika:jq"      args:        input: "${{ with.notes }}"        expression: >-          {            chapters: (.chapters | map("- **\(.title)** — \(.gist)") | join("\n")),            quotes: (.quotes | map("> \(.)") | join("\n\n"))          }  page:    with:      notes_summary: ${{ tasks.notes.output.summary }}      sections_chapters: ${{ tasks.sections.output.chapters }}      sections_quotes: ${{ tasks.sections.output.quotes }}    invoke:      tool: "nika:write"      args:        path: out/show-notes.md        content: |          # Show notes          ${{ with.notes_summary }}          ## Chapters          ${{ with.sections_chapters }}          ## Pull quotes          ${{ with.sections_quotes }}          *Generated by [nika](https://nika.sh) · one bounded infer, typed output · the run's trace is the receipt.*outputs:  notes:    value: ${{ tasks.notes.output }}    description: "The typed show-notes · summary + chapters + quotes"

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

5 declared edges · 4 waves · the plan falls out of the bindings