boost-skill-cli 1.2.5__tar.gz → 1.2.6__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 (729) hide show
  1. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/PKG-INFO +1 -1
  2. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/_version.py +2 -2
  3. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/registry.py +44 -4
  4. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_skill_cli.egg-info/PKG-INFO +1 -1
  5. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_skill_cli.egg-info/SOURCES.txt +4 -0
  6. boost_skill_cli-1.2.6/docs/roadmap/items/pathlib-exists-is-not-total.md +48 -0
  7. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap.html +46 -1
  8. boost_skill_cli-1.2.6/tests/fuzz/corpus/registry/09-nul.txt +0 -0
  9. boost_skill_cli-1.2.6/tests/fuzz/corpus/registry/10-name-too-long.txt +1 -0
  10. boost_skill_cli-1.2.6/tests/fuzz/corpus/registry/11-long-owner-repo.txt +1 -0
  11. boost_skill_cli-1.2.6/tests/unit/test_registry_control_chars.py +233 -0
  12. boost_skill_cli-1.2.5/tests/unit/test_registry_control_chars.py +0 -113
  13. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/.gitattributes +0 -0
  14. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/.gitignore +0 -0
  15. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/.gitleaks.toml +0 -0
  16. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/.htmlvalidate.json +0 -0
  17. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/.lighthouserc.json +0 -0
  18. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/.lycheeignore +0 -0
  19. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/.markdownlint-cli2.jsonc +0 -0
  20. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/.pre-commit-config.yaml +0 -0
  21. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/.stylelintrc.json +0 -0
  22. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/.vale/styles/boost/Terminology.yml +0 -0
  23. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
  24. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/.vale.ini +0 -0
  25. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/CLAUDE.md +0 -0
  26. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/CODE_OF_CONDUCT.md +0 -0
  27. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/CONTRIBUTING.md +0 -0
  28. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/LICENSE +0 -0
  29. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/MANIFEST.in +0 -0
  30. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/Makefile +0 -0
  31. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/README.md +0 -0
  32. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/SECURITY.md +0 -0
  33. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost +0 -0
  34. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/__init__.py +0 -0
  35. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/__main__.py +0 -0
  36. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/cli.py +0 -0
  37. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/cliparse.py +0 -0
  38. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/__init__.py +0 -0
  39. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/_common.py +0 -0
  40. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/bmad.py +0 -0
  41. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/configuration.py +0 -0
  42. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/discovery.py +0 -0
  43. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/hooks.py +0 -0
  44. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/info.py +0 -0
  45. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/intelligence.py +0 -0
  46. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/pkg.py +0 -0
  47. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/quality.py +0 -0
  48. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/run.py +0 -0
  49. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/safety.py +0 -0
  50. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/taps.py +0 -0
  51. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/commands/team.py +0 -0
  52. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/__init__.py +0 -0
  53. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/adapters.py +0 -0
  54. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/agents.py +0 -0
  55. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/ai.py +0 -0
  56. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/bmad.py +0 -0
  57. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/bootstrap.py +0 -0
  58. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/browse.py +0 -0
  59. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/builtin.py +0 -0
  60. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/capabilities.py +0 -0
  61. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/catalog.py +0 -0
  62. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/catalogbundle.py +0 -0
  63. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/chat.py +0 -0
  64. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/claude_settings.py +0 -0
  65. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/complete.py +0 -0
  66. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/config.py +0 -0
  67. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/dense.py +0 -0
  68. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/ed25519.py +0 -0
  69. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/embed.py +0 -0
  70. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/faithfulness.py +0 -0
  71. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/frontmatter.py +0 -0
  72. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/gitutil.py +0 -0
  73. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/imperative.py +0 -0
  74. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/injectscan.py +0 -0
  75. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/installscan.py +0 -0
  76. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/integrity.py +0 -0
  77. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/journal.py +0 -0
  78. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/localembed.py +0 -0
  79. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/lockfile.py +0 -0
  80. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/logs.py +0 -0
  81. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/mcp.py +0 -0
  82. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/mcpdecl.py +0 -0
  83. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/mcphost.py +0 -0
  84. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/minisign.py +0 -0
  85. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/nethttp.py +0 -0
  86. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/output.py +0 -0
  87. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/paths.py +0 -0
  88. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/policy.py +0 -0
  89. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/projectlock.py +0 -0
  90. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/provenance.py +0 -0
  91. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/rag.py +0 -0
  92. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/resolve.py +0 -0
  93. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/rules.py +0 -0
  94. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/scopes.py +0 -0
  95. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/secretscan.py +0 -0
  96. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/selfupdate.py +0 -0
  97. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/serve.py +0 -0
  98. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/stackprobe.py +0 -0
  99. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/staleness.py +0 -0
  100. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/store.py +0 -0
  101. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/trustaudit.py +0 -0
  102. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/typosquat.py +0 -0
  103. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/updatediff.py +0 -0
  104. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/util.py +0 -0
  105. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/core/workflows.py +0 -0
  106. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/data/registries.json +0 -0
  107. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/data/rules/boost-first.mdc +0 -0
  108. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/errors.py +0 -0
  109. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_cli/spin.py +0 -0
  110. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_langchain/__init__.py +0 -0
  111. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_langchain/_compat.py +0 -0
  112. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_langchain/graph.py +0 -0
  113. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_langchain/loader.py +0 -0
  114. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_langchain/py.typed +0 -0
  115. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_langchain/retriever.py +0 -0
  116. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  117. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  118. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_skill_cli.egg-info/requires.txt +0 -0
  119. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/boost_skill_cli.egg-info/top_level.txt +0 -0
  120. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/codecov.yml +0 -0
  121. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/.claude/settings.local.json +0 -0
  122. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/DEBUGGING.md +0 -0
  123. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/adapters.html +0 -0
  124. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/architecture/README.md +0 -0
  125. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/architecture/c4-components-core.md +0 -0
  126. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/architecture/c4-containers.md +0 -0
  127. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/architecture/c4-context.md +0 -0
  128. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/architecture/c4-dynamic-install.md +0 -0
  129. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/gifs/distill.gif +0 -0
  130. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/gifs/doctor.gif +0 -0
  131. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/gifs/explain.gif +0 -0
  132. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/gifs/hooks.gif +0 -0
  133. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/gifs/install.gif +0 -0
  134. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/gifs/pulse.gif +0 -0
  135. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/gifs/search.gif +0 -0
  136. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/gifs/tap.gif +0 -0
  137. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/tapes/distill.tape +0 -0
  138. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/tapes/doctor.tape +0 -0
  139. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/tapes/explain.tape +0 -0
  140. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/tapes/hooks.tape +0 -0
  141. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/tapes/install.tape +0 -0
  142. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/tapes/pulse.tape +0 -0
  143. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/tapes/search.tape +0 -0
  144. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel/tapes/tap.tape +0 -0
  145. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/carousel.html +0 -0
  146. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/chat.html +0 -0
  147. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/commands.html +0 -0
  148. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/demo-index.json +0 -0
  149. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/demo.gif +0 -0
  150. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/demo.html +0 -0
  151. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/demo.tape +0 -0
  152. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/design-roadmap.html +0 -0
  153. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/eval-latest.json +0 -0
  154. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/eval.html +0 -0
  155. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/index.html +0 -0
  156. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/langchain.html +0 -0
  157. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/mcp-hub.html +0 -0
  158. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/rag-architecture.md +0 -0
  159. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D01.md +0 -0
  160. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D02.md +0 -0
  161. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D03.md +0 -0
  162. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D04.md +0 -0
  163. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D05.md +0 -0
  164. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D06.md +0 -0
  165. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D07.md +0 -0
  166. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D08.md +0 -0
  167. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D09.md +0 -0
  168. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D10.md +0 -0
  169. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D11.md +0 -0
  170. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D12.md +0 -0
  171. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D13.md +0 -0
  172. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D14.md +0 -0
  173. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D15.md +0 -0
  174. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D16.md +0 -0
  175. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D17.md +0 -0
  176. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D18.md +0 -0
  177. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D19.md +0 -0
  178. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D20.md +0 -0
  179. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D21.md +0 -0
  180. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D22.md +0 -0
  181. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D23.md +0 -0
  182. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D24.md +0 -0
  183. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D25.md +0 -0
  184. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/BOOST-D26.md +0 -0
  185. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/a11y-sweep-flakes-on-color-contrast.md +0 -0
  186. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  187. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
  188. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
  189. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/agents-field-records-the-request-not-the-links.md +0 -0
  190. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
  191. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
  192. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  193. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  194. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  195. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/bm25-index-is-one-json-blob.md +0 -0
  196. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/bmad-autopilot-one-command-persona-routing.md +0 -0
  197. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/boost-first-carried-the-losing-trigger.md +0 -0
  198. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/boost-first-rule.md +0 -0
  199. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/boost-langchain-publishing.md +0 -0
  200. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  201. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  202. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  203. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/browse-could-not-search-two-words.md +0 -0
  204. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  205. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  206. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  207. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  208. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/catalogue-entries-carry-no-content-identity.md +0 -0
  209. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/chat-cites-sources-by-a-number-it-never-prints.md +0 -0
  210. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/chat-command-grounded-conversational-search.md +0 -0
  211. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
  212. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
  213. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
  214. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  215. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
  216. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
  217. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/command-carousel-page.md +0 -0
  218. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  219. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/completions-complete-only-command-names.md +0 -0
  220. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/completions-install-could-eat-your-rc-file.md +0 -0
  221. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  222. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  223. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  224. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  225. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
  226. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  227. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/crash-reports-leak-api-keys.md +0 -0
  228. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
  229. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
  230. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/demo-workflow-cancels-other-prs.md +0 -0
  231. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
  232. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
  233. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
  234. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
  235. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/dependabot-splits-multi-path-action-repos.md +0 -0
  236. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  237. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/discover-searches-github-not-a-stale-sample.md +0 -0
  238. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
  239. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  240. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  241. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/dry-run-promised-a-link-nobody-makes.md +0 -0
  242. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/efficiency-registries-ponytail-caveman.md +0 -0
  243. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  244. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/est-items-counts-agent-mirrors-as-items.md +0 -0
  245. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/eval-corpus-cannot-see-real-retrieval.md +0 -0
  246. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/eval-corpus-is-96x-smaller-than-a-real-install.md +0 -0
  247. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/eval-corpus-is-one-strangers-repo.md +0 -0
  248. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/eval-corpus-pins-have-no-refresh-path.md +0 -0
  249. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/eval-corpus-was-not-actually-pinned.md +0 -0
  250. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/eval-deduped-ranked-lists-by-name.md +0 -0
  251. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/eval-stats-could-never-publish.md +0 -0
  252. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/expanded-card-bodies-overflow.md +0 -0
  253. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  254. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  255. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  256. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  257. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  258. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  259. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  260. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  261. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  262. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/gemini-agent-frontmatter-sanitizer.md +0 -0
  263. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
  264. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/github-community-health-files.md +0 -0
  265. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  266. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/golden-set-grades-by-name-not-by-skill.md +0 -0
  267. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  268. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  269. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/heal-deleted-links-it-never-made.md +0 -0
  270. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  271. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/info-rejects-the-qualified-name-it-recommends.md +0 -0
  272. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
  273. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
  274. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/install-path-disambiguation.md +0 -0
  275. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
  276. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  277. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
  278. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  279. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
  280. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  281. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
  282. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/keyless-dense-tier-local-static-embeddings.md +0 -0
  283. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/keyless-semantic-search-for-everyone.md +0 -0
  284. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/langchain-in-the-wheel.md +0 -0
  285. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/langchain-integration-explainer-page.md +0 -0
  286. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/langchain-langgraph-langsmith-integration.md +0 -0
  287. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/langchain-retriever-metadata-and-k-floor.md +0 -0
  288. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  289. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/license-compliance-scanning.md +0 -0
  290. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  291. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/lighthouse-scored-a-page-nobody-is-served.md +0 -0
  292. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
  293. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  294. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  295. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
  296. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  297. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  298. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  299. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
  300. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
  301. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
  302. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  303. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  304. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
  305. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-already-covered-defeater.md +0 -0
  306. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-aware-skills.md +0 -0
  307. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
  308. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  309. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
  310. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  311. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-one-benefit-nameable-task.md +0 -0
  312. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  313. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
  314. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-search-cost-was-understated.md +0 -0
  315. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-search-hid-which-ranking-ran.md +0 -0
  316. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +0 -0
  317. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  318. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mcp-zero-setup-and-three-kinds.md +0 -0
  319. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  320. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
  321. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
  322. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  323. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
  324. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  325. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  326. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  327. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
  328. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
  329. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/near-duplicate-items-eat-the-result-slots.md +0 -0
  330. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
  331. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
  332. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  333. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
  334. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/one-dead-tap-broke-every-update.md +0 -0
  335. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  336. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  337. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  338. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
  339. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/pep585-604-modernization-sweep.md +0 -0
  340. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  341. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
  342. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
  343. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  344. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  345. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/prerequisites-and-semantic-search-setup.md +0 -0
  346. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
  347. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
  348. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  349. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  350. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  351. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  352. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  353. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
  354. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
  355. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
  356. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/python-floor-moves-to-312.md +0 -0
  357. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  358. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/ragas-unpin-when-upstream-ships.md +0 -0
  359. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  360. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  361. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  362. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
  363. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
  364. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
  365. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/required-checks-config-drift.md +0 -0
  366. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/resolve-vendored-duplicate-copies.md +0 -0
  367. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  368. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  369. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
  370. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/roadmap-page-weight-grows-without-bound.md +0 -0
  371. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/roadmap-perf-budget-has-no-local-guard.md +0 -0
  372. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  373. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
  374. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  375. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/rules-install-but-cannot-be-governed.md +0 -0
  376. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  377. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  378. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  379. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
  380. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  381. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
  382. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  383. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
  384. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
  385. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/scripts-under-the-lint-gate.md +0 -0
  386. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/search-never-notices-a-new-tap.md +0 -0
  387. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  388. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  389. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  390. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  391. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
  392. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/self-update-claims-up-to-date-without-asking.md +0 -0
  393. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/serve-404-reflected-the-request.md +0 -0
  394. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/serve-is-a-searchable-catalogue.md +0 -0
  395. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
  396. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/shards-pipeline-never-produced-a-shard.md +0 -0
  397. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/shareable-catalogue-bundle.md +0 -0
  398. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  399. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  400. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  401. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  402. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  403. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  404. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
  405. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  406. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  407. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/sweep-died-at-launch-not-at-a-page.md +0 -0
  408. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/sync-could-not-repair-a-gutted-skill.md +0 -0
  409. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
  410. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
  411. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/sync-reported-success-for-a-link-it-refused.md +0 -0
  412. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  413. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/taps-check-out-freight-they-never-index.md +0 -0
  414. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/the-catalogue-advertised-repos-that-no-longer-exist.md +0 -0
  415. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  416. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/tool-call-eval-tier.md +0 -0
  417. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/two-crashes-that-should-have-been-messages.md +0 -0
  418. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  419. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  420. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  421. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
  422. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  423. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/unwatched-crons-hid-a-real-fuzz-crash.md +0 -0
  424. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/update-advertises-a-flag-it-rejects.md +0 -0
  425. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  426. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/update-refreshed-rules-without-a-gate.md +0 -0
  427. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  428. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
  429. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  430. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  431. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  432. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
  433. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  434. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  435. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  436. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/workspace-scope-install.md +0 -0
  437. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/zip-strict-audit.md +0 -0
  438. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/zizmor-ignores-drift-and-make-lint-never-ran-it.md +0 -0
  439. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
  440. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/docs/superpowers/specs/2026-08-16-catalogue-content-identity-design.md +0 -0
  441. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/eslint.config.mjs +0 -0
  442. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/evals/README.md +0 -0
  443. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/evals/__init__.py +0 -0
  444. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/evals/baseline.json +0 -0
  445. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/evals/faithfulness.py +0 -0
  446. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/evals/golden_set.json +0 -0
  447. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/evals/make_corpus.py +0 -0
  448. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/evals/make_golden.py +0 -0
  449. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/evals/metrics.py +0 -0
  450. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/evals/publish_golden_dataset.py +0 -0
  451. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/evals/run_evals.py +0 -0
  452. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/examples/README.md +0 -0
  453. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/examples/adapt-demo.sh +0 -0
  454. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/examples/boost-run-prototype.sh +0 -0
  455. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/index.html +0 -0
  456. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/noxfile.py +0 -0
  457. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/pyproject.toml +0 -0
  458. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/requirements/coverage-tools.in +0 -0
  459. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/requirements/coverage-tools.txt +0 -0
  460. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/requirements/lint-tools.in +0 -0
  461. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/requirements/lint-tools.txt +0 -0
  462. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/requirements/mutation-tools.in +0 -0
  463. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/requirements/mutation-tools.txt +0 -0
  464. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/requirements/platform-pins.lock +0 -0
  465. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/requirements/release-tools.in +0 -0
  466. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/requirements/release-tools.txt +0 -0
  467. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/requirements/test-tools.in +0 -0
  468. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/requirements/test-tools.txt +0 -0
  469. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/a11y_check.py +0 -0
  470. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/bench_cli.sh +0 -0
  471. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/build_command_reference.py +0 -0
  472. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/build_demo_index.py +0 -0
  473. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/build_registries.py +0 -0
  474. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/build_roadmap.py +0 -0
  475. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/build_scale_corpus.py +0 -0
  476. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/check_anchors.py +0 -0
  477. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/check_licenses.py +0 -0
  478. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/check_required_checks.py +0 -0
  479. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/ensure_eval_corpus.sh +0 -0
  480. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/eval_corpus.py +0 -0
  481. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/eval_explain.py +0 -0
  482. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/eval_gate.py +0 -0
  483. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/eval_recommend.py +0 -0
  484. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/eval_retrieval.py +0 -0
  485. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/eval_stats_summary.py +0 -0
  486. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/import_budget.py +0 -0
  487. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/lock_toolchain.py +0 -0
  488. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/measure_registry.py +0 -0
  489. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/mutation_gate.py +0 -0
  490. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/mutation_shards.py +0 -0
  491. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/mutation_weights.json +0 -0
  492. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/page_budget.py +0 -0
  493. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/perf_gate.py +0 -0
  494. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/post_deploy_smoke.py +0 -0
  495. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/publish_eval_json.py +0 -0
  496. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/release_guard.py +0 -0
  497. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/release_preflight.py +0 -0
  498. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/scripts/serve_docs.py +0 -0
  499. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/setup.cfg +0 -0
  500. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/sonar-project.properties +0 -0
  501. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/style/README.md +0 -0
  502. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/style/boost.css +0 -0
  503. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/style/boost.js +0 -0
  504. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/style/demo.html +0 -0
  505. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/adapt.feature +0 -0
  506. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/browse.feature +0 -0
  507. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/count.feature +0 -0
  508. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/discover.feature +0 -0
  509. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/doctor.feature +0 -0
  510. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/environment.py +0 -0
  511. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/explain.feature +0 -0
  512. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/index.feature +0 -0
  513. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/install.feature +0 -0
  514. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/list.feature +0 -0
  515. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/mcp.feature +0 -0
  516. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/search.feature +0 -0
  517. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/steps/cli_steps.py +0 -0
  518. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/steps/discovery_steps.py +0 -0
  519. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/steps/mcp_steps.py +0 -0
  520. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/bdd/features/steps/quality_steps.py +0 -0
  521. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/conftest.py +0 -0
  522. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/eval/baseline.json +0 -0
  523. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/eval/explain.jsonl +0 -0
  524. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/eval/golden-natural.jsonl +0 -0
  525. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/eval/golden.jsonl +0 -0
  526. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/eval/recommend.jsonl +0 -0
  527. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/eval/taps-scale.txt +0 -0
  528. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/eval/taps.txt +0 -0
  529. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_capabilities_policy.py +0 -0
  530. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_adapt.py +0 -0
  531. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_bmad.py +0 -0
  532. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_catalog.py +0 -0
  533. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_chat.py +0 -0
  534. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_configuration.py +0 -0
  535. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_discovery.py +0 -0
  536. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_hooks.py +0 -0
  537. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_info.py +0 -0
  538. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_intelligence.py +0 -0
  539. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_pkg.py +0 -0
  540. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_quality.py +0 -0
  541. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_taps.py +0 -0
  542. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_cli_team.py +0 -0
  543. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_everyday_loop.py +0 -0
  544. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_integrity_enforce.py +0 -0
  545. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_kind_conformance.py +0 -0
  546. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_property_parsers.py +0 -0
  547. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_run.py +0 -0
  548. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_tap_signing.py +0 -0
  549. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/functional/test_workspace_scope.py +0 -0
  550. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/README.md +0 -0
  551. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
  552. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
  553. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
  554. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
  555. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
  556. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
  557. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
  558. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
  559. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
  560. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
  561. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
  562. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
  563. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
  564. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/registry/02-https.txt +0 -0
  565. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
  566. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
  567. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
  568. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/registry/06-space.txt +0 -0
  569. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
  570. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
  571. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/fuzz_frontmatter.py +0 -0
  572. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/fuzz/fuzz_registry.py +0 -0
  573. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/langchain/conftest.py +0 -0
  574. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/langchain/test_graph.py +0 -0
  575. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/langchain/test_loader.py +0 -0
  576. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/langchain/test_retriever.py +0 -0
  577. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/make_fixture.py +0 -0
  578. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/perf/test_benchmarks.py +0 -0
  579. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/smoke.sh +0 -0
  580. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_a11y_check.py +0 -0
  581. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_action_pin_lockstep.py +0 -0
  582. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_adapters.py +0 -0
  583. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_adapters_multi.py +0 -0
  584. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_adapters_runner.py +0 -0
  585. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_agents.py +0 -0
  586. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_ai.py +0 -0
  587. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_bmad_core.py +0 -0
  588. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_boost_first_offer.py +0 -0
  589. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_bootstrap.py +0 -0
  590. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_browse.py +0 -0
  591. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_builtin.py +0 -0
  592. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_capabilities.py +0 -0
  593. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_catalog.py +0 -0
  594. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_catalogbundle.py +0 -0
  595. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_chat.py +0 -0
  596. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_check_anchors.py +0 -0
  597. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_check_licenses.py +0 -0
  598. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_claude_settings.py +0 -0
  599. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_clean_internal_cache.py +0 -0
  600. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_cliparse.py +0 -0
  601. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_codeql_analysis_key.py +0 -0
  602. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_command_reference_fresh.py +0 -0
  603. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_community_health_files.py +0 -0
  604. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_compact.py +0 -0
  605. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_complete.py +0 -0
  606. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_complete_rc_block.py +0 -0
  607. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_config.py +0 -0
  608. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_content_dedupe.py +0 -0
  609. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_content_identity.py +0 -0
  610. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_crash_redaction.py +0 -0
  611. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_dedup_trust.py +0 -0
  612. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_demo_index.py +0 -0
  613. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_dense.py +0 -0
  614. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_dense_embed_dedupe.py +0 -0
  615. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_dense_fallback.py +0 -0
  616. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_dense_fix_hint.py +0 -0
  617. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_dense_shard_real_schema.py +0 -0
  618. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_dense_shard_unreadable_vectors.py +0 -0
  619. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_dense_shards.py +0 -0
  620. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_dense_status.py +0 -0
  621. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_dependabot_config.py +0 -0
  622. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_docs_pages_linked.py +0 -0
  623. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_docsite_chrome.py +0 -0
  624. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_ed25519.py +0 -0
  625. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_embed.py +0 -0
  626. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_embed_local.py +0 -0
  627. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_embed_truncated_response.py +0 -0
  628. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_entry_key.py +0 -0
  629. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_errors_and_cli_table.py +0 -0
  630. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_eval_baseline.py +0 -0
  631. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_eval_corpus.py +0 -0
  632. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_eval_faithfulness.py +0 -0
  633. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_eval_gate.py +0 -0
  634. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_eval_grading.py +0 -0
  635. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_eval_metrics.py +0 -0
  636. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_eval_stats_summary.py +0 -0
  637. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_failure_alerting_covers_unattended.py +0 -0
  638. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_faithfulness.py +0 -0
  639. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_frontmatter.py +0 -0
  640. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_fuzz_targets.py +0 -0
  641. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_gemini_agent_sanitize.py +0 -0
  642. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_gitleaks_config.py +0 -0
  643. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_gitutil.py +0 -0
  644. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_gitutil_lfs.py +0 -0
  645. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_gitutil_sparse.py +0 -0
  646. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_imperative.py +0 -0
  647. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_import_budget.py +0 -0
  648. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_injectscan.py +0 -0
  649. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_install_permission_error.py +0 -0
  650. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_installscan.py +0 -0
  651. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_integrity.py +0 -0
  652. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_journal.py +0 -0
  653. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_langchain_packaging.py +0 -0
  654. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_link_ownership.py +0 -0
  655. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_localembed.py +0 -0
  656. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_localembed_e2e.py +0 -0
  657. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_lockfile.py +0 -0
  658. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_logs.py +0 -0
  659. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_marketing_counts.py +0 -0
  660. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_mcp.py +0 -0
  661. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_mcp_install_scan.py +0 -0
  662. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_mcpdecl.py +0 -0
  663. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_mcphost.py +0 -0
  664. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_measure_registry.py +0 -0
  665. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_minisign.py +0 -0
  666. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_mutation_hardening.py +0 -0
  667. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_mutation_shards.py +0 -0
  668. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_mutation_subfile_shards.py +0 -0
  669. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_mutmut_source_paths.py +0 -0
  670. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_nethttp.py +0 -0
  671. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_output.py +0 -0
  672. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_page_budget.py +0 -0
  673. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_paths.py +0 -0
  674. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_perf_gate.py +0 -0
  675. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_pkg_confusions.py +0 -0
  676. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_pkg_injection.py +0 -0
  677. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_pkg_secrets.py +0 -0
  678. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_platform_pins.py +0 -0
  679. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_policy.py +0 -0
  680. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_post_deploy_smoke.py +0 -0
  681. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_project_mcp_sidecar.py +0 -0
  682. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_projectlock.py +0 -0
  683. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_provenance.py +0 -0
  684. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_publish_golden_dataset.py +0 -0
  685. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_rag.py +0 -0
  686. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_rag_fusion.py +0 -0
  687. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_registries_fresh.py +0 -0
  688. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_registry.py +0 -0
  689. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_registry_categories.py +0 -0
  690. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_release_guard.py +0 -0
  691. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_release_preflight.py +0 -0
  692. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_required_checks.py +0 -0
  693. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_resolve.py +0 -0
  694. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_roadmap_fresh.py +0 -0
  695. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_rules.py +0 -0
  696. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_scale_corpus.py +0 -0
  697. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_scopes.py +0 -0
  698. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_secretscan.py +0 -0
  699. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_selfupdate.py +0 -0
  700. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_serve.py +0 -0
  701. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_serve_docs.py +0 -0
  702. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_shards_matrix.py +0 -0
  703. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_smoke_covers_every_command.py +0 -0
  704. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_spin.py +0 -0
  705. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_stackprobe.py +0 -0
  706. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_staleness.py +0 -0
  707. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_store.py +0 -0
  708. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_store_materialize.py +0 -0
  709. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_sync_blocked_links.py +0 -0
  710. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_sync_repairs_gutted_skill.py +0 -0
  711. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_token_parity.py +0 -0
  712. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_toolchain_lock.py +0 -0
  713. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_trustaudit.py +0 -0
  714. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_typosquat.py +0 -0
  715. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_updatediff.py +0 -0
  716. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_util.py +0 -0
  717. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_version.py +0 -0
  718. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_visual_harness_flags.py +0 -0
  719. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_workflow_concurrency.py +0 -0
  720. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_workflow_concurrency_groups.py +0 -0
  721. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_workflow_push_has_credentials.py +0 -0
  722. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_workflow_timeouts.py +0 -0
  723. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_workflows.py +0 -0
  724. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/unit/test_zizmor_ignores_still_anchor.py +0 -0
  725. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/visual/a11y_check.mjs +0 -0
  726. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/visual/console_check.mjs +0 -0
  727. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/visual/package-lock.json +0 -0
  728. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/tests/visual/package.json +0 -0
  729. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.6}/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.2.5
