boost-skill-cli 1.0.451__tar.gz → 1.0.452__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 (707) hide show
  1. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/PKG-INFO +1 -1
  2. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/_version.py +2 -2
  3. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/pkg.py +15 -2
  4. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/quality.py +14 -2
  5. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/embed.py +9 -1
  6. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/logs.py +38 -1
  7. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/store.py +45 -6
  8. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_skill_cli.egg-info/PKG-INFO +1 -1
  9. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_skill_cli.egg-info/SOURCES.txt +7 -0
  10. boost_skill_cli-1.0.452/docs/roadmap/items/crash-reports-leak-api-keys.md +33 -0
  11. boost_skill_cli-1.0.452/docs/roadmap/items/sync-reported-success-for-a-link-it-refused.md +32 -0
  12. boost_skill_cli-1.0.452/docs/roadmap/items/two-crashes-that-should-have-been-messages.md +34 -0
  13. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap.html +88 -1
  14. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_pkg.py +3 -2
  15. boost_skill_cli-1.0.452/tests/unit/test_crash_redaction.py +58 -0
  16. boost_skill_cli-1.0.452/tests/unit/test_embed_truncated_response.py +68 -0
  17. boost_skill_cli-1.0.452/tests/unit/test_install_permission_error.py +56 -0
  18. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_store.py +1 -1
  19. boost_skill_cli-1.0.452/tests/unit/test_sync_blocked_links.py +128 -0
  20. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/.gitattributes +0 -0
  21. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/.gitignore +0 -0
  22. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/.gitleaks.toml +0 -0
  23. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/.htmlvalidate.json +0 -0
  24. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/.lighthouserc.json +0 -0
  25. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/.lycheeignore +0 -0
  26. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/.markdownlint-cli2.jsonc +0 -0
  27. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/.pre-commit-config.yaml +0 -0
  28. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/.stylelintrc.json +0 -0
  29. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/.vale/styles/boost/Terminology.yml +0 -0
  30. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
  31. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/.vale.ini +0 -0
  32. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/CLAUDE.md +0 -0
  33. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/CODE_OF_CONDUCT.md +0 -0
  34. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/CONTRIBUTING.md +0 -0
  35. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/LICENSE +0 -0
  36. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/MANIFEST.in +0 -0
  37. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/Makefile +0 -0
  38. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/README.md +0 -0
  39. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/SECURITY.md +0 -0
  40. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost +0 -0
  41. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/__init__.py +0 -0
  42. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/__main__.py +0 -0
  43. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/cli.py +0 -0
  44. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/cliparse.py +0 -0
  45. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/__init__.py +0 -0
  46. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/_common.py +0 -0
  47. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/bmad.py +0 -0
  48. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/configuration.py +0 -0
  49. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/discovery.py +0 -0
  50. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/hooks.py +0 -0
  51. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/info.py +0 -0
  52. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/intelligence.py +0 -0
  53. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/run.py +0 -0
  54. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/safety.py +0 -0
  55. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/taps.py +0 -0
  56. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/commands/team.py +0 -0
  57. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/__init__.py +0 -0
  58. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/adapters.py +0 -0
  59. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/agents.py +0 -0
  60. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/ai.py +0 -0
  61. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/bmad.py +0 -0
  62. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/bootstrap.py +0 -0
  63. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/builtin.py +0 -0
  64. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/capabilities.py +0 -0
  65. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/catalog.py +0 -0
  66. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/catalogbundle.py +0 -0
  67. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/chat.py +0 -0
  68. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/claude_settings.py +0 -0
  69. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/complete.py +0 -0
  70. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/config.py +0 -0
  71. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/dense.py +0 -0
  72. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/ed25519.py +0 -0
  73. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/faithfulness.py +0 -0
  74. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/frontmatter.py +0 -0
  75. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/gitutil.py +0 -0
  76. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/imperative.py +0 -0
  77. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/injectscan.py +0 -0
  78. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/installscan.py +0 -0
  79. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/integrity.py +0 -0
  80. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/journal.py +0 -0
  81. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/localembed.py +0 -0
  82. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/lockfile.py +0 -0
  83. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/mcp.py +0 -0
  84. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/mcpdecl.py +0 -0
  85. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/mcphost.py +0 -0
  86. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/minisign.py +0 -0
  87. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/nethttp.py +0 -0
  88. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/output.py +0 -0
  89. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/paths.py +0 -0
  90. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/policy.py +0 -0
  91. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/projectlock.py +0 -0
  92. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/provenance.py +0 -0
  93. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/rag.py +0 -0
  94. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/registry.py +0 -0
  95. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/resolve.py +0 -0
  96. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/rules.py +0 -0
  97. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/scopes.py +0 -0
  98. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/secretscan.py +0 -0
  99. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/selfupdate.py +0 -0
  100. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/serve.py +0 -0
  101. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/stackprobe.py +0 -0
  102. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/staleness.py +0 -0
  103. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/trustaudit.py +0 -0
  104. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/typosquat.py +0 -0
  105. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/updatediff.py +0 -0
  106. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/util.py +0 -0
  107. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/core/workflows.py +0 -0
  108. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/data/registries.json +0 -0
  109. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/data/rules/boost-first.mdc +0 -0
  110. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/errors.py +0 -0
  111. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_cli/spin.py +0 -0
  112. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_langchain/__init__.py +0 -0
  113. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_langchain/_compat.py +0 -0
  114. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_langchain/graph.py +0 -0
  115. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_langchain/loader.py +0 -0
  116. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_langchain/py.typed +0 -0
  117. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_langchain/retriever.py +0 -0
  118. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  119. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  120. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_skill_cli.egg-info/requires.txt +0 -0
  121. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/boost_skill_cli.egg-info/top_level.txt +0 -0
  122. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/codecov.yml +0 -0
  123. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/.claude/settings.local.json +0 -0
  124. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/DEBUGGING.md +0 -0
  125. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/adapters.html +0 -0
  126. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/architecture/README.md +0 -0
  127. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/architecture/c4-components-core.md +0 -0
  128. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/architecture/c4-containers.md +0 -0
  129. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/architecture/c4-context.md +0 -0
  130. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/architecture/c4-dynamic-install.md +0 -0
  131. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/gifs/distill.gif +0 -0
  132. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/gifs/doctor.gif +0 -0
  133. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/gifs/explain.gif +0 -0
  134. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/gifs/hooks.gif +0 -0
  135. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/gifs/install.gif +0 -0
  136. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/gifs/pulse.gif +0 -0
  137. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/gifs/search.gif +0 -0
  138. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/gifs/tap.gif +0 -0
  139. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/tapes/distill.tape +0 -0
  140. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/tapes/doctor.tape +0 -0
  141. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/tapes/explain.tape +0 -0
  142. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/tapes/hooks.tape +0 -0
  143. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/tapes/install.tape +0 -0
  144. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/tapes/pulse.tape +0 -0
  145. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/tapes/search.tape +0 -0
  146. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel/tapes/tap.tape +0 -0
  147. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/carousel.html +0 -0
  148. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/chat.html +0 -0
  149. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/commands.html +0 -0
  150. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/demo-index.json +0 -0
  151. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/demo.gif +0 -0
  152. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/demo.html +0 -0
  153. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/demo.tape +0 -0
  154. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/design-roadmap.html +0 -0
  155. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/eval-latest.json +0 -0
  156. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/eval.html +0 -0
  157. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/index.html +0 -0
  158. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/langchain.html +0 -0
  159. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/mcp-hub.html +0 -0
  160. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/rag-architecture.md +0 -0
  161. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D01.md +0 -0
  162. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D02.md +0 -0
  163. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D03.md +0 -0
  164. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D04.md +0 -0
  165. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D05.md +0 -0
  166. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D06.md +0 -0
  167. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D07.md +0 -0
  168. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D08.md +0 -0
  169. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D09.md +0 -0
  170. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D10.md +0 -0
  171. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D11.md +0 -0
  172. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D12.md +0 -0
  173. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D13.md +0 -0
  174. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D14.md +0 -0
  175. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D15.md +0 -0
  176. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D16.md +0 -0
  177. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D17.md +0 -0
  178. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D18.md +0 -0
  179. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D19.md +0 -0
  180. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D20.md +0 -0
  181. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D21.md +0 -0
  182. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D22.md +0 -0
  183. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D23.md +0 -0
  184. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D24.md +0 -0
  185. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D25.md +0 -0
  186. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/BOOST-D26.md +0 -0
  187. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/a11y-sweep-flakes-on-color-contrast.md +0 -0
  188. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  189. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
  190. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
  191. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/agents-field-records-the-request-not-the-links.md +0 -0
  192. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
  193. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
  194. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  195. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  196. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  197. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/bm25-index-is-one-json-blob.md +0 -0
  198. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/bmad-autopilot-one-command-persona-routing.md +0 -0
  199. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/boost-first-carried-the-losing-trigger.md +0 -0
  200. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/boost-first-rule.md +0 -0
  201. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/boost-langchain-publishing.md +0 -0
  202. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  203. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  204. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  205. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  206. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  207. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  208. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  209. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/chat-cites-sources-by-a-number-it-never-prints.md +0 -0
  210. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/chat-command-grounded-conversational-search.md +0 -0
  211. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
  212. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
  213. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
  214. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  215. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
  216. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
  217. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/command-carousel-page.md +0 -0
  218. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  219. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/completions-complete-only-command-names.md +0 -0
  220. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  221. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  222. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  223. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  224. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
  225. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  226. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
  227. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
  228. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/demo-workflow-cancels-other-prs.md +0 -0
  229. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
  230. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
  231. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
  232. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
  233. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/dependabot-splits-multi-path-action-repos.md +0 -0
  234. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  235. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/discover-searches-github-not-a-stale-sample.md +0 -0
  236. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
  237. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  238. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  239. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/dry-run-promised-a-link-nobody-makes.md +0 -0
  240. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/efficiency-registries-ponytail-caveman.md +0 -0
  241. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  242. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/est-items-counts-agent-mirrors-as-items.md +0 -0
  243. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/eval-corpus-cannot-see-real-retrieval.md +0 -0
  244. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/eval-corpus-is-96x-smaller-than-a-real-install.md +0 -0
  245. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/eval-corpus-is-one-strangers-repo.md +0 -0
  246. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/eval-corpus-pins-have-no-refresh-path.md +0 -0
  247. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/eval-corpus-was-not-actually-pinned.md +0 -0
  248. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/eval-deduped-ranked-lists-by-name.md +0 -0
  249. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/eval-stats-could-never-publish.md +0 -0
  250. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/expanded-card-bodies-overflow.md +0 -0
  251. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  252. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  253. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  254. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  255. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  256. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  257. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  258. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  259. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  260. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/gemini-agent-frontmatter-sanitizer.md +0 -0
  261. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
  262. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/github-community-health-files.md +0 -0
  263. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  264. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/golden-set-grades-by-name-not-by-skill.md +0 -0
  265. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  266. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  267. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/heal-deleted-links-it-never-made.md +0 -0
  268. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  269. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/info-rejects-the-qualified-name-it-recommends.md +0 -0
  270. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
  271. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
  272. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/install-path-disambiguation.md +0 -0
  273. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
  274. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  275. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
  276. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  277. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
  278. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  279. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
  280. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/keyless-dense-tier-local-static-embeddings.md +0 -0
  281. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/keyless-semantic-search-for-everyone.md +0 -0
  282. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/langchain-in-the-wheel.md +0 -0
  283. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/langchain-integration-explainer-page.md +0 -0
  284. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/langchain-langgraph-langsmith-integration.md +0 -0
  285. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/langchain-retriever-metadata-and-k-floor.md +0 -0
  286. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  287. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/license-compliance-scanning.md +0 -0
  288. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  289. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/lighthouse-scored-a-page-nobody-is-served.md +0 -0
  290. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
  291. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  292. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  293. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
  294. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  295. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  296. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  297. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
  298. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
  299. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
  300. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  301. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  302. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
  303. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-already-covered-defeater.md +0 -0
  304. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-aware-skills.md +0 -0
  305. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
  306. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  307. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
  308. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  309. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-one-benefit-nameable-task.md +0 -0
  310. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  311. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
  312. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-search-cost-was-understated.md +0 -0
  313. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-search-hid-which-ranking-ran.md +0 -0
  314. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +0 -0
  315. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  316. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mcp-zero-setup-and-three-kinds.md +0 -0
  317. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  318. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
  319. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
  320. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  321. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
  322. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  323. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  324. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  325. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
  326. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
  327. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/near-duplicate-items-eat-the-result-slots.md +0 -0
  328. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
  329. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
  330. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  331. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
  332. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/one-dead-tap-broke-every-update.md +0 -0
  333. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  334. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  335. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  336. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
  337. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/pep585-604-modernization-sweep.md +0 -0
  338. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  339. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
  340. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
  341. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  342. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  343. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/prerequisites-and-semantic-search-setup.md +0 -0
  344. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
  345. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
  346. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  347. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  348. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  349. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  350. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  351. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
  352. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
  353. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
  354. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/python-floor-moves-to-312.md +0 -0
  355. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  356. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/ragas-unpin-when-upstream-ships.md +0 -0
  357. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  358. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  359. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  360. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
  361. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
  362. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
  363. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/required-checks-config-drift.md +0 -0
  364. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/resolve-vendored-duplicate-copies.md +0 -0
  365. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  366. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  367. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
  368. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/roadmap-page-weight-grows-without-bound.md +0 -0
  369. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/roadmap-perf-budget-has-no-local-guard.md +0 -0
  370. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  371. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
  372. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  373. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/rules-install-but-cannot-be-governed.md +0 -0
  374. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  375. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  376. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  377. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
  378. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  379. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
  380. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  381. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
  382. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
  383. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/scripts-under-the-lint-gate.md +0 -0
  384. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/search-never-notices-a-new-tap.md +0 -0
  385. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  386. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  387. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  388. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  389. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
  390. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/self-update-claims-up-to-date-without-asking.md +0 -0
  391. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/serve-404-reflected-the-request.md +0 -0
  392. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/serve-is-a-searchable-catalogue.md +0 -0
  393. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
  394. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/shards-pipeline-never-produced-a-shard.md +0 -0
  395. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/shareable-catalogue-bundle.md +0 -0
  396. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  397. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  398. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  399. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  400. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  401. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  402. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
  403. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  404. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  405. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/sync-could-not-repair-a-gutted-skill.md +0 -0
  406. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
  407. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
  408. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  409. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  410. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/tool-call-eval-tier.md +0 -0
  411. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  412. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  413. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  414. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
  415. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  416. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/unwatched-crons-hid-a-real-fuzz-crash.md +0 -0
  417. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/update-advertises-a-flag-it-rejects.md +0 -0
  418. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  419. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/update-refreshed-rules-without-a-gate.md +0 -0
  420. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  421. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
  422. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  423. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  424. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  425. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
  426. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  427. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  428. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  429. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/workspace-scope-install.md +0 -0
  430. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/zip-strict-audit.md +0 -0
  431. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/zizmor-ignores-drift-and-make-lint-never-ran-it.md +0 -0
  432. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
  433. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/eslint.config.mjs +0 -0
  434. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/evals/README.md +0 -0
  435. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/evals/__init__.py +0 -0
  436. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/evals/baseline.json +0 -0
  437. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/evals/faithfulness.py +0 -0
  438. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/evals/golden_set.json +0 -0
  439. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/evals/make_corpus.py +0 -0
  440. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/evals/make_golden.py +0 -0
  441. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/evals/metrics.py +0 -0
  442. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/evals/publish_golden_dataset.py +0 -0
  443. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/evals/run_evals.py +0 -0
  444. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/examples/README.md +0 -0
  445. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/examples/adapt-demo.sh +0 -0
  446. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/examples/boost-run-prototype.sh +0 -0
  447. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/index.html +0 -0
  448. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/noxfile.py +0 -0
  449. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/pyproject.toml +0 -0
  450. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/requirements/coverage-tools.in +0 -0
  451. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/requirements/coverage-tools.txt +0 -0
  452. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/requirements/lint-tools.in +0 -0
  453. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/requirements/lint-tools.txt +0 -0
  454. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/requirements/mutation-tools.in +0 -0
  455. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/requirements/mutation-tools.txt +0 -0
  456. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/requirements/platform-pins.lock +0 -0
  457. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/requirements/release-tools.in +0 -0
  458. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/requirements/release-tools.txt +0 -0
  459. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/requirements/test-tools.in +0 -0
  460. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/requirements/test-tools.txt +0 -0
  461. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/a11y_check.py +0 -0
  462. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/bench_cli.sh +0 -0
  463. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/build_command_reference.py +0 -0
  464. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/build_demo_index.py +0 -0
  465. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/build_registries.py +0 -0
  466. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/build_roadmap.py +0 -0
  467. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/build_scale_corpus.py +0 -0
  468. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/check_anchors.py +0 -0
  469. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/check_licenses.py +0 -0
  470. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/check_required_checks.py +0 -0
  471. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/ensure_eval_corpus.sh +0 -0
  472. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/eval_corpus.py +0 -0
  473. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/eval_explain.py +0 -0
  474. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/eval_gate.py +0 -0
  475. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/eval_recommend.py +0 -0
  476. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/eval_retrieval.py +0 -0
  477. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/eval_stats_summary.py +0 -0
  478. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/import_budget.py +0 -0
  479. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/lock_toolchain.py +0 -0
  480. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/measure_registry.py +0 -0
  481. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/mutation_gate.py +0 -0
  482. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/mutation_shards.py +0 -0
  483. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/mutation_weights.json +0 -0
  484. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/page_budget.py +0 -0
  485. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/perf_gate.py +0 -0
  486. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/post_deploy_smoke.py +0 -0
  487. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/publish_eval_json.py +0 -0
  488. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/release_guard.py +0 -0
  489. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/release_preflight.py +0 -0
  490. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/scripts/serve_docs.py +0 -0
  491. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/setup.cfg +0 -0
  492. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/sonar-project.properties +0 -0
  493. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/style/README.md +0 -0
  494. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/style/boost.css +0 -0
  495. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/style/boost.js +0 -0
  496. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/style/demo.html +0 -0
  497. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/adapt.feature +0 -0
  498. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/browse.feature +0 -0
  499. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/count.feature +0 -0
  500. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/discover.feature +0 -0
  501. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/doctor.feature +0 -0
  502. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/environment.py +0 -0
  503. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/explain.feature +0 -0
  504. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/index.feature +0 -0
  505. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/install.feature +0 -0
  506. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/list.feature +0 -0
  507. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/mcp.feature +0 -0
  508. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/search.feature +0 -0
  509. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/steps/cli_steps.py +0 -0
  510. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/steps/discovery_steps.py +0 -0
  511. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/steps/mcp_steps.py +0 -0
  512. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/bdd/features/steps/quality_steps.py +0 -0
  513. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/conftest.py +0 -0
  514. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/eval/baseline.json +0 -0
  515. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/eval/explain.jsonl +0 -0
  516. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/eval/golden-natural.jsonl +0 -0
  517. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/eval/golden.jsonl +0 -0
  518. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/eval/recommend.jsonl +0 -0
  519. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/eval/taps-scale.txt +0 -0
  520. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/eval/taps.txt +0 -0
  521. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_capabilities_policy.py +0 -0
  522. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_adapt.py +0 -0
  523. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_bmad.py +0 -0
  524. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_catalog.py +0 -0
  525. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_chat.py +0 -0
  526. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_configuration.py +0 -0
  527. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_discovery.py +0 -0
  528. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_hooks.py +0 -0
  529. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_info.py +0 -0
  530. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_intelligence.py +0 -0
  531. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_quality.py +0 -0
  532. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_taps.py +0 -0
  533. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_cli_team.py +0 -0
  534. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_everyday_loop.py +0 -0
  535. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_integrity_enforce.py +0 -0
  536. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_kind_conformance.py +0 -0
  537. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_property_parsers.py +0 -0
  538. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_run.py +0 -0
  539. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_tap_signing.py +0 -0
  540. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/functional/test_workspace_scope.py +0 -0
  541. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/README.md +0 -0
  542. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
  543. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
  544. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
  545. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
  546. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
  547. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
  548. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
  549. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
  550. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
  551. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
  552. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
  553. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
  554. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
  555. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/registry/02-https.txt +0 -0
  556. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
  557. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
  558. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
  559. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/registry/06-space.txt +0 -0
  560. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
  561. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
  562. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/fuzz_frontmatter.py +0 -0
  563. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/fuzz/fuzz_registry.py +0 -0
  564. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/langchain/conftest.py +0 -0
  565. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/langchain/test_graph.py +0 -0
  566. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/langchain/test_loader.py +0 -0
  567. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/langchain/test_retriever.py +0 -0
  568. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/make_fixture.py +0 -0
  569. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/perf/test_benchmarks.py +0 -0
  570. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/smoke.sh +0 -0
  571. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_a11y_check.py +0 -0
  572. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_action_pin_lockstep.py +0 -0
  573. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_adapters.py +0 -0
  574. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_adapters_multi.py +0 -0
  575. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_adapters_runner.py +0 -0
  576. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_agents.py +0 -0
  577. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_ai.py +0 -0
  578. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_bmad_core.py +0 -0
  579. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_boost_first_offer.py +0 -0
  580. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_bootstrap.py +0 -0
  581. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_builtin.py +0 -0
  582. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_capabilities.py +0 -0
  583. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_catalog.py +0 -0
  584. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_catalogbundle.py +0 -0
  585. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_chat.py +0 -0
  586. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_check_anchors.py +0 -0
  587. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_check_licenses.py +0 -0
  588. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_claude_settings.py +0 -0
  589. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_cliparse.py +0 -0
  590. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_codeql_analysis_key.py +0 -0
  591. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_command_reference_fresh.py +0 -0
  592. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_community_health_files.py +0 -0
  593. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_complete.py +0 -0
  594. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_config.py +0 -0
  595. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_content_dedupe.py +0 -0
  596. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_dedup_trust.py +0 -0
  597. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_demo_index.py +0 -0
  598. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_dense.py +0 -0
  599. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_dense_fallback.py +0 -0
  600. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_dense_fix_hint.py +0 -0
  601. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_dense_shard_real_schema.py +0 -0
  602. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_dense_shard_unreadable_vectors.py +0 -0
  603. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_dense_shards.py +0 -0
  604. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_dense_status.py +0 -0
  605. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_dependabot_config.py +0 -0
  606. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_docs_pages_linked.py +0 -0
  607. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_docsite_chrome.py +0 -0
  608. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_ed25519.py +0 -0
  609. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_embed.py +0 -0
  610. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_embed_local.py +0 -0
  611. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_entry_key.py +0 -0
  612. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_errors_and_cli_table.py +0 -0
  613. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_eval_baseline.py +0 -0
  614. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_eval_corpus.py +0 -0
  615. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_eval_faithfulness.py +0 -0
  616. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_eval_gate.py +0 -0
  617. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_eval_grading.py +0 -0
  618. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_eval_metrics.py +0 -0
  619. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_eval_stats_summary.py +0 -0
  620. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_failure_alerting_covers_unattended.py +0 -0
  621. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_faithfulness.py +0 -0
  622. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_frontmatter.py +0 -0
  623. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_fuzz_targets.py +0 -0
  624. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_gemini_agent_sanitize.py +0 -0
  625. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_gitleaks_config.py +0 -0
  626. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_gitutil.py +0 -0
  627. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_gitutil_lfs.py +0 -0
  628. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_imperative.py +0 -0
  629. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_import_budget.py +0 -0
  630. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_injectscan.py +0 -0
  631. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_installscan.py +0 -0
  632. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_integrity.py +0 -0
  633. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_journal.py +0 -0
  634. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_langchain_packaging.py +0 -0
  635. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_link_ownership.py +0 -0
  636. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_localembed.py +0 -0
  637. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_localembed_e2e.py +0 -0
  638. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_lockfile.py +0 -0
  639. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_logs.py +0 -0
  640. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_marketing_counts.py +0 -0
  641. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_mcp.py +0 -0
  642. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_mcp_install_scan.py +0 -0
  643. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_mcpdecl.py +0 -0
  644. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_mcphost.py +0 -0
  645. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_measure_registry.py +0 -0
  646. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_minisign.py +0 -0
  647. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_mutation_hardening.py +0 -0
  648. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_mutation_shards.py +0 -0
  649. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_mutation_subfile_shards.py +0 -0
  650. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_mutmut_source_paths.py +0 -0
  651. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_nethttp.py +0 -0
  652. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_output.py +0 -0
  653. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_page_budget.py +0 -0
  654. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_paths.py +0 -0
  655. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_perf_gate.py +0 -0
  656. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_pkg_confusions.py +0 -0
  657. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_pkg_injection.py +0 -0
  658. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_pkg_secrets.py +0 -0
  659. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_platform_pins.py +0 -0
  660. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_policy.py +0 -0
  661. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_post_deploy_smoke.py +0 -0
  662. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_project_mcp_sidecar.py +0 -0
  663. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_projectlock.py +0 -0
  664. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_provenance.py +0 -0
  665. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_publish_golden_dataset.py +0 -0
  666. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_rag.py +0 -0
  667. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_rag_fusion.py +0 -0
  668. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_registries_fresh.py +0 -0
  669. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_registry.py +0 -0
  670. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_registry_categories.py +0 -0
  671. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_registry_control_chars.py +0 -0
  672. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_release_guard.py +0 -0
  673. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_release_preflight.py +0 -0
  674. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_required_checks.py +0 -0
  675. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_resolve.py +0 -0
  676. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_roadmap_fresh.py +0 -0
  677. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_rules.py +0 -0
  678. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_scale_corpus.py +0 -0
  679. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_scopes.py +0 -0
  680. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_secretscan.py +0 -0
  681. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_selfupdate.py +0 -0
  682. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_serve.py +0 -0
  683. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_serve_docs.py +0 -0
  684. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_shards_matrix.py +0 -0
  685. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_smoke_covers_every_command.py +0 -0
  686. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_spin.py +0 -0
  687. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_stackprobe.py +0 -0
  688. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_staleness.py +0 -0
  689. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_sync_repairs_gutted_skill.py +0 -0
  690. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_token_parity.py +0 -0
  691. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_toolchain_lock.py +0 -0
  692. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_trustaudit.py +0 -0
  693. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_typosquat.py +0 -0
  694. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_updatediff.py +0 -0
  695. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_util.py +0 -0
  696. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_version.py +0 -0
  697. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_workflow_concurrency.py +0 -0
  698. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_workflow_concurrency_groups.py +0 -0
  699. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_workflow_push_has_credentials.py +0 -0
  700. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_workflow_timeouts.py +0 -0
  701. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_workflows.py +0 -0
  702. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/unit/test_zizmor_ignores_still_anchor.py +0 -0
  703. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/visual/a11y_check.mjs +0 -0
  704. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/visual/console_check.mjs +0 -0
  705. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/visual/package-lock.json +0 -0
  706. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/visual/package.json +0 -0
  707. {boost_skill_cli-1.0.451 → boost_skill_cli-1.0.452}/tests/visual/visual_check.mjs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.451
