<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://docs.tenzir.com/changelog</id>
    <title>Tenzir Changelog</title>
    <updated>2026-06-22T00:00:00.000Z</updated>
    <generator>Tenzir Changelog</generator>
    <author>
        <name>Tenzir</name>
        <uri>https://tenzir.com</uri>
    </author>
    <link rel="alternate" href="https://docs.tenzir.com/changelog"/>
    <link rel="self" href="https://docs.tenzir.com/changelog/feed.xml"/>
    <subtitle>Release notes across all Tenzir projects</subtitle>
    <icon>https://docs.tenzir.com/favicon.svg</icon>
    <entry>
        <title type="html"><![CDATA[Tenzir Platform v1.34.0]]></title>
        <id>https://docs.tenzir.com/changelog/platform/v1-34-0</id>
        <link href="https://docs.tenzir.com/changelog/platform/v1-34-0"/>
        <updated>2026-06-22T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release introduces OpenTelemetry tracing for the Platform frontend, giving operators end-to-end visibility into the requests its backend handles. It also adds dedicated columns for common fields like timestamps in the Stream view, overhauls login and session handling for better performance, and fixes a range of loading and navigation issues across the app.]]></summary>
        <content type="html"><![CDATA[<p>This release introduces OpenTelemetry tracing for the Platform frontend, giving operators end-to-end visibility into the requests its backend handles. It also adds dedicated columns for common fields like timestamps in the Stream view, overhauls login and session handling for better performance, and fixes a range of loading and navigation issues across the app.</p>

<h2>Features</h2>

<h3>OpenTelemetry tracing for the Platform frontend</h3>
<p><small>Jun 11, 2026 · <a href="https://github.com/avaq">@avaq</a>, <a href="https://github.com/jachris">@jachris</a></small></p>
<p>The Platform frontend can now export OpenTelemetry traces over OTLP, giving operators end-to-end visibility into the requests its backend handles.</p>
<p>Enable tracing and point it at your OTLP collector:</p>
<pre><code class="language-sh">PUBLIC_ENABLE_TRACING=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
</code></pre>
<p>Traces are sent to <code>${OTEL_EXPORTER_OTLP_ENDPOINT}/v1/traces</code> by default. Set <code>OTEL_EXPORTER_OTLP_TRACES_ENDPOINT</code> to override the traces endpoint directly.</p>
<p>When exporting to a collector that requires authentication, supply headers as comma-separated <code>key=value</code> pairs:</p>
<pre><code class="language-sh">OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer &#x3C;token>,x-tenant=acme"
</code></pre>

<h3>Common fields now appear as columns</h3>
<p><small>Jun 3, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We improved the Stream view by displaying fields that are shared across all schemas in dedicated columns. Timestamps are the first supported field, making it easier to scan and compare at a glance while still allowing you to expand rows to view the full event. When no shared timestamp field is available, Stream view continues to use the existing layout.</p>

<h2>Changes</h2>

<h3>Remove direct Websocket Gateway connection support</h3>
<p><small>Jun 22, 2026 · <a href="https://github.com/avaq">@avaq</a></small></p>
<p>The Platform configuration variable <code>PUBLIC_USE_INTERNAL_WS_PROXY</code> no longer
has any effect. The platform now behaves as though this setting is always
enabled: All connections to the Websocket Gateway are now proxied through the
App Server ("BFF").</p>
<p>The <code>PUBLIC_WEBSOCKET_GATEWAY_ENDPOINT</code> variable that used to configure the
direct Gateway connection is now used as a fallback for when the
<code>PRIVATE_WEBSOCKET_GATEWAY_ENDPOINT</code> isn't defined.</p>

<h3>Security and performance improvements</h3>
<p><small>Jun 4, 2026 · <a href="https://github.com/avaq">@avaq</a></small></p>
<p>We overhauled the frontend's login and session handling. Compared to the previous release:</p>
<ul>
<li>OIDC provider metadata is now discovered once at application startup instead of on every session refresh, shaving the round-trip cost off many requests.</li>
<li>User keys (access tokens) are now always cached server-side in the user's session, alleviating the cost of obtaining new access tokens for many requests.</li>
<li>Users of Platform deployments using header-based auth (like Google IAP) are now also granted a login session, allowing them to benefit from session based caches. This means that access tokens and user metadata is no longer fetched externally on every request, potentially saving multiple round trips worth of time with each request.</li>
<li>Session IDs no longer leak to JavaScript, and are solely kept inside secure HTTP cookies.</li>
</ul>

<h2>Bug Fixes</h2>

<h3>Fix the Update bar flickering after saving a pipeline</h3>
<p><small>Jun 19, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>Previously, after saving an edit on the pipeline detail page, the Cancel/Update bar would briefly reappear for about a second before disappearing again, even though nothing had changed. The bar now hides on a successful save and stays hidden until you make a new edit.</p>

<h3>Fix main menu links on some pages in the app</h3>
<p><small>Jun 18, 2026 · <a href="https://github.com/avaq">@avaq</a></small></p>
<p>The main menu links (Pipelines, Explorer, Contexts, and Library) now navigate correctly from all pages in the app. Previously, some pages would always link to the Pipelines page, even when clicking one of the other items.</p>

<h3>Library tab no longer hangs after interrupted load</h3>
<p><small>Jun 16, 2026 · <a href="https://github.com/Zedoraps">@Zedoraps</a>, <a href="https://github.com/claude">@claude</a></small></p>
<p>The Library tab now loads reliably after a previous attempt was
interrupted by a page reload or navigation. Previously the tab could
get stuck at "Loading…" indefinitely until the browser session was
cleared.</p>

<h3>Examples drawer loads on nodes with sparse package metadata</h3>
<p><small>Jun 16, 2026 · <a href="https://github.com/Zedoraps">@Zedoraps</a>, <a href="https://github.com/claude">@claude</a></small></p>
<p>The Explorer's Examples drawer no longer hangs at "Loading…" on Tenzir
Nodes that have installed packages whose examples are missing a <code>name</code>
or <code>description</code> (for instance several mappers under <code>microsoft/</code>,
<code>fortinet/</code>, <code>otel/</code>, and <code>zscaler/</code> in the Tenzir Library).</p>

<h3>Fix docs not loading</h3>
<p><small>Jun 16, 2026 · <a href="https://github.com/avaq">@avaq</a></small></p>
<p>The documentation panel should now show the documentation website again, instead of a white page.</p>

<h3>Fix stuck loading on pipeline details</h3>
<p><small>Jun 9, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We fixed an issue where the pipeline detail page could get stuck on loading skeletons when a node disconnected. The page now stays open and keeps showing the pipeline's definition along with a notice that the node is disconnected, and recovers automatically once the node reconnects.</p>

<h3>Delete dashboards when removing a static workspace</h3>
<p><small>Jun 4, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>Previously, when a workspace was removed from the static configuration file, dashboards that users had created within that workspace were left behind as orphaned records in the database. These could resurface if a new workspace later reused the same workspace ID. Removing a static workspace now also deletes these user-created dashboards.</p>

<h3>Explorer downloads on nodes using the legacy execution engine</h3>
<p><small>Jun 3, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/platform/pull/184">#184</a></small></p>
<p>Downloading results from the Explorer now works on Tenzir Nodes v6+ that are
configured to run pipelines on the legacy execution engine (<code>tenzir.neo: false</code>). Previously, preparing the download failed on such nodes because the
pipeline that uploads the results relied on functionality that is only
available in the new execution engine. The download pipeline now always runs
on the new execution engine, regardless of the node's configuration.</p>
]]></content>
        <category label="Tenzir Platform"/>
        <published>2026-06-22T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Ship v1.9.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-ship/v1-9-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-ship/v1-9-1"/>
        <updated>2026-06-22T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release improves changelog entry guidance so agents avoid premature pull request metadata and rely on automatic pull request inference until a number exists.]]></summary>
        <content type="html"><![CDATA[<p>This release improves changelog entry guidance so agents avoid premature pull request metadata and rely on automatic pull request inference until a number exists.</p>

<h2>Bug Fixes</h2>

<h3>PR metadata guidance for changelog entries</h3>
<p><small>Jun 22, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/ship/pull/31">#31</a></small></p>
<p>The changelog-entry skill no longer suggests passing <code>--pr</code> in the default <code>tenzir-ship add</code> command before a pull request number exists. Agents can rely on PR auto-inference once a pull request is open, or backfill <code>prs</code> after filing the PR.</p>
]]></content>
        <category label="Tenzir Ship"/>
        <published>2026-06-22T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Ship v1.9.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-ship/v1-9-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-ship/v1-9-0"/>
        <updated>2026-06-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release keeps package lockfiles in sync when release creation updates package manifest versions. It updates npm package-lock metadata and regenerates uv lockfile metadata so generated release commits stay consistent.]]></summary>
        <content type="html"><![CDATA[<p>This release keeps package lockfiles in sync when release creation updates package manifest versions. It updates npm package-lock metadata and regenerates uv lockfile metadata so generated release commits stay consistent.</p>

<h2>Features</h2>

<h3>Package lockfile version updates</h3>
<p><small>Jun 18, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/ship/pull/30">#30</a></small></p>
<p>The <code>release create</code> command now keeps supported package lockfiles in sync when it updates package manifest versions.</p>
<p>When a sibling <code>package-lock.json</code> exists, <code>tenzir-ship</code> updates the lockfile root package version metadata alongside <code>package.json</code>, including already-current manifests with stale lockfiles. When a sibling <code>uv.lock</code> exists next to <code>pyproject.toml</code>, <code>tenzir-ship</code> runs <code>uv lock</code> after updating the manifest so uv regenerates the lockfile metadata. This keeps generated release commits consistent without requiring every workflow caller to add package-manager-specific post-create hooks.</p>
]]></content>
        <category label="Tenzir Ship"/>
        <published>2026-06-18T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Test v1.10.3]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-test/v1-10-3</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-test/v1-10-3"/>
        <updated>2026-06-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes a reliability issue in parallel test suites where interdependent pipelines could start out of sync.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes a reliability issue in parallel test suites where interdependent pipelines could start out of sync.</p>

<h2>Bug Fixes</h2>

<h3>Synchronized parallel suite batches</h3>
<p><small>Jun 2, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>Parallel suites now start each reserved batch of tests together, making
publisher/subscriber and other interdependent pipeline suites more reliable.</p>
<p>Use the existing <code>suite.mode: parallel</code> configuration:</p>
<pre><code class="language-yaml">suite:
  name: pipeline-suite
  mode: parallel
  min_jobs: 2