3
+ Version: 1.2.6
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.2.5'
22
- __version_tuple__ = version_tuple = (1, 2, 5)
21
+ __version__ = version = '1.2.6'
22
+ __version_tuple__ = version_tuple = (1, 2, 6)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -37,6 +37,29 @@ class Tap:
37
37
  return self.path.is_dir()
38
38
 
39
39
 
40
+ # One path component, in BYTES. ext4, APFS and NTFS all stop at 255, and
41
+ # `Tap.safe_name` maps "/" to "__" — so the whole tap name becomes exactly one
42
+ # component under `~/.boost/repos` and this is its ceiling. A GitHub owner/repo
43
+ # maxes out at 140 (39 + 1 + 100), so nothing real comes near it.
44
+ MAX_NAME_BYTES = 255
45
+
46
+
47
+ def _looks_like_a_directory(p: Path) -> bool:
48
+ """True if `p` is an existing directory, False if the OS will not say.
49
+
50
+ `Path.exists()` is not total. pathlib swallows ENOENT, ENOTDIR, EBADF and
51
+ ELOOP — ENAMETOOLONG is *not* in that set, so a long enough component makes
52
+ `os.stat` raise straight out of `parse_spec` as a bare OSError, which is not
53
+ a BoostError and so is never framed by the CLI's error handling. A path the
54
+ OS refuses to look at is not a directory we can tap; that is a "no", not a
55
+ crash.
56
+ """
57
+ try:
58
+ return p.is_dir()
59
+ except OSError:
60
+ return False
61
+
62
+
40
63
  def parse_spec(spec: str):
