memware 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. memware-0.1.1/.claude-plugin/marketplace.json +19 -0
  2. memware-0.1.1/.github/CODEOWNERS +1 -0
  3. memware-0.1.1/.github/ISSUE_TEMPLATE/bug_report.yml +21 -0
  4. memware-0.1.1/.github/ISSUE_TEMPLATE/config.yml +5 -0
  5. memware-0.1.1/.github/ISSUE_TEMPLATE/feature_request.yml +17 -0
  6. memware-0.1.1/.github/PULL_REQUEST_TEMPLATE.md +14 -0
  7. memware-0.1.1/.github/dependabot.yml +8 -0
  8. memware-0.1.1/.github/workflows/ci.yml +29 -0
  9. memware-0.1.1/.github/workflows/release.yml +74 -0
  10. memware-0.1.1/.gitignore +15 -0
  11. memware-0.1.1/.pre-commit-config.yaml +13 -0
  12. memware-0.1.1/CHANGELOG.md +53 -0
  13. memware-0.1.1/CODE_OF_CONDUCT.md +47 -0
  14. memware-0.1.1/CONTRIBUTING.md +45 -0
  15. memware-0.1.1/LICENSE +21 -0
  16. memware-0.1.1/PKG-INFO +163 -0
  17. memware-0.1.1/README.md +132 -0
  18. memware-0.1.1/RELEASING.md +136 -0
  19. memware-0.1.1/SECURITY.md +19 -0
  20. memware-0.1.1/docs/design.md +104 -0
  21. memware-0.1.1/docs/eval.md +111 -0
  22. memware-0.1.1/docs/integrations.md +62 -0
  23. memware-0.1.1/docs/upstream-hermes-pr.md +141 -0
  24. memware-0.1.1/eval/questions.example.jsonl +3 -0
  25. memware-0.1.1/integrations/claude-code/.claude-plugin/plugin.json +8 -0
  26. memware-0.1.1/integrations/claude-code/README.md +8 -0
  27. memware-0.1.1/integrations/claude-code/hooks/hooks.json +13 -0
  28. memware-0.1.1/integrations/hermes/README.md +23 -0
  29. memware-0.1.1/integrations/hermes/memware/__init__.py +376 -0
  30. memware-0.1.1/integrations/hermes/memware/plugin.yaml +12 -0
  31. memware-0.1.1/integrations/hermes/upstream/README.md +93 -0
  32. memware-0.1.1/integrations/hermes/upstream/plugins/memory/memware/README.md +69 -0
  33. memware-0.1.1/integrations/hermes/upstream/plugins/memory/memware/__init__.py +509 -0
  34. memware-0.1.1/integrations/hermes/upstream/plugins/memory/memware/config_schema.py +46 -0
  35. memware-0.1.1/integrations/hermes/upstream/plugins/memory/memware/plugin.yaml +14 -0
  36. memware-0.1.1/integrations/hermes/upstream/tests/plugins/memory/test_memware_provider.py +403 -0
  37. memware-0.1.1/integrations/hermes/upstream/website/docs/user-guide/features/memory-providers.memware.md +65 -0
  38. memware-0.1.1/pyproject.toml +72 -0
  39. memware-0.1.1/scripts/leak-check.sh +14 -0
  40. memware-0.1.1/src/memware/__init__.py +25 -0
  41. memware-0.1.1/src/memware/cli.py +311 -0
  42. memware-0.1.1/src/memware/eval.py +208 -0
  43. memware-0.1.1/src/memware/index.py +380 -0
  44. memware-0.1.1/src/memware/ingest/__init__.py +223 -0
  45. memware-0.1.1/src/memware/ingest/claude_code.py +58 -0
  46. memware-0.1.1/src/memware/ingest/generic.py +51 -0
  47. memware-0.1.1/src/memware/ledger.py +347 -0
  48. memware-0.1.1/src/memware/mcp_server.py +96 -0
  49. memware-0.1.1/src/memware/passage.py +87 -0
  50. memware-0.1.1/src/memware/py.typed +0 -0
  51. memware-0.1.1/src/memware/review.py +175 -0
  52. memware-0.1.1/src/memware/store.py +209 -0
  53. memware-0.1.1/tests/__init__.py +0 -0
  54. memware-0.1.1/tests/conftest.py +59 -0
  55. memware-0.1.1/tests/test_cli.py +34 -0
  56. memware-0.1.1/tests/test_eval.py +102 -0
  57. memware-0.1.1/tests/test_hermes_plugin.py +88 -0
  58. memware-0.1.1/tests/test_hermes_upstream_plugin.py +192 -0
  59. memware-0.1.1/tests/test_index.py +193 -0
  60. memware-0.1.1/tests/test_ingest.py +184 -0
  61. memware-0.1.1/tests/test_ledger.py +110 -0
  62. memware-0.1.1/tests/test_passage.py +136 -0
  63. memware-0.1.1/tests/test_review.py +19 -0
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "memware",
3
+ "owner": {
4
+ "name": "ericwalisko",
5
+ "url": "https://github.com/ericwalisko"
6
+ },
7
+ "description": "Memory for AI agents that only remembers the latest truth.",
8
+ "plugins": [
9
+ {
10
+ "name": "memware",
11
+ "source": "./integrations/claude-code",
12
+ "description": "Session transcripts indexed for recall; a belief ledger that only remembers the latest truth. Hooks: SessionEnd/PreCompact sync, prompt-time belief context.",
13
+ "version": "0.1.1",
14
+ "author": {
15
+ "name": "ericwalisko"
16
+ }
17
+ }
18
+ ]
19
+ }
@@ -0,0 +1 @@
1
+ * @ericwalisko
@@ -0,0 +1,21 @@
1
+ name: Bug report
2
+ description: Something behaves differently from what the docs say
3
+ labels: [bug]
4
+ body:
5
+ - type: input
6
+ id: version
7
+ attributes: { label: memware version, placeholder: "memware --version" }
8
+ validations: { required: true }
9
+ - type: input
10
+ id: env
11
+ attributes: { label: Python and OS, placeholder: "3.12, macOS 15" }
12
+ - type: textarea
13
+ id: repro
14
+ attributes:
15
+ label: Minimal reproduction
16
+ description: Commands or a short script using synthetic data. Never paste real transcripts.
17
+ validations: { required: true }
18
+ - type: textarea
19
+ id: expected
20
+ attributes: { label: Expected vs actual }
21
+ validations: { required: true }
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: true
2
+ contact_links:
3
+ - name: Security issue
4
+ url: https://github.com/ericwalisko/memware/security/advisories/new
5
+ about: Report privately via GitHub security advisories.
@@ -0,0 +1,17 @@
1
+ name: Feature request
2
+ description: Propose a change
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes: { label: The problem this solves }
8
+ validations: { required: true }
9
+ - type: textarea
10
+ id: proposal
11
+ attributes: { label: Proposal }
12
+ - type: dropdown
13
+ id: readpath
14
+ attributes:
15
+ label: Does this add a model call to capture or recall?
16
+ options: ["No", "Yes, as an optional extra", "Yes, in the default path"]
17
+ validations: { required: true }
@@ -0,0 +1,14 @@
1
+ ## What
2
+
3
+ <!-- one or two sentences -->
4
+
5
+ ## Why
6
+
7
+ <!-- the problem, with a link to the issue if there is one -->
8
+
9
+ ## Checklist
10
+
11
+ - [ ] Tests added or updated (synthetic fixtures only)
12
+ - [ ] `ruff check`, `ruff format --check`, `mypy`, `pytest` pass locally
13
+ - [ ] Ledger semantics unchanged, or `docs/design.md` updated in this PR
14
+ - [ ] Commits are signed off (`git commit -s`)
@@ -0,0 +1,8 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule: { interval: "monthly" }
6
+ - package-ecosystem: "pip"
7
+ directory: "/"
8
+ schedule: { interval: "monthly" }
@@ -0,0 +1,29 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ${{ matrix.os }}
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ os: [ubuntu-latest, macos-latest]
18
+ python-version: ["3.11", "3.12", "3.13"]
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+ - run: python -m pip install --upgrade pip && pip install -e ".[dev,mcp]"
25
+ - run: ruff check src tests integrations
26
+ - run: ruff format --check src tests integrations
27
+ - run: mypy
28
+ - run: pytest --cov=memware --cov-report=term-missing
29
+ - run: python -m pip install build && python -m build
@@ -0,0 +1,74 @@
1
+ name: Release
2
+
3
+ # Publishing is authorized by a PyPI *trusted publisher* (OIDC): no API token is
4
+ # stored anywhere. The binding on pypi.org names this repository, this workflow
5
+ # file, and the `pypi` environment below — change any of the three and the
6
+ # upload stops working. See RELEASING.md.
7
+
8
+ on:
9
+ push:
10
+ tags: ["v*"]
11
+ workflow_dispatch:
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ build:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.12"
24
+
25
+ - name: Build sdist and wheel
26
+ run: |
27
+ python -m pip install --upgrade pip build twine
28
+ python -m build
29
+ twine check --strict dist/*
30
+
31
+ - name: Install the wheel into a clean venv
32
+ # Core memware has no runtime dependencies, so this must resolve with the
33
+ # index switched off — anything else means a dependency leaked in.
34
+ run: |
35
+ python -m venv /tmp/verify
36
+ /tmp/verify/bin/pip install --no-index --find-links dist memware
37
+
38
+ - name: The console script reports the built version
39
+ run: |
40
+ version="$(/tmp/verify/bin/memware --version)"
41
+ echo "built version: ${version}"
42
+ if [ "${GITHUB_REF_TYPE}" = "tag" ] && [ "${GITHUB_REF_NAME#v}" != "${version}" ]; then
43
+ echo "::error::tag ${GITHUB_REF_NAME} does not match package version ${version}"
44
+ exit 1
45
+ fi
46
+
47
+ - name: The test suite passes against the installed wheel
48
+ # Imports resolve to site-packages, not src/ — this is what catches a
49
+ # subpackage or data file that never made it into the distribution.
50
+ run: |
51
+ /tmp/verify/bin/pip install pytest
52
+ /tmp/verify/bin/python -m pytest tests -q
53
+
54
+ - uses: actions/upload-artifact@v4
55
+ with:
56
+ name: dist
57
+ path: dist/
58
+
59
+ publish:
60
+ needs: build
61
+ # A manual run on a branch builds and verifies but never publishes.
62
+ if: github.ref_type == 'tag'
63
+ runs-on: ubuntu-latest
64
+ environment:
65
+ name: pypi
66
+ url: https://pypi.org/p/memware
67
+ permissions:
68
+ id-token: write
69
+ steps:
70
+ - uses: actions/download-artifact@v4
71
+ with:
72
+ name: dist
73
+ path: dist/
74
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,15 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ dist/
5
+ build/
6
+ *.egg-info/
7
+ .pytest_cache/
8
+ .mypy_cache/
9
+ .ruff_cache/
10
+ .coverage
11
+ htmlcov/
12
+ *.db
13
+ *.db-wal
14
+ *.db-shm
15
+ .memware/
@@ -0,0 +1,13 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.16.5
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+ - repo: https://github.com/pre-commit/pre-commit-hooks
9
+ rev: v5.0.0
10
+ hooks:
11
+ - id: end-of-file-fixer
12
+ - id: trailing-whitespace
13
+ - id: check-added-large-files
@@ -0,0 +1,53 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses
5
+ [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [Unreleased]
8
+
9
+ ### Added
10
+ - **Passage-level index.** Turns are split into ~300-500-token passages at ingest
11
+ (`memware.passage`), anchored by turn id and character offset, and FTS5 now indexes
12
+ passages instead of whole turns. Recall ranks passages, collapses to one hit per turn
13
+ and quotes only that turn's best matching passages (`passages_per_turn`, default 3);
14
+ `read_session` still returns whole turns. On a 24-question fact set this held accuracy
15
+ exactly (fact 24/24, stale 8/8, stale_rate 0) while halving the retrieved context,
16
+ 30,403 -> 15,410 characters. The database is ~1.8x larger, since a passage stores its
17
+ own text.
18
+ - Existing stores migrate on first open (`PRAGMA user_version` 0 -> 1): `turn_fts` is
19
+ dropped and every turn on disk is chunked, ~5 s for an 18k-turn corpus.
20
+ - `memware-eval` reports the median retrieved context size per question.
21
+
22
+ ## [0.1.1] - 2026-09-03
23
+
24
+ ### Added
25
+ - Multi-query recall: `memware recall Q1 Q2 …`, MCP `recall(queries=[…])`, Hermes `memware_recall(queries)` — phrasings fused by reciprocal rank so the calling agent supplies synonyms and expected values at call time.
26
+ - Persistent skip list: `~/.memware/ignore-markers.txt` and `MEMWARE_IGNORE_MARKERS` — content markers every sync honours, so transcripts predating a marker or the no-capture flag are filtered by signature.
27
+ - Evaluation guardrails: `MEMWARE_NO_CAPTURE=1` (hooks/provider/`sync --from-hook` no-op), `sync --skip-if-contains TEXT` / `--exclude GLOB`, `memware prune`, `memware-eval --corpus/--beliefs-from` clean-store builds, `memware.eval.MARKER`.
28
+ - Hermes memory-provider plugin implementing the `MemoryProvider` ABC (prefetch, non-blocking sync_turn, session flush, built-in memory mirroring, four recall/remember tools); the repo is a Claude Code plugin marketplace (`claude plugin marketplace add ericwalisko/memware`).
29
+ - `integrations/hermes/upstream/`: the Hermes provider packaged as hermes-agent's own `plugins/memory/<name>/` tree — lazy-installed dependency, profile-scoped store, `backup_paths()`, declarative desktop config schema — with tests in their layout, a docs entry draft, and a draft PR description in `docs/upstream-hermes-pr.md`. Prepared, not submitted.
30
+ - Turn hits carry `snippet`: the FTS5 window around the matched terms (the head of a long turn often lacks the answer). Default window 96 tokens; `memware recall --snippet-tokens N`.
31
+ - Release workflow that publishes to PyPI from a `v*` tag via trusted publishing
32
+ (OIDC, no stored token). It installs the built wheel into a clean venv and refuses
33
+ to upload when the tag and the package version disagree; `RELEASING.md` documents
34
+ the one-time pypi.org setup and the per-release steps.
35
+
36
+ ### Changed
37
+ - Stale scoring is positional: an answer is stale only when the old value appears before the current one.
38
+ - `memware-eval` mirrors the hook's subject gate for the beliefs context and reports the belief injection rate (overall and on negatives).
39
+ - `memware-eval` now scores two contexts per question: `beliefs` (what a prompt-time hook injects) and `beliefs+turns`; negatives pass when the expected value is absent rather than when the context is empty.
40
+ - The package version is read from `memware.__version__` by the build backend, so
41
+ `memware --version` and the published distribution cannot disagree.
42
+
43
+ ## [0.1.0] - 2026-09-02
44
+
45
+ ### Added
46
+ - Bi-temporal belief ledger with deterministic `(subject, relation)` supersession,
47
+ event-time ordering, reinforcement, and reliability-gated review.
48
+ - FTS5 transcript index with BM25 × activation ranking.
49
+ - Ingest adapters for Claude Code session JSONL and generic message JSONL, with
50
+ idempotent byte-offset cursors.
51
+ - `memware` CLI, optional MCP server, and retrieval-level evaluation runner.
52
+ - `ReviewBackend` contract with JSONL and HTTP implementations.
53
+ - Claude Code hook bundle and Hermes memory-provider skeleton.
@@ -0,0 +1,47 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a
6
+ harassment-free experience for everyone, regardless of age, body size, visible or invisible
7
+ disability, ethnicity, sex characteristics, gender identity and expression, level of
8
+ experience, education, socio-economic status, nationality, personal appearance, race,
9
+ caste, color, religion, or sexual identity and orientation.
10
+
11
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse,
12
+ inclusive, and healthy community.
13
+
14
+ ## Our Standards
15
+
16
+ Examples of behavior that contributes to a positive environment include demonstrating
17
+ empathy and kindness, being respectful of differing opinions, giving and gracefully
18
+ accepting constructive feedback, accepting responsibility and apologizing to those
19
+ affected by our mistakes, and focusing on what is best for the overall community.
20
+
21
+ Examples of unacceptable behavior include sexualized language or imagery, trolling,
22
+ insulting or derogatory comments, personal or political attacks, public or private
23
+ harassment, publishing others' private information without explicit permission, and other
24
+ conduct which could reasonably be considered inappropriate in a professional setting.
25
+
26
+ ## Enforcement Responsibilities
27
+
28
+ Community leaders are responsible for clarifying and enforcing our standards and will take
29
+ appropriate and fair corrective action in response to any behavior they deem inappropriate,
30
+ threatening, offensive, or harmful.
31
+
32
+ ## Scope
33
+
34
+ This Code of Conduct applies within all community spaces, and also applies when an
35
+ individual is officially representing the community in public spaces.
36
+
37
+ ## Enforcement
38
+
39
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the
40
+ maintainers through GitHub's private vulnerability reporting for this repository or by
41
+ opening an issue marked confidential. All complaints will be reviewed and investigated
42
+ promptly and fairly.
43
+
44
+ ## Attribution
45
+
46
+ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
47
+ version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
@@ -0,0 +1,45 @@
1
+ # Contributing
2
+
3
+ Thanks for considering a contribution. Small, focused pull requests are easiest to review.
4
+
5
+ ## Development
6
+
7
+ ```bash
8
+ git clone https://github.com/ericwalisko/memware && cd memware
9
+ uv venv && uv pip install -e ".[dev,mcp]" # or: python -m venv .venv && pip install -e ".[dev,mcp]"
10
+ ruff check src tests && ruff format --check src tests
11
+ mypy
12
+ pytest
13
+ ```
14
+
15
+ CI runs the same commands on Python 3.11, 3.12 and 3.13.
16
+
17
+ ## Ground rules
18
+
19
+ - **Tests first.** Every behaviour change comes with a test that fails without it.
20
+ Fixtures are synthetic — never commit real transcripts or memories.
21
+ - **The ledger semantics are a contract.** Changes to supersession ordering, policies,
22
+ or what `recall` may return need a design note in `docs/design.md` in the same PR.
23
+ - **No model in the read path.** Proposals that add an LLM call to capture or recall
24
+ should be framed as optional, off-by-default extras.
25
+ - Keep the core dependency-free. New runtime dependencies go behind an extra.
26
+
27
+ ## Releasing
28
+
29
+ Maintainers only: [RELEASING.md](RELEASING.md) covers the one-time PyPI trusted-publisher
30
+ setup and the per-release steps. Releases are cut from a `v*` tag; nothing is published
31
+ by hand.
32
+
33
+ ## Sign-off (DCO)
34
+
35
+ This project uses the [Developer Certificate of Origin](https://developercertificate.org/).
36
+ Sign each commit with `git commit -s`, which adds `Signed-off-by: Your Name <email>`.
37
+ No CLA.
38
+
39
+ ## Reporting bugs and proposing features
40
+
41
+ Use the issue templates. For security issues, see [SECURITY.md](SECURITY.md).
42
+
43
+ ## Code of conduct
44
+
45
+ Participation is governed by the [Code of Conduct](CODE_OF_CONDUCT.md).
memware-0.1.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Eric Walisko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
memware-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,163 @@
1
+ Metadata-Version: 2.5
2
+ Name: memware
3
+ Version: 0.1.1
4
+ Summary: Memory for AI agents that only remembers the latest truth: a bi-temporal belief ledger plus a transcript index, in one SQLite file.
5
+ Project-URL: Homepage, https://github.com/ericwalisko/memware
6
+ Project-URL: Issues, https://github.com/ericwalisko/memware/issues
7
+ Project-URL: Changelog, https://github.com/ericwalisko/memware/blob/main/CHANGELOG.md
8
+ Author: ericwalisko
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: agent-memory,bitemporal,claude-code,fts5,hermes,llm,mcp,sqlite
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development :: Libraries
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.11
22
+ Provides-Extra: dev
23
+ Requires-Dist: mypy>=1.11; extra == 'dev'
24
+ Requires-Dist: pytest-cov>=5; extra == 'dev'
25
+ Requires-Dist: pytest>=8; extra == 'dev'
26
+ Requires-Dist: pyyaml>=6; extra == 'dev'
27
+ Requires-Dist: ruff==0.16.5; extra == 'dev'
28
+ Provides-Extra: mcp
29
+ Requires-Dist: mcp>=1.2; extra == 'mcp'
30
+ Description-Content-Type: text/markdown
31
+
32
+ # memware
33
+
34
+ **Memory for AI agents that only remembers the latest truth.**
35
+
36
+ memware is one SQLite file with two stores:
37
+
38
+ - **turns** — immutable evidence. Every prompt and answer from past sessions,
39
+ split into ~400-token passages and indexed with FTS5. Recall ranks passages and
40
+ quotes only the matching ones; reading a session back returns whole turns.
41
+ BM25 × recency × use, no model in the loop.
42
+ - **beliefs** — a bi-temporal ledger of facts. A new value for the same
43
+ `(subject, relation)` **supersedes** the old one. Recall only ever returns the
44
+ currently valid belief; history is kept for audit and never reaches a prompt.
45
+
46
+ No daemon, no vector database, no LLM call at capture or read time. A 30-day
47
+ corpus of a busy coding agent — 18k turns, 40k passages — indexes in about
48
+ fourteen seconds into ~120 MB.
49
+
50
+ ```text
51
+ $ memware sync ~/.claude/projects --harness claude-code
52
+ {"added": 14348, "files": 1475}
53
+
54
+ $ memware assert "api" "listens on port" "8443" --source "session 3f2a, turn 41"
55
+ {"outcome": "superseded", "belief_id": 2, "incumbent_id": 1}
56
+
57
+ $ memware recall "which port does the api use" --what beliefs
58
+ api listens on port 8443 # 8080 is in the ledger, retired, and never surfaces
59
+ ```
60
+
61
+ ## Why
62
+
63
+ Agent memory systems that rewrite what they remember degrade: continuous
64
+ LLM consolidation can push utility *below* having no memory at all
65
+ ([Useful Memories Become Faulty When Continuously Updated by LLMs](https://arxiv.org/abs/2605.12978)).
66
+ And embeddings cannot tell a *contradicted* fact from a *rephrased* one — AUROC 0.59 —
67
+ so vector stores serve stale facts 15–40% of the time on evolving knowledge
68
+ ([Temporal Validity in Retrieval Memory](https://arxiv.org/abs/2606.26511)).
69
+
70
+ memware borrows four mechanisms from human memory research and keeps them deliberately small:
71
+
72
+ | mechanism | in the brain | in memware |
73
+ |---|---|---|
74
+ | evidence ≠ belief | hippocampus vs neocortex (complementary learning systems) | `turn` table is append-only; `belief` table is separate |
75
+ | update on surprise | reconsolidation driven by prediction error | `memware assert` at the moment an agent notices a conflict |
76
+ | only the latest understanding | reconsolidated traces overwrite in place | deterministic supersession keyed on `(subject, relation)`, ordered by **event time** |
77
+ | need-probability recall | Anderson & Schooler 1991 / ACT-R activation | `bm25 × (1+age)^-d × (1 + w·ln(1+uses))` |
78
+
79
+ Full rationale and citations: [docs/design.md](docs/design.md).
80
+
81
+ ## Install
82
+
83
+ ```bash
84
+ pip install memware # core, stdlib only (SQLite with FTS5)
85
+ pip install "memware[mcp]" # + MCP server
86
+ ```
87
+
88
+ ## Use it from Claude Code
89
+
90
+ `integrations/claude-code/` is a Claude Code plugin (`claude plugin marketplace add
91
+ ericwalisko/memware`, then `claude plugin install memware@memware`). Hooks: `SessionEnd`/`PreCompact` sync the
92
+ transcript into the index; an optional `UserPromptSubmit` hook injects the handful of
93
+ currently valid beliefs relevant to the prompt (beliefs only — transcript search is
94
+ on demand through the MCP tools). See [docs/integrations.md](docs/integrations.md).
95
+
96
+ ## Use it from Hermes Agent
97
+
98
+ `integrations/hermes/memware/` is a memory-provider plugin built on Hermes's
99
+ `MemoryProvider` ABC — prompt-time belief prefetch, non-blocking turn capture, and
100
+ `memware_recall` / `memware_remember` tools — sharing one store with Claude Code.
101
+
102
+ ## The supersession rule
103
+
104
+ ```text
105
+ same key, same value → reinforce (reliability rises, use is counted)
106
+ same key, newer value → supersede: incumbent gets valid_to = new.valid_from
107
+ same key, older value → filed as history; the timeline stays consistent
108
+ weaker challenger → parked as a candidate and sent to review
109
+ ```
110
+
111
+ Ordering is decided by `valid_from` (when the evidence says it became true), never by
112
+ insertion order — so a backfill converges to the same state in any order, twice, or in
113
+ batches. Three policies: `auto` (last writer by event time), `gate_conflicts`
114
+ (default: a less reliable challenger goes to review), `await_confirmation`.
115
+
116
+ ## Recall is keyword search; the agent supplies the meaning
117
+
118
+ The index is FTS5/BM25 — fast, model-free, and literal. The `recall` tool therefore takes
119
+ **several phrasings** and fuses them by reciprocal rank, so a tool-calling agent puts its
120
+ own reasoning into retrieval at call time (synonyms, related concepts, the literal value it
121
+ expects), the same way it would issue a few grep or web-search queries:
122
+
123
+ ```text
124
+ recall(queries=["which port does the api listen on", "api port", "8443", "gateway listen port"])
125
+ ```
126
+
127
+ Prompt-time injection (the hooks) stays deterministic and only injects beliefs whose
128
+ *subject* the prompt names.
129
+
130
+ ## Keeping evaluations out of the evidence
131
+
132
+ Headless runs write transcripts too. Set `MEMWARE_NO_CAPTURE=1` in any run you do not want
133
+ indexed (hooks, the Hermes provider and `memware sync --from-hook` all honour it), put
134
+ `[memware-eval]` in evaluation prompts, and use `memware-eval --corpus ROOT --db scratch.db
135
+ --beliefs-from ~/.memware/memware.db` to judge retrieval against a store that excludes them.
136
+ `memware prune --containing TEXT` un-indexes runs that already slipped in. For a durable filter that every sync honours — including runs that predate a marker — list content signatures in `~/.memware/ignore-markers.txt` (or `MEMWARE_IGNORE_MARKERS`); any transcript whose head contains one is never indexed.
137
+
138
+ ## Reviewing contested supersessions
139
+
140
+ memware does not ship a UI. It ships a contract — `ReviewBackend` with `publish()` and
141
+ `collect()` — plus two implementations: JSONL outbox/inbox files and a plain HTTP
142
+ endpoint. Wire it to whatever you already use to make decisions.
143
+
144
+ ```bash
145
+ memware review sync # outbox ~/.memware/review-outbox.jsonl
146
+ echo '{"review_id": 7, "decision": "approve"}' >> ~/.memware/review-inbox.jsonl
147
+ memware review sync # applied
148
+ ```
149
+
150
+ ## Evaluation
151
+
152
+ `memware-eval` scores retrieval against a question set: does the right evidence
153
+ surface, and does the stale value stay hidden? It needs no model, so results are
154
+ reproducible. The protocol for end-to-end comparisons — agent alone vs agent + memware —
155
+ is in [docs/eval.md](docs/eval.md).
156
+
157
+ ## Status
158
+
159
+ Alpha. The schema may change before 1.0; the ledger semantics will not.
160
+
161
+ ## License
162
+
163
+ MIT. See [LICENSE](LICENSE).