</code></pre>
<p>When enough jobs are available for the whole suite, all suite members start
together. When the suite is larger than <code>--jobs</code>, the harness runs synchronized
batches instead.</p>
]]></content>
        <category label="Tenzir Test"/>
        <published>2026-06-15T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Ship v1.8.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-ship/v1-8-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-ship/v1-8-1"/>
        <updated>2026-06-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release keeps the unreleased changelog directory anchored after creating releases. It prevents changelog entries from long-lived branches from moving into already cut release notes during rebases or merges.]]></summary>
        <content type="html"><![CDATA[<p>This release keeps the unreleased changelog directory anchored after creating releases. It prevents changelog entries from long-lived branches from moving into already cut release notes during rebases or merges.</p>

<h2>Bug Fixes</h2>

<h3>Stable unreleased changelog directory after releases</h3>
<p><small>Jun 15, 2026 · <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/ship/pull/29">#29</a></small></p>
<p><code>release create</code> now keeps <code>unreleased/</code> anchored after consuming entries so Git no longer moves changelog entries from long-lived branches into the just-created release during rebases or merges.</p>
<p>This prevents entries for unreleased work from accidentally appearing in release notes that were already cut.</p>
]]></content>
        <category label="Tenzir Ship"/>
        <published>2026-06-15T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Skills v2.2.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-skills/v2-2-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-skills/v2-2-0"/>
        <updated>2026-06-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release adds generated reference skills for major security schema and event formats, including Microsoft Sentinel ASIM, Splunk CIM, Elastic ECS, ArcSight CEF, IBM QRadar LEEF, FortiSIEM EDM, and Google SecOps UDM. It also expands the Tenzir design system skill with machine-readable tokens and per-tool styling guidance.]]></summary>
        <content type="html"><![CDATA[<p>This release adds generated reference skills for major security schema and event formats, including Microsoft Sentinel ASIM, Splunk CIM, Elastic ECS, ArcSight CEF, IBM QRadar LEEF, FortiSIEM EDM, and Google SecOps UDM. It also expands the Tenzir design system skill with machine-readable tokens and per-tool styling guidance.</p>

<h2>Features</h2>

<h3>ArcSight CEF skill</h3>
<p><small>Jun 10, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/skills/pull/23">#23</a></small></p>
<p>Added <code>tenzir-cef</code>, a generated ArcSight CEF (Common Event Format) reference skill for generating, parsing, and mapping CEF events, bundled with the ArcSight ESM event schema behind the format.</p>
<p>The skill exposes all 174 predefined extension keys from the OpenText extension dictionary as YAML — exact key spelling, expanded full name, data type, length, producer/consumer audience, and the CEF specification version that introduced each key — alongside the full ESM event schema: 479 data fields across 18 groups with labels, script aliases, types, and turbo levels. Extension keys whose full name resolves to an ESM script alias are crosswalked to their schema groups. Markdown guidance covers the CEF header, severity, character escaping, special mappings, user-defined extensions, and date formats. Upstream quirks, such as the duplicated <code>dmac</code> row and mid-word line-wrap artifacts in key names, are normalized and documented in the source notes.</p>

<h3>IBM QRadar LEEF skill</h3>
<p><small>Jun 10, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/skills/pull/20">#20</a></small></p>
<p>Added <code>tenzir-leef</code>, a generated IBM QRadar LEEF (Log Event Extended Format) reference skill for generating, parsing, and mapping LEEF 2.0 events.</p>
<p>The skill exposes all 45 predefined event attributes as YAML — exact key spelling, value type, normalization behavior, attribute limits, and reserved status — plus Markdown guidance for the syslog and LEEF headers, delimiter rules, custom event keys, and <code>devTime</code>/<code>devTimeFormat</code> timestamp patterns. Spec quirks published by IBM, such as the <code>identSecondlp</code> typo, are preserved verbatim and annotated.</p>

<h3>FortiSIEM Event Data Model skill</h3>
<p><small>Jun 10, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/skills/pull/21">#21</a></small></p>
<p>Added <code>tenzir-edm</code>, a generated FortiSIEM Event Data Model reference skill for mapping events into Fortinet's normalized event attributes.</p>
<p>The skill covers all 21 data models of the FortiSIEM 7.5.0 Event Data Model documentation, exposing event attributes with types, display names, descriptions, and cross-model usage as YAML, plus Markdown copies of the upstream Fortinet pages for audit.</p>

<h3>Elastic Common Schema skill</h3>
<p><small>Jun 7, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>Added <code>tenzir-ecs</code>, a generated Elastic Common Schema reference skill for mapping logs and security telemetry into ECS.</p>
<p>The skill exposes ECS fields, fieldsets, categorization values, field reuse metadata, and ECS/OpenTelemetry relations as YAML, with curated upstream Markdown guidance for categorization, network mapping, custom fields, cloud and service context, threat indicators, and user modeling.</p>

<h3>Splunk CIM skill</h3>
<p><small>Jun 6, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/skills/pull/15">#15</a></small></p>
<p>Added <code>tenzir-cim</code>, a generated Splunk Common Information Model reference skill for mapping security telemetry to CIM.</p>
<p>The generator takes an unpacked <code>Splunk_SA_CIM</code> app directory as input and emits agent-native YAML catalogs for CIM data models, datasets, effective fields, constraints, calculated fields, and lookup-backed values, translations, and enrichments. The generated skill also bundles core Splunk CIM 8.5 documentation as reference-only prose while keeping the app-derived YAML authoritative.</p>

<h3>Microsoft Sentinel ASIM skill</h3>
<p><small>Jun 4, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/skills/pull/11">#11</a>, <a href="https://github.com/tenzir/skills/pull/17">#17</a></small></p>
<p>Added <code>tenzir-asim</code>, a Microsoft Sentinel ASIM reference skill for mapping security telemetry to ASIM.</p>
<p>The generated reference currently covers 12 event schemas, 1 entity schema, 539 distinct fields, 1,426 schema field records, and 73 alias records from Microsoft Defender Docs. It now emits agent-native YAML catalogs, schema files, field files, alias data, and guidance data so agents can choose target ASIM schemas and map source telemetry with less context-window overhead.</p>

<h2>Changes</h2>

<h3>Multi-tool design system skill with machine-readable tokens</h3>
<p><small>Jun 10, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/skills/pull/22">#22</a></small></p>
<p>The <code>tenzir-design-system</code> skill is now the canonical home of the Tenzir design system and supports many consumers beyond Platform CSS: plain CSS, Tailwind, Quarto documents, slide decks, and Mermaid/Graphviz diagrams.</p>
<p>Token values now live in machine-readable YAML: <code>data/brand.yml</code> follows Quarto's brand.yml schema and can be consumed directly via <code>brand: data/brand.yml</code>, while <code>data/tokens.yml</code> carries the extended tokens (spacing, radius, type scale, shadows, motion, z-index, breakpoints, and a dark-mode mapping). Markdown references explain how to choose tokens; per-tool guides under <code>references/tools/</code> provide ready-to-use CSS custom properties, Tailwind v4/v3 configuration, a shadcn/ui theme, and diagram/slide styling.</p>

<h3>Tenzir UDM skill name</h3>
<p><small>Jun 7, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/skills/pull/18">#18</a></small></p>
<p>The Google UDM skill is now installed and referenced as <code>tenzir-udm</code>.</p>
<p>Use the new skill name when installing it directly:</p>
<pre><code class="language-sh">npx skills add tenzir/skills@tenzir-udm
</code></pre>

<h3>Google UDM record YAML reference</h3>
<p><small>Jun 7, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/skills/pull/16">#16</a></small></p>
<p>The Google UDM skill now exposes record definitions as YAML leaves rather than Markdown message pages. Record YAML uses data-centric type shapes such as <code>list&#x3C;T></code>, <code>optional&#x3C;T></code>, <code>map&#x3C;K, V></code>, <code>variant</code>, and field <code>union</code>s, making event and entity fields easier for agents to scan when mapping logs into UDM.</p>

<h3>Google UDM entity ingestion guidance</h3>
<p><small>Jun 6, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/skills/pull/14">#14</a></small></p>
<p>The Google UDM skill now clarifies that Entity Type Guidance values such as <code>USER</code> or <code>ASSET</code> belong to the Entity object's <code>metadata.entity_type</code> / <code>metadata.entityType</code>, while <code>entities.import</code> uses a separate <code>inlineSource.logType</code> for the context source, such as <code>AZURE_AD_CONTEXT</code>.</p>
]]></content>
        <category label="Tenzir Skills"/>
        <published>2026-06-15T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v6.2.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v6-2-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v6-2-0"/>
        <updated>2026-06-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release adds Amazon Kinesis operators, regex Kafka topic selection, Google SecOps Chronicle import support, and inline drop_null_fields cleanup for cloud and streaming pipelines. It also improves HTTP server bind failures, package field defaults, and timeout flushing for OpenSearch and CloudWatch sinks.]]></summary>
        <content type="html"><![CDATA[<p>This release adds Amazon Kinesis operators, regex Kafka topic selection, Google SecOps Chronicle import support, and inline drop_null_fields cleanup for cloud and streaming pipelines. It also improves HTTP server bind failures, package field defaults, and timeout flushing for OpenSearch and CloudWatch sinks.</p>

<h2>Features</h2>

<h3>Selector defaults for UDO field parameters</h3>
<p><small>Jun 12, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/6352">#6352</a></small></p>
<p>Field-typed parameters of user-defined operators now accept selectors as defaults in the TQL frontmatter, such as <code>this</code>, <code>this.name</code>, or <code>foo.bar</code>. Previously, the only allowed default for a <code>field</code> parameter was <code>null</code>.</p>
<p>For example, this operator wraps a field into a record and operates on the entire event when no argument is given:</p>
<pre><code class="language-tql">---
args:
  named:
    - name: field
      type: field
      default: this
---
this = {wrapped: $field}
</code></pre>
<p>Calling the operator without arguments wraps the whole event, while passing <code>field=name</code> wraps just that field. This makes it easy to write mapping operators that work on the full event by default but can be scoped to a subrecord on demand.</p>

<h3>Regular expression topic selection for from_kafka</h3>
<p><small>Jun 8, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6262">#6262</a></small></p>
<p>The <code>from_kafka</code> operator can now consume from topics selected by a regular
expression when the topic argument starts with <code>^</code>:</p>
<pre><code class="language-tql">from_kafka "^tenant-.*\\.alerts$", offset="beginning"
</code></pre>
<p>This lets one pipeline consume matching Kafka topics without listing each topic
separately.</p>
<p>As part of this change, <code>from_kafka</code> now consumes all topics—exact and
regex—through Kafka's consumer group subscription. This has two visible
effects. First, pipelines that share a <code>group.id</code> (default: <code>tenzir</code>) now split
the partitions of a topic among themselves instead of each receiving every
message; give each pipeline its own <code>group.id</code> to keep full copies. Second,
partition assignments now follow group rebalances, so they may shift when
pipelines with the same <code>group.id</code> start or stop. The <code>exit</code> option is not
available for regex topics, because a regex subscription has no bounded set of
partitions to reach the end of.</p>

<h3>`drop_null_fields` function</h3>
<p><small>Jun 5, 2026 · <a href="https://github.com/zedoraps">@zedoraps</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/6261">#6261</a></small></p>
<p>The new <code>drop_null_fields</code> function strips fields whose value is <code>null</code> from a
record, mirroring the existing <code>drop_null_fields</code> operator. This lets you clean
optional fields inline in expressions, for example
<code>from_http "...", body=drop_null_fields({license: $license, version: 1, mapping: $mapping})</code>.</p>

<h3>Amazon Kinesis operators</h3>
<p><small>May 15, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6188">#6188</a></small></p>
<p>Tenzir can now read from and write to Amazon Kinesis data streams with the <code>from_amazon_kinesis</code> and <code>to_amazon_kinesis</code> operators:</p>
<pre><code class="language-tql">from_amazon_kinesis "telemetry", start="trim_horizon"
this = string(message).parse_json()
</code></pre>
<pre><code class="language-tql">read_ndjson
// ... transform events ...
to_amazon_kinesis "telemetry", partition_key=src_ip
</code></pre>
<p>The operators support existing AWS IAM configuration and endpoint overrides for local testing environments such as LocalStack.</p>

<h2>Changes</h2>

<h3>Google SecOps Chronicle import API</h3>
<p><small>Jun 3, 2026 · <a href="https://github.com/raxyte">@raxyte</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6216">#6216</a></small></p>
<p>The <code>to_google_secops</code> operator now uses the Chronicle <code>logs.import</code>,
<code>events.import</code>, and <code>entities.import</code> APIs instead of the legacy unstructured
ingestion API.</p>
<p>The operator now targets a SecOps instance with <code>project</code>, <code>region</code>, and
<code>instance</code>, authenticates with Google Cloud OAuth2 credentials, and supports raw
log ingestion with <code>mode="raw_log"</code>, UDM event ingestion with <code>mode="udm_event"</code>, and
entity ingestion with <code>mode="udm_entity"</code>.</p>

<h2>Bug Fixes</h2>

<h3>Timeout flushing for OpenSearch and CloudWatch sinks</h3>
<p><small>Jun 12, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6188">#6188</a></small></p>
<p>The <code>to_opensearch</code> and <code>to_amazon_cloudwatch</code> sinks now reliably flush partial batches after their configured timeout while the pipeline continues to run.</p>
<p>Previously, concurrent wakeups could race with batch deadline updates, which could cause timeout-based flushes or CloudWatch send-completion handling to be missed.</p>

<h3>Parallel signed AWS HTTP requests</h3>
<p><small>Jun 12, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6188">#6188</a></small></p>
<p>AWS-backed operators that issue parallel signed HTTP requests now send concurrent requests over separate pooled connections.</p>
<p>Previously, HTTP/1.1 request pipelining could serialize parallel requests behind a single connection, so <code>parallel</code> settings for sinks such as <code>to_amazon_cloudwatch</code> did not provide the intended concurrency.</p>

<h3>Filters escaping parallel subpipelines</h3>
<p><small>Jun 10, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/6270">#6270</a></small></p>
<p>Filters inside a <code>parallel { … }</code> subpipeline no longer escape past the
<code>parallel</code> operator during optimization.</p>
<p>Previously, a filter such as the <code>where</code> below was lifted out of the
subpipeline and applied before <code>parallel</code>:</p>
<pre><code class="language-tql">parallel { where x > 1 | ... }
</code></pre>
<p>The filter now stays inside the subpipeline, where it belongs, so it runs
distributed across the parallel jobs. Filters from downstream of <code>parallel</code> are
still pushed into the subpipeline as before.</p>

<h3>HTTP server operators no longer crash the node on bind failure</h3>
<p><small>Jun 9, 2026 · <a href="https://github.com/Zedoraps">@Zedoraps</a> · <a href="https://github.com/tenzir/tenzir/pull/6267">#6267</a></small></p>
<p>The <code>accept_http</code>, <code>accept_opensearch</code>, and <code>serve_http</code> operators no longer
abort the node when they fail to bind their endpoint. Starting a second
pipeline on a port that is already in use—or restarting one before the
previous instance has released its socket—previously crashed the entire node
process. Now the operator emits a regular diagnostic:</p>
<pre><code class="language-text">error: failed to start HTTP server: failed to bind to async server socket:
0.0.0.0:8774: Address already in use
</code></pre>
<p>The pipeline that hit the conflict exits with an error while every other
pipeline running on the node keeps going.</p>

<h3>Nested assignment through package UDO field parameters</h3>
<p><small>Jun 8, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/jachris">@jachris</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6264">#6264</a></small></p>
<p>Package UDO field parameters now support assignment through field accesses. This lets package operators write to nested fields of a field argument using dot syntax, string-literal bracket syntax, or dynamic index expressions.</p>
<p>For example, this package UDO body is now valid:</p>
<pre><code class="language-tql">$field.subfield = $value
$field["quoted-field"] = $value
$field[$key] = $value
</code></pre>
<p>This is useful for mapping operators that accept an <code>event=</code> target and need to keep temporary state under that target instead of creating top-level scratch fields.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-06-12T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Ship v1.8.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-ship/v1-8-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-ship/v1-8-0"/>
        <updated>2026-06-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release makes stable promotion from a release candidate include changelog entries added after the last candidate, so the final manifest and notes no longer miss late fixes. It also improves changelog automation guidance and gives the validation status check a clearer name.]]></summary>
        <content type="html"><![CDATA[<p>This release makes stable promotion from a release candidate include changelog entries added after the last candidate, so the final manifest and notes no longer miss late fixes. It also improves changelog automation guidance and gives the validation status check a clearer name.</p>

<h2>Changes</h2>

<h3>Readable changelog validation check name</h3>
<p><small>Jun 5, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/ship/pull/27">#27</a></small></p>
<p>The changelog validation workflow now appears as <code>Validate changelog</code> in GitHub status checks instead of the raw job id <code>validate</code>, making required branch checks easier to identify.</p>

<h3>Changelog entry history guidance</h3>
<p><small>Jun 5, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The bundled agent skill now tells release automation to preserve published changelog history while still allowing clearly related unreleased entries to be merged before release.</p>
<p>Historical release notes, manifests, and released entry files are treated as immutable records, with edits reserved for explicit severe publication fixes. For unreleased work, agents now check whether a related entry already exists and merge it instead of creating duplicate changelog entries, reconciling the title, type, and description while appending distinct authors, pull request numbers, and components.</p>
<p>The merge guidance now requires a clear relationship based on the user-facing outcome, not just nearby implementation work, shared files, authors, or PR timing. Ambiguous changes should get a separate entry, and unrelated unreleased entries must remain untouched.</p>

<h2>Bug Fixes</h2>

<h3>RC promotion includes entries added after the last candidate</h3>
<p><small>Jun 10, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/ship/pull/28">#28</a></small></p>
<p>Promoting a release candidate to a stable release now folds in changelog entries added to <code>unreleased/</code> after the last candidate snapshot. The folded entries appear in the release manifest and notes, and are consumed from the unreleased queue. Previously they were silently left behind and missing from the stable release notes. The confirmation table now marks entries carried over from the candidate with a dim bullet and newly folded entries with a plus sign.</p>
]]></content>
        <category label="Tenzir Ship"/>
        <published>2026-06-10T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v6.1.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v6-1-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v6-1-0"/>
        <updated>2026-06-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release introduces the `window` operator for event-time windowing, which groups streaming events into configurable time windows driven by event timestamps rather than wall-clock time. It also adds several new operators — `ai::prompt` for LLM integration, `from_microsoft_sql` for SQL Server reads, and `to_prometheus` for Prometheus Remote Write — along with Crypto-PAn decryption and multiple reliability fixes.]]></summary>
        <content type="html"><![CDATA[<p>This release introduces the <code>window</code> operator for event-time windowing, which groups streaming events into configurable time windows driven by event timestamps rather than wall-clock time. It also adds several new operators — <code>ai::prompt</code> for LLM integration, <code>from_microsoft_sql</code> for SQL Server reads, and <code>to_prometheus</code> for Prometheus Remote Write — along with Crypto-PAn decryption and multiple reliability fixes.</p>

<h2>Features</h2>

<h3>Crypto-PAn decryption</h3>
<p><small>Jun 6, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6259">#6259</a></small></p>
<p>The new <code>decrypt_cryptopan</code> function decrypts IP addresses that were encrypted
with <code>encrypt_cryptopan</code> and the same seed. The function can also force the
Crypto-PAn domain with <code>family="ipv4"</code> or <code>family="ipv6"</code> when decrypting an
ambiguous ciphertext.</p>

<h3>Event-time windowing with the window operator</h3>
<p><small>Jun 4, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/6253">#6253</a></small></p>
<p>The new <code>window</code> operator groups streaming events into event-time windows and
runs a subpipeline for each window:</p>
<pre><code class="language-tql">window size=10min, every=1min, on=ts {
  summarize failures=count()
  start = $window.start
  end = $window.end
}
</code></pre>
<p>Unlike <code>every</code>, which reruns a subpipeline on a wall-clock schedule, <code>window</code>
operates on <strong>event time</strong>: it assigns each event to windows by the timestamp
that <code>on</code> evaluates to, and its internal clock is driven entirely by the
timestamps of the incoming events. Windows are aligned to the Unix epoch and are
either tumbling (omit <code>every</code>) or overlapping/hopping (<code>every &#x3C; size</code>).</p>
<p><code>tolerance</code> sets how much out-of-order lag the clock waits for before a window
closes; events that arrive after their window closed are dropped with a warning.</p>
<p><code>idle_timeout</code> makes <code>window</code> also well suited to low-volume streams: a window
is emitted once it has been inactive for the given duration, so results arrive
promptly even when the next event is far off, instead of waiting for it or for
the end of the input.</p>
<p>Each window's <code>$window.start</code> and <code>$window.end</code> are available inside the
subpipeline, which may also end in a sink.</p>

<h3>Chunk stream operators</h3>
<p><small>Jun 1, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6243">#6243</a></small></p>
<p>TQL now includes <code>read_chunks</code> and <code>write_chunks</code> for converting between byte streams and records with a <code>bytes</code> field.</p>
<p>For example, you can capture arbitrary output as records and turn it back into a byte stream later:</p>
<pre><code class="language-tql">from {line: "hello"}, {line: "world"}
write_lines
read_chunks
write_chunks
read_lines
</code></pre>
<p>This makes it easier to inspect, buffer, transform, and roundtrip chunked byte streams inside a pipeline.</p>

<h3>Add the `ai::prompt` operator</h3>
<p><small>May 28, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6260">#6260</a></small></p>
<p>The new <code>ai::prompt</code> operator sends each input event to an OpenAI-compatible
Responses API endpoint and writes a result record back into the event:</p>
<pre><code class="language-tql">from {message: "summarize this"}
ai::prompt model="gpt-4.1-mini"
</code></pre>
<p>By default the operator serializes <code>this</code> as compact JSON, writes the generated
text plus model, token usage, and latency metadata to <code>ai.prompt</code>, and uses the
local Ollama endpoint at
<code>http://127.0.0.1:11434/v1</code>. Override <code>endpoint</code> to use another
OpenAI-compatible service.</p>

<h3>Microsoft SQL Server source operator</h3>
<p><small>May 26, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6221">#6221</a></small></p>
<p>The new <code>from_microsoft_sql</code> operator reads rows from Microsoft SQL Server:</p>
<pre><code class="language-tql">from_microsoft_sql table="dbo.users",
                   host="sql.example.net",
                   user="tenzir",
                   password=secret("mssql-password"),
                   database="telemetry"
</code></pre>
<p>It supports table reads, custom <code>sql</code> or <code>query</code> statements, schema inspection with <code>show="tables"</code> and <code>show="columns"</code>, SQL authentication, secret-backed passwords, TLS, and live polling via integer tracking columns. Result decoding covers SQL Server scalar values including integers, booleans, floats, decimals, money values, strings, binary data, <code>uniqueidentifier</code>, date/time values, XML, and JSON stored as text.</p>

<h3>Prometheus Remote Write sink</h3>
<p><small>May 15, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6189">#6189</a></small></p>
<p>The new <code>to_prometheus</code> operator sends metric events to Prometheus Remote Write receivers.</p>
<p>For example:</p>
<pre><code class="language-tql">from {
  metric: "http_requests_total",
  value: 42,
  timestamp: 2026-05-15T10:00:00Z,
  labels: {method: "GET", status: 200},
}
to_prometheus "https://prometheus.example/api/v1/write"
</code></pre>
<p>The operator supports Prometheus Remote Write v1 by default and can send Remote Write v2 payloads with <code>protobuf_message="io.prometheus.write.v2.Request"</code>.</p>

<h2>Changes</h2>

<h3>Null list spread warnings</h3>
<p><small>Jun 6, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6258">#6258</a></small></p>
<p>Spreading <code>null</code> into a list no longer emits a warning. This makes optional list-building expressions work without an explicit <code>else []</code> fallback:</p>
<pre><code class="language-tql">from {xs: null}
items = [1, ...xs, 2]
</code></pre>
<p>The expression produces <code>[1, 2]</code>, and <code>concatenate</code>, <code>append</code>, and <code>prepend</code> follow the same warning-free behavior for <code>null</code> list inputs.</p>

<h2>Bug Fixes</h2>

<h3>Platform connection during node startup</h3>
<p><small>Jun 9, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6268">#6268</a></small></p>
<p>Tenzir Nodes now connect to the Tenzir Platform during startup before waiting
for the local index to become available. Previously, Platform connectivity
could be delayed while the index was still initializing.</p>

<h3>Fix `where` substring filters dropping all events from `subscribe`</h3>
<p><small>Jun 9, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/6265">#6265</a></small></p>
<p>A <code>where</code> filter that checks for a substring with the literal on the left, such
as <code>where "TRAFFIC" in log</code>, incorrectly removed every event when reading from
<code>subscribe</code>. Such filters now match correctly again.</p>

<h3>Crash when passing a non-lambda to map or where</h3>
<p><small>Jun 5, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/6256">#6256</a></small></p>
<p>Calling the <code>map</code> or <code>where</code> list functions with a non-lambda argument now
fails with a clear <code>expected a lambda</code> diagnostic instead of aborting the
pipeline with an internal error.</p>
<p>For example, the following pipeline previously crashed and now reports a
proper error:</p>
<pre><code class="language-tql">from {xs: [1, 2, 3]}
xs = xs.map(null)
</code></pre>

<h3>Rebuild memory limits</h3>
<p><small>Jun 2, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6216">#6216</a></small></p>
<p>Rebuilds now limit how much partition data they load into memory at once.
This reduces the risk that automatic rebuilds or <code>tenzir-ctl rebuild start</code>
cause the node to run out of memory when many partitions are selected.</p>
<p>When memory is scarce, rebuilds load fewer partitions in one batch and retry the
remaining partitions later instead of materializing the full selected input set
up front.</p>

<h3>Static pipeline startup validation</h3>
<p><small>Jun 2, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6248">#6248</a></small></p>
<p>Tenzir now validates all configured and packaged pipelines before starting any of them during node startup. Previously, a deployment with multiple configured pipelines could start some valid pipelines and only then abort after discovering that a later pipeline was invalid.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-06-09T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Skills v2.1.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-skills/v2-1-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-skills/v2-1-0"/>
        <updated>2026-06-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release improves agent guidance for package lifecycle management and Google SecOps UDM workflows. It helps agents choose the right package surfaces while making UDM field name differences explicit for mapping and detection use cases.]]></summary>
        <content type="html"><![CDATA[<p>This release improves agent guidance for package lifecycle management and Google SecOps UDM workflows. It helps agents choose the right package surfaces while making UDM field name differences explicit for mapping and detection use cases.</p>

<h2>Features</h2>

<h3>UDM field name forms for mapping and YARA-L</h3>
<p><small>Jun 4, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/skills/pull/12">#12</a></small></p>
<p>The <code>tenzir-google-udm</code> skill now shows both UDM field spellings when they differ, so mapping and detection workflows can use the same reference.</p>
<p>For example, generated field headings now show <code>event_type</code> / <code>eventType</code> and <code>security_result</code> / <code>securityResult</code>. Use the right side when mapping logs into UDM event or entity objects for Google SecOps UDM API ingestion; use the left side in YARA-L, Detect Engine, CBN, and other dotted field-path contexts.</p>

<h2>Changes</h2>

<h3>Package lifecycle management focus</h3>
<p><small>Jun 5, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/skills/pull/13">#13</a></small></p>
<p>The <code>tenzir-manage-packages</code> skill now focuses on package lifecycle management instead of package content development.</p>
<p>It routes agents through package surfaces such as manifests, UDO files, pipelines, examples, tests, changelog entries, and publishing while leaving operator implementation details to the relevant docs or specialized skills.</p>
]]></content>
        <category label="Tenzir Skills"/>
        <published>2026-06-05T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Skills v2.0.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-skills/v2-0-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-skills/v2-0-0"/>
        <updated>2026-06-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release consolidates Tenzir package development into the new tenzir-create-package skill, replacing the older parser and OCSF mapping workflows with one broader package creation workflow. It also adds a generated Google SecOps UDM skill for schema reference and normalization guidance.]]></summary>
        <content type="html"><![CDATA[<p>This release consolidates Tenzir package development into the new tenzir-create-package skill, replacing the older parser and OCSF mapping workflows with one broader package creation workflow. It also adds a generated Google SecOps UDM skill for schema reference and normalization guidance.</p>

<h2>Breaking Changes</h2>

<h3>Consolidated Tenzir package creation skill</h3>
<p><small>May 27, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The package creation workflow is now centered on <code>tenzir-create-package</code>, a single skill for building library-quality Tenzir packages with UDOs, tests, examples, disabled-by-default pipelines, inputs, contexts, and optional OCSF mappings.</p>
<p>Before:</p>
<pre><code class="language-sh">npx skills add tenzir/skills@tenzir-create-parser-package
npx skills add tenzir/skills@tenzir-create-ocsf-mapping
</code></pre>
<p>After:</p>
<pre><code class="language-sh">npx skills add tenzir/skills@tenzir-create-package
</code></pre>
<p>Use the new skill for parser package work, OCSF mapping work, and broader package development.</p>

<h2>Features</h2>

<h3>Add Google UDM skill</h3>
<p><small>Jun 3, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>Added <code>tenzir-google-udm</code>, a generated Google SecOps UDM schema and
normalization guidance skill derived from the canonical <code>googleapis/googleapis</code>
UDM and Entity protocol buffers plus targeted Google SecOps usage guidance.</p>
]]></content>
        <category label="Tenzir Skills"/>
        <published>2026-06-04T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Platform v1.33.1]]></title>
        <id>https://docs.tenzir.com/changelog/platform/v1-33-1</id>
        <link href="https://docs.tenzir.com/changelog/platform/v1-33-1"/>
        <updated>2026-06-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes a regression where users authenticating via the `PRIVATE_JWT_FROM_HEADER` option were redirected to the login page when opening a workspace. Header-based authentication now loads workspaces correctly again.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes a regression where users authenticating via the <code>PRIVATE_JWT_FROM_HEADER</code> option were redirected to the login page when opening a workspace. Header-based authentication now loads workspaces correctly again.</p>

