kernel-lore-mcp 0.3.3__tar.gz → 0.3.4__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 (279) hide show
  1. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/CHANGELOG.md +27 -0
  2. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/Cargo.lock +1 -1
  3. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/Cargo.toml +2 -2
  4. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/PKG-INFO +1 -1
  5. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/pyproject.toml +4 -1
  6. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/bin/ingest.rs +10 -3
  7. kernel_lore_mcp-0.3.4/src/bin/reindex.rs +213 -0
  8. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/bin/sync.rs +128 -45
  9. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/__init__.py +1 -1
  10. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/__main__.py +7 -44
  11. kernel_lore_mcp-0.3.4/src/kernel_lore_mcp/cli/reindex.py +148 -0
  12. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/health.py +79 -0
  13. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/resources/coverage_stats.py +1 -1
  14. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/routes/status.py +16 -16
  15. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/corpus_stats.py +8 -12
  16. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/path_mentions.py +15 -4
  17. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/reader.rs +63 -28
  18. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_cost_class.py +13 -11
  19. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_coverage_stats.py +3 -1
  20. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_mcp_tools_e2e.py +1 -1
  21. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_path_mentions.py +30 -3
  22. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_resources_routes.py +20 -0
  23. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_status_subcommand.py +30 -0
  24. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/uv.lock +1 -1
  25. kernel_lore_mcp-0.3.3/src/bin/reindex.rs +0 -15
  26. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/.github/workflows/ci.yml +0 -0
  27. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/.github/workflows/release.yml +0 -0
  28. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/.gitignore +0 -0
  29. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/.python-version +0 -0
  30. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/CLAUDE.md +0 -0
  31. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/CONTRIBUTING.md +0 -0
  32. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/GOVERNANCE.md +0 -0
  33. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/LEGAL.md +0 -0
  34. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/LICENSE +0 -0
  35. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/README.md +0 -0
  36. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/SECURITY.md +0 -0
  37. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/TODO.md +0 -0
  38. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/README.md +0 -0
  39. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/architecture/data-flow.md +0 -0
  40. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/architecture/deployment-modes.md +0 -0
  41. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/architecture/four-tier-index.md +0 -0
  42. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/architecture/over-db.md +0 -0
  43. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/architecture/overview.md +0 -0
  44. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/architecture/reciprocity.md +0 -0
  45. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/architecture/trade-offs.md +0 -0
  46. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/demos/first-session.md +0 -0
  47. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/indexing/bm25-tier.md +0 -0
  48. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/indexing/compressed-store.md +0 -0
  49. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/indexing/metadata-tier.md +0 -0
  50. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/indexing/path-tier.md +0 -0
  51. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/indexing/tokenizer-spec.md +0 -0
  52. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/indexing/trigram-tier.md +0 -0
  53. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ingestion/grokmirror.md +0 -0
  54. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ingestion/mbox-parsing.md +0 -0
  55. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ingestion/patch-parsing.md +0 -0
  56. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ingestion/shard-walking.md +0 -0
  57. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/mcp/client-config.md +0 -0
  58. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/mcp/query-routing.md +0 -0
  59. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/mcp/tools.md +0 -0
  60. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/mcp/transport-auth.md +0 -0
  61. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ops/corpus-coverage.md +0 -0
  62. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ops/cost-model.md +0 -0
  63. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ops/ec2-sizing.md +0 -0
  64. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ops/monitoring.md +0 -0
  65. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ops/production-hardening.md +0 -0
  66. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ops/public-launch-checklist.md +0 -0
  67. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ops/runbook.md +0 -0
  68. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ops/threat-model.md +0 -0
  69. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ops/update-cadence.md +0 -0
  70. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/ops/update-frequency.md +0 -0
  71. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/plans/2026-04-14-best-in-class-kernel-mcp.md +0 -0
  72. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/plans/2026-04-15-internalize-grokmirror.md +0 -0
  73. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/plans/2026-04-15-mcp-spec-coverage-and-uplift.md +0 -0
  74. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/plans/2026-04-17-overdb-followups.md +0 -0
  75. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/plans/2026-04-17-overdb-metadata-tier.md +0 -0
  76. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/plans/2026-04-20-v0.3.0-plan.md +0 -0
  77. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/plans/2026-04-22-v0.3.1-plan.md +0 -0
  78. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-14-agent-ergonomics.md +0 -0
  79. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-14-best-in-class-mcp-survey.md +0 -0
  80. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-14-external-data-sources.md +0 -0
  81. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-14-gix-vs-git2.md +0 -0
  82. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-14-mcp-python-sdk.md +0 -0
  83. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-14-pyo3-maturin.md +0 -0
  84. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-14-search-library-landscape.md +0 -0
  85. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-14-storage-footprint.md +0 -0
  86. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-14-tantivy.md +0 -0
  87. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-14-workflow-gap-analysis.md +0 -0
  88. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-15-fuzzy-search-design.md +0 -0
  89. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-15-path-mentions.md +0 -0
  90. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/2026-04-17-overdb-validation.md +0 -0
  91. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/research/training-retriever.md +0 -0
  92. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/README.md +0 -0
  93. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/checklists/01-research.md +0 -0
  94. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/checklists/02-design.md +0 -0
  95. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/checklists/03-implement.md +0 -0
  96. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/checklists/04-test.md +0 -0
  97. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/checklists/05-quality.md +0 -0
  98. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/checklists/06-review.md +0 -0
  99. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/checklists/07-commit.md +0 -0
  100. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/checklists/08-debug.md +0 -0
  101. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/checklists/09-optimize.md +0 -0
  102. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/checklists/10-document.md +0 -0
  103. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/checklists/index.md +0 -0
  104. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/code-quality.md +0 -0
  105. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/data-structures.md +0 -0
  106. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/design/boundaries.md +0 -0
  107. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/design/concurrency.md +0 -0
  108. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/design/dependencies.md +0 -0
  109. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/design/errors.md +0 -0
  110. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/design/modules.md +0 -0
  111. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/git.md +0 -0
  112. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/index.md +0 -0
  113. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/language.md +0 -0
  114. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/libraries/fastmcp.md +0 -0
  115. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/libraries/httpx.md +0 -0
  116. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/libraries/pydantic.md +0 -0
  117. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/libraries/structlog.md +0 -0
  118. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/naming.md +0 -0
  119. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/pyo3-maturin.md +0 -0
  120. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/testing.md +0 -0
  121. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/python/uv.md +0 -0
  122. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/cargo.md +0 -0
  123. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/checklists/01-research.md +0 -0
  124. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/checklists/02-design.md +0 -0
  125. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/checklists/03-implement.md +0 -0
  126. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/checklists/04-test.md +0 -0
  127. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/checklists/05-quality.md +0 -0
  128. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/checklists/06-review.md +0 -0
  129. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/checklists/07-commit.md +0 -0
  130. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/checklists/08-debug.md +0 -0
  131. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/checklists/09-optimize.md +0 -0
  132. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/checklists/10-document.md +0 -0
  133. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/checklists/index.md +0 -0
  134. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/code-quality.md +0 -0
  135. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/design/boundaries.md +0 -0
  136. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/design/concurrency.md +0 -0
  137. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/design/data-structures.md +0 -0
  138. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/design/errors.md +0 -0
  139. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/design/modules.md +0 -0
  140. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/ffi.md +0 -0
  141. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/index.md +0 -0
  142. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/language.md +0 -0
  143. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/libraries/arrow-parquet.md +0 -0
  144. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/libraries/gix.md +0 -0
  145. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/libraries/pyo3.md +0 -0
  146. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/libraries/regex-automata.md +0 -0
  147. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/libraries/roaring-fst.md +0 -0
  148. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/libraries/tantivy.md +0 -0
  149. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/libraries/zstd.md +0 -0
  150. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/naming.md +0 -0
  151. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/testing.md +0 -0
  152. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/docs/standards/rust/unsafe.md +0 -0
  153. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/rust-toolchain.toml +0 -0
  154. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/agentic_smoke.sh +0 -0
  155. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/bench/bench_concurrent_mixed.py +0 -0
  156. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/bench/bench_hosted_adversarial.py +0 -0
  157. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/bench/stress_mcp_multiprocess.py +0 -0
  158. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/grokmirror-personal.conf +0 -0
  159. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/grokmirror.conf +0 -0
  160. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/klmcp-doctor.sh +0 -0
  161. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/klmcp-grok-pull.sh +0 -0
  162. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/klmcp-ingest.sh +0 -0
  163. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/post-pull-hook.sh +0 -0
  164. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/rust_call_graph.py +0 -0
  165. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/systemd/etc-kernel-lore-mcp-env.sample +0 -0
  166. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/systemd/klmcp-grokmirror.service +0 -0
  167. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/systemd/klmcp-grokmirror.timer +0 -0
  168. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/systemd/klmcp-ingest.path +0 -0
  169. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/systemd/klmcp-ingest.service +0 -0
  170. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/systemd/klmcp-mcp.service +0 -0
  171. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/systemd/klmcp-sync.service +0 -0
  172. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/scripts/systemd/klmcp-sync.timer +0 -0
  173. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/bin/bench_blob_read.rs +0 -0
  174. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/bin/bench_ingest_stages.rs +0 -0
  175. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/bin/build_git_sidecar.rs +0 -0
  176. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/bin/build_over.rs +0 -0
  177. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/bin/doctor.rs +0 -0
  178. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/bm25.rs +0 -0
  179. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/embedding.rs +0 -0
  180. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/error.rs +0 -0
  181. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/git_sidecar.rs +0 -0
  182. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/ingest.rs +0 -0
  183. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/_core.pyi +0 -0
  184. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/_surface_manifest.py +0 -0
  185. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/cli/__init__.py +0 -0
  186. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/cli/doctor.py +0 -0
  187. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/cli/embed.py +0 -0
  188. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/cli/ingest.py +0 -0
  189. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/cli/sync.py +0 -0
  190. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/config.py +0 -0
  191. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/cost_class.py +0 -0
  192. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/cursor.py +0 -0
  193. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/embedding.py +0 -0
  194. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/errors.py +0 -0
  195. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/freshness.py +0 -0
  196. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/kwic.py +0 -0
  197. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/logging_.py +0 -0
  198. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/mapping.py +0 -0
  199. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/models.py +0 -0
  200. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/observability.py +0 -0
  201. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/prompts.py +0 -0
  202. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/reader_cache.py +0 -0
  203. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/resources/__init__.py +0 -0
  204. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/resources/blind_spots.py +0 -0
  205. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/resources/templates.py +0 -0
  206. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/routes/__init__.py +0 -0
  207. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/routes/metrics.py +0 -0
  208. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/sampling.py +0 -0
  209. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/server.py +0 -0
  210. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/time_bounds.py +0 -0
  211. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/timeout.py +0 -0
  212. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/__init__.py +0 -0
  213. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/activity.py +0 -0
  214. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/author_footprint.py +0 -0
  215. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/author_profile.py +0 -0
  216. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/expand_citation.py +0 -0
  217. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/explain_patch.py +0 -0
  218. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/file_timeline.py +0 -0
  219. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/fix_status.py +0 -0
  220. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/maintainer_profile.py +0 -0
  221. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/message.py +0 -0
  222. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/nearest.py +0 -0
  223. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/patch.py +0 -0
  224. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/patch_diff.py +0 -0
  225. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/patch_search.py +0 -0
  226. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/primitives.py +0 -0
  227. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/sampling_tools.py +0 -0
  228. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/search.py +0 -0
  229. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/series.py +0 -0
  230. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/stable_backport.py +0 -0
  231. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/subsystem_churn.py +0 -0
  232. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/thread.py +0 -0
  233. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/kernel_lore_mcp/tools/thread_state.py +0 -0
  234. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/lib.rs +0 -0
  235. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/maintainers.rs +0 -0
  236. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/metadata.rs +0 -0
  237. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/over.rs +0 -0
  238. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/parse.rs +0 -0
  239. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/path_tier.rs +0 -0
  240. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/python.rs +0 -0
  241. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/router.rs +0 -0
  242. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/schema.rs +0 -0
  243. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/state.rs +0 -0
  244. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/store.rs +0 -0
  245. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/sync.rs +0 -0
  246. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/tid.rs +0 -0
  247. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/timeout.rs +0 -0
  248. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/trailer_refs.rs +0 -0
  249. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/src/trigram.rs +0 -0
  250. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/__init__.py +0 -0
  251. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/bin_ingest.rs +0 -0
  252. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/__init__.py +0 -0
  253. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/conftest.py +0 -0
  254. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/fixtures/__init__.py +0 -0
  255. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_annotations.py +0 -0
  256. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_cost_hints.py +0 -0
  257. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_cursor.py +0 -0
  258. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_embedding_e2e.py +0 -0
  259. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_errors.py +0 -0
  260. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_fix_status.py +0 -0
  261. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_freshness.py +0 -0
  262. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_fuzzy_search.py +0 -0
  263. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_http_transport.py +0 -0
  264. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_ingest_and_reader.py +0 -0
  265. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_kwic.py +0 -0
  266. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_logging_profile.py +0 -0
  267. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_mcp_adversarial.py +0 -0
  268. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_observability.py +0 -0
  269. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_primitives_e2e.py +0 -0
  270. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_prompts.py +0 -0
  271. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_regex_hosted.py +0 -0
  272. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_resource_templates.py +0 -0
  273. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_response_format.py +0 -0
  274. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_sampling_tools.py +0 -0
  275. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_smoke.py +0 -0
  276. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_stdio_subprocess.py +0 -0
  277. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_surface_manifest.py +0 -0
  278. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_sync_cli.py +0 -0
  279. {kernel_lore_mcp-0.3.3 → kernel_lore_mcp-0.3.4}/tests/python/test_thread_patch_explain.py +0 -0
