pycontextdb 0.1.1__tar.gz → 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.
Files changed (131) hide show
  1. pycontextdb-0.2.0/.github/CODEOWNERS +16 -0
  2. pycontextdb-0.2.0/.github/pull_request_template.md +11 -0
  3. pycontextdb-0.2.0/.github/workflows/ci.yml +78 -0
  4. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/.github/workflows/publish.yml +10 -4
  5. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/.gitignore +15 -0
  6. pycontextdb-0.2.0/.pre-commit-config.yaml +31 -0
  7. pycontextdb-0.2.0/CHANGELOG.md +49 -0
  8. pycontextdb-0.2.0/COMMERCIAL.md +78 -0
  9. pycontextdb-0.2.0/CONTRIBUTING.md +69 -0
  10. pycontextdb-0.2.0/NOTICE +9 -0
  11. pycontextdb-0.2.0/OPEN_CORE.md +107 -0
  12. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/PKG-INFO +57 -13
  13. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/README.md +52 -9
  14. pycontextdb-0.2.0/ai-tools/README.md +29 -0
  15. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/assets/hero.png +0 -0
  16. pycontextdb-0.2.0/benchmarks/__init__.py +1 -0
  17. pycontextdb-0.2.0/benchmarks/trust_bakeoff.py +613 -0
  18. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/__init__.py +22 -2
  19. pycontextdb-0.2.0/contextdb/client.py +1186 -0
  20. pycontextdb-0.2.0/contextdb/core/clock.py +43 -0
  21. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/core/config.py +37 -2
  22. pycontextdb-0.2.0/contextdb/core/models.py +339 -0
  23. pycontextdb-0.2.0/contextdb/core/policy.py +138 -0
  24. pycontextdb-0.2.0/contextdb/core/slots.py +255 -0
  25. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/dynamics/evolution.py +28 -1
  26. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/dynamics/formation.py +68 -7
  27. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/dynamics/retrieval.py +121 -9
  28. pycontextdb-0.2.0/contextdb/dynamics/salience.py +78 -0
  29. pycontextdb-0.2.0/contextdb/dynamics/trust.py +362 -0
  30. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/integrations/__init__.py +6 -1
  31. pycontextdb-0.2.0/contextdb/integrations/act.py +103 -0
  32. pycontextdb-0.2.0/contextdb/integrations/livekit.py +67 -0
  33. pycontextdb-0.2.0/contextdb/integrations/pipecat.py +114 -0
  34. pycontextdb-0.2.0/contextdb/integrations/prompting.py +72 -0
  35. pycontextdb-0.2.0/contextdb/mcp.py +221 -0
  36. pycontextdb-0.2.0/contextdb/memory/factual.py +135 -0
  37. pycontextdb-0.2.0/contextdb/privacy/injection.py +43 -0
  38. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/store/base.py +6 -2
  39. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/store/sqlite_store.py +401 -45
  40. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/store/vector_index.py +10 -0
  41. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/utils/embeddings.py +28 -6
  42. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/utils/llm.py +87 -5
  43. pycontextdb-0.2.0/docs/api.md +87 -0
  44. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/docs/architecture.md +32 -7
  45. pycontextdb-0.2.0/docs/index.md +53 -0
  46. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/docs/prompts.md +40 -8
  47. pycontextdb-0.2.0/docs/quickstart.md +74 -0
  48. pycontextdb-0.2.0/legal/CLA-entity.md +67 -0
  49. pycontextdb-0.2.0/legal/CLA-individual.md +66 -0
  50. pycontextdb-0.2.0/legal/signed/README.md +3 -0
  51. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/pyproject.toml +57 -4
  52. pycontextdb-0.2.0/scripts/check_open_core.py +223 -0
  53. pycontextdb-0.2.0/tests/evals/test_trust_model.py +1348 -0
  54. pycontextdb-0.2.0/tests/test_version.py +18 -0
  55. pycontextdb-0.2.0/tests/unit/test_evolution.py +43 -0
  56. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_init.py +2 -1
  57. pycontextdb-0.2.0/tests/unit/test_open_core_boundary.py +28 -0
  58. pycontextdb-0.2.0/tests/unit/test_trust_policy.py +103 -0
  59. pycontextdb-0.1.1/.github/workflows/ci.yml +0 -39
  60. pycontextdb-0.1.1/contextdb/client.py +0 -516
  61. pycontextdb-0.1.1/contextdb/core/models.py +0 -151
  62. pycontextdb-0.1.1/contextdb/memory/factual.py +0 -58
  63. pycontextdb-0.1.1/docs/api.md +0 -50
  64. pycontextdb-0.1.1/docs/index.md +0 -34
  65. pycontextdb-0.1.1/docs/quickstart.md +0 -48
  66. pycontextdb-0.1.1/tests/test_version.py +0 -9
  67. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/.github/copilot-instructions.md +0 -0
  68. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/LICENSE +0 -0
  69. {pycontextdb-0.1.1 → pycontextdb-0.2.0/ai-tools}/.cursorrules +0 -0
  70. {pycontextdb-0.1.1 → pycontextdb-0.2.0/ai-tools}/CLAUDE.md +0 -0
  71. {pycontextdb-0.1.1 → pycontextdb-0.2.0/ai-tools}/llms-full.txt +0 -0
  72. {pycontextdb-0.1.1 → pycontextdb-0.2.0/ai-tools}/llms.txt +0 -0
  73. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/assets/README.md +0 -0
  74. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/assets/architecture.png +0 -0
  75. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/assets/benchmarks.png +0 -0
  76. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/assets/performance.png +0 -0
  77. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/assets/problem.png +0 -0
  78. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/assets/quickstart.png +0 -0
  79. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/benchmarks/run_benchmarks.py +0 -0
  80. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/agents/__init__.py +0 -0
  81. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/agents/memory_bus.py +0 -0
  82. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/agents/rl_manager.py +0 -0
  83. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/cli.py +0 -0
  84. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/core/__init__.py +0 -0
  85. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/core/exceptions.py +0 -0
  86. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/dynamics/__init__.py +0 -0
  87. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/graphs/__init__.py +0 -0
  88. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/graphs/base.py +0 -0
  89. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/graphs/causal.py +0 -0
  90. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/graphs/entity.py +0 -0
  91. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/graphs/semantic.py +0 -0
  92. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/graphs/temporal.py +0 -0
  93. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/integrations/autogen.py +0 -0
  94. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/integrations/crewai.py +0 -0
  95. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/integrations/langchain.py +0 -0
  96. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/integrations/openai_tools.py +0 -0
  97. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/memory/__init__.py +0 -0
  98. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/memory/experiential.py +0 -0
  99. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/memory/working.py +0 -0
  100. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/privacy/__init__.py +0 -0
  101. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/privacy/audit.py +0 -0
  102. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/privacy/pii_detector.py +0 -0
  103. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/privacy/retention.py +0 -0
  104. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/py.typed +0 -0
  105. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/store/__init__.py +0 -0
  106. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/utils/__init__.py +0 -0
  107. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/contextdb/utils/migrations.py +0 -0
  108. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/examples/customer_support.py +0 -0
  109. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/examples/multi_agent_team.py +0 -0
  110. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/examples/phone_agent.py +0 -0
  111. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/examples/research_assistant.py +0 -0
  112. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/mkdocs.yml +0 -0
  113. {pycontextdb-0.1.1/benchmarks → pycontextdb-0.2.0/tests}/__init__.py +0 -0
  114. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/conftest.py +0 -0
  115. {pycontextdb-0.1.1/tests → pycontextdb-0.2.0/tests/evals}/__init__.py +0 -0
  116. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/integration/__init__.py +0 -0
  117. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/integration/test_client.py +0 -0
  118. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/integration/test_langchain_integration.py +0 -0
  119. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/__init__.py +0 -0
  120. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_audit.py +0 -0
  121. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_config.py +0 -0
  122. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_embeddings.py +0 -0
  123. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_formation.py +0 -0
  124. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_graphs.py +0 -0
  125. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_memory_bus.py +0 -0
  126. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_models.py +0 -0
  127. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_pii_detector.py +0 -0
  128. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_retention.py +0 -0
  129. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_retrieval.py +0 -0
  130. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_store.py +0 -0
  131. {pycontextdb-0.1.1 → pycontextdb-0.2.0}/tests/unit/test_vector_index.py +0 -0