3
+ Version: 1.0.452
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -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.0.451'
22
- __version_tuple__ = version_tuple = (1, 0, 451)
21
+ __version__ = version = '1.0.452'
22
+ __version_tuple__ = version_tuple = (1, 0, 452)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -568,6 +568,7 @@ def cmd_uninstall(argv: list[str]) -> int:
568
568
  _PLAN_LABELS = [
569
569
  ("missing_store", "missing from store"),
570
570
  ("missing_links", "missing agent links"),
571
+ ("blocked_links", "agent links blocked by a foreign file"),
571
572
  ("stale_links", "stale links"),
572
573
  ("orphaned_store", "orphaned store dirs"),
573
574
  ("missing_materializations", "missing rule/workflow files"),
@@ -651,9 +652,11 @@ def cmd_sync(argv: list[str]) -> int:
651
652
  journal.log("prune", name)
652
653
  pruned.append(name)
653
654
  left = [n for n in orphans if n not in pruned]
655
+ blocked = plan["blocked_links"]
654
656
  if args.json:
655
657
  print(json.dumps({"actions": actions, "pruned": pruned,
656
- "orphaned_store": left, "out_of_scope_links": oos}))
658
+ "orphaned_store": left, "out_of_scope_links": oos,
659
+ "blocked_links": blocked}))
657
660
  return 0
