Skip to content

v0.6.0

Choose a tag to compare

@cipher813 cipher813 released this 21 May 22:43
ba6714c

[0.6.0] - 2026-05-21

Release

  • Promotion from 0.6.0rc18 to 0.6.0 stable. Closes the rc cycle
    that ran from 0.6.0rc1 (2026-04-21, the simplification arc →
    two-product split) through 0.6.0rc18 (2026-05-18, the layered
    stored-injection defense). 0.6.0 is rc18 plus 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 web now forwards MNEMON_S3_PREFIX and
    MNEMON_VAULT_NAME to the Fly container
    as secrets, so a
    non-default operator override propagates to the container's
    mnemon sync pull seed step. Previously the Fly side fell back
    to sync.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 local now dumps the current Fly vault to S3
    before pulling.
    Previously, downgrade did S3 → local only and
    silently skipped the Fly → S3 step, 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 first mnemon downgrade local call. Now SSHes into the
    Fly machine and runs mnemon sync push before the local
    mnemon sync pull — mirror of upgrade._fly_seed_vault in the
    opposite direction. New --skip-fly-push flag 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 push now 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.sqlite uploads 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-remote the 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.snapshot file 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 the sync.push backup-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 own Connection.backup()

    • aws s3 cp of /data/default.sqlite (plus default.vec.npz
      best-effort), independent of installed mnemon version. Once the
      Fly side is reliably on 0.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. (rc1rc7.)
    • Runtime hardening from rc11-deploy observations: fresh-session
      deadlock fix (json_response=True), _session_creation_lock
      narrowing, periodic expire_old() + decay sweeps in the lifespan
      task, OAuth refresh-token rotation grace, warm-keeper +
      persistent sessions. (rc8rc14.)
    • 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.0 will open the salience-tier work — separating standing
    constraints (capped, unconditionally injected) from situational
    recall.