Skip to content

v0.22.0

Choose a tag to compare

@github-actions github-actions released this 08 Aug 04:57
· 114 commits to main since this release

[0.22.0] - 2026-08-07

Added

  • An install, not a build. Tagged releases now ship what the README used
    to ask you to compile:
    traza-<version>-{linux-x86_64,linux-aarch64,macos-aarch64}.tar.gz, each
    carrying the traza-server binary (musl-static on Linux — no libc to
    match) with the dashboard already built in ui/dist, alongside
    SHA256SUMS and GitHub build-provenance attestations
    (gh attestation verify). The same binaries become the container image,
    ghcr.io/toshish/traza, built FROM scratch — an engine with two
    dependencies does not need a distribution underneath it. A non-loopback
    bind still refuses to start without TRAZA_TOKENS, in the container as
    anywhere else. The tag also publishes to crates.io when the registry
    token is present.
  • The merge bar runs in public. ./ci.sh — the same script, no drift —
    now runs on Linux and macOS for every push and pull request, and the
    README carries the badge. Until this release the script had only ever
    gated one platform: the laptop it was written on.

Fixed

  • The dashboard now renders trace media wherever the trace actually put
    it, instead of only the one lucky shape it recognized before.
    Found via
    a production vision-review trace whose image showed as an empty frame: the
    conversation view understood only data:/http(s): strings in a part's
    data/uri/url, which missed most real emitters and — worse — poured
    every other locator into the transcript as text (a bare-base64 screenshot
    rendered as eight thousand lines of base64). The messages panel and the
    trace inspector's payload modal now recognize, with tests: bare-base64
    data lifted into a data: URI via the declared MIME type; Anthropic
    source.{base64,url,file} parts; Google GenAI typeless inline_data /
    file_data parts; OpenAI input_audio, image_url-object, and file
    parts; MCP-style tool-result content lists (screenshots included);
    width/height metadata; and parts whose bytes were never captured,
    which now say so with the emitter's unavailable_reason instead of
    presenting an empty frame that reads as a rendering bug.

  • Offloading no longer demotes media to a JSON dump. A
    gen_ai.{input,output}.messages attribute past --payload-threshold-bytes
    becomes a payload reference, and the old conversation view could only show
    it as preview text — "load full" printed the raw JSON, megabytes of base64
    included. The payload body is the original messages JSON, so the
    conversation view now fetches it back (automatically up to 4 MiB, when the
    turn nears the viewport; on demand above that, content-addressed and cached
    across screens) and renders the parsed turns — an offloaded text-to-speech
    span plays its audio again. The trace inspector's payload modal gained the
    same understanding: message payloads render as turns, media payloads as
    media, anything else as code, with the literal bytes one raw toggle away.

  • Every MCP tool now advertises ToolAnnotations. The catalog carried
    names, descriptions and schemas but no readOnlyHint, destructiveHint,
    idempotentHint or openWorldHint — and absent hints are not neutral. Each
    defaults to the pessimistic answer, so nine read-only tools were advertised
    as potentially destructive and open-world. A host that gates on that asks for
    approval on every call; one running non-interactively, with nobody to ask,
    cancels them, which is what a Codex run did. The nine readers now declare
    readOnlyHint: true with openWorldHint: false, and record_annotation
    declares an additive, non-idempotent write. Tool nature is a required
    argument of the builder rather than a step that can be skipped.

  • describe_store reports the server version. initialize carried it in
    serverInfo, but a host reads that once and need not pass it to the model,
    so an agent asked which Traza it was talking to correctly answered that it
    could not tell. The overview block — and the traza://store/overview
    resource that shares it — now names the version.

Changed

  • The measurement records moved out of the repository root into
    docs/benchmarks/
    , and are named for what they
    measure rather than shouted: BENCHMARKS.md is now
    docs/benchmarks/canonical-corpus.md, and INGEST-BENCHMARK.md,
    STORAGE-BENCHMARK.md, QUERY-BENCHMARK.md and
    INDEX-MEM-BENCHMARK.{md,json} are ingest.md, storage.md, query.md
    and index-memory.{md,json}. Six SHOUTING files at the root read as project
    furniture on the level of README and LICENSE; they are generated
    documentation, and they belong with the documentation that cites them.
    Every benchmark binary writes to the new path, and docs/README.md now
    indexes all five records rather than two. Entries below this one name the
    files as they were called at the time.

  • query-bench publishes its record only for the canonical configuration, the
    rule bench already held itself to. Now that the record is a published
    document, an experimental corpus or client count would otherwise have
    overwritten the committed numbers with an answer to a different question.

  • The advertised tool catalog is smaller than before the annotations were
    added
    : 14,895 → 14,296 bytes, with 628 bytes of new annotations inside
    that. The four accepted time formats were restated on ten properties while
    the initialize instructions already spell them out once per session; that
    repetition and some restated prose are gone. Every semantic warning stays —
    word-not-substring, status-is-not-an-attribute, a missing key is kept, and
    the ranking ceiling that sends a caller to slowest_spans.

  • The published history was rewritten once, before the repository went
    public
    , to remove an internal live-deployment analysis that had no
    business in a public tree. Tags v0.1.0 through v0.20.0 are
    bit-identical to the private originals; commits from the v0.21.0
    release onward carry new hashes. Stated here because a lineage that
    quietly changed under its tags would be worse than one that says so.