658
661
  for a in actions:
659
662
  out.ok(a)
@@ -668,7 +671,17 @@ def cmd_sync(argv: list[str]) -> int:
668
671
  "`boost install <skill> --force` naming every `--agent`"
669
672
  % (_plural(len(oos), "link"),
670
673
  ", ".join("%s → %s" % (n, a) for n, a in oos)))
671
- if not actions and not pruned and not left and not oos:
674
+ # Before this, a blocked link produced no action and no warning, so the
675
+ # branch below reported "everything in sync" for a repair that had just
676
+ # been refused — and `boost doctor` went on prescribing this command.
677
+ if blocked:
678
+ out.warn("%s could not be created: %s. boost will not delete a file it "
679
+ "does not own — move or delete the path, then re-run `boost "
680
+ "sync`"
681
+ % (_plural(len(blocked), "agent link"),
682
+ ", ".join("%s → %s (%s in the way)"
683
+ % (n, a, _tilde(Path(p))) for n, a, p in blocked)))
684
+ if not actions and not pruned and not left and not oos and not blocked:
672
685
  out.ok("everything in sync")
673
686
  return 0
674
687
 
@@ -427,9 +427,21 @@ def cmd_doctor(argv):
427
427
  if adir is None:
428
428
  continue
429
429
  link = adir / name