<h2>Bug Fixes</h2>

<h3>Fix being redirected to the login page when using header-based authentication</h3>
<p><small>Jun 2, 2026 · <a href="https://github.com/lava">@lava</a></small></p>
<p>We fixed a regression introduced in v1.33.0 where users authenticating via the
<code>PRIVATE_JWT_FROM_HEADER</code> option were redirected to the login page (showing a
"Sign In" button) when opening a workspace, even though a valid JWT was supplied
in the configured header.</p>
<p>The workspace loader looked for the ID token in the session data, which is empty
for header-based authentication. It now reads the token from the configured
header, which is the authoritative source in that mode, so workspaces load
correctly again.</p>
]]></content>
        <category label="Tenzir Platform"/>
        <published>2026-06-02T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v6.0.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v6-0-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v6-0-0"/>
        <updated>2026-06-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Tenzir v6 ships with a rewritten execution engine that unlocks faster, more capable, and more scalable pipelines. Refer to the migration guide at https://docs.tenzir.com/guides/tenzir-v6-migration before upgrading.]]></summary>
        <content type="html"><![CDATA[<p>Tenzir v6 ships with a rewritten execution engine that unlocks faster, more capable, and more scalable pipelines. Refer to the migration guide at https://docs.tenzir.com/guides/tenzir-v6-migration before upgrading.</p>

<h2>Breaking Changes</h2>

<h3>TQL type syntax for package UDOs</h3>
<p><small>May 31, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6242">#6242</a></small></p>
<p>Package UDO argument types now use TQL type names, such as <code>int</code>, <code>uint</code>, and
<code>float</code>, instead of legacy names such as <code>int64</code>, <code>uint64</code>, and <code>double</code>. List
types use TQL syntax, for example <code>type: "[int]"</code> in YAML.</p>
<p>For example, a package operator argument like this now materializes <code>$limit</code>
as <code>int64</code>:</p>
<pre><code class="language-yaml">args:
  named:
    - name: limit
      type: int
      default: 1000
</code></pre>

<h3>Renamed `from_gcs` to `from_google_cloud_storage`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5766">#5766</a></small></p>
<p>The <code>from_gcs</code> operator has been renamed to <code>from_google_cloud_storage</code> so
that its name matches the new <code>to_google_cloud_storage</code> writer:</p>
<pre><code class="language-tql">// Before:
from_gcs "gs://my-bucket/data/**.json"

// After:
from_google_cloud_storage "gs://my-bucket/data/**.json"
</code></pre>
<p>Update test suites that reference <code>from_gcs</code> in <code>requires.operators</code>
accordingly.</p>

<h3>`to_kafka` defaults to NDJSON-encoded messages</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/5742">#5742</a></small></p>
<p>The default <code>message</code> expression of the <code>to_kafka</code> operator is now
<code>this.print_ndjson()</code> instead of <code>this.print_json()</code>. Kafka messages are
single-line records by default, so each event is now emitted as a single
NDJSON line:</p>
<pre><code class="language-json">{"timestamp":"2024-03-15T10:30:00.000000","source_ip":"192.168.1.100","alert_type":"brute_force"}
</code></pre>
<p>instead of pretty-printed multi-line JSON.</p>
<p>To restore the previous behavior, pass <code>message=this.print_json()</code>
explicitly.</p>

<h3>`yara` requires finite input</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6035">#6035</a></small></p>
<p>The <code>yara</code> operator no longer accepts the <code>blockwise</code> argument. Instead, it
buffers the entire input as one contiguous byte sequence and runs the YARA
scan when the input ends. Matches can therefore span chunk boundaries, but
<code>yara</code> is now only suitable for finite byte streams. Don't use it on
never-ending inputs.</p>
<p>The <code>rule</code> argument now also accepts a single string in addition to a list
of strings:</p>
<pre><code class="language-tql">from_file "evil.exe", mmap=true {
  yara "rule.yara"
}
</code></pre>
<p>Removed:</p>
<pre><code class="language-tql">yara ["rule.yara"], blockwise=true
</code></pre>

<h3>Removed `real_time` argument from `measure`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/5880">#5880</a></small></p>
<p>The <code>measure</code> operator no longer accepts the <code>real_time</code> argument. The
operator's emission cadence is now governed entirely by the executor's
backpressure, so the option no longer has a meaningful effect.</p>
<p>Remove <code>real_time=true</code> or <code>real_time=false</code> from your pipelines:</p>
<pre><code class="language-tql">// Before:
measure real_time=true

// After:
measure
</code></pre>

<h3>`$file` let-binding for filesystem readers</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/6001">#6001</a></small></p>
<p>The filesystem and cloud object reader operators (<code>from_file</code>, <code>from_s3</code>,
<code>from_azure_blob_storage</code>, <code>from_google_cloud_storage</code>) no longer accept the
<code>path_field</code> option. Instead, the parsing subpipeline now has access to a
<code>$file</code> let-binding describing the source file:</p>
<p>| Field   | Type     | Description                              |
| :------ | :------- | :--------------------------------------- |
| <code>path</code>  | <code>string</code> | The absolute path of the file being read |
| <code>mtime</code> | <code>time</code>   | The last modification time of the file   |</p>
<p>To attach the source path to each event:</p>
<pre><code class="language-tql">// Before:
from_file "/data/*.json", path_field=source

// After:
from_file "/data/*.json" {
  read_json
  source = $file.path
}
</code></pre>
<p>This makes per-file metadata available throughout the parsing subpipeline
rather than only on emitted events.</p>

<h3>`from_http` is now a pure HTTP client</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/5953">#5953</a></small></p>
<p>The <code>from_http</code> operator no longer doubles as an HTTP server. It is now a
pure HTTP client that issues one request and returns the response.</p>
<p>For accepting incoming HTTP requests, use the dedicated <code>accept_http</code>
operator instead:</p>
<pre><code class="language-tql">// Before:
from_http "0.0.0.0:8080", server=true { read_json }

// After:
accept_http "0.0.0.0:8080" { read_json }
</code></pre>
<p>In the parsing subpipeline, the response metadata is now exposed as the
<code>$response</code> let-binding instead of being written into a <code>metadata_field</code>:</p>
<pre><code class="language-tql">from_http "https://api.example.com/status" {
  read_json
  status_code = $response.code
  server = $response.headers.Server
}
</code></pre>
<p>Additionally, the <code>url</code> and <code>headers</code> arguments are now resolved as
<a href="https://docs.tenzir.com/explanations/secrets">secrets</a>, so you can pass
secret names instead of hardcoding tokens or sensitive URLs.</p>

<h3>OpenSearch ingestion with `accept_opensearch`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/6066">#6066</a></small></p>
<p>The new <code>accept_opensearch</code> operator starts an OpenSearch-compatible HTTP
server and turns incoming Bulk API requests into events:</p>
<pre><code class="language-tql">accept_opensearch "0.0.0.0:9200"
publish "events"
</code></pre>
<p>The operator buffers each bulk request body up to <code>max_request_size</code>,
optionally decompresses it based on the <code>Content-Encoding</code> header, parses the
NDJSON payload, and emits the resulting records. Set <code>keep_actions=true</code> to
also keep the OpenSearch action objects (e.g., <code>{"create": ...}</code>) in the
stream.</p>
<p>The <code>from_opensearch</code> operator has been removed. Use <code>accept_opensearch</code>
instead. The <code>elasticsearch://</code> and <code>opensearch://</code> URL schemes now dispatch
to <code>accept_opensearch</code> via <code>from</code>.</p>

<h3>Dedicated FTP source and sink operators</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6044">#6044</a></small></p>
<p>Two new operators provide first-class FTP and FTPS support with parsing and
printing subpipelines:</p>
<ul>
<li><code>from_ftp</code> downloads bytes from an FTP or FTPS server and forwards them to
the parsing subpipeline.</li>
<li><code>to_ftp</code> uploads bytes produced by the printing subpipeline to an FTP or
FTPS server.</li>
</ul>
<pre><code class="language-tql">from_ftp "ftp://user:pass@ftp.example.org/path/to/file.ndjson" {
  read_ndjson
}
</code></pre>
<pre><code class="language-tql">to_ftp "ftp://user:pass@ftp.example.org/a/b/c/events.ndjson" {
  write_ndjson
}
</code></pre>
<p>The <code>load_ftp</code> and <code>save_ftp</code> operators have been removed, and the <code>ftp://</code>
and <code>ftps://</code> URL schemes no longer dispatch via <code>from</code> and <code>to</code>. Use
<code>from_ftp</code> and <code>to_ftp</code> directly.</p>

<h2>Features</h2>

<h3>Unix domain socket operators</h3>
<p><small>May 30, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6240">#6240</a></small></p>
<p>Tenzir now supports Unix stream sockets in the new executor with three dedicated
operators:</p>
<ul>
<li><code>from_unix_socket</code> connects to a Unix domain socket and parses incoming bytes.</li>
<li><code>accept_unix_socket</code> listens on a socket path and parses each accepted client stream.</li>
<li><code>to_unix_socket</code> connects to a socket path and writes serialized bytes.</li>
</ul>
<p>These operators replace the previous <code>uds=true</code> options on <code>from_file</code> and
<code>to_file</code>. Use <code>from_unix_socket</code> or <code>to_unix_socket</code> for Unix domain socket clients, and keep
<code>from_file</code> and <code>to_file</code> for regular filesystem and object-storage access.</p>
<pre><code class="language-tql">accept_unix_socket "/run/collector.sock" {
  read_json
}
</code></pre>
<pre><code class="language-tql">to_unix_socket "/run/collector.sock" {
  write_ndjson
}
</code></pre>

<h3>Recursive record sorting</h3>
<p><small>May 28, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6237">#6237</a></small></p>
<p>The <code>sort</code> function now recursively sorts record fields wherever they occur in
the sorted value, including records inside lists. Nested list element order is
preserved unless the list itself is being sorted.</p>

<h3>Delimited byte output</h3>
<p><small>May 28, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The new <code>write_delimited</code> operator writes one <code>string</code> or <code>blob</code> value per
event and appends a separator after each value:</p>
<pre><code class="language-tql">from {data: "a"}, {data: "b"}
to_stdout {
  write_delimited data, "|"
}
</code></pre>
<p>This outputs:</p>
<pre><code class="language-txt">a|b|
</code></pre>
<p>This lets you frame compact JSON, GELF over TCP with a null byte, or other
preformatted messages without adding escaping or serialization in the byte
writer.</p>

<h3>HEC queue selection in `to_splunk`</h3>
<p><small>May 18, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The neo <code>to_splunk</code> implementation now accepts <code>queue="indexing"</code> and
<code>queue="typing"</code> for selecting the Splunk HEC processing queue. The default
<code>indexing</code> path keeps Splunk's regular HEC behavior, while <code>typing</code> sends the
Splunk <code>parsingQueue</code> hint in HEC event envelopes for receivers that support
this non-standard HEC metadata.</p>
<p>The default is <code>queue="indexing"</code>. The <code>typing</code> queue is rejected with
<code>raw=...</code>, because Splunk's raw HEC endpoint sends raw requests to the indexer
queue.</p>

<h3>Add `auto_fill` option to `read_csv`, `read_tsv`, `read_ssv`, and `read_xsv`</h3>
<p><small>May 18, 2026 · <a href="https://github.com/jachris">@jachris</a>, <a href="https://github.com/claude">@claude</a></small></p>
<p>The <code>read_csv</code>, <code>read_tsv</code>, <code>read_ssv</code>, and <code>read_xsv</code> operators now accept an
<code>auto_fill=true</code> option. When set, the parser silently fills missing trailing
columns with <code>null</code> instead of emitting a warning, which is useful when working
with feeds that legitimately omit optional trailing fields.</p>

<h3>Request records for `from_http` pagination</h3>
<p><small>May 17, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6193">#6193</a></small></p>
<p>The <code>from_http</code> operator now supports returning request records from
<code>paginate</code> lambdas. This lets APIs keep pagination state in the next request
body or headers instead of only in the next URL:</p>
<pre><code class="language-tql">from_http "https://opensearch.example.com/logs/_search",
  method="post",
  body={size: 500, query: {match_all: {}}},
  paginate=(x => {
    body: {
      size: 500,
      query: {match_all: {}},
      search_after: x.hits.hits[-1].sort,
    },
  } if x.hits.hits != []) {
  read_json
}
</code></pre>
<p>Returned request records can patch <code>url</code>, <code>method</code>, <code>headers</code>, and <code>body</code>.
Missing fields inherit from the current request, and <code>body: null</code> clears the
body.</p>

<h3>Prometheus shape for `metrics`</h3>
<p><small>May 16, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6190">#6190</a></small></p>
<p>The <code>metrics</code> operator now accepts <code>shape="prometheus"</code> to emit metrics from
metrics plugins as canonical <code>{metric, value, timestamp, labels, type, unit}</code>
records. The default remains <code>shape="raw"</code>, which preserves the existing
<code>tenzir.metrics.*</code> schemas.</p>

<h3>Raw byte output with write_all</h3>
<p><small>May 15, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The new <code>write_all</code> operator concatenates one selected <code>string</code> or <code>blob</code> field
into raw bytes:</p>
<pre><code class="language-tql">from_file "/tmp/report.pdf" {
  read_all binary=true
}
to_file "/tmp/report-copy.pdf" {
  write_all data
}
</code></pre>
<p>Use it to copy binary payloads, reconstruct byte streams after event processing,
or write string fields without separators or escaping.</p>

<h3>Repeat string function</h3>
<p><small>May 15, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6181">#6181</a></small></p>
<p>The new <code>repeat</code> function repeats a string a given number of times:</p>
<pre><code class="language-tql">message = "na".repeat(8)
</code></pre>
<pre><code class="language-tql">{
  message: "nananananananana",
}
</code></pre>

<h3>`from_http` infers response parsers</h3>
<p><small>May 15, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6186">#6186</a></small></p>
<p>The <code>from_http</code> operator now accepts requests without an explicit parser
subpipeline when Tenzir can infer the response format from the <code>Content-Type</code>
header or URL extension:</p>
<pre><code class="language-tql">from_http "https://example.com/events.json"
</code></pre>
<p>Explicit parser subpipelines continue to take precedence over inferred formats.</p>

<h3>CloudWatch Logs operators</h3>
<p><small>May 14, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6180">#6180</a></small></p>
<p>Tenzir now supports reading from and writing to CloudWatch Logs with the new
<code>from_amazon_cloudwatch</code> and <code>to_amazon_cloudwatch</code> operators. The source can
subscribe to live streams with <code>mode="live"</code>, search historical log groups with
<code>mode="search"</code>, or replay one stream with <code>mode="replay"</code>.</p>
<pre><code class="language-tql">from_amazon_cloudwatch "/aws/lambda/api", mode="search", filter="ERROR"
</code></pre>
<p>The default sink can send events with <code>PutLogEvents</code>, including configurable
batching, timestamp handling, parallel requests, and AWS IAM authentication via
<code>aws_iam</code>. The sink can also write to the CloudWatch HTTP ingestion endpoints by
setting <code>method</code> to <code>json</code>, <code>ndjson</code>, or <code>hlc</code>, with either SigV4 or bearer-token
authentication.</p>
<pre><code class="language-tql">to_amazon_cloudwatch "/tenzir/events",
  stream="default",
  payload=message,
  timestamp=ts
</code></pre>

<h3>SQS receive controls</h3>
<p><small>May 13, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6167">#6167</a>, <a href="https://github.com/tenzir/tenzir/pull/6174">#6174</a></small></p>
<p>The <code>from_sqs</code> operator now gives you explicit control over how messages are
received from SQS. Use <code>keep_messages=true</code> to inspect or replay messages
without removing them from the queue, <code>batch_size=&#x3C;1..10></code> to control how many
messages each receive request may return, and <code>visibility_timeout=&#x3C;duration></code> to
override the queue visibility timeout for received messages:</p>
<pre><code class="language-tql">from_sqs "events", keep_messages=true, batch_size=10, visibility_timeout=30s
</code></pre>
<p>By default, <code>from_sqs</code> keeps deleting each received message after emitting it.
With <code>keep_messages=true</code>, SQS makes the message visible again after the queue's
visibility timeout.</p>

<h3>SQS receive controls</h3>
<p><small>May 13, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6167">#6167</a>, <a href="https://github.com/tenzir/tenzir/pull/6174">#6174</a></small></p>
<p>The <code>from_amazon_sqs</code> operator now gives you explicit control over how messages
are received from SQS. Use <code>keep_messages=true</code> to inspect or replay messages
without removing them from the queue, <code>batch_size=&#x3C;1..10></code> to control how many
messages each receive request may return, and <code>visibility_timeout=&#x3C;duration></code> to
override the queue visibility timeout for received messages:</p>
<pre><code class="language-tql">from_amazon_sqs "events", keep_messages=true, batch_size=10,
  visibility_timeout=30s
</code></pre>
<p>By default, <code>from_amazon_sqs</code> keeps deleting each received message after
emitting it. With <code>keep_messages=true</code>, SQS makes the message visible again
after the queue's visibility timeout.</p>

<h3>Microsoft Graph source operator</h3>
<p><small>May 12, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6165">#6165</a>, <a href="https://github.com/tenzir/tenzir/pull/6179">#6179</a>, <a href="https://github.com/tenzir/tenzir/pull/6182">#6182</a></small></p>
<p>Tenzir now includes a Microsoft Graph source operator for reads from Microsoft Graph <code>v1.0</code> and <code>beta</code> collections with app-only Microsoft Entra authentication and OData pagination.</p>
<p>For example, you can read Entra ID sign-in logs with client credentials and push down OData query options:</p>
<pre><code class="language-tql">from_microsoft_graph "auditLogs/signIns",
  auth={
    tenant_id: "contoso.onmicrosoft.com",
    client_id: "00000000-0000-0000-0000-000000000000",
    client_secret: secret("ms-graph-client-secret"),
  },
  odata={
    filter: "createdDateTime ge 2026-04-24T00:00:00Z",
    select: ["id", "createdDateTime", "userPrincipalName", "status"],
    top: 1000,
  }
</code></pre>
<p>The operator emits each object from the response <code>value</code> array as a separate event and follows <code>@odata.nextLink</code> until the collection is exhausted.</p>
<p>The operator can also use Microsoft Graph delta queries with <code>delta=true</code>, storing the returned <code>@odata.deltaLink</code> in memory and polling it with a configurable <code>poll_interval</code>. OData query options apply to the initial delta request only, subject to Microsoft Graph's resource-specific support, and subsequent polls use the opaque delta link exactly as Microsoft Graph returned it.</p>
<p>It also retries throttled and transient Microsoft Graph requests, respecting <code>Retry-After</code> when present.</p>

<h3>Event throughput metrics for the new executor</h3>
<p><small>May 12, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6160">#6160</a></small></p>
<p>Pipeline metrics now report event throughput alongside byte throughput for
pipelines running on the new executor:</p>
<pre><code class="language-tql">metrics "pipeline"
summarize ingress_events=sum(ingress.events), ingress_bytes=sum(ingress.bytes), egress_events=sum(egress.events), pipeline_id
sort -egress_events
</code></pre>
<p>This makes node metrics distinguish the amount of data transferred from the
number of events processed.</p>

<h3>Internal memory size function</h3>
<p><small>May 8, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6152">#6152</a></small></p>
<p>The new <code>internal_memory_size</code> function estimates the size of each event in
bytes:</p>
<pre><code class="language-tql">size = internal_memory_size(this)
</code></pre>
<p>This is useful for building pipelines that inspect or route events based on their approximate in-memory payload size.</p>

<h3>from_amqp queue arguments</h3>
<p><small>May 8, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6139">#6139</a></small></p>
<p><code>from_amqp</code> now accepts a <code>queue_arguments</code> record for RabbitMQ queue declaration arguments:</p>
<pre><code class="language-tql">from_amqp "amqp://broker/vhost",
          queue="events",
          queue_arguments={
            "x-queue-type": "quorum",
            "x-quorum-initial-group-size": 3
          }
</code></pre>
<p>Use this to declare queues with broker-specific settings such as quorum queues, maximum lengths, message TTLs, single active consumers, and dead-letter exchanges.</p>

<h3>TQL match statements</h3>
<p><small>May 2, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>TQL now supports statement-level <code>match</code> blocks for branching on patterns:</p>
<pre><code class="language-tql">match action {
  "accept" | "allow" => { verdict = "allowed" }
  "deny" | "drop" => { verdict = "blocked" }
  _ => { verdict = "unknown" }
}
</code></pre>
<p>Patterns can be constants, exclusive ranges, alternatives separated by <code>|</code>, or
the final wildcard <code>_</code>. Every <code>match</code> must include an unguarded final wildcard
arm, so Tenzir can prove at compile time that all possible values are covered.
This provides a concise alternative to long <code>else if</code> chains when routing events
by field value.</p>

<h3>Uncompressed Feather output</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6045">#6045</a></small></p>
<p>The <code>write_feather</code> operator now supports <code>compression_type="uncompressed"</code>
to disable compression entirely. Previously, only <code>zstd</code> and <code>lz4</code> were
accepted:</p>
<pre><code class="language-tql">to_file "events.feather" {
  write_feather compression_type="uncompressed"
}
</code></pre>

<h3>HEC metadata and raw endpoint support in `to_splunk`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6074">#6074</a></small></p>
<p>The <code>to_splunk</code> operator gains three new options for richer HEC metadata.</p>
<p>Use <code>time=</code> to set the per-event Splunk timestamp from an expression that
evaluates to a Tenzir <code>time</code> or a non-negative epoch in seconds:</p>
<pre><code class="language-tql">from {message: "login succeeded", observed_at: 2026-04-24T08:30:00Z}
to_splunk "https://localhost:8088",
  hec_token=secret("splunk-hec-token"),
  time=observed_at
</code></pre>
<p>Use <code>fields=</code> to attach indexed HEC fields. The expression must evaluate to
a flat record whose values are strings or lists of strings:</p>
<pre><code class="language-tql">to_splunk "https://localhost:8088",
  hec_token=secret("splunk-hec-token"),
  event={message: message},
  fields={user: user, tags: tags}
</code></pre>
<p>Use <code>raw=</code> to send already-formatted text to the HEC raw endpoint
(<code>/services/collector/raw</code>). The <code>raw</code> expression must evaluate to a
<code>string</code>. Multiple events in one request are separated by newlines, and
request-level metadata such as <code>host</code>, <code>source</code>, <code>sourcetype</code>, <code>index</code>, and
<code>time</code> is sent as query parameters:</p>
<pre><code class="language-tql">to_splunk "https://localhost:8088",
  hec_token=secret("splunk-hec-token"),
  raw=line,
  source=source,
  sourcetype="linux_secure"
</code></pre>
<p><code>raw</code> and <code>event</code> are mutually exclusive; <code>fields</code> is not supported with
<code>raw</code>.</p>

<h3>DNS result caching in `dns_lookup`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6034">#6034</a></small></p>
<p>The <code>dns_lookup</code> operator now caches DNS results and reuses them across
lookups. Forward-lookup results gain a <code>ttl</code> field that shows the remaining
lifetime of the cached answer:</p>
<pre><code class="language-tql">from {host: "example.com"}
dns_lookup host
</code></pre>
<p>If Tenzir cannot initialize DNS resolution at all, the operator now emits an
error and stops instead of writing <code>null</code> results for every event.
Individual failed or timed-out lookups still produce <code>null</code>, as before.</p>

<h3>Keyed routing and source mode for `parallel`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5821">#5821</a></small></p>
<p>The <code>parallel</code> operator gains two enhancements:</p>
<p>The <code>jobs</code> argument is now optional and defaults to the number of available
CPU cores:</p>
<pre><code class="language-tql">subscribe "events"
parallel {
  parsed = data.parse_json()
}
</code></pre>
<p>The new <code>route_by</code> argument routes events to workers deterministically by
key. Events with the same <code>route_by</code> value always go to the same worker,
which is required for stateful subpipelines like <code>deduplicate</code> or
<code>summarize</code>:</p>
<pre><code class="language-tql">subscribe "events"
parallel route_by=src_ip {
  deduplicate src_ip, dst_ip, dst_port
}
</code></pre>
<p>Additionally, <code>parallel</code> may now be used as a source operator (without
upstream input). This spawns multiple independent instances of the
subpipeline, which is useful for running the same source pipeline with
concurrent connections.</p>

<h3>Memory-mapped reads in `from_file`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/6036">#6036</a></small></p>
<p>The <code>from_file</code> operator now accepts an <code>mmap=bool</code> option that uses
memory-mapped I/O for reading local files instead of regular reads. This can
improve performance for large files:</p>
<pre><code class="language-tql">from_file "/var/log/large.json", mmap=true {
  read_json
}
</code></pre>
<p>Defaults to <code>false</code>.</p>

<h3>Parse TQL records with `read_tql`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/5707">#5707</a></small></p>
<p>The new <code>read_tql</code> operator parses an incoming byte stream of TQL-formatted
records into events. Each top-level record expression becomes one event:</p>
<pre><code class="language-tql">load_file "events.tql"
read_tql
</code></pre>
<p>The input format matches the output of <code>write_tql</code>, so <code>read_tql</code> is useful
for round-tripping data through TQL notation, reading TQL-formatted files,
or processing data piped from other Tenzir pipelines.</p>

<h3>High-level filesystem and object store writers</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/6053">#6053</a></small></p>
<p>Four new high-level writer operators serialize events to local filesystems
and cloud object stores with rotation, hive-style partitioning, and
per-partition unique filenames:</p>
<ul>
<li><code>to_file</code> writes to a local filesystem.</li>
<li><code>to_s3</code> writes to Amazon S3.</li>
<li><code>to_azure_blob_storage</code> writes to Azure Blob Storage.</li>
<li><code>to_google_cloud_storage</code> writes to Google Cloud Storage.</li>
</ul>
<p>Each takes a printing subpipeline, a URL with optional <code>**</code> and <code>{uuid}</code>
placeholders, and rotation parameters. The <code>**</code> placeholder expands into a
hive partitioning hierarchy based on <code>partition_by</code>, and <code>{uuid}</code> ensures
each partition gets unique destination names:</p>
<pre><code class="language-tql">subscribe "events"
to_s3 "s3://my-bucket/year=**/month=**/{uuid}.json",
  partition_by=[year, month] {
  write_ndjson
}
</code></pre>
<p>Files rotate automatically when the configured <code>max_size</code> or <code>timeout</code> is
reached, so long-running pipelines do not produce single huge objects.</p>

<h3>Send events to webhooks with `to_http`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/6019">#6019</a></small></p>
<p>The new <code>to_http</code> operator sends each input event as an HTTP request to a
webhook or API endpoint. By default, it JSON-encodes the entire event as the
request body and sends it as a <code>POST</code>:</p>
<pre><code class="language-tql">subscribe "alerts"
to_http "https://example.com/webhook"
</code></pre>
<p><code>to_http</code> shares its options with <code>from_http</code> and <code>http</code>: configure
<code>method</code>, <code>body</code>, <code>encode</code>, <code>headers</code>, TLS, retries, and pagination per
request. Use <code>parallel</code> to issue multiple concurrent requests when the target
endpoint can keep up with a single pipeline.</p>
<p>This is useful for pushing alerts to webhooks, forwarding events to SIEMs,
and calling external APIs once per event.</p>

<h3>Stream pipeline output with `serve_http`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/6070">#6070</a></small></p>
<p>The new <code>serve_http</code> operator starts an HTTP server and broadcasts the bytes
produced by a nested pipeline to all connected clients:</p>
<pre><code class="language-tql">from_file "example.yaml"
serve_http "0.0.0.0:8080" {
  write_ndjson
}
</code></pre>
<p>Clients connect with a <code>GET</code> request and receive a continuous HTTP response
body. Pick the wire format with the nested pipeline: <code>write_ndjson</code> for
NDJSON streams, <code>write_lines</code> for plain text, and so on. The operator does
not buffer output for clients that connect later—each client receives the
bytes produced after it connects. TLS, connection limits, and graceful
disconnect are all configurable.</p>

<h3>Live packet capture with `from_nic`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6022">#6022</a></small></p>
<p>The new <code>from_nic</code> operator captures packets from a network interface and
emits them as events directly:</p>
<pre><code class="language-tql">from_nic "eth0"
</code></pre>
<p>Without an explicit subpipeline, <code>from_nic</code> parses the captured PCAP byte
stream with <code>read_pcap</code>. Provide a subpipeline when you want to change how
the byte stream is parsed. Use the <code>filter</code> option to apply a Berkeley Packet
Filter (BPF) expression so libpcap drops unwanted traffic before parsing:</p>
<pre><code class="language-tql">from_nic "eth0", filter="tcp port 443"
</code></pre>
<p>The companion <code>read_pcap</code> and <code>write_pcap</code> operators have been refreshed:
<code>read_pcap</code> now also emits a <code>pcap.file_header</code> event when
<code>emit_file_headers=true</code>, which <code>write_pcap</code> consumes to preserve the
original timestamp precision and byte order. The <code>pcap.packet</code> schema's
<code>time.timestamp</code> field is now a top-level <code>timestamp</code> field, and <code>data</code> is
now a <code>blob</code>.</p>

<h3>Dedicated TCP source and sink operators</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/5744">#5744</a>, <a href="https://github.com/tenzir/tenzir/pull/6017">#6017</a></small></p>
<p>Tenzir now has dedicated TCP source and sink operators that match the same
client/server split as the HTTP operators:</p>
<ul>
<li><code>from_tcp</code> connects to a remote TCP or TLS endpoint as a client.</li>
<li><code>accept_tcp</code> listens on a local endpoint and spawns a subpipeline per
accepted connection. Inside the subpipeline, <code>$peer.ip</code> and <code>$peer.port</code>
identify the connecting client; with <code>resolve_hostnames=true</code>,
<code>$peer.hostname</code> is also available from reverse DNS.</li>
<li><code>to_tcp</code> connects to a remote endpoint and writes serialized bytes.</li>
<li><code>serve_tcp</code> listens for incoming connections and broadcasts pipeline output
to all connected clients.</li>
</ul>
<p>Each operator takes a parsing or printing subpipeline so connection
management, framing, and serialization stay separate concerns:</p>
<pre><code class="language-tql">accept_tcp "0.0.0.0:8090" {
  read_json
}
</code></pre>
<pre><code class="language-tql">to_tcp "collector.example.com:5044" {
  write_json
}
</code></pre>
<p><code>from_tcp</code> and <code>to_tcp</code> reconnect with exponential backoff on connection
failure. All four operators support TLS via the <code>tls</code> option.</p>
<p>The legacy <code>load_tcp</code> and <code>save_tcp</code> operators are now deprecated. The
<code>tcp://</code> and <code>tcps://</code> URL schemes still dispatch to them via <code>from</code> and
<code>to</code>.</p>

<h3>Read from standard input with `from_stdin`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/5731">#5731</a></small></p>
<p>The new <code>from_stdin</code> operator reads bytes from standard input through a
parsing subpipeline:</p>
<pre><code class="language-tql">from_stdin {
  read_json
}
</code></pre>
<p>This is useful when piping data into the <code>tenzir</code> executable as part of a
shell script or command chain.</p>

<h3>Synthetic event generation with `anonymize`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a></small></p>
<p>The new <code>anonymize</code> operator generates synthetic events that share the schemas
of its input. The operator first samples a configurable number of input events
to learn what schemas are present and to summarize their values, and then
replaces the input with generated events that match those schemas:</p>
<pre><code class="language-tql">subscribe "events"
anonymize count=1000
</code></pre>
<p>By default, generated values follow the aggregate statistics of the sampled
input: null rates, list lengths, numeric ranges, time and duration ranges,
boolean and enum frequencies, string and blob lengths and byte frequencies, IP
address family frequencies, and subnet prefix length frequencies. Use
<code>fully_random=true</code> to ignore those statistics and instead pick values
uniformly from each type's full range. The optional <code>seed</code> argument makes
output reproducible.</p>
<p>Use <code>anonymize</code> to share representative event traces without leaking the
underlying values.</p>

<h3>Keyed subpipeline routing with `group`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5980">#5980</a></small></p>
<p>The new <code>group</code> operator routes events with the same key through a shared
subpipeline. Inside the subpipeline, <code>$group</code> refers to the key for that
subpipeline:</p>
<pre><code class="language-tql">group tenant {
  summarize count()
}
</code></pre>
<p>The subpipeline either emits events—which are forwarded as the operator's
output—or ends with a sink, in which case <code>group</code> itself becomes a sink. Use
<code>group</code> when you need keyed routing through a stateful subpipeline, such as a
per-tenant sink or a per-session transformation. For grouped aggregations,
keep using <code>summarize</code>.</p>

<h3>Per-event subpipelines with `each`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5981">#5981</a></small></p>
<p>The new <code>each</code> operator runs a fresh subpipeline for every input event. The
event is bound to <code>$this</code> inside the subpipeline so it can parametrize the
nested logic on a per-event basis:</p>
<pre><code class="language-tql">from [
  {file: "a.json"},
  {file: "b.json"},
]
each {
  from $this.file
}
</code></pre>
<p>The subpipeline takes no input from <code>each</code>. It either emits events—which are
forwarded as the operator's output—and may also end with a sink, in which case
<code>each</code> itself becomes a sink.</p>
<p>Use <code>each</code> for per-event jobs such as a lookup, an export, or a sink whose
source depends on the incoming event. For keyed streams that should keep one
subpipeline alive per key, use <code>group</code> instead.</p>

<h3>OData pagination for from_http</h3>
<p><small>Apr 24, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6080">#6080</a></small></p>
<p>The <code>from_http</code> operator now supports <code>paginate="odata"</code> for
<a href="https://www.oasis-open.org/standard/odata-v4-01-os/">OData</a> collection
responses such as Microsoft Graph:</p>
<pre><code class="language-tql">from_http "https://graph.microsoft.com/v1.0/users",
  headers={"ConsistencyLevel": "eventual"},
  paginate="odata" {
  read_json
}
</code></pre>
<p>This mode emits the objects from the response body's top-level <code>value</code> array
and follows top-level <code>@odata.nextLink</code> URLs until no next link is present. The
next link can be absolute or relative to the current response URL.</p>

<h3>NATS JetStream operators</h3>
<p><small>Apr 17, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6047">#6047</a></small></p>
<p>Tenzir can now consume from and publish to NATS JetStream subjects with
<code>from_nats</code> and <code>to_nats</code>.</p>
<p>Use <code>from_nats</code> to receive one event per message. The raw payload appears in the
<code>message</code> blob field, and <code>metadata_field</code> attaches NATS metadata:</p>
<pre><code class="language-tql">from_nats "alerts", metadata_field=nats
parsed = string(message).parse_json()
</code></pre>
<p>Use <code>to_nats</code> to publish one message per event. By default, the operator
serializes the whole event with <code>this.print_ndjson()</code>:</p>
<pre><code class="language-tql">from {severity: "high", alert_type: "suspicious-login"}
to_nats "alerts"
</code></pre>
<p>Both operators support configurable connection settings, authentication, and
the standard Tenzir <code>tls</code> record.</p>

<h3>MySQL source operator</h3>
<p><small>Feb 6, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5721">#5721</a>, <a href="https://github.com/tenzir/tenzir/pull/5738">#5738</a></small></p>
<p>The <code>from_mysql</code> operator lets you read data directly from MySQL databases.</p>
<p>Read a table:</p>
<pre><code class="language-tql">from_mysql table="users", host="localhost", port=3306, user="admin", password="secret", database="mydb"
</code></pre>
<p>List tables:</p>
<pre><code class="language-tql">from_mysql show="tables", host="localhost", port=3306, user="admin", password="secret", database="mydb"
</code></pre>
<p>Show columns:</p>
<pre><code class="language-tql">from_mysql table="users", show="columns", host="localhost", port=3306, user="admin", password="secret", database="mydb"
</code></pre>
<p>And ultimately execute a custom SQL query:</p>
<pre><code class="language-tql">from_mysql sql="SELECT id, name FROM users WHERE active = 1",
           host="localhost",
           port=3306,
           user="admin",
           password="secret",
           database="mydb"
</code></pre>
<p>The operator supports TLS/SSL connections for secure communication with MySQL
servers. Use <code>tls=true</code> for default TLS settings, or pass a record for
fine-grained control:</p>
<pre><code class="language-tql">from_mysql table="users", host="db.example.com", database="prod", tls={
  cacert: "/path/to/ca.pem",
  certfile: "/path/to/client-cert.pem",
  keyfile: "/path/to/client-key.pem",
}
</code></pre>
<p>The operator supports MySQL's <code>caching_sha2_password</code> authentication method and automatically maps MySQL data types to Tenzir types.</p>
<p>Use <code>live=true</code> to continuously stream new rows from a table. The operator
tracks progress using a watermark on an integer column, polling for rows above
the last-seen value:</p>
<pre><code class="language-tql">from_mysql table="events", live=true, host="localhost", database="mydb"
</code></pre>
<p>By default, the tracking column is auto-detected from the table's
auto-increment primary key. To specify one explicitly:</p>
<pre><code class="language-tql">from_mysql table="events", live=true, tracking_column="event_id",
           host="localhost", database="mydb"
</code></pre>

<h2>Changes</h2>

<h3>Region derivation and endpoint logging for SQS</h3>
<p><small>May 13, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/6168">#6168</a></small></p>
<p>The <code>from_sqs</code> and <code>to_sqs</code> operators now derive the AWS region from a queue
URL when <code>aws_region</code> is not set, so passing a full URL such as
<code>https://sqs.us-west-2.amazonaws.com/123456789012/my-queue</code> works without
having to specify the region again:</p>
<pre><code class="language-tql">from_sqs "https://sqs.us-west-2.amazonaws.com/123456789012/my-queue"
</code></pre>
<p>Previously, this would fall back to the SDK default region and fail with a
SigV4 signature mismatch. Explicit <code>aws_region</code>, resolved IAM credentials, and
the SDK default still apply in that order when the URL has no region (for
example VPC endpoints, LocalStack, or an <code>AWS_ENDPOINT_URL</code> override).</p>
<p>SQS API errors and HTTP failures now also include the endpoint URL in their
log lines and diagnostic notes, which makes it easier to tell which queue
produced an error when multiple SQS pipelines run side by side.</p>

<h3>Region derivation and endpoint logging for SQS</h3>
<p><small>May 13, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/6168">#6168</a></small></p>
<p>The <code>from_amazon_sqs</code> and <code>to_amazon_sqs</code> operators now derive the AWS region
from a queue URL when <code>aws_region</code> is not set, so passing a full URL such as
<code>https://sqs.us-west-2.amazonaws.com/123456789012/my-queue</code> works without
having to specify the region again:</p>
<pre><code class="language-tql">from_amazon_sqs "https://sqs.us-west-2.amazonaws.com/123456789012/my-queue"
</code></pre>
<p>Previously, this would fall back to the SDK default region and fail with a
SigV4 signature mismatch. Explicit <code>aws_region</code>, resolved IAM credentials, and
the SDK default still apply in that order when the URL has no region (for
example VPC endpoints, LocalStack, or an <code>AWS_ENDPOINT_URL</code> override).</p>
<p>SQS API errors and HTTP failures now also include the endpoint URL in their
log lines and diagnostic notes, which makes it easier to tell which queue
produced an error when multiple SQS pipelines run side by side.</p>

<h3>Preserve categorical order in `chart_bar`</h3>
<p><small>May 12, 2026 · <a href="https://github.com/mavam">@mavam</a> · <a href="https://github.com/tenzir/tenzir/pull/6158">#6158</a></small></p>
<p>The <code>chart_bar</code> and <code>chart_pie</code> operators now preserve the incoming row order
for categorical x-axis values such as strings, IP addresses, and subnets. This
allows users to control bar order with regular TQL operators such as <code>sort</code>
before charting.</p>

<h3>Per-schema buffering and default timeout for `batch`</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/aljazerzen">@aljazerzen</a> · <a href="https://github.com/tenzir/tenzir/pull/5878">#5878</a>, <a href="https://github.com/tenzir/tenzir/pull/5906">#5906</a></small></p>
<p>The <code>batch</code> operator now maintains separate buffers for each distinct
schema. Each buffer has independent timeout tracking and fills until reaching
the <code>limit</code>, at which point it flushes immediately. Previously, mixed-schema
streams could stall waiting for a single combined buffer to fill.</p>
<p>The <code>timeout</code> argument now defaults to <code>1min</code> instead of an infinite
duration, so buffered events are flushed at least once per minute when no new
events arrive.</p>

<h3>Add `accept_http` operator for receiving HTTP requests</h3>
<p><small>Apr 15, 2026 · <a href="https://github.com/lava">@lava</a></small></p>
<p>We added a new operator to accept data from incoming HTTP connections.</p>
<p>The <code>server</code> option of the <code>from_http</code> operator is now deprecated.
Going forward, it should only be used for client-mode HTTP operations,
and the new <code>accept_http</code> operator should be used for server-mode
operations.</p>

<h2>Bug Fixes</h2>

<h3>Diagnostics for lambda-valued let bindings</h3>
<p><small>May 31, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6241">#6241</a></small></p>
<p>Invalid lambda-valued <code>let</code> bindings now produce a focused diagnostic instead of cascading into a generic evaluation warning and an internal error.</p>
<p>For example, <code>let $f = (x => x + 1)</code> now points at the lambda and suggests inlining it at the use site.</p>

<h3>Complete GeoIP record enrichment</h3>
<p><small>May 29, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6239">#6239</a></small></p>
<p>GeoIP enrichment now includes all fields from MaxMind records. Previously, records containing <code>uint128</code> values could stop materializing subsequent fields, which could omit later enrichment data from affected databases.</p>

<h3>Compaction resolves package UDOs at startup</h3>
<p><small>May 20, 2026 · <a href="https://github.com/raxyte">@raxyte</a> · <a href="https://github.com/tenzir/tenzir/pull/6210">#6210</a></small></p>
<p>The <code>compaction</code> plugin no longer fails to start with
<code>module &#x3C;package> not found</code> when a rule's <code>pipeline</code> references an
operator defined by an installed package. Previously, depending on the
order in which the node's components were initialized, the compactor's
eager rule-pipeline parse could run before the package manager had
published its operator modules to the global registry.</p>

<h3>Reduce disk I/O of time-based compaction</h3>
<p><small>May 12, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/6169">#6169</a></small></p>
<p>Time-based compaction rules no longer cause the node to reprocess data that
has already been compacted in a previous run.</p>

<h3>Top-level package metadata</h3>
<p><small>May 8, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6149">#6149</a></small></p>
<p>Packages can now include a top-level <code>metadata</code> field for data consumed by external tools. Unknown package keys still fail validation, and the error now points users to <code>metadata</code> for non-engine package data.</p>

<h3>Arrow IPC file support in read_feather</h3>
<p><small>Apr 28, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6087">#6087</a></small></p>
<p>The <code>read_feather</code> operator can now read Arrow IPC file containers in addition to Arrow IPC streams:</p>
<pre><code class="language-tql">from_file "partition.feather" {
  read_feather
}
</code></pre>
<p>This fixes reading Tenzir archive partition files directly. If an IPC file contains a Tenzir event envelope, <code>read_feather</code> unwraps the event payload and preserves the import time; IPC files without Tenzir schema metadata use the schema name <code>undefined</code>.</p>

<h3>SentinelOne Data Lake sink support in the new executor</h3>
<p><small>Apr 24, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6081">#6081</a></small></p>
<p>The <code>to_sentinelone_data_lake</code> operator now works in pipelines that run on the new executor. Previously, using it there failed before the pipeline could send events.</p>
<pre><code class="language-tql">from {message: "hello"}
to_sentinelone_data_lake "https://example.com", token="TOKEN"
</code></pre>

<h3>Faster drop_null_fields on heterogeneous data</h3>
<p><small>Mar 31, 2026 · <a href="https://github.com/jachris">@jachris</a>, <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5963">#5963</a></small></p>
<p>The <code>drop_null_fields</code> operator is now much faster on heterogeneous input with many changing null patterns.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-06-01T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Platform v1.33.0]]></title>
        <id>https://docs.tenzir.com/changelog/platform/v1-33-0</id>
        <link href="https://docs.tenzir.com/changelog/platform/v1-33-0"/>
        <updated>2026-06-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release adds the ability to sort events by time in the Stream view, cycling between newest-first, oldest-first, and off. It also fixes the Insights tab freezing on large pipelines and upgrades dependencies to address known security vulnerabilities.]]></summary>
        <content type="html"><![CDATA[<p>This release adds the ability to sort events by time in the Stream view, cycling between newest-first, oldest-first, and off. It also fixes the Insights tab freezing on large pipelines and upgrades dependencies to address known security vulnerabilities.</p>

<h2>Features</h2>

<h3>Single-column results fill the full table width</h3>
<p><small>Jun 3, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>Results with a single column now stretch to fill the full width of the table instead of hugging the left edge. Long values use the available space and truncate at the table's edge rather than at a fixed cutoff.</p>

<h3>Right-click actions in the Explorer</h3>
<p><small>May 18, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>You can now right-click a field name or value in the Explorer table to filter,
sort, aggregate, or reshape your results. Actions like Equals, Not equals,
Greater than, Contains, Starts with, Top values, Rare values, and Count values
are appended to the editor as TQL, so common queries can be built by clicking
instead of typing.</p>
<p>Timestamps get extra options for filtering around the clicked value, with
windows of 5 minutes, 1 hour, and 1 day before, after, or on either side.</p>

<h3>Sort events by time in the Stream view</h3>
<p><small>May 7, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>You can now sort events by time in the Stream view. The control cycles between newest first, oldest first, and off, and is disabled when no timestamp field is detected in the data. Your sorting preference is remembered between sessions.</p>

<h2>Changes</h2>

<h3>Return a dedicated error when a user key expires</h3>
<p><small>May 21, 2026 · <a href="https://github.com/lava">@lava</a></small></p>
<p>When a <code>X-Tenzir-UserKey</code> has expired, the platform now returns a dedicated <code>403</code> response with the detail <code>User key expired</code>, instead of the generic <code>403 Invalid API Key: X-Tenzir-UserKey expired</code> error. This lets clients reliably detect the expired-key case and trigger a re-authentication flow.</p>

<h2>Bug Fixes</h2>

<h3>Insights tab for v6 release candidates</h3>
<p><small>May 26, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/platform/pull/177">#177</a></small></p>
<p>The Insights tab now always shows data for the release candidates of Tenzir Node
v6, even if no <code>// neo</code> comment is present.</p>

<h3>Fix actions on the account, org, and invite pages failing after the page was open for 15 minutes</h3>
<p><small>May 21, 2026 · <a href="https://github.com/avaq">@avaq</a></small></p>
<p>We fixed an issue where actions on the account, organization, and invitation pages would fail if the page had been open for more than 15 minutes. The following operations now automatically refresh the user key when needed: changing account details, updating passwords, deleting accounts, creating and updating organizations, managing organization invitations, and deleting organizations.</p>

<h3>Fix duration round-trip in TQL queries</h3>
<p><small>May 21, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>Negative multi-part durations no longer drift when copied or embedded into a TQL query. Previously a duration like <code>-(19min + 12.636s)</code> was rendered as <code>-19min + 12.636s</code>, which the parser read as <code>-1127.364s</code> instead of the original <code>-1152.636s</code> — off by twice the seconds component. The sign now distributes across every term (<code>-19min - 12.636s</code>) so the value round-trips cleanly.</p>
<p>Duration rendering also picks up a clearer split between display and query forms. The table cells, chart tooltips, and chart axis labels show durations in a human-readable form like <code>1h 30min 5.000s</code>. The inspector and any context that needs to round-trip the value back into a query show the TQL-valid arithmetic form like <code>1h + 30min + 5.000000000s</code>.</p>

<h3>Fix Insights tab freezing on large pipelines</h3>
<p><small>May 19, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We fixed an issue where the Insights tab became unresponsive and flickered on pipelines with many operators. The table now renders smoothly and stays interactive while showing live metrics.</p>
]]></content>
        <category label="Tenzir Platform"/>
        <published>2026-06-01T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tree-sitter TQL v1.1.0]]></title>
        <id>https://docs.tenzir.com/changelog/tree-sitter-tql/v1-1-0</id>
        <link href="https://docs.tenzir.com/changelog/tree-sitter-tql/v1-1-0"/>
        <updated>2026-06-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release expands Tree-sitter TQL parsing with match statement pattern syntax and adds a shared local quality gate for contributors.]]></summary>
        <content type="html"><![CDATA[<p>This release expands Tree-sitter TQL parsing with match statement pattern syntax and adds a shared local quality gate for contributors.</p>

<h2>Features</h2>

<h3>Match statement pattern syntax</h3>
<p><small>May 31, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tree-sitter-tql/pull/2">#2</a></small></p>
<p>The TQL grammar now parses the documented <code>match</code> statement pattern syntax, including alternatives, guards, ranges, and wildcard arms:</p>
<pre><code class="language-tql">match status {
  499..600 | 429 if retries > 0 => {
    action = "retry"
  }
  _ => {}
}
</code></pre>
<p>This improves editor parsing and highlighting for pipelines that use the new <code>match</code> control-flow statement.</p>

<h3>Shared local quality gate</h3>
<p><small>May 12, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>Developers can run the same fast local quality gate used by CI with <code>npm run check</code>:</p>
<pre><code class="language-sh">npm run check
</code></pre>
<p>Use <code>npm run fix</code> to refresh generated parser and editor-query artifacts before committing.</p>
]]></content>
        <category label="Tree-sitter TQL"/>
        <published>2026-06-01T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Test v1.10.2]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-test/v1-10-2</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-test/v1-10-2"/>
        <updated>2026-05-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release lets pre-provisioned environments reuse installed inline Python dependencies and disable runtime installation entirely. It avoids unnecessary uv pip install calls for bare requirements that are already available.]]></summary>
        <content type="html"><![CDATA[<p>This release lets pre-provisioned environments reuse installed inline Python dependencies and disable runtime installation entirely. It avoids unnecessary uv pip install calls for bare requirements that are already available.</p>

<h2>Bug Fixes</h2>

<h3>Inline dependency installation control</h3>
<p><small>May 27, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/test/pull/49">#49</a></small></p>
<p>Inline Python dependencies declared by tests or fixtures no longer force a
runtime <code>uv pip install</code> when a bare dependency name is already available in
the active Python environment.</p>
<p>Pass <code>--disable-inline-dependency-install</code>, or set
<code>TENZIR_TEST_DISABLE_INLINE_DEPENDENCY_INSTALL=1</code>, to skip inline dependency
installation entirely when another tool provisions the test environment. The
harness still reads dependency metadata, but it leaves package installation to
the caller.</p>
]]></content>
        <category label="Tenzir Test"/>
        <published>2026-05-27T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Platform v1.32.2]]></title>
        <id>https://docs.tenzir.com/changelog/platform/v1-32-2</id>
        <link href="https://docs.tenzir.com/changelog/platform/v1-32-2"/>
        <updated>2026-05-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release upgrades frontend, backend, and CLI dependencies, along with the tenzir-seaweed base image, to address known vulnerabilities reported by our container scanner. It also fixes two chart issues: tooltips no longer get clipped in small dashboard cells, and charts no longer zoom unexpectedly on click.]]></summary>
        <content type="html"><![CDATA[<p>This release upgrades frontend, backend, and CLI dependencies, along with the tenzir-seaweed base image, to address known vulnerabilities reported by our container scanner. It also fixes two chart issues: tooltips no longer get clipped in small dashboard cells, and charts no longer zoom unexpectedly on click.</p>

<h2>Bug Fixes</h2>

<h3>Fix accidental chart zoom on click</h3>
<p><small>May 14, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We fixed an issue where clicking on a line, area, or bar chart could unintentionally zoom the chart to a narrow window, hiding the axis labels and most of the data. Charts no longer respond to clicks this way.</p>

<h3>Fix chart tooltip clipping</h3>
<p><small>May 14, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We fixed an issue where chart tooltips were cut off in dashboard cells and the Explorer chart view when the tooltip did not fit inside the chart area. Tooltips now stay fully visible, even on small cells or near the screen edge.</p>
]]></content>
        <category label="Tenzir Platform"/>
        <published>2026-05-14T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Ship v1.7.4]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-ship/v1-7-4</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-ship/v1-7-4"/>
        <updated>2026-05-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release validates changelog entry metadata and release manifests with JSON Schema. It reports malformed fields such as non-numeric pull request references instead of silently accepting invalid changelog data.]]></summary>
        <content type="html"><![CDATA[<p>This release validates changelog entry metadata and release manifests with JSON Schema. It reports malformed fields such as non-numeric pull request references instead of silently accepting invalid changelog data.</p>

<h2>Bug Fixes</h2>

<h3>Schema-backed changelog validation</h3>
<p><small>May 13, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/ship/pull/26">#26</a></small></p>
<p>Validate changelog entry metadata and release manifests with JSON Schema so malformed
fields such as non-numeric pull request references are reported instead of silently
passing validation.</p>
]]></content>
        <category label="Tenzir Ship"/>
        <published>2026-05-14T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Platform v1.32.1]]></title>
        <id>https://docs.tenzir.com/changelog/platform/v1-32-1</id>
        <link href="https://docs.tenzir.com/changelog/platform/v1-32-1"/>
        <updated>2026-05-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This is a security patch release that updates dependencies to address vulnerabilities. It also shortens the default user key expiry to 15 Minutes.]]></summary>
        <content type="html"><![CDATA[<p>This is a security patch release that updates dependencies to address vulnerabilities. It also shortens the default user key expiry to 15 Minutes.</p>

<h2>Changes</h2>

<h3>Shorten default user key lifetime</h3>
<p><small>May 13, 2026 · <a href="https://github.com/lava">@lava</a></small></p>
<p>We reduced the default lifetime of user keys from one week to 15 minutes. Sessions transparently refresh, so this is invisible in normal use, but shortens the window in which a leaked key could be reused.</p>
]]></content>
        <category label="Tenzir Platform"/>
        <published>2026-05-13T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Test v1.10.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-test/v1-10-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-test/v1-10-1"/>
        <updated>2026-05-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Project fixtures can now declare their Python package dependencies inline with PEP 723 metadata. tenzir-test installs those dependencies before loading fixtures, so regular test runs and fixture mode work for projects with self-contained fixture modules.]]></summary>
        <content type="html"><![CDATA[<p>Project fixtures can now declare their Python package dependencies inline with PEP 723 metadata. tenzir-test installs those dependencies before loading fixtures, so regular test runs and fixture mode work for projects with self-contained fixture modules.</p>

<h2>Bug Fixes</h2>

<h3>Project fixture inline dependencies</h3>
<p><small>May 13, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/test/pull/47">#47</a></small></p>
<p>Project fixtures can now declare Python package dependencies inline with PEP
723 metadata:</p>
<pre><code class="language-python"># /// script
# dependencies = ["boto3"]
# ///
</code></pre>
<p><code>tenzir-test</code> installs these dependencies with <code>uv</code> before importing fixture
modules, so fixtures used during regular test runs and <code>tenzir-test --fixture</code>
can manage their own Python package requirements.</p>
]]></content>
        <category label="Tenzir Test"/>
        <published>2026-05-13T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Test v1.10.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-test/v1-10-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-test/v1-10-0"/>
        <updated>2026-05-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[tenzir-test now lets users select scenarios by requested fixture name, making it easier to run only tests that depend on resources such as nodes or Docker Compose. This release also requires Python 3.13 or newer.]]></summary>
        <content type="html"><![CDATA[<p>tenzir-test now lets users select scenarios by requested fixture name, making it easier to run only tests that depend on resources such as nodes or Docker Compose. This release also requires Python 3.13 or newer.</p>

<h2>Features</h2>

<h3>Fixture name test selection</h3>
<p><small>May 12, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>Select tests by requested fixture name with the new <code>--fixture-name</code> option:</p>
<pre><code class="language-sh">tenzir-test --fixture-name node
tenzir-test tests/alerts --match kafka --fixture-name docker-compose
</code></pre>
<p><code>--fixture-name</code> can be repeated and combines with <code>--fixture-tag</code> using OR
semantics before intersecting with positional test paths and <code>--match</code>.
Fixture selectors are long-only; the previous <code>-F</code> alias for <code>--fixture-tag</code>
has been removed before the CLI shape settles.</p>

<h2>Changes</h2>

<h3>Python 3.13 minimum requirement</h3>
<p><small>May 12, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/test/pull/44">#44</a></small></p>
<p><code>tenzir-test</code> now requires Python 3.13 or newer.</p>
<p>Users on Python 3.12 need to upgrade their interpreter before installing or running the CLI:</p>
<pre><code class="language-sh">uvx --python 3.13 tenzir-test --help
</code></pre>
]]></content>
        <category label="Tenzir Test"/>
        <published>2026-05-12T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Skills v1.0.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-skills/v1-0-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-skills/v1-0-0"/>
        <updated>2026-05-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The Tenzir skill collection is now available as its initial stable release. This release establishes the shared skill set as the stable baseline for coding agents working in and around the Tenzir ecosystem.]]></summary>
        <content type="html"><![CDATA[<p>The Tenzir skill collection is now available as its initial stable release. This release establishes the shared skill set as the stable baseline for coding agents working in and around the Tenzir ecosystem.</p>

<h2>Features</h2>

<h3>Initial stable skill collection</h3>
<p><small>May 8, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The Tenzir skill collection is now published as its initial stable release for v1.0.0.</p>
<p>This release establishes the shared skill set as the stable baseline for coding agents working in and around the Tenzir ecosystem.</p>
]]></content>
        <category label="Tenzir Skills"/>
        <published>2026-05-12T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Test v1.9.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-test/v1-9-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-test/v1-9-0"/>
        <updated>2026-05-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release lets users select tests by fixture tag with the new --fixture-tag option. It makes it easier to run focused subsets such as container-backed or Docker Compose tests without naming every test path.]]></summary>
        <content type="html"><![CDATA[<p>This release lets users select tests by fixture tag with the new --fixture-tag option. It makes it easier to run focused subsets such as container-backed or Docker Compose tests without naming every test path.</p>

<h2>Features</h2>

<h3>Fixture tag test selection</h3>
<p><small>May 11, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/test/pull/42">#42</a></small></p>
<p>Select tests by fixture tag with the new <code>--fixture-tag</code> option:</p>
<pre><code class="language-sh">tenzir-test --fixture-tag container
tenzir-test --fixture-tag docker-compose
</code></pre>
<p>Fixture tags are cumulative and can be repeated. The selector intersects with positional test paths and <code>--match</code> patterns, so you can narrow a directory to container-backed tests or run only tests that request the built-in Docker Compose fixture.</p>
<p>Fixtures that use the shared container runtime helpers inherit the <code>container</code> tag automatically. Custom fixtures can pass explicit tags at registration time when they use their own abstraction.</p>
]]></content>
        <category label="Tenzir Test"/>
        <published>2026-05-11T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Test v1.8.4]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-test/v1-8-4</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-test/v1-8-4"/>
        <updated>2026-05-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The test harness now detects the installed Tenzir version across current and upcoming Tenzir releases. This keeps startup and version checks working during the transition to the next Tenzir release series.]]></summary>
        <content type="html"><![CDATA[<p>The test harness now detects the installed Tenzir version across current and upcoming Tenzir releases. This keeps startup and version checks working during the transition to the next Tenzir release series.</p>

<h2>Bug Fixes</h2>

<h3>Version checks with current TQL pipelines</h3>
<p><small>May 9, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/test/pull/41">#41</a></small></p>
<p>The test harness can detect the installed Tenzir version across current and upcoming Tenzir releases. This keeps startup/version checks working during the transition to the next Tenzir release series.</p>
]]></content>
        <category label="Tenzir Test"/>
        <published>2026-05-09T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.36.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-36-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-36-0"/>
        <updated>2026-05-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release makes int64/uint64 column merging lossless during parsing, so fields like `flow_id` that mix signed and unsigned values no longer cause unnecessary table-slice splits. It also extends ocsf::derive to handle list-valued enum fields for full bidirectional OCSF enum normalization.]]></summary>
        <content type="html"><![CDATA[<p>This release makes int64/uint64 column merging lossless during parsing, so fields like <code>flow_id</code> that mix signed and unsigned values no longer cause unnecessary table-slice splits. It also extends ocsf::derive to handle list-valued enum fields for full bidirectional OCSF enum normalization.</p>

<h2>Features</h2>

<h3>OCSF enum list derivation</h3>
<p><small>Apr 30, 2026 · <a href="https://github.com/jachris">@jachris</a>, <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5354">#5354</a></small></p>
<p><code>ocsf::derive</code> now derives OCSF enum sibling fields for lists, not just scalar enum fields. For example, DNS answers with <code>flag_ids: [1, 3, 4]</code> now also get <code>flags: ["Authoritative Answer", "Recursion Desired", "Recursion Available"]</code>, and the reverse direction works for <code>flags</code> to <code>flag_ids</code> as well.</p>

<h2>Changes</h2>

<h3>Lossless int64/uint64 merging during parsing</h3>
<p><small>May 5, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/6125">#6125</a></small></p>
<p>Parsing data that mixes <code>int64</code> and <code>uint64</code> values in the same field no longer
produces unnecessary table-slice splits, improving batching performance. Fields
like <code>flow_id</code> that are always non-negative but occasionally exceed the signed
integer limit of  <code>2^63 − 1</code> are now merged into a single <code>uint64</code> column where
possible, instead of being emitted as separate slices.</p>

<h2>Bug Fixes</h2>

<h3>Empty if branches in the new executor</h3>
<p><small>May 6, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6128">#6128</a></small></p>
<p>Empty <code>if</code> branches no longer crash when running pipelines with the new executor. For example, <code>if false {}</code> now behaves like an empty pass-through branch instead of triggering an internal assertion failure.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-05-07T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Platform v1.32.0]]></title>
        <id>https://docs.tenzir.com/changelog/platform/v1-32-0</id>
        <link href="https://docs.tenzir.com/changelog/platform/v1-32-0"/>
        <updated>2026-05-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release adds a timeline to the Stream view that visualizes event volume over time, segmented by schema, with automatic timestamp detection. The Explorer's table view also gains keyboard navigation between entries and a streamlined Fields popover for quicker field selection.]]></summary>
        <content type="html"><![CDATA[<p>This release adds a timeline to the Stream view that visualizes event volume over time, segmented by schema, with automatic timestamp detection. The Explorer's table view also gains keyboard navigation between entries and a streamlined Fields popover for quicker field selection.</p>

<h2>Features</h2>

<h3>Timeline in the Stream view</h3>
<p><small>May 6, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>The Stream view now includes a timeline that shows event volume over time,
segmented by schema. It automatically detects timestamp fields and adapts
its bucket size to the data’s time range, providing an at-a-glance view of
when events occur and which schemas are most active.</p>
<p>It also probes your data for time fields and shows availability inline,
omitting events without a recognized time field (ts, timestamp, or time).</p>

<h3>Keyboard navigation between entries in Explorer</h3>
<p><small>May 5, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>You can now navigate between entries in the Explorer table using arrow keys.
Press Space to toggle the inspector, then use Arrow Up and Arrow Down to move
between rows and seamlessly across pages.</p>

<h2>Changes</h2>

<h3>Insights tab now available for every pipeline</h3>
<p><small>May 7, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>The Insights tab in the pipeline detail view is no longer experimental and now appears for every pipeline. It shows you live per-operator CPU usage, events per second, batch ratios, and queue backpressure for the selected pipeline. You can see at a glance which operators are working hardest and where data is piling up, so finding hotspots and tuning pipeline performance becomes easier. Update your node to v6 to see the data.</p>

<h3>Improved field selection in the table view</h3>
<p><small>Apr 21, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We moved field selection in the Explorer's table view into a dedicated popover. The 'Fields' button sits in the toolbar and shows how many fields are currently hidden. Opening it reveals the full field list with the same click-to-toggle and shift+click-to-focus behavior as before.</p>
]]></content>
        <category label="Tenzir Platform"/>
        <published>2026-05-07T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.35.2]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-35-2</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-35-2"/>
        <updated>2026-05-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes two package-related bugs: startup pipelines can now reliably reference operators from static packages, and UDOs with slash-delimited string defaults (e.g. "/tmp-data/") load correctly without internal errors.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes two package-related bugs: startup pipelines can now reliably reference operators from static packages, and UDOs with slash-delimited string defaults (e.g. "/tmp-data/") load correctly without internal errors.</p>

