mnemos-continuity 0.2.0__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.
- mnemos_continuity-0.2.0/.github/workflows/release-hardening.yml +99 -0
- mnemos_continuity-0.2.0/.github/workflows/release.yml +133 -0
- mnemos_continuity-0.2.0/.gitignore +48 -0
- mnemos_continuity-0.2.0/CHANGELOG.md +169 -0
- mnemos_continuity-0.2.0/CLAUDE.md +138 -0
- mnemos_continuity-0.2.0/CONTRIBUTING.md +51 -0
- mnemos_continuity-0.2.0/HERMES_INSTALL.md +90 -0
- mnemos_continuity-0.2.0/LICENSE +21 -0
- mnemos_continuity-0.2.0/PKG-INFO +699 -0
- mnemos_continuity-0.2.0/README.md +660 -0
- mnemos_continuity-0.2.0/SETUP.md +286 -0
- mnemos_continuity-0.2.0/benchmarks/README.md +121 -0
- mnemos_continuity-0.2.0/benchmarks/continuity_eval.py +350 -0
- mnemos_continuity-0.2.0/benchmarks/retrieval_benchmark.py +333 -0
- mnemos_continuity-0.2.0/docs/DEVELOPMENT.md +59 -0
- mnemos_continuity-0.2.0/docs/design-audit-2026-07.md +398 -0
- mnemos_continuity-0.2.0/docs/explainer/hypomnema.html +850 -0
- mnemos_continuity-0.2.0/docs/hermes-integration.md +234 -0
- mnemos_continuity-0.2.0/docs/identity-model.md +110 -0
- mnemos_continuity-0.2.0/docs/openclaw-integration.md +229 -0
- mnemos_continuity-0.2.0/docs/privacy-security.md +99 -0
- mnemos_continuity-0.2.0/docs/readiness-0.2.0.md +117 -0
- mnemos_continuity-0.2.0/docs/release-hardening.md +67 -0
- mnemos_continuity-0.2.0/docs/setup-video-frames/01-title.html +113 -0
- mnemos_continuity-0.2.0/docs/setup-video-frames/02-install.svg +51 -0
- mnemos_continuity-0.2.0/docs/setup-video-frames/03-connect.svg +45 -0
- mnemos_continuity-0.2.0/docs/setup-video-frames/04-tools.svg +45 -0
- mnemos_continuity-0.2.0/docs/setup-video-frames/05-hermes.svg +44 -0
- mnemos_continuity-0.2.0/docs/setup-video-frames/06-close.html +114 -0
- mnemos_continuity-0.2.0/docs/setup-video-frames/README.md +26 -0
- mnemos_continuity-0.2.0/docs/setup-video-script.md +208 -0
- mnemos_continuity-0.2.0/docs/shared-pool.md +171 -0
- mnemos_continuity-0.2.0/docs/turnkey-memory-system.md +88 -0
- mnemos_continuity-0.2.0/docs/vision.md +738 -0
- mnemos_continuity-0.2.0/forge/README.md +69 -0
- mnemos_continuity-0.2.0/forge/SKILL.md +249 -0
- mnemos_continuity-0.2.0/forge/references/agent-anatomy.md +110 -0
- mnemos_continuity-0.2.0/forge/scripts/forge-detect.sh +76 -0
- mnemos_continuity-0.2.0/forge/scripts/forge-pane.sh +232 -0
- mnemos_continuity-0.2.0/forge/scripts/forge.py +591 -0
- mnemos_continuity-0.2.0/index.html +1183 -0
- mnemos_continuity-0.2.0/mnemos/__init__.py +63 -0
- mnemos_continuity-0.2.0/mnemos/advanced/__init__.py +43 -0
- mnemos_continuity-0.2.0/mnemos/advanced/attention_gate.py +48 -0
- mnemos_continuity-0.2.0/mnemos/advanced/dreaming.py +56 -0
- mnemos_continuity-0.2.0/mnemos/advanced/intention.py +82 -0
- mnemos_continuity-0.2.0/mnemos/advanced/intention_sweep.py +35 -0
- mnemos_continuity-0.2.0/mnemos/advanced/interference.py +53 -0
- mnemos_continuity-0.2.0/mnemos/advanced/interference_resolution.py +48 -0
- mnemos_continuity-0.2.0/mnemos/advanced/introspection.py +580 -0
- mnemos_continuity-0.2.0/mnemos/advanced/introspection_api.py +488 -0
- mnemos_continuity-0.2.0/mnemos/advanced/metamemory.py +70 -0
- mnemos_continuity-0.2.0/mnemos/advanced/metamemory_update.py +44 -0
- mnemos_continuity-0.2.0/mnemos/advanced/observer.py +52 -0
- mnemos_continuity-0.2.0/mnemos/advanced/predictive.py +41 -0
- mnemos_continuity-0.2.0/mnemos/advanced/schema.py +67 -0
- mnemos_continuity-0.2.0/mnemos/advanced/schema_maintenance.py +44 -0
- mnemos_continuity-0.2.0/mnemos/advanced/schema_matcher.py +34 -0
- mnemos_continuity-0.2.0/mnemos/advanced/spreading_activation.py +43 -0
- mnemos_continuity-0.2.0/mnemos/advanced/working_memory.py +69 -0
- mnemos_continuity-0.2.0/mnemos/bridge.py +199 -0
- mnemos_continuity-0.2.0/mnemos/cli.py +1542 -0
- mnemos_continuity-0.2.0/mnemos/config/__init__.py +8 -0
- mnemos_continuity-0.2.0/mnemos/config/defaults.py +145 -0
- mnemos_continuity-0.2.0/mnemos/config/loader.py +159 -0
- mnemos_continuity-0.2.0/mnemos/consolidation/__init__.py +16 -0
- mnemos_continuity-0.2.0/mnemos/consolidation/belief_review.py +135 -0
- mnemos_continuity-0.2.0/mnemos/consolidation/connection_discovery.py +234 -0
- mnemos_continuity-0.2.0/mnemos/consolidation/daemon.py +332 -0
- mnemos_continuity-0.2.0/mnemos/consolidation/decay.py +170 -0
- mnemos_continuity-0.2.0/mnemos/consolidation/reflection.py +321 -0
- mnemos_continuity-0.2.0/mnemos/consolidation/softening.py +622 -0
- mnemos_continuity-0.2.0/mnemos/core/__init__.py +22 -0
- mnemos_continuity-0.2.0/mnemos/core/belief.py +158 -0
- mnemos_continuity-0.2.0/mnemos/core/emotional_state.py +162 -0
- mnemos_continuity-0.2.0/mnemos/core/engram.py +436 -0
- mnemos_continuity-0.2.0/mnemos/core/identity.py +265 -0
- mnemos_continuity-0.2.0/mnemos/core/types.py +199 -0
- mnemos_continuity-0.2.0/mnemos/dream_journal.py +218 -0
- mnemos_continuity-0.2.0/mnemos/encoding/__init__.py +7 -0
- mnemos_continuity-0.2.0/mnemos/encoding/encoder.py +600 -0
- mnemos_continuity-0.2.0/mnemos/encoding/llm_classifier.py +465 -0
- mnemos_continuity-0.2.0/mnemos/identity_diff.py +983 -0
- mnemos_continuity-0.2.0/mnemos/identity_svg.py +241 -0
- mnemos_continuity-0.2.0/mnemos/indexer/__init__.py +6 -0
- mnemos_continuity-0.2.0/mnemos/indexer/claude_code_adapter.py +275 -0
- mnemos_continuity-0.2.0/mnemos/indexer/prompts/extractor.md +58 -0
- mnemos_continuity-0.2.0/mnemos/indexer/session_indexer.py +745 -0
- mnemos_continuity-0.2.0/mnemos/integrations/__init__.py +1 -0
- mnemos_continuity-0.2.0/mnemos/integrations/hermes/__init__.py +28 -0
- mnemos_continuity-0.2.0/mnemos/integrations/hermes/installer.py +732 -0
- mnemos_continuity-0.2.0/mnemos/integrations/hermes/provider.py +755 -0
- mnemos_continuity-0.2.0/mnemos/integrations/hermes/scope.py +210 -0
- mnemos_continuity-0.2.0/mnemos/interface/__init__.py +18 -0
- mnemos_continuity-0.2.0/mnemos/interface/context_packet.py +365 -0
- mnemos_continuity-0.2.0/mnemos/interface/export.py +87 -0
- mnemos_continuity-0.2.0/mnemos/interface/memory_inspector.py +116 -0
- mnemos_continuity-0.2.0/mnemos/interface/openclaw_export.py +203 -0
- mnemos_continuity-0.2.0/mnemos/interface/prompt_builder.py +161 -0
- mnemos_continuity-0.2.0/mnemos/interface/session.py +109 -0
- mnemos_continuity-0.2.0/mnemos/interface/visual_snapshot.py +145 -0
- mnemos_continuity-0.2.0/mnemos/llm.py +527 -0
- mnemos_continuity-0.2.0/mnemos/mcp_server.py +1633 -0
- mnemos_continuity-0.2.0/mnemos/multiagent/__init__.py +16 -0
- mnemos_continuity-0.2.0/mnemos/multiagent/attestation.py +78 -0
- mnemos_continuity-0.2.0/mnemos/multiagent/bridge.py +326 -0
- mnemos_continuity-0.2.0/mnemos/multiagent/federation.py +66 -0
- mnemos_continuity-0.2.0/mnemos/multiagent/relationships.py +221 -0
- mnemos_continuity-0.2.0/mnemos/multiagent/shared_pool.py +241 -0
- mnemos_continuity-0.2.0/mnemos/openclaw_cron.py +182 -0
- mnemos_continuity-0.2.0/mnemos/retrieval/__init__.py +9 -0
- mnemos_continuity-0.2.0/mnemos/retrieval/reactive.py +273 -0
- mnemos_continuity-0.2.0/mnemos/retrieval/reconsolidation.py +108 -0
- mnemos_continuity-0.2.0/mnemos/setup/__init__.py +8 -0
- mnemos_continuity-0.2.0/mnemos/setup/bootstrap.py +426 -0
- mnemos_continuity-0.2.0/mnemos/setup/cron_installer.py +227 -0
- mnemos_continuity-0.2.0/mnemos/setup/scheduler.py +411 -0
- mnemos_continuity-0.2.0/mnemos/simple_mcp.py +462 -0
- mnemos_continuity-0.2.0/mnemos/simple_runtime.py +2103 -0
- mnemos_continuity-0.2.0/mnemos/simple_scope.py +133 -0
- mnemos_continuity-0.2.0/mnemos/store/__init__.py +3 -0
- mnemos_continuity-0.2.0/mnemos/store/archive.py +73 -0
- mnemos_continuity-0.2.0/mnemos/store/embedding_index.py +391 -0
- mnemos_continuity-0.2.0/mnemos/store/migrations.py +86 -0
- mnemos_continuity-0.2.0/mnemos/store/sqlite_store.py +2217 -0
- mnemos_continuity-0.2.0/mnemos/substrate/__init__.py +18 -0
- mnemos_continuity-0.2.0/mnemos/substrate/config.py +87 -0
- mnemos_continuity-0.2.0/mnemos/substrate/events.py +42 -0
- mnemos_continuity-0.2.0/mnemos/substrate/handlers/__init__.py +5 -0
- mnemos_continuity-0.2.0/mnemos/substrate/handlers/dreaming.py +198 -0
- mnemos_continuity-0.2.0/mnemos/substrate/handlers/initiation.py +103 -0
- mnemos_continuity-0.2.0/mnemos/substrate/handlers/insight.py +96 -0
- mnemos_continuity-0.2.0/mnemos/substrate/handlers/reflection.py +152 -0
- mnemos_continuity-0.2.0/mnemos/substrate/handlers/surprise.py +93 -0
- mnemos_continuity-0.2.0/mnemos/substrate/handlers/wandering.py +199 -0
- mnemos_continuity-0.2.0/mnemos/substrate/introspection_pass.py +267 -0
- mnemos_continuity-0.2.0/mnemos/substrate/llm.py +139 -0
- mnemos_continuity-0.2.0/mnemos/substrate/modulators.py +106 -0
- mnemos_continuity-0.2.0/mnemos/substrate/prompts/connector.md +34 -0
- mnemos_continuity-0.2.0/mnemos/substrate/prompts/consolidator.md +19 -0
- mnemos_continuity-0.2.0/mnemos/substrate/prompts/extractor.md +60 -0
- mnemos_continuity-0.2.0/mnemos/substrate/prompts/reflection.md +33 -0
- mnemos_continuity-0.2.0/mnemos/substrate/prompts/softener.md +19 -0
- mnemos_continuity-0.2.0/mnemos/substrate/tick.py +398 -0
- mnemos_continuity-0.2.0/mnemos/visualization/__init__.py +1 -0
- mnemos_continuity-0.2.0/mnemos/visualization/app.py +1039 -0
- mnemos_continuity-0.2.0/mnemos/visualization/data.py +287 -0
- mnemos_continuity-0.2.0/openclaw/crons/cross-agent-bridge.md +41 -0
- mnemos_continuity-0.2.0/openclaw/crons/daily-debrief.md +75 -0
- mnemos_continuity-0.2.0/openclaw/crons/memory-maintenance.md +46 -0
- mnemos_continuity-0.2.0/openclaw/crons/morning-brief.md +77 -0
- mnemos_continuity-0.2.0/openclaw/crons/observer-context-sync.md +73 -0
- mnemos_continuity-0.2.0/openclaw/crons/substrate-tick.md +47 -0
- mnemos_continuity-0.2.0/pyproject.toml +81 -0
- mnemos_continuity-0.2.0/scripts/health_check.py +884 -0
- mnemos_continuity-0.2.0/scripts/readiness_check.py +313 -0
- mnemos_continuity-0.2.0/synapse-panel.png +0 -0
- mnemos_continuity-0.2.0/templates/AGENTS.md +69 -0
- mnemos_continuity-0.2.0/templates/HEARTBEAT.md +81 -0
- mnemos_continuity-0.2.0/templates/IDENTITY.md +129 -0
- mnemos_continuity-0.2.0/templates/MEMORY.md +131 -0
- mnemos_continuity-0.2.0/templates/SOUL.md +89 -0
- mnemos_continuity-0.2.0/templates/active-context.md +81 -0
- mnemos_continuity-0.2.0/tests/__init__.py +0 -0
- mnemos_continuity-0.2.0/tests/conftest.py +53 -0
- mnemos_continuity-0.2.0/tests/test_agent_scoping.py +132 -0
- mnemos_continuity-0.2.0/tests/test_belief_contradiction_kinds.py +158 -0
- mnemos_continuity-0.2.0/tests/test_belief_edge_correction.py +146 -0
- mnemos_continuity-0.2.0/tests/test_cli_simple.py +125 -0
- mnemos_continuity-0.2.0/tests/test_connection_discovery_relations.py +131 -0
- mnemos_continuity-0.2.0/tests/test_context_packet.py +69 -0
- mnemos_continuity-0.2.0/tests/test_continuity_assay.py +232 -0
- mnemos_continuity-0.2.0/tests/test_continuity_signals.py +111 -0
- mnemos_continuity-0.2.0/tests/test_cron_excludes_indexer.py +51 -0
- mnemos_continuity-0.2.0/tests/test_dream_journal.py +227 -0
- mnemos_continuity-0.2.0/tests/test_encoding.py +46 -0
- mnemos_continuity-0.2.0/tests/test_env_isolation.py +44 -0
- mnemos_continuity-0.2.0/tests/test_forget_is_complete.py +214 -0
- mnemos_continuity-0.2.0/tests/test_functional_memory.py +124 -0
- mnemos_continuity-0.2.0/tests/test_hermes_integration.py +703 -0
- mnemos_continuity-0.2.0/tests/test_hypomnema.py +164 -0
- mnemos_continuity-0.2.0/tests/test_identity_concerns_are_real.py +124 -0
- mnemos_continuity-0.2.0/tests/test_identity_diff.py +456 -0
- mnemos_continuity-0.2.0/tests/test_identity_pass.py +104 -0
- mnemos_continuity-0.2.0/tests/test_impact_provenance.py +125 -0
- mnemos_continuity-0.2.0/tests/test_indexer_config.py +65 -0
- mnemos_continuity-0.2.0/tests/test_indexer_discovery.py +56 -0
- mnemos_continuity-0.2.0/tests/test_integration.py +60 -0
- mnemos_continuity-0.2.0/tests/test_introspection.py +83 -0
- mnemos_continuity-0.2.0/tests/test_lessons.py +104 -0
- mnemos_continuity-0.2.0/tests/test_mcp_surface.py +321 -0
- mnemos_continuity-0.2.0/tests/test_migration_from_0_1.py +107 -0
- mnemos_continuity-0.2.0/tests/test_mind_state_agent_judgment.py +58 -0
- mnemos_continuity-0.2.0/tests/test_packaging_constraints.py +94 -0
- mnemos_continuity-0.2.0/tests/test_reflect_lands_where_it_is_read.py +154 -0
- mnemos_continuity-0.2.0/tests/test_reflection_queue.py +251 -0
- mnemos_continuity-0.2.0/tests/test_retrieval.py +57 -0
- mnemos_continuity-0.2.0/tests/test_scheduler.py +339 -0
- mnemos_continuity-0.2.0/tests/test_scope_isolation_packet.py +114 -0
- mnemos_continuity-0.2.0/tests/test_scope_roundtrip.py +162 -0
- mnemos_continuity-0.2.0/tests/test_serve_mode.py +43 -0
- mnemos_continuity-0.2.0/tests/test_session_hook.py +370 -0
- mnemos_continuity-0.2.0/tests/test_simple_runtime.py +661 -0
- mnemos_continuity-0.2.0/tests/test_softening_conservator.py +182 -0
- mnemos_continuity-0.2.0/tests/test_softening_does_not_destroy.py +214 -0
- mnemos_continuity-0.2.0/tests/test_store.py +160 -0
- mnemos_continuity-0.2.0/tests/test_surprise.py +83 -0
- mnemos_continuity-0.2.0/tests/test_version.py +58 -0
- mnemos_continuity-0.2.0/uv.lock +2878 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
name: Release hardening
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Python ${{ matrix.python-version }}
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
fail-fast: false
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v5
|
|
23
|
+
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: ${{ matrix.python-version }}
|
|
28
|
+
|
|
29
|
+
- name: Run tests with MCP surface
|
|
30
|
+
run: uv run --extra dev --extra mcp pytest -q
|
|
31
|
+
|
|
32
|
+
- name: Compile release entrypoints
|
|
33
|
+
run: |
|
|
34
|
+
uv run --extra mcp python -m py_compile \
|
|
35
|
+
mnemos/simple_runtime.py \
|
|
36
|
+
mnemos/simple_mcp.py \
|
|
37
|
+
mnemos/mcp_server.py \
|
|
38
|
+
mnemos/cli.py
|
|
39
|
+
|
|
40
|
+
- name: Build package
|
|
41
|
+
run: uv build
|
|
42
|
+
|
|
43
|
+
- name: Check wheel contents
|
|
44
|
+
run: |
|
|
45
|
+
uv run python - <<'PY'
|
|
46
|
+
import zipfile
|
|
47
|
+
from pathlib import Path
|
|
48
|
+
|
|
49
|
+
# Glob the project prefix, not the full distribution name, so a
|
|
50
|
+
# rename cannot silently break this check with a StopIteration.
|
|
51
|
+
wheel = next(Path("dist").glob("mnemos*.whl"))
|
|
52
|
+
# Keep this set identical to the one in release.yml — a packaging
|
|
53
|
+
# regression must not pass one gate and fail the other.
|
|
54
|
+
required = {
|
|
55
|
+
"mnemos/simple_runtime.py",
|
|
56
|
+
"mnemos/simple_mcp.py",
|
|
57
|
+
"mnemos/setup/scheduler.py",
|
|
58
|
+
"templates/SOUL.md",
|
|
59
|
+
"templates/IDENTITY.md",
|
|
60
|
+
}
|
|
61
|
+
with zipfile.ZipFile(wheel) as archive:
|
|
62
|
+
names = set(archive.namelist())
|
|
63
|
+
missing = sorted(required - names)
|
|
64
|
+
if missing:
|
|
65
|
+
raise SystemExit(f"Missing from wheel: {missing}")
|
|
66
|
+
print(f"Wheel OK: {wheel}")
|
|
67
|
+
PY
|
|
68
|
+
|
|
69
|
+
- name: Smoke-install the wheel with an unlocked resolver
|
|
70
|
+
run: |
|
|
71
|
+
# Everything above runs against uv.lock, so a broken *declared*
|
|
72
|
+
# dependency range passes every check while a real `pip install`
|
|
73
|
+
# fails. This installs the built wheel into a clean venv with no
|
|
74
|
+
# lockfile, resolving dependencies live from PyPI exactly as a user
|
|
75
|
+
# would — the only step that can catch "green CI, dead install".
|
|
76
|
+
python -m venv /tmp/mnemos-smoke
|
|
77
|
+
/tmp/mnemos-smoke/bin/pip install --quiet --upgrade pip
|
|
78
|
+
/tmp/mnemos-smoke/bin/pip install --quiet dist/*.whl
|
|
79
|
+
/tmp/mnemos-smoke/bin/python - <<'PY'
|
|
80
|
+
import asyncio
|
|
81
|
+
import importlib.metadata as md
|
|
82
|
+
|
|
83
|
+
# Importing constructs the FastMCP server and registers every simple
|
|
84
|
+
# tool at module scope. Under mcp 2.0 this line raised
|
|
85
|
+
# ModuleNotFoundError: No module named 'mcp.server.fastmcp'.
|
|
86
|
+
from mnemos.simple_mcp import SIMPLE_TOOL_NAMES, simple_mcp
|
|
87
|
+
|
|
88
|
+
print("resolved mcp:", md.version("mcp"))
|
|
89
|
+
tools = {t.name for t in asyncio.run(simple_mcp.list_tools())}
|
|
90
|
+
if tools != set(SIMPLE_TOOL_NAMES):
|
|
91
|
+
raise SystemExit(
|
|
92
|
+
f"tool surface mismatch: {sorted(tools)} != "
|
|
93
|
+
f"{sorted(SIMPLE_TOOL_NAMES)}"
|
|
94
|
+
)
|
|
95
|
+
print(f"Fresh install OK: {len(tools)} simple tools registered")
|
|
96
|
+
PY
|
|
97
|
+
|
|
98
|
+
- name: Check package metadata
|
|
99
|
+
run: uvx twine check dist/*
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
# Publishing is triggered by pushing a version tag, so a release never
|
|
4
|
+
# depends on anyone opening a browser. Trusted Publishing (OIDC) means no
|
|
5
|
+
# API token exists anywhere — not in the repo, not in a secret, not on a
|
|
6
|
+
# developer's machine.
|
|
7
|
+
#
|
|
8
|
+
# To cut a release:
|
|
9
|
+
# 1. bump `version` in pyproject.toml, land it through a PR
|
|
10
|
+
# 2. git tag v0.2.0 && git push origin v0.2.0
|
|
11
|
+
#
|
|
12
|
+
# The tag must match the version in pyproject.toml or the run fails before
|
|
13
|
+
# anything is built. A published version can never be replaced on PyPI, so
|
|
14
|
+
# every gate here runs before the upload, not after.
|
|
15
|
+
|
|
16
|
+
on:
|
|
17
|
+
push:
|
|
18
|
+
tags:
|
|
19
|
+
- "v*"
|
|
20
|
+
# Allows a dry run: builds and checks the artifacts, never publishes.
|
|
21
|
+
workflow_dispatch:
|
|
22
|
+
|
|
23
|
+
permissions:
|
|
24
|
+
contents: read
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
verify:
|
|
28
|
+
name: Verify tag and tests
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
outputs:
|
|
31
|
+
version: ${{ steps.version.outputs.version }}
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
|
|
35
|
+
- name: Install uv
|
|
36
|
+
uses: astral-sh/setup-uv@v5
|
|
37
|
+
|
|
38
|
+
- name: Read the packaged version
|
|
39
|
+
id: version
|
|
40
|
+
run: |
|
|
41
|
+
version=$(uv run python -c "import tomllib,pathlib; print(tomllib.loads(pathlib.Path('pyproject.toml').read_text())['project']['version'])")
|
|
42
|
+
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
43
|
+
echo "pyproject version: $version"
|
|
44
|
+
|
|
45
|
+
- name: The tag must match the packaged version
|
|
46
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
47
|
+
run: |
|
|
48
|
+
tag="${GITHUB_REF#refs/tags/v}"
|
|
49
|
+
packaged="${{ steps.version.outputs.version }}"
|
|
50
|
+
if [ "$tag" != "$packaged" ]; then
|
|
51
|
+
echo "::error::tag v$tag does not match pyproject version $packaged"
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
echo "tag v$tag matches pyproject version"
|
|
55
|
+
|
|
56
|
+
- name: Tests must pass before anything is published
|
|
57
|
+
run: uv run --extra dev --extra mcp pytest -q
|
|
58
|
+
|
|
59
|
+
build:
|
|
60
|
+
name: Build distributions
|
|
61
|
+
needs: verify
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
steps:
|
|
64
|
+
- uses: actions/checkout@v4
|
|
65
|
+
|
|
66
|
+
- name: Install uv
|
|
67
|
+
uses: astral-sh/setup-uv@v5
|
|
68
|
+
|
|
69
|
+
- name: Build
|
|
70
|
+
run: uv build
|
|
71
|
+
|
|
72
|
+
- name: The wheel must carry what the package promises
|
|
73
|
+
run: |
|
|
74
|
+
uv run python - <<'PY'
|
|
75
|
+
import zipfile
|
|
76
|
+
from pathlib import Path
|
|
77
|
+
|
|
78
|
+
wheel = next(Path("dist").glob("mnemos*.whl"))
|
|
79
|
+
required = {
|
|
80
|
+
"mnemos/simple_runtime.py",
|
|
81
|
+
"mnemos/simple_mcp.py",
|
|
82
|
+
"mnemos/setup/scheduler.py",
|
|
83
|
+
"templates/SOUL.md",
|
|
84
|
+
"templates/IDENTITY.md",
|
|
85
|
+
}
|
|
86
|
+
with zipfile.ZipFile(wheel) as archive:
|
|
87
|
+
names = set(archive.namelist())
|
|
88
|
+
missing = sorted(required - names)
|
|
89
|
+
if missing:
|
|
90
|
+
raise SystemExit(f"Missing from wheel: {missing}")
|
|
91
|
+
print(f"Wheel OK: {wheel}")
|
|
92
|
+
PY
|
|
93
|
+
|
|
94
|
+
- name: Check metadata renders on PyPI
|
|
95
|
+
run: uvx twine check dist/*
|
|
96
|
+
|
|
97
|
+
- name: A clean install must produce a working server
|
|
98
|
+
run: |
|
|
99
|
+
python -m venv /tmp/fresh
|
|
100
|
+
/tmp/fresh/bin/pip install -q dist/mnemos*.whl
|
|
101
|
+
/tmp/fresh/bin/mnemos --help > /dev/null
|
|
102
|
+
# The failure this guards: `mcp` was once an optional extra while
|
|
103
|
+
# being imported at module scope, so a clean install produced a
|
|
104
|
+
# server that died on first serve with the error hidden on stderr.
|
|
105
|
+
/tmp/fresh/bin/python -c "import mcp.server.fastmcp; print('mcp present in a clean install')"
|
|
106
|
+
|
|
107
|
+
- uses: actions/upload-artifact@v4
|
|
108
|
+
with:
|
|
109
|
+
name: distributions
|
|
110
|
+
path: dist/
|
|
111
|
+
|
|
112
|
+
publish:
|
|
113
|
+
name: Publish to PyPI
|
|
114
|
+
needs: build
|
|
115
|
+
# Tags only. A manual dispatch builds and verifies without publishing,
|
|
116
|
+
# which makes the whole pipeline safe to rehearse.
|
|
117
|
+
if: startsWith(github.ref, 'refs/tags/')
|
|
118
|
+
runs-on: ubuntu-latest
|
|
119
|
+
environment:
|
|
120
|
+
name: pypi
|
|
121
|
+
url: https://pypi.org/p/mnemos-continuity
|
|
122
|
+
permissions:
|
|
123
|
+
# Required for Trusted Publishing. This is the only credential
|
|
124
|
+
# involved, it is minted per-run by GitHub, and it cannot be reused.
|
|
125
|
+
id-token: write
|
|
126
|
+
steps:
|
|
127
|
+
- uses: actions/download-artifact@v4
|
|
128
|
+
with:
|
|
129
|
+
name: distributions
|
|
130
|
+
path: dist/
|
|
131
|
+
|
|
132
|
+
- name: Publish
|
|
133
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
*.egg-info/
|
|
7
|
+
*.egg
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
.eggs/
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
env/
|
|
16
|
+
|
|
17
|
+
# IDE
|
|
18
|
+
.vscode/
|
|
19
|
+
.idea/
|
|
20
|
+
*.swp
|
|
21
|
+
*.swo
|
|
22
|
+
*~
|
|
23
|
+
|
|
24
|
+
# OS
|
|
25
|
+
.DS_Store
|
|
26
|
+
Thumbs.db
|
|
27
|
+
|
|
28
|
+
# Mnemos databases
|
|
29
|
+
*.db
|
|
30
|
+
*.db-shm
|
|
31
|
+
*.db-wal
|
|
32
|
+
|
|
33
|
+
# Environment files
|
|
34
|
+
.env
|
|
35
|
+
.env.local
|
|
36
|
+
|
|
37
|
+
# Testing
|
|
38
|
+
.pytest_cache/
|
|
39
|
+
.coverage
|
|
40
|
+
htmlcov/
|
|
41
|
+
.mypy_cache/
|
|
42
|
+
.ruff_cache/
|
|
43
|
+
|
|
44
|
+
# Local archive — not pushed to GitHub
|
|
45
|
+
archive/
|
|
46
|
+
|
|
47
|
+
# local-only health-harness baselines (per-deployment)
|
|
48
|
+
scripts/health_baseline.local.json
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0 (2026-07-31)
|
|
4
|
+
|
|
5
|
+
Two things happen in this release. Continuity starts arriving on its own —
|
|
6
|
+
loaded at session start and captured as work happens, with nobody asking for
|
|
7
|
+
it. And memory stops being a notebook the agent writes to and becomes something
|
|
8
|
+
the agent *maintains*, in its own voice, on an install with no API key.
|
|
9
|
+
|
|
10
|
+
The first half is plumbing that was missing: scope that matches between the
|
|
11
|
+
write and the read, a session-start hook, background maintenance, and an
|
|
12
|
+
honest signal for when memory comes back empty. The second half is the one the
|
|
13
|
+
project was named for — the five shifts that were supposed to make this a mind
|
|
14
|
+
rather than a log, four of which did not actually run until now.
|
|
15
|
+
|
|
16
|
+
**Start here if you are upgrading:** two breaking changes are listed under
|
|
17
|
+
*Changed* — the default database path and the distribution name. Existing
|
|
18
|
+
stores migrate in place.
|
|
19
|
+
|
|
20
|
+
### What Mnemos is
|
|
21
|
+
Clarified throughout, because the previous framing caused a real failure. Mnemos
|
|
22
|
+
is a continuity and identity layer for the agent itself — it carries what the
|
|
23
|
+
agent should know about you and how you work together, across sessions. It is
|
|
24
|
+
**not** a general memory or retrieval system, and it runs alongside whatever you
|
|
25
|
+
already use for that. Pointing general recall at it buries the continuity layer:
|
|
26
|
+
on one live install the transcript indexer had written ~7,058 engrams against 13
|
|
27
|
+
deliberate captures, and a session packet spent five of six long-term slots on
|
|
28
|
+
paraphrases of a single harvested fact.
|
|
29
|
+
|
|
30
|
+
### A memory that maintains itself
|
|
31
|
+
Mnemos's design came from a session that asked one model what it would want if
|
|
32
|
+
the memory were its own to inhabit. Five shifts came out of that, and the
|
|
33
|
+
explainer has always claimed them — *"most AI memory is a notebook; this is a
|
|
34
|
+
mind."* Measured against a real store, four of the five did not run. Each one
|
|
35
|
+
needed a model, and the install the README advertises has none.
|
|
36
|
+
|
|
37
|
+
They run now, because the direction inverted: **the server never calls a model.
|
|
38
|
+
It asks the agent.** Maintenance proposes the work that needs judgement, and the
|
|
39
|
+
agent answers in its own turn, in its own words — that answer becomes part of
|
|
40
|
+
its memory. Consolidation stopped being something done *to* the agent and became
|
|
41
|
+
something it does. This works in every MCP client, needs no key, and made the
|
|
42
|
+
whole affinity system that used to police which outside model was allowed to
|
|
43
|
+
maintain an agent's memory unnecessary — that question is answered by
|
|
44
|
+
construction now (201 lines removed).
|
|
45
|
+
|
|
46
|
+
- **`mnemos_reflect`** — the eighth simple tool, and the only one whose entire
|
|
47
|
+
job is to let the agent's own voice into its own memory. The context packet
|
|
48
|
+
may quietly raise a question — what a capture changed, what a fading memory
|
|
49
|
+
taught — and the agent answers it here. Nothing is written on its behalf; if
|
|
50
|
+
no true answer comes, the prompt fades on its own. Restraint is enforced, not
|
|
51
|
+
hoped for: at most two requests per packet, each shown at most three times
|
|
52
|
+
then dropped, quiet scopes show nothing.
|
|
53
|
+
- **Traces, not records** — a capture can carry an `impact`: not what happened,
|
|
54
|
+
but what it changed. That sentence is what survives when the details fade, and
|
|
55
|
+
only the agent can write it, so the server never fills it with a template. An
|
|
56
|
+
empty impact is left empty and asked about later.
|
|
57
|
+
- **Forgetting that teaches** — as a memory fades, the lesson in it is distilled
|
|
58
|
+
and kept while the detail softens. With no provider the words are left intact
|
|
59
|
+
and the fade lives in ranking, never a rewrite the store cannot undo.
|
|
60
|
+
- **Surprise as growth** — a capture that does not fit what is already held is
|
|
61
|
+
encoded more deeply. This no longer depends on pre-existing beliefs or a
|
|
62
|
+
model, so it is no longer skipped.
|
|
63
|
+
- **Resonance over search** and **identity from the graph** — retrieval spreads
|
|
64
|
+
through typed connections, and identity is measured from what the agent keeps
|
|
65
|
+
returning to rather than narrated. Honest limit worth stating: without a
|
|
66
|
+
configured provider, edges the encoder cannot judge are labelled
|
|
67
|
+
`co_activated` — *these came up together* — rather than guessed into a
|
|
68
|
+
semantic type. The graph is honestly labelled, not richly typed; semantic
|
|
69
|
+
relations still need semantic judgement, which is the one thing a provider now
|
|
70
|
+
buys.
|
|
71
|
+
|
|
72
|
+
### Proof
|
|
73
|
+
- **The continuity assay** — spawns real subprocesses and passes no scope
|
|
74
|
+
arguments, because defaults are what an agent actually gets. Covers a capture
|
|
75
|
+
surviving into a later session, a capture written in one directory being
|
|
76
|
+
readable from another, earlier captures not being displaced, reading never
|
|
77
|
+
creating a store, and a corrupt store never failing a session. Reintroducing
|
|
78
|
+
the cwd-derived scope makes it fail; the fix makes it pass
|
|
79
|
+
- **Health that reports absence** — `mnemos_health` and `mnemos doctor` now
|
|
80
|
+
report notes held, empty-packet streak, and sessions since the last capture,
|
|
81
|
+
and say plainly when memory is being read but coming back empty. Every failure
|
|
82
|
+
this system has had looked like success from the outside; this is the signal
|
|
83
|
+
none of them could fake
|
|
84
|
+
- **Retrieval mode is legible** — `doctor` states whether recall is semantic or
|
|
85
|
+
keyword-only instead of leaving it to chance
|
|
86
|
+
|
|
87
|
+
### Background Maintenance Without OpenClaw
|
|
88
|
+
- `mnemos daemon {install,status,uninstall}` — schedules maintenance with whatever the host provides: launchd on macOS, systemd user timers on Linux, crontab as a fallback. Background continuity previously existed only as OpenClaw cron templates, so every user without OpenClaw had a memory system that did nothing between sessions. The job logic was never OpenClaw-specific — `mnemos consolidate`, `mnemos substrate-tick` and `mnemos index` are plain CLI commands, and only the scheduling was bound to OpenClaw
|
|
89
|
+
- Jobs are namespaced per agent, so several agents keep separate maintenance on one machine. Reinstall replaces rather than stacks, and the crontab backend only ever removes lines it wrote
|
|
90
|
+
- The model-mediated `index` job is omitted unless a provider is configured, rather than waking every 30 minutes to do nothing
|
|
91
|
+
- Nothing is scheduled without `--write`; `mnemos doctor` reports whether background maintenance is active
|
|
92
|
+
- On macOS, warns when Mnemos is installed under `~/Documents`, `~/Desktop` or `~/Downloads` — scheduled jobs do not inherit Full Disk Access, so they fail with a permission error even though the same command works by hand
|
|
93
|
+
- OpenClaw is now documented as one optional integration for agent-mediated jobs (observer sync, `MEMORY.md` upkeep, briefs) rather than as the way background work happens
|
|
94
|
+
|
|
95
|
+
### Continuity Without Manual Triggering
|
|
96
|
+
- Server instructions — both MCP surfaces now ship `instructions=` to the client, so an agent is told to load context at session start, capture durable things as they appear, and correct rather than contradict. Previously nothing instructed the agent to use memory at all; continuity only happened when a human asked for it
|
|
97
|
+
- `mnemos hooks install [--write]` — registers a Claude Code `SessionStart` hook that injects the continuity packet before the first turn. Preserves unrelated hooks and settings keys, replaces its own entry on reinstall rather than stacking, and refuses to overwrite an unparseable settings file
|
|
98
|
+
- `mnemos hook session-start` — the subcommand the hook runs. Injection logic ships with the package instead of going stale inside a generated script. Fails silent by design: any error, or a missing or corrupt store, exits 0 with no output
|
|
99
|
+
- Reading memory no longer creates a database as a side effect — a mistyped `--db-path` used to mint an empty store at every session start and then report a healthy, permanently empty packet
|
|
100
|
+
|
|
101
|
+
### Fixed
|
|
102
|
+
- **Scope split-brain.** The simple tools resolved scope through `resolve_scope` while the advanced tools took their literal parameter defaults (`default`/`user`/`global`). `mnemos_capture` wrote continuity into one partition and `mnemos_context_packet` read from another, both reporting success, so an agent silently had no memory. All 13 scoped tools now resolve through one shared resolver
|
|
103
|
+
- **`project_scope` no longer derives from the process working directory.** An MCP server's cwd is chosen by whichever client spawned it, so a cwd-derived scope partitioned one agent's memory by launch location. It now defaults to `global`; explicit arguments, `MNEMOS_PROJECT_SCOPE` and config still win
|
|
104
|
+
- **The CLI, simple mode, and advanced mode used three different combinations of agent id and database.** `mnemos stats` and `mnemos serve` reported on different stores. All entry points now share one resolver
|
|
105
|
+
- `ConsolidationDaemon(config={})` in the `mnemos_consolidate` tool, the CLI `consolidate` command, and `bridge.py` silently dropped the entire `consolidation` block of `config.json` — decay rate, thresholds, and `min_idle_minutes` all fell back to hardcoded defaults
|
|
106
|
+
- A function-local `Belief` import left the name undefined for the second seed belief in setup step 5; the resulting `NameError` was swallowed and the belief silently dropped
|
|
107
|
+
- Duplicated `foundational, foundational` label in the context packet
|
|
108
|
+
- **`pip install` produced a dead server.** The `mcp[cli]` dependency was declared `>=1.0.0` with no ceiling, so a fresh install resolved mcp 2.0 — which removed `mcp.server.fastmcp`, the module every server entrypoint imports — and the server died on import. CI never caught it because it installs from the pinned lockfile. Bounded to `<2`, with a wheel smoke job that installs unlocked from PyPI, plus a unit test guarding the declared ceiling
|
|
109
|
+
- **`forget` did not forget.** A successful `mnemos_correct(action="forget")` archived the memory and left `recall` silent — and the text was still read back to the agent, on both delivery paths: the session-start hook replayed it for three sessions from a frozen queue excerpt, and `mnemos_context` quoted it in the verification block with an instruction to say it aloud. Two snapshots taken at write time that no deletion reached. The rule now: no packet block renders a frozen copy of note text; every block re-reads by id and skips a memory that is gone. Older stores are cleaned during maintenance
|
|
110
|
+
- **A reflection did not reach the agent.** `mnemos_reflect` wrote the answer only to the engram, and the session packet is built from the continuity layer, which excludes the engram graph by default — so the one sentence the whole inversion exists to obtain was unreachable from the automatic path. It now lands in the continuity note as well; answering twice revises rather than stacks
|
|
111
|
+
- **Softening could erase what it could not read.** With no provider, the fade step truncated a memory to "An impression related to X... [faded]" and left the impact empty, with no way back. The default now leaves the words intact and lets the fade live in ranking; `mnemos repair-softening` (and a `mnemos doctor` prompt) restore memories an earlier version truncated, from each memory's own pre-fade snapshot
|
|
112
|
+
- **Identity reported its own bookkeeping.** "Persistent concerns" counted every tag, including the classifier and indexer labels Mnemos stamps on nearly every memory, so an agent read back `trace-type:fact, session-indexed, decision` as who it was. Those are excluded now; when nothing meaningful remains, the line is omitted rather than fabricated
|
|
113
|
+
|
|
114
|
+
### Changed
|
|
115
|
+
- **BREAKING:** advanced mode and the CLI now default to `~/.mnemos/<agent>.db` rather than `~/.mnemos/memory.db`, matching what simple mode already did. Pass `--db-path` or set `store.db_path` in `config.json` to keep reading an existing store
|
|
116
|
+
- Distribution renamed from `mnemos-memory` to `mnemos-continuity`. `mnemos-memory` is a different author's package on PyPI, and the published install instructions pointed users at it. The import package and CLI command are unchanged
|
|
117
|
+
- Engrams now record `impact_source` — who wrote the trace: `agent` (via `mnemos_reflect`/`mnemos_capture`), `model` (extracted by a configured provider), or `template` (server boilerplate). The product's claim is that only the agent can say what a memory changed, and this makes an agent-authored impact distinguishable from a generated one instead of something later reconstructed from a boilerplate denylist. Schema version 3 → 4; existing stores migrate in place and their prior impacts read as unknown, never back-filled with a guess
|
|
118
|
+
|
|
119
|
+
### Simple Mode (five tools → eight)
|
|
120
|
+
- Onboarding ritual — a fresh scope's first context packet walks the agent through a short get-to-know-you script (name, current work, durable facts); stores that predate onboarding are grandfathered and never see it
|
|
121
|
+
- mnemos_introduce — the agent declares its own model id and name, so its memory knows whose it is (an explicit MNEMOS_AGENT_MODEL still takes precedence)
|
|
122
|
+
- mnemos_reflect — the agent answers, in its own words, a reflection the packet raised; see *A memory that maintains itself* above
|
|
123
|
+
- Cross-session memory verification — the first context packet after a real restart quotes the very first capture back to the human, once, as proof that memory survived the goodbye. It re-reads that memory live, so a capture the human later forgot is never resurfaced
|
|
124
|
+
- Dream journal — consolidation cycles that did meaningful work leave a short first-person narrative, surfaced in the next context packet ("While you were away")
|
|
125
|
+
- mnemos_health — truly read-only, human-relayable health card: store location and size, memory counts, last maintenance cycle and who performed it, onboarding and verification progress, latest dream entry, and whether any memories are recoverable from an earlier version's truncation
|
|
126
|
+
|
|
127
|
+
## 0.1.0 (2026-04-05)
|
|
128
|
+
|
|
129
|
+
Initial release.
|
|
130
|
+
|
|
131
|
+
### Core Memory Engine
|
|
132
|
+
- Engram model with dual-trace (strength/stability/accessibility)
|
|
133
|
+
- 7 typed connections (supports, contradicts, causes, extends, parallels, synthesizes, grounds)
|
|
134
|
+
- Beliefs with confidence tracking, revision history, epistemic bounds [0.05, 0.95]
|
|
135
|
+
- 6-dimensional emotional state (curiosity, clarity, warmth, tension, surprise, focus)
|
|
136
|
+
- Graph-based identity computation
|
|
137
|
+
- SQLite backend with FTS5 full-text search and WAL mode
|
|
138
|
+
|
|
139
|
+
### MCP Server (9 tools)
|
|
140
|
+
- mnemos_setup — 10-step conversational onboarding wizard
|
|
141
|
+
- mnemos_remember — encode memories with impact, confidence, connection discovery
|
|
142
|
+
- mnemos_recall — spreading activation retrieval with emotional biasing
|
|
143
|
+
- mnemos_inspect — full engram details with version history
|
|
144
|
+
- mnemos_status — system health and statistics
|
|
145
|
+
- mnemos_beliefs — list beliefs with confidence and revision count
|
|
146
|
+
- mnemos_shared — query shared memory pool
|
|
147
|
+
- mnemos_forget — graceful archiving (soft delete)
|
|
148
|
+
- mnemos_consolidate — trigger decay, connection discovery, softening, belief review, reflection
|
|
149
|
+
|
|
150
|
+
### Cognitive Substrate
|
|
151
|
+
- Background tick loop (configurable interval, default 4h)
|
|
152
|
+
- 6 handlers: dreaming, wandering, surprise, reflection, insight, initiation
|
|
153
|
+
- Cognitive modulators (arousal, resolution, openness, selection_threshold, social_drive)
|
|
154
|
+
- Production guardrails: skip_surprise_detection on all handler outputs except surprise, per-handler throttles, confidence change caps
|
|
155
|
+
|
|
156
|
+
### CLI
|
|
157
|
+
- mnemos init, serve, stats, search, inspect, consolidate, export
|
|
158
|
+
- mnemos substrate-tick, index, bridge {status|recall|remember}
|
|
159
|
+
- mnemos setup-openclaw
|
|
160
|
+
|
|
161
|
+
### Multi-Agent
|
|
162
|
+
- Shared memory pool with visibility controls
|
|
163
|
+
- Agent relationship tracking with trust scores
|
|
164
|
+
- Per-agent isolation with optional cross-pollination
|
|
165
|
+
|
|
166
|
+
### Embedding Support
|
|
167
|
+
- Google Gemini embeddings (3072 dims)
|
|
168
|
+
- Local sentence-transformers fallback (384 dims)
|
|
169
|
+
- Graceful degradation to FTS5-only when no embedding backend available
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Working on Mnemos
|
|
2
|
+
|
|
3
|
+
Guidance for agents and contributors working in this repository.
|
|
4
|
+
|
|
5
|
+
Mnemos is a memory system. Its failure mode is not a crash — it is a layer
|
|
6
|
+
that silently reports success while carrying nothing. Most of the bugs found
|
|
7
|
+
in this codebase have been of exactly that shape: a scope that did not match,
|
|
8
|
+
a config that was never applied, a promotion that never fired. Everything
|
|
9
|
+
below exists to make that failure mode visible.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Verify, don't assume
|
|
14
|
+
|
|
15
|
+
If a claim is checkable, check it before stating it.
|
|
16
|
+
|
|
17
|
+
- **Run it.** Reading the code and reasoning about what it will do is not
|
|
18
|
+
verification. Install it, call it, look at the output.
|
|
19
|
+
- **No "too trivial to test" exemption.** The small, obvious changes are where
|
|
20
|
+
untested assumptions slip through.
|
|
21
|
+
- **Say what you actually know.** Distinguish "I verified X, here is the
|
|
22
|
+
command" from "I believe X." If something was not verified, say so.
|
|
23
|
+
|
|
24
|
+
For this repo specifically, a change to the memory path is not done until a
|
|
25
|
+
capture written in one process has been read back in another.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Tests
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pytest -q # the whole suite
|
|
33
|
+
uv run --extra dev --extra mcp pytest -q # exactly what CI runs
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
A bug fix lands with a test that **fails on the previous code**. Confirm that
|
|
37
|
+
directly — stash the fix, run the test, watch it fail, restore. A test that
|
|
38
|
+
passes both before and after documents behaviour; it does not protect it.
|
|
39
|
+
|
|
40
|
+
Beware tests that pass the same explicit arguments to the writer and the
|
|
41
|
+
reader. The scope split-brain survived 202 green tests because every scope
|
|
42
|
+
test hand-matched both sides. Exercise the defaults, because defaults are what
|
|
43
|
+
an agent actually calls.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Release process
|
|
48
|
+
|
|
49
|
+
`main` is public and is what users install. It stays green.
|
|
50
|
+
|
|
51
|
+
All work happens on a branch and lands through a pull request. Agents run the
|
|
52
|
+
entire pipeline — nothing here requires anyone to open GitHub.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git checkout -b <type>/<slug> origin/main
|
|
56
|
+
# work, atomic commits
|
|
57
|
+
git push -u origin <type>/<slug>
|
|
58
|
+
gh pr create --title "..." --body "..."
|
|
59
|
+
gh pr checks --watch # CI gate
|
|
60
|
+
gh pr merge --squash --delete-branch
|
|
61
|
+
git checkout main && git pull
|
|
62
|
+
gh run list --branch main --limit 1 # confirm main is green after the merge
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Rules:
|
|
66
|
+
|
|
67
|
+
- Never commit or push directly to `main`.
|
|
68
|
+
- Never merge with failing or pending checks.
|
|
69
|
+
- One PR is one unit of work, so squash by default. Use `--merge` only when a
|
|
70
|
+
branch carries several genuinely independent fixes worth keeping separately
|
|
71
|
+
revertable.
|
|
72
|
+
- Atomic commits. Stage explicit paths, never `git add .`.
|
|
73
|
+
- Never amend, never force-push, never `--no-verify`.
|
|
74
|
+
- Push when the work is complete and verified, not as a checkpoint.
|
|
75
|
+
- Breaking changes go in the CHANGELOG with the migration in the same entry.
|
|
76
|
+
|
|
77
|
+
`main` is protected. Merging requires a pull request and passing `Python 3.10`
|
|
78
|
+
through `Python 3.13` checks, the branch must be up to date with `main` first,
|
|
79
|
+
and force-pushes and branch deletion are refused.
|
|
80
|
+
|
|
81
|
+
Enforcement includes administrators. That is deliberate: the realistic risk is
|
|
82
|
+
an agent with admin credentials pushing straight to `main`, and an exemption
|
|
83
|
+
would leave the rule unenforced against exactly the party it exists to
|
|
84
|
+
restrain. It is not a lock-out risk either — protection can be lifted through
|
|
85
|
+
the API in a genuine emergency, so recovery never depends on anyone opening
|
|
86
|
+
GitHub.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Commits
|
|
91
|
+
|
|
92
|
+
Conventional prefixes (`fix:`, `feat:`, `docs:`, `test:`, `refactor:`), with a
|
|
93
|
+
scope where it clarifies (`fix(scope):`, `fix(ci):`).
|
|
94
|
+
|
|
95
|
+
The body should explain **what was actually broken and how it was verified**,
|
|
96
|
+
not restate the diff. Someone reading `git log` in a year should be able to
|
|
97
|
+
tell whether a change was reasoned about or guessed at.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Architecture notes
|
|
102
|
+
|
|
103
|
+
Three memory layers, most durable last:
|
|
104
|
+
|
|
105
|
+
1. **Functional memory** — the live working set for a session or task.
|
|
106
|
+
2. **Hypomnema** — scoped continuity that survives sessions and stays revisable.
|
|
107
|
+
3. **Engrams** — the long-term graph, with decay, connections, and beliefs.
|
|
108
|
+
|
|
109
|
+
Two MCP tool surfaces on one server: the seven **simple** tools are the
|
|
110
|
+
product; the **advanced** tools are an operator console. New user-facing
|
|
111
|
+
capability belongs in simple mode.
|
|
112
|
+
|
|
113
|
+
**Scope is a three-tuple** — `agent_id / person_id / project_scope` — and there
|
|
114
|
+
is exactly one resolver for it: `mnemos/simple_scope.py`. Both tool surfaces,
|
|
115
|
+
the CLI, and every serve mode route through `resolve_scope()` or
|
|
116
|
+
`resolve_tool_scope()`. Do not add a second answer to "whose memory is this."
|
|
117
|
+
Scope must never be inferred from ambient state such as the working directory;
|
|
118
|
+
an MCP server's cwd belongs to whichever client spawned it.
|
|
119
|
+
|
|
120
|
+
Storage is local SQLite, one file per agent by default
|
|
121
|
+
(`~/.mnemos/<agent>.db`). Nothing leaves the machine unless a provider is
|
|
122
|
+
configured.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Continuity is the product
|
|
127
|
+
|
|
128
|
+
Memory an agent must be asked to load is not continuity. Two mechanisms carry
|
|
129
|
+
it automatically, and changes must not quietly break either:
|
|
130
|
+
|
|
131
|
+
- **Server instructions** (`SERVER_INSTRUCTIONS` in `mnemos/simple_mcp.py`) are
|
|
132
|
+
passed to every MCP client and tell the agent to load context at session
|
|
133
|
+
start and capture as it goes.
|
|
134
|
+
- **The SessionStart hook** (`mnemos hooks install`) injects the packet before
|
|
135
|
+
the agent's first turn.
|
|
136
|
+
|
|
137
|
+
Anything that runs on the read path must fail silent and must never create a
|
|
138
|
+
store as a side effect of reading it.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Contributing to Mnemos
|
|
2
|
+
|
|
3
|
+
## Development Setup
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
git clone https://github.com/Riley-Coyote/mnemos.git
|
|
7
|
+
cd mnemos
|
|
8
|
+
python -m venv .venv
|
|
9
|
+
source .venv/bin/activate
|
|
10
|
+
pip install -e ".[all,dev]"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Running Tests
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pytest tests/
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Code Style
|
|
20
|
+
|
|
21
|
+
- Python 3.10+
|
|
22
|
+
- Type hints on all public functions
|
|
23
|
+
- Docstrings on all public classes and methods
|
|
24
|
+
- `logging.getLogger(__name__)` in every module
|
|
25
|
+
|
|
26
|
+
## Submitting Changes
|
|
27
|
+
|
|
28
|
+
1. Fork the repository
|
|
29
|
+
2. Create a feature branch
|
|
30
|
+
3. Make your changes
|
|
31
|
+
4. Run `pytest` to verify
|
|
32
|
+
5. Submit a pull request
|
|
33
|
+
|
|
34
|
+
## Architecture
|
|
35
|
+
|
|
36
|
+
Mnemos is organized into these layers:
|
|
37
|
+
|
|
38
|
+
- `core/` — Data structures (Engram, Belief, EmotionalState, Identity)
|
|
39
|
+
- `store/` — SQLite persistence + embedding index
|
|
40
|
+
- `encoding/` — Memory formation pipeline
|
|
41
|
+
- `retrieval/` — Spreading activation retrieval
|
|
42
|
+
- `consolidation/` — Offline processing (decay, softening, belief review, reflection)
|
|
43
|
+
- `substrate/` — Cognitive tick loop + handlers (dreaming, wandering, etc.)
|
|
44
|
+
- `indexer/` — Session transcript → memory extraction
|
|
45
|
+
- `interface/` — Prompt building, export, session tracking
|
|
46
|
+
- `multiagent/` — Shared pools, relationships, federation stubs
|
|
47
|
+
- `advanced/` — Experimental cognitive modules (opt-in)
|
|
48
|
+
|
|
49
|
+
## License
|
|
50
|
+
|
|
51
|
+
MIT
|