41
64
  """Resolve a tap spec -> (name, url).
42
65
 
@@ -61,18 +84,35 @@ def parse_spec(spec: str):
61
84
  # own home-dir lookup (USERPROFILE on Windows), which ignores the $HOME
62
85
  # override the whole test suite (and BOOST_HOME sandboxing) relies on.
63
86
  p = paths.expand(spec)
64
- if p.exists() and p.is_dir():
65
- return (p.resolve().name, str(p.resolve()))
87
+ if _looks_like_a_directory(p):
88
+ return _checked(p.resolve().name, str(p.resolve()), spec)
66
89
  if spec.startswith(("http://", "https://", "git@", "ssh://")):
67
90
  tail = spec.split(":")[-1] if spec.startswith("git@") else spec
68
91
  parts = [x for x in tail.replace(".git", "").split("/") if x][-2:]
69
- return ("/".join(parts), spec)
92
+ return _checked("/".join(parts), spec, spec)
70
93
  if "/" in spec and " " not in spec:
71
- return (spec, "https://github.com/%s" % spec)
94
+ return _checked(spec, "https://github.com/%s" % spec, spec)
72
95
  raise BoostError("cannot parse tap spec %r" % spec,
73
96
  hint="use owner/repo, a git URL, or a local directory")
74
97
 
75
98
 
99
+ def _checked(name: str, url: str, spec: str) -> tuple[str, str]:
100
+ """The derived pair, or a BoostError if the name cannot be a directory.
101
+
102
+ The rule is on the *name*, never on the spec: a deep local path with a short
103
+ basename is a perfectly good tap, and its own length says nothing about the
104
+ component we are about to create. Caught here rather than at clone time,
105
+ where it surfaces as git's own ENAMETOOLONG on a path the user never typed.
106
+ """
107
+ if len(name.encode("utf-8")) > MAX_NAME_BYTES:
108
+ raise BoostError(
109
+ "tap name is too long (%d bytes, limit %d): %r"
110
+ % (len(name.encode("utf-8")), MAX_NAME_BYTES, spec[:80]),
111
+ hint="the name becomes one directory under ~/.boost/repos, and "
112
+ "no filesystem accepts a longer component")
113
+ return (name, url)
114
+
115
+
76
116
  def list_taps() -> list[Tap]:
77
117
  """Configured taps from config.json.