<h2>Bug Fixes</h2>

<h3>Configured pipelines with package operators</h3>
<p><small>May 4, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6113">#6113</a></small></p>
<p>Configured startup pipelines can now reference operators from static packages reliably. Previously, such pipelines could fail during node startup with <code>module &#x3C;package> not found</code>, even though the same package operator worked when run manually after startup.</p>

<h3>Slash-delimited UDO defaults</h3>
<p><small>May 2, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6108">#6108</a></small></p>
<p>Package UDOs now load correctly when a typed string default looks like a TQL pattern, such as <code>default: "/tmp-data/"</code>.</p>
<p>Previously, loading such a package could abort with an unexpected internal error before any pipeline ran.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-05-05T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Test v1.8.3]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-test/v1-8-3</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-test/v1-8-3"/>
        <updated>2026-05-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release makes hook debug diagnostics consistent with the rest of the harness debug trace, so users get uniform output when diagnosing hook behavior.]]></summary>
        <content type="html"><![CDATA[<p>This release makes hook debug diagnostics consistent with the rest of the harness debug trace, so users get uniform output when diagnosing hook behavior.</p>

<h2>Bug Fixes</h2>

<h3>Consistent hook debug diagnostics</h3>
<p><small>May 5, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/test/pull/40">#40</a></small></p>
<p>Hook diagnostics emitted with <code>--debug</code> now use the same formatting as the rest of the harness debug trace. Previously, hook invocation messages used ad-hoc <code>debug:</code> lines, which made debug output inconsistent.</p>
]]></content>
        <category label="Tenzir Test"/>
        <published>2026-05-05T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Ship v1.7.3]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-ship/v1-7-3</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-ship/v1-7-3"/>
        <updated>2026-05-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release tightens changelog validation so unknown entry metadata keys are reported before they can be ignored by release workflows.]]></summary>
        <content type="html"><![CDATA[<p>This release tightens changelog validation so unknown entry metadata keys are reported before they can be ignored by release workflows.</p>

<h2>Bug Fixes</h2>

<h3>Validation for unknown entry metadata keys</h3>
<p><small>May 4, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/ship/pull/23">#23</a></small></p>
<p>The <code>validate</code> command now reports unknown changelog entry metadata keys instead of silently accepting them. This catches misspelled fields such as <code>co-authors</code> early, before they are ignored by release workflows.</p>
]]></content>
        <category label="Tenzir Ship"/>
        <published>2026-05-04T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.35.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-35-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-35-1"/>
        <updated>2026-04-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release restores correct retention for metrics and diagnostics in mixed-age partitions and brings back actionable TLS hints when ClickHouse connections fail due to a TLS/plaintext mismatch.]]></summary>
        <content type="html"><![CDATA[<p>This release restores correct retention for metrics and diagnostics in mixed-age partitions and brings back actionable TLS hints when ClickHouse connections fail due to a TLS/plaintext mismatch.</p>

<h2>Bug Fixes</h2>

<h3>ClickHouse TLS mismatch diagnostics</h3>
<p><small>Apr 29, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6098">#6098</a></small></p>
<p>ClickHouse connection errors caused by TLS/plaintext mismatches now include the TLS notes and hint again. This helps identify when <code>to_clickhouse</code> is using TLS against a plaintext ClickHouse endpoint and suggests setting <code>tls=false</code> when appropriate.</p>

<h3>Retention for mixed-age metrics partitions</h3>
<p><small>Apr 28, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6086">#6086</a></small></p>
<p>Default retention policies now continue deleting metrics and diagnostics as their timestamps age into the retention window, even when older and newer events share a partition.</p>
<p>Previously, a partition that still contained newer events after retention could be skipped by later retention runs, leaving those events behind after they expired.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-04-30T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.35.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-35-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-35-0"/>
        <updated>2026-04-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes crashes in static musl builds when evaluating deeply nested generated TQL expressions.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes crashes in static musl builds when evaluating deeply nested generated TQL expressions.</p>

<h2>Bug Fixes</h2>

<h3>Static musl builds no longer crash on deep TQL expressions</h3>
<p><small>Apr 27, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6082">#6082</a></small></p>
<p>Static musl builds of <code>tenzir</code> no longer crash on deeply nested generated TQL
expressions.</p>
<p>This affected generated pipelines with deeply nested expressions, for example
rules or transformations that expand into long left-associated operator chains.</p>
<p>The <code>tenzir</code> binary now links with a larger default thread stack size on musl,
which brings its behavior in line with non-static builds for these pipelines.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-04-29T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Test v1.8.2]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-test/v1-8-2</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-test/v1-8-2"/>
        <updated>2026-04-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes suite-level requirement checks so they apply consistently across every test runner. Mixed TQL, shell, Python, and custom test suites now evaluate required Tenzir operators independently of runner order.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes suite-level requirement checks so they apply consistently across every test runner. Mixed TQL, shell, Python, and custom test suites now evaluate required Tenzir operators independently of runner order.</p>

<h2>Bug Fixes</h2>

<h3>Runner-independent suite requirements</h3>
<p><small>Apr 29, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/test/pull/39">#39</a></small></p>
<p>Suite-level <code>requires.operators</code> checks now apply consistently to every test runner. Mixed suites that combine TQL, shell, Python, or custom tests no longer depend on the first runner type to decide whether required Tenzir operators are available.</p>
]]></content>
        <category label="Tenzir Test"/>
        <published>2026-04-29T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Test v1.8.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-test/v1-8-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-test/v1-8-1"/>
        <updated>2026-04-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release improves suite fixture failure handling so setup and teardown errors are reported as regular test failures. The harness now continues running independent queued tests instead of aborting with a Python traceback.]]></summary>
        <content type="html"><![CDATA[<p>This release improves suite fixture failure handling so setup and teardown errors are reported as regular test failures. The harness now continues running independent queued tests instead of aborting with a Python traceback.</p>

<h2>Bug Fixes</h2>

<h3>Suite fixture failure reporting</h3>
<p><small>Apr 29, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/test/pull/38">#38</a></small></p>
<p>Suite-scoped fixture setup and teardown failures now appear as regular test failures instead of aborting the entire run with a Python traceback.</p>
<p>This lets the harness continue with independent queued tests after a fixture assertion or cleanup error.</p>
]]></content>
        <category label="Tenzir Test"/>
        <published>2026-04-29T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Test v1.8.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-test/v1-8-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-test/v1-8-0"/>
        <updated>2026-04-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release adds project lifecycle hooks that let projects prepare their environment before tests run. Use hooks to select local Tenzir binaries, configure project-scoped environment variables, and collect diagnostics without custom wrapper scripts.]]></summary>
        <content type="html"><![CDATA[<p>This release adds project lifecycle hooks that let projects prepare their environment before tests run. Use hooks to select local Tenzir binaries, configure project-scoped environment variables, and collect diagnostics without custom wrapper scripts.</p>

<h2>Features</h2>

<h3>Project lifecycle hooks</h3>
<p><small>Apr 27, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/test/pull/36">#36</a></small></p>
<p>Projects can now register Python hooks that run at stable <code>tenzir-test</code> lifecycle points, including before settings discovery:</p>
<pre><code class="language-python">from tenzir_test import hooks

@hooks.startup
def use_local_build(ctx):
    ctx.path.insert(0, str(ctx.root / "build" / "bin"))
    ctx.env["TENZIR_BINARY"] = str(ctx.root / "build" / "bin" / "tenzir")
    ctx.env["TENZIR_NODE_BINARY"] = str(ctx.root / "build" / "bin" / "tenzir-node")
</code></pre>
<p>This makes it possible to select local Tenzir binaries, prepare project-scoped environment variables, and collect diagnostics for failed tests without wrapping the test command in custom shell scripts. Use <code>--no-hooks</code> or <code>TENZIR_TEST_DISABLE_HOOKS=1</code> to bypass hooks when debugging.</p>
]]></content>
        <category label="Tenzir Test"/>
        <published>2026-04-28T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.34.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-34-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-34-0"/>
        <updated>2026-04-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release contains internal changes only.]]></summary>
        <content type="html"><![CDATA[<p>This release contains internal changes only.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-04-27T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.33.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-33-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-33-0"/>
        <updated>2026-04-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release makes the subnet function work directly with typed and string IP addresses, which removes boilerplate in TQL pipelines. It also fixes several stability issues in where, unroll, files, context::enrich, and collection indexing.]]></summary>
        <content type="html"><![CDATA[<p>This release makes the subnet function work directly with typed and string IP addresses, which removes boilerplate in TQL pipelines. It also fixes several stability issues in where, unroll, files, context::enrich, and collection indexing.</p>

<h2>Features</h2>

<h3>IP address support in subnet</h3>
<p><small>Apr 24, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>subnet</code> function now accepts typed IP addresses, plain IP strings, and
existing subnet values with an optional prefix length:</p>
<pre><code class="language-tql">from {source_ip: 10.10.1.124}
net = subnet(source_ip, 24)
</code></pre>
<p>This returns <code>10.10.1.0/24</code> without converting the IP address to a string first.
When you omit the prefix, IPv4 addresses become <code>/32</code> host subnets and IPv6
addresses become <code>/128</code> host subnets.</p>

<h2>Bug Fixes</h2>

<h3>Large unroll output stability</h3>
<p><small>Apr 24, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>unroll</code> operator no longer crashes when expanding very large lists into output that exceeds Arrow's per-array capacity.</p>

<h3>Recursive files traversal of unreadable directories</h3>
<p><small>Apr 24, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>files</code> operator now skips unreadable child directories during recursive traversal, emits a warning for each skipped directory by default, and continues listing accessible siblings. Set <code>skip_permission_denied=true</code> to ignore permission-denied paths silently: this suppresses warnings for skipped child directories and still makes an unreadable initial directory produce no events instead of an error. Non-permission filesystem errors continue to fail the pipeline.</p>

<h3>Fixed unbounded memory growth `context::enrich`</h3>
<p><small>Apr 23, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a></small></p>
<p>We fixed an issue in the <code>context::enrich</code> operator that did cause unbounded
memory growth.</p>

<h3>Crash fix for deep left-associated where expressions</h3>
<p><small>Apr 23, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6068">#6068</a></small></p>
<p>Tenzir no longer segfaults on some very deep left-associated boolean
expressions in <code>where</code> clauses due to source-location handling.</p>

<h3>Unsigned integer indexing in TQL</h3>
<p><small>Apr 22, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>Both list and record indexing in TQL now work with signed and unsigned integer indices.
This also applies to record field-position indexing and to the <code>get</code> function for records and lists.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-04-24T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Test v1.7.7]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-test/v1-7-7</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-test/v1-7-7"/>
        <updated>2026-04-22T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Tests can now skip only the cases that require an unavailable optional fixture instead of skipping an entire suite. This keeps unrelated tests running and makes parameterized fixture setups more reliable.]]></summary>
        <content type="html"><![CDATA[<p>Tests can now skip only the cases that require an unavailable optional fixture instead of skipping an entire suite. This keeps unrelated tests running and makes parameterized fixture setups more reliable.</p>

<h2>Bug Fixes</h2>

<h3>Per-test fixture-unavailable skips</h3>
<p><small>Apr 22, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/test/pull/35">#35</a></small></p>
<p>The test harness now honors <code>skip: {on: fixture-unavailable}</code> for fixtures that are selected by individual tests:</p>
<pre><code class="language-yaml">skip:
  on: fixture-unavailable
fixtures:
  - optional-service
</code></pre>
<p>This lets parameterized per-test fixtures skip only the tests that need the unavailable service. Suite fixtures still require the opt-in in directory-level <code>test.yaml</code>, so one test's frontmatter cannot control the whole suite.</p>
]]></content>
        <category label="Tenzir Test"/>
        <published>2026-04-22T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.32.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-32-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-32-1"/>
        <updated>2026-04-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This patch release fixes two correctness issues in stateful pipeline execution. Partition rebuilds now complete after writing replacement partitions, and periodic summarize output remains deterministic for delayed or sparse streams.]]></summary>
        <content type="html"><![CDATA[<p>This patch release fixes two correctness issues in stateful pipeline execution. Partition rebuilds now complete after writing replacement partitions, and periodic summarize output remains deterministic for delayed or sparse streams.</p>

<h2>Bug Fixes</h2>

<h3>Partition rebuild completion</h3>
<p><small>Apr 20, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6059">#6059</a></small></p>
<p>Partition rebuilds now finish after persisting rebuilt partitions. Previously, rebuild jobs could remain stuck indefinitely even though the replacement partitions were written successfully.</p>

<h3>Deterministic periodic summarize output</h3>
<p><small>Apr 16, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>summarize</code> operator now starts <code>frequency</code>-based emission with the first
input event and emits overdue periodic results before later events are
aggregated. This makes periodic output deterministic in <code>reset</code>,
<code>cumulative</code>, and <code>update</code> modes for delayed or sparse streams.</p>
<p>For example:</p>
<pre><code class="language-tql">from {ts: 0ms.from_epoch(), x: 1},
     {ts: 90ms.from_epoch(), x: 1},
     {ts: 360ms.from_epoch(), x: 1}
delay ts
summarize count=count(), options={frequency: 300ms, mode: "cumulative"}
</code></pre>
<p>The first periodic result now consistently reports a count of <code>2</code> before the
third event arrives.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-04-21T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Platform v1.31.0]]></title>
        <id>https://docs.tenzir.com/changelog/platform/v1-31-0</id>
        <link href="https://docs.tenzir.com/changelog/platform/v1-31-0"/>
        <updated>2026-04-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release introduces organizations to the Tenzir Platform, giving teams a shared home for collaborating across workspaces with admin and member roles. Workspace management has also been enhanced with rename support and a unified Users tab for managing access.]]></summary>
        <content type="html"><![CDATA[<p>This release introduces organizations to the Tenzir Platform, giving teams a shared home for collaborating across workspaces with admin and member roles. Workspace management has also been enhanced with rename support and a unified Users tab for managing access.</p>

<h2>Features</h2>

<h3>Workspace management improvements</h3>
<p><small>Apr 21, 2026 · <a href="https://github.com/lava">@lava</a>, <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>Workspace management has been enhanced with new capabilities for administrators. You can now rename workspaces directly from the workspace settings, and the Users tab now provides a unified interface for managing workspace access. Administrators can view all users with access to a workspace in a single table and easily change user roles between member and admin roles using dropdown controls.</p>

<h3>Organizations</h3>
<p><small>Apr 21, 2026 · <a href="https://github.com/lava">@lava</a>, <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>The Tenzir Platform now supports organizations, giving teams a shared home for collaborating across workspaces. Organization admins can invite members, assign admin or member roles, and manage which workspaces belong to the organization. Members get access to all workspaces owned by the organization and can leave from their user settings at any time.</p>
<p>Learn more in the <a href="https://docs.tenzir.com/guides/platform-management/manage-organizations/">organization management guide</a>.</p>
]]></content>
        <category label="Tenzir Platform"/>
        <published>2026-04-21T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.32.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-32-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-32-0"/>
        <updated>2026-04-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Tenzir nodes now honor standard HTTP proxy environment variables when connecting to the Tenzir Platform, and hash functions produce correct checksums for binary values.]]></summary>
        <content type="html"><![CDATA[<p>Tenzir nodes now honor standard HTTP proxy environment variables when connecting to the Tenzir Platform, and hash functions produce correct checksums for binary values.</p>

<h2>Features</h2>

<h3>Platform websocket proxy support</h3>
<p><small>Apr 16, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6039">#6039</a></small></p>
<p>Tenzir nodes now honor standard HTTP proxy environment variables when connecting to Tenzir Platform:</p>
<pre><code class="language-sh">HTTPS_PROXY=http://proxy.example:3128 tenzir-node
</code></pre>
<p>Use <code>NO_PROXY</code> to bypass the proxy for selected hosts. This helps deployments where outbound connections to the Platform websocket gateway must go through an HTTP proxy.</p>

<h2>Bug Fixes</h2>

<h3>Raw-byte hashing for binary values</h3>
<p><small>Apr 16, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/6022">#6022</a></small></p>
<p>The <code>hash_*</code> functions now hash <code>blob</code> values by their raw bytes. This makes checksums computed from binary data match external tools such as <code>md5sum</code> and <code>sha256sum</code>.</p>
<p>For example:</p>
<pre><code class="language-tql">from_file "trace.pcap" {
  read_all binary=true
}
md5 = data.hash_md5()
</code></pre>
<p>This is useful for verifying file contents and round-tripping binary formats without leaving TQL.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-04-20T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Test v1.7.6]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-test/v1-7-6</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-test/v1-7-6"/>
        <updated>2026-04-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes misleading aggregate test summary percentages in the CLI. Runs with a small number of failures now report non-perfect pass and fail rates, so mixed outcomes no longer appear as `100%` passed and `0%` failed.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes misleading aggregate test summary percentages in the CLI. Runs with a small number of failures now report non-perfect pass and fail rates, so mixed outcomes no longer appear as <code>100%</code> passed and <code>0%</code> failed.</p>

<h2>Bug Fixes</h2>

<h3>Accurate aggregate pass and fail percentages</h3>
<p><small>Apr 16, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The final aggregate summary now reports non-perfect pass and fail percentages whenever at least one executed test fails. Previously, rounding could show <code>100%</code> passed and <code>0%</code> failed for runs with a small number of failures, even though the overall result was not a full success.</p>
<p>For example, a run like <code>586 passed / 1 failed / 152 skipped</code> now renders the executed-test percentages as <code>99%</code> passed and <code>1%</code> failed. This makes mixed outcomes easier to spot at a glance in the CLI output.</p>
]]></content>
        <category label="Tenzir Test"/>
        <published>2026-04-16T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Ship v1.7.2]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-ship/v1-7-2</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-ship/v1-7-2"/>
        <updated>2026-04-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This patch release removes the Node 20 deprecation warning from the reusable release workflow when it generates GitHub App tokens on GitHub-hosted runners. Repositories that call the shared release workflow now get clean release logs without extra configuration.]]></summary>
        <content type="html"><![CDATA[<p>This patch release removes the Node 20 deprecation warning from the reusable release workflow when it generates GitHub App tokens on GitHub-hosted runners. Repositories that call the shared release workflow now get clean release logs without extra configuration.</p>

<h2>Bug Fixes</h2>

<h3>Node 24 GitHub App tokens in reusable workflows</h3>
<p><small>Apr 15, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The reusable release workflow no longer emits the Node 20 deprecation warning when it generates GitHub App tokens on GitHub-hosted runners.</p>
<p>Repositories that call <code>tenzir/ship/.github/workflows/release.yaml</code> now get clean release logs without extra configuration.</p>
]]></content>
        <category label="Tenzir Ship"/>
        <published>2026-04-15T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Ship v1.7.1]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-ship/v1-7-1</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-ship/v1-7-1"/>
        <updated>2026-04-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release updates locked Python dependencies to patched upstream versions and aligns generated release commits with `v`-prefixed tags. It keeps release publishing, local development, and CI installs on maintained versions without changing normal `tenzir-ship` usage.]]></summary>
        <content type="html"><![CDATA[<p>This release updates locked Python dependencies to patched upstream versions and aligns generated release commits with <code>v</code>-prefixed tags. It keeps release publishing, local development, and CI installs on maintained versions without changing normal <code>tenzir-ship</code> usage.</p>

<h2>Bug Fixes</h2>

<h3>Patched locked Python dependencies</h3>
<p><small>Apr 15, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The repository's locked Python dependencies now use patched upstream releases, including fixes for the open security advisories reported by Dependabot.</p>
<p>This refresh keeps local development and CI installs on maintained versions without changing normal <code>tenzir-ship</code> usage.</p>

<h3>Release commit messages matching v tags</h3>
<p><small>Apr 15, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>release publish --commit</code> workflow now uses the tag-form version in generated release commits and annotated tag messages.</p>
<p>For example, publishing <code>v1.1.0</code> now creates <code>Release v1.1.0</code> instead of <code>Release 1.1.0</code>:</p>
<pre><code class="language-sh">tenzir-ship release publish v1.1.0 --commit --tag --yes
</code></pre>
<p>This keeps generated release commits aligned with the corresponding Git tag and avoids mismatches in automation that expects the <code>v</code>-prefixed release identifier.</p>
]]></content>
        <category label="Tenzir Ship"/>
        <published>2026-04-15T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.31.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-31-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-31-0"/>
        <updated>2026-04-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Tenzir now unifies live and retrospective context matching with the new `context::lookup` operator, and it adds pipeline names to diagnostics and metrics for easier operational correlation. This release also improves export reliability under load and fixes Azure transport errors, HTTP Host headers for non-standard ports, and rebuilt-partition export correctness.]]></summary>
        <content type="html"><![CDATA[<p>Tenzir now unifies live and retrospective context matching with the new <code>context::lookup</code> operator, and it adds pipeline names to diagnostics and metrics for easier operational correlation. This release also improves export reliability under load and fixes Azure transport errors, HTTP Host headers for non-standard ports, and rebuilt-partition export correctness.</p>

<h2>Features</h2>

<h3>Unified context lookups with `context::lookup` operator</h3>
<p><small>Apr 1, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a> · <a href="https://github.com/tenzir/tenzir/pull/5964">#5964</a></small></p>
<p>The <code>context::lookup</code> operator enables unified matching of events against contexts
by combining live and retrospective filtering in a single operation.</p>
<p>The operator automatically translates context updates into historical queries
while simultaneously filtering all newly ingested data against any context updates.</p>
<p>This provides:</p>
<ul>
<li><strong>Live matching</strong>: Filter incoming events through a context with <code>live=true</code></li>
<li><strong>Retrospective matching</strong>: Apply context updates to historical data with <code>retro=true</code></li>
<li><strong>Unified operation</strong>: Use both together (default) to match all events—new and historical</li>
</ul>
<p>Example usage:</p>
<pre><code class="language-tql">context::lookup "feodo", field=src_ip
where @name == "suricata.flow"
</code></pre>

<h3>Include pipeline names in diagnostics and metrics</h3>
<p><small>Mar 30, 2026 · <a href="https://github.com/IyeOnline">@IyeOnline</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5959">#5959</a></small></p>
<p>The <code>metrics</code> and <code>diagnostics</code> operators now include a <code>pipeline_name</code> field.</p>
<p>Previously, output from these operators only identified the source pipeline by its ID.
Now the human-readable name is available too, making it straightforward to filter
or group results by pipeline name without needing to look up IDs separately.</p>
<p>Please keep in mind that pipeline names are not unique.</p>

<h2>Bug Fixes</h2>

<h3>Fix crash on Azure SSL/transport errors during read and write operations</h3>
<p><small>Apr 8, 2026 · <a href="https://github.com/claude">@claude</a></small></p>
<p>Bumped Apache Arrow from 23.0.0 to 23.0.1, which includes an upstream fix
for unhandled <code>Azure::Core::Http::TransportException</code> in Arrow's
<code>AzureFileSystem</code> methods. Previously, transport-level errors (e.g., SSL
certificate failures) could crash the node during file listing, reading, or
writing. Additionally, the direct Azure SDK calls in the blob deletion code
paths now catch <code>Azure::Core::RequestFailedException</code> (the common base of
both <code>StorageException</code> and <code>TransportException</code>) instead of listing
specific exception types.</p>

<h3>Reliable export for null rows in rebuilt partitions</h3>
<p><small>Apr 7, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5988">#5988</a></small></p>
<p>The <code>export</code> operator no longer emits partially populated events from rebuilt partitions when a row is null at the record level. Previously, some events could appear with most fields set to <code>null</code> while a few values, such as <code>event_type</code> or interface fields, were still present.</p>
<p>This makes exports from rebuilt data more reliable when investigating sparse or malformed-looking events.</p>

<h3>Fix HTTP Host header missing port for non-standard ports</h3>
<p><small>Mar 31, 2026</small></p>
<p>The <code>from_http</code> and <code>http</code> operators now include the port in the <code>Host</code> header
when the URL uses a non-standard port. Previously, the port was omitted, which
caused requests to fail with HTTP 403 when the server validates the <code>Host</code>
header against the full authority, such as for pre-signed URL signature
verification.</p>

<h3>Reliable recent exports during partition flushes</h3>
<p><small>Mar 30, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The <code>export</code> command no longer fails or misses recent events when a node is flushing active partitions to disk under heavy load. Recent exports now keep the in-memory partitions they depend on alive until the snapshot completes, which preserves correctness for concurrent import and export workloads.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-04-14T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Platform v1.30.3]]></title>
        <id>https://docs.tenzir.com/changelog/platform/v1-30-3</id>
        <link href="https://docs.tenzir.com/changelog/platform/v1-30-3"/>
        <updated>2026-04-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This patch release fixes an issue with the container build of the bundled seaweedFS image.]]></summary>
        <content type="html"><![CDATA[<p>This patch release fixes an issue with the container build of the bundled seaweedFS image.</p>
]]></content>
        <category label="Tenzir Platform"/>
        <published>2026-04-09T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Platform v1.30.2]]></title>
        <id>https://docs.tenzir.com/changelog/platform/v1-30-2</id>
        <link href="https://docs.tenzir.com/changelog/platform/v1-30-2"/>
        <updated>2026-04-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes an issue where the pipeline table stayed filtered after navigating away from a pipeline's detail page. It adds thousands separators to numeric values in the Insights tab for better readability. It also updates dependencies to address security issues.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes an issue where the pipeline table stayed filtered after navigating away from a pipeline's detail page. It adds thousands separators to numeric values in the Insights tab for better readability. It also updates dependencies to address security issues.</p>

