Status: SemVer SSOT (claimed vs planned vs Later). Package memnet-llm uses locked a.b.c below.
Audience: product developers. Dialect teach = GQL (grammar/gql-wire-profile.md). Product shape: SHAPE.md. British English.
Package now: Hatch 0.19.16 (memnet.__version__). Last published PyPI wheel is memnet-llm==0.19.15 until this cut is uploaded. Numbered extras 0.10–0.19 are in this package (unchanged). 0.19.16 honesty c is 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 (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-04 (a.b.c law locked; package 0.19.16 honesty c — shared ingest defaults 2000 nodes / 2000 edges; extras 0.10–0.19 unchanged; Hatch 0.19.16; last published PyPI memnet-llm==0.19.15; do not claim 1.0; do not invent a 0.20 extra; do not claim tip=face).
Patch notes: ../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.
Package memnet-llm uses a.b.c. Coordinator lock 2026-08-23. This is law, not a suggestion.
0= 1.0 is unclaimed.1= coordinator claim of 0.5 + 0.6 + 0.7 + 0.8 (goldfish, honesty, Agens adapter + operator round trip with no runtime caller, GQL teach). Not GraphRAG. Not a new engine. Not cabinet-only.amoves only if the product contract breaks: two operators (Recall =pin_map/ Commit =mutate), GraphElement identity, GQL-only wire.- Do not bump
afor extras, efficiency, N-server, or a new cabinet adapter.
Feature changes that change how an agent uses MemNet. b moves only when the usage method changes: a new required loop step, a new tool they must learn as product, a cue / outline / identity law change, a new goldfish verb.
Historical 0.10–0.19 extras were this (identity, outline, SameThingAbsorb, caller, live Neo4j, catalog Snap, two namespaces, HostSearch, Peak_L, pin-map export).
N-server (#47) is not a b. It stays Later research, unnumbered. LAN MCP front (#191) is the same: invent-only, not a b, not a SemVer cut.
One concern per b. Do not fuse two usage-method changes into one b. Skip a b only if the coordinator writes the skip in CHANGELOG.
0.20 exists only if a later cut changes usage method. Do not add a 0.20 extra row for efficiency.
Same usage method. Honesty, leftover naming, docs / skills, wheel / tag, caps, façade, faster same goldfish loop (cue → pin_map → mutate with no new agent step).
0.19.1–0.19.11 were this (session_close + sessions|n/max + cap 1024 + ranking + nickname-off-pin_map + SHAPE_DROP_KEYS + Truncation-on-clip + catalog leftover nicknames + snapshot leftover nicks on every record + camelCase :inFile + Path-B SysML connection → CON + CueMiss/Peak_L vs CueConflict + catalog cross-session satisfy locators shipped as c because the loop stayed the same).
Pure efficiency / speed on the current loop is 0.19.c, not 0.20.
- Package is 0.19.16. 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-classPORT, and full ACL modes /session_tokenstay Later / unnumbered until a cut exists.
MemNet is mission working memory — the memory plane of an agent harness, not the harness, not the library, not the cabinet.
outer harness (Cursor, OpenHands, SWE-agent, Inspect, …)
owns: completion API, bash, sandbox, eval, chat list
|
| MCP / CLI session id + cue / re-pin
v
memnet-llm / memnet-mcp ← this repo (engine + generic MCP)
Recall pin_map(q) Commit Δ
|
+----------+------------------+
| |
host Snap (RAG) cabinet Bolt
locators only hydrate / flush
HostSearch locators (0.17) Agens 0.7: adapter + operator
outside MemNetSystem round trip (no runtime caller)
Neo4j retired (#187)
| Layer | Job | This repo? |
|---|---|---|
| Outer harness | Loop, tools, env blob, eval tape | No |
| Memory plane | Named session (S); goldfish Shape; sparse mutate; Path-B Absorb | Yes — engine + memnet-mcp |
| Library RAG | Corpus → locators (Snap) | 0.17 HostSearch outside MemNetSystem (skip valid) |
| Cabinet | Persist one (S) | Agens 0.7: adapter + operator round trip (no runtime caller). Neo4j retired (#187) |
Handoff = session id (+ cue / write scope). Peers re-pin_map from labels+properties (or a kind/keyword cue). Chat is never SSOT. A durable store backs (S); it is not the handle and not the default teach surface. MUST NOT reframe MemNet as a Cypher proxy or as GraphRAG.
Two operators only. Recall and Commit. CueConflict is an emit mark, not a command. SameThingAbsorb is a Commit rule, not a third operator. MUST NOT invent a replacement application store key (locator-as-PK, qname-as-PK, minted string-as-PK). GraphElement is identity. Optional property id is a nickname.
Two channels (thesis leftover, not a SemVer gate). Mission names (TSK/USR/MOD) live on (S). Env blobs (test logs, screenshots) stay in the outer harness (or its condenser). Do not put bash on (S) and call that Shape.
Goldfish caller (thesis leftover, not 1.0). Shape saves tokens only if the harness drops old pin_map rows from the chat list. Stuffing MCP JSON into growing messages saves zero. That caller is unshipped in public harnesses; user-pack mcp-memnet is how Cursor is taught. Do not hold 1.0 for OpenHands/SWE-agent adoption. The contract in this repo is 0.13.
| Version | Owns | Status |
|---|---|---|
| 0.5.0 | Goldfish leftover: paradox V1/V3/V4/V6; BoundedMatchFind (#73) seed-only find; multi-ego pin_map under one (M) + one LAW |
Shipped (v0.5.0) |
| 0.6.0 | Honesty: V5 LAW×N pytest; snapshot as offered durable; version-map docs | Shipped (v0.6.0) |
| 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. 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.16; last published PyPI memnet-llm==0.19.15; 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.16 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.
1.0 MUST NOT wait on 0.10+ — not HostSearch, not live Neo4j, not Peak_L, not catalog Snap, not a second Neo4j database name, not OpenHands/SWE-agent adoption, not GraphGlot, not N-server, not 0.19.c, not efficiency on the current loop.
GraphGlot (#109 @ 73a63c9b) is shipped as parse-front only. ProductGqlGate still runs after parse. Layer stays retired. HOLD is lifted (0.10 already shipped).
The nest on master (#108–#118) models GraphElement identity, CueConflict on emit, empty-cue session outline (MN-REQ-04.9 / #118), and SameThingAbsorb (SysML implemented=false; 0.12 engine already on master: agent-gated Commit MATCH (a),(b) SET a += b after CueConflict). The 0.11 engine cut emits the outline census (in package 0.19.0). leftover empty-seed skip is leftover only. Outline SHALL NOT absorb. Do not claim 1.0. Do not revert the 0.11 nest or the 0.12 Commit rule. Live Neo4j is extra 0.14 (claimed on master); not this leftover-store gap.
The 0.9 engine still runs leftover invented store. Numbered extras start at 0.10 because this gap is not named in 0.5–0.9:
| Leftover (as-is 0.9) | TARGET (model) |
|---|---|
by_id is the graph |
GraphElement is identity; hidden handle off the wire |
gql.py NEW / require ground id / CREATE () illegal |
CREATE () legal; MERGE/SET/DELETE by labels+properties; emit does not require {id} |
MCP/CLI pin_map --anchor; require_anchor as product |
pin_map from cue; no require_anchor as product |
find teaches copy-id then --anchor |
Seed (Q), then pin_map from labels+props. When ( |
SCHEMA id_first |
SCHEMA not id_first |
| import keep = MERGE-by-id | ImportAbsorb keep = pattern MERGE (labels+props / type+ends) |
ingest allocate_from_locator |
Locators are properties, not a PK |
leftover read_get / NEW / AssignedIdMap / import_slice id_policy as product commands |
Not product commands |
| Application notes still teach leftover 0.9 as law | 0.10 owns the TARGET teach rewrite |
Do not treat leftover 0.9 identity as a live-Neo4j claim. Do not claim 1.0 from 0.10.
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.16). There is no 0.20 extra row.
| Version | Owns | Depends on | MUST NOT |
|---|---|---|---|
| 0.10.0 | Identity + leftover façade. Done / in package 0.19.0. Engine: GraphElement identity; hidden handle off the wire; CREATE () legal; MERGE/SET/DELETE by labels+properties; SCHEMA not id_first; emit does not require {id}. Façade: pin_map from cue (no require_anchor as product); find emit CueConflict when ( |
Q | >1) (do not pick one root; do not absorb); leftover read_get / NEW / AssignedIdMap / import_slice id_policy / ingest allocate_from_locator are not product commands. Tests that lock leftover as success are rewritten. Application-note + LLM-GUIDE example rewrite (TARGET loop; leftover named leftover). SysML README nest sync. |
| 0.11.0 | Session outline. Done / in package 0.19.0. Empty cue is Recall of (S): kinds + hard-LIMIT exemplars (Neo4j Browser / db.labels + LIMIT k pattern). Model first if not yet in SysML, then code. Still one Recall. Name conflict among exemplars is CueConflict. |
0.10 (need pattern cue, not --anchor) |
Dump (S); getAllPages; RAG search; third operator; view=shell as the outline (that is grain on a seed) |
| 0.12.0 | SameThingAbsorb implemented. Done / in package 0.19.0. Agent-gated Commit after CueConflict. Pattern collapse (labels+props), not MERGE-by-id. Distinct from ImportAbsorb. SysML nest flag still implemented=false (Sysmler). |
0.10 CueConflict | Silent LLM merge in Recall; name-as-identity; third operator |
| 0.13.0 | Goldfish caller contract (old 0.10). Done / in package 0.19.0. Playbook + pytest: stuffed history of maps is a fail; drop prior map rows; sparse Δ. | 0.10 teach | Patch OpenHands/SWE-agent; rag_query; raise (M); claim 1.0 |
| 0.14.0 | Live Neo4j claimed (old 0.11). Historical operator proof rpi5-syson @ d23cc71. Retired from the current package (#187): model on MemNetArchive; adapter and extra removed; MEMNET_NEO4J_* ignored. |
0.10 identity (else live claim cements leftover_MERGE_by_id) | Vendor Neo4j server; LLM↔Bolt; restore the cabinet; claim hydrate-by-hid proven on live |
| 0.15.0 | Catalog Snap + session strata + model Snap (old 0.12). Done / in package 0.19.0 (#124 @ 7767ed84). extras/memnet-session-strata.md. Catalog cut's own fence: that extra does not own liveNeo4jClaimed. |
ImportAbsorb pattern match (0.10); ingest locators as props | ANN rank sessions; Absorb whole (S); Layer; one session per REQ |
| 0.16.0 | Two Neo4j namespaces (old 0.13). Was in package 0.19.0 (#127 @ c32d4c52). Retired with the Neo4j cabinet (#187). | 0.14 live claim | Fuse RRF/PPR into pin_map; rag_query; Snap-on-session; restore Neo4j; LLM↔Bolt |
| 0.17.0 | HostSearch locators (old 0.14). Done / in package 0.19.0 (#129 @ 00e74dfb). RagHostHook.implemented=true outside MemNetSystem; locators into MutateGate / ingest; skip is valid. |
0.16 | rag_query MCP; Snap-on-session |
| 0.18.0 | Peak_L last-resort (old 0.15). Done / in package 0.19.0 (#128 @ dc464cd4). Topology cue on residual (\rho^*) when codebook miss; never default goldfish; V9 paradox pytest. | 0.5 find | Peak as default |
| 0.19.0 | Pin-map export (old 0.16 / #66). Done / in package 0.19.0 (#123 @ 2c460e7d). Ingest ≠ export. | Shaped emit | Export as Absorb |
After 0.19 (still Later, unnumbered until a cut exists): hosted AgensGraph as a product service; first-class PORT NODE / SCHEMA vocab freeze; full ACL modes / session_token (CapsPolicy already ships when enabled). N-server session pipe stays research (no cut; #47).
Not a memnet-llm b: cache-hit dump vs Shape+Flash (measure, do not ship a SKU); OpenHands condenser patches; Inspect dual-tape; Letta MemFS; pure efficiency / speed on the current goldfish loop (that is 0.19.c). Gap plan (unshipped): extras/memnet-efficiency-gap.md. Teach Cursor via user-pack mcp-memnet. Sibling skills repo may absorb 0.13 caller text; this engine still owns the fail-the-stuffed-maps test.
0.10 MUST NOT wait on 0.14. 0.11 MUST NOT wait on HostSearch. 0.14 MUST NOT happen before 0.10. Parallel only when the Depends-on cell is already shipped.
0.8 MUST: one dialect teach (GQL only; Layer archive only); Write = display = bounded shaped pin_map; session id = handoff handle; working memory ≠ corpus (no rag_query). Wire SSOT: grammar/gql-wire-profile.md.
0.8 MUST NOT: Peak_L / HostSearch / N-server / export / rag_query; second live cabinet claim; vendor AgensGraph/Neo4j servers; restore Layer teach or novel-writer.
0.9 MUST NOT: vendor a Neo4j server; hold 1.0 for live Neo4j, HostSearch, N-server, Peak_L, catalog Snap, OpenHands adoption, or GraphGlot. Extra 0.14 claimed liveNeo4jClaimed while the package was still 0.9.0; coordinated bump is 0.19.0.
0.10 MUST NOT: wait on live Neo4j, HostSearch, Peak_L, catalog Snap, or GraphGlot.
Numbered fill is 0.10–0.19 above. This list is the overflow. MUST NOT treat design docs as implemented.
| Item | Notes |
|---|---|
| Hosted AgensGraph as a product service | 0.7 is the client adapter + operator round trip (no runtime caller); server not vendored |
First-class PORT NODE; SCHEMA vocab freeze |
Grammar Open; ports stay properties |
Full ACL modes / roles / session_token |
CapsPolicy cut already ships when enabled |
| GraphGlot parse-front (#109 @ 73a63c9b) | Shipped as parse-front only on master. ProductGqlGate still runs after parse. Not a store. Layer stays retired. |
| N-server session pipe (#47) | Research — no cut exists; not a b; MUST NOT treat the issue as a SemVer owns. Shared (S) across serve processes without Snap-on-session stays a research question. Not in 0.8; 1.0 MUST NOT wait on it. |
| Item | Notes |
|---|---|
| Goldfish caller in other harnesses | 0.13 owns the contract in this repo. OpenHands/SWE-agent/Inspect patches are not memnet-llm SemVer. |
| Cache-hit dump vs Shape+Flash | MN-REQ-00 unmeasured. Do not pretend dump always loses. |
| Env-blob channel | Harness condenser of pytest logs ≠ MemNet Shape. |
| Eval dual-tape | Inspect (and cousins) keep a transcript for scoring; (S) is not that tape. |
GQL: agent teach/wire only. MUST NOT revive Layer teach.
AgensGraph: backing graph for sessions — not a MemNet substitute and not the handoff handle. 0.7 is adapter + operator round trip (no runtime caller). MUST NOT dual-write without a single sync owner. MUST NOT teach LLM ↔ Bolt as the miss path. Neo4j is retired (#187).
| Phase | Owns | Shipped? |
|---|---|---|
| M1 | GQL wire profile SSOT; Layer archive; no Layer teach | Done (docs) |
| M2 | Engine/MCP: GQL accept + shaped pin_map emit; retire Layer/Tier A from product accept |
Done |
| M3 | In-repo LLM-GUIDE + application-notes bodies → GQL examples |
Done for Layer retirement. 0.10 TARGET teach rewrite (in package 0.19.0): cue/pin_map + pattern Commit; leftover --anchor / id:'NEW' named leftover. |
| M2.5 | Durable store behind working memory (MemNet ↔ AgensGraph hydrate/flush; one sync owner) | Done (0.7 adapter + operator round trip, no runtime caller). Neo4j retired (#187) |
Durable: cabinet/agensgraph-buffer.md, cabinet/neo4j-buffer.md. Numbered extras 0.10–0.19 above (in package 0.19.0).
CapsPolicy ACL (off by default), neighbourhood reserve (RSV), Path-B ingest domains (#64), ImportAbsorb + ImportGuard / CheapLlmImportGuard, LocalIpcGateway. See ../CHANGELOG.md and ../README.md.
| MUST | MUST NOT |
|---|---|
Teach Cursor remote as memnet-pi via "url" → streamable-http (:18766/mcp) |
Treat project memnet-local (stdio) as the default remote/shared path |
| Keep stdio local MCP optional / dev-only | Document stdio and HTTP as equal “primary” remotes |
Local single-agent may still use in-process stdio when no shared graph is needed. Multitask / shared graph → HTTP or TCP only.
| MUST | MUST NOT |
|---|---|
Teach GQL (openCypher-shaped) as the only agent wire (grammar/gql-wire-profile.md; family authority = openCypher CIP / oC9) |
Teach Layer / Tier A as wire, peer, or accept path |
Redefine Write = display as bounded shaped GQL subgraph via pin_map-class tool |
Ship unbounded tabular MATCH/RETURN as primary goldfish read |
Do not restore Layer / Tier A sources into docs/ |
Invent a third peer dialect |
Decision SSOT: adr/ADR-001-gql-agent-wire.md (supersession: no Layer).
| MUST | MUST NOT |
|---|---|
Bridge HTTP MCP to memnet serve (TCP :18765) so one process owns the store |
Run HTTP MCP with a separate InProcessEngine and TCP serve as two writers |
| Default remote HTTP so tools share the serve graph | Dual-write the same mission across two engines |
| Concern | Default / gate |
|---|---|
| Host | LAN bind + MEMNET_MCP_HTTP_TRUSTED_HOSTS |
| Token | Non-empty MEMNET_MCP_HTTP_TOKEN; Cursor Authorization: Bearer … |
view= |
Omit → shell-safe default; teach shell / interior first |
MUST NOT advertise empty-token LAN MCP as safe.
| MUST | MUST NOT |
|---|---|
Keep retrieve / generate / remember unfused. Goldfish = serial cue then pin_map |
Add rag_query (or equivalent) to memnet-mcp |
| Host search MAY propose locators into MutateGate / ingest; skip is valid | Store embeddings or chunk bodies as the memory surface |
#73 find is graph lookup (seed nodes only; then pin_map from labels+props), not corpus RAG. Do not teach copy-id then --anchor. When ( |
Q |
Design: extras/memnet-host-search-nest.md. Math: grammar/math-skeleton.md. Research: #77.
| Path | Role |
|---|---|
SHAPE.md |
Product shape from the problem (identity SSOT) |
extras/memnet-session-strata.md |
Sessions as strata (not Layer); 0.15 catalog |
../README.md |
Doctrine / how to run |
adr/ADR-001-gql-agent-wire.md |
GQL wire; no Layer |
grammar/gql-wire-profile.md |
M1 SSOT |
cabinet/agensgraph-buffer.md |
Durable GQL store adapter (M2.5) |
cabinet/neo4j-buffer.md |
Retired Neo4j cabinet (#187) |
grammar/math-skeleton.md |
0.5 Recall/Commit math |
extras/memnet-host-search-nest.md |
Host search nest (0.17; skip valid) |
application-notes/examples/inverting-amplifier-gql-case-study.md |
InvAmp GQL case study |
../sysml-models/README.md |
Nested SysML outline |
../parts/memnet-mcp/README.md |
HTTP env / Pi paste |
operations/multi-agent-sessions.md |
Multitask transport MUST |
../.cursor/mcp.json.example |
memnet-pi primary |