430
- if not link.is_symlink() or not link.exists():
430
+ # Two different failures wore one message. `boost sync` creates a
431
+ # link where nothing is in the way and replaces a boost-owned one
432
+ # that dangles — but it will not delete a real file or directory
433
+ # another installer put there, so prescribing it for that case sent
434
+ # the reader in a circle: sync answers "everything in sync", doctor
435
+ # repeats itself. Name the thing in the way instead.
436
+ if link.is_symlink() and link.exists():
437
+ continue
438
+ if not link.is_symlink() and link.exists():
439
+ bad("skill %s not linked for %s — %s exists and is not a boost "
440
+ "link; move or delete it, then run `boost sync`"
441
+ % (name, agent, paths.tilde(link)))
442
+ else:
431
443
  bad("skill %s not linked for %s — run `boost sync`" % (name, agent))
432
- skill_issues += 1
444
+ skill_issues += 1
433
445
  # The other direction. `agents` records what is linked and `only_agents`
434
446
  # what was asked for, so a link the declaration excludes is pure lock
435
447
  # arithmetic here — no second walk of the agent dirs. Doctor has to say
@@ -33,6 +33,7 @@ index.
33
33
  from __future__ import annotations
34
34
 
35
35
  import contextlib
36
+ import http.client
36
37
  import json