<h2>Changes</h2>

<h3>Readable numbers in the Insights tab</h3>
<p><small>Apr 7, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We added thousands separators to numeric values in the pipeline Insights tab, making large numbers easier to read at a glance.</p>

<h2>Bug Fixes</h2>

<h3>Fix pipeline table filter not clearing</h3>
<p><small>Apr 7, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We fixed an issue where the pipeline table stayed filtered after viewing a pipeline's detail page and navigating away to another tab. Returning to the Pipelines page would show only the previously viewed pipeline, and clearing the search had no effect.</p>
]]></content>
        <category label="Tenzir Platform"/>
        <published>2026-04-09T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Ship v1.7.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir-ship/v1-7-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir-ship/v1-7-0"/>
        <updated>2026-04-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The reusable release workflow now works out of the box in external repositories without requiring Tenzir-org-specific secrets.]]></summary>
        <content type="html"><![CDATA[<p>The reusable release workflow now works out of the box in external repositories without requiring Tenzir-org-specific secrets.</p>

<h2>Changes</h2>

<h3>Simplify reusable release workflow and decouple Tenzir org secrets</h3>
<p><small>Mar 12, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a></small></p>
<p>The reusable GitHub Actions release workflow now works in external repositories by default. It falls back to the caller repository's <code>GITHUB_TOKEN</code>, makes GitHub App authentication optional, and only enables GPG signing when a caller provides a signing key and opts into commit and/or tag signing. The single <code>release.yaml</code> workflow now also exposes the advanced hooks and release controls directly, including <code>skip-publish</code> for dry runs and smoke tests. Tenzir repositories can still opt into the existing bot identity, GitHub App token flow, and signed commits and tags by passing those settings explicitly.</p>
]]></content>
        <category label="Tenzir Ship"/>
        <published>2026-04-03T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Platform v1.30.1]]></title>
        <id>https://docs.tenzir.com/changelog/platform/v1-30-1</id>
        <link href="https://docs.tenzir.com/changelog/platform/v1-30-1"/>
        <updated>2026-04-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release fixes an issue that prevented users from accessing the public Tenzir Platform instance at app.tenzir.com.]]></summary>
        <content type="html"><![CDATA[<p>This release fixes an issue that prevented users from accessing the public Tenzir Platform instance at app.tenzir.com.</p>
]]></content>
        <category label="Tenzir Platform"/>
        <published>2026-04-02T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Platform v1.30.0]]></title>
        <id>https://docs.tenzir.com/changelog/platform/v1-30-0</id>
        <link href="https://docs.tenzir.com/changelog/platform/v1-30-0"/>
        <updated>2026-04-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release introduces a new Stream view in the Explorer that displays pipeline results as a continuous, expandable event list. It also adds a time range selector, sortable table columns, and copyable inspector values, alongside several bug fixes for package management and the library view.]]></summary>
        <content type="html"><![CDATA[<p>This release introduces a new Stream view in the Explorer that displays pipeline results as a continuous, expandable event list. It also adds a time range selector, sortable table columns, and copyable inspector values, alongside several bug fixes for package management and the library view.</p>

<h2>Features</h2>

<h3>Field selection in the table view</h3>
<p><small>Mar 27, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>You can now choose which fields are visible in the Explorer's table view. When you select a schema in the sidebar, its fields are listed below. Click a field to hide its column from the table. Shift+click a field to show only that field. A "fields hidden" indicator in the table header lets you clear all hidden fields at once. Field selections are remembered per schema and reset when you run a new pipeline.</p>

<h3>Schema filtering in the Stream view</h3>
<p><small>Mar 26, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>You can now filter events in the Stream view by clicking schemas in the sidebar. The schemas panel shows color-coded dots matching each schema's badge color, and selecting one or more schemas limits the view to only those events. Same-name schema variants are merged into a single entry in the sidebar for easier navigation.</p>

<h3>Stream view in the Explorer</h3>
<p><small>Mar 26, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We added a new Stream view to the Explorer that shows all pipeline results as a continuous list of expandable events. You can switch between the Table, Chart, and Stream views using the view selector in the toolbar. The Stream view displays events from all schemas together, with color-coded badges to distinguish between them. Each row shows a one-line preview that you can expand to inspect the full event. The view remembers your selection across pipeline runs, and the event list scrolls horizontally as a whole, with schema badges staying pinned on the left.</p>

<h3>Sortable columns in the Explorer table</h3>
<p><small>Mar 13, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>You can now sort the Explorer table by clicking column headers. Sortable columns show a sort indicator, and clicking cycles through ascending, descending, and unsorted states. Sorting works for both top-level and nested fields.</p>

<h3>Copyable field names and values in the inspector</h3>
<p><small>Mar 12, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>You can now click on field names and values in the Explorer inspector to copy them to the clipboard. Field names copy the full dot-separated path, and values copy their TQL representation.</p>

<h3>Time range selector in the Explorer</h3>
<p><small>Mar 12, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>You can now select a time range directly from the Explorer header. Choose from quick presets like 5 minutes or 12 hours, or open the custom popover to pick from a grid of relative durations or set an absolute date range. The selector is currently available for pipelines that start with the <code>export</code> operator.</p>

<h2>Changes</h2>

<h3>Unified package detail view in the library</h3>
<p><small>Mar 12, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We combined the 'About' and 'Install' tabs in the package detail drawer into a single scrollable view. Package information, examples, and configuration options are now shown on one page instead of requiring tab switches.</p>

<h2>Bug Fixes</h2>

<h3>Prevent renaming a node to an empty string</h3>
<p><small>Apr 1, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We fixed an issue where a node could be renamed to an empty string, causing the app to malfunction. Node names are now properly validated, so empty or whitespace-only names are no longer allowed.</p>

<h3>Fix stale token when switching disconnected nodes</h3>
<p><small>Apr 1, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We fixed an issue where the connection token shown in the "Connect node" dialog did not update when switching between different disconnected nodes. The token now correctly refreshes for the selected node.</p>

<h3>Show custom packages in the library view</h3>
<p><small>Mar 24, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We fixed an issue where custom packages installed on a node were not visible in the library view. Previously, only packages from the official Tenzir library were shown. Custom packages are now included alongside library packages.</p>

<h3>Fix rotated text in package detail accordion</h3>
<p><small>Mar 24, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>We fixed a bug where operator description text on the package detail page appeared rotated 90 degrees, overlapping other content.</p>

<h3>Package installs for packages with user-defined operators</h3>
<p><small>Mar 17, 2026 · <a href="https://github.com/gitryder">@gitryder</a></small></p>
<p>Packages containing user-defined operators can again be installed through the
platform. Previously, installing such packages failed because the operator
arguments were serialized incorrectly. This only affected installs through the
platform UI—command-line package installs were not impacted.</p>
]]></content>
        <category label="Tenzir Platform"/>
        <published>2026-04-02T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Tenzir Node v5.30.0]]></title>
        <id>https://docs.tenzir.com/changelog/tenzir/v5-30-0</id>
        <link href="https://docs.tenzir.com/changelog/tenzir/v5-30-0"/>
        <updated>2026-03-31T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This release adds OIDC web identity authentication for AWS operators, so you can assume AWS roles from external identity providers without long-lived credentials. It also speeds up logical and conditional expression evaluation and fixes several crashes and configuration diagnostics.]]></summary>
        <content type="html"><![CDATA[<p>This release adds OIDC web identity authentication for AWS operators, so you can assume AWS roles from external identity providers without long-lived credentials. It also speeds up logical and conditional expression evaluation and fixes several crashes and configuration diagnostics.</p>

<h2>Features</h2>

<h3>OIDC web identity authentication for AWS operators</h3>
<p><small>Feb 4, 2026 · <a href="https://github.com/tobim">@tobim</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5703">#5703</a></small></p>
<p>AWS operators now support OIDC-based authentication via the <code>AssumeRoleWithWebIdentity</code> API.</p>
<p>You can authenticate with AWS resources using OpenID Connect tokens from external identity providers like Azure, Google Cloud, or custom endpoints. This enables secure cross-cloud authentication without sharing long-lived AWS credentials.</p>
<p>Configure web identity authentication in any AWS operator by specifying a token source and target role:</p>
<pre><code>from_s3 "s3://bucket/path", aws_iam={
  region: "us-east-1",
  assume_role: "arn:aws:iam::123456789012:role/cross-cloud-role",
  web_identity: {
    token_file: "/path/to/oidc/token"
  }
}
</code></pre>
<p>The <code>web_identity</code> option accepts three token sources: <code>token_file</code> (path to a token file), <code>token_endpoint</code> (HTTP endpoint that returns a token), or <code>token</code> (direct token value). For HTTP endpoints, you can extract tokens from JSON responses using <code>path</code>.</p>
<p>Credentials automatically refresh before expiration, with exponential backoff retry logic for transient failures. This is especially useful for long-running pipelines that need persistent authentication.</p>

<h2>Changes</h2>

<h3>Faster evaluation of logical and conditional expressions</h3>
<p><small>Mar 30, 2026 · <a href="https://github.com/jachris">@jachris</a> · <a href="https://github.com/tenzir/tenzir/pull/5954">#5954</a></small></p>
<p>Pipelines that use <code>and</code>, <code>or</code>, or <code>if</code>-<code>else</code> expressions run significantly faster in certain cases — up to <strong>30×</strong> in our benchmarks. The improvement is most noticeable in pipelines with complex filtering or branching logic. No pipeline changes are needed to benefit.</p>

<h3>OCSF 1.8.0 support in ocsf::derive</h3>
<p><small>Mar 23, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/codex">@codex</a> · <a href="https://github.com/tenzir/tenzir/pull/5939">#5939</a></small></p>
<p>The <code>ocsf::derive</code> operator now supports OCSF <code>1.8.0</code> events.</p>
<p>For example, you can now derive enum and sibling fields for events that declare
<code>metadata.version: "1.8.0"</code>:</p>
<pre><code class="language-tql">from {metadata: {version: "1.8.0"}, class_uid: 1007}
ocsf::derive
</code></pre>
<p>This keeps OCSF normalization pipelines working when producers emit <code>1.8.0</code>
events.</p>

<h3>Platform configuration error message</h3>
<p><small>Feb 10, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/5341">#5341</a></small></p>
<p>Platform configuration validation now provides clearer error messages when an invalid configuration is encountered, helping you quickly diagnose and fix configuration issues.</p>

<h2>Bug Fixes</h2>

<h3>Fix crash when connecting to unresolvable host</h3>
<p><small>Mar 26, 2026 · <a href="https://github.com/lava">@lava</a> · <a href="https://github.com/tenzir/tenzir/pull/5827">#5827</a></small></p>
<p>Setting <code>TENZIR_ENDPOINT</code> to an unresolvable hostname no longer crashes the pipeline with a segfault.</p>

<h3>Spurious warning for Other (99) enum sibling in ocsf::derive</h3>
<p><small>Mar 25, 2026 · <a href="https://github.com/mavam">@mavam</a>, <a href="https://github.com/claude">@claude</a> · <a href="https://github.com/tenzir/tenzir/pull/5949">#5949</a></small></p>
<p><code>ocsf::derive</code> no longer emits a false warning when an <code>_id</code> field is set
to <code>99</code> (Other) and the sibling string contains a source-specific value.</p>
<p>Per the OCSF specification, <code>99</code>/Other is an explicit escape hatch: the
integer signals that the value is not in the schema's enumeration and the
companion string <strong>must</strong> hold the raw value from the data source. For
example, the following is now accepted silently:</p>
<pre><code class="language-tql">from {
  metadata: { version: "1.7.0" },
  type_uid: 300201,
  class_uid: 3002,
  auth_protocol_id: 99,
  auth_protocol: "Negotiate",
}
ocsf::derive
</code></pre>
<p>Previously this produced a spurious <code>warning: found invalid value for 'auth_protocol'</code> because <code>"Negotiate"</code> is not a named enum caption.</p>

<h3>Fix crash on Azure SSL/transport errors</h3>
<p><small>Mar 24, 2026 · <a href="https://github.com/lava">@lava</a></small></p>
<p>The Azure Blob Storage connector now handles <code>Azure::Core::Http::TransportException</code>
(e.g., SSL certificate errors) gracefully instead of crashing. Previously, a
self-signed certificate in the certificate chain would cause an unhandled
exception and terminate the node.</p>
]]></content>
        <category label="Tenzir Node"/>
        <published>2026-03-31T00:00:00.000Z</published>
    </entry>
</feed>