Skip to content

v0.4.0 — the gate holds

Choose a tag to compare

@renezander030 renezander030 released this 26 Jul 05:51
· 7 commits to master since this release
cc5a921

Governance you can prove: approvals that survive anything, spend capped in money, and an audit trail you can read back.

Everything is additive. With no cost keys, no approvers, and no signature header, v0.3.1 behavior is unchanged.

Approval gates that survive a restart

Every gate is written to SQLite before the draft goes out, so an approval in flight outlives a redeploy, a crash, or a host reboot. Whatever happens to the process, the outcome of every gate lands in the audit trail, and the operator is told where things stand.

Spend caps in money

budgets:
  per_day_cost:      5.00   # same unit as your model rates
  per_pipeline_cost: 0.50

Token caps tell you how much the model thought. These answer what it costs. 0 leaves them off.

Per-operator approver scoping

- name: release-payment
  type: approval
  quorum: 2                     # how many must approve
  approvers: [111111, 222222]   # which ones

Quorum says how many. approvers says which ones, so the person who clears inbox drafts is not automatically the person who releases a payment. It narrows the channel's allowed_users and can never widen it.

Body-signed webhooks

Bind each inbound trigger to its exact body and a timestamp:

X-Draftcat-Signature: t=<unix>,v1=<hex hmac-sha256(t + "." + body)>

Enable with webhook.require_signature: true. Requests outside the skew window are refused and each signature is spent once, so a captured request cannot be re-fired. Verified whenever the header is present, even when not required.

Config validated on the boot path

The engine now runs the full draftcat validate check set at startup and refuses to start on errors, so problems surface at boot rather than mid-run. Typos get a suggestion:

ERROR pipelines[0].steps[1].type: invalid type "ia" — did you mean "ai"? (must be one of: deterministic, ai, approval)

DRAFTCAT_SKIP_VALIDATE=1 overrides.

draftcat runs

Read the governance record back out: what ran, when, and who decided what.

draftcat runs [pipeline] [--limit N] [--json]

2026-07-26T05:37:31Z  invoices    ok    60.0s
    release-payment      adjust      by 111 (0/2)
    release-payment      approve     by 222 (2/2) [signed]

--json gives the archivable form on stdout, ready to pipe into jq or a log shipper. Per-step timings and token counts stay in the observability spans.

Also in this release

  • WhatsApp intake (whatsapp_intake) for governed inbound messages.
  • internal/channels is the single registry the validator and engine share, so channel: only accepts what the binary can actually route to. Telegram remains the operator channel.

Issues #1, #2, #3 and #4 are closed by this release.

Full diff: v0.3.1...v0.4.0