hypermnesic 0.1.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.
- hypermnesic-0.1.0/.claude-plugin/marketplace.json +19 -0
- hypermnesic-0.1.0/.env.example +31 -0
- hypermnesic-0.1.0/.github/CODEOWNERS +25 -0
- hypermnesic-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- hypermnesic-0.1.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- hypermnesic-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +31 -0
- hypermnesic-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +32 -0
- hypermnesic-0.1.0/.github/workflows/ci.yml +26 -0
- hypermnesic-0.1.0/.github/workflows/release.yml +68 -0
- hypermnesic-0.1.0/.gitignore +41 -0
- hypermnesic-0.1.0/.linear.toml +3 -0
- hypermnesic-0.1.0/AGENTS.md +168 -0
- hypermnesic-0.1.0/ARCHITECTURE.md +128 -0
- hypermnesic-0.1.0/CHANGELOG.md +250 -0
- hypermnesic-0.1.0/CITATION.cff +44 -0
- hypermnesic-0.1.0/CLAUDE.md +1 -0
- hypermnesic-0.1.0/CODE_OF_CONDUCT.md +36 -0
- hypermnesic-0.1.0/CONTRIBUTING.md +110 -0
- hypermnesic-0.1.0/GLOSSARY.md +129 -0
- hypermnesic-0.1.0/LICENSE +661 -0
- hypermnesic-0.1.0/PKG-INFO +23 -0
- hypermnesic-0.1.0/README.md +322 -0
- hypermnesic-0.1.0/SECURITY.md +67 -0
- hypermnesic-0.1.0/docs/2026-06-03-blocklist-write-surface-security-review.md +193 -0
- hypermnesic-0.1.0/docs/2026-06-03-unified-write-anywhere-security-review.md +126 -0
- hypermnesic-0.1.0/docs/README.md +113 -0
- hypermnesic-0.1.0/docs/archive/2026-06-02-deployment-topology-write-model-requirements.md +240 -0
- hypermnesic-0.1.0/docs/archive/2026-06-02-gate-A-rollout-runbook.md +78 -0
- hypermnesic-0.1.0/docs/archive/cloud-oauth-mcp-deploy-runbook.md +90 -0
- hypermnesic-0.1.0/docs/assets/readme-local-proof.cast +7 -0
- hypermnesic-0.1.0/docs/assets/readme-local-proof.svg +27 -0
- hypermnesic-0.1.0/docs/assets/social-preview.png +0 -0
- hypermnesic-0.1.0/docs/assets/social-preview.svg +36 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-02-cloud-oauth-mcp-mobile-requirements.md +232 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-02-gbrain-decommission-requirements.md +154 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-02-longmemeval-benchmark-protocol-requirements.md +250 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-02-obsidian-community-directory-publishing-requirements.md +374 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-02-obsidian-companion-first-class-ui-requirements.md +376 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-02-obsidian-companion-plugin-redesign-requirements.md +407 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-02-phase-2-5-fresh-recall-requirements.md +373 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-03-first-class-documentation-requirements.md +397 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-03-unified-oauth-endpoint-and-setup-requirements.md +286 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-03-vault-structure-discovery-and-blocklist-write-model-requirements.md +326 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-04-first-class-product-requirements.md +539 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-07-hypermnesic-incremental-doc-surface-invalidation.md +306 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-08-dense-retrieval-reliability-requirements.md +323 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-12-list-folders-agent-instructions-requirements.md +145 -0
- hypermnesic-0.1.0/docs/brainstorms/2026-06-15-launch-demo-assets-requirements.md +207 -0
- hypermnesic-0.1.0/docs/gate-artifacts/2026-06-02-gate-1-foundation.md +49 -0
- hypermnesic-0.1.0/docs/gate-artifacts/2026-06-02-gate-2-safe-to-go-live.md +65 -0
- hypermnesic-0.1.0/docs/gate-artifacts/2026-06-02-gate-3-release-and-canary.md +90 -0
- hypermnesic-0.1.0/docs/gate-artifacts/2026-06-02-gate-A-plugin-and-oauth.md +179 -0
- hypermnesic-0.1.0/docs/gbrain-decommission-STATE-2026-06-03.md +92 -0
- hypermnesic-0.1.0/docs/guides/consent-and-clients.md +82 -0
- hypermnesic-0.1.0/docs/guides/daily-workflows.md +124 -0
- hypermnesic-0.1.0/docs/guides/demo-asset-frame-review-checklist.md +63 -0
- hypermnesic-0.1.0/docs/guides/getting-started.md +297 -0
- hypermnesic-0.1.0/docs/guides/memory-control.md +153 -0
- hypermnesic-0.1.0/docs/guides/memory-taxonomy.md +84 -0
- hypermnesic-0.1.0/docs/guides/remote-client-smoke-checklist.md +131 -0
- hypermnesic-0.1.0/docs/handoff-macbook-gate-A-completion.md +116 -0
- hypermnesic-0.1.0/docs/handoff-macbook-plugin-update.md +62 -0
- hypermnesic-0.1.0/docs/handoff-macbook-prompt.md +126 -0
- hypermnesic-0.1.0/docs/handoffs/2026-06-02-companion-directory-publishing-U9-U10-handoff.md +122 -0
- hypermnesic-0.1.0/docs/ideation/2026-06-05-dreaming-mode-ideation.md +395 -0
- hypermnesic-0.1.0/docs/launch/CITATION.cff +44 -0
- hypermnesic-0.1.0/docs/launch/LICENSE-AGPL-3.0.txt +661 -0
- hypermnesic-0.1.0/docs/launch/directory-submission-prep.md +224 -0
- hypermnesic-0.1.0/docs/launch/discussions-roadmap-prep.md +175 -0
- hypermnesic-0.1.0/docs/launch/first-class-product-readiness-checklist.md +85 -0
- hypermnesic-0.1.0/docs/launch/launch-narrative-drafts.md +246 -0
- hypermnesic-0.1.0/docs/launch/launch-sequencing.md +64 -0
- hypermnesic-0.1.0/docs/launch/launch-week-response-slo.md +103 -0
- hypermnesic-0.1.0/docs/launch/mcp-registry-server.draft.json +23 -0
- hypermnesic-0.1.0/docs/launch/public-flip-runbook.md +170 -0
- hypermnesic-0.1.0/docs/launch/public-launch-checklist.md +108 -0
- hypermnesic-0.1.0/docs/launch/pypi-publication-decision.md +125 -0
- hypermnesic-0.1.0/docs/launch/v0.1.0-github-release-notes.md +36 -0
- hypermnesic-0.1.0/docs/oauth-as-finding.md +59 -0
- hypermnesic-0.1.0/docs/plans/2026-06-01-002-feat-retrieval-mrr-parity-plan.md +86 -0
- hypermnesic-0.1.0/docs/plans/2026-06-01-003-feat-phase01-followups-plan.md +302 -0
- hypermnesic-0.1.0/docs/plans/2026-06-01-004-feat-gate-surgical-scalar-set-plan.md +85 -0
- hypermnesic-0.1.0/docs/plans/2026-06-01-005-feat-phase2-human-surface-plan.md +731 -0
- hypermnesic-0.1.0/docs/plans/2026-06-02-006-feat-phase-2-5-engine-deployment-plan.md +331 -0
- hypermnesic-0.1.0/docs/plans/2026-06-02-007-feat-phase-2-5-obsidian-companion-plan.md +318 -0
- hypermnesic-0.1.0/docs/plans/2026-06-02-008-feat-longmemeval-benchmark-harness-plan.md +677 -0
- hypermnesic-0.1.0/docs/plans/2026-06-02-009-feat-companion-first-class-ui-plan.md +749 -0
- hypermnesic-0.1.0/docs/plans/2026-06-02-009-feat-gbrain-decommission-plan.md +1359 -0
- hypermnesic-0.1.0/docs/plans/2026-06-02-010-feat-companion-directory-publishing-plan.md +700 -0
- hypermnesic-0.1.0/docs/plans/2026-06-03-001-feat-unified-oauth-endpoint-and-setup-plan.md +569 -0
- hypermnesic-0.1.0/docs/plans/2026-06-03-001-fix-think-surface-quality-plan.md +258 -0
- hypermnesic-0.1.0/docs/plans/2026-06-03-002-feat-vault-folder-discovery-blocklist-write-plan.md +454 -0
- hypermnesic-0.1.0/docs/plans/2026-06-03-003-docs-first-class-documentation-readiness-plan.md +917 -0
- hypermnesic-0.1.0/docs/plans/2026-06-04-001-feat-local-first-value-proof-plan.md +429 -0
- hypermnesic-0.1.0/docs/plans/2026-06-04-002-feat-setup-doctor-status-plan.md +422 -0
- hypermnesic-0.1.0/docs/plans/2026-06-04-003-feat-memory-control-center-plan.md +497 -0
- hypermnesic-0.1.0/docs/plans/2026-06-04-004-feat-consent-client-trust-plan.md +456 -0
- hypermnesic-0.1.0/docs/plans/2026-06-04-005-feat-plugin-hook-observability-plan.md +410 -0
- hypermnesic-0.1.0/docs/plans/2026-06-04-006-feat-memory-taxonomy-agent-guidance-plan.md +388 -0
- hypermnesic-0.1.0/docs/plans/2026-06-04-007-feat-daily-human-workflows-plan.md +431 -0
- hypermnesic-0.1.0/docs/plans/2026-06-04-008-feat-product-proof-launch-readiness-plan.md +450 -0
- hypermnesic-0.1.0/docs/plans/2026-06-07-1521-ce-plan-incremental-doc-surface-invalidation.md +442 -0
- hypermnesic-0.1.0/docs/plans/2026-06-08-001-fix-dense-retrieval-repo-scoped-key-plan.md +986 -0
- hypermnesic-0.1.0/docs/plans/2026-06-12-001-feat-list-folders-agent-instructions-plan.md +331 -0
- hypermnesic-0.1.0/docs/plans/2026-06-15-001-feat-launch-demo-assets-plan.md +344 -0
- hypermnesic-0.1.0/docs/reference/cli.md +278 -0
- hypermnesic-0.1.0/docs/reference/configuration.md +98 -0
- hypermnesic-0.1.0/docs/reference/mcp-tools.md +126 -0
- hypermnesic-0.1.0/docs/reports/2026-06-04-hypermnesic-product-design-review.md +598 -0
- hypermnesic-0.1.0/docs/reports/public-launch-retro-template.md +56 -0
- hypermnesic-0.1.0/docs/solutions/design-patterns/surgical-scalar-set-frontmatter-byte-preservation.md +149 -0
- hypermnesic-0.1.0/docs/threat-model-commit-note.md +308 -0
- hypermnesic-0.1.0/docs/unified-oauth-mcp-deploy-runbook.md +136 -0
- hypermnesic-0.1.0/docs/why-hypermnesic.md +84 -0
- hypermnesic-0.1.0/harness/BENCHMARKS.md +398 -0
- hypermnesic-0.1.0/harness/PARITY_VERDICT.md +229 -0
- hypermnesic-0.1.0/harness/build_query_set.py +144 -0
- hypermnesic-0.1.0/harness/capture_gbrain_baseline.py +90 -0
- hypermnesic-0.1.0/harness/corpus_equivalence.py +95 -0
- hypermnesic-0.1.0/harness/dogfood_commit_note.py +76 -0
- hypermnesic-0.1.0/harness/gate_audit.py +132 -0
- hypermnesic-0.1.0/harness/judge_labels.py +227 -0
- hypermnesic-0.1.0/harness/label_review.py +175 -0
- hypermnesic-0.1.0/harness/longmemeval/__init__.py +15 -0
- hypermnesic-0.1.0/harness/longmemeval/adapter.py +258 -0
- hypermnesic-0.1.0/harness/longmemeval/batch.py +91 -0
- hypermnesic-0.1.0/harness/longmemeval/diagnostic.py +250 -0
- hypermnesic-0.1.0/harness/longmemeval/judge.py +172 -0
- hypermnesic-0.1.0/harness/longmemeval/manifest.json +36 -0
- hypermnesic-0.1.0/harness/longmemeval/manifest.py +228 -0
- hypermnesic-0.1.0/harness/longmemeval/materialize.py +228 -0
- hypermnesic-0.1.0/harness/longmemeval/qa.py +297 -0
- hypermnesic-0.1.0/harness/longmemeval/reader.py +176 -0
- hypermnesic-0.1.0/harness/longmemeval/smoke.example.jsonl +5 -0
- hypermnesic-0.1.0/harness/parity_harness.py +303 -0
- hypermnesic-0.1.0/harness/portability_probe.py +134 -0
- hypermnesic-0.1.0/harness/queries.example.jsonl +3 -0
- hypermnesic-0.1.0/implementation-notes.md +452 -0
- hypermnesic-0.1.0/media/.review-log.md +25 -0
- hypermnesic-0.1.0/media/README.md +83 -0
- hypermnesic-0.1.0/media/companion/.gitkeep +1 -0
- hypermnesic-0.1.0/media/companion/RECORDING.md +78 -0
- hypermnesic-0.1.0/media/companion/demo-vault-seed/daily/2026-06-10.md +13 -0
- hypermnesic-0.1.0/media/companion/demo-vault-seed/daily/2026-06-11.md +13 -0
- hypermnesic-0.1.0/media/companion/demo-vault-seed/daily/2026-06-12.md +12 -0
- hypermnesic-0.1.0/media/companion/demo-vault-seed/ideas/evergreen-notes.md +13 -0
- hypermnesic-0.1.0/media/companion/demo-vault-seed/ideas/second-brain.md +14 -0
- hypermnesic-0.1.0/media/companion/demo-vault-seed/ideas/spaced-repetition.md +14 -0
- hypermnesic-0.1.0/media/companion/demo-vault-seed/people/alex-rivera.md +13 -0
- hypermnesic-0.1.0/media/companion/demo-vault-seed/people/priya-nair.md +12 -0
- hypermnesic-0.1.0/media/companion/demo-vault-seed/projects/garden-redesign.md +13 -0
- hypermnesic-0.1.0/media/companion/demo-vault-seed/projects/reading-system.md +13 -0
- hypermnesic-0.1.0/media/engine/.gitkeep +1 -0
- hypermnesic-0.1.0/media/engine/benchmark-data.md +38 -0
- hypermnesic-0.1.0/media/engine/benchmark-longmemeval.svg +91 -0
- hypermnesic-0.1.0/media/engine/carousel-hn/01-agent-writes.png +0 -0
- hypermnesic-0.1.0/media/engine/carousel-hn/02-real-commit.png +0 -0
- hypermnesic-0.1.0/media/engine/carousel-hn/03-fresh-recall.png +0 -0
- hypermnesic-0.1.0/media/engine/carousel-hn/captions.md +15 -0
- hypermnesic-0.1.0/media/engine/carousel-localllama/01-one-endpoint.png +0 -0
- hypermnesic-0.1.0/media/engine/carousel-localllama/02-real-commit.png +0 -0
- hypermnesic-0.1.0/media/engine/carousel-localllama/03-grounded-recall.png +0 -0
- hypermnesic-0.1.0/media/engine/carousel-localllama/captions.md +13 -0
- hypermnesic-0.1.0/media/engine/carousel-selfhosted/01-local-files.png +0 -0
- hypermnesic-0.1.0/media/engine/carousel-selfhosted/02-plain-markdown.png +0 -0
- hypermnesic-0.1.0/media/engine/carousel-selfhosted/03-real-git.png +0 -0
- hypermnesic-0.1.0/media/engine/carousel-selfhosted/captions.md +14 -0
- hypermnesic-0.1.0/media/engine/connector-montage/README.md +27 -0
- hypermnesic-0.1.0/media/engine/connector-montage/claude-code.mcp.json +8 -0
- hypermnesic-0.1.0/media/engine/connector-montage/connectors.md +36 -0
- hypermnesic-0.1.0/media/engine/connector-montage/one-endpoint-many-clients.png +0 -0
- hypermnesic-0.1.0/media/engine/connector-montage/one-endpoint-many-clients.svg +62 -0
- hypermnesic-0.1.0/media/engine/demo-vault-seed/decisions/use-sqlite-vec.md +17 -0
- hypermnesic-0.1.0/media/engine/demo-vault-seed/people/dana-ops.md +14 -0
- hypermnesic-0.1.0/media/engine/demo-vault-seed/people/sam-dx.md +13 -0
- hypermnesic-0.1.0/media/engine/demo-vault-seed/projects/atlas-search.md +17 -0
- hypermnesic-0.1.0/media/engine/demo-vault-seed/projects/launch-receipts.md +15 -0
- hypermnesic-0.1.0/media/engine/hero-receipt-loop.gif +0 -0
- hypermnesic-0.1.0/media/engine/hero-receipt-loop.tape +70 -0
- hypermnesic-0.1.0/media/engine/hero_commit.py +85 -0
- hypermnesic-0.1.0/media/engine/index-recovery.gif +0 -0
- hypermnesic-0.1.0/media/engine/index-recovery.tape +65 -0
- hypermnesic-0.1.0/media/engine/materialize-demo-vault +62 -0
- hypermnesic-0.1.0/obsidian-plugin/README.md +24 -0
- hypermnesic-0.1.0/plugin/.claude-plugin/marketplace.json +25 -0
- hypermnesic-0.1.0/plugin/README.md +138 -0
- hypermnesic-0.1.0/plugin/hermes/README.md +66 -0
- hypermnesic-0.1.0/plugin/hermes/__init__.py +121 -0
- hypermnesic-0.1.0/plugin/hermes/flat-skill/hypermnesic-memory/SKILL.md +70 -0
- hypermnesic-0.1.0/plugin/hermes/plugin.yaml +9 -0
- hypermnesic-0.1.0/plugin/hermes/skills/hypermnesic-memory/SKILL.md +70 -0
- hypermnesic-0.1.0/plugin/plugins/hypermnesic/.claude-plugin/plugin.json +11 -0
- hypermnesic-0.1.0/plugin/plugins/hypermnesic/.codex-plugin/plugin.json +14 -0
- hypermnesic-0.1.0/plugin/plugins/hypermnesic/.mcp.json +8 -0
- hypermnesic-0.1.0/plugin/plugins/hypermnesic/hooks/hooks.json +16 -0
- hypermnesic-0.1.0/plugin/plugins/hypermnesic/hooks/scripts/hypermnesic_agent_hook.py +177 -0
- hypermnesic-0.1.0/plugin/plugins/hypermnesic/hooks/scripts/hypermnesic_hook_status.py +293 -0
- hypermnesic-0.1.0/plugin/plugins/hypermnesic/skills/hypermnesic-memory/SKILL.md +125 -0
- hypermnesic-0.1.0/pyproject.toml +60 -0
- hypermnesic-0.1.0/scripts/check_version_consistency.py +153 -0
- hypermnesic-0.1.0/scripts/license_scan.py +169 -0
- hypermnesic-0.1.0/scripts/preflight_public_scan.py +191 -0
- hypermnesic-0.1.0/scripts/product_smoke.py +165 -0
- hypermnesic-0.1.0/src/hypermnesic/__init__.py +11 -0
- hypermnesic-0.1.0/src/hypermnesic/audit_log.py +125 -0
- hypermnesic-0.1.0/src/hypermnesic/auth.py +224 -0
- hypermnesic-0.1.0/src/hypermnesic/auth_cloud.py +551 -0
- hypermnesic-0.1.0/src/hypermnesic/capture.py +96 -0
- hypermnesic-0.1.0/src/hypermnesic/cli.py +1102 -0
- hypermnesic-0.1.0/src/hypermnesic/client_control.py +127 -0
- hypermnesic-0.1.0/src/hypermnesic/client_guidance.py +66 -0
- hypermnesic-0.1.0/src/hypermnesic/commit_note.py +293 -0
- hypermnesic-0.1.0/src/hypermnesic/config.py +158 -0
- hypermnesic-0.1.0/src/hypermnesic/connect.py +101 -0
- hypermnesic-0.1.0/src/hypermnesic/converge.py +176 -0
- hypermnesic-0.1.0/src/hypermnesic/daily_review.py +150 -0
- hypermnesic-0.1.0/src/hypermnesic/doctor.py +448 -0
- hypermnesic-0.1.0/src/hypermnesic/embed.py +109 -0
- hypermnesic-0.1.0/src/hypermnesic/expand.py +62 -0
- hypermnesic-0.1.0/src/hypermnesic/folders.py +151 -0
- hypermnesic-0.1.0/src/hypermnesic/frontmatter_gate.py +171 -0
- hypermnesic-0.1.0/src/hypermnesic/generated.py +39 -0
- hypermnesic-0.1.0/src/hypermnesic/graph.py +121 -0
- hypermnesic-0.1.0/src/hypermnesic/index.py +767 -0
- hypermnesic-0.1.0/src/hypermnesic/ingest.py +195 -0
- hypermnesic-0.1.0/src/hypermnesic/install.py +663 -0
- hypermnesic-0.1.0/src/hypermnesic/local_proof.py +320 -0
- hypermnesic-0.1.0/src/hypermnesic/mcp_server.py +864 -0
- hypermnesic-0.1.0/src/hypermnesic/memory_control.py +337 -0
- hypermnesic-0.1.0/src/hypermnesic/nav_surface.py +105 -0
- hypermnesic-0.1.0/src/hypermnesic/propose.py +306 -0
- hypermnesic-0.1.0/src/hypermnesic/retrieve.py +219 -0
- hypermnesic-0.1.0/src/hypermnesic/salience.py +169 -0
- hypermnesic-0.1.0/src/hypermnesic/serialize.py +272 -0
- hypermnesic-0.1.0/src/hypermnesic/sidecar.py +230 -0
- hypermnesic-0.1.0/src/hypermnesic/think.py +197 -0
- hypermnesic-0.1.0/tests/conftest.py +86 -0
- hypermnesic-0.1.0/tests/test_audit_log.py +78 -0
- hypermnesic-0.1.0/tests/test_auth.py +162 -0
- hypermnesic-0.1.0/tests/test_auth_cloud.py +831 -0
- hypermnesic-0.1.0/tests/test_blocklist_write_gate.py +44 -0
- hypermnesic-0.1.0/tests/test_capture.py +149 -0
- hypermnesic-0.1.0/tests/test_cli.py +748 -0
- hypermnesic-0.1.0/tests/test_client_control.py +58 -0
- hypermnesic-0.1.0/tests/test_client_guidance.py +35 -0
- hypermnesic-0.1.0/tests/test_commit_note.py +303 -0
- hypermnesic-0.1.0/tests/test_config.py +227 -0
- hypermnesic-0.1.0/tests/test_connect.py +120 -0
- hypermnesic-0.1.0/tests/test_converge.py +326 -0
- hypermnesic-0.1.0/tests/test_corpus_equivalence.py +54 -0
- hypermnesic-0.1.0/tests/test_daily_review.py +95 -0
- hypermnesic-0.1.0/tests/test_doctor.py +368 -0
- hypermnesic-0.1.0/tests/test_dogfood.py +50 -0
- hypermnesic-0.1.0/tests/test_embed_stale.py +149 -0
- hypermnesic-0.1.0/tests/test_expand.py +45 -0
- hypermnesic-0.1.0/tests/test_folders.py +163 -0
- hypermnesic-0.1.0/tests/test_frontmatter_gate.py +126 -0
- hypermnesic-0.1.0/tests/test_gate_audit.py +30 -0
- hypermnesic-0.1.0/tests/test_graph.py +101 -0
- hypermnesic-0.1.0/tests/test_hermes_plugin.py +187 -0
- hypermnesic-0.1.0/tests/test_hermes_plugin_hook.py +135 -0
- hypermnesic-0.1.0/tests/test_index.py +352 -0
- hypermnesic-0.1.0/tests/test_index_projection.py +81 -0
- hypermnesic-0.1.0/tests/test_install.py +533 -0
- hypermnesic-0.1.0/tests/test_judge_labels.py +84 -0
- hypermnesic-0.1.0/tests/test_label_review.py +63 -0
- hypermnesic-0.1.0/tests/test_license_scan.py +85 -0
- hypermnesic-0.1.0/tests/test_local_proof.py +230 -0
- hypermnesic-0.1.0/tests/test_longmemeval_harness.py +1080 -0
- hypermnesic-0.1.0/tests/test_mcp_server.py +854 -0
- hypermnesic-0.1.0/tests/test_memory_control.py +215 -0
- hypermnesic-0.1.0/tests/test_nav_surface.py +127 -0
- hypermnesic-0.1.0/tests/test_parity_harness.py +187 -0
- hypermnesic-0.1.0/tests/test_plugin.py +238 -0
- hypermnesic-0.1.0/tests/test_plugin_hook.py +390 -0
- hypermnesic-0.1.0/tests/test_portability_probe.py +91 -0
- hypermnesic-0.1.0/tests/test_preflight_public_scan.py +208 -0
- hypermnesic-0.1.0/tests/test_product_readiness_docs.py +85 -0
- hypermnesic-0.1.0/tests/test_product_remote_smoke.py +179 -0
- hypermnesic-0.1.0/tests/test_propose.py +267 -0
- hypermnesic-0.1.0/tests/test_reindex_isolated.py +89 -0
- hypermnesic-0.1.0/tests/test_rename.py +182 -0
- hypermnesic-0.1.0/tests/test_retrieve.py +367 -0
- hypermnesic-0.1.0/tests/test_salience.py +163 -0
- hypermnesic-0.1.0/tests/test_serialize.py +200 -0
- hypermnesic-0.1.0/tests/test_sidecar.py +147 -0
- hypermnesic-0.1.0/tests/test_smoke.py +85 -0
- hypermnesic-0.1.0/tests/test_think.py +361 -0
- hypermnesic-0.1.0/tests/test_version_consistency.py +70 -0
- hypermnesic-0.1.0/uv.lock +3416 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
|
3
|
+
"name": "hypermnesic",
|
|
4
|
+
"metadata": {
|
|
5
|
+
"description": "hypermnesic — the git-native memory layer. A skillset + a lightweight auto-recall hook + a self-hosted tailnet MCP, so coding agents reach durable memory by default."
|
|
6
|
+
},
|
|
7
|
+
"owner": {
|
|
8
|
+
"name": "Leonard Sellem",
|
|
9
|
+
"email": "leonard@sellem.me"
|
|
10
|
+
},
|
|
11
|
+
"plugins": [
|
|
12
|
+
{
|
|
13
|
+
"name": "hypermnesic",
|
|
14
|
+
"source": "./plugin/plugins/hypermnesic",
|
|
15
|
+
"category": "productivity",
|
|
16
|
+
"tags": ["memory", "knowledge", "mcp", "search", "git", "tailnet"]
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Copy to .env (gitignored) and fill in. All secrets are read from the environment /
|
|
2
|
+
# this file only — never written to the index, audit log, or any structured output
|
|
3
|
+
# (credential discipline). Leave a var empty to disable that path. NEVER commit real
|
|
4
|
+
# values. See docs/reference/configuration.md.
|
|
5
|
+
|
|
6
|
+
# --- Embeddings (required for dense retrieval) ------------------------------------
|
|
7
|
+
# The OpenAI API key for text-embedding-3-large. Without it, retrieval degrades to
|
|
8
|
+
# lexical-only (and the test suite runs in exactly that offline mode).
|
|
9
|
+
OPENAI_API_KEY=
|
|
10
|
+
|
|
11
|
+
# --- Remote client wiring (Claude Code / Codex plugin) ----------------------------
|
|
12
|
+
# Point the plugin at YOUR hypermnesic endpoint, e.g. https://YOUR-HOST.ts.net/mcp .
|
|
13
|
+
# The bundled .mcp.json templates the URL from this var; OAuth is via browser
|
|
14
|
+
# discovery, so the MCP wiring itself needs no token.
|
|
15
|
+
HYPERMNESIC_MCP_URL=
|
|
16
|
+
|
|
17
|
+
# --- Auto-recall hook on a remote device (optional) -------------------------------
|
|
18
|
+
# The per-prompt recall hook reads this bearer token for its bounded read on a remote
|
|
19
|
+
# (non-tailnet) device. Leave empty to use the tailnet read route instead.
|
|
20
|
+
HYPERMNESIC_MCP_TOKEN=
|
|
21
|
+
|
|
22
|
+
# --- Public cloud endpoint operator (serve-cloud / setup) -------------------------
|
|
23
|
+
# The operator approval token that gates every public connection. Read from the
|
|
24
|
+
# environment ONLY (never a CLI flag — it would leak via the process table / logs).
|
|
25
|
+
# Generate one with: python -c "import secrets; print(secrets.token_urlsafe(32))"
|
|
26
|
+
HYPERMNESIC_CLOUD_APPROVAL_TOKEN=
|
|
27
|
+
|
|
28
|
+
# Optional: scopes requested by default when a dynamic OAuth client omits scope.
|
|
29
|
+
# Default is read. Use read,write when you want new connector approvals to ask for
|
|
30
|
+
# both read access and commit_note write access on the consent screen.
|
|
31
|
+
HYPERMNESIC_DEFAULT_CLIENT_SCOPES=read
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Code owners — review routing. The owner is requested for review on any change to
|
|
2
|
+
# these paths. Security-sensitive surfaces (auth, the MCP server, the write path, the
|
|
3
|
+
# protected-path/governance guard) and the security/license docs route here.
|
|
4
|
+
|
|
5
|
+
# Default owner for everything.
|
|
6
|
+
* @leonardsellem
|
|
7
|
+
|
|
8
|
+
# Security-sensitive engine surfaces.
|
|
9
|
+
/src/hypermnesic/auth.py @leonardsellem
|
|
10
|
+
/src/hypermnesic/auth_cloud.py @leonardsellem
|
|
11
|
+
/src/hypermnesic/mcp_server.py @leonardsellem
|
|
12
|
+
/src/hypermnesic/commit_note.py @leonardsellem
|
|
13
|
+
/src/hypermnesic/serialize.py @leonardsellem
|
|
14
|
+
/src/hypermnesic/frontmatter_gate.py @leonardsellem
|
|
15
|
+
/src/hypermnesic/audit_log.py @leonardsellem
|
|
16
|
+
|
|
17
|
+
# Security, license, and contribution policy.
|
|
18
|
+
/SECURITY.md @leonardsellem
|
|
19
|
+
/LICENSE @leonardsellem
|
|
20
|
+
/CONTRIBUTING.md @leonardsellem
|
|
21
|
+
/docs/threat-model-commit-note.md @leonardsellem
|
|
22
|
+
/docs/launch/ @leonardsellem
|
|
23
|
+
/scripts/license_scan.py @leonardsellem
|
|
24
|
+
/scripts/preflight_public_scan.py @leonardsellem
|
|
25
|
+
/.github/ @leonardsellem
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report something that isn't working as documented
|
|
4
|
+
title: "[bug] "
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ""
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What happened
|
|
10
|
+
|
|
11
|
+
A clear description of the bug and what you expected instead.
|
|
12
|
+
|
|
13
|
+
## Steps to reproduce
|
|
14
|
+
|
|
15
|
+
1. …
|
|
16
|
+
2. …
|
|
17
|
+
|
|
18
|
+
## Deployment shape
|
|
19
|
+
|
|
20
|
+
Help us reproduce — hypermnesic's behavior depends on how it's deployed:
|
|
21
|
+
|
|
22
|
+
- **hypermnesic version:** (`hypermnesic --version`)
|
|
23
|
+
- **How you're running it:** self-hosted endpoint / local CLI only / plugin client
|
|
24
|
+
- **Engine host OS:** (e.g. Ubuntu 24.04, macOS 14)
|
|
25
|
+
- **Client:** (Claude / ChatGPT connector, Claude Code plugin, Codex, Obsidian companion, CLI)
|
|
26
|
+
- **Vault size:** approximate number of markdown files
|
|
27
|
+
- **Serving lane:** unified public OAuth `/mcp` (Funnel) / tailnet read companion (`:8848`) / local CLI
|
|
28
|
+
- **Tailscale / Funnel state:** (e.g. `tailscale status` healthy? Funnel configured?)
|
|
29
|
+
- **Embeddings:** `OPENAI_API_KEY` set, or running lexical-only / degraded?
|
|
30
|
+
|
|
31
|
+
## Logs / output
|
|
32
|
+
|
|
33
|
+
Paste relevant output. **Redact any tokens, hostnames, or IPs** — never paste secrets.
|
|
34
|
+
|
|
35
|
+
## Additional context
|
|
36
|
+
|
|
37
|
+
Anything else that might help.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: true
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Security vulnerability
|
|
4
|
+
url: https://github.com/leonardsellem/hypermnesic/security/advisories/new
|
|
5
|
+
about: Do NOT open a public issue for security problems. Report privately — see SECURITY.md.
|
|
6
|
+
- name: Question / discussion
|
|
7
|
+
url: https://github.com/leonardsellem/hypermnesic/discussions
|
|
8
|
+
about: For questions and open-ended discussion rather than a specific bug or feature.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an improvement or new capability
|
|
4
|
+
title: "[feature] "
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ""
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem / motivation
|
|
10
|
+
|
|
11
|
+
What are you trying to do that hypermnesic doesn't support today? What's the
|
|
12
|
+
underlying need (not just the proposed solution)?
|
|
13
|
+
|
|
14
|
+
## Proposed solution
|
|
15
|
+
|
|
16
|
+
What you'd like to see. If it touches the retrieval engine, the write path, the
|
|
17
|
+
serving topology, or the plugin/companion, say which.
|
|
18
|
+
|
|
19
|
+
## Alternatives considered
|
|
20
|
+
|
|
21
|
+
Other approaches you've thought about, and why they fall short.
|
|
22
|
+
|
|
23
|
+
## Fit with the project's identity
|
|
24
|
+
|
|
25
|
+
hypermnesic is a git-first, files-are-truth memory layer with a disposable index.
|
|
26
|
+
Does this proposal keep that invariant? (See [`ARCHITECTURE.md`](../../ARCHITECTURE.md)
|
|
27
|
+
and [`docs/why-hypermnesic.md`](../../docs/why-hypermnesic.md).)
|
|
28
|
+
|
|
29
|
+
## Additional context
|
|
30
|
+
|
|
31
|
+
Anything else — links, examples, prior art.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!-- Thanks for contributing! Keep PRs focused. See CONTRIBUTING.md and AGENTS.md. -->
|
|
2
|
+
|
|
3
|
+
## What & why
|
|
4
|
+
|
|
5
|
+
Briefly describe the change and the problem it solves. Link any issue or plan
|
|
6
|
+
(`docs/plans/…`).
|
|
7
|
+
|
|
8
|
+
## Gates (must pass — same as CI's `lint-test-license` job)
|
|
9
|
+
|
|
10
|
+
- [ ] `uv run ruff check .`
|
|
11
|
+
- [ ] `uv run python scripts/check_version_consistency.py`
|
|
12
|
+
- [ ] `uv run pytest` (new behavior is covered by a test — test-first)
|
|
13
|
+
- [ ] `uv run python scripts/license_scan.py` (no new AGPL/GPL/SSPL dependency)
|
|
14
|
+
- [ ] `uv run python scripts/preflight_public_scan.py` (no operator host/IP/token/secret added)
|
|
15
|
+
|
|
16
|
+
## Security surface
|
|
17
|
+
|
|
18
|
+
- [ ] This PR does **not** touch auth (`src/hypermnesic/auth*.py`), the MCP server,
|
|
19
|
+
the write path (`commit_note` / `serialize` / `frontmatter_gate`), or the
|
|
20
|
+
protected-path / governance guard.
|
|
21
|
+
- [ ] If it does: I referenced the relevant `SECURITY.md` / threat-model entry, and a
|
|
22
|
+
CODEOWNER review is requested.
|
|
23
|
+
|
|
24
|
+
## Docs
|
|
25
|
+
|
|
26
|
+
- [ ] User-facing changes are reflected in the docs (README / references / guides /
|
|
27
|
+
`CHANGELOG.md`), and any tool/CLI/config surface change updates the matching
|
|
28
|
+
reference doc.
|
|
29
|
+
|
|
30
|
+
## Sign-off
|
|
31
|
+
|
|
32
|
+
- [ ] My commits are signed off (`git commit -s`) per the DCO (see `CONTRIBUTING.md`).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
lint-test-license:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- name: Install uv
|
|
14
|
+
uses: astral-sh/setup-uv@v5
|
|
15
|
+
- name: Sync (dev extras)
|
|
16
|
+
run: uv sync --extra dev
|
|
17
|
+
- name: Ruff
|
|
18
|
+
run: uv run ruff check .
|
|
19
|
+
- name: Version consistency (pyproject ↔ manifests ↔ __init__)
|
|
20
|
+
run: uv run python scripts/check_version_consistency.py
|
|
21
|
+
- name: Tests
|
|
22
|
+
run: uv run pytest
|
|
23
|
+
- name: License gate (zero AGPL/GPL/SSPL)
|
|
24
|
+
run: uv run python scripts/license_scan.py
|
|
25
|
+
- name: Preflight public scan (no operator secret/host in the to-be-public surface)
|
|
26
|
+
run: uv run python scripts/preflight_public_scan.py
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
# Publish the hypermnesic engine to PyPI via OIDC Trusted Publishing.
|
|
4
|
+
#
|
|
5
|
+
# Trusted Publishing exchanges a short-lived GitHub OIDC token for a PyPI upload
|
|
6
|
+
# token at run time — there is NO long-lived PyPI API token stored in repo secrets
|
|
7
|
+
# (honours the "never echo secrets" rule in AGENTS.md / CONTRIBUTING.md).
|
|
8
|
+
#
|
|
9
|
+
# One-time operator setup (see PR / LS-1684) before this can publish:
|
|
10
|
+
# 1. Create the `hypermnesic` project on PyPI, OR add a *pending* Trusted Publisher.
|
|
11
|
+
# 2. On PyPI → project → Publishing, add a Trusted Publisher with:
|
|
12
|
+
# owner = leonardsellem
|
|
13
|
+
# repository = hypermnesic
|
|
14
|
+
# workflow = release.yml
|
|
15
|
+
# environment = pypi (must match the `environment:` below)
|
|
16
|
+
# 3. First publish: push a version tag (e.g. `v0.1.0`) or run this workflow via
|
|
17
|
+
# "Run workflow" (workflow_dispatch). The build version comes from pyproject.
|
|
18
|
+
|
|
19
|
+
on:
|
|
20
|
+
push:
|
|
21
|
+
tags:
|
|
22
|
+
- "v*.*.*"
|
|
23
|
+
workflow_dispatch:
|
|
24
|
+
|
|
25
|
+
permissions:
|
|
26
|
+
contents: read
|
|
27
|
+
|
|
28
|
+
jobs:
|
|
29
|
+
build:
|
|
30
|
+
name: Build sdist + wheel
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
|
|
35
|
+
- name: Install uv
|
|
36
|
+
uses: astral-sh/setup-uv@v5
|
|
37
|
+
|
|
38
|
+
- name: Verify version consistency (pyproject ↔ manifests ↔ __init__)
|
|
39
|
+
run: uv run python scripts/check_version_consistency.py
|
|
40
|
+
|
|
41
|
+
- name: Build distributions
|
|
42
|
+
run: uv build
|
|
43
|
+
|
|
44
|
+
- name: Upload dist artifact
|
|
45
|
+
uses: actions/upload-artifact@v4
|
|
46
|
+
with:
|
|
47
|
+
name: dist
|
|
48
|
+
path: dist/
|
|
49
|
+
if-no-files-found: error
|
|
50
|
+
|
|
51
|
+
publish:
|
|
52
|
+
name: Publish to PyPI (Trusted Publishing)
|
|
53
|
+
needs: build
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
environment:
|
|
56
|
+
name: pypi
|
|
57
|
+
url: https://pypi.org/p/hypermnesic
|
|
58
|
+
permissions:
|
|
59
|
+
id-token: write # OIDC token for Trusted Publishing — no stored API token
|
|
60
|
+
steps:
|
|
61
|
+
- name: Download dist artifact
|
|
62
|
+
uses: actions/download-artifact@v4
|
|
63
|
+
with:
|
|
64
|
+
name: dist
|
|
65
|
+
path: dist/
|
|
66
|
+
|
|
67
|
+
- name: Publish to PyPI
|
|
68
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# hypermnesic engine state (disposable, rebuildable index) — never tracked.
|
|
2
|
+
.hypermnesic/
|
|
3
|
+
|
|
4
|
+
# Secrets — the OpenAI key lives in .env (env/secrets only; never committed).
|
|
5
|
+
.env
|
|
6
|
+
.env.*
|
|
7
|
+
!.env.example
|
|
8
|
+
|
|
9
|
+
# Python
|
|
10
|
+
__pycache__/
|
|
11
|
+
*.py[cod]
|
|
12
|
+
.venv/
|
|
13
|
+
venv/
|
|
14
|
+
*.egg-info/
|
|
15
|
+
dist/
|
|
16
|
+
build/
|
|
17
|
+
|
|
18
|
+
# Corpus-derived evaluation data — NEVER committed. These are generated locally
|
|
19
|
+
# by the harness tools over a private corpus and may contain real names, paths,
|
|
20
|
+
# and queries. The repo ships only the generic tooling + a synthetic example.
|
|
21
|
+
harness/queries.frozen.jsonl
|
|
22
|
+
harness/gbrain_baseline.frozen.jsonl
|
|
23
|
+
harness/results/
|
|
24
|
+
harness/review*.md
|
|
25
|
+
|
|
26
|
+
# LongMemEval harness — the downloaded dataset (referenced by hash, never
|
|
27
|
+
# committed: ~GBs + contamination, R15) and all generated artifacts. The repo
|
|
28
|
+
# ships only the tooling, the committed manifest, the synthetic smoke subset, and
|
|
29
|
+
# aggregate/per-ability results in harness/BENCHMARKS.md.
|
|
30
|
+
harness/longmemeval/longmemeval_*.json
|
|
31
|
+
harness/longmemeval/corpus/
|
|
32
|
+
harness/longmemeval/results/
|
|
33
|
+
harness/longmemeval/*.frozen.jsonl
|
|
34
|
+
harness/longmemeval/.embed_cache.sqlite
|
|
35
|
+
|
|
36
|
+
# Local index / scratch artifacts
|
|
37
|
+
*.db
|
|
38
|
+
*.sqlite
|
|
39
|
+
*.sqlite3
|
|
40
|
+
.pytest_cache/
|
|
41
|
+
.ruff_cache/
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Linear Task Creation
|
|
4
|
+
|
|
5
|
+
Every Linear task or subtask created by an agent must be fully documented at creation time with a state-of-the-art description: context, intent, acceptance criteria, validation plan, and handoff/deployment notes when relevant.
|
|
6
|
+
|
|
7
|
+
Required creation metadata is non-negotiable: effort estimate, priority, and dependency relations (`blockedBy` / `blocks`) mapped from the plan, parent issue, or nearest sibling. If a connector cannot set one of those fields during creation, state the gap immediately and fill it through the next available Linear surface before handoff.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
Contract for AI coding agents (Claude Code, Codex, and similar) working in this
|
|
11
|
+
repository. Humans: see [`CONTRIBUTING.md`](CONTRIBUTING.md) — the two are consistent;
|
|
12
|
+
this file states the parts an autonomous agent most needs up front.
|
|
13
|
+
|
|
14
|
+
> [`CLAUDE.md`](CLAUDE.md) is a **symlink to this file** — the two are one document, not
|
|
15
|
+
> two. Edit `AGENTS.md`; the mirror follows. (These governance files are themselves
|
|
16
|
+
> protected by the write guard — they are **refused** by the `commit_note` memory write
|
|
17
|
+
> path and can only be changed in an ordinary, reviewed PR.)
|
|
18
|
+
|
|
19
|
+
## The prime invariant
|
|
20
|
+
|
|
21
|
+
**Files are the source of truth; the index is a disposable, rebuildable projection of
|
|
22
|
+
the git tree.** Never treat the index as a database of record. A reindex must never be
|
|
23
|
+
able to lose a committed write. Everything in [`ARCHITECTURE.md`](ARCHITECTURE.md)
|
|
24
|
+
follows from this one line.
|
|
25
|
+
|
|
26
|
+
## Repo map — where things live
|
|
27
|
+
|
|
28
|
+
| Area | Path | What it is |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| Engine source | `src/hypermnesic/` | The Python package (details below) |
|
|
31
|
+
| Retrieval | `retrieve.py`, `index.py`, `embed.py`, `graph.py`, `converge.py` | Hybrid FTS5 + sqlite-vec search; read-time convergence |
|
|
32
|
+
| Write path | `commit_note.py`, `serialize.py`, `frontmatter_gate.py`, `audit_log.py` | The one git-first write, its guards, its gate, its log |
|
|
33
|
+
| Serving | `mcp_server.py`, `auth.py`, `auth_cloud.py` | Public OAuth `/mcp` + tailnet read companion |
|
|
34
|
+
| Local surface | `cli.py` | The engine-host-local `hypermnesic` CLI |
|
|
35
|
+
| Provisioning / config | `install.py`, `connect.py`, `config.py` | Roles, setup, env-driven config |
|
|
36
|
+
| Human surfaces | `capture.py`, `salience.py`, `nav_surface.py`, `think.py`, `propose.py`, `expand.py`, `sidecar.py`, `folders.py`, `generated.py` | Capture/triage, digest, navigation, thinking-mode, sidecar extraction |
|
|
37
|
+
| Tests | `tests/` | `pytest`, `--import-mode=importlib` |
|
|
38
|
+
| Gate scripts | `scripts/` | `check_version_consistency.py`, `license_scan.py`, `preflight_public_scan.py` |
|
|
39
|
+
| Plugin | `plugin/` | Claude Code / Codex plugin (OAuth-discovery, distribution-generic) |
|
|
40
|
+
| Companion | `obsidian-plugin/` | Read-only Obsidian companion (ships from a **separate** GPL-3.0 repo) |
|
|
41
|
+
| Benchmarks | `harness/` | LongMemEval harness + `harness/BENCHMARKS.md` |
|
|
42
|
+
| Docs | `docs/` | Start at [`docs/README.md`](docs/README.md) — it pins current truth |
|
|
43
|
+
|
|
44
|
+
## Build, test, and gates
|
|
45
|
+
|
|
46
|
+
Python ≥ 3.11, [uv](https://docs.astral.sh/uv/) for dependencies. The full gate set —
|
|
47
|
+
identical to CI's single `lint-test-license` job — is:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
uv sync --extra dev
|
|
51
|
+
uv run ruff check . # lint (line-length 100; E,F,I,UP,B)
|
|
52
|
+
uv run python scripts/check_version_consistency.py # pyproject ↔ manifests ↔ __init__
|
|
53
|
+
uv run pytest # full suite (offline, deterministic)
|
|
54
|
+
uv run python scripts/license_scan.py # zero AGPL/GPL/SSPL *dependency* gate
|
|
55
|
+
uv run python scripts/preflight_public_scan.py # no operator secret/host in the public surface
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
All six must pass before a change is done. The suite runs offline and deterministic
|
|
59
|
+
(the OpenAI key is neutralized in tests; dense retrieval degrades to lexical).
|
|
60
|
+
|
|
61
|
+
## Working rules
|
|
62
|
+
|
|
63
|
+
- **Test-first.** No new production behavior without a failing test first. Tests live
|
|
64
|
+
in `tests/`, run with `--import-mode=importlib`.
|
|
65
|
+
- **No "pre-existing" failures.** A red test is either fixed in your change or filed as a
|
|
66
|
+
tracked issue — never dismissed or deleted.
|
|
67
|
+
- **Branch off `main`; never commit to `main` directly.** Use a worktree per task when
|
|
68
|
+
changes could conflict. Commit per logical unit with a conventional subject and a
|
|
69
|
+
`Signed-off-by:` DCO line (`git commit -s`).
|
|
70
|
+
- **Permissive dependencies only.** Any new dependency must keep
|
|
71
|
+
`scripts/license_scan.py` green (zero AGPL/GPL/SSPL). The gate is dependency-scoped;
|
|
72
|
+
it does not constrain the engine's own (planned-AGPL) license.
|
|
73
|
+
- **Never echo secrets.** The OpenAI key, OAuth consent secret, and tokens are read
|
|
74
|
+
from the environment / a gitignored `.env` only — never written to the index, the
|
|
75
|
+
audit log, any output, or chat. `scripts/preflight_public_scan.py` enforces that no
|
|
76
|
+
operator host/IP/token ships in the public surface — so **use placeholders**
|
|
77
|
+
(`<your-host>.ts.net`, the `100.64.0.0/10` CGNAT range), never real operator values,
|
|
78
|
+
in any doc or fixture.
|
|
79
|
+
- **Respect the write guard.** The write path (`commit_note`) is git-first and bounded
|
|
80
|
+
by a blocklist (protected-path + governance-file fence). Do not weaken it; changes to
|
|
81
|
+
`serialize.py` / `frontmatter_gate.py` / `auth*.py` / `mcp_server.py` are
|
|
82
|
+
security-sensitive (CODEOWNERS-routed) and must cite [`SECURITY.md`](SECURITY.md) and
|
|
83
|
+
the threat model.
|
|
84
|
+
- **Native primitives first.** Before adding any adapter, wrapper, shell-out, or
|
|
85
|
+
parser, check whether an upstream tool (the MCP SDK, Tailscale, OAuth libs, uv) already
|
|
86
|
+
exposes the primitive. Prefer it over re-inventing it.
|
|
87
|
+
|
|
88
|
+
## Documentation must not drift — NON-NEGOTIABLE
|
|
89
|
+
|
|
90
|
+
**Documentation is part of the change, not a follow-up.** A change is **not done** until
|
|
91
|
+
every document it affects is corrected **in the same PR**. "Update the docs later" is not
|
|
92
|
+
allowed — later never comes, and a stale doc actively misleads the next agent.
|
|
93
|
+
|
|
94
|
+
This is not a style preference; it is paid-for scar tissue. This repo has been bitten
|
|
95
|
+
twice: the **0.0.4 ↔ 0.0.5** release that bumped only the Python package and let the
|
|
96
|
+
plugin manifests drift (now caught by `scripts/check_version_consistency.py`), and a
|
|
97
|
+
whole **"Phase A — drift correction"** in [`PR #26`](https://github.com/leonardsellem/hypermnesic/pull/26)
|
|
98
|
+
spent un-stale-ing the "tailnet-only / read-only" self-description and the
|
|
99
|
+
"allowlist-by-default" write model that code had long since moved past. Every hour spent
|
|
100
|
+
there is an hour the rule below would have saved.
|
|
101
|
+
|
|
102
|
+
### When you change X, update its docs in the same PR
|
|
103
|
+
|
|
104
|
+
| If your change touches… | …update, in the same PR |
|
|
105
|
+
|---|---|
|
|
106
|
+
| **MCP tool surface** (`mcp_server.py` — add/remove/rename a tool or change args) | [`docs/reference/mcp-tools.md`](docs/reference/mcp-tools.md); the tool list in [`README.md`](README.md); `ARCHITECTURE.md` if the serving picture changes |
|
|
107
|
+
| **CLI** (`cli.py` — commands/flags) | [`docs/reference/cli.md`](docs/reference/cli.md); the CLI examples in [`README.md`](README.md) and [`CONTRIBUTING.md`](CONTRIBUTING.md) |
|
|
108
|
+
| **Config / env** (`config.py`, `.env.example`) | [`docs/reference/configuration.md`](docs/reference/configuration.md); `.env.example`; any `CONVERGE_*`/budget mentions in [`ARCHITECTURE.md`](ARCHITECTURE.md) |
|
|
109
|
+
| **Write guard / protected paths / governance fence** (`serialize.py`, `frontmatter_gate.py`, `commit_note.py`) | `ARCHITECTURE.md` write-path section; [`SECURITY.md`](SECURITY.md) + [`docs/threat-model-commit-note.md`](docs/threat-model-commit-note.md); the write-model pin in [`docs/README.md`](docs/README.md); the write-guard bullet above; `README.md` "How it works" |
|
|
110
|
+
| **Auth / serving topology / lanes** (`auth*.py`, `mcp_server.py`) | `ARCHITECTURE.md` serving section; the serving-topology pin in `docs/README.md`; [`docs/unified-oauth-mcp-deploy-runbook.md`](docs/unified-oauth-mcp-deploy-runbook.md); `README.md`; `SECURITY.md` |
|
|
111
|
+
| **Retrieval / convergence / index** (`retrieve.py`, `converge.py`, `index.py`, `embed.py`, `graph.py`) | `ARCHITECTURE.md` retrieval + convergence sections; `README.md` "How it works" if user-visible; `harness/BENCHMARKS.md` if measured numbers move |
|
|
112
|
+
| **Version** (`pyproject.toml` `[project].version`) | `src/hypermnesic/__init__.__version__` **and the plugin manifests** — do not hand-enumerate them; run `scripts/check_version_consistency.py`, which names every file that must match; plus a dated [`CHANGELOG.md`](CHANGELOG.md) section |
|
|
113
|
+
| **Any new dependency** | keep `scripts/license_scan.py` green; record it in `pyproject.toml` |
|
|
114
|
+
| **New term or concept** | [`GLOSSARY.md`](GLOSSARY.md) |
|
|
115
|
+
| **Renaming / superseding a doc** | the [`docs/README.md`](docs/README.md) index **and** its "current truth" pins; move the superseded doc to `docs/archive/` with a pointer banner to its replacement |
|
|
116
|
+
| **Any user-visible behavior at all** | a dated entry under `[Unreleased]` in [`CHANGELOG.md`](CHANGELOG.md) |
|
|
117
|
+
|
|
118
|
+
### Anti-drift discipline
|
|
119
|
+
|
|
120
|
+
- **Point to the enforcing gate; don't re-list the enumerable set.** Where an automated
|
|
121
|
+
gate already pins truth (versions → `check_version_consistency.py`; copyleft →
|
|
122
|
+
`license_scan.py`; secrets/hosts → `preflight_public_scan.py`), reference the gate
|
|
123
|
+
rather than copying its list into prose — a copied list is the next thing to drift.
|
|
124
|
+
- **`docs/README.md` "current truth" is the tie-breaker.** When a process-history doc
|
|
125
|
+
(a plan, brainstorm, handoff, gate artifact) conflicts with current truth, the pins in
|
|
126
|
+
[`docs/README.md`](docs/README.md) win. If your change moves current truth, update those
|
|
127
|
+
pins.
|
|
128
|
+
- **Signed-off reviews are append-only.** Do not rewrite a dated, signed-off security
|
|
129
|
+
review or gate artifact — add a dated amendment (`amends:` / `signed_off:` frontmatter).
|
|
130
|
+
- **Found drift you didn't cause? Fix it or file it.** Same rule as a failing test — a
|
|
131
|
+
doc that contradicts the code is a defect, not background noise.
|
|
132
|
+
|
|
133
|
+
## Linear
|
|
134
|
+
|
|
135
|
+
- Use `linear-safe` / `linear-ls` for routine interactive issue reads,
|
|
136
|
+
comments, branch starts, and status changes. Keep Linear MCP as a
|
|
137
|
+
fallback/lifecycle surface only when a task explicitly requires MCP behavior
|
|
138
|
+
or wrapper healthchecks fail.
|
|
139
|
+
- The repo-root `.linear.toml` pins `workspace = "ls-ventures"` and
|
|
140
|
+
`team_id = "LS"` only as a human/raw-CLI fallback. It is not the agent safety
|
|
141
|
+
boundary because ambient Linear env vars override `.linear.toml`; wrappers
|
|
142
|
+
remain the agent default.
|
|
143
|
+
|
|
144
|
+
## How this repo plans and ships work
|
|
145
|
+
|
|
146
|
+
- **Plans** live under `docs/plans/` (`YYYY-MM-DD-NNN-<type>-<slug>-plan.md`) and are the
|
|
147
|
+
authoritative scope of record; brainstorms (the "what") live under `docs/brainstorms/`.
|
|
148
|
+
Both are **process history** — when they conflict with `docs/README.md`'s current
|
|
149
|
+
truth, the pins win.
|
|
150
|
+
- **Gate artifacts** (`docs/gate-artifacts/`) and dated **security reviews**
|
|
151
|
+
(`docs/*-security-review.md`, with `amends:` / `signed_off:` frontmatter) record
|
|
152
|
+
signed-off decisions; reusable design decisions live under `docs/solutions/`.
|
|
153
|
+
- **Release history** is [`CHANGELOG.md`](CHANGELOG.md) (Keep a Changelog format); the
|
|
154
|
+
narrative build log is `implementation-notes.md` (historical, not a changelog).
|
|
155
|
+
- **Public-launch staging** lives under `docs/launch/` — the AGPL-3.0 text, the one-PR
|
|
156
|
+
flip runbook, and the launch checklist are staged but **not live**; the `LICENSE` stays
|
|
157
|
+
proprietary until the flip PR.
|
|
158
|
+
|
|
159
|
+
## Reference
|
|
160
|
+
|
|
161
|
+
- Architecture: [`ARCHITECTURE.md`](ARCHITECTURE.md)
|
|
162
|
+
- Documentation index (start here): [`docs/README.md`](docs/README.md)
|
|
163
|
+
- MCP tools: [`docs/reference/mcp-tools.md`](docs/reference/mcp-tools.md)
|
|
164
|
+
- CLI: [`docs/reference/cli.md`](docs/reference/cli.md)
|
|
165
|
+
- Configuration: [`docs/reference/configuration.md`](docs/reference/configuration.md)
|
|
166
|
+
- Security: [`SECURITY.md`](SECURITY.md) · threat model: [`docs/threat-model-commit-note.md`](docs/threat-model-commit-note.md)
|
|
167
|
+
- Glossary: [`GLOSSARY.md`](GLOSSARY.md)
|
|
168
|
+
- Contributing (humans): [`CONTRIBUTING.md`](CONTRIBUTING.md)
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
This document gives you an accurate mental model of hypermnesic without reading the
|
|
4
|
+
source. For the user-facing quick start see [`README.md`](README.md); for the exact
|
|
5
|
+
tool/CLI/config surfaces see [`docs/reference/`](docs/reference/).
|
|
6
|
+
|
|
7
|
+
## The one invariant
|
|
8
|
+
|
|
9
|
+
> **The git-tracked markdown files are the single source of truth. The search/graph
|
|
10
|
+
> index is a disposable, rebuildable projection of the committed tree.**
|
|
11
|
+
|
|
12
|
+
Everything else follows from this. There is no separate database of record. A reindex
|
|
13
|
+
can be run at any time and **never loses a committed write** — because writes go to git
|
|
14
|
+
first, and the index is rebuilt *from* git. This is what makes the system safe to drop
|
|
15
|
+
into any repo and safe to operate without backups of the index.
|
|
16
|
+
|
|
17
|
+
## Layers
|
|
18
|
+
|
|
19
|
+
```mermaid
|
|
20
|
+
flowchart TB
|
|
21
|
+
subgraph SOT["Source of truth"]
|
|
22
|
+
G["git-tracked markdown vault<br/>(notes, sources, projects, …)"]
|
|
23
|
+
end
|
|
24
|
+
subgraph IDX["Disposable index (a projection of HEAD)"]
|
|
25
|
+
ING["ingest.py — walk *.md, strip frontmatter, chunk ≤4000"]
|
|
26
|
+
DB["index.py — SQLite: FTS5 (lexical) + sqlite-vec KNN (dense, 1536-d)<br/>+ SHA checkpoint"]
|
|
27
|
+
EMB["embed.py — OpenAI text-embedding-3-large @ 1536"]
|
|
28
|
+
GR["graph.py — wikilink edges"]
|
|
29
|
+
ING --> DB
|
|
30
|
+
EMB --> DB
|
|
31
|
+
DB --> GR
|
|
32
|
+
end
|
|
33
|
+
subgraph READ["Read path"]
|
|
34
|
+
CV["converge.py — catch index up to HEAD + bounded dense fill (every read)"]
|
|
35
|
+
RT["retrieve.py — RRF fusion of FTS5 + KNN, recency, dedup"]
|
|
36
|
+
TH["think.py — related notes + Socratic prompts (no write)"]
|
|
37
|
+
CV --> RT
|
|
38
|
+
end
|
|
39
|
+
subgraph WRITE["Write path (git-first)"]
|
|
40
|
+
CN["commit_note.py — guard → gate → write file → git commit → index follows → audit"]
|
|
41
|
+
FG["frontmatter_gate.py — diff-or-die"]
|
|
42
|
+
SE["serialize.py — protected-path + governance fence, within-repo, locks"]
|
|
43
|
+
AU["audit_log.py — append-only, body-free"]
|
|
44
|
+
CN --> FG --> SE --> AU
|
|
45
|
+
end
|
|
46
|
+
subgraph SERVE["Serving"]
|
|
47
|
+
M1["public OAuth /mcp (mcp_server.build_cloud_server) — every remote client"]
|
|
48
|
+
M2["tailnet read companion :8848 (mcp_server.build_server, auth-off, read-only)"]
|
|
49
|
+
CLI["hypermnesic CLI (cli.py) — engine-host-local"]
|
|
50
|
+
end
|
|
51
|
+
G --> ING
|
|
52
|
+
G -. "HEAD delta" .-> CV
|
|
53
|
+
CN -->|commit| G
|
|
54
|
+
READ --> SERVE
|
|
55
|
+
WRITE --> SERVE
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Retrieval (`retrieve.py`, `index.py`, `embed.py`, `graph.py`)
|
|
59
|
+
|
|
60
|
+
Hybrid: **SQLite FTS5** (lexical) fused with **sqlite-vec** KNN (dense; OpenAI
|
|
61
|
+
`text-embedding-3-large` at **1536 dims**) via **Reciprocal Rank Fusion**. The dense
|
|
62
|
+
channel degrades gracefully — if the embedding API is unreachable, lexical + graph
|
|
63
|
+
results still return, flagged `degraded_lexical_only`. Near-duplicate hits are collapsed
|
|
64
|
+
and a per-hit write-recency timestamp is attached (consumers derive their own forgetting
|
|
65
|
+
curve). The wikilink **graph** (`graph.py`) answers `build_context` and entity
|
|
66
|
+
`resolve`.
|
|
67
|
+
|
|
68
|
+
### Read-time convergence (`converge.py`)
|
|
69
|
+
|
|
70
|
+
Every read first runs `converge()`: it delta-replays the lexical index up to `HEAD`,
|
|
71
|
+
invalidates doc-surface vectors for changed markdown paths, closes a bounded slice of
|
|
72
|
+
the dense lag for both chunks and missing/stale doc surfaces (`CONVERGE_EMBED_BUDGET`),
|
|
73
|
+
and signals (never forces) a manual reindex when `HEAD` has jumped far past the
|
|
74
|
+
checkpoint (`CONVERGE_MAX_DELTA_FILES`). A debounce (`CONVERGE_DEBOUNCE_SECONDS`)
|
|
75
|
+
coalesces bursts. This is the correctness guarantee that lets the index stay a pure
|
|
76
|
+
projection while reads remain fresh — a just-committed or edited note is recall-able on
|
|
77
|
+
the next read with no manual reindex.
|
|
78
|
+
|
|
79
|
+
### Git-first write path (`commit_note.py`, `serialize.py`, `frontmatter_gate.py`, `audit_log.py`)
|
|
80
|
+
|
|
81
|
+
`commit_note` is the one sanctioned write. It is **git-first**: write file → `git
|
|
82
|
+
commit` (→ push) → the index follows as a projection. The agent never merges. It is
|
|
83
|
+
bounded by, in order: the **blocklist write guard** (`serialize.py` — protected-path
|
|
84
|
+
refusal for `.git/`, `.github/`, agent-instruction files, `scripts/`/`hooks/`/`skills/`,
|
|
85
|
+
plus a governance-file fence for build/CI/credential files; within-repo resolution,
|
|
86
|
+
no traversal/symlink escape; an optional allowlist to *narrow*); the **diff-or-die
|
|
87
|
+
frontmatter gate** (`frontmatter_gate.py` — any unrequested frontmatter change aborts
|
|
88
|
+
the write); single-writer **locks** (`serialize.py`); and an **append-only audit log**
|
|
89
|
+
(`audit_log.py` — summaries only, never bodies, never credentials). A refusal returns
|
|
90
|
+
`{committed: false, refused: …}` — never a silent success.
|
|
91
|
+
|
|
92
|
+
### Serving topology — two lanes (`mcp_server.py`, `auth.py`, `auth_cloud.py`)
|
|
93
|
+
|
|
94
|
+
1. **Public OAuth `/mcp`** (`build_cloud_server`) — the sole network lane for every
|
|
95
|
+
remote client (ChatGPT/Claude connectors, the Claude Code / Codex plugin, the
|
|
96
|
+
Obsidian companion). OAuth 2.1 with Dynamic Client Registration + PKCE; an
|
|
97
|
+
operator-consent gate issues tokens; tokens are audience-bound (RFC 8707) and
|
|
98
|
+
revocable. The AS metadata advertises both confidential-client methods and the
|
|
99
|
+
public-client `none` method because Codex/app connectors may register without a
|
|
100
|
+
client secret. DCR client registrations and live bearer/refresh token state persist
|
|
101
|
+
in owner-only `.hypermnesic/cloud-oauth-state.json` so refresh survives deploy
|
|
102
|
+
restarts; `.hypermnesic/client-grants.json` remains a separate secret-free grant
|
|
103
|
+
metadata surface for owner listing/revocation. Read tools are always available; the
|
|
104
|
+
gated `commit_note` write tool requires the `write` scope. Exposed via Tailscale
|
|
105
|
+
Funnel (HTTPS + auto-TLS).
|
|
106
|
+
2. **Tailnet read companion** (`build_server`, `:8848`, auth-off, **read-only**) — for
|
|
107
|
+
the Obsidian companion and the per-prompt recall hook on tailnet devices; tailnet
|
|
108
|
+
membership is the boundary. A write-enabled serve requires auth
|
|
109
|
+
(`write_enabled ⇒ auth-required`) unless the bounded `--allow-tailnet-write` opt-in
|
|
110
|
+
is used on a CGNAT bind.
|
|
111
|
+
|
|
112
|
+
The server binds a specific Tailscale interface at the socket level and refuses
|
|
113
|
+
`0.0.0.0` at construction. The CLI (`cli.py`) is the engine-host-local surface and
|
|
114
|
+
skips the network entirely.
|
|
115
|
+
|
|
116
|
+
### Installer & roles (`install.py`)
|
|
117
|
+
|
|
118
|
+
`hypermnesic install --role={single|master|client}` and `hypermnesic setup` provision a
|
|
119
|
+
host: render service units, configure the funnel + OAuth discovery, install the
|
|
120
|
+
post-merge convergence hook, and verify the live HTTPS discovery chain before reporting
|
|
121
|
+
success (fail-closed: no partial state).
|
|
122
|
+
|
|
123
|
+
## Companion
|
|
124
|
+
|
|
125
|
+
The Obsidian companion (`obsidian-plugin/`, shipped as a separate GPL-3.0 repository) is
|
|
126
|
+
a strictly read-only recall surface that talks to the engine only over the MCP wire
|
|
127
|
+
(`search` / `build_context` / `think`). It is not a derivative of the engine — see the
|
|
128
|
+
license boundary in [`README.md`](README.md).
|