kernel-lore-mcp 0.3.1__tar.gz → 0.3.2__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 (277) hide show
  1. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/CHANGELOG.md +35 -0
  2. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/Cargo.lock +1 -1
  3. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/Cargo.toml +1 -1
  4. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/PKG-INFO +10 -9
  5. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/README.md +9 -8
  6. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/TODO.md +16 -2
  7. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/pyproject.toml +1 -1
  8. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/ingest.rs +1 -1
  9. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/__init__.py +1 -1
  10. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/_core.pyi +20 -0
  11. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/server.py +5 -0
  12. kernel_lore_mcp-0.3.2/src/kernel_lore_mcp/time_bounds.py +118 -0
  13. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/activity.py +23 -2
  14. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/author_footprint.py +8 -23
  15. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/author_profile.py +30 -7
  16. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/file_timeline.py +18 -9
  17. kernel_lore_mcp-0.3.2/src/kernel_lore_mcp/tools/fix_status.py +373 -0
  18. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/path_mentions.py +28 -2
  19. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/primitives.py +127 -8
  20. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/stable_backport.py +2 -6
  21. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/subsystem_churn.py +4 -7
  22. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/lib.rs +5 -0
  23. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/over.rs +405 -31
  24. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/python.rs +103 -15
  25. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/reader.rs +235 -61
  26. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/router.rs +114 -7
  27. kernel_lore_mcp-0.3.2/src/trailer_refs.rs +283 -0
  28. kernel_lore_mcp-0.3.2/tests/python/test_fix_status.py +95 -0
  29. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_mcp_tools_e2e.py +11 -0
  30. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_primitives_e2e.py +15 -0
  31. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/uv.lock +1 -1
  32. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/.github/workflows/ci.yml +0 -0
  33. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/.github/workflows/release.yml +0 -0
  34. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/.gitignore +0 -0
  35. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/.python-version +0 -0
  36. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/CLAUDE.md +0 -0
  37. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/CONTRIBUTING.md +0 -0
  38. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/GOVERNANCE.md +0 -0
  39. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/LEGAL.md +0 -0
  40. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/LICENSE +0 -0
  41. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/SECURITY.md +0 -0
  42. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/README.md +0 -0
  43. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/architecture/data-flow.md +0 -0
  44. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/architecture/deployment-modes.md +0 -0
  45. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/architecture/four-tier-index.md +0 -0
  46. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/architecture/over-db.md +0 -0
  47. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/architecture/overview.md +0 -0
  48. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/architecture/reciprocity.md +0 -0
  49. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/architecture/trade-offs.md +0 -0
  50. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/demos/first-session.md +0 -0
  51. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/indexing/bm25-tier.md +0 -0
  52. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/indexing/compressed-store.md +0 -0
  53. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/indexing/metadata-tier.md +0 -0
  54. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/indexing/path-tier.md +0 -0
  55. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/indexing/tokenizer-spec.md +0 -0
  56. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/indexing/trigram-tier.md +0 -0
  57. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ingestion/grokmirror.md +0 -0
  58. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ingestion/mbox-parsing.md +0 -0
  59. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ingestion/patch-parsing.md +0 -0
  60. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ingestion/shard-walking.md +0 -0
  61. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/mcp/client-config.md +0 -0
  62. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/mcp/query-routing.md +0 -0
  63. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/mcp/tools.md +0 -0
  64. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/mcp/transport-auth.md +0 -0
  65. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ops/corpus-coverage.md +0 -0
  66. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ops/cost-model.md +0 -0
  67. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ops/ec2-sizing.md +0 -0
  68. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ops/monitoring.md +0 -0
  69. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ops/production-hardening.md +0 -0
  70. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ops/public-launch-checklist.md +0 -0
  71. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ops/runbook.md +0 -0
  72. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ops/threat-model.md +0 -0
  73. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ops/update-cadence.md +0 -0
  74. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/ops/update-frequency.md +0 -0
  75. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/plans/2026-04-14-best-in-class-kernel-mcp.md +0 -0
  76. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/plans/2026-04-15-internalize-grokmirror.md +0 -0
  77. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/plans/2026-04-15-mcp-spec-coverage-and-uplift.md +0 -0
  78. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/plans/2026-04-17-overdb-followups.md +0 -0
  79. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/plans/2026-04-17-overdb-metadata-tier.md +0 -0
  80. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/plans/2026-04-20-v0.3.0-plan.md +0 -0
  81. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/plans/2026-04-22-v0.3.1-plan.md +0 -0
  82. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-14-agent-ergonomics.md +0 -0
  83. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-14-best-in-class-mcp-survey.md +0 -0
  84. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-14-external-data-sources.md +0 -0
  85. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-14-gix-vs-git2.md +0 -0
  86. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-14-mcp-python-sdk.md +0 -0
  87. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-14-pyo3-maturin.md +0 -0
  88. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-14-search-library-landscape.md +0 -0
  89. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-14-storage-footprint.md +0 -0
  90. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-14-tantivy.md +0 -0
  91. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-14-workflow-gap-analysis.md +0 -0
  92. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-15-fuzzy-search-design.md +0 -0
  93. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-15-path-mentions.md +0 -0
  94. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/2026-04-17-overdb-validation.md +0 -0
  95. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/research/training-retriever.md +0 -0
  96. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/README.md +0 -0
  97. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/checklists/01-research.md +0 -0
  98. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/checklists/02-design.md +0 -0
  99. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/checklists/03-implement.md +0 -0
  100. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/checklists/04-test.md +0 -0
  101. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/checklists/05-quality.md +0 -0
  102. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/checklists/06-review.md +0 -0
  103. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/checklists/07-commit.md +0 -0
  104. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/checklists/08-debug.md +0 -0
  105. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/checklists/09-optimize.md +0 -0
  106. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/checklists/10-document.md +0 -0
  107. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/checklists/index.md +0 -0
  108. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/code-quality.md +0 -0
  109. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/data-structures.md +0 -0
  110. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/design/boundaries.md +0 -0
  111. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/design/concurrency.md +0 -0
  112. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/design/dependencies.md +0 -0
  113. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/design/errors.md +0 -0
  114. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/design/modules.md +0 -0
  115. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/git.md +0 -0
  116. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/index.md +0 -0
  117. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/language.md +0 -0
  118. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/libraries/fastmcp.md +0 -0
  119. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/libraries/httpx.md +0 -0
  120. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/libraries/pydantic.md +0 -0
  121. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/libraries/structlog.md +0 -0
  122. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/naming.md +0 -0
  123. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/pyo3-maturin.md +0 -0
  124. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/testing.md +0 -0
  125. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/python/uv.md +0 -0
  126. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/cargo.md +0 -0
  127. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/checklists/01-research.md +0 -0
  128. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/checklists/02-design.md +0 -0
  129. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/checklists/03-implement.md +0 -0
  130. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/checklists/04-test.md +0 -0
  131. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/checklists/05-quality.md +0 -0
  132. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/checklists/06-review.md +0 -0
  133. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/checklists/07-commit.md +0 -0
  134. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/checklists/08-debug.md +0 -0
  135. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/checklists/09-optimize.md +0 -0
  136. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/checklists/10-document.md +0 -0
  137. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/checklists/index.md +0 -0
  138. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/code-quality.md +0 -0
  139. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/design/boundaries.md +0 -0
  140. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/design/concurrency.md +0 -0
  141. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/design/data-structures.md +0 -0
  142. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/design/errors.md +0 -0
  143. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/design/modules.md +0 -0
  144. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/ffi.md +0 -0
  145. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/index.md +0 -0
  146. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/language.md +0 -0
  147. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/libraries/arrow-parquet.md +0 -0
  148. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/libraries/gix.md +0 -0
  149. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/libraries/pyo3.md +0 -0
  150. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/libraries/regex-automata.md +0 -0
  151. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/libraries/roaring-fst.md +0 -0
  152. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/libraries/tantivy.md +0 -0
  153. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/libraries/zstd.md +0 -0
  154. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/naming.md +0 -0
  155. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/testing.md +0 -0
  156. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/docs/standards/rust/unsafe.md +0 -0
  157. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/rust-toolchain.toml +0 -0
  158. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/agentic_smoke.sh +0 -0
  159. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/bench/bench_concurrent_mixed.py +0 -0
  160. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/bench/bench_hosted_adversarial.py +0 -0
  161. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/bench/stress_mcp_multiprocess.py +0 -0
  162. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/grokmirror-personal.conf +0 -0
  163. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/grokmirror.conf +0 -0
  164. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/klmcp-doctor.sh +0 -0
  165. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/klmcp-grok-pull.sh +0 -0
  166. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/klmcp-ingest.sh +0 -0
  167. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/post-pull-hook.sh +0 -0
  168. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/rust_call_graph.py +0 -0
  169. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/systemd/etc-kernel-lore-mcp-env.sample +0 -0
  170. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/systemd/klmcp-grokmirror.service +0 -0
  171. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/systemd/klmcp-grokmirror.timer +0 -0
  172. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/systemd/klmcp-ingest.path +0 -0
  173. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/systemd/klmcp-ingest.service +0 -0
  174. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/systemd/klmcp-mcp.service +0 -0
  175. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/systemd/klmcp-sync.service +0 -0
  176. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/scripts/systemd/klmcp-sync.timer +0 -0
  177. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/bin/bench_blob_read.rs +0 -0
  178. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/bin/bench_ingest_stages.rs +0 -0
  179. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/bin/build_git_sidecar.rs +0 -0
  180. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/bin/build_over.rs +0 -0
  181. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/bin/doctor.rs +0 -0
  182. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/bin/ingest.rs +0 -0
  183. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/bin/reindex.rs +0 -0
  184. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/bin/sync.rs +0 -0
  185. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/bm25.rs +0 -0
  186. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/embedding.rs +0 -0
  187. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/error.rs +0 -0
  188. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/git_sidecar.rs +0 -0
  189. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/__main__.py +0 -0
  190. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/_surface_manifest.py +0 -0
  191. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/cli/__init__.py +0 -0
  192. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/cli/doctor.py +0 -0
  193. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/cli/embed.py +0 -0
  194. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/cli/ingest.py +0 -0
  195. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/cli/sync.py +0 -0
  196. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/config.py +0 -0
  197. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/cost_class.py +0 -0
  198. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/cursor.py +0 -0
  199. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/embedding.py +0 -0
  200. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/errors.py +0 -0
  201. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/freshness.py +0 -0
  202. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/health.py +0 -0
  203. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/kwic.py +0 -0
  204. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/logging_.py +0 -0
  205. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/mapping.py +0 -0
  206. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/models.py +0 -0
  207. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/observability.py +0 -0
  208. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/prompts.py +0 -0
  209. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/reader_cache.py +0 -0
  210. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/resources/__init__.py +0 -0
  211. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/resources/blind_spots.py +0 -0
  212. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/resources/coverage_stats.py +0 -0
  213. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/resources/templates.py +0 -0
  214. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/routes/__init__.py +0 -0
  215. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/routes/metrics.py +0 -0
  216. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/routes/status.py +0 -0
  217. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/sampling.py +0 -0
  218. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/timeout.py +0 -0
  219. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/__init__.py +0 -0
  220. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/corpus_stats.py +0 -0
  221. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/expand_citation.py +0 -0
  222. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/explain_patch.py +0 -0
  223. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/maintainer_profile.py +0 -0
  224. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/message.py +0 -0
  225. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/nearest.py +0 -0
  226. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/patch.py +0 -0
  227. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/patch_diff.py +0 -0
  228. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/patch_search.py +0 -0
  229. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/sampling_tools.py +0 -0
  230. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/search.py +0 -0
  231. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/series.py +0 -0
  232. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/thread.py +0 -0
  233. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/kernel_lore_mcp/tools/thread_state.py +0 -0
  234. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/maintainers.rs +0 -0
  235. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/metadata.rs +0 -0
  236. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/parse.rs +0 -0
  237. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/path_tier.rs +0 -0
  238. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/schema.rs +0 -0
  239. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/state.rs +0 -0
  240. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/store.rs +0 -0
  241. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/sync.rs +0 -0
  242. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/tid.rs +0 -0
  243. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/timeout.rs +0 -0
  244. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/src/trigram.rs +0 -0
  245. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/__init__.py +0 -0
  246. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/bin_ingest.rs +0 -0
  247. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/__init__.py +0 -0
  248. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/conftest.py +0 -0
  249. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/fixtures/__init__.py +0 -0
  250. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_annotations.py +0 -0
  251. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_cost_class.py +0 -0
  252. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_cost_hints.py +0 -0
  253. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_coverage_stats.py +0 -0
  254. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_cursor.py +0 -0
  255. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_embedding_e2e.py +0 -0
  256. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_errors.py +0 -0
  257. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_freshness.py +0 -0
  258. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_fuzzy_search.py +0 -0
  259. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_http_transport.py +0 -0
  260. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_ingest_and_reader.py +0 -0
  261. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_kwic.py +0 -0
  262. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_logging_profile.py +0 -0
  263. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_mcp_adversarial.py +0 -0
  264. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_observability.py +0 -0
  265. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_path_mentions.py +0 -0
  266. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_prompts.py +0 -0
  267. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_regex_hosted.py +0 -0
  268. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_resource_templates.py +0 -0
  269. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_resources_routes.py +0 -0
  270. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_response_format.py +0 -0
  271. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_sampling_tools.py +0 -0
  272. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_smoke.py +0 -0
  273. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_status_subcommand.py +0 -0
  274. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_stdio_subprocess.py +0 -0
  275. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_surface_manifest.py +0 -0
  276. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_sync_cli.py +0 -0
  277. {kernel_lore_mcp-0.3.1 → kernel_lore_mcp-0.3.2}/tests/python/test_thread_patch_explain.py +0 -0
@@ -10,6 +10,41 @@ release tags move them into a dated section. Release process in
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.3.2] — 2026-04-22
14
+
15
+ ### Added
16
+
17
+ - Added `lore_fix_status`, a bug-centric fix-correlation tool that
18
+ follows `Reported-by:`, `Link:`, and `Closes:` evidence across
19
+ separate lore threads and upgrades to an authoritative `merged`
20
+ verdict when the git sidecar can confirm it.
21
+ - Added a normalized trailer-reference side index in `over.db` for
22
+ `reported_by`, `fixes`, `link`, and `closes`, plus backfill support
23
+ and reader-side exact lookups for syzbot hashes, lore message-ids,
24
+ SHA prefixes, lowercased URLs, and normalized trailer payloads.
25
+ - Added human-friendly `since` / `until` parsing for MCP tools and the
26
+ Rust query router: raw nanoseconds remain supported, but callers can
27
+ now also pass ISO dates, RFC3339 timestamps, and relative windows
28
+ such as `90d`.
29
+
30
+ ### Changed
31
+
32
+ - `lore_activity`, `lore_author_profile`, `lore_file_timeline`,
33
+ `lore_path_mentions`, `lore_eq`, `lore_in_list`, `lore_count`,
34
+ `lore_substr_subject`, `lore_substr_trailers`, and `lore_regex` now
35
+ accept both legacy `*_unix_ns` bounds and new human-readable
36
+ `since` / `until` fields, with shared validation.
37
+ - `lore_search` query parsing now understands `since:` and `until:`
38
+ bounds in human formats instead of requiring raw integer nanoseconds
39
+ only.
40
+
41
+ ### Fixed
42
+
43
+ - Upper-bound date filtering is now carried consistently through the
44
+ Rust reader, over.db index helpers, PyO3 boundary, and MCP tool
45
+ layer instead of being post-filtered inconsistently or silently
46
+ ignored on some paths.
47
+
13
48
  ## [0.3.1] — 2026-04-22
14
49
 
15
50
  ### Added
@@ -2638,7 +2638,7 @@ dependencies = [
2638
2638
 
2639
2639
  [[package]]
2640
2640
  name = "kernel_lore_mcp"
2641
- version = "0.3.1"
2641
+ version = "0.3.2"
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.1"
3
+ version = "0.3.2"
4
4
  edition = "2024"
5
5
  rust-version = "1.85"
6
6
  authors = ["Michael Bommarito <michael@bommaritollc.com>"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kernel-lore-mcp
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Classifier: Development Status :: 2 - Pre-Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -95,7 +95,7 @@ git clone --depth 1 https://github.com/mjbommar/kernel-lore-mcp.git
95
95
  cd kernel-lore-mcp && ./scripts/agentic_smoke.sh local
96
96
  # PASS: 7/7 tools, 5/5 resource templates, 5/5 prompts (the
97
97
  # `REQUIRED_*` subset from src/kernel_lore_mcp/_surface_manifest.py;
98
- # the live server registers 24 tools in total).
98
+ # the live server registers 25 tools in total).
99
99
  ```
100
100
 
101
101
  Then pick your agent and copy its snippet from
@@ -146,13 +146,14 @@ Want production-grade systemd deployment (single `klmcp-sync.timer`
146
146
  replacing the pre-v0.2.0 grokmirror + ingest pair)?
147
147
  [`docs/ops/runbook.md`](./docs/ops/runbook.md) §1 onwards.
148
148
 
149
- ## Status — v0.3.1 (2026-04-22)
149
+ ## Status — v0.3.2 (2026-04-22)
150
150
 
151
- Current release: `v0.3.1`, the first patch line after the hosted
152
- readiness release. The focus is same-box sync visibility and safer
153
- inline BM25 behavior: live sync state in `/status`, explicit
154
- post-ingest stage logs, conservative BM25 writer defaults, and
155
- load-aware retry hints when writer-heavy work is active.
151
+ Current release: `v0.3.2`, the follow-on patch after the hosted
152
+ readiness and same-box sync hardening line. The focus is better bug
153
+ workflow ergonomics and safer query scoping: a first-class
154
+ `lore_fix_status` tool, indexed trailer-reference correlation for
155
+ syzbot / lore / `Fixes:` joins, and human-readable `since` / `until`
156
+ bounds across both tools and `lore_search`.
156
157
 
157
158
  Shipped:
158
159
 
@@ -164,7 +165,7 @@ Shipped:
164
165
  manifest fetch, gix smart-HTTP clone-or-fetch (rayon-fanned
165
166
  across shards), ingest, tid rebuild, generation bump — all
166
167
  under one writer lock so there's no trigger/debounce race.
167
- - Full MCP surface: **24 tools** (search, primitives, sampling-
168
+ - Full MCP surface: **25 tools** (search, primitives, sampling-
168
169
  backed summarize/classify/explain, authoritative `merged` /
169
170
  `picked_up` verdicts via git-sidecar, `lore_corpus_stats` for
170
171
  coverage transparency, `lore_author_footprint` for address-
@@ -60,7 +60,7 @@ git clone --depth 1 https://github.com/mjbommar/kernel-lore-mcp.git
60
60
  cd kernel-lore-mcp && ./scripts/agentic_smoke.sh local
61
61
  # PASS: 7/7 tools, 5/5 resource templates, 5/5 prompts (the
62
62
  # `REQUIRED_*` subset from src/kernel_lore_mcp/_surface_manifest.py;
63
- # the live server registers 24 tools in total).
63
+ # the live server registers 25 tools in total).
64
64
  ```
65
65
 
66
66
  Then pick your agent and copy its snippet from
@@ -111,13 +111,14 @@ Want production-grade systemd deployment (single `klmcp-sync.timer`
111
111
  replacing the pre-v0.2.0 grokmirror + ingest pair)?
112
112
  [`docs/ops/runbook.md`](./docs/ops/runbook.md) §1 onwards.
113
113
 
114
- ## Status — v0.3.1 (2026-04-22)
114
+ ## Status — v0.3.2 (2026-04-22)
115
115
 
116
- Current release: `v0.3.1`, the first patch line after the hosted
117
- readiness release. The focus is same-box sync visibility and safer
118
- inline BM25 behavior: live sync state in `/status`, explicit
119
- post-ingest stage logs, conservative BM25 writer defaults, and
120
- load-aware retry hints when writer-heavy work is active.
116
+ Current release: `v0.3.2`, the follow-on patch after the hosted
117
+ readiness and same-box sync hardening line. The focus is better bug
118
+ workflow ergonomics and safer query scoping: a first-class
119
+ `lore_fix_status` tool, indexed trailer-reference correlation for
120
+ syzbot / lore / `Fixes:` joins, and human-readable `since` / `until`
121
+ bounds across both tools and `lore_search`.
121
122
 
122
123
  Shipped:
123
124
 
@@ -129,7 +130,7 @@ Shipped:
129
130
  manifest fetch, gix smart-HTTP clone-or-fetch (rayon-fanned
130
131
  across shards), ingest, tid rebuild, generation bump — all
131
132
  under one writer lock so there's no trigger/debounce race.
132
- - Full MCP surface: **24 tools** (search, primitives, sampling-
133
+ - Full MCP surface: **25 tools** (search, primitives, sampling-
133
134
  backed summarize/classify/explain, authoritative `merged` /
134
135
  `picked_up` verdicts via git-sidecar, `lore_corpus_stats` for
135
136
  coverage transparency, `lore_author_footprint` for address-
@@ -13,8 +13,22 @@ Status markers:
13
13
  ## Current release track (2026-04-22)
14
14
 
15
15
  `v0.3.0` shipped on 2026-04-21. The active patch line is
16
- `v0.3.1`: sync-under-load hardening, operator visibility, and release
17
- cleanup after the first same-box hosted soak on `server6`.
16
+ `v0.3.2`: bug-workflow correlation and human time-bound ergonomics
17
+ after the same-box hosted soak and sync-under-load hardening on
18
+ `server6`.
19
+
20
+ ### 0.3.2 target — bug correlation + human time bounds
21
+
22
+ - [x] Add a first-class `lore_fix_status` tool for bug-centric
23
+ correlation across separate lore threads, with authoritative
24
+ `merged` only when the git sidecar can confirm it.
25
+ - [x] Materialize a normalized trailer-reference index for
26
+ `reported_by`, `fixes`, `link`, and `closes`, and expose exact
27
+ reader lookups over syzbot hashes, lore mids, SHA prefixes, and
28
+ normalized trailer values.
29
+ - [x] Accept human-friendly `since` / `until` values across the
30
+ low-level tools and query router, while keeping raw
31
+ `*_unix_ns` compatibility for existing clients.
18
32
 
19
33
  ### 0.3.1 target — sync-under-load visibility + safer inline BM25
20
34
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kernel-lore-mcp"
3
- version = "0.3.1"
3
+ version = "0.3.2"
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" }
@@ -30,7 +30,7 @@ use crate::over::{DddPayload, OverDb, OverRow};
30
30
  use crate::parse::{self, ParsedMessage};
31
31
  use crate::state::State;
32
32
  use crate::store::{Store, StoreOffset};
33
- use crate::trigram::{segment_dir as trigram_segment_dir, SegmentBuilder as TrigramBuilder};
33
+ use crate::trigram::{SegmentBuilder as TrigramBuilder, segment_dir as trigram_segment_dir};
34
34
 
35
35
  /// Ingest one public-inbox shard end-to-end.
36
36
  ///
@@ -15,7 +15,7 @@ from typing import Any
15
15
 
16
16
  __all__ = ["__version__", "native_version"]
17
17
 
18
- __version__ = "0.3.1"
18
+ __version__ = "0.3.2"
19
19
 
20
20
 
21
21
  def __getattr__(name: str) -> Any:
@@ -33,6 +33,7 @@ def rebuild_tid(data_dir: str | PathLike[str]) -> TidRebuildResult: ...
33
33
  def rebuild_bm25(data_dir: str | PathLike[str]) -> int: ...
34
34
  def backfill_subject_normalized(data_dir: str | PathLike[str]) -> int: ...
35
35
  def backfill_trailer_emails(data_dir: str | PathLike[str]) -> int: ...
36
+ def backfill_trailer_refs(data_dir: str | PathLike[str]) -> int: ...
36
37
  def backfill_touched_files(data_dir: str | PathLike[str]) -> int: ...
37
38
  def backfill_side_table_dates(data_dir: str | PathLike[str]) -> int: ...
38
39
  def rebuild_path_vocab(data_dir: str | PathLike[str]) -> int: ...
@@ -109,6 +110,7 @@ class Reader:
109
110
  file: str | None = ...,
110
111
  function: str | None = ...,
111
112
  since_unix_ns: int | None = ...,
113
+ until_unix_ns: int | None = ...,
112
114
  list: str | None = ...,
113
115
  limit: int = ...,
114
116
  ) -> list[dict[str, Any]]: ...
@@ -144,6 +146,7 @@ class Reader:
144
146
  field: str,
145
147
  value: str,
146
148
  since_unix_ns: int | None = ...,
149
+ until_unix_ns: int | None = ...,
147
150
  list: str | None = ...,
148
151
  limit: int = ...,
149
152
  ) -> list[dict[str, Any]]: ...
@@ -152,6 +155,7 @@ class Reader:
152
155
  field: str,
153
156
  values: list[str],
154
157
  since_unix_ns: int | None = ...,
158
+ until_unix_ns: int | None = ...,
155
159
  list: str | None = ...,
156
160
  limit: int = ...,
157
161
  ) -> list[dict[str, Any]]: ...
@@ -160,6 +164,7 @@ class Reader:
160
164
  field: str,
161
165
  value: str,
162
166
  since_unix_ns: int | None = ...,
167
+ until_unix_ns: int | None = ...,
163
168
  list: str | None = ...,
164
169
  ) -> dict[str, Any]: ...
165
170
  def author_profile(
@@ -167,6 +172,7 @@ class Reader:
167
172
  addr: str,
168
173
  list: str | None = ...,
169
174
  since_unix_ns: int | None = ...,
175
+ until_unix_ns: int | None = ...,
170
176
  limit: int = ...,
171
177
  include_mentions: bool = ...,
172
178
  mention_limit: int = ...,
@@ -182,6 +188,7 @@ class Reader:
182
188
  needle: str,
183
189
  list: str | None = ...,
184
190
  since_unix_ns: int | None = ...,
191
+ until_unix_ns: int | None = ...,
185
192
  limit: int = ...,
186
193
  ) -> list[dict[str, Any]]: ...
187
194
  def substr_trailers(
@@ -190,6 +197,17 @@ class Reader:
190
197
  value_substring: str,
191
198
  list: str | None = ...,
192
199
  since_unix_ns: int | None = ...,
200
+ until_unix_ns: int | None = ...,
201
+ limit: int = ...,
202
+ ) -> list[dict[str, Any]]: ...
203
+ def trailer_ref_lookup(
204
+ self,
205
+ name: str,
206
+ ref_kind: str,
207
+ ref_value: str,
208
+ list: str | None = ...,
209
+ since_unix_ns: int | None = ...,
210
+ until_unix_ns: int | None = ...,
193
211
  limit: int = ...,
194
212
  ) -> list[dict[str, Any]]: ...
195
213
  def regex(
@@ -199,6 +217,7 @@ class Reader:
199
217
  anchor_required: bool = ...,
200
218
  list: str | None = ...,
201
219
  since_unix_ns: int | None = ...,
220
+ until_unix_ns: int | None = ...,
202
221
  limit: int = ...,
203
222
  ) -> list[dict[str, Any]]: ...
204
223
  def diff(
@@ -234,5 +253,6 @@ class Reader:
234
253
  match_mode: str = ...,
235
254
  list: str | None = ...,
236
255
  since_unix_ns: int | None = ...,
256
+ until_unix_ns: int | None = ...,
237
257
  limit: int = ...,
238
258
  ) -> list[dict[str, Any]]: ...
@@ -70,6 +70,7 @@ def build_server(settings: Settings | None = None) -> FastMCP:
70
70
  from kernel_lore_mcp.tools.expand_citation import lore_expand_citation
71
71
  from kernel_lore_mcp.tools.explain_patch import lore_explain_patch
72
72
  from kernel_lore_mcp.tools.file_timeline import lore_file_timeline
73
+ from kernel_lore_mcp.tools.fix_status import lore_fix_status
73
74
  from kernel_lore_mcp.tools.maintainer_profile import lore_maintainer_profile
74
75
  from kernel_lore_mcp.tools.message import lore_message