78
118
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.2.5
3
+ Version: 1.2.6
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -335,6 +335,7 @@ docs/roadmap/items/one-shared-atomic-write-helper.md
335
335
  docs/roadmap/items/package-metadata-validation-twine-check-friends.md
336
336
  docs/roadmap/items/patch-coverage-gate-diff-cover.md
337
337
  docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md
338
+ docs/roadmap/items/pathlib-exists-is-not-total.md
338
339
  docs/roadmap/items/pep585-604-modernization-sweep.md
339
340
  docs/roadmap/items/performance-regression-gate-pytest-benchmark.md
340
341
  docs/roadmap/items/pin-the-lint-toolchain.md
@@ -565,6 +566,9 @@ tests/fuzz/corpus/registry/05-empty.txt
565
566
  tests/fuzz/corpus/registry/06-space.txt
566
567
  tests/fuzz/corpus/registry/07-slash.txt
567
568
  tests/fuzz/corpus/registry/08-bare-host.txt
569
+ tests/fuzz/corpus/registry/09-nul.txt
570
+ tests/fuzz/corpus/registry/10-name-too-long.txt
571
+ tests/fuzz/corpus/registry/11-long-owner-repo.txt
568
572
  tests/langchain/conftest.py
569
573
  tests/langchain/test_graph.py
