Repository navigation
v0.20.0
v0.20.0 is the first stable release since v0.19.0 (2026-07-24). It adds conduit generate, which
writes a pipeline config from a plain-English description; a Postgres-to-pgvector RAG pipeline
template with new chunking and embedding processors; outbound HTTP for WASM processors, closed by
default; and signed release artifacts. It fixes a SEV-0 bug, present in v0.19.0, where a Postgres
snapshot-to-CDC handoff could stall silently, and a gRPC server panic. It also changes how stopped
pipelines are reported and recovered; read Behavior changes before you
upgrade. The default pipeline engine is unchanged. The RAG pipeline needs the preview engine
(arch-v2).
Upgrading from v0.19.0
Upgrade if you run v0.19.0:
- SEV-0 snapshot-to-CDC stall. In v0.19.0 the Postgres source could stop after its snapshot
without starting CDC. Inserts, updates and deletes after the snapshot were not delivered, there
was no error, and the pipeline still showed running. Fixed in this release. - gRPC advisory GO-2026-6443. v0.19.0 ships grpc v1.82.1, which can panic on a request with no
:authorityorHostheader. v0.20.0 ships v1.83.2.
Check these before you upgrade:
- Stop and shutdown status. A force stop is now
UserStopped, notDegraded, and no longer
triggerspipelines.exit-on-degraded. Stopped pipelines can carry an error message. Pipelines
stopped by a shutdown areSystemStoppedand start again on the next boot. If you alert on
Degradedor on status alone, see Behavior changes. - Error text. Fan-out on the default engine now fails with
pipeline.fanout_requires_arch_v2,
andStartduring shutdown fails withpipeline.shutting_down. Update anything that matches on
error text. - Community links. The Discord invite is gone. Use
GitHub Discussions. Docs links now point to
conduitdata.io;conduit.iono longer resolves. - Mirrors. If you mirror releases, also copy
checksums.txt.sigstore.jsonand the
.sbom.jsonfiles.
Highlights
conduit generate (preview)
conduit generate "<description>" writes a pipeline config file using Anthropic, OpenAI or a local
Ollama server. Set ANTHROPIC_API_KEY or OPENAI_API_KEY, or run Ollama, and pick one with
--provider if more than one is available. Every candidate goes through the same offline check as
conduit pipelines validate, including that each connector it names exists, and the command never
writes an invalid config. It does not deploy anything: there is no --apply flag, and deploying is
the usual conduit pipelines deploy step.
The command is a preview. Review what it writes before you deploy it. On our 28-request test
corpus with Claude Sonnet 5, every generated config validated, and about two in three (64–68%
over three runs) matched what the request asked for. It is reliable at picking connectors
(45/45 on requests that need no processor) and often leaves out a requested processor step (8/39
on requests that need one). These are measurements from one model on a small corpus. A weekly
eval tracks them from v0.20.1, and processor-aware generation is planned for v0.21.
Correction (2026-10-12): the semantic-match and processor figures above understate
conduit generate. Our scorer did not accept processor names written with thebuiltin:prefix,
which is the form the prompt tells the model to use, so some correct pipelines were scored as
missing a processor. Rescoring the same recorded outputs with the fixed scorer moves the corpus
from 18 to 22 of 28 matched requests. The validation result is unaffected. Corrected numbers,
measured on fresh runs, will be in the v0.20.1 release notes.
conduit generate "read from postgres and write new rows to s3 as json" --out pg-to-s3.yaml
conduit pipelines validate pg-to-s3.yaml--json is supported.
RAG pipeline template (requires the preview engine and egress)
The postgres-pgvector-rag template reads Postgres (snapshot, then CDC), splits text with
ai.chunk, embeds it with ai.embed, and upserts into pgvector. Writes are keyed so redelivery
and updates converge to one row per chunk, and deleting a source row deletes every chunk made from
it.
It needs two things the defaults don't give you:
- The preview engine,
--preview.pipeline-arch-v2.ai.chunkturns one record into many,
and the default engine passes one record in and one out. On the default engine the pipeline
stops at the chunk step withpipeline.fanout_requires_arch_v2. - The egress ceiling. WASM processors have no network access unless the operator allows it.
The template already setsollama.baseURL: http://127.0.0.1:11434and
sdk.egress.allow: http://127.0.0.1:11434on the embed processor. You open the ceiling with
--processors.egress.enabled --processors.egress.allow http://127.0.0.1:11434, or
processors.egress.enabled: trueandprocessors.egress.allow: [http://127.0.0.1:11434]in
conduit.yaml. Without it every embed call fails with
http egress is not enabled for this processorand the record is nacked.
Use the IP literal. The egress gate rejects http://localhost:11434 as an allowlist entry and
only admits loopback through an exact IP:port entry. If you scaffolded this template from a
nightly up to and including v0.20.0-nightly.20261007, change ollama.baseURL to http://127.0.0.1:11434 and add
sdk.egress.allow: http://127.0.0.1:11434 to the embed processor, or scaffold it again.
conduit pipelines init --template postgres-pgvector-rag # prints the prerequisites
conduit connectors install pgvector
conduit processor-plugins install ai.chunk
conduit processor-plugins install ai.embed
conduit run --preview.pipeline-arch-v2 \
--processors.egress.enabled --processors.egress.allow http://127.0.0.1:11434Create the pgvector table first; the template README has the SQL and the settings for a hosted
provider such as OpenAI. ai.chunk and ai.embed (0.1.0) require Conduit 0.20.0 or later.
conduit-connector-pgvector v0.1.0 is a standalone connector, not built in.
Registry installs depend on a fresh signature on the hosted index. The client refuses an index
signed more than 7 days ago with registry.index_stale. For offline or air-gapped hosts, use
--index-file (a local signed index) or --bundle (a signed bundle).
The flag is temporary. Conduit is moving to a single pipeline engine that supports one-to-many
processors, fan-out and multiple sources and destinations, so you won't have to choose. Until that
engine is the default, the RAG template needs --preview.pipeline-arch-v2. Once it is, the flag
will be accepted and ignored with a deprecation warning before it is removed. We make no
performance claims for arch-v2 and don't recommend it for pipelines that don't need fan-out.
Host egress for WASM processors (processor SDK v0.6.0)
Standalone (WASM) processors can make outbound HTTP calls through the host. ai.embed uses this
to reach its embedding provider. Egress is closed by default. A processor gets it only when the
operator opens the instance ceiling (processors.egress.*) and the pipeline opts that processor in
with sdk.egress.allow; the effective allowlist is where the two overlap. Addresses are checked
again when the connection is made, so a hostname that resolves to a private, link-local or
metadata address is refused. Credentials stay on the host: grant a name in
processors.egress.secret-refs, export CONDUIT_SECRET_<NAME>, and the host injects the
Authorization header. The secret never enters the guest. Build processors against
github.com/conduitio/conduit-processor-sdk v0.6.0. Older processors work unchanged.
Configuration reference: README, "Processor host egress".
conduit processor-plugins install / uninstall
Installs WASM processors from the signed registry, with the same signature and SLSA provenance
checks as conduit connectors install. Offline installs work with --index-file or --bundle.
uninstall refuses to remove a processor that a pipeline still uses.
conduit processor-plugins install ai.chunk --dry-run --jsonThe registry index now lists processors next to connectors. The change is additive, so older
clients ignore processor entries and keep installing connectors.
Signed releases
From this release on, every release and nightly is signed with Sigstore keyless signing through
GitHub Actions OIDC. There is no long-lived key. checksums.txt is signed
(checksums.txt.sigstore.json), and since it lists every archive, package and SBOM, one signature
covers all of them. Each archive comes with an SPDX SBOM (<archive>.sbom.json). The Docker image
on GHCR is signed by digest. See the snippet at the end of these notes or
"Verifying a release".
Releases up to and including v0.19.0 are not signed. macOS binaries are not notarized yet.
CI gates
The chaos suite (tests/chaos) is a required check on main and runs on every PR and nightly. It
SIGKILLs pipelines mid-snapshot, mid-batch and mid-checkpoint, then checks for loss and position
correctness on recovery. govulncheck runs on every PR, push to main and nightly, and fails a PR
that makes a new vulnerability reachable. bundle-e2e (WASM egress) and rag-e2e (chunk, embed,
pgvector) are also required.
Behavior changes
Stopped pipelines are never recovered (#2901)
Both engines. Details:
ADR 20261007.
- Once a stop is requested, by you or by shutdown, the pipeline is not sent into recovery and not
restarted. - A user
Stop, graceful or force, endsUserStopped. If the drain hit an error, the error is
kept. - A force stop is now
UserStoppedwithforce stoprecorded. It wasDegraded. It no longer
runs OnFailure handlers, so it no longer shuts Conduit down underpipelines.exit-on-degraded. - A shutdown, graceful or not, ends
SystemStoppedwith any error kept. Those pipelines start
again on the next boot and resume from their last persisted position. - Under
exit-on-degraded, only the pipeline whose own fatal error triggered the exit is
Degraded. The other pipelines areSystemStoppedwith the reason recorded and auto-start next
boot. Before, they were alsoDegradedand needed a manual start. Startand recovery restarts during shutdown are refused withpipeline.shutting_down(gRPC
Unavailable).- A shutdown during a recovery backoff completes at once instead of waiting out the backoff or the
30s exit timeout. - Drain errors are kept: shutdown returns them as its error, and arch-v2 now records them on the
pipeline. - A stopped pipeline can carry a non-empty error. It means the drain did not end cleanly; the
affected records were nacked and replay on the next start. Dashboards that alert only on
Degradedno longer see drain failures. Alert on the error field of stopped pipelines too. pipeline_recovering_countno longer counts a run whose stop was requested before it failed.
| Case | v0.19.0 | v0.20.0 | Error kept | OnFailure |
|---|---|---|---|---|
User Stop, clean drain |
UserStopped | UserStopped | — | no |
User Stop, error during drain |
default engine: recovered and restarted; arch-v2: UserStopped, error dropped | UserStopped | yes | no |
| User force stop | Degraded | UserStopped | force stop |
no (was yes) |
User Stop during recovery backoff |
restarted after the backoff | UserStopped | original error | no |
| Shutdown, clean drain | SystemStopped | SystemStopped | — | no |
| Shutdown with an error (drain error, runtime error, exit-on-degraded) | default engine: restarted during shutdown, or Degraded if the cause was fatal; arch-v2: error dropped | SystemStopped, auto-starts next boot | yes | no (was yes when Degraded) |
| Fatal error before any stop | Degraded | Degraded | yes | yes |
| Transient error, no stop | Recovering, then restarted | unchanged | — | — |
Start during shutdown |
could start | refused, pipeline.shutting_down |
— | — |
Other changes
- Built-in connectors: postgres v0.14.0 → v0.14.2, kafka v0.12.3 → v0.12.5, file v0.10.3 →
v0.10.8, log v0.7.3 → v0.7.5. Dependency updates and re-releases with signed artifacts, no
feature changes. - New error code
pipeline.fanout_requires_arch_v2replacesunknown record type: sdk.MultiRecordwhen a fan-out processor runs on the default engine. --preview.pipeline-arch-v2still defaults to off. Its help text now says what it is for
and names one limit: a split record whose pieces are cut across a multi-destination fan-out fails
withpipeline.split_run_straddles_fanout.- New
processors.egress.*settings (enabled,allow,secret-refs,timeout,
max-response-bytes). With the defaultenabled: falsenothing changes. Processor settings
undersdk.egress.*are reserved for the host and are no longer passed to the processor. - Settings are redacted in API responses. Connector, processor and DLQ setting values come
back as"***". Requests must send real values (see Known issues, #2913). - Embedded Conduit with the API enabled (#2747):
/metricsserves from the registry you pass
in. AMetricsRegistererthat is not also aprometheus.Gatherernow makes the firstRunor
ImportreturnCodeInvalidArgument; before, it started and served unrelated default metrics. - Prerelease builds and
minConduitVersion(#2822): a v0.20.0 nightly now satisfies a
minConduitVersionof 0.20.0.
Fixes
- SEV-0: Postgres snapshot-to-CDC handoff could stall silently (#2707). Present in v0.19.0. An
ack the source waits for at the end of a snapshot could be dropped under load, so CDC never
started and later changes were never delivered, with no error and no DLQ entry. Found before
release by the RAG e2e; no production occurrence is known. Postmortem:
docs/postmortems/20260729-snapshot-handoff-deferred-ack-deadlock.md. - Connector state write errors were ignored, so a source could ack upstream without a saved
position (#2925). Present since 2023, including v0.19.0. If saving one connector's state failed
inside an otherwise healthy write, the error was only logged, the write was committed without it,
and the source was told the position was saved. It then released its upstream ack (for example a
Postgres slot advance or a Kafka offset commit), so after a restart those records could be lost.
The failure now aborts the write and fails the pipeline instead. - gRPC server panic, GO-2026-6443 / CVE-2026-84445 (#2881). A request with no
:authorityor
Hostheader could panic the gRPC API server. v0.19.0 ships the affected grpc v1.82.1; v0.20.0
pins the fixed v1.83.2. - Go standard library advisories (#2914). Moving to Go 1.25.14 clears the 20 standard-library
advisories govulncheck found reachable in the Conduit binary. - HTTP/2 server advisories GO-2026-6603, -6611, -6612, -6617 (#2970). A malicious HTTP/2 client
could crash the API server, exhaust its memory or CPU, or corrupt flow control. v0.20.0 builds
with Go 1.26.9 and golang.org/x/net v0.60.0, which fix all four. Go 1.25 gets no fix upstream, so
building Conduit from source or embedding it now requires Go 1.26 or newer. - Shutdown could restart pipelines and write positions after the database closed (#2901). On a
non-graceful shutdown, or a transient error during a userStop, the default engine sent
pipelines into recovery and restarted them. During shutdown, a restarted run could write
positions after the database was closed. Fixed by the stop semantics above. - Failed pipeline reported as
UserStopped(#2896). Default engine. A node error could leave a
pipeline marked user-stopped with no error, skipping OnFailure and recovery, so a transient error
stopped the pipeline for good. No data loss. - arch-v2: run cleanup could erase a live run (#2811). If a status write failed during a
recovery restart, the superseded run's cleanup could remove the live run, which then could not be
stopped or waited on. - Process panic on shutdown of a multi-source pipeline (#2749). Shutting down a pipeline with
two or more sources could crash Conduit withsync: WaitGroup is reused. Reproduced on v0.19.0. - Recovered pipeline reported with its old error; shutdown could close the DB under a live run
(#2807, #2812). Default engine, on recovery restarts. conduit initthenconduit runfailed out of the box (#2855). The generatedconduit.yaml
wrote empty lists as the string'[]', whichconduit runrejected.conduit pipelines initwith no arguments failed outside a workspace (#2857). It now creates
pipelines/, and remaining failures return a validation code with the OS error and a fix.processor-plugins installrefused every processor (#2818). Fixed before any stable release
shipped the command.- Other arch-v2 fixes: destination-scoped processors run before the write (#2805); split records
hold back their source position until every piece is done (#2731); nack and retry bounds (#2732,
#2733); empty batch and empty position guards (#2738, #2744).
Known issues
- arch-v2: destination batching can stall (#2979). On
--preview.pipeline-arch-v2, a destination
withsdk.batch.sizeabove 1 and the defaultsdk.batch.delayof 0 can stop delivering, and with a
delay set it slows to roughly one batch delay per record. The defaults and the RAG template are not
affected. On arch-v2, don't setsdk.batch.sizeon destinations. v0.20.1 refuses that
configuration at start with an actionable error. - Shutdown can hang if a source fails at the same moment (#2969). Default engine, present in
v0.19.0. If a source errors just as Conduit is stopping, shutdown can block indefinitely. No data
is lost: kill the process and the unacked records are replayed on restart. Fix planned for
v0.20.1. - Postgres CDC can lose a row on restart when transactions interleave
(conduit-connector-postgres#331). Present since 2022, including v0.19.0. Trigger: a transaction
that started before the last checkpoint commits after it while other transactions commit in
between (for example a long-running transaction alongside short ones), and then Conduit
restarts. On resume, that transaction's changes are skipped and never delivered. Restarts with
no long-running transaction in flight are not affected. Fixed in Postgres connector v0.14.3
(released 2026-10-08), which becomes the built-in connector in v0.20.1. - Postgres CDC can lose rows loaded in one statement (for example
COPYor a multi-row
insert) if Conduit restarts partway through them. Present in v0.19.0 and earlier. Postgres
gives all rows from such a statement the same log position, so after a restart between two of
them the rest are skipped, and the connector can confirm progress past rows it has not
delivered yet. Fixed in the same v0.20.1 connector patch. - Avro decoder advisories GO-2026-5046, GO-2026-5047, GO-2026-5048 (CPU exhaustion, integer
overflow, unbounded map allocation inhamba/avro, archived upstream with no fix). Reachable when
Conduit decodes untrusted Avro through the built-in Avro processor, or through the built-in
Postgres connector's schema extraction. v0.20.1 partly mitigates them (conduit-commons v0.7.0 caps Avro arrays and maps at
1,000,000 elements). v0.21 clears them by moving to a maintained fork. - #2929 (arch-v2 preview engine): a persistent connector-state write failure stalls without
a status signal. No data is lost: upstream acks are withheld (#2925). But the pipeline keeps
reporting healthy, logs one error per flush, and the upstream keeps retention, for example a
growing Postgres replication slot. Transient failures recover on their own. Very unlikely on the
default store for single-source pipelines such as the RAG template. Watch replication-slot lag. - #2898 (default engine): a failed
Runningstatus write can orphan a live run. Trigger: a
transient pipeline-store write failure on start. Impact: a run that can't be stopped or drained;
starting it again puts two readers on one source (duplicates, positions can move backwards). - #2899 (both engines): a failed status write during recovery can leave a live run
Degraded.
Trigger: a status-store write failure during recovery. Impact: the run keeps going, can't be
stopped, can be started twice, and can trip exit-on-degraded. - #2900 (default engine): source teardown waits its full 10s after a plugin stream error.
Trigger: a source plugin's stream ends with an error. Impact: about 10s of extra delay before
Degraded/Recovering and on shutdown. No data loss. - #2913: sending a redacted settings map back stores
"***"as the value. Trigger: an API
update that echoes settings read from the API. Impact: the real secret is overwritten. Send real
values. - #2908:
generate.providerinconduit.yamlis not read. Use--provider. - #2907:
processor-plugins install/uninstall --helplist the wrong exit codes. postgres-s3template is not verified end to end. The built-in S3 connector (v0.9.3) fails
against MinIO and other S3-compatible stores; the fix needs an S3 connector release with
conduit-connector-s3#994 and reaches Conduit in v0.21. The template targets AWS S3.
Deferred
- A single pipeline engine. Instead of switching the default to arch-v2, v0.21 designs and
prototypes one engine that keeps arch-v2's batching and fan-out and runs pipeline stages
concurrently, as the default engine does. The target is to make it the default in v0.22, after
it matches or beats the current default on throughput and passes the chaos suite. - Debezium-parity Postgres CDC → v0.21. The built-in Postgres connector stays at v0.14.2 until
then. - Protobuf decode (Confluent wire format) → v0.21.
- → v0.22: embedded Conduit with external connectors (embed Slice 2), a Node client, a Qdrant
destination, and a source-side DLQ path. - Python connector SDK and
conduit-clientGA ship on their own schedule. Neither blocks this
release.
Verify this release
Requires cosign v3 or later.
Download checksums.txt, checksums.txt.sigstore.json and the files you want into one directory,
then:
cosign verify-blob \
--certificate-identity 'https://github.com/ConduitIO/conduit/.github/workflows/release.yml@refs/tags/v0.20.0' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
--bundle checksums.txt.sigstore.json \
checksums.txt
# only once the signature verifies (on macOS: shasum -a 256 --check --ignore-missing)
sha256sum --check --ignore-missing checksums.txtThe Docker image:
cosign verify \
--certificate-identity 'https://github.com/ConduitIO/conduit/.github/workflows/release.yml@refs/tags/v0.20.0' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
ghcr.io/conduitio/conduit:v0.20.0cosign verify resolves the tag to a digest and checks the signature on that digest. To pin what
you run, use the digest it prints: ghcr.io/conduitio/conduit@sha256:....
Full changelog: v0.19.0...v0.20.0
Commit list
Changelog
- f00813d: Go tools: bump github.com/docker/cli in /tools (#2440) (@dependabot[bot])
- 4aad940: Go tools: bump github.com/google/cel-go from 0.24.1 to 0.29.0 in /tools (#2689) (@dependabot[bot])
- c60003b: Go tools: bump github.com/moby/sys/user from 0.4.0 to 0.4.1 in /tools (#2972) (@dependabot[bot])
- fc812a5: bench(archv2): benchmark methodology + retraction of the v1-vs-v2 numbers (#2748) (@devarismeroxa)
- 0ef64e1: bench(funnel): in-process engine benchmarks — the mutex is not the cost, fan-out is (#2754) (@devarismeroxa)
- a7018b7: build(release): sign releases and images with keyless cosign, add SBOMs (#2892) (@devarismeroxa)
- 5526eec: build: bump Go toolchain to 1.25.14 (#2914) (@devarismeroxa)
- a0e990f: chore: record the trimmed govulncheck baseline, hold golang images on 1.25 (#2916) (@devarismeroxa)
- 39bec9c: ci(chaos): make the chaos gate always report so it can be a required check (#2690) (@devarismeroxa)
- 76743db: ci(security): add a govulncheck ratchet and correct the gates CLAUDE.md claims are live (#2816) (@devarismeroxa)
- d6b33de: ci: bump actions/setup-go from 5 to 6 (#2383) (@dependabot[bot])
- b4c92b0: ci: exclude load-bearing deps from dependabot auto-merge (#2890) (@devarismeroxa)
- 10e1f56: ci: restructure bundle-e2e/rag-e2e to always-report + pin sibling refs (toward required) (#2714) (@devarismeroxa)
- 54631b6: ci: run the chaos suite (tests/chaos) as an enforced gate (v0.20 WS0) (#2686) (@devarismeroxa)
- 2a2d8c9: docker-compose: bump postgres from 17 to 18 in /test (#2393) (@dependabot[bot])
- 516e361: docs(adr): arch-v2 graduation is a v0.21 go/no-go against a fixed gate (#2906) (@devarismeroxa)
- 70e914e: docs(adr): scope a columnar record representation to arch-v2 exploration (#2826) (@devarismeroxa)
- b3b611b: docs(api): describe stopped status and error after the stop-semantics change (#2917) (@devarismeroxa)
- 439441d: docs(api): state that Settings values are redacted in API responses (#2891) (@devarismeroxa)
- 1b1337a: docs(design): AI-pipeline components (v0.20 WS8) (#2687) (@devarismeroxa)
- 159e355: docs(design): DBZ-2 CDC correctness / acceptance-test suite (v0.20 WS6) (#2692) (@devarismeroxa)
- 20a2875: docs(design): DLQ record visibility — descope record-reading for v0.18, defer Tier-1 store (#2639) (@devarismeroxa)
- 2a605ee: docs(design): WASM host-egress capability (AI-pipeline prerequisite, SSRF-hardened) (#2696) (@devarismeroxa)
- 7486372: docs(design): add Protobuf schema support design doc (#2827) (@devarismeroxa)
- cd0222e: docs(design): amend generate §8 with generate.destination_exists (#2798) (@devarismeroxa)
- c073543: docs(design): decide fork vs replace vs accept for archived hamba/avro (#2823) (@devarismeroxa)
- 051bdbe: docs(design): embed Slice-2 external-connector addendum (v0.20 WS3) (#2688) (@devarismeroxa)
- df8ecd2: docs(generate): label conduit generate as preview in --help (#2934) (@devarismeroxa)
- 7958be2: docs(pipelines): point RAG template preflight at the shipped processor-plugins install (PR-E) (#2713) (@devarismeroxa)
- e68d0b3: docs(postmortem): verify MySQL/Mongo not in the Source.Ack gap class (#2691) (@devarismeroxa)
- 2d26ec5: docs(postmortems): snapshot-handoff deferred-ack deadlock (SEV-0, follow-on of #2680) (#2709) (@devarismeroxa)
- abf348b: docs(roadmap): state what the template gallery actually ships, and the registry freshness gap (#2802) (@devarismeroxa)
- 5f315cd: docs(templates): install pgvector from the registry in postgres-pgvector-rag (#2915) (@devarismeroxa)
- 0b7853e: feat(chaos): DBZ-2 Phase 1a — CDC correctness Properties 1, 2, 3 (#2693) (@devarismeroxa)
- b55f9c4: feat(cli): conduit processor-plugins install/uninstall + Tranche-A offline install (PR-C) (#2712) (@devarismeroxa)
- b6e255e: feat(deps): bump conduit-processor-sdk to v0.6.0 (#2905) (@devarismeroxa)
- 3069af6: feat(egress): env-backed SecretResolver — host-inject AuthSecretRef credentials (#2700) (@devarismeroxa)
- 4e87748: feat(foundation): add fuzzymatch for did-you-mean connector suggestions (#2769) (@devarismeroxa)
- 62ab007: feat(generate): capture tool and workflow for provider transcripts (WS1 A5a-3) (#2808) (@devarismeroxa)
- 0e087d0: feat(generate): committed provider-transcript format, loader, redaction scanner, and replay provider (WS1 A5a-2) (#2804) (@devarismeroxa)
- 4963202: feat(generate): give the file-exists case its own error code (#2799) (@devarismeroxa)
- 488db38: feat(generate): in-memory validate seam + provider resolution (WS1 seams) (#2772) (@devarismeroxa)
- d98a1d4: feat(generate): judge a candidate against what the prompt asked for (#2790) (@devarismeroxa)
- d17aa5f: feat(generate): openai, anthropic and ollama provider adapters (WS1) (#2775) (@devarismeroxa)
- c8150ef: feat(generate): wire the
conduit generatecommand (#2791) (@devarismeroxa) - a980aa0: feat(lifecycle): actionable error when a fan-out processor runs on the classic engine (#2715) (@devarismeroxa)
- 9729b5b: feat(lifecycle-poc): M-destination fan-out with per-record ack accounting (3a) (#2721) (@devarismeroxa)
- cbe697c: feat(lifecycle-poc): N-source topology with shared-sink teardown ordering (3b) (#2734) (@devarismeroxa)
- 8b442be: feat(lifecycle-poc): drain-safe StopAndWait/ReconfigureProcessor for arch-v2 (#2720) (@devarismeroxa)
- a61d4bc: feat(lifecycle-poc): port pipeline error-recovery to arch-v2 (#2718) (@devarismeroxa)
- 8eb7a4b: feat(pipelines): add postgres-pgvector-rag gallery template with scoped non-builtin exception (#2704) (@devarismeroxa)
- 4042bac: feat(plugin): embed Slice-2 slice 1 — external-connector dispenser (#2697) (@devarismeroxa)
- f201df1: feat(registry): generalize install pipeline for WASM-processor artifacts (Tier-1, PR-B) (#2711) (@devarismeroxa)
- e0ded3f: feat(registry): index schema carries WASM-processor artifacts + ADR/design (Tier-1, PR-A) (#2710) (@devarismeroxa)
- f0d1da0: feat(standalone): WASM host-egress capability (http_request) + SSRF gate + config + bundle e2e (#2699) (@devarismeroxa)
- a5ec913: fix(chaos): bound property2 kill points by construction, not by a race (#2840) (@devarismeroxa)
- 2c638ca: fix(chaos): bound the ack drain on progress, not on a wall clock (#2820) (@devarismeroxa)
- 9244dd7: fix(chaos): bound the recovery kill point by construction, not by a race (#2835) (@devarismeroxa)
- b0a6bf3: fix(chaos): bound the sigkill mid-stream kill point by construction (#2841) (#2842) (@devarismeroxa)
- 2f88d07: fix(cli): conduit init must generate a config conduit run accepts (#2855) (@devarismeroxa)
- d82606c: fix(cli): pipelines init must work in a directory that is not a workspace (#2857) (@devarismeroxa)
- 71e4652: fix(config): stop advertising unverified N×M support in the arch-v2 flag (#2737) (@devarismeroxa)
- ce758f9: fix(connector): fail the whole persist batch when a connector write fails (#2932) (@devarismeroxa)
- 601c9c0: fix(connector): reliably deliver deferred acks to a running plugin — snapshot-handoff deadlock (SEV-0) (#2707) (@devarismeroxa)
- d7cb5da: fix(connector): stop the Persister panicking the process on multi-source shutdown (#2749) (@devarismeroxa)
- a9f0e0f: fix(deps): Go 1.26.9 and golang.org/x/net v0.60.0 for GO-2026-6603/6611/6612/6617 (#2970) (@devarismeroxa)
- 76f97ca: fix(deps): pin google.golang.org/grpc to v1.83.2 for GO-2026-6443 (#2881) (@devarismeroxa)
- 7af7a05: fix(funnel): advance the tainted-batch cursor by the span actually covered (#2724) (@devarismeroxa)
- b69abea: fix(funnel): bound the retry recursion and fail loud on a non-converging processor (#2732) (@devarismeroxa)
- 70b7906: fix(funnel): guard Worker.Nack's upstream ack against an empty source position (#2744) (@devarismeroxa)
- b9b53d1: fix(funnel): guard the metrics divide-by-zero panic on an empty batch (#2738) (@devarismeroxa)
- fc951d1: fix(funnel): mark records end→start and stop nacks overwriting split-run siblings (#2733) (@devarismeroxa)
- 8fc8407: fix(funnel): treat a source's io.EOF as graceful even when a stop is in flight (#2745) (@devarismeroxa)
- 391a184: fix(funnel): withhold a split run's source position until every member is terminal (#2731) (@devarismeroxa)
- 6172130: fix(generate): gate eval harness through validate.RunBytes, not a weaker temp-file Run (#2803) (@devarismeroxa)
- 51e7b79: fix(generate): preserve partial capture results instead of discarding them (#2814) (@devarismeroxa)
- db0df52: fix(generate): stop cueWindow from crossing connector-mention boundaries (#2813) (@devarismeroxa)
- ea12a77: fix(lifecycle): a stopped run is never recovered and keeps its error; refuse starts during shutdown (#2912) (@devarismeroxa)
- 4ec2b5f: fix(lifecycle): publish the live run before announcing StatusRunning (#2806) (#2812) (@devarismeroxa)
- 4d047fd: fix(lifecycle): record a node's error on the tomb before nodesWg.Done (#2904) (@devarismeroxa)
- f0364fd: fix(lifecycle-poc): bound the deferred persister wait so a failed assertion fails fast (#2770) (@devarismeroxa)
- 674c1d7: fix(lifecycle-poc): compare-and-delete runningPipelines in run cleanup (#2894) (@devarismeroxa)
- 83e6abf: fix(lifecycle-poc): fatal-tag force-stop so recovery never restarts a user stop (#2716) (@devarismeroxa)
- 1f47fff: fix(lifecycle-poc): publish the live run before releasing its workers (#2834) (@devarismeroxa)
- 2269d39: fix(lifecycle-poc): run destination-scoped processors before the write (#2805) (@devarismeroxa)
- bb6ce44: fix(pipelines): correct postgres-pgvector-rag's prerequisites in both directions (#2815) (@devarismeroxa)
- ba14b8c: fix(processor): strip host-reserved sdk.egress.* keys before guest Configure (#2705) (@devarismeroxa)
- 8f2b4fc: fix(registry): permit dots in the processor-name schema pattern (#2717) (@devarismeroxa)
- 4977582: fix(registry): processor install refused on every build (#2818) (#2822) (@devarismeroxa)
- db687b7: fix(schemaregistry): make TestClient_CacheHit independent of registry state (#2883) (@devarismeroxa)
- 15d13d4: fix(standalone): convert MultiRecord processor responses host-side (#2701) (@devarismeroxa)
- 117c330: fix(templates): let postgres-pgvector-rag reach its embedding provider (#2911) (@devarismeroxa)
- ee542d4: fix(test): replace unpullable minio/minio image in template e2e compose (#2893) (@devarismeroxa)
- fba19d0: fix(test): use explicit continue so SA5011 needs no noreturn inference (#2771) (@devarismeroxa)
- 34bf97d: fix: two production bugs and one async assertion behind three flaky tests (#2807) (@devarismeroxa)
- 11e4d30: fix: use embedded metrics gatherer (#2747) (@Guflly)
- b7d30e8: perf(registry): stop paying wazero's optimizing compiler per test (CI test check 14m23s -> 7m34s) (#2861) (@devarismeroxa)
- ac70306: test(chaos): DBZ-2 Phase 1b — invariant-6 transport half + SIGTERM/invariant-7 (#2694) (@devarismeroxa)
- d09fa3e: test(chaos): PR-3 SIGKILL chaos coverage for arch-v2 recovery loop (#2719) (@devarismeroxa)
- 9a33505: test(chaos): end-to-end H2 ack-stream-injection coverage under real position collision (#2753) (@devarismeroxa)
- 4e5146e: test(chaos): make the mid-snapshot precondition deterministic and self-diagnosing (#2735) (@devarismeroxa)
- 66f050a: test(chaos): prove H2's shared-destination fix under a genuine position collision (#2739) (@devarismeroxa)
- d045e32: test(connector): de-flake the Teardown deferred-ack regression tests (#2695) (@devarismeroxa)
- e585c0b: test(generate): adversarial prompt-injection fixtures (WS1 slice A4) (#2801) (@devarismeroxa)
- fb1c195: test(lifecycle): assert run identity, not liveness, in nested-start recovery test (#2897) (@devarismeroxa)
- ec21023: test(lifecycle-poc): N×M shape coverage for arch-v2 (N sources x M destinations) (#2752) (@devarismeroxa)
- ab8f184: test(lifecycle-poc): wait for the live status on the recovery path, don't instant-read it (#2832) (@devarismeroxa)
- 5971952: test(mock): wait for the source mock's run goroutine instead of sampling a flag (#2750) (@devarismeroxa)
- 65f261a: test(pipelines): engine-level RAG template gallery e2e + arch-v2 requirement docs (#2708) (@devarismeroxa)
- 403746f: test(standalone): CI-gated RAG pipeline e2e (chunk → embed → pgvector, incl. delete) (#2702) (@devarismeroxa)
- dbbeb5d: test(upgrade): batch-shape upgrade coverage for the v1→v2 engine flip (#2751) (@devarismeroxa)
Release Artifacts
OSX Darwin
Linux
- 📦 conduit_0.20.0_Linux_arm64.deb
- 📦 conduit_0.20.0_Linux_arm64.rpm
- 📦 conduit_0.20.0_Linux_arm64.tar.gz
- 📦 conduit_0.20.0_Linux_i386.deb
- 📦 conduit_0.20.0_Linux_i386.rpm
- 📦 conduit_0.20.0_Linux_i386.tar.gz
- 📦 conduit_0.20.0_Linux_x86_64.deb
- 📦 conduit_0.20.0_Linux_x86_64.rpm
- 📦 conduit_0.20.0_Linux_x86_64.tar.gz
Windows
Verifying
checksums.txt is signed with Sigstore keyless signing (checksums.txt.sigstore.json), and each archive has an SPDX SBOM. The Docker image is signed by digest. See Verifying a release.
cosign verify-blob \
--certificate-identity 'https://github.com/ConduitIO/conduit/.github/workflows/release.yml@refs/tags/v0.20.0' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
--bundle checksums.txt.sigstore.json checksums.txt
sha256sum --check --ignore-missing checksums.txt
Docker images
To pull the image, you can execute the following command:
docker pull conduit.docker.scarf.sh/conduitio/conduit:v0.20.0
