Repository navigation
Keep expire-save failures live; lossless snapshot, WHERE, ACL who - #202
Merged
Merged
Conversation
SysML-first honesty cut: lossless snapshot round-trip, honour-or-refuse WHERE, consistent decoded value_bytes cap, and who-check on session save/load/close. Verify cases MN-VER-01-S04, 01-S05, 03-S01, 05-S01. Co-authored-by: chouswei <chouswei@users.noreply.github.com>
Snapshot emit escapes LF/CR/pipe/backslash; load decodes; save fails closed with snapshot_unsaveable. GQL mutate shares MEMNET_MAX_VALUE_BYTES on decoded UTF-8. MATCH WHERE SET/DELETE honours the predicate or refuses unsupported_predicate with nothing applied. Session save/load/close accept --caller when ACL is enabled; MCP passes caller through. Co-authored-by: chouswei <chouswei@users.noreply.github.com>
Pytest covers lossless specials, 0.19.18 fixture load, GQL value_bytes, unsupported_predicate, fail-closed save, and session save/load/close ACL. Cap-contract probe hits the new wires; bug 4 (GQL mutate skipping the value cap) is removed. Co-authored-by: chouswei <chouswei@users.noreply.github.com>
Co-authored-by: chouswei <chouswei@users.noreply.github.com>
… check line_bytes at save. Co-authored-by: chouswei <chouswei@users.noreply.github.com>
…ite-time line_bytes. Co-authored-by: chouswei <chouswei@users.noreply.github.com>
Co-authored-by: chouswei <chouswei@users.noreply.github.com>
…HERE, and ACL who. Co-authored-by: chouswei <chouswei@users.noreply.github.com>
…TE in E16. Co-authored-by: chouswei <chouswei@users.noreply.github.com>
cursor
Bot
force-pushed
the
cursor/engine-snapshot-where-acl-44e2
branch
from
October 8, 2026 14:43
bfb986b to
f38746c
Compare
Expire-save failure (snapshot_unsaveable or OSError) no longer drops RAM. The session still counts against MEMNET_MAX_SESSIONS, retries warn expire_snapshot_failed, and access after TTL is session_expired|overdue until an explicit successful save or close. Save-on-expire off is unchanged. Co-authored-by: chouswei <chouswei@users.noreply.github.com>
Serve @err replaces inner pipes with spaces; the hold still counts against MEMNET_MAX_SESSIONS. Co-authored-by: chouswei <chouswei@users.noreply.github.com>
Trivial WHERE true stays honoured, not unsupported_predicate. In-process and live serve loopback cover the exact no-space id map spelling the gate sends. Co-authored-by: chouswei <chouswei@users.noreply.github.com>
chouswei
marked this pull request as ready for review
October 8, 2026 15:14
chouswei
added a commit
that referenced
this pull request
Oct 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Patch-level honesty cut on 0.19.18 (no version bump, tag, or PyPI publish). Follow-on from the doc-gate readiness probe in #201 (squash-merged as
8a634d3). This branch is rebased onto that master. SysML first: MN-REQ-01.9, MN-REQ-01.3, MN-REQ-01.10, MN-REQ-03.4, MN-REQ-05.3, then engine. Do not merge.Owner decision — expire-save failure keeps RAM
When save-on-expire cannot write a snapshot (
snapshot_unsaveableor any other save failure, such as an unwritable disk or directory), MemNet does not drop the session. It stays live in RAM, still counts againstMEMNET_MAX_SESSIONS, and every sweep or access that retries expiry emits@WRN: expire_snapshot_failed|{code}. Access after TTL is@ERR: session_expired|overdueso the caller can fix and save, or close. An explicitsession savethat succeeds, or an explicitsession close, ends that hold.session expire-status,session list, and the admin usage report expose the hold count (@STAT: expire_snapshot_failed|n|/sessions.expire_snapshot_failed). When save-on-expire is off, TTL still drops RAM.Tests (in-process and live serve loopback): unsaveable expiry keeps and warns; later fix plus save clears; close clears; the held session still counts against the cap.
Endleaf compatibility —
WHERE trueEndleaf's gate deletes edges with
MATCH (n WHERE true)-[r {id:'…'}]->() DELETE rand never sends any other WHERE. TrivialWHERE trueis honoured (notunsupported_predicate). In-processtest_where_true_edge_delete_still_worksand livetest_endleaf_where_true_edge_deleteuse that exact spelling.Bug 1 — snapshot save/load round-trip
Anything the write path accepts now saves and reloads byte for byte, including LF, CR, tab, VT, FF, FS/GS/RS, NEL, LS, PS, backslash, both quote kinds,
$, braces,|, and CJK.str.splitlines()separator plus|and\\; load splits records on LF only (notstr.splitlines()).qname) persist by widening the snapshot SCHEMA. Live session SCHEMA is unchanged. Extras on fixed tagsEDG/LAW, or a widened SCHEMA overmax_fields, refusesnapshot_unsaveableand write no file.MEMNET_MAX_VALUE_BYTES(default 4096; a product MAY raise it to 16384).@ERR: limit_exceeded|value_bytes {n}/{max}.line_bytesis the UTF-8 length of the escaped/raw leftover-pipe or snapshot line. Save verify and load share this check.@ERR: snapshot_unsaveable|{tag} nick={nick} …and no file.Bug 2 — MATCH WHERE SET/DELETE
WHERE is honoured or the whole statement is refused. Nothing is applied on refuse.
MATCH ()-[r {id}]-() DELETE rhonours relationship DELETE.MATCH (n WHERE true)-[r {id}]->() DELETE rremains the gated edge-delete spelling.Bug 3 — ACL on save / load / close
When session ACL is enabled,
session save,session load(into that ACL'd session), andsession closeaccept--caller/MEMNET_CALLERand enforceacl_who/acl_denied/acl_forbidden. MCP passescaller. Without ACL, behaviour is unchanged.#201 probe / docs flipped (not skipped)
tests/test_doc_gate_readiness.py,tests/doc_gate_lib.py,scripts/probe_doc_gate_readiness.py, anddocs/operations/one-session-per-document.mdnow expect the fixed behaviour: multiline/CR round-trip, 16 KiB refused at mutate (value_bytes 16384/4096), WHERE honoured, ACL who on save/close, extras persist or refuse at save overmax_fields. Expire-save failure keep-live is also taught there and indocs/cap-contract.md.Synthetic data only. No real
mn_…session ids in the tree.