37
38
  import os
38
39
  import urllib.error
@@ -253,7 +254,14 @@ def _post(url: str, key: str, payload: dict, timeout: int) -> dict | None:
253
254
  try:
254
255
  with nethttp.urlopen(req, timeout=timeout) as resp:
255
256
  return json.loads(resp.read())
256
- except (urllib.error.URLError, OSError, ValueError):
257
+ # http.client.HTTPException is the gap this list used to have. A connection
258
+ # cut mid-body raises IncompleteRead, which subclasses HTTPException and
259
+ # *neither* OSError nor ValueError — so it went straight through and out of
260
+ # `boost search` as a traceback, for a network hiccup whose right answer is
261
+ # to fall back to BM25. (RemoteDisconnected was already covered only by
262
+ # accident: it also subclasses ConnectionResetError.)
263
+ except (urllib.error.URLError, OSError, ValueError,
264
+ http.client.HTTPException):
257
265
  return None
258
266
 
259
267
 
@@ -47,6 +47,7 @@ import logging
47
47
  import logging.handlers
48
48
  import os
49
49
  import platform
50
+ import re
50
51
  import sys
51
52
  import time
52
53
  import traceback
@@ -262,10 +263,46 @@ def _boost_version() -> str:
262
263
  return "unknown"
263
264
 
264
265
 
266
+ #: Variable names whose value is a credential by definition. Matched on the
267
+ #: trailing word so ``BOOST_ANTHROPIC_API_KEY``, ``BOOST_GITHUB_TOKEN`` and
268
+ #: ``BOOST_TAP_PASSWORD`` are all caught without enumerating providers.
269
+ _SECRET_NAME = re.compile(
270
+ r"(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIALS?|AUTH)$", re.IGNORECASE)
271
+
272
+ #: Value prefixes that are unmistakably a credential whatever the variable is
273
+ #: called. A name denylist alone always trails the next provider someone adds,
274
+ #: and the leak this guards against cost nothing to introduce: boost documents
275
+ #: ``BOOST_ANTHROPIC_API_KEY``, so the variable most likely to be *set* was also
276
+ #: the one most likely to be secret.
277
+ _SECRET_VALUE = re.compile(
278
+ r"^(?:sk-|pk-|rk-|voy-|pa-|ghp_|gho_|ghu_|ghs_|ghr_|github_pat_"
279
+ r"|xox[abprs]-|AKIA[0-9A-Z]{16}|AIza[0-9A-Za-z_-]{35})")
280
+
281
+ REDACTED = "<REDACTED>"
282
+
283
+
284
+ def _redact(name: str, value: str) -> str:
285
+ """The value to print for ``name``, with credentials withheld.
286
+
287
+ Redacts rather than drops. A missing line reads as "unset", which sends
288
+ whoever is reading the crash report down the wrong path — the fact that a
289
+ key *was* configured is exactly what they need to know.
290
+ """
291
+ if _SECRET_NAME.search(name) or _SECRET_VALUE.match(value):
292
+ return REDACTED
293
+ # Belt and braces for the shape a credential takes even when it carries no
294
+ # recognised prefix: one long opaque run with no separators. Excluding
295
+ # anything path-like keeps ordinary debug values (dirs, URLs) readable.
296
+ if (len(value) >= 40 and not set(value) & set(" \t/\\")
297
+ and re.fullmatch(r"[A-Za-z0-9_.+=-]+", value)):
298
+ return REDACTED
299
+ return value
300
+
301
+
265
302
  def _env_snapshot() -> list[str]:
266
303
  keys = sorted(k for k in os.environ
267
304
  if k.startswith("BOOST_") or k in ("NO_COLOR", "CLICOLOR_FORCE"))
268
- return ["%s=%s" % (k, os.environ[k]) for k in keys]
305
+ return ["%s=%s" % (k, _redact(k, os.environ[k])) for k in keys]
269
306
 
270
307
 
271
308
  def write_crash_report(exc: BaseException, argv: list[str]) -> Path | None:
@@ -251,9 +251,29 @@ def _copy_skill(src: Path, dest: Path) -> None:
251
251
  fast renames, and a failed swap rolls back to the original.
252
252
  """
253
253
  dest = Path(dest)
254
- dest.parent.mkdir(parents=True, exist_ok=True)
255
- staged = Path(tempfile.mkdtemp(dir=str(dest.parent),
256
- prefix="." + dest.name + ".tmp"))
254
+ # Staging needs to *write* next to dest, and a store that cannot be written
255
+ # is an ordinary, fixable condition — a sandboxed shell, a synced folder, a
256
+ # store owned by another user. It used to escape as a raw PermissionError
257
+ # from tempfile.mkdtemp, so boost answered `boost install <skill>` with a
258
+ # stack trace ending in a temp path nobody recognises, and filed a crash
259
+ # report for it. Name the directory instead: that is the whole diagnosis.
260
+ try:
261
+ dest.parent.mkdir(parents=True, exist_ok=True)
262
+ staged = Path(tempfile.mkdtemp(dir=str(dest.parent),
263
+ prefix="." + dest.name + ".tmp"))
264
+ except PermissionError as exc:
265
+ raise BoostError(
266
+ "cannot write to the skill store at %s" % dest.parent,
267
+ hint="check that you own the directory and it is writable "
268
+ "(`ls -ld %s`); a sandboxed shell is the usual cause"
269
+ % dest.parent) from exc
270
+ except OSError as exc:
271
+ # Not a permissions problem — disk full, read-only mount, name too
272
+ # long. Say which, rather than describing every one of them as denied.
273
+ raise BoostError(
274
+ "cannot stage a copy in %s: %s"
275
+ % (dest.parent, exc.strerror or exc),
276
+ hint="free space or fix the mount, then re-run") from exc
257
277
  backup = None
258
278
  try:
259
279
  shutil.copytree(
@@ -1257,15 +1277,27 @@ def sync_plan() -> dict[str, list]:
1257
1277
 
1258
1278
  Returns {missing_store, missing_links, stale_links, orphaned_store}
1259
1279
  missing_store: lock entries whose store dir is gone
1260
- missing_links: (skill, agent) pairs that should be linked but aren't
1280
+ missing_links: (skill, agent) pairs that should be linked but aren't,
1281
+ and that sync *can* create
1282
+ blocked_links: (skill, agent, path) where something that is not a boost
1283
+ symlink occupies the link path — sync will not clobber it
1261
1284
  stale_links: paths in agent dirs that are broken/unmanaged symlinks
1262
1285
  orphaned_store: store dirs not present in the lock file
1263
1286
  out_of_scope_links: (skill, agent) pairs linked outside a declared
1264
1287
  ``--agent`` narrowing — reported, never auto-removed
1288
+
1289
+ ``blocked_links`` exists because lumping it into ``missing_links`` made
1290
+ ``boost sync`` promise a repair it could never perform. ``link_agents``
1291
+ refuses to delete a real file or directory it does not own (right), records
1292
+ it in ``.conflicts`` — and ``sync_apply`` dropped that on the floor, so the
1293
+ command printed "everything in sync" while ``boost doctor`` went on
1294
+ reporting the same skill unlinked and prescribing ``boost sync``. Seen for
1295
+ real where another installer had written ``~/.claude/skills/hyperframes``
1296
+ as a directory: a closed loop with no exit.
1265
1297
  """
