Skip to content

v0.9.0

Choose a tag to compare

@ohdearquant ohdearquant released this 27 Sep 20:12
· 1780 commits to main since this release
f20eabf

khive v0.9.0

Minor release. Five changes need action on upgrade: two Rust API changes for out-of-tree pack and fusion code, the web pack's dropped manifest entities, gtd completion that now respects dependencies, and a required setting for Telegram group chats. They are listed first under Upgrading.

This release adds two new packs loaded by default, a policy-gated tool registry paired with sandboxed tool execution over content-addressed trees, and grows the git pack into a full dev-loop surface that reads, branches, commits, pushes, and opens, reviews and merges pull requests directly, each step recorded as a durable receipt. Notes gain caller-chosen keys with optimistic-concurrency updates and ordered per-stream appends, search gets ranking evidence and an any-term matching mode, and a new standalone khive-py Python client ships alongside the MCP surface, including a khive-cloud command line for a hosted deployment. A handful of fixes close real gaps: mail silently stopped arriving for up to an hour after a host slept, a malformed remote URL could mislead a git policy check about which host it was really talking to, and a group Telegram chat accepted a message from any member as if it came from the maintainer.

Upgrading from 0.8.0

  • KindHook::prepare_note_update is removed; the registry now sequences a pack's normalize_note_update and validate_note_update itself. An out-of-tree KindHook that overrode the removed method no longer compiles: move its normalization into normalize_note_update and its checks into validate_note_update. There is no compatibility shim.
  • FusionExecutor implementers must add rank_score_kind(), and SearchHit and NoteSearchHit struct literals must set the new rank_score_kind and signals fields (#3112).
  • The web pack no longer reads a .well-known application manifest or emits machine_view, agent_tool or agent_skill entities; ADR-191 supersedes ADR-175 (#3000).
  • gtd.complete and gtd.transition to done now refuse by default when a task's dependencies are unresolved, a cancelled or missing blocker included. Pass ignore_dependencies=true to keep the previous always-succeeds behaviour (#2839).
  • A Telegram channel configured on a group chat must set KHIVE_TELEGRAM_AUTHORIZED_SENDER_ID before upgrading, or the channel refuses to start. Before, any member of that group could send a message the channel accepted as if from the maintainer (#3412).
  • A database that has run the V21 attachments cutover (introduced in 0.8.0) still cannot be served by a binary older than 0.8.0; this release does not change that.

New features

  • Tool and exec packs (ADR-180, ADR-181): a policy-gated registry for tools, skills and plugins (tool.suggest, tool.request, tool.grant, tool.check and more) and sandboxed tool execution over content-addressed trees (exec.tree, exec.run, exec.receipt and more), both loaded by default (#2457).
  • Git dev-loop verbs (ADR-182): local git.checkout, git.diff, git.branch, git.commit, git.status, git.log, git.init and git.update_ref; guarded remote git.push, git.pr_open, git.pr_review and git.pr_merge, each with fast-forward proof and a durable receipt for every attempt, refusals included.
  • Keyed, versioned notes and ordered streams (ADR-172, ADR-174): create, get and update accept a caller-chosen key and an expected_version compare-and-set; stream.append gives a run dense per-stream sequence numbers with a lease fence against competing writers (#2459, #2501).
  • A new khive-py Python client (python/): a unified record interface over the daemon's Unix-socket wire, a weighted-incidence and hyperedge model, an HTTP transport and MCP helper for a khive-cloud deployment, and a khive-cloud console script (#2362).
  • Search ranking evidence and an any-term mode: rank_score, rank_score_kind and signals on every hit, an inclusive min_rank_score floor, and a text_mode (all_terms by default, or any_term) for KG lexical search (#3112, #3419).
  • comm.read returns the message body by default (subject, content, from, to, direction, created_at), so reading a message no longer needs a follow-up comm.thread call; opt out with body=false (#3172).
  • Chunked blob uploads (blob.begin, put_part, commit, abort; ADR-173) for objects larger than one request, bounded by default at 128 concurrent uploads and 16 per actor (#2642).
  • Schedule recurrence: fixed intervals (every:<N><s|m|h|d>) and five-field cron expressions evaluated in UTC, alongside the existing daily, weekly and monthly aliases (#2484).
  • gtd.repair for reviewed correction of legacy task data (#3164).
  • A caller-named timezone on task due dates (#2633).
  • Idempotent comm.send and comm.reply through a caller key (#2494).
  • Scoped mailbox readers with stable cursors (#3041).
  • A dry run for knowledge.upsert_atoms (#3170).
  • An admin verb that moves records between namespaces (#2821).
  • A CLI that backfills legacy entity types into entity_type (#2604).
  • The daemon refuses to start on a socket a supervisor has claimed (#2836).
  • A [gate].deny_writes_for setting that restricts an actor's writes by configured patterns (#3039).
  • gtd.tasks tag and context filters.

Bug fixes

  • The email channel stopped receiving mail for up to about an hour after the host woke from sleep, because its OAuth token cache measured freshness on a clock that does not advance during sleep. It now also checks the wall clock, and a rejected token is invalidated immediately (#3064).
  • Inbound IMAP fetches are capped per message (25 MiB by default) and per page (50 MiB by default); an oversized message is quarantined instead of stalling the poll (#3312).
  • A remote git URL with an @ inside a path segment no longer has its real host dropped when the git pack derives a GitHub owner/repo slug for a policy check (#3179).
  • The Telegram channel honours a 429 response's retry_after interval instead of retrying at its normal cadence (#3360).
  • A cron expression that can never occur on a real calendar date is refused at schedule creation instead of being stored and never firing, and daily and weekly recurrence no longer panics at the edge of the representable date range (#3396).
  • The events daemon no longer releases SQLite's advisory locks on its own database during sidecar permission hardening (#2398).
  • neighbors and traverse resolve a full-id anchor or root by id, like get: an absent one is a not-found error instead of an empty result, and returned edges stay scoped to the caller's visible namespaces (#3389).
  • Knowledge-graph sync refuses the reserved khive:secret_gate property, stores entity kinds under their canonical names, and hashes symmetric edges the same way in either endpoint order, so status no longer reports a change right after a clean sync (#3377).
  • Remote issue and pull-request ingest no longer blocks a runtime worker on a hung gh call, and moodboard image processing runs off the async workers.
  • Brain profile accounting no longer holds a namespace lock across unrelated requests, and an archived profile stops accumulating automatic updates (#3398).

Security

  • rustls is bumped to 0.23.45 for RUSTSEC-2026-0285: a TLS 1.3 handshake message could be accepted across an encryption level boundary in 0.23.42 and earlier.
  • The web pack's pinned egress client no longer picks up an ambient proxy, and IPv4-mapped, NAT64 and 6to4 IPv6 forms carrying a private or loopback IPv4 destination are classified and refused (#3388).
  • The secret-detection gate matches PEM private keys by body rather than header alone and lookup-key labels whole rather than by suffix, and technical references beside a credential word no longer trigger a false refusal.
  • A generic create or update of a message note refuses a caller-supplied external_id, so a caller cannot choose an outgoing Message-ID or steer reply threading (#3380).

Known issues

  • Staged blob upload filesystem operations are race-free on Unix only. On other platforms a local process able to write inside the blob root can substitute a directory, junction or reparse point between the validation check and its use, so the blob root and its ancestors must be writable only by trusted processes.

Install

Every workspace crate is published at 0.9.0; khive-pack-tool, khive-pack-exec, khive-pack-telemetry, khive-pack-web and khive-mounts are new on crates.io.

cargo install kkernel@0.9.0

Full list of changes: v0.8.0...v0.9.0