code-atlas-mcp 0.2.0.dev1__tar.gz → 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. code_atlas_mcp-0.3.1/.gitattributes +84 -0
  2. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.github/workflows/release.yml +19 -7
  3. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/CHANGELOG.md +46 -4
  4. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/CLAUDE.md +5 -3
  5. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/PKG-INFO +35 -33
  6. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/README.md +32 -32
  7. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docker-compose.yml +12 -1
  8. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/adr/0004-event-driven-tiered-pipeline.md +32 -35
  9. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/adr/0005-deployment-process-model.md +8 -14
  10. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/adr/0006-pure-python-tree-sitter.md +4 -4
  11. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/architecture.md +27 -37
  12. code_atlas_mcp-0.3.1/docs/benchmarks.md +67 -0
  13. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/guides/repo-guidelines.md +1 -1
  14. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/pyproject.toml +5 -4
  15. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/ruff.toml +6 -0
  16. code_atlas_mcp-0.3.1/scripts/profile_index.py +539 -0
  17. code_atlas_mcp-0.3.1/scripts/profile_query.py +546 -0
  18. code_atlas_mcp-0.3.1/src/code_atlas/__init__.py +8 -0
  19. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/cli.py +125 -39
  20. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/events.py +113 -22
  21. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/graph/client.py +848 -246
  22. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/indexing/__init__.py +4 -6
  23. code_atlas_mcp-0.3.1/src/code_atlas/indexing/consumers.py +964 -0
  24. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/indexing/daemon.py +8 -11
  25. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/indexing/orchestrator.py +345 -123
  26. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/schema.py +25 -1
  27. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/search/embeddings.py +90 -11
  28. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/search/engine.py +14 -6
  29. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/server/mcp.py +31 -45
  30. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/settings.py +35 -5
  31. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/conftest.py +1 -1
  32. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/graph/test_client.py +1 -1
  33. code_atlas_mcp-0.3.1/tests/integration/indexing/test_consumers.py +370 -0
  34. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/search/test_embeddings.py +41 -33
  35. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/test_schema.py +25 -1
  36. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/uv.lock +37 -1
  37. code_atlas_mcp-0.2.0.dev1/docs/benchmarks.md +0 -45
  38. code_atlas_mcp-0.2.0.dev1/src/code_atlas/__init__.py +0 -5
  39. code_atlas_mcp-0.2.0.dev1/src/code_atlas/indexing/consumers.py +0 -572
  40. code_atlas_mcp-0.2.0.dev1/tests/integration/indexing/test_consumers.py +0 -140
  41. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.atlasignore +0 -0
  42. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.dockerignore +0 -0
  43. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.env.dist +0 -0
  44. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.github/FUNDING.yml +0 -0
  45. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  46. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  47. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  48. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  49. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.github/dependabot.yml +0 -0
  50. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.github/labels.yml +0 -0
  51. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.github/workflows/ci.yml +0 -0
  52. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.github/workflows/labels.yml +0 -0
  53. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.github/workflows/security.yml +0 -0
  54. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.gitignore +0 -0
  55. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.pre-commit-config.yaml +0 -0
  56. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.prettierignore +0 -0
  57. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/.prettierrc.yaml +0 -0
  58. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/CONTRIBUTING.md +0 -0
  59. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/Dockerfile +0 -0
  60. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/LICENSE +0 -0
  61. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/agent.md +0 -0
  62. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/atlas.toml +0 -0
  63. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/adr/0000-template.md +0 -0
  64. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/adr/0001-memgraph-as-database.md +0 -0
  65. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/adr/0002-build-from-scratch.md +0 -0
  66. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/adr/0003-python-rust-hybrid.md +0 -0
  67. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/adr/0007-qualified-name-strategy.md +0 -0
  68. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/adr/README.md +0 -0
  69. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/guides/adding-languages.md +0 -0
  70. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/guides/configuration.md +0 -0
  71. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/guides/usage.md +0 -0
  72. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/docs/landscape.md +0 -0
  73. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/graph/__init__.py +0 -0
  74. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/indexing/watcher.py +0 -0
  75. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/__init__.py +0 -0
  76. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/ast.py +0 -0
  77. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/detectors.py +0 -0
  78. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/languages/__init__.py +0 -0
  79. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/languages/cpp.py +0 -0
  80. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/languages/go.py +0 -0
  81. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/languages/jvm.py +0 -0
  82. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/languages/markdown.py +0 -0
  83. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/languages/php.py +0 -0
  84. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/languages/python.py +0 -0
  85. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/languages/ruby.py +0 -0
  86. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/languages/rust.py +0 -0
  87. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/parsing/languages/typescript.py +0 -0
  88. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/search/__init__.py +0 -0
  89. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/search/guidance.py +0 -0
  90. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/server/__init__.py +0 -0
  91. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/server/analysis.py +0 -0
  92. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/server/health.py +0 -0
  93. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/src/code_atlas/telemetry.py +0 -0
  94. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/__init__.py +0 -0
  95. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/bench/__init__.py +0 -0
  96. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/bench/conftest.py +0 -0
  97. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/bench/test_bench_concurrent.py +0 -0
  98. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/bench/test_bench_indexing.py +0 -0
  99. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/bench/test_bench_memory.py +0 -0
  100. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/bench/test_bench_parser.py +0 -0
  101. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/bench/test_bench_query.py +0 -0
  102. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/__init__.py +0 -0
  103. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/conftest.py +0 -0
  104. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/graph/__init__.py +0 -0
  105. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/indexing/__init__.py +0 -0
  106. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/indexing/test_monorepo.py +0 -0
  107. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/indexing/test_orchestrator.py +0 -0
  108. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/indexing/test_watcher.py +0 -0
  109. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/search/__init__.py +0 -0
  110. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/search/test_embeddings.py +0 -0
  111. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/search/test_engine.py +0 -0
  112. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/server/__init__.py +0 -0
  113. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/integration/server/test_mcp.py +0 -0
  114. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/__init__.py +0 -0
  115. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/conftest.py +0 -0
  116. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/indexing/__init__.py +0 -0
  117. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/indexing/test_monorepo.py +0 -0
  118. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/indexing/test_orchestrator.py +0 -0
  119. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/indexing/test_watcher.py +0 -0
  120. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/parsing/__init__.py +0 -0
  121. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/parsing/test_cpp.py +0 -0
  122. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/parsing/test_detectors.py +0 -0
  123. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/parsing/test_go.py +0 -0
  124. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/parsing/test_jvm.py +0 -0
  125. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/parsing/test_php.py +0 -0
  126. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/parsing/test_python.py +0 -0
  127. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/parsing/test_ruby.py +0 -0
  128. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/parsing/test_rust.py +0 -0
  129. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/parsing/test_typescript.py +0 -0
  130. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/search/__init__.py +0 -0
  131. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/search/test_engine.py +0 -0
  132. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/search/test_guidance.py +0 -0
  133. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/server/__init__.py +0 -0
  134. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/server/test_health.py +0 -0
  135. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/server/test_mcp.py +0 -0
  136. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/test_cli.py +0 -0
  137. {code_atlas_mcp-0.2.0.dev1 → code_atlas_mcp-0.3.1}/tests/unit/test_telemetry.py +0 -0
