Skip to content

Releases: h-wata/kioku-mesh

v0.6.0

24 Jun 02:14
06a7555

Choose a tag to compare

release: v0.6.0

kioku-mesh v0.5.0

12 Jun 00:38
b2b3790

Choose a tag to compare

v0.5.0 — Visibility-tiered namespace readers (ADR-0019 Phase A)

This release prepares every reader in the mesh for visibility-tiered
replication
(ADR-0019): alongside the legacy mem/obs/... namespace, all
read paths now also understand the upcoming mem/mesh/...,
mem/user/{user_id}/... and mem/team/{team_id}/... key shapes. Nothing
writes those keys yet — that lands in Phase B — so this release is fully
backward compatible. Upgrade every host in your mesh to 0.5.x before any
host starts writing tiered keys
: that ordering is the whole point of
shipping readers first (the rolling-upgrade lesson from #75 / ADR-0012).

Highlights

  • Readers cover legacy + tiered namespaces (ADR-0019 Phase A). The
    replication subscriber, the startup index rebuild, the legacy fallback
    search / find-by-id, and the shadow-sweep re-verify all use broadened
    selectors (mem/**/obs/** — Zenoh's ** matches zero or more chunks, so
    one selector covers every shape). A new keyspace module is the single
    home for the key vocabulary.

  • Canonical-key gate on every index-mutating read path. Found in an
    external (Codex) review of the Phase A diff: the broadened selectors also
    match key shapes outside the spec, and a well-formed Observation payload
    under such a key could pollute the local index. Every ingest point now
    requires the key to parse as a canonical kioku-mesh key and the payload
    id to match the key's trailing id — including the shadow-revive path, so a
    forged payload can no longer resurrect a shadowed row.

  • Session-scoped save nudge in get_memory_status (#158). The status
    tool now reports session_age, this_session_saves and
    this_session_last_save_age, and emits a machine-readable nudge when a
    session has gone 10+ minutes without a save (or 20+ minutes since the last
    one). Counts come from the store itself, so they survive MCP server
    restarts. Server instructions also re-define the save triggers as
    language-agnostic semantic acts (EN/JA/ZH/KO anchors), and an optional
    Claude Code hook script (scripts/hooks/check-unsaved-decisions.sh) can
    remind about unsaved decisions before compaction / /clear.

  • store.py split into focused modules (#167). The 1,600-line monolith
    is now transport.py (session lifecycle, retry, health), pending_queue.py
    (failed-put queue + drain), replication.py (rebuild policy, key parsing,
    subscriber), purge.py (retention GC, shadow sweep, bulk purge) and a
    ~430-line store.py core. store.<name> keeps working for every public
    symbol via re-exports; if you monkeypatch internals in tests, patch the
    owning module (see the patching rule in store.py's docstring, #172).

Upgrade notes

  • No breaking changes. On-disk schema, env vars, CLI and the wire format
    are unchanged; writes still emit legacy keys only.
  • Roll out 0.5.x to all mesh hosts before a future Phase B release
    starts writing tiered keys.
  • New ADRs since 0.4.1: ADR-0017 (dual-hub), ADR-0018 (save-recall
    instructions), ADR-0019 (visibility tiers, revised to user/team/mesh),
    ADR-0020 (skills-mesh, Proposed), ADR-0021 (FTS5 + supersedes search,
    Proposed).

v0.4.1

01 Jun 08:02
8974da7

Choose a tag to compare

[0.4.1] - 2026-06-01

Removed

  • BREAKING: kioku-mesh init --mode localhost removed (#151). The localhost mode generated an ephemeral zenohd + in-memory volume that did not survive a router restart, and was a strict subset of features already covered by --mode local (persistent single-host, no zenohd) and kioku-mesh mesh start (ephemeral Zenoh smoke test, no zenohd binary needed). The init default changes from localhost to local. Migration: replace kioku-mesh init / kioku-mesh init --mode localhost with kioku-mesh init --mode local for persistent single-host use, or kioku-mesh mesh start for a throwaway Zenoh smoke test. The shipped config/zenohd_localhost.json5 template is removed. Existing ~/.config/kioku-mesh/zenohd.json5 files generated by past runs continue to work — only the wrapper command changes.

Added

  • scripts/save_coverage.py: objective metric for proactive-save adherence (#105). A standalone, transport-agnostic tool that turns a JSONL trace of opportunity (a moment that should have been saved — bug fix, decision, discovery) and save (an actual save_observation call) events into a single number: coverage = saved opportunities / total opportunities. Greedy 1:1 matching within a configurable window (--window-seconds, default 1800s), with --require-type-match to gate on kind/memory_type agreement, --json output, and --min-coverage for CI gating (exits non-zero when the trace falls below the bar). Lives under scripts/ (not the mesh_mem package) because it's analysis tooling, not part of the MCP server. Trace-collection paths (hook scripts, log scrapers) are intentionally out of scope here and tracked separately. See docs/design/issue-105-proactive-save-opportunity-coverage.md.

v0.4.0 — Mutual TLS for the mesh

31 May 15:39
8b1dd68

Choose a tag to compare

v0.4.0 — Mutual TLS for the mesh

This release adds optional mutual TLS (mTLS) peer authentication for the
Zenoh mesh, plus a low-friction enrollment flow. Network admission (Tailscale /
WireGuard / trusted LAN) remains the first line of defense; mTLS adds
transport-level peer authentication on top for deployments that want it.

Highlights

  • Mutual TLS via a CSR-based private CA (kioku-mesh tls). A new tls
    command group provisions a small private PKI: tls init-ca creates the CA,
    tls request --san <addr> generates a peer key (which never leaves the host)
    plus a CSR, tls sign issues the certificate on the CA host, and
    tls install places the signed cert + CA cert into
    ~/.config/kioku-mesh/tls/. tls info reports subjects, SANs, and expiry.
    Only non-secret material (CSRs, signed certs, the CA cert) is ever exchanged
    between hosts. kioku-mesh init --mode <hub|spoke> --tls emits a
    tls/-scheme config with a transport.link.tls block (enable_mtls,
    verify_name_on_connect) and refuses to run until the certs exist. Keys are
    EC P-256; peer certs carry both serverAuth and clientAuth.

  • Copy-paste enrollment + one-command tls enroll. Replaces the scp
    round-trip that proved fiddly in practice. tls request / tls sign print a
    single armored, copy-pasteable block (-----BEGIN KIOKU-MESH CSR/CERT BUNDLE-----) you paste into the next command on the other host — no SSH, no
    path juggling, works over any channel. The signed block bundles the peer cert
    and the CA cert, so the peer pastes one block instead of shuttling two
    files. For anyone with SSH to the CA host, tls enroll <ca-host> --san <addr>
    folds request → sign-over-SSH → install into a single command.

  • doctor gains a tls_certs check. WARN under 30 days to expiry, FAIL if
    expired or missing while the config enables mTLS.

See docs/mtls.md for the full walkthrough and trust model.

Upgrade notes

  • Adds a cryptography runtime dependency.
  • mTLS is opt-in — existing non-TLS meshes are unaffected and need no changes.
  • No on-disk storage-schema changes.

Install / upgrade

uv tool install --upgrade kioku-mesh

v0.3.3

30 May 02:04
5ffe160

Choose a tag to compare

v0.3.3 Release Notes

A documentation-only release on top of v0.3.2 for the OSS launch. No code or
on-disk storage-schema changes — existing installs are unaffected.

Highlights

  • README overhaul for the OSS launch (PR #136, #137).
    • Leads with the differentiator — "Shared memory for AI coding agents, across
      tools and machines" — and adds a "Why kioku-mesh" section framing the
      cross-machine, multi-agent problem.
    • Adds the project logo as the title and a 20s demo GIF (one agent saves a
      decision; an agent on another host recalls it live over the mesh).
    • Adds Mermaid architecture and hub-and-spoke topology diagrams to the
      Multi-Host Mesh section.
    • Describes mesh mode as "Zenoh/RocksDB is the source of truth, each host's
      SQLite is a rebuilt local read cache", restates the trusted-network model,
      and notes mTLS peer authentication is under consideration.
    • Tightens prose throughout.

Upgrade

No breaking changes. Documentation only.

v0.3.2

29 May 06:26
84aa23e

Choose a tag to compare

v0.3.2 Release Notes

A spoke-onboarding bug-fix release on top of v0.3.1. No breaking changes —
existing installs keep working without any manual step.

Highlights

  • Fresh spoke no longer reports count: 0 after joining a populated mesh
    (#133, PR #134). When a newly provisioned spoke connects, zenoh replicates the
    existing memories into its rocksdb, but status / search used to report
    count: 0 until kioku-mesh --rebuild status was run by hand — the local
    SQLite index is only backfilled by an explicit rebuild, and the replication
    subscriber ingests only new writes. get_index() now rebuilds once when the
    index is empty, even under the one-shot CLI's default skip (#38), so a fresh
    spoke self-heals. Explicit opt-outs (set_rebuild_on_init_explicit(False) /
    MESH_MEM_SKIP_REBUILD=1) are honored and the populated-index fast path is
    unchanged.
  • kioku-mesh init --mode spoke now tells you the next step (#133, PR #134).
    The completion output points at the one-time kioku-mesh --rebuild status, so
    the empty-index count: 0 state during onboarding is self-explanatory.
  • kioku-mesh init --install-systemd reuses an existing config (#133,
    PR #134). Installing the systemd unit on top of an already-provisioned
    zenohd.json5 no longer errors with "already exists, use --force" nor rewrites
    the config; it reuses the existing config unchanged and only generates the
    unit. --force still overwrites the config when explicitly requested.

Upgrade

No breaking changes.

uv tool install --upgrade git+https://github.com/h-wata/kioku-mesh.git
# or, from PyPI:
pip install --upgrade kioku-mesh

After upgrading on a spoke that previously showed count: 0, the next index
access (any status / search, or an agent connecting via the MCP server)
backfills automatically; no manual --rebuild is required.

v0.3.1

29 May 04:06
921bc2f

Choose a tag to compare

v0.3.1 Release Notes

A consistency + polish release on top of v0.3.0. No breaking changes — existing
installs keep working without any manual step.

Highlights

  • On-disk paths renamed mesh-memkioku-mesh (#128). kioku-mesh init
    now writes ~/.config/kioku-mesh/, the state dir defaults to
    ~/.local/share/kioku-mesh/, and init --install-systemd generates
    kioku-mesh-zenohd.service. This finishes the brand consistency the v0.3.0
    rename intentionally deferred. No automatic data migration: when only a
    legacy mesh-mem directory exists, kioku-mesh reads it as before and prints a
    one-time warning nudging a manual mv. The env-var prefix (MESH_MEM_*) and
    Python import name (mesh_mem) are intentionally unchanged.
  • kioku-mesh init guides the path to multi-host mesh (#96, PR #127):
    mode-specific follow-up hints after init (localhost → both scale-up paths;
    hub → a ready-to-run --mode spoke command pre-filled with the detected LAN
    IP; spoke → a hub-side --listen reminder), plus a full per-mode --mode
    description block and a "Picking a --mode" table in the README.
  • "Tier 1" demoted from a first-class architecture tier to a demo path
    (ADR-0013). The README architecture is now Local (SQLite, default) vs
    Mesh (zenohd + RocksDB, persistent); mesh start / mesh join are
    documented as a "try mesh without zenohd" demo with the ephemeral-replication
    caveat called out. Docs/CLI-help only — no runtime behavior change.
  • README restructured (#125, #126): hero + table of contents + Roadmap, a
    single end-to-end Quickstart, Operations folded under Power users.

Upgrade

No breaking changes.

uv tool install --upgrade git+https://github.com/h-wata/kioku-mesh.git
# or, after this release is on PyPI:
pip install --upgrade kioku-mesh

Optional: move data to the new path

Existing installs keep working from ~/.config/mesh-mem / ~/.local/share/mesh-mem
(with a one-time warning). To adopt the new paths, follow
docs/migration.md — stop zenohd + MCP servers, mv the
config/state dirs, update your zenohd systemd unit, and restart. The migration
guide includes how to identify an environment-specific zenohd unit before
stopping it.

mesh-mem v0.3.0

25 May 03:03
7f3e041

Choose a tag to compare


Highlights

  • Renamed to kioku-mesh — PyPI distribution and CLI binary renamed from mesh-memkioku-mesh (the original name conflicted with an unrelated PyPI package meshmem). On-disk paths (~/.config/mesh-mem/, ~/.local/share/mesh-mem/), env vars (MESH_MEM_*), and the systemd unit name are intentionally preserved — existing users only need to swap the binary. See docs/migration.md for the one-line upgrade. The mesh_mem Python import name also stays unchanged.
  • Tier 0: Local backend (#109) — kioku-mesh init --mode local works with no zenohd on PATH. Single-machine persistent memory in 30 seconds.
  • Tier 1: Embedded zenoh router (#112, integration fix #120) — kioku-mesh mesh start opens an in-process zenoh router (no binary install). Multi-host ephemeral mesh without zenohd.
  • README v0.3 overhaul (#110) — hero → Tier 0/1/2 quickstart → Power users narrative.
  • MemoryBackend abstraction (#109) — unified get_backend() surface shared by CLI, MCP server, and all Tiers.
  • kioku-mesh doctor (#84) — first-touch diagnostic with embedded router status.
  • kioku-mesh mcp install (#85) — one-shot Claude Code / Codex CLI MCP registration.
  • Forward-compat for Observation schema (#75) — older readers preserve unknown fields via _extras.

New Commands

Command Description
kioku-mesh init --mode local Initialize local (Tier 0) backend — no zenohd needed
kioku-mesh mesh start [--listen tcp/0.0.0.0:17447] Start in-process zenoh router (Tier 1)
kioku-mesh mesh join Connect to a peer endpoint and verify connectivity
kioku-mesh doctor Run diagnostic checks (zenohd, config, state dir, embedded router)
kioku-mesh mcp install --client <claude-code|codex-cli> Register MCP server with one command
kioku-mesh init --mode localhost|hub|spoke|local Generate zenohd config or local config

Config file changes

~/.config/mesh-mem/config.yaml (new in v0.3):

backend: local  # Use Tier 0 SQLite-only mode

Known limitations / deferred to v0.3.1+

  • macOS smoke-test pending (#87): kioku-mesh is verified on Linux and WSL2 only. Apple Silicon / Intel macOS support is plausible but unverified — maintainer does not currently have a Mac to test on. Community reports welcome on #87. docs/macos-setup.md will land in v0.3.1 once verified.

Issues / PRs

  • #109 (PR #115): Introduce local backend for single-machine persistent mode
  • #110 (PR #114): README v0.3 overhaul — hero + Tier 0/1/2 narrative
  • #111 (PR #118): Polish README Power users section
  • #112 (PR #117): Embedded zenoh router (Tier 1) — mesh start / mesh join
  • PR #120: Tier 1 actual mesh integration (post-merge fix for #117)
  • #75 (PR #102): Forward-compat _extras for unknown Observation fields
  • #84: kioku-mesh doctor diagnostic command
  • #85: kioku-mesh mcp install one-shot MCP registration
  • #86: kioku-mesh init --install-systemd
  • #82: client_id defaults to user@host
  • #76: Shell completion via argcomplete
  • #73: Observation.references field
  • #66: Bulk delete cursor pages past MAX_SEARCH
  • #53: CLI/MCP strings unified to English

Closes #90

mesh-mem v0.2.5

19 May 02:15

Choose a tag to compare

Highlights

  • Shadow retention sweep (#70): gc --retention-days now also prunes long-shadowed index rows (after #67's shadow-delete reconcile). Re-verifies each candidate against live Zenoh state — false-shadows are upserted back to live, genuine expiries are physically deleted. Output reads retention N-day sweep: physically deleted {n} tombstones / {m} shadows (revived {k}). --no-shadow-prune opts out.
  • i18n: user-facing CLI / MCP runtime strings are now English (#53). mesh-mem CLI prints and MCP tool returns (save_observation, search_memory, get_memory, delete_memory, get_memory_status, drain_pending_puts) used to mix Japanese and English; they are now uniformly English to match the already-English logger.* output. The "前にやった" hint inside MCP instructions is intentionally preserved so the agent still recognizes Japanese user input as a search trigger.
  • Rebuild reconcile fixes ghost rows (#67): LocalIndex.rebuild_from_zenoh was add-only and left long-lived ghost rows after Zenoh-side purges on offline peers. Rebuild now marks existing - zenoh_set rows as shadowed; tombstones remain stronger than shadows; live rows whose payload_json is unchanged are skipped to avoid WAL inflation on populated meshes.
  • Replication subscriber mirrors Zenoh DELETE into the SQLite index (#64). Previously gc --by-pc-id --execute on one peer purged Zenoh + that peer's index but left ghost rows on every other peer (~11.7 万件 observed on dogfood). Subscriber now dispatches on sample.kind and calls LocalIndex.physical_delete for DELETE samples.
  • Local fallback queue for failed puts (#50, #57). Retryable put_observation / put_tombstone failures are persisted to state_dir()/pending_puts.db and replayed automatically by the MCP daemon background drain, or manually via mesh-mem drain --pending / the MCP drain_pending_puts tool.
  • search --format {text,markdown,json} (#58) for stable machine-oriented output. Sample Claude Code SessionStart hook script ships in scripts/hooks/session-start.sh.

Breaking

  • Japanese substring grep on CLI / MCP output no longer matches (#53). Scripts relying on 保存完了 / 削除 / 件数 / 該当するメモリ / キャンセルしました / 物理削除完了 / bulk delete 対象 etc. must update their patterns to the new English equivalents (saved / deleted / count (within limit ...) / No matching memories / cancelled. / physically deleted / bulk delete target: N entries).
  • TransportStatus schema gained pending_puts: int. Callers destructuring the dataclass must pick up the new field.
  • SQLite local index schema migrates v1 → v2 (adds shadowed_at TEXT column). Migration is forward-only; existing rows are treated as live until the next rebuild revisits them.

Added

  • gc --retention-days shadow sweep + --no-shadow-prune opt-out (#70).
  • LocalIndex.mark_shadowed_missing + VisibilityCounts; get_memory_status now reports index_rows: live=N / tomb=N / shadow=N.
  • Local fallback queue for failed puts (#50). Daemon and manual drain (#57). pending_puts exposed in CLI status and MCP get_memory_status.
  • mesh-mem search --format {text,markdown,json} (#58); machine-oriented JSON + single-line markdown for SessionStart hooks; sample hook script.

Changed

  • All user-facing CLI / MCP runtime strings translated to English (#53). _INSTRUCTIONS keeps "前にやった" intentionally.
  • Drain progress surfaced in status output (in-progress flag, last-run timestamp, cumulative drained count).

Fixed

  • Rebuild now reconciles SQLite index against Zenoh, not just appends (#67, ADR-0011).
  • Replication subscriber dispatches on sample.kind and physically deletes the index row for DELETE samples (#64).
  • get_memory_status exposes shadow / tomb / live counts.

Upgrade note

Reinstall the editable venv to refresh __version__ metadata:

~/work/mesh-mem/.venv/bin/pip install -e .

Then /mcp reconnect (or restart your MCP host).

If your existing peer index has accumulated ghost rows from before #64 / #67, the next gc --retention-days run will sweep them via the new shadow path (re-verifying each candidate against live Zenoh).

See CHANGELOG.md for full details.

mesh-mem v0.2.4

11 May 00:32

Choose a tag to compare

Highlights

  • mesh-mem gc --by-pc-id new CLI: bulk-purge every observation saved under a given pc_id (optionally narrowed by --session-prefix). Built for the case where a benchmark or smoke run on a peer flooded the mesh with tens of thousands of throwaway-session obs. Dry-run by default; --execute requires interactive yes (or --yes for CI).
  • CLI is now interactive-fast on populated meshes (#38): startup rebuild_from_zenoh is skipped by default, so mesh-mem save / search / get-memory / delete / status no longer pay the ~15 s zenoh scan + JSON-parse + SQLite-membership-check on every invocation against a busy peer (~117k records observed). Long-running processes (mesh-mem-mcp) keep the previous behavior. Opt back in per-invocation with mesh-mem --rebuild ... or MESH_MEM_FORCE_REBUILD=1.
  • Project-scoped gc is O(N) on the SQLite local index (#32-A): gc --project ... previously took ~60 s on production data with months of test residue regardless of how few tombstones matched the project. Now uses the local index for (project, deleted_at) rows + exact-key deletes — O(N) on the project subset, not O(M) global.
  • SQLite WAL is bounded (#32-B): long-running mesh-mem-mcp processes used to grow WAL to 130 MB (≈ same size as the main DB) because they hold the connection open and SQLite never finishes the truncate phase. LocalIndex now issues PRAGMA wal_checkpoint(TRUNCATE) every 256 upserts and on close().

Added

  • mesh-mem gc --by-pc-id PCID [--session-prefix X] [--execute] [--yes] (#45). Backed by store.scan_obs_by_pc_id + store.execute_bulk_purge. For every matched obs the mirrored mem/tomb/... slot is also exact-key deleted, so legitimate tombstones under the same pc_id are cleaned up at O(1)/match without falling back to the mem/tomb/** global sweep that --force-id performs (the sweep stalls on GET_TIMEOUT past 30k tombstones).

Changed

  • CLI skips rebuild_from_zenoh on startup by default (#38). Resolution order for the override channel: explicit --rebuild > MESH_MEM_FORCE_REBUILD > MESH_MEM_SKIP_REBUILD > module default. Direct user intent on the typed invocation always wins over env-level config (codex review P2).
  • One-off migration scripts moved to scripts/migrations/. cleanup_legacy_memory_types.py (v0.2.2 → v0.2.3 enum migration) is operator tooling that should travel with the repo for un-migrated peers but should not ship as a CLI subcommand. The ad-hoc scripts/purge_observations_by_pc_id.py is removed in favor of the gc --by-pc-id flag.

Fixed

  • #44: mesh-mem CLI commands no longer hang on exit. Short-lived invocations now explicitly close the Zenoh session on exit (including on early returns / exceptions). Previously the session lingered until process teardown and made shell scripts that chain mesh-mem commands unusable on some hosts.

Performance

  • Project-scoped gc on SQLite local index (#32-A). Falls through to the legacy global scan when the index is disabled (MESH_MEM_DISABLE_INDEX=1) or the fast path raises. Always realigns the index via rebuild_from_zenoh before the SQLite query (codex review P1) — a non-empty sidecar from earlier short-lived CLI runs may be partial.
  • WAL bounded checkpoint (#32-B). Explicit PRAGMA wal_checkpoint(TRUNCATE) every 256 upserts and on close(), no background thread.

Documentation

  • README Windows quick start refreshed (#36): drop the misleading pip install mesh-mem line; pin exact zenohd zip asset names; document non-admin install path; clarify elevated PowerShell for New-NetFirewallRule; cross-link --rebuild opt-in.
  • Spec.md, ADR-0006..0009 (hub-and-spoke topology / SQLite local index sidecar / project-aware O(N) gc / MCP server instructions protocol — supersedes ADR-0003 and ADR-0005), and 3-PC topology PoC report (#41#43).

Upgrade note

Reinstall the editable venv to refresh __version__ metadata:

~/work/mesh-mem/.venv/bin/pip install -e .

Then /mcp reconnect (or restart your MCP host).

If your shell scripts rely on the old "rebuild on every CLI invocation" behavior (e.g. first-time bootstrap on a populated mesh), pass --rebuild once or set MESH_MEM_FORCE_REBUILD=1 in the environment.

See CHANGELOG.md for full details.