v0.6.0
[0.6.0] - 2026-05-21
Release
- Promotion from
0.6.0rc18to0.6.0stable. Closes the rc cycle
that ran from0.6.0rc1(2026-04-21, the simplification arc →
two-product split) through0.6.0rc18(2026-05-18, the layered
stored-injection defense).0.6.0isrc18plus several
upgrade/downgrade-correctness fixes surfaced 2026-05-21 while
exercising the pre-promote Layer-3 web test for the first time
(see the Fixes section below).
Fixes
-
mnemon upgrade webnow forwardsMNEMON_S3_PREFIXand
MNEMON_VAULT_NAMEto the Fly container as secrets, so a
non-default operator override propagates to the container's
mnemon sync pullseed step. Previously the Fly side fell back
tosync.S3_PREFIX_DEFAULT(mnemon/vaults) regardless of what
the operator set locally — which broke the runbook's
"test against an isolated S3 prefix" ritual. Not user-affecting
for normal prod redeploys (both sides default identically); only
affects ad-hoc test deploys where the operator overrides the
prefix. Surfaced + fixed during the 0.6.0 Layer-3 attempt; 4
regression tests cover the forwarding contract. -
mnemon downgrade localnow dumps the current Fly vault to S3
before pulling. Previously, downgrade didS3 → localonly and
silently skipped theFly → S3step, so any memory added via
remote between upgrade time and downgrade time was lost — the
local vault was seeded from a stale S3 snapshot. For ad-hoc
testing this manifested as "docs added post-upgrade missing
after downgrade." For prod operators it would have been a quiet,
severe data-loss bug: weeks of remote-added memories vanishing
on the firstmnemon downgrade localcall. Now SSHes into the
Fly machine and runsmnemon sync pushbefore the local
mnemon sync pull— mirror ofupgrade._fly_seed_vaultin the
opposite direction. New--skip-fly-pushflag as an operator
escape hatch (e.g., when the Fly machine is unreachable);
default behavior is to fail-loud if the dump SSH errors out,
rather than silently fall through to the stale-pull data loss.
5 regression tests cover the call order (fly_dump → s3_pull),
the override flag, the fail-loud on SSH error, the
custom-domain skip, and the SSH command shape. -
mnemon sync pushnow uses SQLite's online-backup API as the
canonical cross-host transfer primitive (replaces an earlier
WAL-checkpoint approach that was wrong cross-process). Raw
aws s3 cp default.sqliteuploads only the main sqlite file's
bytes — for short-lived CLI processes that's fine because SQLite
auto-checkpoints WAL on connection close, but for long-running
mnemon serve-remotethe WAL accumulates indefinitely (default
auto-checkpoint at 1000 pages). The natural-seeming fix —
PRAGMA wal_checkpoint(TRUNCATE)from a transient connection — is
silently broken when another process holds the connection open:
it returns(busy=0, total=0, checkpointed=0), reports success,
flushes zero frames. Verified against a long-lived holder + 3
commits: PRAGMA reported success, main file stayed at 8KB (just
schema), no frames moved;Connection.backup()from the same
position captured all 3 rows.push()now snapshots via the
online-backup API to a transient.sqlite.snapshotfile beside
the source,aws s3 cp's the snapshot, then removes it. The
online-backup API uses SQLite's WAL-aware backup protocol and
produces a consistent atomic snapshot even with concurrent
writers. Vec store (default.vec.npz) is a binary numpy file with
no SQLite semantics — uploaded directly. 6 regression tests
cover the snapshot helper, the cross-process write capture, the
source-is-read-only contract, the error-string contract for
invalid sources, the snapshot-before-cp call order, the transient
cleanup, and the vec.npz direct-upload path. -
mnemon downgrade local(_fly_dump_vault) uses SQLite's
online-backup API directly for the version-skew bootstrap.
When Layer-3 runs Pre-publish validation, the Fly container is
pinned to the latest-published mnemon (e.g.0.6.0rc18) which
predates thesync.pushbackup-API fix above — so SSHing
flyctl ssh -C "mnemon sync push"would invoke the older
broken push. To handle this version-skew,_fly_dump_vault
SSHes a stdlib Python script that does its ownConnection.backup()aws s3 cpof/data/default.sqlite(plusdefault.vec.npz
best-effort), independent of installed mnemon version. Once the
Fly side is reliably on0.6.0+, this can simplify to
flyctl ssh -C "mnemon sync push"and rely on the canonical
primitive — tracked as a follow-up.
The rc cycle delivered:
- The simplification arc — mnemon local (stdio + single-file vault)
and mnemon web (Fly + S3 backup) as one codebase, symmetric
upgrade web/downgrade local, single source of truth
invariant. (rc1→rc7.) - Runtime hardening from rc11-deploy observations: fresh-session
deadlock fix (json_response=True),_session_creation_lock
narrowing, periodicexpire_old()+ decay sweeps in the lifespan
task, OAuth refresh-token rotation grace, warm-keeper +
persistent sessions. (rc8→rc14.) - Auto-mirror discipline: shape gate (
is_well_shaped) + confidence
cap to keep transcript fragments from outranking deliberate
user-authored memories; upsert-by-slug (source_key) to stop the
multi-edit duplication pattern. (rc15,rc16.) - The five-layer stored-injection defense end-to-end: token defang
allowlist (Layer 2), capture-time scaffolding rejection (Layer 0
— root cause), provenance trust-tiering (Layer 4), spotlighting
data envelope at recall (Layer 1, Claude Code path). (rc17,
rc18.)
0.7.0will open the salience-tier work — separating standing
constraints (capped, unconditionally injected) from situational
recall.