@@ -10,6 +10,33 @@ release tags move them into a dated section. Release process in
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.3.4] - 2026-04-23
14
+
15
+ ### Added
16
+
17
+ - Added `kernel-lore-reindex`, a dedicated derived-tier rebuild command
18
+ for BM25, TID parquet, and path vocabulary refreshes after live sync.
19
+ - Added tier generation and freshness reporting to `/status`,
20
+ `kernel-lore-mcp status`, coverage resources, and corpus stats so
21
+ operators can tell exactly which derived indexes are stale.
22
+
23
+ ### Changed
24
+
25
+ - `kernel-lore-sync` is now live-safe by default: it fetches and
26
+ ingests lore shards without automatically rebuilding expensive
27
+ derived tiers on the serving box.
28
+ - Derived rebuilds are now explicit via `kernel-lore-reindex` or the
29
+ opt-in sync flags `--with-tid-rebuild`, `--with-path-vocab-rebuild`,
30
+ and `--with-derived-rebuilds`.
31
+
32
+ ### Fixed
33
+
34
+ - Sync no longer bumps the corpus generation, BM25 marker, TID marker,
35
+ or path-vocabulary marker when no corresponding content was actually
36
+ ingested or rebuilt.
37
+ - BM25 and path-mention readers now reject stale derived indexes instead
38
+ of silently serving results from a previous corpus generation.
39
+
13
40
  ## [0.3.2] — 2026-04-22
