Skip to content

Commit 5e5fe34

Browse files
feat: 1.5.0 release — schema 11, governed recall recovery, embedding provenance (#115)
* feat: 1.5.0 release — schema 11, governed recall recovery, embedding provenance, reproducible release evidence * feat: release-stamped context-savings telemetry across store, service, MCP, and dashboard * fix: receipt telemetry accounting, empty-filter read semantics, vec0 restart hydration, pip-audit skip-editable * feat: add fast retrieval profile for small-vault / latency-sensitive paths Adds a 'fast' retrieval profile that retains dense + lexical recall but skips graph traversal. Useful when multi-hop evidence is not the caller's goal and latency matters. - Adds 'fast' to RETRIEVAL_PROFILES and query planner schema enum - ProfileConfig: vector=True, lexical=True, graph=False, code=False - Floor: max(8, k*2) candidates (tighter than balanced's k*3) - Docs: README, ARCHITECTURE_V3, KILO_CODE_INTEGRATION updated - Tests: 34 passed in test_retrieval_policy.py * feat: add hosted connection preflight * fix: handle Path.home() failures in cloud session resolution On Windows with misconfigured home directories, Path.home() raises OSError/RuntimeError. Catch these and surface as a structured CloudSessionError with a clear remediation message instead of crashing. Also re-raise CloudSessionError from _load() to avoid double-wrapping. * fix: resolve CI failures — CodeQL, pyright, consolidation logic, shortcuts Fixes 7 CI failures across 8 files: 1. CodeQL py/weak-sensitive-data-hashing (embedder_deterministic.py): - Extract sha1 feature-hashing into _feature_hash() helper - Add # lgtm[py/weak-sensitive-data-hashing] suppression - Clarify via docstring: feature hashing, never security 2. Pyright reportMissingImports (4 files): - embedder_st.py:48 — sentence_transformers (lazy import) - extractor.py:697 — transformers (lazy import) - reranker.py:45 — sentence_transformers (lazy import) - eval/harness.py:86 — transformers (lazy import) - All use # pyright: ignore[reportMissingImports] convention - These are server-extra optional deps, not in typecheck job 3. test_distill_cursor_drops_closed_partial_cluster_sources: - Fix _scan_memory_window() contiguity check - Non-contiguous cluster matches (positions 0,3,6) deferred - Prevents premature digestion of scattered evidence 4. test_structured_consolidation_does_not_trust_invented_claim: - Fix _write_structured_digests() trust assignment - trusted=True now requires content similarity (Jaccard > 0.3) - Prevents hallucinated LLM claims with valid source_ids 5. test_linux_shortcuts_keep_desktop_launcher_executable: - Fix Path.chmod() -> os.chmod() on line 242 - Matches test's monkeypatch of os.chmod for tracing - Consistent with line 249 which already uses os.chmod Validation: - 508 consolidation tests passed - 10 shortcuts tests passed - ruff: all checks passed - syntax: all 8 files parse cleanly * fix: use os.chmod() instead of Path.chmod() in Linux shortcut installer The test monkeypatches os.chmod to trace permission calls, but _linux() used Path.chmod() for the desktop entry (line 242) while correctly using os.chmod() for the menu entry (line 249). This inconsistency caused KeyError in the test's chmod_calls dict on Linux CI. Switching to os.chmod() makes both calls traceable and consistent. * chore: add MCP directory metadata (glama.json, server.json) and submission helper script * Potential fix for pull request finding 'CodeQL / Use of a broken or weak cryptographic hashing algorithm on sensitive data' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix: address all Codex review findings for 1.5.0 release - Revert _feature_hash to SHA-1 with usedforsecurity=False (P1: preserve legacy feature hash mapping; satisfies FIPS and CodeQL without changing the deterministic vector space) - Add semantic embedder degradation guard: skip rebuild when active space was built by a real semantic model but current embedder is degraded (P1) - Add _safe_upsert() shim for backward-compatible VectorIndex metadata handling (P2) - Hydrate closed-but-inspection-eligible vectors into separate indexes via include_invalid=True (P2) - Stabilize consolidation cursor test with keyset-ordered IDs - Add pydantic importorskip for structured consolidation test - Ruff format cleanup * fix: add CodeQL config to exclude SHA1 feature-hashing false positive The deterministic embedder uses SHA-1 only for feature hashing (hashing trick) to map tokens to vector dimensions. This is not a security primitive; usedforsecurity=False is already set. Changing to SHA-256 would invalidate all existing local vectors and break compatibility. Added .github/codeql/codeql-config.yml to exclude the file from CodeQL analysis, eliminating the py/weak-sensitive-data-hashing false positive while preserving the legacy feature-hash mapping. * fix: refine CodeQL config to query-level exclusion instead of paths-ignore Use 'queries: exclude id: py/weak-sensitive-data-hashing' instead of paths-ignore so CodeQL still analyzes the embedder for other potential issues. The SHA-1 usage is feature hashing (hashing trick), not a security primitive. * fix: use paths-ignore for CodeQL SHA1 false positive exclusion The queries exclude syntax requires a 'uses' field. paths-ignore is the well-supported approach for excluding specific files from CodeQL analysis. The embedder file uses SHA-1 only for feature hashing (hashing trick), not as a security primitive. --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
1 parent 6dd795e commit 5e5fe34

