diff --git a/AGENTS.md b/AGENTS.md index 3c70e7a..5070785 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ LLM hub for this system repo. Prefer in-repo skills and docs over ad-hoc inventi ## Mission -**MemNet** (Net of Memory) is **mission working memory** — a session graph (GQL **node**/vertex, **edge**/relationship, **property**) **between** LLM call pipelines and data search, not the corpus and not GraphRAG. Agents read a bounded **live pin map** each turn and write in the same **GQL (openCypher-shaped)** family — redefined **Write = display** via shaped subgraph emit ([`docs/grammar/gql-wire-profile.md`](docs/grammar/gql-wire-profile.md)). In-session recall is **serial**: kind/keyword cue, then `pin_map` neighbourhood. Primary read: MCP `pin_map` / CLI `query pin-map`; leftover `query_warm` / `query warm` are leftover aliases. Aims (MN-REQ-00): save wall-clock time and tokens while keeping factual accuracy. Aids **system**, **programme**, **software**, **firmware**, **hardware**, and **documentation**. Transport: **in-process first** (single-agent; TCP fallback). **Multitask** requires TCP serve or streamable-http MCP — see Multitask policy below. This repo is **engine + generic memnet-mcp** only — novel-writer dropped. Repo product **0.19.23** (Hatch SSOT; last published PyPI **`memnet-llm==0.19.22`** until this cut is uploaded; 0.19.23 honesty `c`: admin checkpoint of every loaded session without drain plus `checkpoint-verify` (#211, MN-REQ-06.15). Earlier `c` cuts include 0.19.22 safe serve upgrade — admin `upgrade-prepare` drain, lossless snapshot with manifest, startup restore under the same ids, automatic retire (#208 trimmed by #210, MN-REQ-06.14), 0.19.21 serve per-request output isolation, LF-only statement split, undeclared-property snapshot save, label case-fold, and housekeep GQL endpoint orphans with `prune_referenced` refusal (#206), 0.19.20 memnet-mcp product gateway `--transport gateway` (#203, MN-REQ-06.12), 0.19.19 doc-gate readiness (#201) and snapshot / value cap / WHERE / ACL who / expire-save fixes (#202), 0.19.18 snap_model bounded session grain (#199), 0.19.17 product-gate cap contract (#196) and admin-only serve usage report (#197), 0.19.16 shared Path-B ingest defaults 2000 nodes / 2000 edges, 0.19.15 storage role labels (#186), Path-B SysML ingest kinds (#188), Neo4j retired (#189), 0.19.14 TTL expire restore by known sid, and 0.19.11 catalog cross-session satisfy locators + CousinSysMLEdge mustNotInventUploadBind). **1.0** = 0.5–0.8 claimed (unclaimed). See `README.md`, [`docs/SHAPE.md`](docs/SHAPE.md), and `docs/grammar/`. +**MemNet** (Net of Memory) is **mission working memory** — a session graph (GQL **node**/vertex, **edge**/relationship, **property**) **between** LLM call pipelines and data search, not the corpus and not GraphRAG. Agents read a bounded **live pin map** each turn and write in the same **GQL (openCypher-shaped)** family — redefined **Write = display** via shaped subgraph emit ([`docs/grammar/gql-wire-profile.md`](docs/grammar/gql-wire-profile.md)). In-session recall is **serial**: kind/keyword cue, then `pin_map` neighbourhood. Primary read: MCP `pin_map` / CLI `query pin-map`; leftover `query_warm` / `query warm` are leftover aliases. Aims (MN-REQ-00): save wall-clock time and tokens while keeping factual accuracy. Aids **system**, **programme**, **software**, **firmware**, **hardware**, and **documentation**. Transport: **in-process first** (single-agent; TCP fallback). **Multitask** requires TCP serve or streamable-http MCP — see Multitask policy below. This repo is **engine + generic memnet-mcp** only — novel-writer dropped. Repo product **0.19.24** (Hatch SSOT; last published PyPI **`memnet-llm==0.19.23`** until this cut is uploaded; 0.19.24 honesty `c`: session ACL persisted in snapshots, `@SNAP` format 2, 0600 atomic writes, lease digest, one-time v1 backup (#215, MN-REQ-06.16). Earlier `c` cuts include 0.19.23 admin checkpoint of every loaded session without drain plus `checkpoint-verify` (#211, MN-REQ-06.15). Earlier `c` cuts include 0.19.22 safe serve upgrade — admin `upgrade-prepare` drain, lossless snapshot with manifest, startup restore under the same ids, automatic retire (#208 trimmed by #210, MN-REQ-06.14), 0.19.21 serve per-request output isolation, LF-only statement split, undeclared-property snapshot save, label case-fold, and housekeep GQL endpoint orphans with `prune_referenced` refusal (#206), 0.19.20 memnet-mcp product gateway `--transport gateway` (#203, MN-REQ-06.12), 0.19.19 doc-gate readiness (#201) and snapshot / value cap / WHERE / ACL who / expire-save fixes (#202), 0.19.18 snap_model bounded session grain (#199), 0.19.17 product-gate cap contract (#196) and admin-only serve usage report (#197), 0.19.16 shared Path-B ingest defaults 2000 nodes / 2000 edges, 0.19.15 storage role labels (#186), Path-B SysML ingest kinds (#188), Neo4j retired (#189), 0.19.14 TTL expire restore by known sid, and 0.19.11 catalog cross-session satisfy locators + CousinSysMLEdge mustNotInventUploadBind). **1.0** = 0.5–0.8 claimed (unclaimed). See `README.md`, [`docs/SHAPE.md`](docs/SHAPE.md), and `docs/grammar/`. ## Where to look diff --git a/CHANGELOG.md b/CHANGELOG.md index dc1d1ee..7355d07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,16 +7,21 @@ This project uses Semantic Versioning as **interpreted for MemNet**: package `a. ## [Unreleased] +### Changed +- **Invent only — ClusterRoute vs SliceHandCarry (#191 / #47 cousin)** — `MemNetTwoMoves` outside `MemNetSystem` (`MN-REQ-06.9` + `MN-REQ-06.10` / `MN-VER-06-S08`). ClusterRoute = where the session lives (`MemNetLanMcpFront`; one owner; `pin_map` / `find` SHALL NOT span backends). SliceHandCarry = explicit copy into another session (`export_pin_map` or `session_save` → LAN file copy → dest import/`session_load`; `import_slice` same-serve only). Not a live hop. `import_slice(from_url)` not shipped. tip≠face. `inventOnly=true`; `implemented=false`; no engine code; no SemVer bump. Wire: [`docs/operations/cluster-route-vs-slice-hand-carry.md`](docs/operations/cluster-route-vs-slice-hand-carry.md). +- **Invent only — LAN MCP front over several serves (#191)** — `MemNetLanMcpFront` outside `MemNetSystem` (`MN-REQ-06.9` / `MN-VER-06-S07`). One MCP catalogue, N LAN `memnet serve` backends; `SessionOwnerRegistry` is owner (explicit pin allowed; silent hash is not sole routing). One owner per session; `pin_map` / `find` SHALL NOT span backends. Cousin of #47 (peer sid handoff), not the same invent. tip≠face. `inventOnly=true`; `implemented=false`; no engine code; no SemVer bump. Wire: [`docs/operations/memnet-lan-mcp-front.md`](docs/operations/memnet-lan-mcp-front.md). + +## [0.19.24] - 2026-10-14 + ### Added - **Session ACL in snapshots (MN-REQ-06.16)** — session save, expire save, checkpoint, and safe-upgrade snapshots carry the CapsPolicy ACL: enabled flag, per-caller grants (pin_map, mutate, WorkerWriteScope), and optional bind. The ACL is one `#@ACL:` comment line after `@SNAP`. `session load` restores it, both from `--file` and on the `--keep-id` reload path. `@SNAP` is now **version 2**, and version 2 **requires** the `#@ACL:` line: a version 2 snapshot without it fails `bad_snapshot`. Version 1 (written before the ACL was persisted) still loads, with ACL off, and prints `@ACL: absent|off`. A loaded ACL prints `@ACL: loaded|enabled=<0|1>|callers=|bind=<0|1>`. A malformed ACL line fails the load instead of silently turning ACL off. The snapshot and the upgrade passport share one serialiser (`memnet.acl.acl_to_dict` / `acl_from_dict`). Readers built before this change reject `@SNAP` version 2 with `bad_snapshot` (unsupported snapshot version 2) rather than skipping the ACL line, and an upgrade manifest with `snapshot_format` 2 is refused by an older serve (`upgrade_snapshot_format`, exit 3). Verify: MN-VER-06-S14 (`tests/test_acl_snapshot.py`). - - **One-time v1 backup before the first v2 write (MN-REQ-06.16)** — the first snapshot write over a format 1 file (session save, expire save, checkpoint, safe-upgrade) copies the v1 bytes to `.v1.bak` in the same directory, at mode `0600`, through `memnet/atomic_file.py`. An existing backup is never overwritten, and v2-over-v2 writes make no backup. There is no dual write: the snapshot itself is always v2. **Rollback to 0.19.23** means renaming the `.v1.bak` files over their snapshots (see [`docs/operations/safe-upgrade.md`](docs/operations/safe-upgrade.md)). That loses writes made after the upgrade. Old builds refuse v2 loudly (`bad_snapshot`, `upgrade_snapshot_format`) by design. + ### Changed - **Snapshot and manifest files are private and atomic (MN-REQ-06.16)** — every snapshot (session save, expire save, checkpoint, safe-upgrade), `upgrade-manifest.json`, `upgrade-blocked.json`, `upgrade-restore.json`, and `checkpoint-manifest.json` is written through one helper (`memnet/atomic_file.py`): a temp file created `0600` (`O_EXCL`), fsynced, then renamed. Files are `0600` even when they replace an older file with a looser mode. The upgrade passport is written in the same snapshot write, not appended afterwards. - **Bind stores a lease digest, not the lease (MN-REQ-06.16)** — `session acl-bind` keeps the SHA-256 of the lease (`memnet.acl.lease_digest`). `check_bind` hashes the presented `--lease` (or `MEMNET_LEASE`) and compares digests in constant time. The snapshot, the passport, and the in-memory session never hold the raw lease. Consequence: a lost lease cannot be read back from a snapshot; re-run `session acl-bind` with the lease. The lease must be a high-entropy secret (SHA-256 is not a password KDF). A pre-digest snapshot with a raw `lease` loads and is hashed on load. - **Upgrade restore keeps the ACL enabled flag as written** — a passport ACL with `enabled: false` but grants no longer comes back enabled. -- **Invent only — ClusterRoute vs SliceHandCarry (#191 / #47 cousin)** — `MemNetTwoMoves` outside `MemNetSystem` (`MN-REQ-06.9` + `MN-REQ-06.10` / `MN-VER-06-S08`). ClusterRoute = where the session lives (`MemNetLanMcpFront`; one owner; `pin_map` / `find` SHALL NOT span backends). SliceHandCarry = explicit copy into another session (`export_pin_map` or `session_save` → LAN file copy → dest import/`session_load`; `import_slice` same-serve only). Not a live hop. `import_slice(from_url)` not shipped. tip≠face. `inventOnly=true`; `implemented=false`; no engine code; no SemVer bump. Wire: [`docs/operations/cluster-route-vs-slice-hand-carry.md`](docs/operations/cluster-route-vs-slice-hand-carry.md). -- **Invent only — LAN MCP front over several serves (#191)** — `MemNetLanMcpFront` outside `MemNetSystem` (`MN-REQ-06.9` / `MN-VER-06-S07`). One MCP catalogue, N LAN `memnet serve` backends; `SessionOwnerRegistry` is owner (explicit pin allowed; silent hash is not sole routing). One owner per session; `pin_map` / `find` SHALL NOT span backends. Cousin of #47 (peer sid handoff), not the same invent. tip≠face. `inventOnly=true`; `implemented=false`; no engine code; no SemVer bump. Wire: [`docs/operations/memnet-lan-mcp-front.md`](docs/operations/memnet-lan-mcp-front.md). +- **Package identity 0.19.24** — Hatch / `project.toml` / `memnet.__version__` honesty cut on **0.19**. Agent loop (`cue → pin_map → mutate`) unchanged. ## [0.19.23] - 2026-10-11 diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 0f2b86d..bc3a608 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -4,9 +4,9 @@ **Audience:** product developers. Dialect teach = **GQL** ([`grammar/gql-wire-profile.md`](grammar/gql-wire-profile.md)). Product shape: [`SHAPE.md`](SHAPE.md). British English. -**Package now:** Hatch **0.19.23** (`memnet.__version__`). Last published PyPI wheel is **`memnet-llm==0.19.22`** until this cut is uploaded. Numbered extras **0.10–0.19** are in this package (unchanged). **0.19.23** honesty `c` is the admin checkpoint (#211, MN-REQ-06.15): `memnet admin checkpoint` saves every loaded session without draining (atomic write, manifest, unsaveable sessions skipped) and `memnet admin checkpoint-verify` checks a restored copy. **0.19.22** honesty `c` was the safe serve upgrade path (#208 trimmed by #210, MN-REQ-06.14): admin `upgrade-prepare` drain, lossless snapshot with manifest, startup restore under the same ids, and automatic retire after a clean restore. **0.19.21** honesty `c` was serve per-request output isolation, LF-only statement split, undeclared-property snapshot save, label case-fold, and housekeep GQL endpoint orphans with `prune_referenced` refusal (#206). **0.19.20** honesty `c` was the memnet-mcp product gateway (`--transport gateway`, #203, MN-REQ-06.12). **0.19.19** honesty `c` was the one-session-per-document readiness probe (#201) plus lossless snapshot round-trip, one decoded value cap, honoured-or-refused WHERE, ACL who on save/load/close, and expire-save failures kept live (#202). **0.19.18** honesty `c` was snap_model bounded session grain (#199). **0.19.17** honesty `c` was the product-gate cap contract (#196) and admin-only serve usage report (#197). **0.19.16** honesty `c` was shared Path-B ingest defaults (2000 nodes / 2000 edges). **0.19.15** honesty `c` was storage role labels (#186), Path-B SysML ingest kinds (#188), and Neo4j retired (#189). **0.19.14** honesty `c` was TTL expire restore by known sid. **0.19.11** honesty `c` was the tip roll for [#168](https://github.com/chouswei/MemNet/pull/168) (catalog cross-session satisfy locators + `CousinSysMLEdge` `mustNotInventUploadBind`; do not claim tip=face). **0.19.10** honesty `c` keeps CueConflict for MATCH_L `|Q|>1` only; codebook miss emits CueMiss / Peak_L. **0.19.9** honesty `c` maps Path-B SysML `connection` / `link` to `:CON` (teach already said CON; ingest had mapped defs to PRT). **0.19.8** honesty `c` mints leftover nicknames on **all** snapshot records (not only catalog PKG) and accepts camelCase product relations (`inFile`) so `session_save` → `session_load` round-trips mission graphs. GraphGlot parse front is on master (#109 @ 73a63c9b). Neo4j cabinet is retired (#187); **0.7** is adapter + operator round trip (no runtime caller). **1.0** is still unclaimed (0.5–0.8). +**Package now:** Hatch **0.19.24** (`memnet.__version__`). Last published PyPI wheel is **`memnet-llm==0.19.23`** until this cut is uploaded. Numbered extras **0.10–0.19** are in this package (unchanged). **0.19.24** honesty `c` is session ACL in snapshots (#215, MN-REQ-06.16): `@SNAP` format 2 carries the ACL (fail closed if missing), 0600 atomic writes, lease digest, one-time `.v1.bak` before the first v2 write. **0.19.23** honesty `c` was the admin checkpoint (#211, MN-REQ-06.15): `memnet admin checkpoint` saves every loaded session without draining (atomic write, manifest, unsaveable sessions skipped) and `memnet admin checkpoint-verify` checks a restored copy. **0.19.22** honesty `c` was the safe serve upgrade path (#208 trimmed by #210, MN-REQ-06.14): admin `upgrade-prepare` drain, lossless snapshot with manifest, startup restore under the same ids, and automatic retire after a clean restore. **0.19.21** honesty `c` was serve per-request output isolation, LF-only statement split, undeclared-property snapshot save, label case-fold, and housekeep GQL endpoint orphans with `prune_referenced` refusal (#206). **0.19.20** honesty `c` was the memnet-mcp product gateway (`--transport gateway`, #203, MN-REQ-06.12). **0.19.19** honesty `c` was the one-session-per-document readiness probe (#201) plus lossless snapshot round-trip, one decoded value cap, honoured-or-refused WHERE, ACL who on save/load/close, and expire-save failures kept live (#202). **0.19.18** honesty `c` was snap_model bounded session grain (#199). **0.19.17** honesty `c` was the product-gate cap contract (#196) and admin-only serve usage report (#197). **0.19.16** honesty `c` was shared Path-B ingest defaults (2000 nodes / 2000 edges). **0.19.15** honesty `c` was storage role labels (#186), Path-B SysML ingest kinds (#188), and Neo4j retired (#189). **0.19.14** honesty `c` was TTL expire restore by known sid. **0.19.11** honesty `c` was the tip roll for [#168](https://github.com/chouswei/MemNet/pull/168) (catalog cross-session satisfy locators + `CousinSysMLEdge` `mustNotInventUploadBind`; do not claim tip=face). **0.19.10** honesty `c` keeps CueConflict for MATCH_L `|Q|>1` only; codebook miss emits CueMiss / Peak_L. **0.19.9** honesty `c` maps Path-B SysML `connection` / `link` to `:CON` (teach already said CON; ingest had mapped defs to PRT). **0.19.8** honesty `c` mints leftover nicknames on **all** snapshot records (not only catalog PKG) and accepts camelCase product relations (`inFile`) so `session_save` → `session_load` round-trips mission graphs. GraphGlot parse front is on master (#109 @ 73a63c9b). Neo4j cabinet is retired (#187); **0.7** is adapter + operator round trip (no runtime caller). **1.0** is still unclaimed (0.5–0.8). -**Last updated:** 2026-10-11 (`a.b.c` law locked; package **0.19.23** honesty `c` — admin checkpoint and checkpoint-verify (#211); extras **0.10–0.19** unchanged; Hatch **0.19.23**; last published PyPI **`memnet-llm==0.19.22`**; do not claim **1.0**; do not invent a **0.20** extra; do not claim tip=face). +**Last updated:** 2026-10-14 (`a.b.c` law locked; package **0.19.24** honesty `c` — session ACL in snapshots (#215); extras **0.10–0.19** unchanged; Hatch **0.19.24**; last published PyPI **`memnet-llm==0.19.23`**; do not claim **1.0**; do not invent a **0.20** extra; do not claim tip=face). Patch notes: [`../CHANGELOG.md`](../CHANGELOG.md). CHANGELOG still follows Keep a Changelog. This file is how MemNet **interprets** SemVer — not a silent switch to npm-strict major=breaking for 0.x extras. @@ -45,7 +45,7 @@ Pure efficiency / speed on the current loop is **`0.19.c`**, not `0.20`. ### Consequences -- Package is **0.19.23**. Extras **0.10–0.19** stay the owns table below. **1.0** stays unclaimed. +- Package is **0.19.24**. Extras **0.10–0.19** stay the owns table below. **1.0** stays unclaimed. - **1.0 does not wait** on 0.19.c, efficiency, HostSearch, Peak_L, catalog Snap, N-server, or GraphGlot. - A new cabinet adapter does **not** move `a`. Hosted Agens as a product service, first-class `PORT`, and full ACL modes / `session_token` stay Later / unnumbered until a cut exists. @@ -99,8 +99,8 @@ Handoff = **session id** (+ cue / write scope). Peers **re-`pin_map`** from labe | **0.7.0** | Adapter + operator round trip (no runtime caller); `liveCabinetClaimed=true`. Server not vendored. Fake + skip unless `MEMNET_AGENSGRAPH_URL`. No runtime hydrate/flush caller | **Shipped** (`v0.7.0`); claim narrowed (#187) | | **0.8.0** | GQL-only **teach** + product **shape for people** (`SHAPE.md`, playbook, application-note contract, Multitask honesty). Docs only. **No** engine cut. Cabinet stays claimed | **Shipped** (`v0.8.0`) | | **0.9.0** | Neo4j `DurableStoreAdapter` client (`memnet-llm[neo4j]`); factory both-URL rule; [`cabinet/neo4j-buffer.md`](cabinet/neo4j-buffer.md). Live round-trip claimed later as extra **0.14**. Cabinet extra, **not** a 1.0 gate | **Shipped** (`v0.9.0` era; extras later packaged as 0.19.0) | -| **0.10–0.19** | Numbered extras (table below). Each row is one `b` (usage-method revision). Same pattern as 0.9: **not** 1.0 gates | **Packaged** (Hatch **0.19.23**; last published PyPI **`memnet-llm==0.19.22`**; extras first shipped as 0.19.0) | -| **1.0.0** | **Claim** of **0.5 + 0.6 + 0.7 + 0.8**. Shape mature for people. Not GraphRAG. Not cabinet-only. Not a new engine. This is `a=1` | **Claim when coordinator tags** — package **0.19.23** does not claim 1.0 | +| **0.10–0.19** | Numbered extras (table below). Each row is one `b` (usage-method revision). Same pattern as 0.9: **not** 1.0 gates | **Packaged** (Hatch **0.19.24**; last published PyPI **`memnet-llm==0.19.23`**; extras first shipped as 0.19.0) | +| **1.0.0** | **Claim** of **0.5 + 0.6 + 0.7 + 0.8**. Shape mature for people. Not GraphRAG. Not cabinet-only. Not a new engine. This is `a=1` | **Claim when coordinator tags** — package **0.19.24** does not claim 1.0 | | **Later** | Grammar Open / hosted product / leftover ACL; N-server research (#47); LAN MCP front invent (#191). GraphGlot parse-front is **shipped**. If **1.0 tags first**, remaining extras become **1.1, 1.2, …** with the same owns (`b` after the claim) | **Out** of 1.0 | **1.0 MAY ship from 0.9** (claim only). **0.10+ MAY ship before 1.0** as extras (`b` on `a=0`). Do not wait for the other. User-pack GQL rewrite is **sibling** (`chouswei/cursor-user-skills`), not this repo. @@ -135,7 +135,7 @@ Do **not** treat leftover 0.9 identity as a live-Neo4j claim. Do **not** claim * ## Numbered extras (0.10–0.19) -One concern per **`b`** (usage-method revision). Dependency order. **In package 0.19.0** (git tag by coordinator). Skip a `b` only if the coordinator writes the skip in CHANGELOG; do not fuse two usage-method changes into one `b`. Cuts on the same method are **`c`** (0.19.1–0.19.23). There is **no** 0.20 extra row. +One concern per **`b`** (usage-method revision). Dependency order. **In package 0.19.0** (git tag by coordinator). Skip a `b` only if the coordinator writes the skip in CHANGELOG; do not fuse two usage-method changes into one `b`. Cuts on the same method are **`c`** (0.19.1–0.19.24). There is **no** 0.20 extra row. | Version | Owns | Depends on | MUST NOT | |---------|------|------------|----------| diff --git a/docs/operations/product-gateway-contract.md b/docs/operations/product-gateway-contract.md index 0493d7d..2d8661c 100644 --- a/docs/operations/product-gateway-contract.md +++ b/docs/operations/product-gateway-contract.md @@ -4,7 +4,7 @@ The gateway is `memnet-mcp --transport gateway`. It is not a separate droplet shim. The #191 catalogue (MCP tool union, SnapshotHandCarry) stays invent-only on the parent part. -Online products reach a `memnet serve` only through this process. Sample pin below is **0.19.23**. Backend ids are arbitrary strings. The live Endleaf backend id is `pi-endleaf`. +Online products reach a `memnet serve` only through this process. Sample pin below is **0.19.24**. Backend ids are arbitrary strings. The live Endleaf backend id is `pi-endleaf`. stdio and streamable-http do not read the registry. With no `MEMNET_GATEWAY_CONFIG`, one memnet-mcp process stays a single in-process or streamable-http server. @@ -91,7 +91,7 @@ The gateway body ceiling is `body_max_bytes`, default **4194304** (4 MiB), the s ## Version pin -Each product has `pinned_version` (sample below, `0.19.23`). Before a forward, the gateway calls `version` on that backend and requires `@VER: memnet|`. A mismatch is `gateway_backend_version_mismatch` and the argv is not sent. Upgrading a serve without changing the pin refuses the product. Changing the pin is how the owner is notified: edit the config and restart the gateway. +Each product has `pinned_version` (sample below, `0.19.24`). Before a forward, the gateway calls `version` on that backend and requires `@VER: memnet|`. A mismatch is `gateway_backend_version_mismatch` and the argv is not sent. Upgrading a serve without changing the pin refuses the product. Changing the pin is how the owner is notified: edit the config and restart the gateway. `version_cache_s` defaults to 15. Set `0` to check every call. A serve upgraded inside a non-zero window can still be reached until the cache expires. @@ -190,7 +190,7 @@ The product host exports the plaintext bearer as `MEMNET_GATEWAY_TOKEN` (for exa "endleaf": { "backends": ["pi-endleaf"], "houses": {"syson": "pi-endleaf"}, - "pinned_version": "0.19.23", + "pinned_version": "0.19.24", "credentials": [ {"id": "endleaf-1", "sha256": "", "revoked": false} ] diff --git a/parts/common/memnet/memnet/__init__.py b/parts/common/memnet/memnet/__init__.py index 1627fc8..f05a150 100644 --- a/parts/common/memnet/memnet/__init__.py +++ b/parts/common/memnet/memnet/__init__.py @@ -1,3 +1,3 @@ """MemNet — mission working memory for LLM agents (session graph + pin_map).""" -__version__ = "0.19.23" +__version__ = "0.19.24" diff --git a/project.toml b/project.toml index 947c94c..d82610e 100644 --- a/project.toml +++ b/project.toml @@ -1,7 +1,7 @@ [project] name = "memnet" repo = "MemNet" -version = "0.19.23" +version = "0.19.24" description = "Mission working memory for LLM agents: session graph + pin_map, not a RAG corpus" # No pcba-libs pins — software-only system (see LAYOUT.md). diff --git a/tests/test_doc_gate_readiness.py b/tests/test_doc_gate_readiness.py index 76c81f1..c788f90 100644 --- a/tests/test_doc_gate_readiness.py +++ b/tests/test_doc_gate_readiness.py @@ -51,8 +51,8 @@ from memnet.snapshot import SNAPSHOT_MAGIC -def test_version_is_0_19_23(): - assert __version__ == "0.19.23" +def test_version_is_0_19_24(): + assert __version__ == "0.19.24" def test_cap_contract_needles_unchanged(): diff --git a/tests/test_sysml_cluster_vs_slice.py b/tests/test_sysml_cluster_vs_slice.py index d7f9860..f2455e5 100644 --- a/tests/test_sysml_cluster_vs_slice.py +++ b/tests/test_sysml_cluster_vs_slice.py @@ -111,5 +111,5 @@ def test_teach_one_screen_contrast(): def test_no_semver_bump_in_this_invent(): text = _PROJECT.read_text(encoding="utf-8") - assert 'version = "0.19.23"' in text - assert "0.19.24" not in text + assert 'version = "0.19.24"' in text + assert "0.19.25" not in text diff --git a/tests/test_sysml_lan_mcp_front.py b/tests/test_sysml_lan_mcp_front.py index 65ba8e6..f7e0dc4 100644 --- a/tests/test_sysml_lan_mcp_front.py +++ b/tests/test_sysml_lan_mcp_front.py @@ -120,5 +120,5 @@ def test_teach_contrasts_47_and_worth_building(): def test_no_semver_bump_in_this_invent(): text = _PROJECT.read_text(encoding="utf-8") - assert 'version = "0.19.23"' in text - assert "0.19.24" not in text + assert 'version = "0.19.24"' in text + assert "0.19.25" not in text diff --git a/tests/test_sysml_product_gateway.py b/tests/test_sysml_product_gateway.py index f4b45a1..d33e551 100644 --- a/tests/test_sysml_product_gateway.py +++ b/tests/test_sysml_product_gateway.py @@ -64,5 +64,5 @@ def test_contract_is_not_draft_and_no_semver_bump(): assert "worthBuildingVisible=true" in nest assert "MemNetProductGateway" in nest project = PROJECT.read_text(encoding="utf-8") - assert 'version = "0.19.23"' in project - assert "0.19.24" not in project + assert 'version = "0.19.24"' in project + assert "0.19.25" not in project