@@ -0,0 +1,16 @@
1
+ # Maintainer review on the open-core SDK and on anything that could
2
+ # move the Apache / Cloud boundary or ship a bad PyPI artifact.
3
+ # Username: https://github.com/gaufire
4
+
5
+ * @gaufire
6
+
7
+ /.github/ @gaufire
8
+ /legal/ @gaufire
9
+ /scripts/check_open_core.py @gaufire
10
+ /OPEN_CORE.md @gaufire
11
+ /COMMERCIAL.md @gaufire
12
+ /NOTICE @gaufire
13
+ /LICENSE @gaufire
14
+ /CONTRIBUTING.md @gaufire
15
+ /pyproject.toml @gaufire
16
+ /contextdb/ @gaufire
@@ -0,0 +1,11 @@
1
+ ## Summary
2
+
3
+ <!-- What changed, and why. Evals win over prose. -->
4
+
5
+ ## Open-core checklist
6
+
7
+ - [ ] I have read OPEN_CORE.md. This PR does not add cloud, billing, SSO, or entitlement code to the Apache tree.
8
+ - [ ] The SDK still does not import `contextdb_cloud` or any cloud control plane.
9
+ - [ ] No new local paid / license-key / entitlement boolean.
10
+ - [ ] Substantial contribution: I agree to the CLA in CONTRIBUTING.md (legal name and email in this description). Trivial typo PRs may skip this.
11
+ - [ ] `pytest tests/evals/ -v` and `python scripts/check_open_core.py` pass, or I explain why not.
@@ -0,0 +1,78 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ # Gitleaks + pre-commit checks. Scans the staged diff (and on CI the
11
+ # full history via --no-git-log=false by default) for tokens. Runs in
12
+ # parallel with `test` so secret leaks fail the PR even if contributors
13
+ # skipped `pre-commit install` locally.
14
+ secret-scan:
15
+ name: Secret scan (gitleaks + pre-commit)
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ with:
20
+ # gitleaks needs the full history to scan across commits,
21
+ # not just the shallow checkout.
22
+ fetch-depth: 0
23
+
24
+ - uses: actions/setup-python@v5
25
+ with:
26
+ python-version: "3.12"
27
+ cache: pip
28
+
29
+ - name: Install pre-commit
30
+ run: pip install pre-commit
31
+
32
+ - name: Run pre-commit on all files
33
+ run: pre-commit run --all-files --show-diff-on-failure
34
+
35
+ test:
36
+ name: Test (Python ${{ matrix.python-version }})
37
+ runs-on: ubuntu-latest
38
+ strategy:
39
+ fail-fast: false
40
+ matrix:
41
+ python-version: ["3.10", "3.11", "3.12"]
42
+
43
+ steps:
44
+ - uses: actions/checkout@v4
45
+
46
+ - name: Set up Python ${{ matrix.python-version }}
47
+ uses: actions/setup-python@v5
48
+ with:
49
+ python-version: ${{ matrix.python-version }}
50
+ cache: pip
51
+
52
+ - name: Install package and dev dependencies
53
+ run: |
54
+ python -m pip install --upgrade pip
55
+ pip install -e ".[dev]"
56
+
57
+ - name: Lint with ruff
58
+ run: ruff check .
59
+
60
+ - name: Type-check with mypy
61
+ run: mypy contextdb --python-version ${{ matrix.python-version }}
62
+
63
+ - name: Run tests
64
+ run: pytest
65
+
66
+ open-core:
67
+ name: Open-core boundary
68
+ runs-on: ubuntu-latest
69
+ steps:
70
+ - uses: actions/checkout@v4
71
+
72
+ - name: Set up Python
73
+ uses: actions/setup-python@v5
74
+ with:
75
+ python-version: "3.12"
76
+
77
+ - name: Package-boundary and accidental-publication checks
78
+ run: python scripts/check_open_core.py
@@ -8,8 +8,8 @@ permissions:
8
8
  contents: read