1266
1298
  lock = lockfile.installed()
1267
1299
  plan: dict[str, list] = {"missing_store": [], "missing_links": [],
1268
- "stale_links": [], "orphaned_store": [],
1300
+ "blocked_links": [], "stale_links": [], "orphaned_store": [],
1269
1301
  "missing_materializations": [], "out_of_scope_links": []}
1270
1302
  for name, entry in lock.items():
1271
1303
  sdir = skill_store_dir(name)
@@ -1298,7 +1330,14 @@ def sync_plan() -> dict[str, list]:
1298
1330
  in_scope = scoped_agents(entry, linking)
1299
1331
  for agent, adir in in_scope.items():
1300
1332
  link = adir / name
1301
- if not link.is_symlink() or not link.exists():
1333
+ # A symlink is boost's to replace even when it dangles; anything
1334
+ # else that exists is someone else's file and stays put.
1335
+ if link.is_symlink():
1336
+ if not link.exists():
1337
+ plan["missing_links"].append((name, agent))
1338
+ elif link.exists():
1339
+ plan["blocked_links"].append((name, agent, str(link)))
1340
+ else:
1302
1341
  plan["missing_links"].append((name, agent))
1303
1342
  # The other direction, which nothing checked: a link that exists in an
1304
1343
  # agent the declaration excludes. The loop above is narrowed to the
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.451
3
+ Version: 1.0.452
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -219,6 +219,7 @@ docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md
219
219
  docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md
220
220
  docs/roadmap/items/crash-listing-branch-untested.md
221
221
  docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md
222
+ docs/roadmap/items/crash-reports-leak-api-keys.md
222
223
  docs/roadmap/items/demo-cannot-open-its-own-pr.md
223
224
  docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md
224
225
  docs/roadmap/items/demo-workflow-cancels-other-prs.md
@@ -401,9 +402,11 @@ docs/roadmap/items/surface-every-docs-page-from-the-guide.md
401
402
  docs/roadmap/items/sync-could-not-repair-a-gutted-skill.md
402
403
  docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md
403
404
  docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md
405
+ docs/roadmap/items/sync-reported-success-for-a-link-it-refused.md
404
406
  docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md
405
407
  docs/roadmap/items/theme-asset-linting-stylelint-eslint.md
406
408
  docs/roadmap/items/tool-call-eval-tier.md
409
+ docs/roadmap/items/two-crashes-that-should-have-been-messages.md
407
410
  docs/roadmap/items/typo-detection-codespell.md
408
411
  docs/roadmap/items/typosquat-and-name-confusion-detection.md
409
412
  docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md
@@ -584,6 +587,7 @@ tests/unit/test_community_health_files.py
584
587
  tests/unit/test_complete.py
585
588
  tests/unit/test_config.py
586
589
  tests/unit/test_content_dedupe.py
590
+ tests/unit/test_crash_redaction.py
587
591
  tests/unit/test_dedup_trust.py
588
592
  tests/unit/test_demo_index.py
589
593
  tests/unit/test_dense.py
@@ -599,6 +603,7 @@ tests/unit/test_docsite_chrome.py
599
603
  tests/unit/test_ed25519.py
600
604
  tests/unit/test_embed.py
601
605
  tests/unit/test_embed_local.py
606
+ tests/unit/test_embed_truncated_response.py
602
607
  tests/unit/test_entry_key.py
603
608
  tests/unit/test_errors_and_cli_table.py
604
609
  tests/unit/test_eval_baseline.py
@@ -619,6 +624,7 @@ tests/unit/test_gitutil_lfs.py
619
624
  tests/unit/test_imperative.py
620
625
  tests/unit/test_import_budget.py
621
626
  tests/unit/test_injectscan.py
627
+ tests/unit/test_install_permission_error.py
622
628
  tests/unit/test_installscan.py
623
629
  tests/unit/test_integrity.py
624
630
  tests/unit/test_journal.py
@@ -678,6 +684,7 @@ tests/unit/test_spin.py
678
684
  tests/unit/test_stackprobe.py
679
685
  tests/unit/test_staleness.py
680
686
  tests/unit/test_store.py
687
+ tests/unit/test_sync_blocked_links.py
681
688
  tests/unit/test_sync_repairs_gutted_skill.py
682
689
  tests/unit/test_token_parity.py
683
690
  tests/unit/test_toolchain_lock.py