14
41
 
15
42
  ### Added
@@ -2638,7 +2638,7 @@ dependencies = [
2638
2638
 
2639
2639
  [[package]]
2640
2640
  name = "kernel_lore_mcp"
2641
- version = "0.3.3"
2641
+ version = "0.3.4"
2642
2642
  dependencies = [
2643
2643
  "aho-corasick",
2644
2644
  "anyhow",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "kernel_lore_mcp"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  edition = "2024"
5
5
  rust-version = "1.85"
6
6
  authors = ["Michael Bommarito <michael@bommaritollc.com>"]
@@ -145,7 +145,7 @@ version = "0.3"
145
145
  features = ["env-filter", "json"]
146
146
 
147
147
  [[bin]]
148
- name = "reindex"
148
+ name = "kernel-lore-reindex"
149
149
  path = "src/bin/reindex.rs"
150
150
 
151
151
  [[bin]]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kernel-lore-mcp
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Classifier: Development Status :: 2 - Pre-Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kernel-lore-mcp"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  description = "MCP server exposing fast, structured search over lore.kernel.org to LLM developer tools."
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -59,6 +59,9 @@ kernel-lore-ingest = "kernel_lore_mcp.cli.ingest:main"
59
59
  # generation bump). This thin Python entry point exec's the Rust
60
60
  # binary so `uv tool install`d users get it without hunting PATH.
61
61
  kernel-lore-sync = "kernel_lore_mcp.cli.sync:main"
62
+ # kernel-lore-reindex rebuilds slower derived tiers from the local
63
+ # corpus without refetching lore. Complements the live-safe sync path.
64
+ kernel-lore-reindex = "kernel_lore_mcp.cli.reindex:main"
62
65
  # Health / repair probe for local shard mirrors and tier files.
63
66
  kernel-lore-doctor = "kernel_lore_mcp.cli.doctor:main"
64
67
 
@@ -265,9 +265,16 @@ fn main() -> Result<()> {
265
265
  "over.generation marker NOT advanced: readers will bypass over.db until reconciled"
266
266
  );
267
267
  }
268
- state
269
- .set_tier_generation("bm25", new_gen)
270
- .context("set bm25.generation marker")?;
268
+ if !skip_bm25 {
269
+ state
270
+ .set_tier_generation("bm25", new_gen)
271
+ .context("set bm25.generation marker")?;
272
+ } else {
273
+ tracing::warn!(
274
+ corpus_gen = new_gen,
275
+ "bm25.generation marker NOT advanced: BM25 was deferred for this ingest"
276
+ );
277
+ }
271
278
  state
272
279
  .set_tier_generation("trigram", new_gen)
273
280
  .context("set trigram.generation marker")?;
@@ -0,0 +1,213 @@
1
+ //! `kernel-lore-reindex` — rebuild derived tiers from the local data
2
+ //! store without refetching lore.
3
+ //!
4
+ //! This is the maintenance complement to the live-safe sync path:
5
+ //! `kernel-lore-sync` keeps raw metadata, over.db, and optional BM25
6
+ //! current; `kernel-lore-reindex` rebuilds slower derived artifacts
7
+ //! from the already-downloaded corpus.
8
+ //!
9
+ //! Defaults:
10
+ //! * `tid`
11
+ //! * `path_vocab`
12
+ //!
13
+ //! Explicit `--tier bm25` is supported, but a long-lived serving
14
+ //! process may need a restart (or a later generation bump) before it
15
+ //! reloads the rebuilt Tantivy reader.
16
+
17
+ use std::path::PathBuf;
18
+ use std::time::Instant;
19
+
20
+ use anyhow::{Context, Result, anyhow};
21
+
22
+ const REINDEX_VERSION: &str = env!("CARGO_PKG_VERSION");
23
+
24
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
25
+ enum Tier {
26
+ Tid,
27
+ PathVocab,
28
+ Bm25,
29
+ }
30
+
31
+ impl Tier {
32
+ fn parse(raw: &str) -> Result<Self> {
33
+ match raw {
34
+ "tid" => Ok(Self::Tid),
35
+ "path_vocab" | "path-vocab" | "paths" => Ok(Self::PathVocab),
36
+ "bm25" => Ok(Self::Bm25),
37
+ other => Err(anyhow!(
38
+ "unknown tier {other:?}; use tid | path_vocab | bm25"
39
+ )),
40
+ }
41
+ }
42
+
43
+ fn name(self) -> &'static str {
44
+ match self {
45
+ Self::Tid => "tid",
46
+ Self::PathVocab => "path_vocab",
47
+ Self::Bm25 => "bm25",
48
+ }
49
+ }
50
+ }
51
+
52
+ #[derive(Default)]
53
+ struct Args {
54
+ data_dir: Option<PathBuf>,
55
+ tiers: Vec<String>,
56
+ all: bool,
57
+ }
58
+
59
+ fn main() -> Result<()> {
60
+ tracing_subscriber::fmt()
61
+ .with_writer(std::io::stderr)
62
+ .with_env_filter(
63
+ tracing_subscriber::EnvFilter::try_from_default_env()
64
+ .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")),
65
+ )
66
+ .json()
67
+ .init();
68
+
69
+ let args = parse_args()?;
70
+ let tiers = resolve_tiers(&args)?;
71
+ let data_dir = args
72
+ .data_dir
73
+ .or_else(|| std::env::var_os("KLMCP_DATA_DIR").map(PathBuf::from))
74
+ .context("--data-dir or KLMCP_DATA_DIR required")?;
75
+ std::fs::create_dir_all(&data_dir)?;
76
+ let tier_names: Vec<&str> = tiers.iter().map(|t| t.name()).collect();
77
+
78
+ let state = _core::State::new(&data_dir)?;
79
+ let _writer_lock = state
80
+ .acquire_writer_lock()
81
+ .context("another writer is running (writer.lock held)")?;
82
+ let corpus_generation = state.generation().context("read corpus generation")?;
83
+
84
+ tracing::info!(
85
+ version = REINDEX_VERSION,
86
+ data_dir = %data_dir.display(),
87
+ corpus_generation,
88
+ tiers = ?tier_names,
89
+ "reindex starting"
90
+ );
91
+
92
+ let start = Instant::now();
93
+ for tier in tiers {
94
+ let tier_start = Instant::now();
95
+ match tier {
96
+ Tier::Tid => {
97
+ tracing::info!("tid rebuild starting");
98
+ let (path, rows) =
99
+ _core::rebuild_tid(&data_dir).context("rebuild tid side-table")?;
100
+ state
101
+ .set_tier_generation("tid", corpus_generation)
102
+ .context("set tid.generation marker")?;
103
+ tracing::info!(
104
+ rows,
105
+ marker_generation = corpus_generation,
106
+ path = %path.display(),
107
+ elapsed_secs = tier_start.elapsed().as_secs_f64(),
108
+ "tid rebuild done"
109
+ );
110
+ }
111
+ Tier::PathVocab => {
112
+ tracing::info!("path vocab rebuild starting");
113
+ let count = _core::path_tier::rebuild_vocab_from_over(&data_dir)
114
+ .context("rebuild path vocab from over/parquet")?;
115
+ if count > 0 {
116
+ state
117
+ .set_tier_generation("path_vocab", corpus_generation)
118
+ .context("set path_vocab.generation marker")?;
119
+ tracing::info!(
120
+ paths = count,
121
+ marker_generation = corpus_generation,
122
+ path = %data_dir.join("paths").join("vocab.txt").display(),
123
+ elapsed_secs = tier_start.elapsed().as_secs_f64(),
124
+ "path vocab rebuild done"
125
+ );
126
+ } else {
127
+ tracing::info!(
128
+ paths = count,
129
+ elapsed_secs = tier_start.elapsed().as_secs_f64(),
130
+ "path vocab rebuild produced an empty vocab; marker left unchanged"
131
+ );
132
+ }
133
+ }
134
+ Tier::Bm25 => {
135
+ tracing::warn!(
136
+ "bm25 rebuild starting; restart serving processes or run a later generation bump if you need live readers to reload immediately"
137
+ );
138
+ let docs = _core::rebuild_bm25(&data_dir).context("rebuild bm25 from store")?;
139
+ state
140
+ .set_tier_generation("bm25", corpus_generation)
141
+ .context("set bm25.generation marker")?;
142
+ tracing::warn!(
143
+ docs,
144
+ marker_generation = corpus_generation,
145
+ elapsed_secs = tier_start.elapsed().as_secs_f64(),
146
+ "bm25 rebuild done; marker updated, but long-lived readers may still need a restart to pick up the new index"
147
+ );
148
+ }
149
+ }
150
+ }
151
+
152
+ tracing::info!(
153
+ elapsed_secs = start.elapsed().as_secs_f64(),
154
+ corpus_generation,
155
+ tiers = ?tier_names,
156
+ "reindex complete"
157
+ );
158
+ Ok(())
159
+ }
160
+
161
+ fn resolve_tiers(args: &Args) -> Result<Vec<Tier>> {
162
+ let mut out: Vec<Tier> = Vec::new();
163
+ if args.all {
164
+ out.extend([Tier::Tid, Tier::PathVocab, Tier::Bm25]);
165
+ }
166
+ if !args.all && args.tiers.is_empty() {
167
+ out.extend([Tier::Tid, Tier::PathVocab]);
168
+ }
169
+ for raw in &args.tiers {
170
+ let tier = Tier::parse(raw)?;
171
+ if !out.contains(&tier) {
172
+ out.push(tier);
173
+ }
174
+ }
175
+ Ok(out)
176
+ }
177
+
178
+ fn parse_args() -> Result<Args> {
179
+ let mut args = Args::default();
180
+ let mut it = std::env::args().skip(1);
181
+ while let Some(a) = it.next() {
182
+ match a.as_str() {
183
+ "--data-dir" => args.data_dir = it.next().map(PathBuf::from),
184
+ "--tier" => args.tiers.push(it.next().context("--tier expects a name")?),
185
+ "--all" => args.all = true,
186
+ "--help" | "-h" => {
187
+ println!(
188
+ "kernel-lore-reindex\n\
189
+ version: {REINDEX_VERSION}\n\
190
+ \n\
191
+ --data-dir PATH (or $KLMCP_DATA_DIR)\n\
192
+ --tier NAME repeatable: tid | path_vocab | bm25\n\
193
+ --all rebuild tid + path_vocab + bm25\n\
194
+ \n\
195
+ Defaults:\n\
196
+ with no --tier flags, rebuilds tid + path_vocab only.\n\
197
+ \n\
198
+ Notes:\n\
199
+ - This command rebuilds from the local corpus; it does NOT refetch lore.\n\
200
+ - `--tier bm25` updates the on-disk index and marker, but a long-lived\n\
201
+ serving process may need a restart before it reloads the rebuilt reader.\n"
202
+ );
203
+ std::process::exit(0);
204
+ }
205
+ "--version" | "-V" => {
206
+ println!("{REINDEX_VERSION}");
207
+ std::process::exit(0);
208
+ }
209
+ other => return Err(anyhow!("unknown arg: {other}")),
210
+ }
211
+ }
212
+ Ok(args)
213
+ }
@@ -12,8 +12,9 @@
12
12
  //! 3. For each changed shard, gix clone-or-fetch in parallel.