570
574
  tests/langchain/test_loader.py
@@ -0,0 +1,48 @@
1
+ ---
2
+ id: pathlib-exists-is-not-total
3
+ board: code
4
+ section: internals
5
+ status: shipped
6
+ category: Bug
7
+ complexity: S
8
+ impact: Medium
9
+ wow: 4
10
+ note: the weekly fuzzer has now found two crashes in one function, three weeks apart, and been ignored both times
11
+ order: 118
12
+ owner: fix/tap-spec-name-too-long
13
+ pr: 528
14
+ title: <code>Path.exists()</code> looks total, and is not
15
+ ---
16
+ <b><code>boost tap &lt;anything long enough&gt;</code> died with a raw traceback on Linux.</b>
17
+ <code>parse_spec</code> probes whether the spec names an existing directory, and
18
+ <code>pathlib</code> swallows only <b>ENOENT, ENOTDIR, EBADF and ELOOP</b> &mdash;
19
+ <b>ENAMETOOLONG is not in that set</b>. So on any filesystem with a 255-byte component limit, which
20
+ is to say ext4 and therefore every Linux runner and most users, <code>os.stat</code> raises straight
21
+ out through <code>parse_spec</code> as a bare <code>OSError</code>. Not a <code>BoostError</code>,
22
+ so the CLI's error handling never got to frame it.
23
+
24
+ <b>macOS does not reproduce it.</b> That is the whole reason it shipped: the only thing that ever saw
25
+ it was the scheduled Linux fuzz job.
26
+
27
+ <b>Which had been reporting it for three weeks.</b> <code>fuzz.yml</code> runs libFuzzer over
28
+ <code>parse_spec</code> weekly and has now failed <b>four scheduled runs out of four</b>. The first
29
+ three were one bug &mdash; an embedded NUL &mdash; found on 2026-07-25, 08-01 and 08-08 and fixed
30
+ after the third. The fourth, on 08-15, is this one, minimised to 91 bytes: <code>0x38</code>
31
+ followed by ninety <code>0xff</code>, each un-decodable and so each becoming U+FFFD, which is
32
+ <b>three</b> UTF-8 bytes apiece &mdash; <b>271 bytes</b> from an input only 91 characters long.
33
+
34
+ <b>The limit is on bytes, and on the derived name.</b> Measuring characters would have let exactly
35
+ this input through. Measuring the <em>spec</em> would have turned away a legitimate deep local path
36
+ whose basename is short, so the rule applies to the name that is about to become one directory under
37
+ <code>~/.boost/repos</code>, caught at the parse boundary rather than at clone time where it
38
+ resurfaces as git's own ENAMETOOLONG on a path the user never typed.
39
+
40
+ <b>Rejecting is only half of it.</b> A path the OS refuses to <em>look at</em> is a &ldquo;no&rdquo;,
41
+ not a crash, so the probe is now total by construction &mdash; and pinned by a test on every
42
+ platform, not only the one where it fails, because a test that needs a real over-long path proves
43
+ nothing on the machine most of this is written on.
44
+
45
+ <b>Both reproducers are now seeds.</b> The NUL one was fixed and never added to the corpus, so
46
+ the fuzzer was free to spend runs rediscovering it. <code>tests/fuzz/corpus/registry/</code> carries
47
+ both, which means the no-atheris seed smoke &mdash; the path that runs without the fuzzer installed
48
+ &mdash; is now a regression test for both.
@@ -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>255</b><span>Loop finds</span></div>
136
+ <div class="stat"><b>256</b><span>Loop finds</span></div>
137
137
  <!-- /ROADMAP:stats -->