@@ -0,0 +1,33 @@
1
+ ---
2
+ id: crash-reports-leak-api-keys
3
+ board: code
4
+ section: trust
5
+ status: shipped
6
+ category: Bug
7
+ complexity: S
8
+ impact: High
9
+ wow: 5
10
+ note:
11
+ order: 3
12
+ owner: fix/audit-findings
13
+ pr:
14
+ title: Crash reports carried API keys in cleartext
15
+ ---
16
+ A crash report is the one file boost actively invites a user to paste into a bug report — its
17
+ docstring says so: "a user can attach one file to a bug report instead of reproducing by hand."
18
+ <code>_env_snapshot()</code> built that file by printing every <code>BOOST_*</code> variable
19
+ verbatim. Since boost documents <code>BOOST_ANTHROPIC_API_KEY</code> as the way to supply a key,
20
+ the variable most likely to be <em>set</em> was also the one most likely to be secret.
21
+
22
+ Found on a real machine, not in review: three reports under <code>~/.boost/logs/</code>, each
23
+ carrying a live <code>sk-ant-api03-…</code> key, written by two ordinary
24
+ <code>boost install</code> failures and one <code>boost search</code>. Nothing had to go wrong
25
+ beyond the crash itself — the leak was the reporting path working as designed.
26
+
27
+ Values are now withheld two ways, because either alone rots. A name ending in
28
+ <code>KEY</code>/<code>TOKEN</code>/<code>SECRET</code>/<code>PASSWORD</code>/<code>AUTH</code> is
29
+ redacted, which covers every provider without enumerating them; and a value carrying a known
30
+ credential prefix (<code>sk-</code>, <code>ghp_</code>, <code>xox…</code>, <code>AKIA…</code>) is
31
+ redacted whatever it is called, because a name denylist always trails the next provider someone
32
+ adds. Redacted, never dropped: a missing line reads as "unset", and the fact that a key
33
+ <em>was</em> configured is exactly what the reader needs.
@@ -0,0 +1,32 @@
1
+ ---
2
+ id: sync-reported-success-for-a-link-it-refused
3
+ board: code
4
+ section: compat
5
+ status: shipped
6
+ category: Bug
7
+ complexity: S
8
+ impact: High
9
+ wow: 4
10
+ note:
11
+ order: 12
12
+ owner: fix/audit-findings
13
+ pr:
14
+ title: <code>sync</code> reported success for a link it had just refused
15
+ ---
16
+ Observed on a real machine as a closed loop with no exit: <code>boost sync</code> answers
17
+ "✓ everything in sync" &middot; <code>boost doctor</code> answers "! skill hyperframes not linked
18
+ for claude-code — run <code>boost sync</code>" &middot; repeat forever.
19
+
20
+ Another installer had written <code>~/.claude/skills/hyperframes</code> as a real directory.
21
+ <code>link_agents</code> correctly refuses to delete a path boost does not own and records it in
22
+ <code>.conflicts</code> — but <code>sync_apply</code> dropped that value on the floor, appended no
23
+ action, and the command layer read "no actions" as "nothing to do". Doctor, meanwhile, tested only
24
+ <code>is_symlink()</code> and prescribed the command that had just declined to help.
25
+
26
+ <code>sync_plan</code> now separates the two cases it had been conflating: a
27
+ <code>missing_link</code> is one sync can create (nothing in the way, or a dangling symlink boost
28
+ owns and may replace), and a <code>blocked_link</code> is a path occupied by a file boost will not
29
+ touch. <code>sync</code> warns and names the path; <code>doctor</code> says why sync did nothing
30
+ and gives the step that unblocks it. store.py's own comment already named this anti-pattern — "sync
31
+ would answer 'everything in sync', change nothing, and send the reader back to the same error" —
32
+ one function above the code that was doing it.
@@ -0,0 +1,34 @@
1
+ ---
2
+ id: two-crashes-that-should-have-been-messages
3
+ board: code
4
+ section: compat
5
+ status: shipped
6
+ category: Bug
7
+ complexity: S
8
+ impact: Medium
9
+ wow: 3
10
+ note:
11
+ order: 13
12
+ owner: fix/audit-findings
13
+ pr:
14
+ title: Two crashes that should have been messages
15
+ ---
16
+ Both were found by reading the crash reports on a real machine rather than by review, and both are
17
+ the same shape: an expected, fixable condition escaping as a traceback.
18
+
19
+ <strong>An unwritable store.</strong> <code>store._copy_skill</code> stages its copy with
20
+ <code>tempfile.mkdtemp</code> next to the destination. Where <code>~/.agents/skills</code> could not
21
+ be written — a sandboxed shell is the usual cause — the raw <code>PermissionError</code> escaped, so
22
+ <code>boost install &lt;skill&gt;</code> answered with a stack trace ending in a temp path nobody
23
+ recognises, and filed a crash report for a permissions problem. It now names the directory, which
24
+ is the whole diagnosis. A non-permissions <code>OSError</code> (disk full, read-only mount) is
25
+ reported as itself rather than described as denied.
26
+
27
+ <strong>A truncated embedding response.</strong> <code>embed._post</code> guarded with
28
+ <code>except (URLError, OSError, ValueError)</code>. <code>http.client.IncompleteRead</code> — what
29
+ a connection cut mid-body raises — subclasses <code>HTTPException</code> and <em>none</em> of those
30
+ three, so it went straight through <code>resp.read()</code> and out of <code>boost search</code>.
31
+ Seen as <code>IncompleteRead(6629 bytes read, 6200 more expected)</code> on
32
+ <code>boost search mempalace</code>. The right answer to a network hiccup is to return None and let
33
+ retrieval fall back to BM25, which is what it now does. <code>RemoteDisconnected</code> had been
34
+ covered only by accident — it also subclasses <code>ConnectionResetError</code>.
@@ -133,7 +133,7 @@
133
133
  <div class="stat"><b>16</b><span>Shipped</span></div>
134
134
  <div class="stat"><b>1</b><span>Next up</span></div>
135
135
  <div class="stat"><b>7</b><span>Planned</span></div>
136
- <div class="stat"><b>246</b><span>Loop finds</span></div>
136
+ <div class="stat"><b>249</b><span>Loop finds</span></div>
137
137
  <!-- /ROADMAP:stats -->
138
138
  </div>
139
139
  </section>
@@ -9218,6 +9218,64 @@ reaches the network as a side effect of checking what a command prints.</p></det
9218
9218
  </div>
9219
9219
  </article>
9220
9220
 
9221
+ <article class="cap rcard" id="sync-reported-success-for-a-link-it-refused">
9222
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Bug</span></div>
9223
+ <h3><code>sync</code> reported success for a link it had just refused</h3>
9224
+ <details class="cardbody"><summary>Write-up</summary>
9225
+ <p>Observed on a real machine as a closed loop with no exit: <code>boost sync</code> answers
9226
+ "✓ everything in sync" &middot; <code>boost doctor</code> answers "! skill hyperframes not linked
9227
+ for claude-code — run <code>boost sync</code>" &middot; repeat forever.
9228
+
9229
+ Another installer had written <code>~/.claude/skills/hyperframes</code> as a real directory.
9230
+ <code>link_agents</code> correctly refuses to delete a path boost does not own and records it in
9231
+ <code>.conflicts</code> — but <code>sync_apply</code> dropped that value on the floor, appended no
9232
+ action, and the command layer read "no actions" as "nothing to do". Doctor, meanwhile, tested only
9233
+ <code>is_symlink()</code> and prescribed the command that had just declined to help.
9234
+
9235
+ <code>sync_plan</code> now separates the two cases it had been conflating: a
9236
+ <code>missing_link</code> is one sync can create (nothing in the way, or a dangling symlink boost
9237
+ owns and may replace), and a <code>blocked_link</code> is a path occupied by a file boost will not
9238
+ touch. <code>sync</code> warns and names the path; <code>doctor</code> says why sync did nothing
9239
+ and gives the step that unblocks it. store.py's own comment already named this anti-pattern — "sync
9240
+ would answer 'everything in sync', change nothing, and send the reader back to the same error" —
9241
+ one function above the code that was doing it.</p></details>
9242
+ <div class="meta">
9243
+ <span class="m">Complexity <b>S</b></span>
9244
+ <span class="m hi">Impact <b>High</b></span>
9245
+ <span class="m">Wow <b class="wow">★★★★</b></span>
9246
+ </div>
9247
+ </article>
9248
+
9249
+ <article class="cap rcard" id="two-crashes-that-should-have-been-messages">
9250
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Bug</span></div>
9251
+ <h3>Two crashes that should have been messages</h3>
9252
+ <details class="cardbody"><summary>Write-up</summary>
9253
+ <p>Both were found by reading the crash reports on a real machine rather than by review, and both are
9254
+ the same shape: an expected, fixable condition escaping as a traceback.
9255
+
9256
+ <strong>An unwritable store.</strong> <code>store._copy_skill</code> stages its copy with
9257
+ <code>tempfile.mkdtemp</code> next to the destination. Where <code>~/.agents/skills</code> could not
9258
+ be written — a sandboxed shell is the usual cause — the raw <code>PermissionError</code> escaped, so
9259
+ <code>boost install &lt;skill&gt;</code> answered with a stack trace ending in a temp path nobody
9260
+ recognises, and filed a crash report for a permissions problem. It now names the directory, which
9261
+ is the whole diagnosis. A non-permissions <code>OSError</code> (disk full, read-only mount) is
9262
+ reported as itself rather than described as denied.
9263
+
9264
+ <strong>A truncated embedding response.</strong> <code>embed._post</code> guarded with
9265
+ <code>except (URLError, OSError, ValueError)</code>. <code>http.client.IncompleteRead</code> — what
9266
+ a connection cut mid-body raises — subclasses <code>HTTPException</code> and <em>none</em> of those
9267
+ three, so it went straight through <code>resp.read()</code> and out of <code>boost search</code>.
9268
+ Seen as <code>IncompleteRead(6629 bytes read, 6200 more expected)</code> on
9269
+ <code>boost search mempalace</code>. The right answer to a network hiccup is to return None and let
9270
+ retrieval fall back to BM25, which is what it now does. <code>RemoteDisconnected</code> had been
9271
+ covered only by accident — it also subclasses <code>ConnectionResetError</code>.</p></details>
9272
+ <div class="meta">
9273
+ <span class="m">Complexity <b>S</b></span>
9274
+ <span class="m">Impact <b>Medium</b></span>
9275
+ <span class="m">Wow <b class="wow">★★★</b></span>
9276
+ </div>
9277
+ </article>
9278
+
9221
9279
  <article class="cap rcard" id="mcp-register-names-server-before-env">