9
9
 
10
10
  jobs:
11
- build:
12
- name: Build distribution
11
+ inspect:
12
+ name: Inspect package contents
13
13
  runs-on: ubuntu-latest
14
14
  steps:
15
15
  - uses: actions/checkout@v4
@@ -25,6 +25,10 @@ jobs:
25
25
  - name: Build sdist and wheel
26
26
  run: python -m build
27
27
 
28
+ - name: Open-core and accidental-publication inspection
29
+ run: |
30
+ python scripts/check_open_core.py --dist dist --release-tag "${{ github.event.release.tag_name }}"
31
+
28
32
  - name: Upload dist artifacts
29
33
  uses: actions/upload-artifact@v4
30
34
  with:
@@ -33,10 +37,12 @@ jobs:
33
37
 
34
38
  publish:
35
39
  name: Publish to PyPI
36
- needs: build
40
+ needs: inspect
37
41
  runs-on: ubuntu-latest
38
42
 
39
- # Trusted-publisher flow: PyPI verifies this workflow via OIDC — no token needed.
43
+ # Trusted-publisher flow: PyPI verifies this workflow via OIDC.
44
+ # Require reviewers on this GitHub Environment so a published tag
45
+ # cannot reach PyPI without a human (OPEN_CORE.md).
40
46
  environment:
41
47
  name: pypi
42
48
  url: https://pypi.org/project/pycontextdb/
@@ -55,3 +55,18 @@ Thumbs.db
55
55
  *.sqlite3
56
56
  team.db
57
57
  contextdb.db
58
+
59
+ # Secrets and scratch files — the 0.1.0 PyPI release shipped a .rtf
60
+ # containing a token because these patterns were not gated anywhere.
61
+ *.rtf
62
+ *.key
63
+ *.pem
64
+ *.p12
65
+ .env
66
+ .env.*
67
+ secrets/
68
+ Untitled*
69
+
70
+ # CLA acceptances (personal data — keep out of the sdist)
71
+ legal/signed/*
72
+ !legal/signed/README.md
@@ -0,0 +1,31 @@
1
+ # Run locally before each commit:
2
+ # pip install -e ".[dev]"
3
+ # pre-commit install
4
+ #
5
+ # Then every git commit is gated on the hooks below. CI also runs them
6
+ # via .github/workflows/ci.yml, so skipping locally is only a temporary
7
+ # papercut — the PR will fail.
8
+
9
+ repos:
10
+ # Secret scanning — the reason this file exists. Gitleaks scans the
11
+ # staged diff for tokens (PyPI, GitHub, AWS, Stripe, Slack, generic
12
+ # entropy-high strings, ...). First run auto-downloads the binary.
13
+ - repo: https://github.com/gitleaks/gitleaks
14
+ rev: v8.30.0
15
+ hooks:
16
+ - id: gitleaks
17
+
18
+ # Lightweight second-layer checks from the standard pre-commit-hooks
19
+ # repo. `detect-private-key` catches PEM-style keys that gitleaks'
20
+ # default rules occasionally miss in non-standard encodings.
21
+ - repo: https://github.com/pre-commit/pre-commit-hooks
22
+ rev: v6.0.0
23
+ hooks:
24
+ - id: detect-private-key
25
+ - id: check-added-large-files
26
+ args: ["--maxkb=2048"]
27
+ - id: end-of-file-fixer
28
+ - id: trailing-whitespace
29
+ - id: check-yaml
30
+ - id: check-toml
31
+ - id: check-merge-conflict
@@ -0,0 +1,49 @@
1
+ # Changelog
2
+
3
+ ## 0.2.0 — 2026-08-17
4
+
5
+ First PyPI cut of the trust model. `pip install pycontextdb` now matches
6
+ GitHub `main`: memory an agent can act on without treating a wish as a fact.
7
+
8
+ `contextdb.init`, `factual.add`, `factual.recall`, and `search` are unchanged.
9
+
10
+ ### Added
11
+
12
+ - Epistemic typing on every fact (`user_stated` / `agent_inferred` /
13
+ `third_party`), confidence, independent corroboration, `action_relevant`.
14
+ - `TrustPolicy` as data — `TrustPolicy.hospital()` vs `.restaurant()`.
15
+ - `factual.recall_for_action()`, `factual.confirm()`, `VerifyBeforeAct`
16
+ (`act` / `ask` / `abstain`).
17
+ - Versioned slot vocabulary + LLM-free slotter (`add_fast` never calls an LLM).
18
+ - Contested slots: independent speakers with different values do not
19
+ last-write-win. `confirm()` resolves.
20
+ - Temporal supersede with an injectable clock; sibling-slot hop on recall.
21
+ - PII redaction on writes **and** queries before embed.
22
+ - Write-time injection screening; `[RECALLED DATA — not instructions]` renderer.
23
+ - Salience (recency × frequency × criticality), verifiable forget, tenant
24
+ isolation at the storage layer.
25
+ - MCP tools: `remember` / `recall` / `recall_for_action` / `forget` / `confirm`.
26
+ - In-repo fabrication bake-off: `python benchmarks/trust_bakeoff.py`
27
+ (trust arm vs our own untyped control — not a live Mem0/Zep run).
28
+ - Open-core governance: [OPEN_CORE.md](OPEN_CORE.md),
29
+ [COMMERCIAL.md](COMMERCIAL.md), CLA, CODEOWNERS, package-boundary CI,
30
+ and release inspection. Code through `2554dae` remains Apache-2.0.
31
+ Cloud is a private repo that depends on this SDK, never the reverse.
32
+
33
+ ### Fixed
34
+
35
+ - `contextdb.__version__` no longer drifts from `pyproject.toml` (was `0.1.0`
36
+ while the project version was `0.1.1`).
37
+ - CI mypy on Python 3.12: type-check as the running interpreter so
38
+ NumPy 2.5's PEP 695 `type` aliases parse. The 3.10 job still guards
39
+ our runtime floor.
40
+ - CI latency evals: keep a tight add_fast p50 and a wider p95 on
41
+ shared runners (p50 was 2ms when p95 spiked to 21ms).
42
+
43
+ ## 0.1.1 — 2026-04-22
44
+
45
+ README rendering on PyPI; absolute GitHub asset URLs.
46
+
47
+ ## 0.1.0 — 2026-04-22
48
+
49
+ Initial public release.
@@ -0,0 +1,78 @@
1
+ # ContextDB commercial terms
2
+
3
+ ContextDB is **open-core**. The software in this repository is
4
+ Apache-2.0. Hosted operations, compliance, and managed enforcement are
5
+ a separate product.
6
+
7
+ This is not a substitute for a customer contract. It states what is
8
+ free, what is sold, and how the name may be used.
9
+
10
+ ## Free (this repository)
11
+
12
+ `pip install pycontextdb` (and this GitHub tree) includes:
13
+
14
+ - The full local SDK and CLI
15
+ - Epistemic typing, `TrustPolicy`, `VerifyBeforeAct`, `confirm()`
16
+ - SQLite runtime, backend interfaces, `add_fast`, recall, forget, export
17
+ - Stock adapters (Pipecat, LiveKit, MCP, …) and prompt-injection defenses
18
+ - Baseline policies and the public eval / bake-off suite
19
+
20
+ There is **no license key**. There is **no local paid boolean**. If a
21
+ flag exists in `ContextDBConfig`, it is an optional local pathway, not
22
+ an entitlement.
23
+
24
+ ## Paid (ContextDB Cloud)
25
+
26
+ Sold from the private `contextdb-cloud` control plane, enforced
27
+ **server-side**:
28
+
29
+ - Hosted multi-tenant runtime and managed storage / indexing
30
+ - Organizations, projects, API keys, entitlements
31
+ - SSO, SCIM, RBAC, approval workflows
32
+ - Policy deployment, versioning, canaries, rollback
33
+ - Audit retention, signed exports, compliance evidence
34
+ - Managed confirmation workflows and SLAs
35
+ - Customer-transcript evaluation and trust reports
36
+ - Proprietary ranking / consolidation models
37
+ - Regional hosting, backups, HA, observability, support
38
+ - PyAI-native managed memory and voice-path enforcement
39
+
40
+ Cloud **depends on** the open SDK. The SDK **never** depends on cloud.
41
+ See [OPEN_CORE.md](OPEN_CORE.md).
42
+
43
+ ## Trademark
44
+
45
+ **ContextDB** and the ContextDB logo are trademarks of Atoms AI.
46
+
47
+ The Apache License 2.0 grants rights to the *software*. It does **not**
48
+ grant rights to the *marks* (Apache License §6).
49
+
50
+ You may:
51
+
52
+ - Say you use ContextDB
53
+ - Cite the project and link to this repository
54
+ - State compatibility (“works with ContextDB”) when that is true
55
+
56
+ You may not, without written permission:
57
+
58
+ - Use ContextDB or confusingly similar names as the name of a competing
59
+ product, hosted service, or company
60
+ - Use the logo or word mark to imply Atoms AI endorsement
61
+ - Register domains, social handles, or trademarks that trade on the mark
62
+
63
+ File notices and the [NOTICE](NOTICE) file exist so redistributors keep
64
+ this distinction visible.
65
+
66
+ ## Dual licensing
67
+
68
+ Code published through `2554dae` is Apache-2.0 forever, including forks
69
+ already taken. New substantial contributions to *this* repo are accepted
70
+ only under the CLA in [CONTRIBUTING.md](CONTRIBUTING.md) so Atoms AI can
71
+ relicense *future* work if needed. That does not revoke Apache-2.0 on
72
+ anything already released.
73
+
74
+ ## Contact
75
+
76
+ - Product and Cloud: Gaurav Sharma — gaurav@saaslabs.co
77
+ - Issues (SDK): https://github.com/atomsai/contextdb/issues
78
+ - Trademark misuse: the same address, subject `ContextDB trademark`
@@ -0,0 +1,69 @@
1
+ # Contributing to ContextDB
2
+
3
+ Thank you for wanting to improve ContextDB. This repository is the
4
+ **open-core SDK**. Read [OPEN_CORE.md](OPEN_CORE.md) before you write
5
+ code. If the change belongs in hosted multi-tenant operations, it does
6
+ not belong here.
7
+
8
+ ## What we accept here
9
+
10
+ Trust and safety correctness, local runtime fixes, adapters, docs, and
11
+ evals. Evals win over prose: `pytest tests/evals/ -v`.
12
+
13
+ We do **not** accept:
14
+
15
+ - Cloud control-plane, billing, SSO, or entitlement code
16
+ - Local license keys or `if paid:` branches
17
+ - Imports of `contextdb_cloud` or any private cloud package
18
+ - Changes that loosen PII-before-embed or the hash-chained audit log
19
+
20
+ ## Contributor License Agreement
21
+
22
+ Trivial changes (typos, broken links, comment nits) do not need a CLA.
23
+
24
+ **Substantial contributions** (new or material code, evals, or docs that
25
+ are not typo-fixes) require a signed CLA **before** merge. The CLA lets
26
+ Atoms AI relicense *future* contributions if dual-licensing ever
27
+ matters. It does not change the Apache-2.0 grant on code already
28
+ public through `2554dae`.
29
+
30
+ 1. Read [legal/CLA-individual.md](legal/CLA-individual.md) (or
31
+ [legal/CLA-entity.md](legal/CLA-entity.md) if you contribute on
32
+ behalf of an employer).
33
+ 2. Open a pull request whose description includes:
34
+
35
+ > I have read and agree to the ContextDB CLA
36
+ > (legal/CLA-individual.md or legal/CLA-entity.md).
37
+ > Legal name: \<name\>. Email: \<email\>.
38
+
39
+ 3. Maintainers record acceptances under `legal/signed/` (gitignored
40
+ from the sdist; not a public dump of personal data).
41
+
42
+ We may enable a CLA bot later. The requirement is the signature, not
43
+ the bot.
44
+
45
+ ## Development
46
+
47
+ ```bash
48
+ pip install -e ".[dev]"
49
+ pre-commit install
50
+ ruff check .
51
+ mypy contextdb --strict
52
+ pytest
53
+ python scripts/check_open_core.py
54
+ ```
55
+
56
+ Do not break `contextdb.init`, `factual.add`, `factual.recall`, or
57
+ `search`. New fields need backward-compatible defaults.
58
+
59
+ ## Review
60
+
61
+ [`.github/CODEOWNERS`](.github/CODEOWNERS) routes reviews. Governance
62
+ files (`OPEN_CORE.md`, `COMMERCIAL.md`, `LICENSE`, `legal/`, workflows)
63
+ need a maintainer.
64
+
65
+ ## License of your contribution
66
+
67
+ By opening a substantial PR you agree the contribution is your original
68
+ work (or you have the right to submit it) and you offer it under
69
+ Apache-2.0 **and** the CLA.
@@ -0,0 +1,9 @@
1
+ ContextDB
2
+ Copyright 2026 Atoms AI and contributors
3
+
4
+ This product includes software developed by Atoms AI and contributors.
5
+ Licensed under the Apache License, Version 2.0. See LICENSE.
6
+
7
+ ContextDB and the ContextDB logo are trademarks of Atoms AI.
8
+ The Apache License does not grant permission to use the ContextDB
9
+ trademarks. See COMMERCIAL.md.
@@ -0,0 +1,107 @@
1
+ # ContextDB open-core boundary
2
+
3
+ **Decision:** ContextDB remains open-core.
4
+
5
+ All code public through commit `2554dae` remains Apache-2.0. This
6
+ repository stays Apache-2.0. New work in *this* tree is the community
7
+ SDK. Hosted operations live in a private `contextdb-cloud` repository
8
+ that **depends on** this SDK and that this SDK **must never** depend on.
9
+
10
+ The evals in `tests/evals/test_trust_model.py` are the spec for trust
11
+ and safety. Monetize operating, proving, and governing that spec — not
12
+ hiding it.
13
+
14
+ ## Public — `atomsai/contextdb` (this repo)
15
+
16
+ Apache-2.0. Anyone may use, modify, and ship it under that license.
17
+
18
+ - Epistemic types, provenance, and corroboration
19
+ - `TrustPolicy`, `VerifyBeforeAct`, `decide()`, and confirmation APIs
20
+ - Local SQLite runtime and backend interfaces
21
+ - `add_fast`, recall, deletion, and export
22
+ - Safe Pipecat, LiveKit, and agent adapters
23
+ - Prompt rendering and injection defenses
24
+ - Baseline policy implementations (`TrustPolicy.hospital()`, `.restaurant()`)
25
+ - Trust evals, fabrication benchmarks, and synthetic fixtures
26
+ - Community SDK, CLI, and documentation
27
+
28
+ Local feature flags (`enable_multi_graph`, `enable_rl_manager`, …) are
29
+ **optional pathways in the open SDK**. They are not entitlements. They
30
+ must never consult a license key, a cloud control plane, or a “paid”
31
+ boolean.
32
+
33
+ ## Private — `contextdb-cloud`
34
+
35
+ Not in this tree. Cloud depends on `pycontextdb`. The SDK does not
36
+ import it.
37
+
38
+ - Hosted, multi-tenant runtime
39
+ - Managed distributed storage and indexing
40
+ - Organization, project, API-key, and entitlement control plane
41
+ - SSO, SCIM, RBAC, and approval workflows
42
+ - Policy deployment, versioning, canaries, and rollback
43
+ - Audit retention, signed exports, and compliance evidence
44
+ - Managed human-confirmation workflows and SLAs
45
+ - Customer-transcript evaluation and trust reports
46
+ - Advanced proprietary ranking / consolidation models
47
+ - Regional hosting, backups, HA, observability, and support
48
+ - PyAI-native managed memory and voice-path enforcement
49
+
50
+ ## Hard rules
51
+
52
+ 1. **Dependency direction.** Cloud may import `contextdb`. `contextdb`
53
+ must not import cloud, billing, or entitlement packages.
54
+ 2. **No premium-in-Apache.** Do not place cloud code in this repo behind
55
+ feature flags. If it is here, it is Apache-2.0.
56
+ 3. **Entitlements are server-side.** Never a local boolean, license
57
+ file, or compiled-in key. A checkout of this repo can do everything
58
+ the SDK documents, offline.
59
+ 4. **Trust and safety stay open.** Typing, corroboration, contest,
60
+ `VerifyBeforeAct`, PII-before-embed, injection rendering, forget, and
61
+ the evals that lock those behaviors are not paid features.
62
+ 5. **Trademark.** Apache-2.0 is a copyright and patent license, not a
63
+ trademark license. See [COMMERCIAL.md](COMMERCIAL.md) and [NOTICE](NOTICE).
64
+ 6. **Releases.** PyPI publishes only from a GitHub Release after package
65
+ inspection and the `pypi` environment approval. See below.
66
+ 7. **CLA.** Substantial external contributions require a signed CLA so
67
+ future dual-licensing of *new* work remains possible. Code through
68
+ `2554dae` is already Apache-2.0 and stays that way. See
69
+ [CONTRIBUTING.md](CONTRIBUTING.md).
70
+
71
+ ## What we monetize
72
+
73
+ Operating the trust bar in production (hosted runtime, isolation,
74
+ uptime), proving it on customer transcripts, and governing it (SSO,
75
+ policy canaries, signed audit, confirmation SLAs). Not the correctness
76
+ of `decide()`.
77
+
78
+ ## Release and accidental publication
79
+
80
+ - `scripts/check_open_core.py` — import direction, forbidden paths,
81
+ no local entitlement fields, sdist/wheel denylist.
82
+ - CI job **Open-core boundary** runs the source checks on every push
83
+ and pull request to `main`.
84
+ - `publish.yml` builds the distributions, inspects them, checks the
85
+ release tag against `pyproject.toml`, then publishes only after the
86
+ GitHub Environment `pypi` is approved.
87
+ - Hatch excludes secrets, keys, and stray scratch files from sdist and
88
+ wheel (the 0.1.0 release shipped a token in an `.rtf`; that must not
89
+ happen again).
90
+ - [`.github/CODEOWNERS`](.github/CODEOWNERS) requires a maintainer
91
+ review on governance, license, and the SDK tree.
92
+
93
+ Configure the `pypi` environment with **required reviewers** so a
94
+ published tag cannot reach PyPI without a human.
95
+
96
+ ## Moving a feature across the boundary
97
+
98
+ - **SDK → cloud:** delete it from this repo in a public commit. Do not
99
+ leave a stub that phones home.
100
+ - **Cloud → SDK:** land it here as Apache-2.0 with an eval. No
101
+ “disabled unless entitled” branch.
102
+
103
+ ## Related
104
+
105
+ - [COMMERCIAL.md](COMMERCIAL.md) — product split, trademark, contact
106
+ - [CONTRIBUTING.md](CONTRIBUTING.md) — CLA and review
107
+ - [CHANGELOG.md](CHANGELOG.md) — 0.2.0 is the first trust-model PyPI cut
@@ -1,7 +1,7 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: pycontextdb
3
- Version: 0.1.1
4
- Summary: The unified context layer for AI agents — replacing the patchwork with a memory operating system
3
+ Version: 0.2.0
4
+ Summary: The unified context layer for AI agents — memory you can act on without treating wishes as facts
5
5
  Project-URL: Homepage, https://github.com/atomsai/contextdb
6
6
  Project-URL: Documentation, https://contextdb.dev
7
7
  Project-URL: Repository, https://github.com/atomsai/contextdb
@@ -9,7 +9,8 @@ Project-URL: Issues, https://github.com/atomsai/contextdb/issues
9
9
  Author-email: Gaurav Sharma <gaurav@saaslabs.co>
10
10
  License-Expression: Apache-2.0
11
11
  License-File: LICENSE
12
- Keywords: ai-agents,context,knowledge-graph,llm,memory,rag,vector-database
12
+ License-File: NOTICE
13
+ Keywords: agent-memory,ai-agents,context,knowledge-graph,llm,memory,rag,trust,vector-database
13
14
  Classifier: Development Status :: 3 - Alpha
14
15
  Classifier: Intended Audience :: Developers
15
16
  Classifier: License :: OSI Approved :: Apache Software License
@@ -66,7 +67,7 @@ Description-Content-Type: text/markdown
66
67
  <p align="center">
67
68
  <a href="https://pypi.org/project/pycontextdb/"><img src="https://img.shields.io/pypi/v/pycontextdb.svg" alt="PyPI version"></a>
68
69
  <a href="https://github.com/atomsai/contextdb/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache 2.0"></a>
69
- <a href="https://github.com/atomsai/contextdb/blob/main/tests/"><img src="https://img.shields.io/badge/tests-82%20passing-brightgreen.svg" alt="Tests"></a>
70
+ <a href="https://github.com/atomsai/contextdb/blob/main/tests/"><img src="https://img.shields.io/badge/tests-122%20passing-brightgreen.svg" alt="Tests"></a>
70
71
  <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10%2B-blue.svg" alt="Python 3.10+"></a>
71
72
  <a href="https://github.com/atomsai/contextdb/blob/main/pyproject.toml"><img src="https://img.shields.io/badge/mypy-strict-blue.svg" alt="Type Checked"></a>
72
73
  <a href="https://github.com/atomsai/contextdb/blob/main/benchmarks/run_benchmarks.py"><img src="https://img.shields.io/badge/search_p95-%3C5ms_%40_5K-brightgreen.svg" alt="Search p95"></a>
@@ -94,13 +95,32 @@ Description-Content-Type: text/markdown
94
95
  | **Search latency (5K memories)** | p50 **3.9ms** · p95 **5.0ms** |
95
96
  | **Vector search (10K × 1,536d)** | p50 **0.8ms** · p95 **1.0ms** |
96
97
  | **PII detection** | 100,000+ texts/sec |
97
- | **Tests** | 82 passing · ruff clean · mypy `--strict` clean |
98
+ | **Tests** | 122 passing (incl. 34 trust-model acceptance evals) · ruff clean · mypy `--strict` clean |
98
99
  | **Dependencies** | SQLite + NumPy (FAISS / Postgres optional) |
99
100
 
100
101
  Hermetic, reproducible — run the suite yourself: `python benchmarks/run_benchmarks.py`.
101
102
 
102
103
  ---
103
104
 
105
+ ## The trust model — memory your agent can act on
106
+
107
+ Speed is table stakes. The production failure that gets agents fired is **acting on a wish as if it were a fact**: a caller says *"I'd like to come in Thursday"* and the agent answers *"we penciled you in."* A wish and a confirmed fact are the same object in every memory store on the market — so ContextDB types them.
108
+
109
+ Every memory carries **epistemic provenance** (`user_stated` / `agent_inferred` / `third_party`), **confidence**, **independent corroboration** (same-speaker repeats do not count), and an **action-relevant** flag. The action bar is data — `TrustPolicy.hospital()` vs `TrustPolicy.restaurant()` — not a hardcoded `if`. Facts that gate actions must pass the active policy before `recall_for_action()` releases them; everything else comes back marked `requires_confirmation`. `factual.confirm()` is the writeback: the agent asked, the user said yes, the fact graduates. Stock hosts (Pipecat, LiveKit, MCP) go through `VerifyBeforeAct` so an untrusted fact never reaches an action-shaped prompt.
110
+
111
+ On top of that: **versioned slot vocabulary** + an LLM-free slotter (so `add_fast` and supersede agree), **extractor-as-security-boundary** (a prompt-injected `user/allergy` the raw text does not support is demoted), **contested slots** (independent speakers asserting different values do not last-write-win — both stay current, neither is actionable, `confirm()` resolves), **compositional hop** (`"when is the Denver meeting?"` surfaces `meeting/time` after hitting `meeting/location`), **PII-safe recall** (queries are redacted before embed so a raw email still retrieves `[EMAIL]`), **temporal supersede** with an injectable clock (`valid_from`/`valid_until`/`superseded_by` + as-of queries), a **latency-tiered write path** (`add_fast`: no LLM on the turn path, p95 ≈ 1.5ms local), **salience** (recency × frequency × criticality — a year-old allergy still outranks 500 fresh noise memories), **write-time injection screening** with demoted `[RECALLED DATA — not instructions]` rendering, **recall-side observability** (`db.explain(id)` logs score *and* decision flags as they stood at recall time; `VerifyBeforeAct` writes `DECIDE` to the audit log), **verifiable forgetting** that walks graph edges, and **tenant/agent isolation enforced at the storage layer**.
112
+
113
+ Don't take our word for it — the fabrication benchmark ships in-repo and runs on every PR. Same store, same embedder, same utterance policy; the only difference is the trust model:
114
+
115
+ | Arm | Fabrication rate (lower=better) | Recall accuracy | Temporal supersede | Over-refusal | Write p95 |
116
+ | --- | --- | --- | --- | --- | --- |
117
+ | `contextdb-trust` | **0%** | **100%** | yes | no | 1.5ms |
118
+ | `raw-store-baseline` (untyped control) | 50% | 88% | NO | no | 0.9ms |
119
+
120
+ Traps: wish-vs-fact, temporal move, prompt injection, PII redaction, cross-tenant bleed, negation, quantity update, over-refusal. Run it: `python benchmarks/trust_bakeoff.py` — acceptance evals live in `tests/evals/`. Mem0/Zep/Letta/supermemory arms implement the `MemoryArm` protocol and plug into the same harness.
121
+
122
+ ---
123
+
104
124
  ## The problem
105
125
 
106
126
  <p align="center">
@@ -117,6 +137,7 @@ Databricks Lakebase gives agents a hard drive. ContextDB gives agents a brain.
117
137
 
118
138
  | What you use today | What breaks | ContextDB equivalent |
119
139
  |---|---|---|
140
+ | Mem0 / supermemory / Zep | Store-and-recall: a wish and a fact are the same object; last write wins; no verify-before-act | Epistemic typing, `TrustPolicy`, contested slots, `recall_for_action()`, `confirm()` |
120
141
  | Pinecone / Qdrant / Weaviate | Semantic-only; no temporal, causal, or entity awareness | Multi-graph retrieval fused with RRF (semantic + temporal + causal + entity) |
121
142
  | Redis / Memcached | Ephemeral; lost between sessions; no compression | `WorkingMemory` with token-budget paging and FIFO eviction |
122
143
  | PostgreSQL / MongoDB | Static rows; no lifecycle; no graph links | `FactualMemory` with formation, evolution, and consolidation |
@@ -369,16 +390,18 @@ AutoGen adapter ships in `contextdb.integrations.autogen` with the same shape.
369
390
 
370
391
  ---
371
392
 
372
- ## Use with AI coding tools
393
+ ## Use with Cursor, Claude Code, and GitHub Copilot
373
394
 
374
- Drop any of these files into your project and your AI coding tool will automatically reach for ContextDB whenever it needs to add memory to an agent — no hand-holding required.
395
+ Drop-in files live in [`ai-tools/`](https://github.com/atomsai/contextdb/tree/main/ai-tools) — copy whichever ones match your stack into your own project and the AI tool will reach for ContextDB automatically when an agent needs memory. No prompt gymnastics, no "please use ContextDB" in every message.
396
+
397
+ **Why:** with one of these rule files in your repo, "add memory to this agent" just works — the assistant already knows `db.factual.add` / `db.search` is the right shape and stops suggesting raw Pinecone, Redis for session state, custom PII regex, or `ConversationBufferMemory`. Fewer revert-and-redo cycles.
375
398
 
376
399
  | File | Tool | What it does |
377
400
  |---|---|---|
378
- | [`.cursorrules`](https://github.com/atomsai/contextdb/blob/main/.cursorrules) | Cursor | Auto-uses ContextDB for all agent-memory tasks; bans raw Pinecone / Redis / custom PII regex |
379
- | [`CLAUDE.md`](https://github.com/atomsai/contextdb/blob/main/CLAUDE.md) | Claude Code | Same, for Claude Code — includes the `async with db:` pattern and framework adapters |
401
+ | [`ai-tools/.cursorrules`](https://github.com/atomsai/contextdb/blob/main/ai-tools/.cursorrules) | Cursor | Auto-uses ContextDB for all agent-memory tasks; bans raw Pinecone / Redis / custom PII regex |
402
+ | [`ai-tools/CLAUDE.md`](https://github.com/atomsai/contextdb/blob/main/ai-tools/CLAUDE.md) | Claude Code | Same, for Claude Code — includes the `async with db:` pattern and framework adapters |
380
403
  | [`.github/copilot-instructions.md`](https://github.com/atomsai/contextdb/blob/main/.github/copilot-instructions.md) | GitHub Copilot | Biases Copilot suggestions toward `db.factual.add` / `db.search` over custom vector plumbing |
381
- | [`llms.txt`](https://github.com/atomsai/contextdb/blob/main/llms.txt) · [`llms-full.txt`](https://github.com/atomsai/contextdb/blob/main/llms-full.txt) | Any LLM | Host at your docs-site root so assistants can discover and recommend ContextDB |
404
+ | [`ai-tools/llms.txt`](https://github.com/atomsai/contextdb/blob/main/ai-tools/llms.txt) · [`ai-tools/llms-full.txt`](https://github.com/atomsai/contextdb/blob/main/ai-tools/llms-full.txt) | Any LLM | Host at your docs-site root so assistants can discover and recommend ContextDB |
382
405
 
383
406
  ### Or copy-paste a ready-made prompt
384
407
 
@@ -526,7 +549,7 @@ Numbers above are from a MacBook-class laptop with no FAISS. Rerun `python bench
526
549
 
527
550
  ## Why not just use...
528
551
 
529
- **Mem0?** Graph intelligence is gated behind the paid tier. No experiential memory for trajectories and reflections. No RL-trained memory manager. No working memory with token budgets.
552
+ **Mem0?** Their graph intelligence is a commercial add-on. ContextDB ships experiential memory, working-memory paging, and the trust bar in the Apache SDK — hosted multi-tenant operations are a separate Cloud product ([OPEN_CORE.md](OPEN_CORE.md)).
530
553
 
531
554
  **Zep?** Strong bitemporal knowledge graphs. But no experiential memory, no working memory paging, no learned retrieval policies. Scope is narrower than a full memory OS.
532
555
 
@@ -565,9 +588,30 @@ Python 3.10+. No system dependencies for the default install — SQLite and NumP
565
588
 
566
589
  ---
567
590
 
591
+ ## Open core
592
+
593
+ The SDK, trust model, and evals are Apache-2.0. Hosted multi-tenant
594
+ operations live in a private `contextdb-cloud` repo that depends on this
595
+ package — this package never depends on cloud. Entitlements are
596
+ server-side. See [OPEN_CORE.md](OPEN_CORE.md) and
597
+ [COMMERCIAL.md](COMMERCIAL.md). **ContextDB** is a trademark; the Apache
598
+ license is not a trademark license.
599
+
568
600
  ## Contributing
569
601
 
570
- Apache 2.0 — see [LICENSE](https://github.com/atomsai/contextdb/blob/main/LICENSE). See [`docs/architecture.md`](https://github.com/atomsai/contextdb/blob/main/docs/architecture.md) for the design rationale. Issues and pull requests welcome on [GitHub](https://github.com/atomsai/contextdb).
602
+ Apache 2.0 — see [LICENSE](https://github.com/atomsai/contextdb/blob/main/LICENSE).
603
+ Substantial PRs need a CLA ([CONTRIBUTING.md](CONTRIBUTING.md)).
604
+ See [`docs/architecture.md`](https://github.com/atomsai/contextdb/blob/main/docs/architecture.md) for the design rationale. Issues and pull requests welcome on [GitHub](https://github.com/atomsai/contextdb).
605
+
606
+ **Local setup:**
607
+
608
+ ```bash
609
+ pip install -e ".[dev]"
610
+ pre-commit install # enables gitleaks + basic hygiene checks on every commit
611
+ pytest # runs the test suite
612
+ ```
613
+
614
+ The pre-commit hook blocks commits that would leak secrets (PyPI / GitHub / AWS tokens, private keys, etc.). CI re-runs the same checks, so you can't push past a leak even if the hook is skipped locally.
571
615
 
572
616
  If you use ContextDB in research, please cite the paper: [zenodo.org/records/19647089](https://zenodo.org/records/19647089).
573
617