138
138
  </div>
139
139
  </section>
@@ -4120,6 +4120,51 @@ separately for the same reason.</p></details>
4120
4120
  <span class="m">a scheduled gate had never once passed, and the reason was one deleted upstream in its pinned corpus</span>
4121
4121
  </div>
4122
4122
  </article>
4123
+
4124
+ <article class="cap rcard" id="pathlib-exists-is-not-total">
4125
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Bug</span></div>
4126
+ <h3><code>Path.exists()</code> looks total, and is not</h3>
4127
+ <details class="cardbody"><summary>Write-up</summary>
4128
+ <p><b><code>boost tap &lt;anything long enough&gt;</code> died with a raw traceback on Linux.</b>
4129
+ <code>parse_spec</code> probes whether the spec names an existing directory, and
4130
+ <code>pathlib</code> swallows only <b>ENOENT, ENOTDIR, EBADF and ELOOP</b> &mdash;
4131
+ <b>ENAMETOOLONG is not in that set</b>. So on any filesystem with a 255-byte component limit, which
4132
+ is to say ext4 and therefore every Linux runner and most users, <code>os.stat</code> raises straight
4133
+ out through <code>parse_spec</code> as a bare <code>OSError</code>. Not a <code>BoostError</code>,
4134
+ so the CLI's error handling never got to frame it.
4135
+
4136
+ <b>macOS does not reproduce it.</b> That is the whole reason it shipped: the only thing that ever saw
4137
+ it was the scheduled Linux fuzz job.
4138
+
4139
+ <b>Which had been reporting it for three weeks.</b> <code>fuzz.yml</code> runs libFuzzer over
4140
+ <code>parse_spec</code> weekly and has now failed <b>four scheduled runs out of four</b>. The first
4141
+ three were one bug &mdash; an embedded NUL &mdash; found on 2026-07-25, 08-01 and 08-08 and fixed
4142
+ after the third. The fourth, on 08-15, is this one, minimised to 91 bytes: <code>0x38</code>
4143
+ followed by ninety <code>0xff</code>, each un-decodable and so each becoming U+FFFD, which is
4144
+ <b>three</b> UTF-8 bytes apiece &mdash; <b>271 bytes</b> from an input only 91 characters long.
4145
+
4146
+ <b>The limit is on bytes, and on the derived name.</b> Measuring characters would have let exactly
4147
+ this input through. Measuring the <em>spec</em> would have turned away a legitimate deep local path
4148
+ whose basename is short, so the rule applies to the name that is about to become one directory under
4149
+ <code>~/.boost/repos</code>, caught at the parse boundary rather than at clone time where it
4150
+ resurfaces as git's own ENAMETOOLONG on a path the user never typed.
4151
+
4152
+ <b>Rejecting is only half of it.</b> A path the OS refuses to <em>look at</em> is a &ldquo;no&rdquo;,
4153
+ not a crash, so the probe is now total by construction &mdash; and pinned by a test on every
4154
+ platform, not only the one where it fails, because a test that needs a real over-long path proves
4155
+ nothing on the machine most of this is written on.
4156
+
4157
+ <b>Both reproducers are now seeds.</b> The NUL one was fixed and never added to the corpus, so
4158
+ the fuzzer was free to spend runs rediscovering it. <code>tests/fuzz/corpus/registry/</code> carries
4159
+ both, which means the no-atheris seed smoke &mdash; the path that runs without the fuzzer installed
4160
+ &mdash; is now a regression test for both.</p></details>
4161
+ <div class="meta">
4162
+ <span class="m">Complexity <b>S</b></span>
4163
+ <span class="m">Impact <b>Medium</b></span>
4164
+ <span class="m">Wow <b class="wow">★★★★</b></span>
4165
+ <span class="m">the weekly fuzzer has now found two crashes in one function, three weeks apart, and been ignored both times</span>
4166
+ </div>
4167
+ </article>
4123
4168
  <!-- /ROADMAP:cards -->
4124
4169
 
4125
4170
  </div>