9222
9280
  <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Bug · MCP</span></div>
9223
9281
  <h3>Order the server name before -e flags in `boost mcp register`</h3>
@@ -9656,6 +9714,35 @@ the command layer never was.</p></details>
9656
9714
  </div>
9657
9715
  </article>
9658
9716
 
9717
+ <article class="cap rcard" id="crash-reports-leak-api-keys">
9718
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Bug</span></div>
9719
+ <h3>Crash reports carried API keys in cleartext</h3>
9720
+ <details class="cardbody"><summary>Write-up</summary>
9721
+ <p>A crash report is the one file boost actively invites a user to paste into a bug report — its
9722
+ docstring says so: "a user can attach one file to a bug report instead of reproducing by hand."
9723
+ <code>_env_snapshot()</code> built that file by printing every <code>BOOST_*</code> variable
9724
+ verbatim. Since boost documents <code>BOOST_ANTHROPIC_API_KEY</code> as the way to supply a key,
9725
+ the variable most likely to be <em>set</em> was also the one most likely to be secret.
9726
+
9727
+ Found on a real machine, not in review: three reports under <code>~/.boost/logs/</code>, each
9728
+ carrying a live <code>sk-ant-api03-…</code> key, written by two ordinary
9729
+ <code>boost install</code> failures and one <code>boost search</code>. Nothing had to go wrong
9730
+ beyond the crash itself — the leak was the reporting path working as designed.
9731
+
9732
+ Values are now withheld two ways, because either alone rots. A name ending in
9733
+ <code>KEY</code>/<code>TOKEN</code>/<code>SECRET</code>/<code>PASSWORD</code>/<code>AUTH</code> is
9734
+ redacted, which covers every provider without enumerating them; and a value carrying a known
9735
+ credential prefix (<code>sk-</code>, <code>ghp_</code>, <code>xox…</code>, <code>AKIA…</code>) is
9736
+ redacted whatever it is called, because a name denylist always trails the next provider someone
9737
+ adds. Redacted, never dropped: a missing line reads as "unset", and the fact that a key
9738
+ <em>was</em> configured is exactly what the reader needs.</p></details>
9739
+ <div class="meta">
9740
+ <span class="m">Complexity <b>S</b></span>
9741
+ <span class="m hi">Impact <b>High</b></span>
9742
+ <span class="m">Wow <b class="wow">★★★★★</b></span>
9743
+ </div>
9744
+ </article>
9745
+
9659
9746
  <article class="cap rcard" id="tap-signing-and-provenance-sigstore-minisign">
9660
9747
  <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Security · Provenance</span></div>
9661
9748
  <h3>Tap signing &amp; provenance — Sigstore / minisign</h3>
@@ -1184,12 +1184,13 @@ class TestSyncJson:
1184
1184
  assert "everything in sync" in r.out
1185
1185
  plan = json.loads(boost("sync", "--diff", "--json").out)
1186
1186
  assert plan == {"missing_store": [], "missing_links": [],
1187
- "stale_links": [], "orphaned_store": [],
1187
+ "blocked_links": [], "stale_links": [],
1188
+ "orphaned_store": [],
1188
1189
  "missing_materializations": [], "out_of_scope_links": [],
1189
1190
  "project": {"missing": [], "orphaned": []}}
1190
1191
  data = json.loads(boost("sync", "--json").out)
1191
1192
  assert data == {"actions": [], "pruned": [], "orphaned_store": [],
1192
- "out_of_scope_links": []}
1193
+ "out_of_scope_links": [], "blocked_links": []}
1193
1194
 
1194
1195
  def test_a_narrowing_reinstall_is_reported_and_pruned_only_on_request(
1195
1196
  self, boost, installed):
@@ -0,0 +1,58 @@
1
+ """A crash report is the one file users are invited to paste into a bug report.
2
+
3
+ `_env_snapshot` captured every ``BOOST_*`` variable verbatim, and boost's own
4
+ documented way to supply a key is ``BOOST_ANTHROPIC_API_KEY`` — so the variable
5
+ most likely to be set was also the one most likely to be secret. Three reports
6
+ on a real machine carried a live ``sk-ant-api03-...`` key in cleartext.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import pytest
11
+
12
+ from boost_cli.core import logs
13
+
14
+
15
+ class TestEnvSnapshotRedaction:
16
+ SECRET = "sk-ant-api03-" + "x" * 80
17
+
18
+ @pytest.mark.parametrize("var", [
19
+ "BOOST_ANTHROPIC_API_KEY",
20
+ "BOOST_OPENAI_API_KEY",
21
+ "BOOST_VOYAGE_API_KEY",
22
+ "BOOST_GITHUB_TOKEN",
23
+ "BOOST_REGISTRY_SECRET",
24
+ "BOOST_TAP_PASSWORD",
25
+ ])
26
+ def test_secret_value_never_appears(self, var, monkeypatch):
27
+ monkeypatch.setenv(var, self.SECRET)
28
+ body = "\n".join(logs._env_snapshot())
29
+ assert self.SECRET not in body
30
+ assert var in body, "the variable is still worth reporting — only its value is not"
31
+
32
+ def test_redaction_is_marked_not_silently_dropped(self, monkeypatch):
33
+ monkeypatch.setenv("BOOST_ANTHROPIC_API_KEY", self.SECRET)
34
+ line = next(x for x in logs._env_snapshot() if x.startswith("BOOST_ANTHROPIC_API_KEY"))
35
+ # A dropped line reads as "unset", which sends a bug reporter down the
36
+ # wrong path. Say the value was withheld.
37
+ assert "REDACTED" in line
38
+
39
+ def test_non_secret_values_survive(self, monkeypatch):
40
+ monkeypatch.setenv("BOOST_ASSUME_YES", "1")
41
+ monkeypatch.setenv("BOOST_NO_AI", "1")
42
+ body = "\n".join(logs._env_snapshot())
43
+ assert "BOOST_ASSUME_YES=1" in body
44
+ assert "BOOST_NO_AI=1" in body
45
+
46
+ def test_crash_report_on_disk_carries_no_secret(self, monkeypatch, sandbox):
47
+ monkeypatch.setenv("BOOST_ANTHROPIC_API_KEY", self.SECRET)
48
+ report = logs.write_crash_report(RuntimeError("boom"), ["install", "x"])
49
+ assert report is not None
50
+ assert self.SECRET not in report.read_text(encoding="utf-8")
51
+
52
+ def test_a_secret_by_value_shape_is_caught_whatever_its_name(self, monkeypatch):
53
+ # Name-matching alone is a denylist and will always trail the next
54
+ # variable someone adds. A value that is unmistakably a key is redacted
55
+ # on its shape too.
56
+ monkeypatch.setenv("BOOST_SOMETHING_HARMLESS_SOUNDING", self.SECRET)
57
+ body = "\n".join(logs._env_snapshot())
58
+ assert self.SECRET not in body