Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"name": "engraphis-memory",
"source": "./",
"description": "Discipline for giving agents durable, scoped, explainable memory across sessions and repos with the Engraphis MCP tools.",
"version": "1.1.0"
"version": "1.1.2"
}
]
}
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "engraphis-memory",
"version": "1.1.0",
"version": "1.1.2",
"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.",
"author": {
"name": "The Engraphis Authors",
Expand Down
4 changes: 2 additions & 2 deletions .claude-plugin/skill-assets.sha256
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
f02c452829de41bae8ab81a6e74a3a9f89895c51dc9ba01cd3947c4baf0622e2 .claude-plugin/marketplace.json
a17b520f3c1f3002aeba29d9312f9091d5a281035996c2e9c90b0397f4fb9fb9 .claude-plugin/plugin.json
bb2b52154d945062415a318f1a2d5a7c754bc96e3a9c43535b88973e14f53499 .claude-plugin/marketplace.json
d19925a19a350264ecf464ab0bbe99398a5f1499631784cd586a76efef59ef39 .claude-plugin/plugin.json
89bf2728e44a3c877e31982d387fcfab10fbe065eb6441b2792375ca5105c07c skills/engraphis-memory/SKILL.md
a295b0448e2ff372ddd8ea4e0bc8dc53f3d4bd56ff1fbd0d88cf4b6179511ce1 skills/engraphis-memory/references/CONVENTIONS.md
45f4b4ad9dbfd39f2b377083d9b3eec5eed7cba7cb8fa139e3f420bdd6105343 skills/engraphis-memory/references/SCOPING.md
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ jobs:
python scripts/check_commercial_manifest.py
python scripts/externalize_dashboard_assets.py
- name: Unit tests (full suite — extras-gated tests included)
run: python -m pytest tests/ -q
run: |
python -c "import fastapi, httpx, mcp, multipart, pydantic, uvicorn"
python -m pytest -o addopts="" tests/ -q -rs
- name: Retrieval eval gate
run: python -m eval.harness --dataset eval/datasets/sample.jsonl --k 5
- name: Retrieval eval gate — CodeMem (coding-agent wedge, incl. conflict resolution)
Expand All @@ -53,7 +55,7 @@ jobs:
python -m pip install --upgrade pip
pip install numpy pytest
- name: Unit tests (extras-gated tests skip; the core must pass)
run: python -m pytest tests/ -q
run: python -m pytest -o addopts="" tests/ -q -rs
- name: Retrieval eval gate
run: python -m eval.harness --dataset eval/datasets/sample.jsonl --k 5
- name: Ablation
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ jobs:
python scripts/check_commercial_manifest.py
python scripts/externalize_dashboard_assets.py
ruff check .
python -m pytest tests/ -q
python -c "import fastapi, httpx, mcp, multipart, pydantic, uvicorn"
python -m pytest -o addopts="" tests/ -q -rs
python -m eval.harness --dataset eval/datasets/sample.jsonl --k 5
python -m eval.harness --dataset eval/datasets/codemem.jsonl --k 5
python -m eval.ablation
Expand Down Expand Up @@ -104,7 +105,10 @@ jobs:
- name: Unit, lint, and retrieval gates
run: |
ruff check .
python -m pytest tests/ -q
if [ "${{ matrix.python-version }}" != "3.9" ]; then
python -c "import fastapi, httpx, mcp, multipart, pydantic, uvicorn"
fi
python -m pytest -o addopts="" tests/ -q -rs
python -m eval.harness --dataset eval/datasets/sample.jsonl --k 5
python -m eval.harness --dataset eval/datasets/codemem.jsonl --k 5
python -m eval.ablation
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ models_cache/
.secrets/
internal/

# Local review/snapshot staging. These archives can recursively capture ignored runtime
# state (including engraphis.db), so they must never enter a source or release archive.
/_to_delete/

# Local internal design-review tooling output (candid self-assessment, not for the repo).
.commandcode/

Expand Down
55 changes: 54 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,60 @@
All notable changes to Engraphis are documented here. Format loosely follows
[Keep a Changelog](https://keepachangelog.com/); versions use SemVer.

## [Unreleased]
## [1.1.2] - 2026-07-27

### Added

- **The complete Ledger design is now the primary local WebUI**, ported from the final
five-area design package without its sample store or unsafe design runtime. Today, grounded
Ask, Library, the advanced Graph & Relations view, Provenance, and Manage all use live v2 data.
Manage includes workspaces, reviewed local consolidation, hosted Analytics/Automation/Team
status, the full plan comparison, settings, and persisted Slate, Midnight, Paper, and Matrix
themes.
- Ledger now exposes the production grounded-answer route (`POST /api/answer`), returning a
cited answer or an explicit abstention. Graph & Relations ships the supplied graph capabilities:
five layouts, four render styles, palettes, degree/betweenness sizing, bridge detection,
valid-time filtering, superseded ghosts, focus, and automatic cluster collapse.
- The complete former dashboard remains available at `/classic`. Both interfaces expose a
visible dashboard selector and share the same workspaces, memories, receipts, and engine.

### Changed

- Ledger defers both the CSP-sensitive renderer and graph payload until Graph & Relations is opened,
ignores stale workspace responses, renders memory text through DOM text nodes, and provides
responsive, reduced-motion-aware keyboard focus styling. Classic loads its lazy graph vendor
dependency from its own packaged backup tree.
- Graph nodes now use oversampled, cached screen-space material rendering with face-level
texture: full-face iridescent PVD for Cyber, directional blue-violet anodizing for Galaxy,
concentric brushed copper for Solar, and horizontal satin gunmetal grain for Classic, with
deterministic low-detail fallbacks for large graphs.
- Dashboard asset URLs now carry the node-material revision and local static responses
revalidate, preventing an already-open browser from pinning the pre-material renderer.
- Pro and Team purchase actions now preserve both the selected plan and billing interval, while
existing or lapsed subscribers are sent to the plan-neutral account portal for billing recovery.
Public documentation now distinguishes hosted-account grace and recovery behavior from the
always-local, Apache-licensed dashboard and MCP write paths.

### Fixed

- Token-protected dashboards can now establish a short-lived signed, HttpOnly browser session
without storing the API token in browser storage. Remote peers remain denied when no token is
configured, and non-loopback v1 server startup is refused unless authentication is enabled.
- Hosted entitlement refreshes use bounded exponential backoff, terminal denials settle every
local entitlement view, inactive sessions expose no paid feature flags, and ambiguous
single-use refresh responses permanently retire the possibly spent credential instead of
replaying it.
- Recommended Automation bootstrap is resumable across partial upload/policy-save failures and
authorizes paid work before generating or locking a local snapshot.
- Release checks now enforce commercial prices and trial terms, expose skipped tests instead of
hiding them behind duplicate quiet flags, and verify the full-stack dependency imports used by
the HTTP authorization boundary.

### Security

- Credential state directories are owner-only, product token forms are redacted consistently
from logs, checkout overrides fail closed to validated HTTPS or loopback HTTP destinations, and
unsafe control characters can no longer reform blocked browser URL schemes.

## [1.1.0] - 2026-07-26

Expand Down
80 changes: 80 additions & 0 deletions COMMERCIAL_AUDIT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Engraphis 1.1.2 commercial release audit

Date: 2026-07-27

Scope: every local unmerged file, with four parallel review lanes covering licensing,
entitlements and Team authorization, payments and checkout routing, and end-to-end
dashboard/release integration.

## Outcome

The local 1.1.2 candidate has no known release-blocking defect in the public repository.
Local Free behavior remains Apache-licensed and offline-capable. Pro and Team operations
remain private hosted capabilities whose access is granted only by short-lived,
control-plane-scoped credentials; a client-side plan label cannot grant them.

The audit initially found release blockers in remote-server authentication, browser
authentication, entitlement recovery, single-use credential handling, checkout selection,
automation bootstrap, and release enforcement. Those issues are fixed and regression-tested.

## Corrected findings

| Area | Problem | Final behavior |
|---|---|---|
| Remote authentication | The v1 REST app could serve non-loopback peers without an API token. | Remote peers are denied without a token, and non-loopback v1 startup refuses to proceed without authentication. |
| Browser authentication | A configured bearer token made normal dashboard navigation unusable without encouraging unsafe browser storage. | A one-time token exchange establishes a 12-hour signed HttpOnly session cookie; privileged browser requests also require a dedicated session header. The token is never stored by the page. |
| Commercial invariants | Prices and trial terms were not enforced by the always-run repository check. | Free/Pro/Team price types, monthly and annual relationships, trial duration, card policy, and eligible plans are release invariants. |
| Checkout routing | Purchase links did not reliably preserve plan and interval; billing recovery could send a Team customer to Pro checkout. | Pro/Team monthly/annual actions use four exact validated targets. Active and lapsed subscribers use the plan-neutral account portal. |
| Entitlement settlement | Some 401/402/403 outcomes left stale saved or compatibility entitlement state. | Terminal denials settle every local entitlement view; inactive state exposes no paid features. |
| Refresh pressure | Failed entitlement refreshes could retry at dashboard read rate. | Refresh uses bounded exponential backoff from 30 seconds to 15 minutes. |
| Single-use credentials | An ambiguous or truncated refresh response could cause a possibly spent credential to be replayed. | The credential is durably retired and the customer must reconnect; a successful rotation clears the marker. |
| Credential replacement | A durable "spent" marker could also suppress a newly supplied environment bootstrap credential. | The tombstone is keyed to a digest of the exact credential, so a replacement can bootstrap while the spent value stays blocked; no raw credential is persisted. |
| Paid side effects | A denied managed job could generate and lock a snapshot before authorization. | Authorization completes before any snapshot generation, database lock, or generation receipt. |
| Automation bootstrap | Upload success followed by policy-save failure repeated expensive work on the next GET; concurrent first views could duplicate the upload. | Durable phases resume at the failed step, and a per-organization/workspace bootstrap lock serializes same-process first views so only one snapshot is uploaded and followers receive the saved policy version. |
| Capability mapping | Unknown and Team-only capability handling was incomplete. | Every sold capability has an explicit minimum plan; Team UI state follows authoritative entitlement data. |
| Licensing boundary | Hosted-account grace language could be read as gating local MCP/dashboard writes. | Public docs and the manifest explicitly scope grace/recovery restrictions to private hosted-account growth and hosted writes. |
| Credential hygiene | State directories and log redaction had defense-in-depth gaps. | Credential directories are owner-only where POSIX semantics apply, and refresh/token forms are redacted consistently. |
| Dashboard safety | URL control characters, hidden-state CSS, theme contrast, heading order, and duplicate classic handlers had correctness/accessibility gaps. | URL handling fails closed; Ledger and Classic pass their browser, accessibility, theme, mobile, CSP, and commercial-flow assertions. |
| Receipt export | A normal link navigation to the protected receipt export endpoint omitted the browser-session header. | Ledger fetches the filtered export with the authenticated API helper and downloads the returned JSON blob; it never falls back to an unauthenticated navigation. |
| Container API profile | The documented non-loopback Compose API profile could start without an API token even though the server rejects that configuration. | Compose requires `ENGRAPHIS_API_TOKEN` before interpolation and the README documents the required launch command. |
| Release identity | The dirty candidate still declared immutable, already-published version 1.1.0. | The candidate is version 1.1.2 across Python and plugin metadata, with updated plugin asset hashes and changelog. PyPI currently has no 1.1.2 artifacts. |

## Plan and payment contract checked

- Free: local dashboard, MCP tools, local memory operations, and data portability remain
available without a hosted entitlement.
- Pro: one owner account; purchase actions preserve monthly or annual cadence.
- Team: per named seat; Team-only capabilities require authoritative Team entitlement.
- Hosted denials and billing recovery use the account portal. Purchase and upgrade actions use
exact checkout targets. Operator URL overrides accept only absolute HTTPS or loopback HTTP.
- Stripe price IDs and payment credentials are intentionally absent from this public client.
Live charging, refunds, tax, invoices, and webhook fulfillment are private-service concerns.

## Verification evidence

- Python: **1,761 passed, 12 skipped** in the explicit full suite. Every skip is reported and
accounted for: optional encryption/sqlite-vec extras or platform permission/symlink semantics.
- Commercial, entitlement, licensing, payment-routing, and release-infrastructure subset:
**467 passed, 1 expected platform skip**. The final cloud-session/dashboard authorization
regression subset adds **120 passed**.
- Browser E2E: **26 passed**, covering Ledger, Classic, commercial actions, accessibility,
themes, responsive layouts, and CSP behavior.
- Retrieval: sample and CodeMem recall@5, hit@5, and answer-token recall are all **1.000**.
PPR multi-hop arm recall@5 is **1.000** versus **0.000** for the expected one-hop ablation.
- Static gates: Ruff, commercial manifest validation, dashboard externalization/CSP validation,
JavaScript syntax checks, and `git diff --check` pass.
- Packaging: a fresh 1.1.2 wheel and sdist build successfully from this tree and pass Twine,
release-artifact validation, and an entry-by-entry wheel-to-source digest comparison. They
include Ledger, Classic, vendor notices, LICENSE, and NOTICE; neither contains databases,
`_to_delete`, bytecode, or cache directories.
- Immutable publication guard: 1.1.0 correctly conflicts because it is already published;
1.1.2 verifies as an unpublished candidate with zero existing artifacts.

## External release gates

No live purchase was attempted: that would spend money and requires the private payment stack
and explicit approval. The Docker daemon is not running in this workstation, though the Compose
API profile was validated client-side with a token and verified to reject an unset token.
`pip-audit` is not installed locally; both it and a daemon-backed container run remain encoded
in the CI/release workflows. These are environmental verification limits, not unresolved defects
in the reviewed tree.
5 changes: 4 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ global-exclude *.pyo

recursive-include engraphis/static *.html *.css *.js *.png *.ico
recursive-include engraphis/static/vendor *
recursive-include engraphis/dashboard_assets *.js
recursive-include engraphis/classic_assets *.html *.css *.js *.png *.ico
recursive-include engraphis/classic_assets/vendor *
recursive-include engraphis/dashboard_assets *.html *.css *.js *.png *.ico
recursive-include engraphis/dashboard_assets/vendor *
include engraphis/commercial_manifest.json
include LICENSE NOTICE README.md CHANGELOG.md
include pyproject.toml
Expand Down
Loading
Loading