diff --git a/README.md b/README.md index 60ab4a2..5120b4f 100644 --- a/README.md +++ b/README.md @@ -417,7 +417,7 @@ Claims carry provenance — source, observation time, and the run that produced **Contradiction detection reports; it never resolves.** A new claim sharing a normalized (subject, predicate) with a stored one and differing in object is flagged. That is a structural test: it will not relate "is fast" to "is slow", will not match a rephrased object, and *will* flag a legitimately multi-valued predicate as disagreement. Auto-superseding on a detected conflict would delete half a multi-valued fact inside the one subsystem whose promise is that facts are never destroyed, so a caller supersedes on purpose or not at all. -The limit to know: **the in-process store is still the default.** `grapharc demo stage6` and `grapharc demo capstone` keep claims in a dict for the life of the process unless you pass `--memory PATH`, which hands them the `SQLiteMemoryStore` — verified to survive across two separate interpreters, not just two calls in one. In-process stays the default so a plain run writes nothing you did not ask for. `pyproject.toml` also declares a `memory` extra for Neo4j that has no implementation behind it. +The limit to know: **the in-process store is still the default.** `grapharc demo stage6` and `grapharc demo capstone` keep claims in a dict for the life of the process unless you pass `--memory PATH`, which hands them the `SQLiteMemoryStore` — verified to survive across two separate interpreters, not just two calls in one. In-process stays the default so a plain run writes nothing you did not ask for. The durable stores that exist are `SQLiteMemoryStore` (no extra needed) and `LadybugMemoryStore` (the `ladybug` extra); there is no extra beyond those. ## Sessions, the HTTP API, and policy diff --git a/ROADMAP.md b/ROADMAP.md index 19f58f7..620b425 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -384,7 +384,8 @@ Everything here works and nothing calls it. - [x] **8.7 — Hand a durable store to the shipped graphs.** `grapharc run --memory PATH` gives `stage6` and `capstone` the `SQLiteMemoryStore`; the in-process one remains the default so a plain run stays hermetic. The - `memory` extra still names Neo4j with nothing importing it. + `memory` extra that named Neo4j with nothing importing it was removed; + a Neo4j-backed store would bring its own extra with it. ## 9. Triggers & surfaces — `[~] ~55%` diff --git a/pyproject.toml b/pyproject.toml index 5aa8c67..7a4061c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,11 +85,6 @@ server = [ mcp = [ "mcp>=1.2", ] -# Neo4j-backed claim store (ROADMAP 8.x). Nothing imports `neo4j` today; the -# durable store that does exist is SQLite-backed and needs no extra. -memory = [ - "neo4j>=5.20", -] # LadybugDB-backed claim store — grapharc/memory/ladybug_store.py imports this # one, unlike the `memory` extra above. The distribution is `real-ladybug`, not # `ladybug`: the latter name belongs to Ladybug Tools, an unrelated @@ -115,7 +110,7 @@ slack = [ ] # Everything above. Self-referential so it cannot drift out of sync. all = [ - "grapharc[api,ladybug,mcp,memory,ollama,openai,openrouter,otel,server,slack]", + "grapharc[api,ladybug,mcp,ollama,openai,openrouter,otel,server,slack]", ] [dependency-groups] diff --git a/uv.lock b/uv.lock index eaa209b..c916e01 100644 --- a/uv.lock +++ b/uv.lock @@ -365,7 +365,6 @@ all = [ { name = "fastapi" }, { name = "langchain-openai" }, { name = "mcp" }, - { name = "neo4j" }, { name = "opentelemetry-api" }, { name = "opentelemetry-exporter-otlp-proto-http" }, { name = "opentelemetry-sdk" }, @@ -382,9 +381,6 @@ ladybug = [ mcp = [ { name = "mcp" }, ] -memory = [ - { name = "neo4j" }, -] ollama = [ { name = "langchain-openai" }, ] @@ -420,7 +416,7 @@ dev = [ requires-dist = [ { name = "anthropic", marker = "extra == 'api'", specifier = ">=0.40" }, { name = "fastapi", marker = "extra == 'server'", specifier = ">=0.115" }, - { name = "grapharc", extras = ["api", "ladybug", "mcp", "memory", "ollama", "openai", "openrouter", "otel", "server", "slack"], marker = "extra == 'all'" }, + { name = "grapharc", extras = ["api", "ladybug", "mcp", "ollama", "openai", "openrouter", "otel", "server", "slack"], marker = "extra == 'all'" }, { name = "langchain-core", specifier = ">=0.3" }, { name = "langchain-openai", marker = "extra == 'ollama'", specifier = ">=0.2" }, { name = "langchain-openai", marker = "extra == 'openai'", specifier = ">=0.2" }, @@ -428,7 +424,6 @@ requires-dist = [ { name = "langgraph", specifier = ">=0.4" }, { name = "langgraph-checkpoint-sqlite", specifier = ">=2.0" }, { name = "mcp", marker = "extra == 'mcp'", specifier = ">=1.2" }, - { name = "neo4j", marker = "extra == 'memory'", specifier = ">=5.20" }, { name = "opentelemetry-api", marker = "extra == 'otel'", specifier = ">=1.27" }, { name = "opentelemetry-exporter-otlp-proto-http", marker = "extra == 'otel'", specifier = ">=1.27" }, { name = "opentelemetry-sdk", marker = "extra == 'otel'", specifier = ">=1.27" }, @@ -437,7 +432,7 @@ requires-dist = [ { name = "slack-bolt", marker = "extra == 'slack'", specifier = ">=1.20" }, { name = "uvicorn", marker = "extra == 'server'", specifier = ">=0.32" }, ] -provides-extras = ["openrouter", "openai", "ollama", "server", "mcp", "memory", "ladybug", "otel", "api", "slack", "all"] +provides-extras = ["openrouter", "openai", "ollama", "server", "mcp", "ladybug", "otel", "api", "slack", "all"] [package.metadata.requires-dev] dev = [ @@ -797,18 +792,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e2/5e/d118fce19f87a2e7d8101c35c8ae0ec289098a4df0ff244cec23e415aca0/mcp-1.28.1-py3-none-any.whl", hash = "sha256:2726bca5e7193f61c5dde8b12500a6de2d9acf6d1a1c0be9e8c2e706437991df", size = 222620, upload-time = "2026-06-26T12:57:27.218Z" }, ] -[[package]] -name = "neo4j" -version = "6.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pytz" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ce/f4/aaa4ac19adae4b01bc742b63afd2672a77e7351566f02721e713e4b863ee/neo4j-6.2.0.tar.gz", hash = "sha256:e1e246b65b572bd8ea97f9e0e721b7d40a5ce53e53d0007c29aef63e4f9124d9", size = 241459, upload-time = "2026-05-04T07:35:41.428Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/cf/1c3795866cefaac6e648d4e98c373cafd97810f6e317c307371007ab4abb/neo4j-6.2.0-py3-none-any.whl", hash = "sha256:b87abdd13a5cc2e3bd51026926c2f20ac38fa3febe98c340520dce19e97388d0", size = 327824, upload-time = "2026-05-04T07:35:39.604Z" }, -] - [[package]] name = "openai" version = "2.48.0" @@ -1229,15 +1212,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e1/04/e8135ebd1ad02c56ec633277529b2602ff99ff634be76cdba5744cf554fd/python_multipart-0.0.32-py3-none-any.whl", hash = "sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23", size = 30042, upload-time = "2026-06-04T16:18:57.319Z" }, ] -[[package]] -name = "pytz" -version = "2026.3.post1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fb/48/fb042503b6ca6cd271261dc559fd6432f7d8c713153e9ec5c591af4dfc1c/pytz-2026.3.post1.tar.gz", hash = "sha256:2211d3fcf9a797d3405cac96ac7f61d80e6a644f72a3309607282fe8a2010c5d", size = 319745, upload-time = "2026-07-25T15:12:07.385Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/7b/39c34ca613b0b198cb866466651b26b045e2009864c5183c979a3b83f383/pytz-2026.3.post1-py2.py3-none-any.whl", hash = "sha256:dd95840dd199baea12d9cc096a1d452caa6596a1c1e4b5f3dbd1541855d5e815", size = 508283, upload-time = "2026-07-25T15:12:05.782Z" }, -] - [[package]] name = "pywin32" version = "312"