13
13
  //! 4. For each fetched shard, ingest via the existing
14
14
  //! `ingest_shard_with_bm25` under a single writer lock.
15
- //! 5. Rebuild tid side-table once at the end, bump generation once.
16
- //! 6. Persist the fresh manifest cache (only on full success, so a
15
+ //! 5. Optionally rebuild derived tiers (tid / path vocab) at the end.
16
+ //! 6. Bump generation once iff the raw corpus changed.
17
+ //! 7. Persist the fresh manifest cache (only on full success, so a
17
18
  //! partial-failure rerun re-fetches the same shards).
18
19
  //!
19
20
  //! Exit codes:
@@ -28,7 +29,8 @@
28
29
  //! kernel-lore-sync --dry-run # manifest fetch + diff only
29
30
  //!
30
31
  //! Stays single-process: the writer lock taken here covers manifest
31
- //! fetch, gix fetch, ingest, tid rebuild, and the generation bump,
32
+ //! fetch, gix fetch, ingest, optional derived rebuilds, and the
33
+ //! generation bump,
32
34
  //! so a concurrent sync invocation fails the flock and exits cleanly
33
35
  //! without touching state.
34
36
 
@@ -127,6 +129,8 @@ struct SyncStatusRecord {
127
129
  stage: String,
128
130
  with_bm25: bool,
129
131
  with_over: bool,
132
+ rebuild_tid: bool,
133
+ rebuild_path_vocab: bool,
130
134
  workers: usize,
131
135
  total_shards: usize,
132
136
  started_shards: usize,
@@ -159,6 +163,8 @@ impl SyncStateReporter {
159
163
  run_id: &str,
160
164
  with_bm25: bool,
161
165
  with_over: bool,
166
+ rebuild_tid: bool,
167
+ rebuild_path_vocab: bool,
162
168
  workers: usize,
163
169
  total_shards: usize,
164
170
  ) -> Result<Self> {
@@ -173,6 +179,8 @@ impl SyncStateReporter {
173
179
  stage: "starting".to_string(),
174
180
  with_bm25,
175
181
  with_over,
182
+ rebuild_tid,
183
+ rebuild_path_vocab,
176
184
  workers,
177
185
  total_shards,
178
186
  started_shards: 0,
@@ -521,6 +529,13 @@ fn main() -> Result<()> {
521
529
  (false, true) => false,
522
530
  (false, false) => over_path.exists(),
523
531
  };
532
+ let rebuild_tid = args.with_derived_rebuilds || args.with_tid_rebuild;
533
+ let rebuild_path_vocab = args.with_derived_rebuilds || args.with_path_vocab_rebuild;
534
+ if !rebuild_tid && !rebuild_path_vocab {
535
+ tracing::info!(
536
+ "derived rebuilds deferred (live-safe default). Run `kernel-lore-reindex` or pass explicit --with-*-rebuild flags when you want tid/path vocab refreshed inline."
537
+ );
538
+ }
524
539
 
525
540
  // Resolve manifest paths to ChangedShard descriptors.
526
541
  let changed: Vec<ChangedShard> = changed_paths
@@ -538,6 +553,8 @@ fn main() -> Result<()> {
538
553
  &run_id,
539
554
  !skip_bm25,
540
555
  with_over,
556
+ rebuild_tid,
557
+ rebuild_path_vocab,
541
558
  workers,
542
559
  changed.len(),
543
560
  )
@@ -674,6 +691,8 @@ fn main() -> Result<()> {
674
691
  lists = stores.len(),
675
692
  with_over,
676
693
  with_bm25 = !skip_bm25,
694
+ rebuild_tid,
695
+ rebuild_path_vocab,
677
696
  workers = workers,
678
697
  "ingest phase starting"
679
698
  );
@@ -782,33 +801,46 @@ fn main() -> Result<()> {
782
801
  drop(stage_guard);
783
802
  }
784
803
 
785
- // tid rebuild: reasonable to do every sync tick; touches only the
786
- // subset of rows whose tid changed. Cheap at steady state.
787
- sync_state
788
- .set_stage("tid_rebuild", None)
789
- .context("update sync status to tid_rebuild")?;
790
- let tid_stage_guard = stage_heartbeat(sync_state.clone(), "tid_rebuild", None, start);
791
- tracing::info!("tid rebuild starting");
792
- let tid_result = _core::rebuild_tid(&data_dir).context("rebuild tid side-table")?;
793
- tracing::info!(
794
- rows = tid_result.1,
795
- path = %tid_result.0.display(),
796
- "tid rebuild done"
797
- );
798
- drop(tid_stage_guard);
799
- sync_state
800
- .set_stage("path_vocab_rebuild", None)
801
- .context("update sync status to path_vocab_rebuild")?;
802
- let path_stage_guard = stage_heartbeat(sync_state.clone(), "path_vocab_rebuild", None, start);
803
- tracing::info!("path vocab rebuild starting");
804
- if let Some(path_count) = rebuild_path_vocab_after_sync(&data_dir)? {
804
+ let mut tid_rebuilt = false;
805
+ let mut path_vocab_rebuilt = false;
806
+ if rebuild_tid {
807
+ sync_state
808
+ .set_stage("tid_rebuild", None)
809
+ .context("update sync status to tid_rebuild")?;
810
+ let tid_stage_guard = stage_heartbeat(sync_state.clone(), "tid_rebuild", None, start);
811
+ tracing::info!("tid rebuild starting");
812
+ let tid_result = _core::rebuild_tid(&data_dir).context("rebuild tid side-table")?;
805
813
  tracing::info!(
806
- paths = path_count,
807
- path = %data_dir.join("paths").join("vocab.txt").display(),
808
- "path vocab rebuild done"
814
+ rows = tid_result.1,
815
+ path = %tid_result.0.display(),
816
+ "tid rebuild done"
809
817
  );
818
+ tid_rebuilt = true;
819
+ drop(tid_stage_guard);
820
+ } else {
821
+ tracing::info!("tid rebuild skipped (live-safe default)");
822
+ }
823
+ if rebuild_path_vocab {
824
+ sync_state
825
+ .set_stage("path_vocab_rebuild", None)
826
+ .context("update sync status to path_vocab_rebuild")?;
827
+ let path_stage_guard =
828
+ stage_heartbeat(sync_state.clone(), "path_vocab_rebuild", None, start);
829
+ tracing::info!("path vocab rebuild starting");
830
+ if let Some(path_count) = rebuild_path_vocab_after_sync(&data_dir)? {
831
+ tracing::info!(
832
+ paths = path_count,
833
+ path = %data_dir.join("paths").join("vocab.txt").display(),
834
+ "path vocab rebuild done"
835
+ );
836
+ path_vocab_rebuilt = true;
837
+ } else {
838
+ tracing::info!("path vocab rebuild skipped by environment");
839
+ }
840
+ drop(path_stage_guard);
841
+ } else {
842
+ tracing::info!("path vocab rebuild skipped (live-safe default)");
810
843
  }
811
- drop(path_stage_guard);
812
844
 
813
845
  // Tally.
814
846
  let mut total_ingested: u64 = 0;
@@ -851,36 +883,73 @@ fn main() -> Result<()> {
851
883
  }
852
884
  }
853
885
 
854
- sync_state
855
- .set_stage("generation_bump", None)
856
- .context("update sync status to generation_bump")?;
857
- tracing::info!("generation bump starting");
858
- let new_gen = state.bump_generation().context("bump generation")?;
859
- tracing::info!(generation = new_gen, "generation bumped");
886
+ let corpus_changed = total_ingested > 0;
887
+ let current_gen = state.generation().context("read generation")?;
888
+ let new_gen = if corpus_changed {
889
+ sync_state
890
+ .set_stage("generation_bump", None)
891
+ .context("update sync status to generation_bump")?;
892
+ tracing::info!("generation bump starting");
893
+ let bumped = state.bump_generation().context("bump generation")?;
894
+ tracing::info!(generation = bumped, "generation bumped");
895
+ bumped
896
+ } else {
897
+ tracing::info!(
898
+ generation = current_gen,
899
+ "generation not bumped (no new messages ingested)"
900
+ );
901
+ current_gen
902
+ };
860
903
 
861
904
  // Per-tier markers. Same discipline as bin/ingest.rs: only
862
905
  // advance the `over` marker on full success so readers bypass
863
906
  // over.db on drift.
864
- if with_over && total_over_failed == 0 {
907
+ if corpus_changed && with_over && total_over_failed == 0 {
865
908
  state
866
909
  .set_tier_generation("over", new_gen)
867
910
  .context("set over.generation marker")?;
868
- } else if with_over {
911
+ } else if corpus_changed && with_over {
869
912
  tracing::warn!(
870
913
  over_failed_shards = total_over_failed,
871
914
  corpus_gen = new_gen,
872
915
  "over.generation marker NOT advanced"
873
916
  );
874
917
  }
875
- state
876
- .set_tier_generation("bm25", new_gen)
877
- .context("set bm25.generation marker")?;
878
- state
879
- .set_tier_generation("trigram", new_gen)
880
- .context("set trigram.generation marker")?;
881
- state
882
- .set_tier_generation("tid", new_gen)
883
- .context("set tid.generation marker")?;
918
+ if corpus_changed && !skip_bm25 {
919
+ state
920
+ .set_tier_generation("bm25", new_gen)
921
+ .context("set bm25.generation marker")?;
922
+ } else if corpus_changed && skip_bm25 {
923
+ tracing::warn!(
924
+ corpus_gen = new_gen,
925
+ "bm25.generation marker NOT advanced: BM25 was deferred for this sync"
926
+ );
927
+ }
928
+ if corpus_changed {
929
+ state
930
+ .set_tier_generation("trigram", new_gen)
931
+ .context("set trigram.generation marker")?;
932
+ }
933
+ if tid_rebuilt {
934
+ state
935
+ .set_tier_generation("tid", new_gen)
936
+ .context("set tid.generation marker")?;
937
+ } else if corpus_changed {
938
+ tracing::warn!(
939
+ corpus_gen = new_gen,
940
+ "tid.generation marker NOT advanced: tid rebuild was deferred for this sync"
941
+ );
942
+ }
943
+ if path_vocab_rebuilt {
944
+ state
945
+ .set_tier_generation("path_vocab", new_gen)
946
+ .context("set path_vocab.generation marker")?;
947
+ } else if corpus_changed {
948
+ tracing::warn!(
949
+ corpus_gen = new_gen,
950
+ "path_vocab.generation marker NOT advanced: path vocab rebuild was deferred for this sync"
951
+ );
952
+ }
884
953
 
885
954
  // Persist manifest cache — start from the existing local entries
886
955
  // (so filtered-out shards keep their history) and overwrite only
@@ -974,6 +1043,9 @@ struct Args {
974
1043
  with_bm25: bool,
975
1044
  with_over: bool,
976
1045
  no_over: bool,
1046
+ with_tid_rebuild: bool,
1047
+ with_path_vocab_rebuild: bool,
1048
+ with_derived_rebuilds: bool,
977
1049
  max_retries: u32,
978
1050
  dry_run: bool,
979
1051
  }
@@ -1005,6 +1077,9 @@ fn parse_args() -> Result<Args> {
1005
1077
  "--with-bm25" => args.with_bm25 = true,
1006
1078
  "--with-over" => args.with_over = true,
1007
1079
  "--no-over" => args.no_over = true,
1080
+ "--with-tid-rebuild" => args.with_tid_rebuild = true,
1081
+ "--with-path-vocab-rebuild" => args.with_path_vocab_rebuild = true,
1082
+ "--with-derived-rebuilds" => args.with_derived_rebuilds = true,
1008
1083
  "--max-retries" => {
1009
1084
  args.max_retries = it.next().and_then(|s| s.parse().ok()).unwrap_or(3);
1010
1085
  }
@@ -1031,6 +1106,14 @@ fn parse_args() -> Result<Args> {
1031
1106
  --with-over force on over.db writes\n\
1032
1107
  --no-over force off over.db writes\n\
1033
1108
  (default: on iff <data_dir>/over.db exists)\n\
1109
+ --with-tid-rebuild rebuild tid side-table inline\n\
1110
+ after ingest (heavier)\n\
1111
+ --with-path-vocab-rebuild\n\
1112
+ rebuild paths/vocab.txt inline\n\
1113
+ after ingest (heavier)\n\
1114
+ --with-derived-rebuilds\n\
1115
+ rebuild both tid + path vocab\n\
1116
+ inline after ingest\n\
1034
1117
  --max-retries N per-shard ingest retry count (default: 3)\n\
1035
1118
  --dry-run fetch manifest + diff, don't touch shards\n\
1036
1119
  \n\
@@ -1043,7 +1126,7 @@ fn parse_args() -> Result<Args> {
1043
1126
  (default: 1)\n\
1044
1127
  KLMCP_BM25_WRITER_MEMORY_MB BM25 total writer memory budget\n\
1045
1128
  in MiB (default: 128)\n\
1046
- KLMCP_SKIP_PATH_VOCAB=1 skip automatic paths/vocab.txt rebuild\n"
1129
+ KLMCP_SKIP_PATH_VOCAB=1 skip requested path vocab rebuild\n"
1047
1130
  );
1048
1131
  std::process::exit(0);
1049
1132
  }
@@ -15,7 +15,7 @@ from typing import Any
15
15
 
16
16
  __all__ = ["__version__", "native_version"]
17
17
 
18
- __version__ = "0.3.3"
18
+ __version__ = "0.3.4"
19
19
 
20
20
 
21
21
  def __getattr__(name: str) -> Any: