boost-skill-cli 1.2.54__tar.gz → 1.2.56__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 (822) hide show
  1. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/CLAUDE.md +20 -0
  2. {boost_skill_cli-1.2.54/boost_skill_cli.egg-info → boost_skill_cli-1.2.56}/PKG-INFO +5 -3
  3. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/README.md +4 -2
  4. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/_version.py +2 -2
  5. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/configuration.py +83 -7
  6. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/discovery.py +23 -2
  7. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/info.py +15 -1
  8. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/quality.py +24 -5
  9. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/quickstart.py +20 -0
  10. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/dense.py +171 -19
  11. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/mcp.py +56 -0
  12. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56/boost_skill_cli.egg-info}/PKG-INFO +5 -3
  13. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_skill_cli.egg-info/SOURCES.txt +2 -0
  14. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/mcp-hub.html +9 -7
  15. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dense-reindex-reuses-whole-taps.md +33 -2
  16. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-cannot-read-a-skill-before-installing.md +25 -3
  17. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap.html +60 -5
  18. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/doctor.feature +4 -2
  19. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_configuration.py +2 -2
  20. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_info.py +40 -0
  21. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_quality.py +40 -1
  22. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_quickstart.py +74 -0
  23. boost_skill_cli-1.2.56/tests/unit/test_dense_entry_reuse.py +512 -0
  24. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_fallback.py +8 -1
  25. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_shard_unreadable_vectors.py +1 -1
  26. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_shards.py +1 -1
  27. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mcp.py +1 -1
  28. boost_skill_cli-1.2.56/tests/unit/test_mcp_read.py +341 -0
  29. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.gitattributes +0 -0
  30. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.gitignore +0 -0
  31. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.gitleaks.toml +0 -0
  32. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.htmlvalidate.json +0 -0
  33. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.lighthouserc.json +0 -0
  34. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.lycheeignore +0 -0
  35. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.markdownlint-cli2.jsonc +0 -0
  36. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.pre-commit-config.yaml +0 -0
  37. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.stylelintrc.json +0 -0
  38. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.vale/styles/boost/AIWriting.yml +0 -0
  39. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.vale/styles/boost/Terminology.yml +0 -0
  40. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
  41. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/.vale.ini +0 -0
  42. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/CODE_OF_CONDUCT.md +0 -0
  43. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/CONTRIBUTING.md +0 -0
  44. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/DCO +0 -0
  45. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/GOVERNANCE.md +0 -0
  46. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/LICENSE +0 -0
  47. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/MAINTAINERS.md +0 -0
  48. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/MANIFEST.in +0 -0
  49. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/Makefile +0 -0
  50. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/SECURITY.md +0 -0
  51. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/SUPPORT.md +0 -0
  52. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost +0 -0
  53. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/__init__.py +0 -0
  54. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/__main__.py +0 -0
  55. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/cli.py +0 -0
  56. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/cliparse.py +0 -0
  57. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/__init__.py +0 -0
  58. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/_common.py +0 -0
  59. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/bmad.py +0 -0
  60. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/hooks.py +0 -0
  61. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/intelligence.py +0 -0
  62. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/pkg.py +0 -0
  63. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/run.py +0 -0
  64. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/safety.py +0 -0
  65. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/taps.py +0 -0
  66. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/commands/team.py +0 -0
  67. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/__init__.py +0 -0
  68. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/adapters.py +0 -0
  69. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/agents.py +0 -0
  70. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/ai.py +0 -0
  71. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/aihost.py +0 -0
  72. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/bmad.py +0 -0
  73. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/bootstrap.py +0 -0
  74. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/browse.py +0 -0
  75. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/builtin.py +0 -0
  76. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/capabilities.py +0 -0
  77. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/catalog.py +0 -0
  78. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/catalogbundle.py +0 -0
  79. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/chat.py +0 -0
  80. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/claude_settings.py +0 -0
  81. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/complete.py +0 -0
  82. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/config.py +0 -0
  83. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/ed25519.py +0 -0
  84. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/embed.py +0 -0
  85. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/faithfulness.py +0 -0
  86. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/frontmatter.py +0 -0
  87. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/gitutil.py +0 -0
  88. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/hookhost.py +0 -0
  89. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/imperative.py +0 -0
  90. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/injectscan.py +0 -0
  91. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/installscan.py +0 -0
  92. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/integrity.py +0 -0
  93. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/journal.py +0 -0
  94. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/localembed.py +0 -0
  95. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/lockfile.py +0 -0
  96. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/logs.py +0 -0
  97. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/mcpdecl.py +0 -0
  98. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/mcphost.py +0 -0
  99. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/minisign.py +0 -0
  100. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/nethttp.py +0 -0
  101. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/output.py +0 -0
  102. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/paths.py +0 -0
  103. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/policy.py +0 -0
  104. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/projectlock.py +0 -0
  105. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/provenance.py +0 -0
  106. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/rag.py +0 -0
  107. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/registry.py +0 -0
  108. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/resolve.py +0 -0
  109. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/rules.py +0 -0
  110. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/scopes.py +0 -0
  111. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/secretscan.py +0 -0
  112. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/selfupdate.py +0 -0
  113. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/serve.py +0 -0
  114. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/shards.py +0 -0
  115. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/stackprobe.py +0 -0
  116. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/staleness.py +0 -0
  117. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/store.py +0 -0
  118. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/trustaudit.py +0 -0
  119. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/typosquat.py +0 -0
  120. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/updatediff.py +0 -0
  121. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/util.py +0 -0
  122. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/core/workflows.py +0 -0
  123. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/data/registries.json +0 -0
  124. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/data/rules/boost-first.mdc +0 -0
  125. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/errors.py +0 -0
  126. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_cli/spin.py +0 -0
  127. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_langchain/__init__.py +0 -0
  128. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_langchain/_compat.py +0 -0
  129. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_langchain/graph.py +0 -0
  130. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_langchain/loader.py +0 -0
  131. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_langchain/py.typed +0 -0
  132. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_langchain/retriever.py +0 -0
  133. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  134. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  135. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_skill_cli.egg-info/requires.txt +0 -0
  136. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/boost_skill_cli.egg-info/top_level.txt +0 -0
  137. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/codecov.yml +0 -0
  138. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/.claude/settings.local.json +0 -0
  139. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/DEBUGGING.md +0 -0
  140. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/adapters.html +0 -0
  141. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/architecture/README.md +0 -0
  142. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/architecture/c4-components-core.md +0 -0
  143. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/architecture/c4-containers.md +0 -0
  144. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/architecture/c4-context.md +0 -0
  145. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/architecture/c4-dynamic-install.md +0 -0
  146. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/bmad.md +0 -0
  147. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/distill.gif +0 -0
  148. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/doctor.gif +0 -0
  149. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/explain.gif +0 -0
  150. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/hooks.gif +0 -0
  151. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/install.gif +0 -0
  152. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/pulse.gif +0 -0
  153. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/search.gif +0 -0
  154. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/gifs/tap.gif +0 -0
  155. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/distill.tape +0 -0
  156. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/doctor.tape +0 -0
  157. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/explain.tape +0 -0
  158. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/hooks.tape +0 -0
  159. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/install.tape +0 -0
  160. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/pulse.tape +0 -0
  161. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/search.tape +0 -0
  162. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel/tapes/tap.tape +0 -0
  163. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/carousel.html +0 -0
  164. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/chat.html +0 -0
  165. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/code-review.md +0 -0
  166. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/commands.html +0 -0
  167. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/commit-audit.md +0 -0
  168. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/demo-index.json +0 -0
  169. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/demo.gif +0 -0
  170. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/demo.html +0 -0
  171. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/demo.tape +0 -0
  172. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/dependencies.md +0 -0
  173. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/design-roadmap.html +0 -0
  174. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/eval-latest.json +0 -0
  175. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/eval.html +0 -0
  176. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/index.html +0 -0
  177. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/langchain.html +0 -0
  178. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/openssf-badge.md +0 -0
  179. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/openssf-playbook.md +0 -0
  180. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/rag-architecture.md +0 -0
  181. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D01.md +0 -0
  182. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D02.md +0 -0
  183. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D03.md +0 -0
  184. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D04.md +0 -0
  185. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D05.md +0 -0
  186. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D06.md +0 -0
  187. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D07.md +0 -0
  188. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D08.md +0 -0
  189. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D09.md +0 -0
  190. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D10.md +0 -0
  191. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D11.md +0 -0
  192. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D12.md +0 -0
  193. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D13.md +0 -0
  194. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D14.md +0 -0
  195. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D15.md +0 -0
  196. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D16.md +0 -0
  197. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D17.md +0 -0
  198. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D18.md +0 -0
  199. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D19.md +0 -0
  200. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D20.md +0 -0
  201. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D21.md +0 -0
  202. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D22.md +0 -0
  203. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D23.md +0 -0
  204. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D24.md +0 -0
  205. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D25.md +0 -0
  206. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D26.md +0 -0
  207. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/BOOST-D27.md +0 -0
  208. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/a11y-sweep-flakes-on-color-contrast.md +0 -0
  209. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  210. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
  211. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
  212. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/agents-field-records-the-request-not-the-links.md +0 -0
  213. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ai-backend-fanout.md +0 -0
  214. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
  215. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
  216. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  217. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  218. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  219. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/bm25-has-no-stemming.md +0 -0
  220. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/bm25-index-is-one-json-blob.md +0 -0
  221. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/bmad-autopilot-one-command-persona-routing.md +0 -0
  222. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/bmad-hooks-all-hosts.md +0 -0
  223. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/boost-first-carried-the-losing-trigger.md +0 -0
  224. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/boost-first-rule.md +0 -0
  225. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/boost-langchain-publishing.md +0 -0
  226. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  227. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/branch-current-gate.md +0 -0
  228. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  229. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  230. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/browse-could-not-search-two-words.md +0 -0
  231. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  232. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  233. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  234. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  235. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/catalogue-entries-carry-no-content-identity.md +0 -0
  236. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/chat-cites-sources-by-a-number-it-never-prints.md +0 -0
  237. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/chat-command-grounded-conversational-search.md +0 -0
  238. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
  239. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
  240. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
  241. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  242. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/cli-command-audit.md +0 -0
  243. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/cli-output-ignored-the-terminal.md +0 -0
  244. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
  245. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
  246. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/cold-search-reads-the-whole-catalogue.md +0 -0
  247. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/command-carousel-page.md +0 -0
  248. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  249. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/completions-complete-only-command-names.md +0 -0
  250. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/completions-install-could-eat-your-rc-file.md +0 -0
  251. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  252. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  253. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  254. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  255. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
  256. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  257. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/crash-reports-leak-api-keys.md +0 -0
  258. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
  259. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
  260. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/demo-workflow-cancels-other-prs.md +0 -0
  261. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dense-reindex-has-no-progress-or-durability.md +0 -0
  262. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
  263. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dense-search-rescans-every-vector.md +0 -0
  264. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
  265. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
  266. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
  267. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dependabot-splits-multi-path-action-repos.md +0 -0
  268. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  269. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/discover-searches-github-not-a-stale-sample.md +0 -0
  270. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
  271. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  272. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  273. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/dry-run-promised-a-link-nobody-makes.md +0 -0
  274. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/efficiency-registries-ponytail-caveman.md +0 -0
  275. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  276. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/est-items-counts-agent-mirrors-as-items.md +0 -0
  277. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-corpus-cannot-see-real-retrieval.md +0 -0
  278. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-corpus-is-96x-smaller-than-a-real-install.md +0 -0
  279. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-corpus-is-one-strangers-repo.md +0 -0
  280. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-corpus-pins-have-no-refresh-path.md +0 -0
  281. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-corpus-was-not-actually-pinned.md +0 -0
  282. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-deduped-ranked-lists-by-name.md +0 -0
  283. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/eval-stats-could-never-publish.md +0 -0
  284. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/expanded-card-bodies-overflow.md +0 -0
  285. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  286. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  287. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  288. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  289. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  290. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  291. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  292. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  293. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  294. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/gemini-agent-frontmatter-sanitizer.md +0 -0
  295. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
  296. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/gemini-duplicate-skill-discovery.md +0 -0
  297. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/gemini-hooks-host-aware.md +0 -0
  298. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/gemini-mcp-parity.md +0 -0
  299. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/github-community-health-files.md +0 -0
  300. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  301. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/golden-set-grades-by-name-not-by-skill.md +0 -0
  302. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  303. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/gstack-tap-first-then-coexistence.md +0 -0
  304. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  305. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/heal-deleted-links-it-never-made.md +0 -0
  306. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  307. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/info-rejects-the-qualified-name-it-recommends.md +0 -0
  308. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
  309. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
  310. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/install-path-disambiguation.md +0 -0
  311. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
  312. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  313. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
  314. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  315. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
  316. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  317. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
  318. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/keyless-dense-tier-local-static-embeddings.md +0 -0
  319. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/keyless-semantic-search-for-everyone.md +0 -0
  320. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/langchain-in-the-wheel.md +0 -0
  321. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/langchain-integration-explainer-page.md +0 -0
  322. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/langchain-langgraph-langsmith-integration.md +0 -0
  323. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/langchain-retriever-metadata-and-k-floor.md +0 -0
  324. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  325. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/license-compliance-scanning.md +0 -0
  326. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  327. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/lighthouse-scored-a-page-nobody-is-served.md +0 -0
  328. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
  329. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  330. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  331. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
  332. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  333. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  334. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/long-hints-overflow-narrow-panes.md +0 -0
  335. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  336. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
  337. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
  338. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
  339. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  340. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  341. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
  342. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/marketing-crm-domain-had-no-category.md +0 -0
  343. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-already-covered-defeater.md +0 -0
  344. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-aware-skills.md +0 -0
  345. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
  346. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  347. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
  348. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  349. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-one-benefit-nameable-task.md +0 -0
  350. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  351. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
  352. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-search-cost-was-understated.md +0 -0
  353. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-search-hid-which-ranking-ran.md +0 -0
  354. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +0 -0
  355. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  356. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mcp-zero-setup-and-three-kinds.md +0 -0
  357. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  358. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
  359. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
  360. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  361. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
  362. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  363. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  364. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  365. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
  366. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
  367. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/near-duplicate-items-eat-the-result-slots.md +0 -0
  368. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
  369. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
  370. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  371. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
  372. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/one-dead-tap-broke-every-update.md +0 -0
  373. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  374. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/openssf-best-practices-badge.md +0 -0
  375. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/openssf-gold-ceiling.md +0 -0
  376. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/openssf-playbook.md +0 -0
  377. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/openssf-silver.md +0 -0
  378. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/osps-baseline-levels.md +0 -0
  379. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  380. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  381. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
  382. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/pathlib-exists-is-not-total.md +0 -0
  383. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/pep585-604-modernization-sweep.md +0 -0
  384. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  385. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
  386. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
  387. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  388. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  389. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/prerequisites-and-semantic-search-setup.md +0 -0
  390. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
  391. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
  392. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  393. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  394. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  395. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  396. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  397. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
  398. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
  399. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/published-shards-have-no-consumer.md +0 -0
  400. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
  401. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/python-floor-moves-to-312.md +0 -0
  402. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  403. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ragas-unpin-when-upstream-ships.md +0 -0
  404. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  405. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/readme-prune-and-search-guide.md +0 -0
  406. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  407. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  408. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
  409. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
  410. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/relicence-apache-2.md +0 -0
  411. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/reproducible-release-artifacts.md +0 -0
  412. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
  413. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/required-checks-config-drift.md +0 -0
  414. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/resolve-vendored-duplicate-copies.md +0 -0
  415. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  416. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  417. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
  418. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/roadmap-page-weight-grows-without-bound.md +0 -0
  419. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/roadmap-perf-budget-has-no-local-guard.md +0 -0
  420. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  421. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
  422. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  423. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/rules-install-but-cannot-be-governed.md +0 -0
  424. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  425. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  426. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  427. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
  428. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  429. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
  430. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  431. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
  432. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
  433. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/scripts-under-the-lint-gate.md +0 -0
  434. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/search-and-browse-visual-refresh.md +0 -0
  435. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/search-never-notices-a-new-tap.md +0 -0
  436. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  437. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  438. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  439. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  440. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
  441. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/self-update-claims-up-to-date-without-asking.md +0 -0
  442. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/serve-404-reflected-the-request.md +0 -0
  443. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/serve-is-a-searchable-catalogue.md +0 -0
  444. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
  445. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/shard-runs-reembed-everything-weekly.md +0 -0
  446. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/shards-pipeline-never-produced-a-shard.md +0 -0
  447. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/shareable-catalogue-bundle.md +0 -0
  448. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  449. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  450. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  451. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/smart-rerank-pays-per-novel-query.md +0 -0
  452. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  453. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  454. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  455. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
  456. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  457. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  458. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sweep-died-at-launch-not-at-a-page.md +0 -0
  459. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sync-could-not-repair-a-gutted-skill.md +0 -0
  460. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
  461. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
  462. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/sync-reported-success-for-a-link-it-refused.md +0 -0
  463. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  464. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/taps-check-out-freight-they-never-index.md +0 -0
  465. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/the-catalogue-advertised-repos-that-no-longer-exist.md +0 -0
  466. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/the-scale-corpus-refreshed-the-wrong-rows.md +0 -0
  467. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/the-shard-job-that-could-not-finish.md +0 -0
  468. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  469. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/tool-call-eval-tier.md +0 -0
  470. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/two-ci-controls-that-could-not-act.md +0 -0
  471. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/two-crashes-that-should-have-been-messages.md +0 -0
  472. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  473. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  474. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  475. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
  476. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  477. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/unwatched-crons-hid-a-real-fuzz-crash.md +0 -0
  478. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/update-advertises-a-flag-it-rejects.md +0 -0
  479. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  480. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/update-refreshed-rules-without-a-gate.md +0 -0
  481. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  482. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
  483. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/vex-openvex-feed.md +0 -0
  484. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  485. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  486. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  487. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
  488. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  489. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  490. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  491. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/workspace-scope-install.md +0 -0
  492. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/zip-strict-audit.md +0 -0
  493. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/zizmor-ignores-drift-and-make-lint-never-ran-it.md +0 -0
  494. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
  495. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/security-design.md +0 -0
  496. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/semantic-search.md +0 -0
  497. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/superpowers/specs/2026-08-16-catalogue-content-identity-design.md +0 -0
  498. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/verifying-releases.md +0 -0
  499. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/vex/meta.md +0 -0
  500. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/vex/openvex.json +0 -0
  501. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/vex/statements/gitleaks-secretscan-test-fixtures.md +0 -0
  502. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/vex/statements/quality-trust-fingerprint-not-sensitive.md +0 -0
  503. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/vex/statements/zizmor-adhoc-packages-lint-runners.md +0 -0
  504. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/docs/vex/statements/zizmor-dangerous-triggers-workflow-run.md +0 -0
  505. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/eslint.config.mjs +0 -0
  506. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/README.md +0 -0
  507. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/__init__.py +0 -0
  508. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/baseline.json +0 -0
  509. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/faithfulness.py +0 -0
  510. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/golden_set.json +0 -0
  511. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/make_corpus.py +0 -0
  512. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/make_golden.py +0 -0
  513. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/metrics.py +0 -0
  514. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/publish_golden_dataset.py +0 -0
  515. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/evals/run_evals.py +0 -0
  516. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/examples/README.md +0 -0
  517. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/examples/adapt-demo.sh +0 -0
  518. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/examples/boost-run-prototype.sh +0 -0
  519. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/index.html +0 -0
  520. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/noxfile.py +0 -0
  521. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/pyproject.toml +0 -0
  522. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/coverage-tools.in +0 -0
  523. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/coverage-tools.txt +0 -0
  524. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/lint-tools.in +0 -0
  525. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/lint-tools.txt +0 -0
  526. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/mutation-tools.in +0 -0
  527. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/mutation-tools.txt +0 -0
  528. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/platform-pins.lock +0 -0
  529. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/release-tools.in +0 -0
  530. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/release-tools.txt +0 -0
  531. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/test-tools.in +0 -0
  532. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/requirements/test-tools.txt +0 -0
  533. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/a11y_check.py +0 -0
  534. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/add_spdx_headers.py +0 -0
  535. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/bench_cli.sh +0 -0
  536. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/build_command_reference.py +0 -0
  537. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/build_demo_index.py +0 -0
  538. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/build_registries.py +0 -0
  539. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/build_roadmap.py +0 -0
  540. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/build_scale_corpus.py +0 -0
  541. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/build_vex.py +0 -0
  542. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/check_anchors.py +0 -0
  543. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/check_branch_current.py +0 -0
  544. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/check_dco.py +0 -0
  545. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/check_licenses.py +0 -0
  546. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/check_reproducible.py +0 -0
  547. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/check_required_checks.py +0 -0
  548. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/ensure_eval_corpus.sh +0 -0
  549. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/eval_corpus.py +0 -0
  550. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/eval_explain.py +0 -0
  551. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/eval_gate.py +0 -0
  552. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/eval_recommend.py +0 -0
  553. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/eval_retrieval.py +0 -0
  554. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/eval_stats_summary.py +0 -0
  555. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/import_budget.py +0 -0
  556. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/lock_toolchain.py +0 -0
  557. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/measure_registry.py +0 -0
  558. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/mutation_gate.py +0 -0
  559. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/mutation_shards.py +0 -0
  560. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/mutation_weights.json +0 -0
  561. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/normalize_sdist.py +0 -0
  562. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/page_budget.py +0 -0
  563. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/perf_gate.py +0 -0
  564. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/post_deploy_smoke.py +0 -0
  565. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/publish_eval_json.py +0 -0
  566. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/publish_shards.py +0 -0
  567. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/release_guard.py +0 -0
  568. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/release_preflight.py +0 -0
  569. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/serve_docs.py +0 -0
  570. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/scripts/shard_plan.py +0 -0
  571. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/setup.cfg +0 -0
  572. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/sonar-project.properties +0 -0
  573. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/style/README.md +0 -0
  574. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/style/boost.css +0 -0
  575. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/style/boost.js +0 -0
  576. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/style/demo.html +0 -0
  577. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/adapt.feature +0 -0
  578. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/browse.feature +0 -0
  579. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/count.feature +0 -0
  580. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/discover.feature +0 -0
  581. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/environment.py +0 -0
  582. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/explain.feature +0 -0
  583. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/index.feature +0 -0
  584. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/install.feature +0 -0
  585. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/list.feature +0 -0
  586. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/mcp.feature +0 -0
  587. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/search.feature +0 -0
  588. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/steps/cli_steps.py +0 -0
  589. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/steps/discovery_steps.py +0 -0
  590. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/steps/mcp_steps.py +0 -0
  591. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/bdd/features/steps/quality_steps.py +0 -0
  592. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/conftest.py +0 -0
  593. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/baseline.json +0 -0
  594. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/explain.jsonl +0 -0
  595. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/golden-natural.jsonl +0 -0
  596. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/golden.jsonl +0 -0
  597. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/recommend.jsonl +0 -0
  598. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/taps-scale.txt +0 -0
  599. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/eval/taps.txt +0 -0
  600. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_bmad_all_hosts.py +0 -0
  601. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_capabilities_policy.py +0 -0
  602. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_adapt.py +0 -0
  603. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_bmad.py +0 -0
  604. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_catalog.py +0 -0
  605. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_chat.py +0 -0
  606. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_discovery.py +0 -0
  607. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_hooks.py +0 -0
  608. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_hooks_gemini.py +0 -0
  609. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_intelligence.py +0 -0
  610. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_pane_width.py +0 -0
  611. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_pkg.py +0 -0
  612. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_tap_pins.py +0 -0
  613. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_taps.py +0 -0
  614. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_cli_team.py +0 -0
  615. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_everyday_loop.py +0 -0
  616. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_integrity_enforce.py +0 -0
  617. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_kind_conformance.py +0 -0
  618. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_property_parsers.py +0 -0
  619. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_run.py +0 -0
  620. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_tap_signing.py +0 -0
  621. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/functional/test_workspace_scope.py +0 -0
  622. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/README.md +0 -0
  623. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
  624. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
  625. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
  626. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
  627. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
  628. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
  629. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
  630. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
  631. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
  632. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
  633. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
  634. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
  635. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
  636. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/02-https.txt +0 -0
  637. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
  638. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
  639. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
  640. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/06-space.txt +0 -0
  641. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
  642. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
  643. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/09-nul.txt +0 -0
  644. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/10-name-too-long.txt +0 -0
  645. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/corpus/registry/11-long-owner-repo.txt +0 -0
  646. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/fuzz_frontmatter.py +0 -0
  647. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/fuzz/fuzz_registry.py +0 -0
  648. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/langchain/conftest.py +0 -0
  649. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/langchain/test_graph.py +0 -0
  650. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/langchain/test_loader.py +0 -0
  651. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/langchain/test_retriever.py +0 -0
  652. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/make_fixture.py +0 -0
  653. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/perf/test_benchmarks.py +0 -0
  654. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/smoke.sh +0 -0
  655. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_a11y_check.py +0 -0
  656. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_action_pin_lockstep.py +0 -0
  657. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_adapters.py +0 -0
  658. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_adapters_multi.py +0 -0
  659. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_adapters_runner.py +0 -0
  660. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_agents.py +0 -0
  661. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_ai.py +0 -0
  662. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_aihost.py +0 -0
  663. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_bmad_core.py +0 -0
  664. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_boost_first_offer.py +0 -0
  665. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_bootstrap.py +0 -0
  666. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_branch_current.py +0 -0
  667. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_browse.py +0 -0
  668. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_builtin.py +0 -0
  669. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_capabilities.py +0 -0
  670. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_catalog.py +0 -0
  671. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_catalogbundle.py +0 -0
  672. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_chat.py +0 -0
  673. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_check_anchors.py +0 -0
  674. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_check_dco.py +0 -0
  675. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_check_licenses.py +0 -0
  676. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_check_reproducible.py +0 -0
  677. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_claude_settings.py +0 -0
  678. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_clean_internal_cache.py +0 -0
  679. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_cliparse.py +0 -0
  680. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_codeql_analysis_key.py +0 -0
  681. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_command_reference_fresh.py +0 -0
  682. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_community_health_files.py +0 -0
  683. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_compact.py +0 -0
  684. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_complete.py +0 -0
  685. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_complete_rc_block.py +0 -0
  686. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_config.py +0 -0
  687. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_content_dedupe.py +0 -0
  688. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_content_identity.py +0 -0
  689. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_crash_redaction.py +0 -0
  690. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dedup_trust.py +0 -0
  691. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_demo_index.py +0 -0
  692. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense.py +0 -0
  693. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_embed_dedupe.py +0 -0
  694. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_fix_hint.py +0 -0
  695. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_progress.py +0 -0
  696. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_quantized.py +0 -0
  697. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_ready_order.py +0 -0
  698. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_shard_real_schema.py +0 -0
  699. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_status.py +0 -0
  700. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dense_status_cheap.py +0 -0
  701. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_dependabot_config.py +0 -0
  702. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_docs_pages_linked.py +0 -0
  703. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_docsite_chrome.py +0 -0
  704. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_ed25519.py +0 -0
  705. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_embed.py +0 -0
  706. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_embed_local.py +0 -0
  707. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_embed_truncated_response.py +0 -0
  708. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_entry_key.py +0 -0
  709. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_errors_and_cli_table.py +0 -0
  710. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_baseline.py +0 -0
  711. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_corpus.py +0 -0
  712. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_faithfulness.py +0 -0
  713. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_gate.py +0 -0
  714. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_grading.py +0 -0
  715. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_metrics.py +0 -0
  716. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_eval_stats_summary.py +0 -0
  717. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_failure_alerting_covers_unattended.py +0 -0
  718. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_faithfulness.py +0 -0
  719. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_frontmatter.py +0 -0
  720. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_fuzz_targets.py +0 -0
  721. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_gemini_agent_sanitize.py +0 -0
  722. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_gitleaks_config.py +0 -0
  723. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_gitutil.py +0 -0
  724. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_gitutil_lfs.py +0 -0
  725. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_gitutil_sparse.py +0 -0
  726. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_hook_settings_hosts.py +0 -0
  727. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_hookhost.py +0 -0
  728. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_imperative.py +0 -0
  729. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_import_budget.py +0 -0
  730. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_injectscan.py +0 -0
  731. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_install_permission_error.py +0 -0
  732. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_installscan.py +0 -0
  733. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_integrity.py +0 -0
  734. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_journal.py +0 -0
  735. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_langchain_packaging.py +0 -0
  736. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_link_ownership.py +0 -0
  737. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_localembed.py +0 -0
  738. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_localembed_e2e.py +0 -0
  739. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_lockfile.py +0 -0
  740. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_logs.py +0 -0
  741. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_marketing_counts.py +0 -0
  742. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mcp_install_scan.py +0 -0
  743. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mcpdecl.py +0 -0
  744. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mcphost.py +0 -0
  745. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_measure_registry.py +0 -0
  746. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_minisign.py +0 -0
  747. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mutation_hardening.py +0 -0
  748. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mutation_shards.py +0 -0
  749. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mutation_subfile_shards.py +0 -0
  750. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_mutmut_source_paths.py +0 -0
  751. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_nethttp.py +0 -0
  752. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_normalize_sdist.py +0 -0
  753. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_output.py +0 -0
  754. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_page_budget.py +0 -0
  755. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_paths.py +0 -0
  756. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_perf_gate.py +0 -0
  757. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_pkg_confusions.py +0 -0
  758. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_pkg_injection.py +0 -0
  759. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_pkg_secrets.py +0 -0
  760. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_platform_pins.py +0 -0
  761. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_policy.py +0 -0
  762. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_post_deploy_smoke.py +0 -0
  763. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_project_mcp_sidecar.py +0 -0
  764. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_projectlock.py +0 -0
  765. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_provenance.py +0 -0
  766. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_publish_golden_dataset.py +0 -0
  767. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_rag.py +0 -0
  768. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_rag_fastpath.py +0 -0
  769. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_rag_fusion.py +0 -0
  770. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_registries_fresh.py +0 -0
  771. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_registry.py +0 -0
  772. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_registry_categories.py +0 -0
  773. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_registry_control_chars.py +0 -0
  774. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_registry_parallel.py +0 -0
  775. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_release_guard.py +0 -0
  776. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_release_preflight.py +0 -0
  777. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_required_checks.py +0 -0
  778. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_rerank_cache.py +0 -0
  779. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_resolve.py +0 -0
  780. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_roadmap_fresh.py +0 -0
  781. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_rules.py +0 -0
  782. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_scale_corpus.py +0 -0
  783. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_scopes.py +0 -0
  784. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_secretscan.py +0 -0
  785. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_selfupdate.py +0 -0
  786. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_serve.py +0 -0
  787. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_serve_docs.py +0 -0
  788. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_shard_plan.py +0 -0
  789. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_shards.py +0 -0
  790. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_shards_incremental.py +0 -0
  791. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_shards_matrix.py +0 -0
  792. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_smoke_covers_every_command.py +0 -0
  793. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_spdx_headers.py +0 -0
  794. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_spin.py +0 -0
  795. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_stackprobe.py +0 -0
  796. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_staleness.py +0 -0
  797. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_store.py +0 -0
  798. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_store_materialize.py +0 -0
  799. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_sync_blocked_links.py +0 -0
  800. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_sync_repairs_gutted_skill.py +0 -0
  801. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_tap_pins.py +0 -0
  802. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_token_parity.py +0 -0
  803. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_toolchain_lock.py +0 -0
  804. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_trustaudit.py +0 -0
  805. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_typosquat.py +0 -0
  806. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_updatediff.py +0 -0
  807. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_util.py +0 -0
  808. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_version.py +0 -0
  809. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_version_tags.py +0 -0
  810. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_vex.py +0 -0
  811. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_visual_harness_flags.py +0 -0
  812. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_workflow_concurrency.py +0 -0
  813. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_workflow_concurrency_groups.py +0 -0
  814. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_workflow_push_has_credentials.py +0 -0
  815. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_workflow_timeouts.py +0 -0
  816. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_workflows.py +0 -0
  817. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/unit/test_zizmor_ignores_still_anchor.py +0 -0
  818. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/visual/a11y_check.mjs +0 -0
  819. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/visual/console_check.mjs +0 -0
  820. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/visual/package-lock.json +0 -0
  821. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/visual/package.json +0 -0
  822. {boost_skill_cli-1.2.54 → boost_skill_cli-1.2.56}/tests/visual/visual_check.mjs +0 -0
@@ -584,6 +584,26 @@ Consequences for code you write here:
584
584
  real install are repeats and are embedded once — so a progress total taken
585
585
  from row count would over-report the work.
586
586
 
587
+ - **Dense reuse is decided at TWO levels, and the second one is why `chunks`
588
+ carries a `digest`.** A tap whose git commit is unchanged is skipped whole.
589
+ A tap whose commit *moved* is not therefore changed: `_split_by_digest`
590
+ compares each entry's `content` digest against the one stored beside its
591
+ chunks, and only the entries that really differ are deleted and re-embedded.
592
+ Measured on a real 464-tap install: 19 taps drifted in 6.85 h and re-embedded
593
+ 112,081 chunks for 659 chunks of actual change (**170x**), and **10 of the
594
+ 19 changed nothing boost indexes at all** — badge `.json`, star-history
595
+ `.svg`, CI `.yml` — for 40.0% of the bill. Three rules make it safe, and
596
+ each was a real bug waiting: an entry is reused only when **every** stored
597
+ chunk carries the current digest, because a half-written entry must not be
598
+ served as a mixture of two versions' vectors; `_prune_stale_entries` drops
599
+ rows for entries the catalog dropped, which whole-tap deletion used to sweep
600
+ for free; and a **missing digest is never a match**, because two absences
601
+ are two unknowns. The digest travels in a shard too — without it an imported
602
+ shard re-embeds on the next build, spending the CPU the download existed to
603
+ save. The lookup is scoped by tap through the `chunks_tap` index: reading
604
+ the whole table instead measured 3.75 s cold on a 657,587-chunk store, and
605
+ ran even on the build where nothing had changed.
606
+
587
607
  - **Nothing on the search path may count `chunks`.** `SELECT COUNT(*)` scans the
588
608
  `chunks_tap` covering index — 8,419 pages / 34.5 MB, measured 1.94 s — and
589
609
  both `ready()` and `status()` did it on every search, the latter only to word
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.2.54
3
+ Version: 1.2.56
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License-Expression: Apache-2.0
@@ -448,8 +448,10 @@ purely local operation, for CI images and air-gapped machines.
448
448
  | Claude Code | `claude` | `claude mcp add` → its user-scope MCP config |
449
449
  | Gemini CLI | `gemini` | `gemini mcp add -s user` → `~/.gemini/settings.json` |
450
450
 
451
- Six tools are exposed: `boost_search`, `boost_list`, `boost_info`,
452
- `boost_install`, `boost_doctor` and `boost_discover_github`.
451
+ Seven tools are exposed: `boost_search`, `boost_list`, `boost_info`,
452
+ `boost_read`, `boost_install`, `boost_doctor` and
453
+ `boost_discover_github`. `boost_read` is the one that returns an item's
454
+ actual text — without it, installing was the only way to read a skill.
453
455
 
454
456
  The server also returns MCP `instructions`, telling the agent when boost is
455
457
  relevant. The two hosts place those differently, and it matters. Claude Code
@@ -406,8 +406,10 @@ purely local operation, for CI images and air-gapped machines.
406
406
  | Claude Code | `claude` | `claude mcp add` → its user-scope MCP config |
407
407
  | Gemini CLI | `gemini` | `gemini mcp add -s user` → `~/.gemini/settings.json` |
408
408
 
409
- Six tools are exposed: `boost_search`, `boost_list`, `boost_info`,
410
- `boost_install`, `boost_doctor` and `boost_discover_github`.
409
+ Seven tools are exposed: `boost_search`, `boost_list`, `boost_info`,
410
+ `boost_read`, `boost_install`, `boost_doctor` and
411
+ `boost_discover_github`. `boost_read` is the one that returns an item's
412
+ actual text — without it, installing was the only way to read a skill.
411
413
 
412
414
  The server also returns MCP `instructions`, telling the agent when boost is
413
415
  relevant. The two hosts place those differently, and it matters. Claude Code
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.2.54'
22
- __version_tuple__ = version_tuple = (1, 2, 54)
21
+ __version__ = version = '1.2.56'
22
+ __version_tuple__ = version_tuple = (1, 2, 56)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -1169,6 +1169,47 @@ def _tool_info(args: dict):
1169
1169
  return "\n".join(lines), False
1170
1170
 
1171
1171
 
1172
+ def _tool_read(args: dict):
1173
+ """`boost_read` — the item's own text, so an agent can look before it acts.
1174
+
1175
+ The gap this closes: ``boost_info`` returns the same one-line description
1176
+ ``boost_search`` already returned, so an agent deciding whether a procedure
1177
+ is worth adopting had one sentence written by whoever published it, and its
1178
+ only route to the actual steps was to install into the user's real
1179
+ ``~/.agents/skills`` and read it off disk. That inverts the surface's own
1180
+ pitch — ``boost_search`` spends 10-15 s of rerank so the top result is worth
1181
+ acting on, and then nothing let the agent look at it.
1182
+
1183
+ The body is also the only thing separating a written skill from a generated
1184
+ stub, and the catalogue holds both: two ranked hits share the description
1185
+ "To optimize **Skill**, we enforce the following foundational rules:" — an
1186
+ unfilled template — and ``superpowers-lab`` is an 868-byte SKILL.md whose
1187
+ Instructions section is its own name echoed back. Both index, rank and
1188
+ render exactly like real results. The eval gate cannot catch it either:
1189
+ ``golden.jsonl`` grades by *name*, and a stub matches its own name
1190
+ perfectly.
1191
+
1192
+ Read-only, and that is the whole point rather than a side note — this is
1193
+ the tool that exists so an agent does *not* have to install to look, so it
1194
+ must never become a second install path. It reuses ``boost cat``'s
1195
+ resolution (``info._resolve_text``): the installed copy when there is one,
1196
+ the tap source otherwise, with the same integrity and quarantine rules. A
1197
+ second resolver would be a second opinion about what "this item" means,
1198
+ disagreeing with the tool it is advising about.
1199
+
1200
+ ``cat`` rather than ``explain``: cat is offline, deterministic and free,
1201
+ while ``explain`` goes through ``core/ai.py`` and costs seconds plus a key.
1202
+ The cheap answer must not sit behind the expensive one's latency — the same
1203
+ reason ``boost_list`` never reads the catalog.
1204
+ """
1205
+ from . import info
1206
+ name = str(args.get("name", ""))
1207
+ if not name.strip():
1208
+ return "boost_read needs a name — pass one as boost_search returned it", True
1209
+ text, kind, lock, _cat = info._resolve_text(name)
1210
+ return mcp.read_reply(name, text, kind=kind, installed=lock is not None), False
1211
+
1212
+
1172
1213
  def _tool_install(args: dict):
1173
1214
  entry = catalog.resolve_one(str(args.get("name", "")))
1174
1215
  res = store.install(entry)
@@ -1369,19 +1410,54 @@ REGISTRY.register(
1369
1410
  _tool_list)
1370
1411
  REGISTRY.register(
1371
1412
  "boost_info",
1372
- "The whole picture of one skill, rule or workflow by name — what it does, "
1373
- "its kind, the tap it came "
1374
- "from, its version, and whether it is already installed — so you can "
1375
- "commit or move on without guessing. Reach for it when a name arrives from "
1376
- "somewhere else: a teammate, a README, a repo you are reading. You do not "
1377
- "need this between a search and an install — boost_search already returns "
1378
- "each match's kind and description.",
1413
+ # This used to promise "the whole picture" and return five fields, one of
1414
+ # which — description — is byte-identical to the one-liner boost_search
1415
+ # already returned. So the tool added `installed: no`, which the search
1416
+ # reply already marks, to an agent that had been told to expect what the
1417
+ # item does. An overstated description costs a wasted call and teaches an
1418
+ # agent to discount the rest of the surface, which is the expensive half.
1419
+ # It now says what it returns (status and provenance) and names the tool
1420
+ # that returns the body.
1421
+ "Where one skill, rule or workflow came from, by name, and whether it is "
1422
+ "already here — its kind, tap, version, install state, and which agents "
1423
+ "it reached. It is the STATUS of an item, not its contents: the description "
1424
+ "it echoes is the same one-liner boost_search returned, so to read what "
1425
+ "the item actually says, call boost_read. Reach for boost_info when a "
1426
+ "name arrives from somewhere else — a teammate, a README, a repo you are "
1427
+ "reading — and you need to know whether this machine already has it. You "
1428
+ "do not need this between a search and an install: boost_search already "
1429
+ "returns each match's kind, description and installed marker.",
1379
1430
  {"type": "object",
1380
1431
  "properties": {"name": {"type": "string",
1381
1432
  "description": "the item's name, as boost_search "
1382
1433
  "or boost_list returned it"}},
1383
1434
  "required": ["name"]},
1384
1435
  _tool_info)
1436
+ REGISTRY.register(
1437
+ "boost_read",
1438
+ "Read the actual procedure before you commit to it — the item's own text, "
1439
+ "not its one-line description. This is the tool that makes looking cheaper "
1440
+ "than installing: without it the only way to see what a skill actually "
1441
+ "says is to install it into the user's machine and read it off disk, which "
1442
+ "is a change to their setup made in order to answer a question. Reach for "
1443
+ "it on the top hit from boost_search before boost_install, and whenever a "
1444
+ "one-liner is doing more selling than describing. What you are checking "
1445
+ "for is specific: the catalogue is indexed rather than reviewed, so it "
1446
+ "holds unfilled templates and stubs that echo their own name back, and "
1447
+ "those rank and render exactly like a procedure someone debugged. The body "
1448
+ "is the only thing that tells them apart. Read-only and offline — it "
1449
+ "installs nothing, changes nothing, and unlike boost_search costs no "
1450
+ "rerank, so it is fast. Long items are truncated at a stated character "
1451
+ "count and the reply says so and names the command that returns the rest; "
1452
+ "a body that arrives whole is whole.",
1453
+ {"type": "object",
1454
+ "properties": {"name": {"type": "string",
1455
+ "description": "the item's name, as boost_search "
1456
+ "or boost_list returned it; qualify with the tap "
1457
+ "(\"owner/repo:name\") when the same name exists "
1458
+ "in more than one"}},
1459
+ "required": ["name"]},
1460
+ _tool_read)
1385
1461
  REGISTRY.register(
1386
1462
  "boost_install",
1387
1463
  "Turn a skill you found with boost_search into permanent capability: copied "
@@ -423,8 +423,29 @@ def cmd_reindex(argv):
423
423
  "`boost reindex --dense --force`."
424
424
  % len(dense_stats["reused"]))
425
425
  else:
426
- out.ok("embedded %d passages (%s) into the dense vector store"
427
- % (dense_stats["chunks"], dense_stats["provider"]))
426
+ # `chunks` is the store TOTAL, not this run's work, so on an
427
+ # incremental run "embedded 657,587 passages" described an
428
+ # afternoon of CPU that did not happen. `added` is what this
429
+ # run actually paid for.
430
+ added = dense_stats.get("added", dense_stats["chunks"])
431
+ out.ok("embedded %d passage%s (%s) — the dense store holds %d"
432
+ % (added, "" if added == 1 else "s",
433
+ dense_stats["provider"], dense_stats["chunks"]))
434
+ # The saving the tap-level line cannot show: a tap appears in
435
+ # `reindexed` the moment its commit moves, so a run that reused
436
+ # every entry inside three moved taps otherwise reads as three
437
+ # taps fully re-embedded.
438
+ kept = dense_stats.get("reused_entries") or 0
439
+ if kept:
440
+ out.info(out.role(
441
+ "reused %d unchanged item%s inside %d moved tap%s — "
442
+ "only %d item%s changed"
443
+ % (kept, "" if kept == 1 else "s",
444
+ len(dense_stats["reindexed"]),
445
+ "" if len(dense_stats["reindexed"]) == 1 else "s",
446
+ dense_stats.get("embedded_entries") or 0,
447
+ "" if dense_stats.get("embedded_entries") == 1
448
+ else "s"), "muted"))
428
449
  if dense_stats.get("quantized"):
429
450
  out.ok("quantized %d existing vectors — dense search no longer "
430
451
  "scans the whole store on every query"
@@ -149,7 +149,21 @@ def _resolve_text(name: str):
149
149
  found = lockfile.find_any(bare)
150
150
  if found is None or found[0] == "skill":
151
151
  path, lock, cat = _resolve_skill_md(name)
152
- return _read(path), "skill", lock, cat
152
+ # The lock file is the authority for an INSTALLED item, and for one
153
+ # that is not installed it has no opinion at all — so a rule or
154
+ # workflow that is only in a tap arrived here and was reported as a
155
+ # skill, contradicting this function's own "any kind" contract. The
156
+ # catalog entry knows, and `_resolve_skill_md` has already resolved it:
157
+ # it returns a catalog entry on exactly the branch where `lock` is
158
+ # None, so no second lookup is needed (and a fallback for `cat is None`
159
+ # here would guard a state that function cannot produce).
160
+ #
161
+ # Every caller before `boost_read` discarded this value (`_kind`), so
162
+ # the wrong answer was invisible: the resolution and the text were
163
+ # always right, only the label was not.
164
+ kind = ((cat.get("kind") or "skill")
165
+ if lock is None and cat else "skill")
166
+ return _read(path), kind, lock, cat
153
167
  kind, entry = found
154
168
  lock = _for_tap(entry, qualifier)
155
169
  if lock is not None:
@@ -395,7 +395,14 @@ def cmd_doctor(argv):
395
395
  if taps and tap_ok == len(taps):
396
396
  out.ok("%d tap%s cloned & cached" % (len(taps), _s(len(taps))))
397
397
  elif not taps:
398
- out.info("no taps configured — add one with `boost tap owner/repo`")
398
+ # `boost tap --defaults` leads, and it is the same command in the same
399
+ # order that `boost search`'s error, `mcp.no_results` and the MCP
400
+ # `boost_doctor` tool all name. A user who hits two of these surfaces
401
+ # in one session must not see the recommendation flip and read it as
402
+ # two different fixes — which is exactly what happened here: search
403
+ # said `--defaults`, doctor said `owner/repo`.
404
+ out.info("no registries tapped — nothing is searchable yet; add the "
405
+ "recommended ones with `boost tap --defaults`", wrap=True)
399
406
 
400
407
  lock_ok = True
401
408
  lp = paths.lockfile_path()
@@ -598,10 +605,22 @@ def cmd_doctor(argv):
598
605
  else:
599
606
  out.warn("lock file integrity or log rotation needs attention")
600
607
 
601
- out.verdict(issues == 0,
602
- "healthy" if not issues else
603
- "%d issue%s need attention — see the suggestions above"
604
- % (issues, _s(issues)))
608
+ # A machine with no taps has nothing to disagree about, so every check
609
+ # above passes and the verdict read "healthy" — directly under the line
610
+ # saying no registries are tapped. That is the one state where a clean bill
611
+ # of health actively misleads: boost cannot answer anything yet, which is a
612
+ # setup step rather than a fault. Reported, never fatal — the exit code
613
+ # still turns only on real issues, so scripts and CI are unaffected. The
614
+ # MCP `boost_doctor` tool already refused to say "healthy" here; this is
615
+ # the CLI half of the same rule.
616
+ if issues == 0 and not taps:
617
+ out.verdict(True, "ready to set up — tap a registry to make boost "
618
+ "searchable")
619
+ else:
620
+ out.verdict(issues == 0,
621
+ "healthy" if not issues else
622
+ "%d issue%s need attention — see the suggestions above"
623
+ % (issues, _s(issues)))
605
624
  return 1 if issues else 0
606
625
 
607
626
 
@@ -162,6 +162,26 @@ def cmd_quickstart(argv) -> int:
162
162
  planned = [n for n in names if n in pins] if manifest else []
163
163
  out.info("would build the keyword index, then import %d shard(s)"
164
164
  % len(planned))
165
+ # "0 shard(s)" reads as "none are published" when the real cause is
166
+ # local, and --dry-run is exactly what a cautious new user runs first.
167
+ # The live path already explains both cases; without this the preview
168
+ # is the one surface that reports the symptom and withholds the reason.
169
+ if not planned:
170
+ if args.no_vectors:
171
+ out.info(out.role("(0 because --no-vectors was asked for)",
172
+ "muted"))
173
+ elif not dense.have_backend():
174
+ out.info("0 because semantic search needs the extra: "
175
+ "`pipx inject boost-skill-cli "
176
+ "\"boost-skill-cli[rag]\"` — keyword search works "
177
+ "without it", wrap=True)
178
+ elif manifest is None:
179
+ out.info(out.role("(0 because the shard manifest could not be "
180
+ "read — keyword search is unaffected)",
181
+ "muted"), wrap=True)
182
+ else:
183
+ out.info(out.role("(0 because none of these registries have a "
184
+ "published shard yet)", "muted"), wrap=True)
165
185
  return 0
166
186
 
167
187
  with spin.Spinner("building the keyword index"):
@@ -23,7 +23,13 @@ from ..errors import BoostError
23
23
  from . import catalog, embed, paths
24
24
  from .rag import Hit, chunk, entry_key, read_body
25
25
 
26
- INDEX_VERSION = 2
26
+ # 3 -- `chunks.digest` carries each row's entry content digest, which is what
27
+ # lets reuse be decided per ENTRY rather than per tap. Bumping this is the
28
+ # migration: a v2 store has no such column, `_ensure_schema` cannot add one
29
+ # to an existing table (CREATE TABLE IF NOT EXISTS), and `build` already
30
+ # wipes on a version change. That costs one full re-embed, once — the same
31
+ # price v2 charged when it landed, and the last one this mechanism needs.
32
+ INDEX_VERSION = 3
27
33
  _BATCH = 128 # texts per embedding request
28
34
 
29
35
  #: Rows between commits while storing vectors. Small enough that an interrupted
@@ -112,8 +118,14 @@ def quantized(con: sqlite3.Connection) -> bool:
112
118
  def _ensure_schema(con: sqlite3.Connection, dim: int) -> None:
113
119
  con.execute(
114
120
  "CREATE TABLE IF NOT EXISTS chunks (id INTEGER PRIMARY KEY AUTOINCREMENT,"
115
- " name TEXT, tap TEXT, path TEXT, kind TEXT, cix INTEGER, snip TEXT)")
121
+ " name TEXT, tap TEXT, path TEXT, kind TEXT, cix INTEGER, snip TEXT,"
122
+ " digest TEXT)")
116
123
  con.execute("CREATE INDEX IF NOT EXISTS chunks_tap ON chunks(tap)")
124
+ # Keyed by (tap, path) because that is `rag.entry_key` — row identity, the
125
+ # thing an entry's chunks belong to. Keying it on `digest` alone would be
126
+ # the content question, which is a different one: two taps shipping the
127
+ # same file share a digest and must still be deleted independently.
128
+ con.execute("CREATE INDEX IF NOT EXISTS chunks_entry ON chunks(tap, path)")
117
129
  con.execute("CREATE TABLE IF NOT EXISTS meta (k TEXT PRIMARY KEY, v TEXT)")
118
130
  if _quantizable(dim):
119
131
  # Two relations, because one cannot do both jobs. `vec0` is the only
@@ -518,17 +530,38 @@ def build(entries: list[dict] | None = None, force: bool = False,
518
530
  if commit and old_commits.get(safe) == commit:
519
531
  reused.add(safe)
520
532
 
521
- fresh = [e for e in entries
522
- if e["tap"].replace("/", "__") not in reused]
523
- changed_taps = sorted({e["tap"] for e in fresh})
533
+ candidates = [e for e in entries
534
+ if e["tap"].replace("/", "__") not in reused]
535
+ changed_taps = sorted({e["tap"] for e in candidates})
524
536
  # Prune taps that are gone entirely, not only the ones that changed.
525
537
  # `boost untap` removes a tap's entries, so it can never appear in
526
- # `fresh` and its vectors survived every later incremental build —
538
+ # `candidates` and its vectors survived every later incremental build —
527
539
  # crowding the KNN pool on every query with rows `retrieve` then
528
540
  # discards for not being live, which is how a dense search quietly
529
541
  # returns fewer hits the longer an index has been in use.
530
542
  removed_taps = sorted(_indexed_taps(con) - {e["tap"] for e in entries})
531
- _delete_taps(con, changed_taps + removed_taps)
543
+ _delete_taps(con, removed_taps)
544
+
545
+ # Second-level reuse, and the reason it is worth the column. A tap's
546
+ # commit moving says *something* in that clone changed — not that
547
+ # anything boost indexes did. Measured on a real 464-tap install: 19
548
+ # taps drifted in 6.85 h, and 10 of them changed nothing indexed at all
549
+ # (badge JSON, star-history SVGs, CI YAML, e2e TypeScript), yet cost
550
+ # 44,866 chunks — 40.0% of the incremental bill. Across all 19, 967
551
+ # changed files mapped to 39 indexed entries owning 659 chunks, against
552
+ # 112,081 re-embedded: 170x the actual change.
553
+ #
554
+ # The digest is not new identity machinery. `catalog._content_digest`
555
+ # already stamps every entry with a hash of exactly what `read_body`
556
+ # assembles, and `tests/unit/test_content_identity.py` pins that parity
557
+ # — so an entry whose digest matches the one stored beside its chunks
558
+ # is one whose embedded text is byte-identical.
559
+ fresh, kept = _split_by_digest(con, candidates)
560
+ _delete_entries(con, [entry_key(e) for e in fresh])
561
+ # An entry deleted upstream keeps answering queries otherwise: whole-tap
562
+ # deletion used to sweep it for free, and reuse is exactly what stops
563
+ # that happening.
564
+ _prune_stale_entries(con, changed_taps, {entry_key(e) for e in entries})
532
565
 
533
566
  added, failed_taps = _embed_and_store(con, fresh, tap_paths,
534
567
  on_progress=on_progress)
@@ -555,6 +588,12 @@ def build(entries: list[dict] | None = None, force: bool = False,
555
588
  "reindexed": changed_taps,
556
589
  "pruned": removed_taps,
557
590
  "reused": sorted(reused),
591
+ # Entries inside a moved tap whose content had not changed. This is
592
+ # the number the tap-level `reused` cannot show — a tap appears in
593
+ # `reindexed` the moment its commit moves, and on real data most of
594
+ # its entries are still untouched.
595
+ "reused_entries": len(kept),
596
+ "embedded_entries": len(fresh),
558
597
  "failed": sorted(failed_taps),
559
598
  "provider": prov,
560
599
  "model": mdl,
@@ -614,7 +653,8 @@ def export_shard(tap: str) -> dict:
614
653
  vt = "vec_raw v ON v.id = c.id" if quantized(con) \
615
654
  else "vec_chunks v ON v.rowid = c.id"
616
655
  rows = con.execute(
617
- "SELECT c.name, c.tap, c.path, c.kind, c.cix, c.snip, v.embedding " # noqa: S608 relation name from a literal pair
656
+ "SELECT c.name, c.tap, c.path, c.kind, c.cix, c.snip, " # noqa: S608 relation name from a literal pair
657
+ "c.digest, v.embedding "
618
658
  "FROM chunks c JOIN %s WHERE c.tap = ? ORDER BY c.id" % vt,
619
659
  (tap,)).fetchall()
620
660
  except sqlite3.Error as exc:
@@ -630,10 +670,16 @@ def export_shard(tap: str) -> dict:
630
670
  # the vector rows are gone or unlinked. Still not "never built".
631
671
  raise _unreadable_vectors(tap, expected, None)
632
672
  for row in rows:
633
- name, ctap, path, kind, cix, snip, emb = row
673
+ name, ctap, path, kind, cix, snip, digest, emb = row
634
674
  chunks.append({
635
675
  "name": name, "tap": ctap, "path": path, "kind": kind,
636
676
  "cix": cix, "snip": snip,
677
+ # The digest travels with the vector or the shard defeats its
678
+ # own purpose: `_split_by_digest` reuses an entry only when the
679
+ # stored digest matches the catalog's, so an imported chunk
680
+ # without one is re-embedded on the very next build — paying
681
+ # in CPU exactly what downloading the shard was meant to save.
682
+ "digest": digest,
637
683
  # base64 so the shard is plain JSON and can be published as a
638
684
  # release artifact without a binary format of its own.
639
685
  "embedding": base64.b64encode(bytes(emb)).decode("ascii"),
@@ -714,10 +760,15 @@ def import_shard(shard: dict, commit: str) -> tuple[bool, str]:
714
760
  mod = _load()
715
761
  for c in shard.get("chunks") or []:
716
762
  cur = con.execute(
717
- "INSERT INTO chunks (name, tap, path, kind, cix, snip) "
718
- "VALUES (?, ?, ?, ?, ?, ?)",
763
+ "INSERT INTO chunks (name, tap, path, kind, cix, snip, digest) "
764
+ "VALUES (?, ?, ?, ?, ?, ?, ?)",
719
765
  (c.get("name"), c.get("tap"), c.get("path"), c.get("kind"),
720
- c.get("cix"), c.get("snip")))
766
+ c.get("cix"), c.get("snip"),
767
+ # A shard published before the digest travelled has none, and
768
+ # None is the honest value: that tap re-embeds once, which is
769
+ # what it did before this existed. Never a placeholder — a
770
+ # wrong digest would suppress a real re-embed forever.
771
+ c.get("digest")))
721
772
  blob = base64.b64decode(c["embedding"])
722
773
  _store_vector(con, cur.lastrowid, blob)
723
774
  commits = meta.get("commits")
@@ -748,12 +799,109 @@ def _indexed_taps(con: sqlite3.Connection) -> set:
748
799
  return set() # no chunks table yet — nothing indexed, nothing stale
749
800
 
750
801
 
802
+ def _delete_matching(con: sqlite3.Connection, where: str,
803
+ params: tuple) -> int:
804
+ """Drop the chunk rows matching ``where``, and their vectors. Rows hit.
805
+
806
+ Deleting a chunk is two statements that must not drift apart: the vectors
807
+ go through :func:`_drop_vectors` (which knows both store layouts) and only
808
+ then does the row go. Tap-level and entry-level deletion had that pair
809
+ written out twice, which is one copy too many for a rule this easy to half-
810
+ apply — an orphan vector outlives every later deletion, because those are
811
+ all scoped through ``chunks``.
812
+
813
+ ``where`` is a literal from this module, never caller data; the parameters
814
+ are bound.
815
+ """
816
+ # `%` rather than `+`, to match every other interpolated statement in this
817
+ # module: those are the shapes ruff's S608 is known to flag here, so the
818
+ # suppression is one ruff actually consumes rather than an unused `noqa`
819
+ # that RUF100 would then reject.
820
+ ids = [r[0] for r in con.execute(
821
+ "SELECT id FROM chunks WHERE %s" % where, params)] # noqa: S608 literal clause
822
+ if not ids:
823
+ return 0
824
+ _drop_vectors(con, ids)
825
+ con.execute("DELETE FROM chunks WHERE %s" % where, params) # noqa: S608 same literal
826
+ return len(ids)
827
+
828
+
829
+ def _delete_entries(con: sqlite3.Connection,
830
+ keys: list[tuple[str, str]]) -> int:
831
+ """Drop every chunk row for these ``(tap, path)`` entries. Returns rows hit.
832
+
833
+ The entry-level counterpart to :func:`_delete_taps`, and it must stay
834
+ row-scoped rather than content-scoped: two taps can ship a byte-identical
835
+ file, so deleting by digest would take another tap's rows with it.
836
+ """
837
+ return sum(_delete_matching(con, "tap = ? AND path = ?", (tap, path))
838
+ for tap, path in keys)
839
+
840
+
841
+ def _prune_stale_entries(con: sqlite3.Connection, taps: list[str],
842
+ live: set[tuple[str, str]]) -> int:
843
+ """Drop rows in ``taps`` for entries the catalog no longer has.
844
+
845
+ Whole-tap deletion used to do this for free: a changed tap was emptied and
846
+ rebuilt, so an entry deleted upstream simply never came back. Reuse keeps
847
+ the rows instead, which means a file removed from a registry would answer
848
+ queries forever — the same silent-stale-row failure `_delete_taps`'s
849
+ `removed_taps` sweep exists to prevent, one level down.
850
+ """
851
+ stale = [(tap, path) for tap in taps
852
+ for (path,) in con.execute(
853
+ "SELECT DISTINCT path FROM chunks WHERE tap = ?", (tap,))
854
+ if (tap, path) not in live]
855
+ return _delete_entries(con, stale)
856
+
857
+
858
+ def _split_by_digest(con: sqlite3.Connection,
859
+ entries: list[dict]) -> tuple[list[dict], list[dict]]:
860
+ """Partition ``entries`` into ``(to_embed, already_stored)``.
861
+
862
+ An entry is already stored when the store holds chunks for its
863
+ ``(tap, path)`` **and every one of them** carries its current content
864
+ digest. Every one, not any: a partially-written entry — an interrupted
865
+ build, or one whose digest changed mid-run — would otherwise be reused
866
+ with a mixture of two versions' vectors, which is worse than re-embedding
867
+ because nothing later notices.
868
+
869
+ An entry with no digest is never reused. `catalog._content_digest` stamps
870
+ them at scan time, but a cache written before ``CACHE_FORMAT`` has none,
871
+ and CLAUDE.md's rule is explicit: consumers degrade cleanly when ``content``
872
+ is absent and **must never treat two absences as a match**. Two entries
873
+ with no digest are not the same entry; they are two unknowns.
874
+ """
875
+ # Nothing to decide, and the early return is the common case rather than a
876
+ # guard: on a build where no tap moved, `candidates` is empty, and without
877
+ # this the store gets scanned end to end to answer a question nobody asked.
878
+ if not entries:
879
+ return [], []
880
+ # Scoped to the taps actually in play, via the `chunks_tap` index. Reading
881
+ # the whole table instead measured 3.75 s cold (0.17 s warm) against 0.08 s
882
+ # for the nineteen largest taps and under 0.01 s for nineteen typical ones,
883
+ # on a real 657,587-chunk store. The full read was also the wrong shape: it
884
+ # grows with the store while the work grows with the drift.
885
+ stored: dict[tuple[str, str], set] = {}
886
+ for tap in sorted({e["tap"] for e in entries}):
887
+ for path, digest in con.execute(
888
+ "SELECT path, digest FROM chunks WHERE tap = ?", (tap,)):
889
+ stored.setdefault((tap, path), set()).add(digest)
890
+ to_embed, kept = [], []
891
+ for e in entries:
892
+ digest = e.get("content")
893
+ have = stored.get(entry_key(e))
894
+ if digest and have == {digest}:
895
+ kept.append(e)
896
+ else:
897
+ to_embed.append(e)
898
+ return to_embed, kept
899
+
900
+
751
901
  def _delete_taps(con: sqlite3.Connection, taps: list[str]) -> None:
902
+ """Drop every chunk row belonging to these taps, and their vectors."""
752
903
  for tap in taps:
753
- ids = [r[0] for r in
754
- con.execute("SELECT id FROM chunks WHERE tap = ?", (tap,))]
755
- _drop_vectors(con, ids)
756
- con.execute("DELETE FROM chunks WHERE tap = ?", (tap,))
904
+ _delete_matching(con, "tap = ?", (tap,))
757
905
 
758
906
 
759
907
  def _embed_and_store(con: sqlite3.Connection, entries: list[dict],
@@ -825,10 +973,14 @@ def _embed_and_store(con: sqlite3.Connection, entries: list[dict],
825
973
  failed_taps.add(e["tap"])
826
974
  continue
827
975
  cur = con.execute(
828
- "INSERT INTO chunks (name, tap, path, kind, cix, snip) "
829
- "VALUES (?, ?, ?, ?, ?, ?)",
976
+ "INSERT INTO chunks (name, tap, path, kind, cix, snip, digest) "
977
+ "VALUES (?, ?, ?, ?, ?, ?, ?)",
830
978
  (e["name"], e["tap"], e["skill_md"],
831
- e.get("kind", "skill"), ci, text[:200].strip()))
979
+ e.get("kind", "skill"), ci, text[:200].strip(),
980
+ # None where the catalog has no digest, which `_split_by_digest`
981
+ # then refuses to reuse — the honest answer for a cache written
982
+ # before CACHE_FORMAT stamped one.
983
+ e.get("content")))
832
984
  _store_vector(con, cur.lastrowid, mod.serialize_float32(vec))
833
985
  added += 1
834
986
  since_commit += 1
@@ -266,6 +266,62 @@ def hit_line(entry: dict, *, installed: bool = False) -> str:
266
266
  entry.get("tap", "?"))
267
267
 
268
268
 
269
+ # `boost_read`'s budget, and it is a measured number rather than a round one.
270
+ # An MCP reply lands directly in an agent's context and a SKILL.md is not
271
+ # bounded above, so a tool that returns one whole is how a single lookup costs
272
+ # a session. Measured over the 63,053 items in a real 467-tap install: median
273
+ # 6,063 bytes, p90 16,225, p99 35,275, **max 567,484** — three orders of
274
+ # magnitude between the middle and the tail, which is the shape that makes an
275
+ # unbounded read a real hazard rather than a theoretical one.
276
+ #
277
+ # 12,000 is the knee. It delivers 80.3% of the catalogue whole against 62.8%
278
+ # at 8,000 — two thirds of the remaining truncations bought for 50% more bytes
279
+ # — and caps the worst case near 3,000 tokens. Raising it to 16,000 buys 9.3
280
+ # points for another third again, which is the wrong side of the trade for a
281
+ # tool an agent may call several times in one turn.
282
+ #
283
+ # The cap counts CHARACTERS, deliberately: boost cannot know the caller's
284
+ # tokenizer, and a character count is one an agent can check against the reply
285
+ # it is already holding. Truncation is never the failure mode this guards
286
+ # against, because it is announced — see :func:`read_reply`.
287
+ READ_LIMIT = 12000
288
+
289
+
290
+ def read_reply(name: str, text: str, *, kind: str = "skill",
291
+ installed: bool = False, limit: int = READ_LIMIT) -> str:
292
+ """`boost_read`'s reply: a header, then the item's own content.
293
+
294
+ The header exists because the body alone does not say what the agent is
295
+ holding. A tap-qualified name resolves to one item out of several that
296
+ share a bare name, and whether it is already installed decides whether the
297
+ next call is `boost_install` or nothing at all — both are one line here and
298
+ neither is recoverable from Markdown.
299
+
300
+ **Truncation is announced, in the reply, at the point it happens.** A body
301
+ cut silently reads as a complete document that simply ends — which for a
302
+ procedure is worse than no body at all, because the agent acts on the half
303
+ it can see and never learns there was a second half. The notice names the
304
+ command that returns the rest, so the reply carries its own recovery path
305
+ the way ``tool-design`` asks agent-facing errors to.
306
+
307
+ Truncation cuts at a LINE boundary within the budget rather than mid-line.
308
+ A Markdown body cut mid-fence or mid-sentence is text an agent has to
309
+ guess about; a whole-line cut is unambiguously "the document continues".
310
+ A body whose first line already exceeds the budget has no such boundary,
311
+ so it falls back to a hard character cut — announced the same way.
312
+ """
313
+ head = ["name: %s" % name]
314
+ if kind != "skill":
315
+ head.append("kind: %s" % kind)
316
+ head.append("installed: %s" % ("yes" if installed else "no"))
317
+ body = text.strip("\n")
318
+ if len(body) > limit:
319
+ cut = body[:limit].rpartition("\n")[0] or body[:limit]
320
+ body = ("%s\n\n[truncated at %d of %d characters — read the rest with "
321
+ "`boost cat %s`]" % (cut, len(cut), len(text), name))
322
+ return "\n".join(head) + "\n\n" + body
323
+
324
+
269
325
  # The lock sections, in the order every boost surface names them. Fixed here
270
326
  # rather than read off the caller's dict, so the footer's column order cannot
271
327
  # drift between a machine that has rules and one that does not.