Korvun v0.5.0
The fifth release adds Korvun's third channel: a generic Webhook. Any system that
speaks JSON over HTTP becomes a mouth into Korvun — no provider account, no SDK.
No breaking changes: every existing config runs exactly as before, and go.mod is
untouched (stdlib only).
Highlights
Generic Webhook channel (ADR-0038)
The Stage-2 webhook adapter is now a first-class core channel: declare type: "webhook" in your config and Korvun opens an authenticated HTTP endpoint that turns
inbound JSON into a message, routes it through a brain, and POSTs the reply back to a
URL you choose. What it brings:
- Mandatory, fail-closed Bearer auth. Every request must carry
Authorization: Bearer <secret>, compared in constant time (SHA-256 +subtle.ConstantTimeCompare
— the same mechanism as the admin gate, ADR-0028 §1). An empty/unresolved secret
rejects every request; the body is never read on a 401, and the secret never
appears in a log or error. - Conversation identity. A configurable
conversation_idfield groups messages
into one conversation for brain memory; when a payload omits it, Korvun falls back
to the sender id, and the reply echoes the conversation id back to your
outbound URL. - Honest saturation. A momentarily full inbound buffer answers
503(retry
later) and counts the drop — it never blocks the HTTP goroutine on a slow
brain. - Loopback by default, warned when exposed. The endpoint binds
127.0.0.1:8090;
binding a non-loopback address emits a loud boot warning that the Bearer secret
would cross the network in cleartext without a TLS-terminating reverse proxy in
front (Korvun terminates no TLS itself). - Two env-only secrets.
token_env(inbound, required) and an optional
outbound_token_env(outbound Bearer to your receiver) — both are env-var names,
never values (ADR-0010). A named outbound secret that does not resolve at boot is
a loud, named error, never a silent unauthenticated outbound. - Edge validation.
POSTonly (else 405),application/json(else 415), ≤ 1 MiB
body (else 413), well-formed JSON with a sender and content (else 400).
Validated end to end on real hardware (2026-07-26, Intel iMac, macOS 13): a real
curl message into the webhook was routed through a local llama3.2:1b brain and the
reply — carrying the same conversation_id — arrived at a one-line test receiver in
~11s cold / ~1s warm; the unauthenticated request was correctly rejected with 401, and
the process shut down cleanly on SIGINT.
New guide — zero to round-trip
A new docs/WEBHOOK-SETUP.md walks the whole path: generate the
secret (openssl rand -hex 32), curl a message in, watch the brain's replies with a
one-line python3 test receiver, read what each rejection means (401/415/413/400,
and 503 = retry), and expose it safely behind a minimal reverse-proxy/TLS snippet. The
full schema lives in the new webhook section of
docs/CONFIGURATION.md, and configs/korvun.example.json ships
a webhook channel example.
Korvun Desktop carries it too
Korvun Desktop 0.5.0 embeds the webhook channel in the core from day one — it is
declarable by JSON config exactly like the headless binary. The visual form for it
arrives later with the Builder-canvas; today it is config-driven.
Compatibility
No breaking changes. The schema addition is strictly additive: existing
telegram/discord configs parse, validate, and behave byte-for-byte as before. Zero
new dependencies — the channel is pure standard library (net/http, crypto/sha256,
crypto/subtle), so go.mod is unchanged.
Minor
- V1 criteria updated on the roadmap; the Webhook piece marked complete
(docs/ROAD-TO-BETA.md). - Docs:
WEBHOOK-SETUP.md, thewebhookblock inCONFIGURATION.md, the example
config, and the setup/config cross-links.
Artifacts
Two families in one release, exactly as v0.4.0. <ver> is the version without the
leading v (e.g. 0.5.0).
| Family | Artifact | Target |
|---|---|---|
| Headless | korvun_<ver>_{linux,darwin}_{amd64,arm64}.tar.gz, korvun_<ver>_windows_{amd64,arm64}.zip |
server / CLI, six OS·arch |
| Headless | checksums.txt + .sig + .pem, per-archive *.sbom.json |
signed manifest + SBOMs |
| Desktop | korvun-desktop_<ver>_darwin_universal.dmg |
macOS universal app |
| Desktop | korvun-desktop_<ver>_windows_amd64-installer.exe |
Windows NSIS installer |
| Desktop | korvun-desktop_<ver>_linux_amd64.tar.gz |
Linux binary + .desktop |
| Desktop | checksums-desktop.txt + .sig + .pem |
signed desktop manifest |
Draft-until-complete: the release is born a draft and is published only once
both families and their signatures are present, so a broken desktop build can never
expose a half-populated public release (ADR-0035 §8; SP7 §1e).
Verifying this release
Both families are signed keyless with cosign
(Sigstore), each with its own manifest. Verify the manifest signature you need, then
check your download against it.
Headless:
cosign verify-blob checksums.txt \
--signature checksums.txt.sig \
--certificate checksums.txt.pem \
--certificate-identity-regexp 'https://github.com/Sebastian197/korvun/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comDesktop:
cosign verify-blob checksums-desktop.txt \
--signature checksums-desktop.txt.sig \
--certificate checksums-desktop.txt.pem \
--certificate-identity-regexp 'https://github.com/Sebastian197/korvun/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comFull install and verification walkthrough: docs/packaging/INSTALL.md.
For the webhook channel specifically: docs/WEBHOOK-SETUP.md.