75
76
  from kernel_lore_mcp.tools.nearest import lore_nearest, lore_similar
@@ -166,6 +167,10 @@ def build_server(settings: Settings | None = None) -> FastMCP:
166
167
  lore_thread_state,
167
168
  "Classify a thread (rfc/superseded/nacked/...)",
168
169
  )
170
+ _reg(
171
+ lore_fix_status,
172
+ "Correlate a bug report to candidate fixes across threads",
173
+ )
169
174
  _reg(
170
175
  lore_subsystem_churn,
171
176
  "Hot files in a list/subsystem (top-N + histogram)",
@@ -0,0 +1,118 @@
1
+ """Shared parsing for human-friendly time bounds on MCP tools."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ from datetime import UTC, date, datetime, timedelta
7
+
8
+ from kernel_lore_mcp.errors import invalid_argument
9
+
10
+ TIME_BOUND_DESCRIPTION = (
11
+ "ISO date/time, raw nanoseconds since epoch, or a relative window like `90d` / `6mo`."
12
+ )
13
+
14
+ _RELATIVE_RE = re.compile(r"^(?P<count>\d+)(?P<unit>mo|y|w|d|h|s)$", re.IGNORECASE)
15
+
16
+
17
+ def parse_time_bound(
18
+ *,
19
+ name: str,
20
+ value: str,
21
+ now: datetime | None = None,
22
+ ) -> int:
23
+ raw = value.strip()
24
+ if not raw:
25
+ raise invalid_argument(
26
+ name=name,
27
+ reason="time bound must be non-empty",
28
+ value=value,
29
+ example="2026-01-15 or 90d",
30
+ )
31
+ if raw.isdigit():
32
+ return int(raw)
33
+
34
+ match = _RELATIVE_RE.fullmatch(raw)
35
+ if match:
36
+ count = int(match.group("count"))
37
+ unit = match.group("unit").lower()
38
+ now_dt = now or datetime.now(tz=UTC)
39
+ if unit == "s":
40
+ delta = timedelta(seconds=count)
41
+ elif unit == "h":
42
+ delta = timedelta(hours=count)
43
+ elif unit == "d":
44
+ delta = timedelta(days=count)
45
+ elif unit == "w":
46
+ delta = timedelta(weeks=count)
47
+ elif unit == "mo":
48
+ delta = timedelta(days=30 * count)
49
+ else:
50
+ delta = timedelta(days=365 * count)
51
+ return int((now_dt - delta).timestamp() * 1_000_000_000)
52
+
53
+ try:
54
+ if len(raw) == 10 and raw.count("-") == 2:
55
+ dt = datetime.combine(date.fromisoformat(raw), datetime.min.time(), tzinfo=UTC)
56
+ else:
57
+ dt = datetime.fromisoformat(raw.replace("Z", "+00:00"))
58
+ if dt.tzinfo is None:
59
+ dt = dt.replace(tzinfo=UTC)
60
+ else:
61
+ dt = dt.astimezone(UTC)
62
+ except ValueError as exc:
63
+ raise invalid_argument(
64
+ name=name,
65
+ reason=(
66
+ "time bound must be ISO-8601 (`2026-01-15`, `2026-01-15T00:00:00Z`), "
67
+ "raw nanoseconds, or a relative window like `90d` / `6mo`"
68
+ ),
69
+ value=value,
70
+ example="2026-01-15 or 90d",
71
+ ) from exc
72
+ return int(dt.timestamp() * 1_000_000_000)
73
+
74
+
75
+ def resolve_time_bounds(
76
+ *,
77
+ since: str | None = None,
78
+ since_unix_ns: int | None = None,
79
+ until: str | None = None,
80
+ until_unix_ns: int | None = None,
81
+ ) -> tuple[int | None, int | None]:
82
+ if since is not None and since_unix_ns is not None:
83
+ raise invalid_argument(
84
+ name="since",
85
+ reason="pass only one of `since` or `since_unix_ns`",
86
+ value={"since": since, "since_unix_ns": since_unix_ns},
87
+ example='{"since": "2026-01-15"}',
88
+ )
89
+ if until is not None and until_unix_ns is not None:
90
+ raise invalid_argument(
91
+ name="until",
92
+ reason="pass only one of `until` or `until_unix_ns`",
93
+ value={"until": until, "until_unix_ns": until_unix_ns},
94
+ example='{"until": "2026-04-01"}',
95
+ )
96
+
97
+ resolved_since = since_unix_ns
98
+ resolved_until = until_unix_ns
99
+ if since is not None:
100
+ resolved_since = parse_time_bound(name="since", value=since)
101
+ if until is not None:
102
+ resolved_until = parse_time_bound(name="until", value=until)
103
+
104
+ if (
105
+ resolved_since is not None
106
+ and resolved_until is not None
107
+ and resolved_since >= resolved_until
108
+ ):
109
+ raise invalid_argument(
110
+ name="window",
111
+ reason="since must be less than until",
112
+ value={"since": resolved_since, "until": resolved_until},
113
+ example='{"since": "2026-01-01", "until": "2026-02-01"}',
114
+ )
115
+ return resolved_since, resolved_until
116
+
117
+
118
+ __all__ = ["TIME_BOUND_DESCRIPTION", "parse_time_bound", "resolve_time_bounds"]
@@ -15,6 +15,7 @@ from kernel_lore_mcp.cursor import decode_cursor, mint_cursor, query_hash
15
15
  from kernel_lore_mcp.freshness import build_freshness
16
16
  from kernel_lore_mcp.mapping import row_to_activity_row
17
17
  from kernel_lore_mcp.models import ActivityResponse
18
+ from kernel_lore_mcp.time_bounds import TIME_BOUND_DESCRIPTION, resolve_time_bounds
18
19
  from kernel_lore_mcp.timeout import run_with_timeout
19
20
 
20
21
  _CONCISE_ROWS = 20
@@ -29,10 +30,22 @@ async def lore_activity(
29
30
  str | None,
30
31
  Field(description="Exact identifier, e.g. `smb_check_perm_dacl`."),
31
32
  ] = None,
33
+ since: Annotated[
34
+ str | None,
35
+ Field(description=f"Human-friendly lower bound. {TIME_BOUND_DESCRIPTION}"),
36
+ ] = None,
32
37
  since_unix_ns: Annotated[
33
38
  int | None,
34
39
  Field(description="Lower bound on message date (nanoseconds since epoch UTC)."),
35
40
  ] = None,
41
+ until: Annotated[
42
+ str | None,
43
+ Field(description=f"Human-friendly exclusive upper bound. {TIME_BOUND_DESCRIPTION}"),
44
+ ] = None,
45
+ until_unix_ns: Annotated[
46
+ int | None,
47
+ Field(description="Exclusive upper bound on message date (nanoseconds since epoch UTC)."),
48
+ ] = None,
36
49
  list: Annotated[
37
50
  str | None,
38
51
  Field(description="Restrict to one mailing list (e.g. `linux-cifs`)."),
@@ -78,6 +91,12 @@ async def lore_activity(
78
91
 
79
92
  settings = get_settings()
80
93
  reader = _core.Reader(settings.data_dir)
94
+ resolved_since, resolved_until = resolve_time_bounds(
95
+ since=since,
96
+ since_unix_ns=since_unix_ns,
97
+ until=until,
98
+ until_unix_ns=until_unix_ns,
99
+ )
81
100
 
82
101
  # Cursor scope: (file, function, since, list) define the sorted
83
102
  # result set. `limit` / `response_format` can change between
@@ -86,7 +105,8 @@ async def lore_activity(
86
105
  "lore_activity",
87
106
  file or "",
88
107
  function or "",
89
- since_unix_ns or 0,
108
+ resolved_since or 0,
109
+ resolved_until or 0,
90
110
  list or "",
91
111
  )
92
112
  resume = decode_cursor(cursor, expected_q_hash=q_hash, arg_name="cursor")
@@ -98,7 +118,8 @@ async def lore_activity(
98
118
  reader.activity,
99
119
  file,
100
120
  function,
101
- since_unix_ns,
121
+ resolved_since,
122
+ resolved_until,
102
123
  list,
103
124
  fetch_budget,
104
125
  )
@@ -66,9 +66,7 @@ class FootprintHit(BaseModel):
66
66
 
67
67
  class AuthorFootprintResponse(BaseModel):
68
68
  addr_queried: str
69
- total_distinct: int = Field(
70
- description="Distinct message_ids across all three sources."
71
- )
69
+ total_distinct: int = Field(description="Distinct message_ids across all three sources.")
72
70
  authored_count: int
73
71
  trailer_mention_count: int
74
72
  body_mention_count: int
@@ -165,7 +163,7 @@ async def lore_author_footprint(
165
163
 
166
164
  # Source 1: authored rows, via indexed from_addr.
167
165
  authored_rows = await run_with_timeout(
168
- reader.eq, "from_addr", addr, None, list_filter, limit
166
+ reader.eq, "from_addr", addr, None, None, list_filter, limit
169
167
  )
170
168
  authored_mids = {r["message_id"] for r in authored_rows}
171
169
 
@@ -182,6 +180,7 @@ async def lore_author_footprint(
182
180
  addr,
183
181
  list_filter,
184
182
  None,
183
+ None,
185
184
  0, # we don't want the authored slice here
186
185
  True, # include_mentions
187
186
  min(limit, 500),
@@ -209,11 +208,7 @@ async def lore_author_footprint(
209
208
  query = " ".join(tokens)
210
209
  try:
211
210
  scored = await run_with_timeout(reader.prose_search, query, limit)
212
- body_rows = [
213
- (r, r.get("_score", 0.0))
214
- for r in scored
215
- if r.get("message_id")
216
- ]
211
+ body_rows = [(r, r.get("_score", 0.0)) for r in scored if r.get("message_id")]
217
212
  except Exception: # noqa: BLE001
218
213
  # BM25 can still error on pathological inputs; skipping
219
214
  # this source is better than 500ing the whole tool.
@@ -241,11 +236,7 @@ async def lore_author_footprint(
241
236
  # Optional list_filter post-filter on body_mention rows
242
237
  # (BM25 doesn't honor it intrinsically).
243
238
  if list_filter is not None:
244
- per_mid = {
245
- mid: row
246
- for mid, row in per_mid.items()
247
- if row.get("list") == list_filter
248
- }
239
+ per_mid = {mid: row for mid, row in per_mid.items() if row.get("list") == list_filter}
249
240
  roles = {mid: roles[mid] for mid in per_mid}
250
241
 
251
242
  # Sort newest-first; cursor-skip before truncating.
@@ -283,15 +274,9 @@ async def lore_author_footprint(
283
274
  for row in page
284
275
  ]
285
276
 
286
- authored_count = sum(
287
- 1 for h in hits if "authored" in h.roles
288
- )
289
- trailer_count = sum(
290
- 1 for h in hits if "trailer_mention" in h.roles
291
- )
292
- body_count = sum(
293
- 1 for h in hits if "body_mention" in h.roles
294
- )
277
+ authored_count = sum(1 for h in hits if "authored" in h.roles)
278
+ trailer_count = sum(1 for h in hits if "trailer_mention" in h.roles)
279
+ body_count = sum(1 for h in hits if "body_mention" in h.roles)
295
280
 
296
281
  next_cursor: str | None = None
297
282
  if hits and total_available > limit:
@@ -33,6 +33,7 @@ from kernel_lore_mcp.models import (
33
33
  ReceivedTrailerStats,
34
34
  SubsystemBucket,
35
35
  )
36
+ from kernel_lore_mcp.time_bounds import TIME_BOUND_DESCRIPTION, resolve_time_bounds
36
37
  from kernel_lore_mcp.timeout import run_with_timeout
37
38
 
38
39
 
@@ -64,10 +65,22 @@ async def lore_author_profile(
64
65
  ),
65
66
  ),
66
67
  ] = None,
68
+ since: Annotated[
69
+ str | None,
70
+ Field(description=f"Human-friendly lower bound. {TIME_BOUND_DESCRIPTION}"),
71
+ ] = None,
67
72
  since_unix_ns: Annotated[
68
73
  int | None,
69
74
  Field(description="Lower-bound on message date (ns since epoch)."),
70
75
  ] = None,
76
+ until: Annotated[
77
+ str | None,
78
+ Field(description=f"Human-friendly exclusive upper bound. {TIME_BOUND_DESCRIPTION}"),
79
+ ] = None,
80
+ until_unix_ns: Annotated[
81
+ int | None,
82
+ Field(description="Exclusive upper-bound on message date (ns since epoch)."),
83
+ ] = None,
71
84
  limit: Annotated[
72
85
  int,
73
86
  Field(
@@ -128,18 +141,27 @@ async def lore_author_profile(
128
141
  value=addr,
129
142
  example="gregkh@linuxfoundation.org",
130
143
  )
131
- if include_mentions and list_filter is None and since_unix_ns is None:
144
+ resolved_since, resolved_until = resolve_time_bounds(
145
+ since=since,
146
+ since_unix_ns=since_unix_ns,
147
+ until=until,
148
+ until_unix_ns=until_unix_ns,
149
+ )
150
+ if include_mentions and list_filter is None and resolved_since is None:
132
151
  raise invalid_argument(
133
152
  name="include_mentions",
134
153
  reason=(
135
154
  "unbounded mention scan is not allowed on this server; "
136
155
  "pass either `list_filter` (e.g. list_filter='linux-cifs') "
137
- "or `since_unix_ns` (a date lower bound) to narrow"
138
- ),
139
- value={"include_mentions": True, "list_filter": None, "since_unix_ns": None},
140
- example=(
141
- '{"include_mentions": true, "list_filter": "linux-cifs"}'
156
+ "or `since` / `since_unix_ns` (a date lower bound) to narrow"
142
157
  ),
158
+ value={
159
+ "include_mentions": True,
160
+ "list_filter": None,
161
+ "since": since,
162
+ "since_unix_ns": since_unix_ns,
163
+ },
164
+ example=('{"include_mentions": true, "list_filter": "linux-cifs"}'),
143
165
  )
144
166
 
145
167
  from kernel_lore_mcp import _core
@@ -150,7 +172,8 @@ async def lore_author_profile(
150
172
  reader.author_profile,
151
173
  addr,
152
174
  list_filter,
153
- since_unix_ns,
175
+ resolved_since,
176
+ resolved_until,
154
177
  limit,
155
178
  include_mentions,
156
179
  mention_limit,