@@ -0,0 +1,84 @@
1
+ # Default
2
+ # ==================
3
+ * text=auto eol=lf
4
+
5
+ # Python Source files
6
+ # =================
7
+ *.pxd text diff=python
8
+ *.py text diff=python
9
+ *.py3 text diff=python
10
+ *.pyw text diff=python
11
+ *.pyx text diff=python
12
+ *.pyz text diff=python
13
+ *.pyi text diff=python
14
+
15
+ # Python Binary files
16
+ # =================
17
+ *.db binary
18
+ *.p binary
19
+ *.pkl binary
20
+ *.pickle binary
21
+ *.pyc binary export-ignore
22
+ *.pyo binary export-ignore
23
+ *.pyd binary
24
+
25
+ # Jupyter notebook
26
+ # =================
27
+ *.ipynb text
28
+
29
+ # ML models
30
+ # =================
31
+ *.h5 filter=lfs diff=lfs merge=lfs -text
32
+ *.onnx filter=lfs diff=lfs merge=lfs -text
33
+ *.model filter=lfs diff=lfs merge=lfs -text
34
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
35
+ *.pb filter=lfs diff=lfs merge=lfs -text
36
+ *.pt filter=lfs diff=lfs merge=lfs -text
37
+ *.pth filter=lfs diff=lfs merge=lfs -text
38
+ pytorch_model.bin filter=lfs diff=lfs merge=lfs -text
39
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
40
+ unigram.json filter=lfs diff=lfs merge=lfs -text
41
+
42
+ # Data files
43
+ # =================
44
+ *.csv filter=lfs diff=lfs merge=lfs -text
45
+ *.tsv filter=lfs diff=lfs merge=lfs -text
46
+ *.parquet filter=lfs diff=lfs merge=lfs
47
+
48
+ # Presentation files
49
+ # =================
50
+ *.pptx filter=lfs diff=lfs merge=lfs -text
51
+ *.word filter=lfs diff=lfs merge=lfs -text
52
+ *.xlsx filter=lfs diff=lfs merge=lfs -text
53
+ *.xls filter=lfs diff=lfs merge=lfs -text
54
+ *.pdf filter=lfs diff=lfs merge=lfs -text
55
+
56
+ # Archives
57
+ # =================
58
+ *.7z filter=lfs diff=lfs merge=lfs -text
59
+ *.br filter=lfs diff=lfs merge=lfs -text
60
+ *.gz filter=lfs diff=lfs merge=lfs -text
61
+ *.tar filter=lfs diff=lfs merge=lfs -text
62
+ *.tgz filter=lfs diff=lfs merge=lfs -text
63
+ *.tar.gz filter=lfs diff=lfs merge=lfs -text
64
+ *.zip filter=lfs diff=lfs merge=lfs -text
65
+ *.rar filter=lfs diff=lfs merge=lfs -text
66
+
67
+ # Image files
68
+ # =================
69
+ *.jpg filter=lfs diff=lfs merge=lfs -text
70
+ *.jpeg filter=lfs diff=lfs merge=lfs -text
71
+ *.png filter=lfs diff=lfs merge=lfs -text
72
+ *.gif filter=lfs diff=lfs merge=lfs -text
73
+ *.webp filter=lfs diff=lfs merge=lfs -text
74
+ *.bmp filter=lfs diff=lfs merge=lfs -text
75
+ *.svg filter=lfs diff=lfs merge=lfs -text
76
+ *.tiff filter=lfs diff=lfs merge=lfs -text
77
+
78
+ # Other
79
+ # =================
80
+ # Windows - keep CRLF
81
+ *.exe filter=lfs diff=lfs merge=lfs -text
82
+ *.bat text eol=crlf
83
+ *.cmd text eol=crlf
84
+ *.ps1 text eol=crlf
@@ -31,19 +31,22 @@ jobs:
31
31
  contents: write
32
32
 
33
33
  steps:
34
+ - uses: actions/create-github-app-token@v1
35
+ id: app-token
36
+ with:
37
+ app-id: ${{ vars.RELEASE_APP_ID }}
38
+ private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
39
+
34
40
  - uses: actions/checkout@v6
35
41
  with:
36
42
  fetch-depth: 0
37
- ref: ${{ github.ref_name }}
38
-
39
- - name: Pin to triggering SHA
40
- run: git reset --hard ${{ github.sha }}
43
+ token: ${{ steps.app-token.outputs.token }}
41
44
 
42
45
  - name: Semantic Release
43
46
  id: release
44
47
  uses: python-semantic-release/python-semantic-release@v10
45
48
  with:
46
- github_token: ${{ secrets.GITHUB_TOKEN }}
49
+ github_token: ${{ steps.app-token.outputs.token }}
47
50
  git_committer_name: "github-actions[bot]"
48
51
  git_committer_email: "github-actions[bot]@users.noreply.github.com"
49
52
  force: ${{ inputs.force || '' }}
@@ -53,7 +56,7 @@ jobs:
53
56
  if: steps.release.outputs.released == 'true'
54
57
  uses: python-semantic-release/publish-action@v10
55
58
  with:
56
- github_token: ${{ secrets.GITHUB_TOKEN }}
59
+ github_token: ${{ steps.app-token.outputs.token }}
57
60
  tag: ${{ steps.release.outputs.tag }}
58
61
 
59
62
  outputs:
@@ -67,7 +70,7 @@ jobs:
67
70
  # ------------------------------------------------------------------- #
68
71
  publish-pypi:
69
72
  needs: release
70
- if: needs.release.outputs.released == 'true'
73
+ if: needs.release.outputs.released == 'true' && needs.release.outputs.is_prerelease != 'true'
71
74
  runs-on: ubuntu-latest
72
75
  environment:
73
76
  name: pypi
@@ -89,6 +92,15 @@ jobs:
89
92
  with:
90
93
  python-version: "3.14-dev"
91
94
 