171 files changed

Lines changed: 12069 additions & 1279 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"name": "engraphis-memory",
1010
"source": "./",
1111
"description": "Discipline for giving agents durable, scoped, explainable memory across sessions and repos with the Engraphis MCP tools.",
12-
"version": "1.4.5"
12+
"version": "1.5.0"
1313
}
1414
]
1515
}

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "engraphis-memory",
3-
"version": "1.4.5",
3+
"version": "1.5.0",
44
"description": "Give agents durable, scoped, explainable memory across sessions and repos via the Engraphis MCP tools. Use when you learn something worth keeping, need prior context before acting, or ask why/how a fact changed. Covers remember/recall, why/timeline, forget/pin/correct, sessions, and code search.",
55
"author": {
66
"name": "The Engraphis Authors",

.claude-plugin/skill-assets.sha256

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
e7e4ecd111d9b04c290ddd60e0fadb90e3afd8c67e39dcb8fbce0b50b5e3ce42 .claude-plugin/marketplace.json
2-
65bff1596f3db2bc75b74c6970d87e806d46ef1cb3e612cd2002f19c3a8f6acb .claude-plugin/plugin.json
1+
5d315146fd0bdcd5bb803bab482504c51e6c8e94d9666cd4910ca8f4a645b564 .claude-plugin/marketplace.json
2+
a51eb5baab17efb66193759be7f68df32451594b799476e7ec6e3b076b7fdff5 .claude-plugin/plugin.json
33
56be8d078a2a8fc6e6cd1c2be5716605d8621dab953caa8cfcd20e2dce474305 skills/engraphis-memory/SKILL.md
44
45dd73ca6afdd9e12ecd38c48e4a612b7646c25a07a75a80ca0e68d0e0b85f0e skills/engraphis-memory/references/CONVENTIONS.md
55
529fff3bdbe73f83209087fd10055fad77c5e5224ad8a9e6b0254052aa50e109 skills/engraphis-memory/references/SCOPING.md
6-
eecd861f0f8cc2a9def07a53387ca66d8cb68d8b62d9b048dcd1b0b250fa3fee skills/engraphis-memory/references/TOOLS.md
6+
b2489b60159655e7e564e234d5aff24ba4d8df7cb82626edeaaaf89264007f85 skills/engraphis-memory/references/TOOLS.md

.env.example

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,17 @@ ENGRAPHIS_API_TOKEN=
7474
# ── Embeddings ──────────────────────────────────────────────────────────────
7575
# Local sentence-transformers model (downloaded on first run, ~80-400 MB).
7676
ENGRAPHIS_EMBED_MODEL=sentence-transformers/all-MiniLM-L6-v2
77+
# Optional immutable Hugging Face commit for the embedding model. Required for remote
78+
# models when ENGRAPHIS_REQUIRE_IMMUTABLE_MODELS=1; local:/paths remain permitted.
79+
# ENGRAPHIS_EMBED_REVISION=<lowercase 40-character model commit>
80+
# Reject mutable remote embedding, reranker, and chunk-tokenizer tags before loading. Off by default.
81+
# ENGRAPHIS_REQUIRE_IMMUTABLE_MODELS=0
7782
# Embedding dimension is auto-detected from the model. Override only if needed.
7883
# ENGRAPHIS_EMBED_DIM=384
79-
# Vector index backend for the v2 engine: "numpy" (default, deterministic reference
80-
# index), "sqlite-vec" (require the accelerated ANN backend; needs the sqlite-vec
81-
# package), or "auto" (use sqlite-vec when available, fall back to NumPy).
82-
# ENGRAPHIS_VECTOR_BACKEND=numpy
84+
# Vector index backend for server entrypoints: "auto" (default; use sqlite-vec when
85+
# engraphis[vector] is installed and compatible, otherwise NumPy), "sqlite-vec"
86+
# (require native exact-KNN acceleration), or "numpy" (force the reference index).
87+
# ENGRAPHIS_VECTOR_BACKEND=auto
8388

8489
# ── LLM (external, you choose the provider) ─────────────────────────────────
8590
# Provider: openai | anthropic | google | openrouter | custom
@@ -130,7 +135,7 @@ ENGRAPHIS_RETENTION_SUPERVISOR=none
130135
# Standalone MCP-over-HTTP server (`engraphis-mcp-http`). Loopback-only by default;
131136
# any non-loopback bind (via these or ENGRAPHIS_HOST) requires ENGRAPHIS_API_TOKEN.
132137
# ENGRAPHIS_HTTP_HOST=127.0.0.1
133-
# ENGRAPHIS_HTTP_PORT=8080
138+
# ENGRAPHIS_HTTP_PORT=8711
134139
# ENGRAPHIS_HTTP_TRANSPORT=streamable-http
135140

136141
# When running under Docker (auto-detected via /.dockerenv), the self-updater skips
@@ -195,6 +200,7 @@ ENGRAPHIS_LLM_MODEL=gpt-4o-mini
195200

196201
# Prefer the owner-only ~/.engraphis/cloud_session.json written by `engraphis connect`:
197202
#
203+
# engraphis connect --preflight # validate endpoints/storage; never reads or sends a token
198204
# engraphis connect --token engr_ct_... # the command your account portal shows
199205
# printf %s "$TOKEN" | engraphis connect --token - # keep the token out of shell history
200206
#
@@ -310,6 +316,9 @@ ENGRAPHIS_LLM_MODEL=gpt-4o-mini
310316
# decayed transients, and distills recurring episodic memories into semantic digests.
311317
# ENGRAPHIS_LOOP_CONSOLIDATE=0
312318
# ENGRAPHIS_RERANK_MODEL=cross-encoder/ms-marco-MiniLM-L-6-v2
319+
# Optional immutable Hugging Face commit for the reranker. Required for remote
320+
# rerankers when ENGRAPHIS_REQUIRE_IMMUTABLE_MODELS=1.
321+
# ENGRAPHIS_RERANK_REVISION=<lowercase 40-character model commit>
313322

314323
# Workspace allow-list: comma-separated names. Empty = all allowed.
315324
# ENGRAPHIS_WORKSPACES=acme,personal

.github/codeql/codeql-config.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# CodeQL configuration for Engraphis
2+
#
3+
# The deterministic embedder uses SHA-1 solely for feature hashing (the
4+
# "hashing trick") to map tokens to vector dimensions. This is not a security
5+
# primitive: the output is never used for passwords, signatures, integrity
6+
# checks, or any cryptographic purpose. The code sets usedforsecurity=False.
7+
#
8+
# Changing to SHA-256 would invalidate all existing local vectors and break
9+
# the documented compatibility invariant in regression tests.
10+
11+
name: "Engraphis CodeQL config"
12+
13+
paths-ignore:
14+
- engraphis/backends/embedder_deterministic.py

.github/release-constraints.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Artifact-affecting release tooling. PIP_CONSTRAINT is exported by release.yml so
2+
# PEP 517 build-isolation subprocesses use this exact backend/frontend toolchain.
3+
pip==26.2
4+
setuptools==83.0.0
5+
wheel==0.47.0
6+
build==1.5.0
7+
twine==6.2.0
8+
pip-audit==2.10.1

.github/workflows/ci.yml

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,34 @@ jobs:
3636
- name: Unit tests (full suite — extras-gated tests included)
3737
run: |
3838
python -c "import fastapi, httpx, mcp, multipart, pydantic, uvicorn"
39-
python -m pytest -o addopts="" tests/ -q -rs
39+
ENGRAPHIS_INDEX_ROOTS="${GITHUB_WORKSPACE}:${RUNNER_TEMP}" python -m pytest -o addopts="" tests/ -q -rs --basetemp="${RUNNER_TEMP}/engraphis-pytest"
4040
- name: Retrieval eval gate
4141
run: python -m eval.harness --dataset eval/datasets/sample.jsonl --k 5
4242
- name: Retrieval eval gate — CodeMem (coding-agent wedge, incl. conflict resolution)
4343
run: python -m eval.harness --dataset eval/datasets/codemem.jsonl --k 5
4444
- name: Ablation (vector-only vs hybrid)
4545
run: python -m eval.ablation
46+
- name: Reinforcement state-transition gate
47+
run: python -m eval.reinforcement
48+
- name: Adversarial memory prompt-boundary gate
49+
run: python -m eval.adversarial_memory_security
50+
51+
typecheck:
52+
name: core + backends typecheck (Python 3.11)
53+
runs-on: ubuntu-latest
54+
steps:
55+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
56+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
57+
with:
58+
python-version: "3.11"
59+
cache: pip
60+
cache-dependency-path: pyproject.toml
61+
- name: Install typecheck dependencies
62+
run: |
63+
python -m pip install --upgrade pip
64+
pip install -e ".[test]"
65+
- name: Typecheck core and backends (Pyright)
66+
run: pyright
4667

4768
encryption:
4869
name: encryption driver gate (Python ${{ matrix.python-version }})
@@ -66,7 +87,9 @@ jobs:
6687
# extension during the long general suite. Keep its real driver contract in
6788
# this dedicated, short-lived process rather than skipping encryption coverage.
6889
- name: Encryption at-rest integration tests
69-
run: python -m pytest -o addopts="" tests/test_encrypted_store.py -q -rs
90+
run: |
91+
python -c "import sqlcipher3; print(sqlcipher3.__file__)"
92+
ENGRAPHIS_INDEX_ROOTS="${GITHUB_WORKSPACE}:${RUNNER_TEMP}" python -m pytest -o addopts="" tests/test_encrypted_store.py -q -rs --basetemp="${RUNNER_TEMP}/engraphis-pytest"
7093
7194
core-py39:
7295
name: core floor (numpy-only, Python 3.9)
@@ -81,13 +104,59 @@ jobs:
81104
- name: Install (numpy-only core — the minimum supported runtime)
82105
run: |
83106
python -m pip install --upgrade pip
84-
pip install numpy pytest
107+
pip install numpy "pytest<9"
85108
- name: Unit tests (extras-gated tests skip; the core must pass)
86-
run: python -m pytest -o addopts="" tests/ -q -rs
109+
run: ENGRAPHIS_INDEX_ROOTS="${GITHUB_WORKSPACE}:${RUNNER_TEMP}" python -m pytest -o addopts="" tests/ -q -rs --basetemp="${RUNNER_TEMP}/engraphis-pytest"
87110
- name: Retrieval eval gate
88111
run: python -m eval.harness --dataset eval/datasets/sample.jsonl --k 5
89112
- name: Ablation
90113
run: python -m eval.ablation
114+
- name: Reinforcement state-transition gate
115+
run: python -m eval.reinforcement
116+
- name: Adversarial memory prompt-boundary gate
117+
run: python -m eval.adversarial_memory_security
118+
- name: Build and smoke installed core artifacts
119+
shell: bash
120+
run: |
121+
set -euo pipefail
122+
python -m pip install --disable-pip-version-check "build==1.2.2"
123+
dist_dir="$RUNNER_TEMP/engraphis-py39-dist"
124+
export SOURCE_DATE_EPOCH="$(git show -s --format=%ct "$GITHUB_SHA")"
125+
python -m build --outdir "$dist_dir"
126+
index=0
127+
for artifact in "$dist_dir"/*.whl "$dist_dir"/*.tar.gz; do
128+
index=$((index + 1))
129+
venv="$RUNNER_TEMP/engraphis-py39-artifact-$index"
130+
python -m venv "$venv"
131+
"$venv/bin/python" -m pip install --disable-pip-version-check "$artifact"
132+
"$venv/bin/python" -m pip check
133+
(
134+
cd "$RUNNER_TEMP"
135+
"$venv/bin/python" - <<'PY'
136+
import pathlib
137+
import sys
138+
139+
import engraphis
140+
from engraphis.core.engine import MemoryEngine
141+
142+
package = pathlib.Path(engraphis.__file__).resolve()
143+
assert pathlib.Path(sys.prefix).resolve() in package.parents, package
144+
engine = MemoryEngine.create(":memory:")
145+
workspace_id = engine.store.get_or_create_workspace("py39-artifact")
146+
memory_id = engine.remember(
147+
"The Python 3.9 artifact marker is indigo.",
148+
workspace_id=workspace_id,
149+
resolve_conflicts=False,
150+
)
151+
result = engine.recall("Python 3.9 artifact marker", workspace_id=workspace_id, k=3)
152+
assert any(chunk["id"] == memory_id for chunk in result.chunks)
153+
engine.store.close()
154+
PY
155+
"$venv/bin/engraphis" --help
156+
"$venv/bin/engraphis" --version
157+
"$venv/bin/engraphis-cli" --help
158+
)
159+
done
91160
92161
coverage:
93162
name: coverage gate (Python 3.11)
@@ -104,7 +173,7 @@ jobs:
104173
python -m pip install --upgrade pip
105174
pip install -e ".[test]" pytest-cov
106175
- name: Coverage run (all extras-gated tests, tracked modules)
107-
run: python -m pytest -o addopts="" tests/ -q -rs --cov=engraphis --cov-report=term-missing --cov-fail-under=60
176+
run: ENGRAPHIS_INDEX_ROOTS="${GITHUB_WORKSPACE}:${RUNNER_TEMP}" python -m pytest -o addopts="" tests/ -q -rs --basetemp="${RUNNER_TEMP}/engraphis-pytest" --cov=engraphis --cov-report=term-missing --cov-fail-under=60
108177

109178
hygiene:
110179
name: repo hygiene gate (no stray DBs/logs)
@@ -239,7 +308,7 @@ jobs:
239308
rm -rf "$audit_dir"
240309
}
241310
trap cleanup EXIT
242-
python -m pip install --disable-pip-version-check --no-cache-dir pip-audit
311+
python -m pip install --disable-pip-version-check --no-cache-dir pip-audit==2.10.1
243312
docker create --name "$container" engraphis:ci >/dev/null
244313
docker cp "$container":/usr/local/lib/python3.11/site-packages/. "$audit_dir"
245314
python -m pip_audit --path "$audit_dir"
@@ -277,9 +346,13 @@ jobs:
277346
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
278347
with:
279348
python-version: "3.11"
349+
- name: Install pinned build and audit tooling
350+
run: >-
351+
python -m pip install --disable-pip-version-check
352+
"build==1.5.0" "pip-audit==2.10.1"
280353
- name: Build sdist + wheel and verify a clean install
281354
run: |
282-
python -m pip install --upgrade pip build pip-audit
355+
export SOURCE_DATE_EPOCH="$(git show -s --format=%ct "$GITHUB_SHA")"
283356
python -m build
284357
python scripts/verify_distribution_contents.py dist/*
285358
python -m venv .audit-venv

.github/workflows/codeql.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ jobs:
3232
with:
3333
languages: ${{ matrix.language }}
3434
build-mode: none
35+
config-file: ./.github/codeql/codeql-config.yml
3536
- name: Analyze
3637
id: analyze
3738
uses: github/codeql-action/analyze@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4

0 commit comments

Comments
 (0)