@@ -0,0 +1 @@
1
+ 8������������������������������������������������������������������������������������������
@@ -0,0 +1 @@
1
+ owner/rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
@@ -0,0 +1,233 @@
1
+ """Unit tests: a tap spec carrying control characters is rejected at the door.
2
+
3
+ `parse_spec` used to accept them. Given the ten bytes ``/\\0\\0\\0\\0\\0\\0\\0\\0A`` it
4
+ returned a perfectly well-formed pair::
5
+
6
+ ('/\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00A',
7
+ 'https://github.com//\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00A')
8
+
9
+ Nothing raised, so the name travelled onward — into ``config.json``, into
10
+ ``Tap.safe_name``, and eventually into a filesystem call, where it died as
11
+ ``ValueError: lstat: embedded null character in path`` from deep inside
12
+ ``posixpath.realpath``. That message names neither the tap nor the command, and
13
+ ``ValueError`` is not ``BoostError``, so the CLI's error handling never got to
14
+ frame it.
15
+
16
+ This is how the repo found out: ``fuzz.yml`` runs libFuzzer over ``parse_spec``
17
+ weekly, and it has failed **three scheduled runs out of three** — 2026-07-25,
18
+ 08-01 and 08-08 — writing the same reproducer each time. Nobody noticed, because
19
+ ``ci-failure-issue.yml`` watches only ``["ci", "demo"]``, so a red cron job is a
20
+ red square on a page nobody opens. The fuzzer had been right for three weeks.
21
+
22
+ A control character can never appear in a GitHub owner/repo, a git URL, or a
23
+ usable directory name, so there is no input this rejects that anyone wanted.
24
+ Rejecting at the parse boundary turns an arbitrary later ``ValueError`` into the
25
+ documented ``BoostError`` rejection path — which the fuzz harness already
26
+ handles, and which the CLI already renders with a hint.
27
+ """
28
+ from __future__ import annotations
29
+
30
+ import pytest
31
+
32
+ from boost_cli.core import registry
33
+ from boost_cli.errors import BoostError
34
+
35
+ #: The exact ten bytes libFuzzer minimised to, decoded the way the harness does.
36
+ CRASHER = "/\x00\x00\x00\x00\x00\x00\x00\x00A"
37
+
38
+
39
+ class TestControlCharactersAreRejected:
40
+ def test_the_fuzzer_reproducer_raises_boost_error(self):
41
+ with pytest.raises(BoostError):
42
+ registry.parse_spec(CRASHER)
43
+
44
+ def test_a_bare_nul_is_rejected(self):
45
+ with pytest.raises(BoostError):
46
+ registry.parse_spec("owner/re\x00po")
47
+
48
+ @pytest.mark.parametrize("ch", ["\x00", "\x01", "\x07", "\x1b", "\x7f"])
49
+ def test_every_control_character_is_rejected(self, ch):
50
+ # \x1b in particular: an escape sequence in a name is echoed back by
51
+ # every surface that prints a tap list.
52
+ with pytest.raises(BoostError):
53
+ registry.parse_spec("owner/re%spo" % ch)
54
+
55
+ def test_the_error_names_the_problem(self):
56
+ with pytest.raises(BoostError) as caught:
57
+ registry.parse_spec(CRASHER)
58
+ assert "control character" in str(caught.value).lower()
59
+
60
+ def test_a_newline_or_tab_is_rejected_too(self):
61
+ # These survive `.strip()` when they are in the middle, and a newline in
62
+ # a tap name breaks every line-oriented output in the CLI.
63
+ for spec in ("owner/re\npo", "owner/re\tpo"):
64
+ with pytest.raises(BoostError):
65
+ registry.parse_spec(spec)
66
+
67
+
68
+ #: The 91 bytes libFuzzer minimised to on 2026-08-15, decoded the way the
69
+ #: harness does: `0x38` then ninety `0xff`, each of which is un-decodable and so
70
+ #: becomes U+FFFD — three UTF-8 bytes apiece, 271 bytes for the name alone.
71
+ TOO_LONG = "8" + "�" * 90
72
+
73
+
74
+ class TestAnOverlongSpecIsRejected:
75
+ """The second thing the fuzzer found, and the same shape as the first.
76
+
77
+ ``p.exists()`` looks total and is not. ``pathlib`` swallows only ENOENT,
78
+ ENOTDIR, EBADF and ELOOP; **ENAMETOOLONG is not in that set**, so on a
79
+ filesystem with a 255-byte component limit — ext4, which is to say every
80
+ Linux runner and most users — a long enough spec makes ``os.stat`` raise
81
+ straight through ``parse_spec``. macOS does not reproduce it, which is why
82
+ only the scheduled Linux fuzz job ever saw it.
83
+
84
+ Rejecting is not the whole fix. A *legitimate* long path (a deep directory
85
+ with a short basename) must still parse, so the probe treats "too long for
86
+ this OS" as "not an existing directory" and the length rule applies to the
87
+ derived NAME, which is what becomes a single component under
88
+ ``~/.boost/repos``.
89
+ """
90
+
91
+ def test_the_fuzzer_reproducer_raises_boost_error(self):
92
+ with pytest.raises(BoostError):
93
+ registry.parse_spec(TOO_LONG)
94
+
95
+ def test_an_overlong_owner_repo_is_rejected(self):
96
+ """Plain ASCII reaches the same limit, it just takes 256 of them."""
97
+ with pytest.raises(BoostError):
98
+ registry.parse_spec("owner/" + "r" * 300)
99
+
100
+ def test_the_error_names_the_problem(self):
101
+ """Only for a spec that *parses* — the fuzzer's own reproducer carries
102
+ no separator, so it is rejected as unparseable and never reaches the
103
+ length rule. Both paths raise BoostError, which is the invariant; this
104
+ pins the message on the one where length is the actual reason."""
105
+ with pytest.raises(BoostError) as caught:
106
+ registry.parse_spec("owner/" + "r" * 300)
107
+ assert "too long" in str(caught.value).lower()
108
+
109
+ def test_the_limit_is_on_bytes_not_characters(self):
110
+ """A component limit is a *byte* limit, and non-ASCII costs more.
111
+
112
+ 90 characters is nothing; 90 U+FFFD is 270 bytes and does not fit.
113
+ Measuring characters would let exactly the fuzzer's input through.
114
+ """
115
+ assert len(TOO_LONG) < 255 < len(TOO_LONG.encode("utf-8"))
116
+ with pytest.raises(BoostError):
117
+ registry.parse_spec(TOO_LONG)
118
+
119
+ def test_a_probe_that_cannot_stat_is_not_an_existing_directory(self, tmp_path):
120
+ """The OS refusing to look is a "no", not a crash.
121
+
122
+ This is the assertion that actually fails on Linux without the fix:
123
+ the spec is a path shape, so it reaches the filesystem probe before any
124
+ length rule could have rejected it.
125
+ """
126
+ spec = str(tmp_path / ("d" * 400))
127
+ with pytest.raises(BoostError):
128
+ registry.parse_spec(spec)
129
+
130
+ def test_a_stat_that_raises_reads_as_not_a_directory(self):
131
+ """Pinned on every platform, because it only *fails* on one.
132
+
133
+ macOS returns False where Linux raises ENAMETOOLONG, so a test that
134
+ relies on a real long path proves nothing on the machine most of this
135
+ is written on — and this bug reached production precisely because the
136
+ scheduled Linux job was the only thing that ever saw it.
137
+ """
138
+ class Raises:
139
+ def is_dir(self):
140
+ raise OSError(36, "File name too long")
141
+
142
+ assert registry._looks_like_a_directory(Raises()) is False
143
+
144
+ def test_a_stat_that_succeeds_is_still_a_directory(self, tmp_path):
145
+ """The guard must not swallow the answer it exists to return."""
146
+ assert registry._looks_like_a_directory(tmp_path) is True
147
+ assert registry._looks_like_a_directory(tmp_path / "nope") is False
148
+
149
+ def test_the_rejection_carries_a_hint(self):
150
+ """A BoostError with no hint is the CLI printing a dead end.
151
+
152
+ Every other rejection in `parse_spec` says what to do instead, and this
153
+ one has something specific to say: the name is about to become a
154
+ directory, which is why the limit is what it is.
155
+ """
156
+ with pytest.raises(BoostError) as caught:
157
+ registry.parse_spec("owner/" + "r" * 300)
158
+ assert caught.value.hint
159
+ assert "~/.boost/repos" in caught.value.hint
160
+
161
+ def test_a_url_whose_derived_name_is_too_long_names_the_spec(self):
162
+ """The URL branch derives a name too, and the error must be traceable
163
+ back to what the user typed rather than to the name we computed."""
164
+ with pytest.raises(BoostError) as caught:
165
+ registry.parse_spec("https://github.com/owner/" + "r" * 300)
166
+ assert "owner" in str(caught.value)
167
+
168
+ def test_a_long_path_with_a_short_basename_still_parses(self, tmp_path):
169
+ """The rule is about the derived name, never the spec's own length."""
170
+ deep = tmp_path
171
+ for _ in range(6):
172
+ deep = deep / ("segment-" + "x" * 30)
173
+ deep = deep / "my-tap"
174
+ deep.mkdir(parents=True)
175
+ assert len(str(deep)) > 255
176
+ name, url = registry.parse_spec(str(deep))
177
+ assert name == "my-tap"
178
+ assert url == str(deep.resolve())
179
+
180
+ def test_a_name_at_the_limit_is_still_accepted(self):
181
+ """Reject one byte over, not one byte under — the boundary is pinned
182
+ because an off-by-one here silently turns away a legal repo name."""
183
+ name = "o" * 100 + "/" + "r" * 154 # 255 bytes exactly
184
+ assert len(name.encode("utf-8")) == 255
185
+ assert registry.parse_spec(name)[0] == name
186
+
187
+
188
+ class TestOrdinarySpecsStillParse:
189
+ """The rejection must not widen. Each of these is a documented input."""
190
+
191
+ def test_owner_repo(self):
192
+ assert registry.parse_spec("anthropics/skills") == (
193
+ "anthropics/skills", "https://github.com/anthropics/skills")
194
+
195
+ def test_an_https_url(self):
196
+ name, url = registry.parse_spec("https://github.com/acme/skills")
197
+ assert name == "acme/skills" and url.startswith("https://")
198
+
199
+ def test_an_ssh_url(self):
200
+ name, _url = registry.parse_spec("git@github.com:acme/skills.git")
201
+ assert name == "acme/skills"
202
+
203
+ def test_a_local_directory(self, tmp_path):
204
+ target = tmp_path / "my-skills"
205
+ target.mkdir()
206
+ name, url = registry.parse_spec(str(target))
207
+ assert name == "my-skills" and url == str(target.resolve())
208
+
209
+ def test_surrounding_whitespace_is_still_only_stripped(self):
210
+ # Leading/trailing whitespace is trimmed, not rejected — that is a
211
+ # paste artifact, not a hostile name, and it always worked.
212
+ assert registry.parse_spec(" acme/skills ")[0] == "acme/skills"
213
+
214
+ def test_a_unicode_name_is_not_a_control_character(self):
215
+ # Non-ASCII is legal in a path and must not be caught by this net.
216
+ assert registry.parse_spec("acmé/skïlls")[0] == "acmé/skïlls"
217
+
218
+
219
+ class TestTheDerivedPathIsNowAlwaysUsable:
220
+ """The property the fuzz harness asserts, and could not reach before.
221
+
222
+ Its containment check calls ``os.path.realpath`` on the derived clone
223
+ directory. That is what raised — so the harness could never even evaluate
224
+ the invariant it exists to protect.
225
+ """
226
+
227
+ def test_realpath_of_the_derived_path_no_longer_raises(self):
228
+ import os
229
+ with pytest.raises(BoostError):
230
+ name, url = registry.parse_spec(CRASHER)
231
+ # Unreachable once parse_spec rejects; kept so this test fails
232
+ # loudly rather than silently if the rejection is ever removed.
233
+ os.path.realpath(str(registry.Tap(name=name, url=url).path))
@@ -1,113 +0,0 @@
1
- """Unit tests: a tap spec carrying control characters is rejected at the door.
2
-
3
- `parse_spec` used to accept them. Given the ten bytes ``/\\0\\0\\0\\0\\0\\0\\0\\0A`` it
4
- returned a perfectly well-formed pair::
5
-
6
- ('/\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00A',
7
- 'https://github.com//\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00A')
8
-
9
- Nothing raised, so the name travelled onward — into ``config.json``, into
10
- ``Tap.safe_name``, and eventually into a filesystem call, where it died as
11
- ``ValueError: lstat: embedded null character in path`` from deep inside
12
- ``posixpath.realpath``. That message names neither the tap nor the command, and
13
- ``ValueError`` is not ``BoostError``, so the CLI's error handling never got to
14
- frame it.
15
-
16
- This is how the repo found out: ``fuzz.yml`` runs libFuzzer over ``parse_spec``
17
- weekly, and it has failed **three scheduled runs out of three** — 2026-07-25,
18
- 08-01 and 08-08 — writing the same reproducer each time. Nobody noticed, because
19
- ``ci-failure-issue.yml`` watches only ``["ci", "demo"]``, so a red cron job is a
20
- red square on a page nobody opens. The fuzzer had been right for three weeks.
21
-
22
- A control character can never appear in a GitHub owner/repo, a git URL, or a
23
- usable directory name, so there is no input this rejects that anyone wanted.
24
- Rejecting at the parse boundary turns an arbitrary later ``ValueError`` into the
25
- documented ``BoostError`` rejection path — which the fuzz harness already
26
- handles, and which the CLI already renders with a hint.
27
- """
28
- from __future__ import annotations
29
-
30
- import pytest
31
-
32
- from boost_cli.core import registry
33
- from boost_cli.errors import BoostError
34
-
35
- #: The exact ten bytes libFuzzer minimised to, decoded the way the harness does.
36
- CRASHER = "/\x00\x00\x00\x00\x00\x00\x00\x00A"
37
-
38
-
39
- class TestControlCharactersAreRejected:
40
- def test_the_fuzzer_reproducer_raises_boost_error(self):
41
- with pytest.raises(BoostError):
42
- registry.parse_spec(CRASHER)
43
-
44
- def test_a_bare_nul_is_rejected(self):
45
- with pytest.raises(BoostError):
46
- registry.parse_spec("owner/re\x00po")
47
-
48
- @pytest.mark.parametrize("ch", ["\x00", "\x01", "\x07", "\x1b", "\x7f"])
49
- def test_every_control_character_is_rejected(self, ch):
50
- # \x1b in particular: an escape sequence in a name is echoed back by
51
- # every surface that prints a tap list.
52
- with pytest.raises(BoostError):
53
- registry.parse_spec("owner/re%spo" % ch)
54
-
55
- def test_the_error_names_the_problem(self):
56
- with pytest.raises(BoostError) as caught:
57
- registry.parse_spec(CRASHER)
58
- assert "control character" in str(caught.value).lower()
59
-
60
- def test_a_newline_or_tab_is_rejected_too(self):
61
- # These survive `.strip()` when they are in the middle, and a newline in
62
- # a tap name breaks every line-oriented output in the CLI.
63
- for spec in ("owner/re\npo", "owner/re\tpo"):
64
- with pytest.raises(BoostError):
65
- registry.parse_spec(spec)
66
-
67
-
68
- class TestOrdinarySpecsStillParse:
69
- """The rejection must not widen. Each of these is a documented input."""
70
-
71
- def test_owner_repo(self):
72
- assert registry.parse_spec("anthropics/skills") == (
73
- "anthropics/skills", "https://github.com/anthropics/skills")
74
-
75
- def test_an_https_url(self):
76
- name, url = registry.parse_spec("https://github.com/acme/skills")
77
- assert name == "acme/skills" and url.startswith("https://")
78
-
79
- def test_an_ssh_url(self):
80
- name, _url = registry.parse_spec("git@github.com:acme/skills.git")
81
- assert name == "acme/skills"
82
-
83
- def test_a_local_directory(self, tmp_path):
84
- target = tmp_path / "my-skills"
85
- target.mkdir()
86
- name, url = registry.parse_spec(str(target))
87
- assert name == "my-skills" and url == str(target.resolve())
88
-
89
- def test_surrounding_whitespace_is_still_only_stripped(self):
90
- # Leading/trailing whitespace is trimmed, not rejected — that is a
91
- # paste artifact, not a hostile name, and it always worked.
92
- assert registry.parse_spec(" acme/skills ")[0] == "acme/skills"
93
-
94
- def test_a_unicode_name_is_not_a_control_character(self):
95
- # Non-ASCII is legal in a path and must not be caught by this net.
96
- assert registry.parse_spec("acmé/skïlls")[0] == "acmé/skïlls"
97
-
98
-
99
- class TestTheDerivedPathIsNowAlwaysUsable:
100
- """The property the fuzz harness asserts, and could not reach before.
101
-
102
- Its containment check calls ``os.path.realpath`` on the derived clone
103
- directory. That is what raised — so the harness could never even evaluate
104
- the invariant it exists to protect.
105
- """
106
-
107
- def test_realpath_of_the_derived_path_no_longer_raises(self):
108
- import os
109
- with pytest.raises(BoostError):
110
- name, url = registry.parse_spec(CRASHER)
111
- # Unreachable once parse_spec rejects; kept so this test fails
112
- # loudly rather than silently if the rejection is ever removed.
113
- os.path.realpath(str(registry.Tap(name=name, url=url).path))
File without changes
File without changes