95
+ - name: Verify version matches tag
96
+ run: |
97
+ TAG="${{ needs.release.outputs.tag }}"
98
+ TOML_VERSION=$(python -c "import tomllib; print('v' + tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
99
+ if [ "$TAG" != "$TOML_VERSION" ]; then
100
+ echo "::error::Tag $TAG does not match pyproject.toml version $TOML_VERSION"
101
+ exit 1
102
+ fi
103
+
92
104
  - run: uv build
93
105
 
94
106
  - uses: pypa/gh-action-pypi-publish@release/v1
@@ -2,6 +2,47 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v0.3.1 (2026-03-07)
6
+
7
+ ### Bug Fixes
8
+
9
+ - **ci**: Use GitHub App token to push to protected main branch
10
+ ([`13b46b9`](https://github.com/SerPeter/code-atlas/commit/13b46b972f900e4d1170b9c42af0c40d9c0cf35c))
11
+
12
+
13
+ ## v0.3.0 (2026-03-04)
14
+
15
+ ### Features
16
+
17
+ - **indexing**: Add file hash gate to skip unchanged files
18
+ ([#9](https://github.com/SerPeter/code-atlas/pull/9))
19
+ - **indexing**: Add per-file cooldown for daemon mode
20
+ ([#9](https://github.com/SerPeter/code-atlas/pull/9))
21
+
22
+ ### Performance Improvements
23
+
24
+ - Reduce RTTs across indexing and query pipelines
25
+ ([`cf3a519`](https://github.com/SerPeter/code-atlas/commit/cf3a519))
26
+
27
+ ### Refactoring
28
+
29
+ - **indexing**: Eliminate Tier 1 consumer, simplify to two-tier pipeline
30
+ ([#9](https://github.com/SerPeter/code-atlas/pull/9))
31
+ - **indexing**: Rename Tier 2/3 to AST/Embed stage across code and docs
32
+ ([#9](https://github.com/SerPeter/code-atlas/pull/9))
33
+
34
+ ### Bug Fixes
35
+
36
+ - **ci**: Remove detached HEAD checkout in release workflow
37
+
38
+ ## v0.2.0-dev.2 (2026-02-23)
39
+
40
+ ### Bug Fixes
41
+
42
+ - **indexing**: Label-constrained queries, PEL reclaim, and drain progress
43
+ ([`9ec9150`](https://github.com/SerPeter/code-atlas/commit/9ec915088058b05396a506ca23bfd0a0492d67f6))
44
+
45
+
5
46
  ## v0.2.0-dev.1 (2026-02-23)
6
47
 
7
48
  ### Bug Fixes
@@ -13,14 +54,15 @@
13
54
  - **ci**: Resolve ty check failures with --all-extras in CI
14
55
  ([`3f74816`](https://github.com/SerPeter/code-atlas/commit/3f7481635091d2d676aed75c3fbcaa5db4332242))
15
56
 
16
- - **consumers**: Group batches by project in Tier1/Tier2
57
+ - **consumers**: Group batches by project in AST/Embed consumers
17
58
  ([#2](https://github.com/SerPeter/code-atlas/pull/2),
18
59
  [`5107b24`](https://github.com/SerPeter/code-atlas/commit/5107b24a7dfbcb44cadc7917f632ae6a9743c057))
19
60
 
20
61
  ### Build System
21
62
 
22
63
  - **release**: Add python-semantic-release v10 for automated releases
23
- ([`044e9a3`](https://github.com/SerPeter/code-atlas/commit/044e9a31c5f7673a4be45a6519860d247e1b3cb1))
64
+ ([#5](https://github.com/SerPeter/code-atlas/pull/5),
65
+ [`de9c06d`](https://github.com/SerPeter/code-atlas/commit/de9c06d8c1e1744a92ff7ef160e06f859b5aa768))
24
66
 
25
67
  ### Features
26
68
 
@@ -181,7 +223,7 @@
181
223
  - **docs**: Add markdown parser with tree-sitter-markdown
182
224
  ([`e8d372c`](https://github.com/SerPeter/code-atlas/commit/e8d372c162652d6d73d1f66da5e14a61fcb2136a))
183
225
 
184
- - **embeddings**: Add EmbedClient with litellm routing and Tier 3 pipeline
226
+ - **embeddings**: Add EmbedClient with litellm routing and embed pipeline
185
227
  ([`ad7c972`](https://github.com/SerPeter/code-atlas/commit/ad7c9726f2e48fdb8746b50547089c5c483bcb75))
186
228
 
187
229
  - **embeddings**: Add three-tier embedding cache with Valkey backend
@@ -232,7 +274,7 @@
232
274
  - **naming**: Worktree-aware naming and monorepo sub-project prefixing
233
275
  ([`2acdfb3`](https://github.com/SerPeter/code-atlas/commit/2acdfb33ba4b486f966272a01cf8a37f670661f6))
234
276
 
235
- - **parser**: Add py-tree-sitter parser, implement Tier 2 pipeline, drop Rust
277
+ - **parser**: Add py-tree-sitter parser, implement AST pipeline, drop Rust
236
278
  ([`d56e7d2`](https://github.com/SerPeter/code-atlas/commit/d56e7d2a686ec279a52d85bbc4903f4d85f51a4e))
237
279
 
238
280
  - **parsing**: Add multi-language support (10 languages, 7 modules)
@@ -51,7 +51,7 @@ src/code_atlas/
51
51
  ├── __init__.py # __version__ only
52
52
  ├── schema.py # Graph schema (labels, relationships, DDL generators)
53
53
  ├── settings.py # Pydantic configuration (atlas.toml + env vars)
54
- ├── events.py # Event types (FileChanged, ASTDirty, EmbedDirty) + Valkey Streams EventBus
54
+ ├── events.py # Event types (FileChanged, EmbedDirty) + Valkey Streams EventBus
55
55
  ├── telemetry.py # OpenTelemetry integration
56
56
  ├── cli.py # Typer CLI entrypoint (index, search, status, mcp, daemon commands)
57
57
 
@@ -69,7 +69,7 @@ src/code_atlas/
69
69
 
70
70
  ├── indexing/
71
71
  │ ├── orchestrator.py # Full-index, monorepo detection, staleness checking
72
- │ ├── consumers.py # Tier 1/2/3 event consumers (batch-pull pattern)
72
+ │ ├── consumers.py # AST + Embed event consumers (batch-pull pattern)
73
73
  │ ├── watcher.py # Filesystem watcher (watchfiles + hybrid debounce)
74
74
  │ └── daemon.py # Daemon lifecycle manager (watcher + pipeline)
75
75
 
@@ -78,12 +78,14 @@ src/code_atlas/
78
78
  └── health.py # Infrastructure health checks + diagnostics
79
79
  ```
80
80
 
81
- **Event Pipeline:** File Watcher → Valkey Streams → Tier 1 (graph metadata) Tier 2 (AST diff + gate) → Tier 3 (embeddings) → Memgraph
81
+ **Event Pipeline:** File Watcher → Valkey Streams → AST stage (hash gate + parse + diff) → Embed stage (embeddings) → Memgraph
82
82
 
83
83
  **Query Pipeline:** MCP Server → Query Router → [Graph Search | Vector Search | BM25 Search] → RRF Fusion → Results
84
84
 
85
85
  **Deployment:** Daemon (`atlas daemon start`) for indexing + MCP (`atlas mcp`) per agent session, decoupled via Valkey + Memgraph
86
86
 
87
+ **Event model:** Events are atomic — one logical change per event (one file per FileChanged, one entity per EmbedDirty). Never bundle lists of work items into a single event; use `EventBus.publish_many()` for network-efficient batch publishing. The consumer's `max_batch_size` must directly control work volume, not just message count.
88
+
87
89
  **Infrastructure:** Memgraph (graph DB, port 7687), TEI (embeddings, port 8080), Valkey (event bus, port 6379)
88
90
 
89
91
  ## Code Style
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-atlas-mcp
3
- Version: 0.2.0.dev1
3
+ Version: 0.3.1
4
4
  Summary: A code intelligence graph that gives AI coding agents deep, token-efficient understanding of your codebase.
5
5
  Project-URL: Homepage, https://github.com/SerPeter/code-atlas
6
6
  Project-URL: Documentation, https://github.com/SerPeter/code-atlas/tree/main/docs
@@ -27,11 +27,13 @@ Requires-Dist: loguru~=0.7
27
27
  Requires-Dist: mcp~=1.26
28
28
  Requires-Dist: neo4j~=6.1
29
29
  Requires-Dist: numpy~=2.4
30
+ Requires-Dist: orjson>=3.10
30
31
  Requires-Dist: pathspec~=1.0
31
32
  Requires-Dist: pydantic-settings~=2.12
32
33
  Requires-Dist: pydantic~=2.12
33
34
  Requires-Dist: python-dotenv~=1.1
34
35
  Requires-Dist: redis[hiredis]~=7.1
36
+ Requires-Dist: tenacity~=9.1
35
37
  Requires-Dist: tiktoken~=0.12
36
38
  Requires-Dist: tree-sitter-markdown~=0.5
37
39
  Requires-Dist: tree-sitter-python~=0.23
@@ -130,30 +132,30 @@ For a detailed comparison covering DeepWiki, Cursor, Sourcegraph Cody, Kit, code
130
132
 
131
133
  15 tools exposed via the [Model Context Protocol](https://modelcontextprotocol.io/), designed to minimize context window overhead.
132
134
 
133
- | Tool | What it does | Search | Full |
134
- | ---------------------- | -------------------------------------------------------------------------------------------- | -----: | ---: |
135
- | **Search** | | | |
136
- | `hybrid_search` | **Primary tool** — fuses graph + BM25 + vector via RRF. Auto-adjusts weights by query shape. | ~117 | ~497 |
137
- | `text_search` | BM25 keyword search. Quoted phrases, wildcards, field-specific queries. | ~90 | ~275 |
138
- | `vector_search` | Semantic similarity via embeddings. Finds code by meaning, not name. | ~67 | ~297 |
139
- | `get_node` | Find entities by name. Cascade: exact uid name → suffix prefix contains. | ~100 | ~254 |
140
- | **Navigation** | | | |
141
- | `get_context` | Expand a node's neighborhood: parent, siblings, callers, callees, docs. | ~64 | ~273 |
142
- | `cypher_query` | Run read-only Cypher against the graph. Auto-limited, write-protected. | ~59 | ~168 |
143
- | **Analysis** | | | |
144
- | `analyze_repo` | Structure, centrality, dependencies, or pattern analysis. | ~41 | ~266 |
145
- | `generate_diagram` | Mermaid diagrams: packages, imports, inheritance, module detail. | ~37 | ~254 |
146
- | **Guidance** | | | |
147
- | `get_usage_guide` | Quick-start or topic-specific guidance for the agent. | ~35 | ~106 |
148
- | `plan_search_strategy` | Recommends which search tool + params for a question. | ~40 | ~97 |
149
- | `validate_cypher` | Catches Cypher errors before execution. | ~58 | ~116 |
150
- | `schema_info` | Full graph schema: labels, relationships, Cypher examples. | ~75 | ~96 |
151
- | **Status** | | | |
152
- | `index_status` | Projects, entity counts, schema version, index health. | ~72 | ~93 |
153
- | `list_projects` | Monorepo project list with dependency relationships. | ~56 | ~77 |
154
- | `health_check` | Infrastructure diagnostics: Memgraph, TEI, Valkey, schema. | ~55 | ~76 |
155
-
156
- Token counts measured from MCP JSON tool definitions (tiktoken cl100k_base). **Search** = name + description (~966 total); **Full** = name + description + parameter schema with field descriptions, enums, and constraints (~2,945 total). All parameters are self-documented — agents can one-shot any tool without calling `get_usage_guide` first.
135
+ | Tool | What it does | Search | Full | Latency (avg / p95) |
136
+ | ---------------------- | -------------------------------------------------------------------------------------------- | -----: | ---: | ------------------: |
137
+ | **Search** | | | | |
138
+ | `hybrid_search` | **Primary tool** — fuses graph + BM25 + vector via RRF. Auto-adjusts weights by query shape. | ~117 | ~497 | 548 / 677 ms |
139
+ | `text_search` | BM25 keyword search. Quoted phrases, wildcards, field-specific queries. | ~90 | ~275 | 34 / 36 ms |
140
+ | `vector_search` | Semantic similarity via embeddings. Finds code by meaning, not name. | ~67 | ~297 | 102 / 125 ms |
141
+ | `get_node` | Find entities by name. Cascade: exact (uid + name)partial (suffix > prefix > contains). | ~100 | ~254 | 7 / 8 ms |
142
+ | **Navigation** | | | | |
143
+ | `get_context` | Expand a node's neighborhood: parent, siblings, callers, callees, docs. | ~64 | ~273 | 34 / 36 ms |
144
+ | `cypher_query` | Run read-only Cypher against the graph. Auto-limited, write-protected. | ~59 | ~168 | 3 / 3 ms |
145
+ | **Analysis** | | | | |
146
+ | `analyze_repo` | Structure, centrality, dependencies, pattern, or quality analysis. | ~41 | ~266 | 22 / 23 ms |
147
+ | `generate_diagram` | Mermaid diagrams: packages, imports, inheritance, module detail. | ~37 | ~254 | 3 / 3 ms |
148
+ | **Guidance** | | | | |
149
+ | `get_usage_guide` | Quick-start or topic-specific guidance for the agent. | ~35 | ~106 | < 1 / < 1 ms |
150
+ | `plan_search_strategy` | Recommends which search tool + params for a question. | ~40 | ~97 | < 1 / < 1 ms |
151
+ | `validate_cypher` | Catches Cypher errors before execution. | ~58 | ~116 | 1 / 2 ms |
152
+ | `schema_info` | Full graph schema: labels, relationships, Cypher examples. | ~75 | ~96 | < 1 / < 1 ms |
153
+ | **Status** | | | | |
154
+ | `index_status` | Projects, entity counts, schema version, index health. | ~72 | ~93 | 22 / 23 ms |
155
+ | `list_projects` | Monorepo project list with dependency relationships. | ~56 | ~77 | 12 / 13 ms |
156
+ | `health_check` | Infrastructure diagnostics: Memgraph, TEI, Valkey, schema. | ~55 | ~76 | 218 / 264 ms |
157
+
158
+ Token counts measured from MCP JSON tool definitions (tiktoken cl100k_base). **Search** = name + description (~966 total); **Full** = name + description + parameter schema with field descriptions, enums, and constraints (~2,945 total). All parameters are self-documented — agents can one-shot any tool without calling `get_usage_guide` first. **Latency** measured with local TEI embeddings on the code-atlas repo (~1,400 entities), 5 iterations, warm embedding cache. See `scripts/profile_query.py`.
157
159
 
158
160
  ## Quick Start
159
161
 
@@ -220,15 +222,15 @@ uv run pre-commit install
220
222
 
221
223
  ## Performance
222
224
 
223
- | Metric | Value |
224
- | ------------------- | --------------------- |
225
- | Parse throughput | **600–700 files/sec** |
226
- | Graph search (p50) | 8 ms |
227
- | BM25 search (p50) | 10 ms |
228
- | Vector search (p50) | 47 ms |
229
- | Concurrent QPS | **238** (zero errors) |
225
+ | Metric | Value |
226
+ | -------------------------- | --------------------- |
227
+ | Full index (107 files) | **55s** (local TEI) |
228
+ | Parse-only throughput | **600–700 files/sec** |
229
+ | `get_node` / `text_search` | 7 ms / 34 ms |
230
+ | `vector_search` | 102 ms |
231
+ | Concurrent QPS | **238** (zero errors) |
230
232
 
231
- Full benchmark tables and methodology: [docs/benchmarks.md](docs/benchmarks.md)
233
+ Full index includes parsing, graph upserts, and embedding via local TEI (8 concurrent workers). Parse-only is raw tree-sitter CPU time without I/O. Query latencies are averages from `scripts/profile_query.py`. Full benchmark tables: [docs/benchmarks.md](docs/benchmarks.md)
232
234
 
233
235
  ## Documentation
234
236
 
@@ -54,30 +54,30 @@ For a detailed comparison covering DeepWiki, Cursor, Sourcegraph Cody, Kit, code
54
54
 
55
55
  15 tools exposed via the [Model Context Protocol](https://modelcontextprotocol.io/), designed to minimize context window overhead.
56
56
 
57
- | Tool | What it does | Search | Full |
58
- | ---------------------- | -------------------------------------------------------------------------------------------- | -----: | ---: |
59
- | **Search** | | | |
60
- | `hybrid_search` | **Primary tool** — fuses graph + BM25 + vector via RRF. Auto-adjusts weights by query shape. | ~117 | ~497 |
61
- | `text_search` | BM25 keyword search. Quoted phrases, wildcards, field-specific queries. | ~90 | ~275 |
62
- | `vector_search` | Semantic similarity via embeddings. Finds code by meaning, not name. | ~67 | ~297 |
63
- | `get_node` | Find entities by name. Cascade: exact uid name → suffix prefix contains. | ~100 | ~254 |
64
- | **Navigation** | | | |
65
- | `get_context` | Expand a node's neighborhood: parent, siblings, callers, callees, docs. | ~64 | ~273 |
66
- | `cypher_query` | Run read-only Cypher against the graph. Auto-limited, write-protected. | ~59 | ~168 |
67
- | **Analysis** | | | |
68
- | `analyze_repo` | Structure, centrality, dependencies, or pattern analysis. | ~41 | ~266 |
69
- | `generate_diagram` | Mermaid diagrams: packages, imports, inheritance, module detail. | ~37 | ~254 |
70
- | **Guidance** | | | |
71
- | `get_usage_guide` | Quick-start or topic-specific guidance for the agent. | ~35 | ~106 |
72
- | `plan_search_strategy` | Recommends which search tool + params for a question. | ~40 | ~97 |
73
- | `validate_cypher` | Catches Cypher errors before execution. | ~58 | ~116 |
74
- | `schema_info` | Full graph schema: labels, relationships, Cypher examples. | ~75 | ~96 |
75
- | **Status** | | | |
76
- | `index_status` | Projects, entity counts, schema version, index health. | ~72 | ~93 |
77
- | `list_projects` | Monorepo project list with dependency relationships. | ~56 | ~77 |
78
- | `health_check` | Infrastructure diagnostics: Memgraph, TEI, Valkey, schema. | ~55 | ~76 |
79
-
80
- Token counts measured from MCP JSON tool definitions (tiktoken cl100k_base). **Search** = name + description (~966 total); **Full** = name + description + parameter schema with field descriptions, enums, and constraints (~2,945 total). All parameters are self-documented — agents can one-shot any tool without calling `get_usage_guide` first.
57
+ | Tool | What it does | Search | Full | Latency (avg / p95) |
58
+ | ---------------------- | -------------------------------------------------------------------------------------------- | -----: | ---: | ------------------: |
59
+ | **Search** | | | | |
60
+ | `hybrid_search` | **Primary tool** — fuses graph + BM25 + vector via RRF. Auto-adjusts weights by query shape. | ~117 | ~497 | 548 / 677 ms |
61
+ | `text_search` | BM25 keyword search. Quoted phrases, wildcards, field-specific queries. | ~90 | ~275 | 34 / 36 ms |
62
+ | `vector_search` | Semantic similarity via embeddings. Finds code by meaning, not name. | ~67 | ~297 | 102 / 125 ms |
63
+ | `get_node` | Find entities by name. Cascade: exact (uid + name)partial (suffix > prefix > contains). | ~100 | ~254 | 7 / 8 ms |
64
+ | **Navigation** | | | | |
65
+ | `get_context` | Expand a node's neighborhood: parent, siblings, callers, callees, docs. | ~64 | ~273 | 34 / 36 ms |
66
+ | `cypher_query` | Run read-only Cypher against the graph. Auto-limited, write-protected. | ~59 | ~168 | 3 / 3 ms |
67
+ | **Analysis** | | | | |
68
+ | `analyze_repo` | Structure, centrality, dependencies, pattern, or quality analysis. | ~41 | ~266 | 22 / 23 ms |
69
+ | `generate_diagram` | Mermaid diagrams: packages, imports, inheritance, module detail. | ~37 | ~254 | 3 / 3 ms |
70
+ | **Guidance** | | | | |
71
+ | `get_usage_guide` | Quick-start or topic-specific guidance for the agent. | ~35 | ~106 | < 1 / < 1 ms |
72
+ | `plan_search_strategy` | Recommends which search tool + params for a question. | ~40 | ~97 | < 1 / < 1 ms |
73
+ | `validate_cypher` | Catches Cypher errors before execution. | ~58 | ~116 | 1 / 2 ms |
74
+ | `schema_info` | Full graph schema: labels, relationships, Cypher examples. | ~75 | ~96 | < 1 / < 1 ms |
75
+ | **Status** | | | | |
76
+ | `index_status` | Projects, entity counts, schema version, index health. | ~72 | ~93 | 22 / 23 ms |
77
+ | `list_projects` | Monorepo project list with dependency relationships. | ~56 | ~77 | 12 / 13 ms |
78
+ | `health_check` | Infrastructure diagnostics: Memgraph, TEI, Valkey, schema. | ~55 | ~76 | 218 / 264 ms |
79
+
80
+ Token counts measured from MCP JSON tool definitions (tiktoken cl100k_base). **Search** = name + description (~966 total); **Full** = name + description + parameter schema with field descriptions, enums, and constraints (~2,945 total). All parameters are self-documented — agents can one-shot any tool without calling `get_usage_guide` first. **Latency** measured with local TEI embeddings on the code-atlas repo (~1,400 entities), 5 iterations, warm embedding cache. See `scripts/profile_query.py`.
81
81
 
82
82
  ## Quick Start
83
83
 
@@ -144,15 +144,15 @@ uv run pre-commit install
144
144
 
145
145
  ## Performance
146
146
 
147
- | Metric | Value |
148
- | ------------------- | --------------------- |
149
- | Parse throughput | **600–700 files/sec** |
150
- | Graph search (p50) | 8 ms |
151
- | BM25 search (p50) | 10 ms |
152
- | Vector search (p50) | 47 ms |
153
- | Concurrent QPS | **238** (zero errors) |
147
+ | Metric | Value |
148
+ | -------------------------- | --------------------- |
149
+ | Full index (107 files) | **55s** (local TEI) |
150
+ | Parse-only throughput | **600–700 files/sec** |
151
+ | `get_node` / `text_search` | 7 ms / 34 ms |
152
+ | `vector_search` | 102 ms |
153
+ | Concurrent QPS | **238** (zero errors) |
154
154
 
155
- Full benchmark tables and methodology: [docs/benchmarks.md](docs/benchmarks.md)
155
+ Full index includes parsing, graph upserts, and embedding via local TEI (8 concurrent workers). Parse-only is raw tree-sitter CPU time without I/O. Query latencies are averages from `scripts/profile_query.py`. Full benchmark tables: [docs/benchmarks.md](docs/benchmarks.md)
156
156
 
157
157
  ## Documentation
158
158
 
@@ -34,8 +34,12 @@ services:
34
34
  - "6379:6379"
35
35
  volumes:
36
36
  - valkey-data:/data
37
+ deploy:
38
+ resources:
39
+ limits:
40
+ memory: 384m
37
41
  command: >
38
- valkey-server --appendonly no --save "" --maxmemory 64mb --maxmemory-policy noeviction
42
+ valkey-server --appendonly no --save "" --maxmemory 256mb --maxmemory-policy noeviction
39
43
  healthcheck:
40
44
  test: ["CMD", "valkey-cli", "ping"]
41
45
  interval: 10s
@@ -54,6 +58,13 @@ services:
54
58
  - "8080:80"
55
59
  volumes:
56
60
  - tei-models:/data
61
+ deploy:
62
+ resources:
63
+ limits:
64
+ memory: 4g
65
+ reservations:
66
+ memory: 1g
67
+ command: --auto-truncate
57
68
  environment:
58
69
  MODEL_ID: ${TEI_MODEL:-Qwen/Qwen3-Embedding-0.6B}
59
70
  healthcheck:
@@ -45,53 +45,50 @@ Redis Streams provide the pub/sub backbone with consumer groups:
45
45
  Typed frozen dataclasses with JSON serialization for Redis transport:
46
46
 
47
47
  - `FileChanged(path, change_type, timestamp)` — published by file watcher
48
- - `ASTDirty(paths, batch_id)` — published by Tier 1
49
- - `EmbedDirty(entities: list[EntityRef], significance, batch_id)` — published by Tier 2
48
+ - `EmbedDirty(entities: list[EntityRef], significance, batch_id)` — published by AST stage
50
49
 
51
- ### Three-Stream Pipeline
50
+ ### Two-Stage Pipeline
52
51
 
53
52
  ```
54
- atlas:file-changed atlas:ast-dirty atlas:embed-dirty
55
- stream stream stream
56
-
57
- ┌──────▼───────┐ ┌──────▼───────┐ ┌──────▼───────┐
58
- File Watcher ────► │ Tier 1 ──────► │ Tier 2 ─gate─►│ Tier 3
59
- Graph Metadata│ alwaysAST Diff + only │ Embeddings │
60
- (0.5s batch) │ │ Graph Update if sig │ (15s batch) │
61
- └──────────────┘ │ (3s batch) │ change └──────────────┘
62
- └──────────────┘
53
+ atlas:file-changed atlas:embed-dirty
54
+ stream stream
55
+
56
+ ┌──────▼───────┐ ┌──────▼───────┐
57
+ File Watcher ────► │ AST Stage─────── significance gate ───► Embed Stage
58
+ hash gate +only if semantically changed │ Embeddings │
59
+ parse + diff │ (15s batch) │
60
+ │ (3s batch) │ └──────────────┘
61
+ └──────────────┘
63
62
  ```
64
63
 
65
- Each tier pulls at its own pace via `XREADGROUP`, deduplicates within its batch window, and publishes downstream only if
66
- warranted.
64
+ Each stage pulls at its own pace via `XREADGROUP`, deduplicates within its batch window, and publishes downstream only
65
+ if warranted.
67
66
 
68
67
  ### Per-Consumer Batch Policy
69
68
 
70
- | Tier | Window | Max Batch | Dedup Key |
71
- | -------------- | ------ | --------- | --------------------- |
72
- | Tier 1 (Graph) | 0.5s | 50 | File path |
73
- | Tier 2 (AST) | 3.0s | 20 | File path |
74
- | Tier 3 (Embed) | 15.0s | 100 | Entity qualified name |
69
+ | Stage | Window | Max Batch | Dedup Key |
70
+ | ----- | ------ | --------- | --------------------- |
71
+ | AST | 3.0s | 30 | File path |
72
+ | Embed | 15.0s | 100 | Entity qualified name |
75
73
 
76
74
  Hybrid batching: flush when count OR time threshold hit, whichever first. Same file changed 5× in window = 1 work item.
77
75
 
78
76
  ### Event Data Flow
79
77
 
80
78
  ```
81
- FileChanged ASTDirty EmbedDirty
82
- ┌─────────────┐ ┌──────────────────┐ ┌──────────────────────────┐
83
- │ path: str │ paths: [str] │ │ entities: [EntityRef]
84
- │ change_type │ ─Tier 1──► batch_id: str │ ─Tier 2─►│ significance: str │
85
- │ timestamp │ └──────────────────┘ gate │ batch_id: str │
86
- └─────────────┘ └──────────────────────────┘
87
- EntityRef:
88
- qualified_name, node_type,
89
- file_path
79
+ FileChanged EmbedDirty
80
+ ┌─────────────┐ ┌──────────────────────────┐
81
+ │ path: str │ entity: EntityRef
82
+ │ change_type │ ─── AST stage ── sig gate ────────► significance: str │
83
+ │ timestamp │ └──────────────────────────┘
84
+ └─────────────┘ EntityRef:
85
+ qualified_name, node_type,
86
+ file_path
90
87
  ```
91
88
 
92
- ### Significance Gating (Tier 2 3)
89
+ ### Significance Gating (ASTEmbed)
93
90
 
94
- Tier 2 evaluates whether a change is semantically significant enough to warrant re-embedding:
91
+ The AST stage evaluates whether a change is semantically significant enough to warrant re-embedding:
95
92
 
96
93
  | Condition | Level | Action |
97
94
  | --------------------------- | -------- | ------------------- |
@@ -115,25 +112,25 @@ own retries through this mechanism, avoiding the need for a separate dead-letter
115
112
  - Cheap operations (staleness flags, graph metadata) are near-instant — MCP queries reflect changes within ~1s
116
113
  - Expensive operations (embeddings) only run when semantically justified — significant cost reduction
117
114
  - Decoupled stages can be developed, tested, and scaled independently
118
- - Batching per tier matches the cost profile of each operation
115
+ - Batching per stage matches the cost profile of each operation
119
116
  - Multi-process from day one — no rewrite needed when scaling
120
117
  - Dual-use of Valkey for event bus + embedding cache
121
- - Natural extension point: new tiers or event types can be added without restructuring
118
+ - Natural extension point: new stages or event types can be added without restructuring
122
119
 
123
120
  ### Negative
124
121
 
125
122
  - More architectural complexity than a simple "reindex everything on change"
126
123
  - Significance threshold heuristics need tuning and may produce false negatives (skipping re-embeds that should have
127
124
  happened)
128
- - Debugging event flow across tiers is harder than a linear pipeline
125
+ - Debugging event flow across stages is harder than a linear pipeline
129
126
  - Additional infrastructure dependency (Valkey), though lightweight
130
127
 
131
128
  ### Risks
132
129
 
133
130
  - Threshold tuning: too aggressive = stale embeddings, too conservative = excessive TEI calls. Need observability on
134
131
  gate decisions.
135
- - Event ordering: if Tier 2 processes file A before file B, but B depends on A's entities, the diff may be incorrect.
136
- Batch boundaries must align with dependency boundaries.
132
+ - Event ordering: if the AST stage processes file A before file B, but B depends on A's entities, the diff may be
133
+ incorrect. Batch boundaries must align with dependency boundaries.
137
134
  - Complexity creep: the event bus must stay simple. If we find ourselves adding routing rules, dead-letter queues, or
138
135
  retry logic, we've gone too far.
139
136