boost-skill-cli 1.2.5__tar.gz → 1.2.7__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 (730) hide show
  1. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/PKG-INFO +1 -1
  2. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/_version.py +2 -2
  3. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/registry.py +44 -4
  4. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_skill_cli.egg-info/PKG-INFO +1 -1
  5. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_skill_cli.egg-info/SOURCES.txt +5 -0
  6. boost_skill_cli-1.2.7/docs/roadmap/items/pathlib-exists-is-not-total.md +48 -0
  7. boost_skill_cli-1.2.7/docs/roadmap/items/two-ci-controls-that-could-not-act.md +50 -0
  8. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap.html +93 -1
  9. boost_skill_cli-1.2.7/tests/fuzz/corpus/registry/09-nul.txt +0 -0
  10. boost_skill_cli-1.2.7/tests/fuzz/corpus/registry/10-name-too-long.txt +1 -0
  11. boost_skill_cli-1.2.7/tests/fuzz/corpus/registry/11-long-owner-repo.txt +1 -0
  12. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_failure_alerting_covers_unattended.py +44 -0
  13. boost_skill_cli-1.2.7/tests/unit/test_registry_control_chars.py +233 -0
  14. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_workflow_push_has_credentials.py +40 -0
  15. boost_skill_cli-1.2.5/tests/unit/test_registry_control_chars.py +0 -113
  16. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/.gitattributes +0 -0
  17. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/.gitignore +0 -0
  18. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/.gitleaks.toml +0 -0
  19. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/.htmlvalidate.json +0 -0
  20. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/.lighthouserc.json +0 -0
  21. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/.lycheeignore +0 -0
  22. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/.markdownlint-cli2.jsonc +0 -0
  23. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/.pre-commit-config.yaml +0 -0
  24. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/.stylelintrc.json +0 -0
  25. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/.vale/styles/boost/Terminology.yml +0 -0
  26. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
  27. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/.vale.ini +0 -0
  28. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/CLAUDE.md +0 -0
  29. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/CODE_OF_CONDUCT.md +0 -0
  30. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/CONTRIBUTING.md +0 -0
  31. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/LICENSE +0 -0
  32. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/MANIFEST.in +0 -0
  33. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/Makefile +0 -0
  34. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/README.md +0 -0
  35. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/SECURITY.md +0 -0
  36. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost +0 -0
  37. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/__init__.py +0 -0
  38. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/__main__.py +0 -0
  39. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/cli.py +0 -0
  40. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/cliparse.py +0 -0
  41. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/__init__.py +0 -0
  42. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/_common.py +0 -0
  43. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/bmad.py +0 -0
  44. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/configuration.py +0 -0
  45. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/discovery.py +0 -0
  46. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/hooks.py +0 -0
  47. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/info.py +0 -0
  48. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/intelligence.py +0 -0
  49. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/pkg.py +0 -0
  50. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/quality.py +0 -0
  51. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/run.py +0 -0
  52. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/safety.py +0 -0
  53. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/taps.py +0 -0
  54. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/commands/team.py +0 -0
  55. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/__init__.py +0 -0
  56. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/adapters.py +0 -0
  57. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/agents.py +0 -0
  58. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/ai.py +0 -0
  59. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/bmad.py +0 -0
  60. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/bootstrap.py +0 -0
  61. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/browse.py +0 -0
  62. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/builtin.py +0 -0
  63. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/capabilities.py +0 -0
  64. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/catalog.py +0 -0
  65. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/catalogbundle.py +0 -0
  66. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/chat.py +0 -0
  67. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/claude_settings.py +0 -0
  68. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/complete.py +0 -0
  69. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/config.py +0 -0
  70. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/dense.py +0 -0
  71. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/ed25519.py +0 -0
  72. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/embed.py +0 -0
  73. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/faithfulness.py +0 -0
  74. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/frontmatter.py +0 -0
  75. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/gitutil.py +0 -0
  76. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/imperative.py +0 -0
  77. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/injectscan.py +0 -0
  78. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/installscan.py +0 -0
  79. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/integrity.py +0 -0
  80. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/journal.py +0 -0
  81. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/localembed.py +0 -0
  82. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/lockfile.py +0 -0
  83. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/logs.py +0 -0
  84. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/mcp.py +0 -0
  85. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/mcpdecl.py +0 -0
  86. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/mcphost.py +0 -0
  87. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/minisign.py +0 -0
  88. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/nethttp.py +0 -0
  89. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/output.py +0 -0
  90. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/paths.py +0 -0
  91. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/policy.py +0 -0
  92. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/projectlock.py +0 -0
  93. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/provenance.py +0 -0
  94. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/rag.py +0 -0
  95. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/resolve.py +0 -0
  96. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/rules.py +0 -0
  97. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/scopes.py +0 -0
  98. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/secretscan.py +0 -0
  99. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/selfupdate.py +0 -0
  100. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/serve.py +0 -0
  101. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/stackprobe.py +0 -0
  102. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/staleness.py +0 -0
  103. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/store.py +0 -0
  104. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/trustaudit.py +0 -0
  105. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/typosquat.py +0 -0
  106. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/updatediff.py +0 -0
  107. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/util.py +0 -0
  108. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/core/workflows.py +0 -0
  109. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/data/registries.json +0 -0
  110. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/data/rules/boost-first.mdc +0 -0
  111. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/errors.py +0 -0
  112. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_cli/spin.py +0 -0
  113. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_langchain/__init__.py +0 -0
  114. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_langchain/_compat.py +0 -0
  115. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_langchain/graph.py +0 -0
  116. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_langchain/loader.py +0 -0
  117. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_langchain/py.typed +0 -0
  118. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_langchain/retriever.py +0 -0
  119. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  120. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  121. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_skill_cli.egg-info/requires.txt +0 -0
  122. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/boost_skill_cli.egg-info/top_level.txt +0 -0
  123. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/codecov.yml +0 -0
  124. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/.claude/settings.local.json +0 -0
  125. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/DEBUGGING.md +0 -0
  126. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/adapters.html +0 -0
  127. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/architecture/README.md +0 -0
  128. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/architecture/c4-components-core.md +0 -0
  129. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/architecture/c4-containers.md +0 -0
  130. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/architecture/c4-context.md +0 -0
  131. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/architecture/c4-dynamic-install.md +0 -0
  132. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/gifs/distill.gif +0 -0
  133. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/gifs/doctor.gif +0 -0
  134. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/gifs/explain.gif +0 -0
  135. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/gifs/hooks.gif +0 -0
  136. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/gifs/install.gif +0 -0
  137. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/gifs/pulse.gif +0 -0
  138. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/gifs/search.gif +0 -0
  139. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/gifs/tap.gif +0 -0
  140. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/tapes/distill.tape +0 -0
  141. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/tapes/doctor.tape +0 -0
  142. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/tapes/explain.tape +0 -0
  143. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/tapes/hooks.tape +0 -0
  144. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/tapes/install.tape +0 -0
  145. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/tapes/pulse.tape +0 -0
  146. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/tapes/search.tape +0 -0
  147. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel/tapes/tap.tape +0 -0
  148. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/carousel.html +0 -0
  149. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/chat.html +0 -0
  150. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/commands.html +0 -0
  151. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/demo-index.json +0 -0
  152. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/demo.gif +0 -0
  153. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/demo.html +0 -0
  154. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/demo.tape +0 -0
  155. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/design-roadmap.html +0 -0
  156. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/eval-latest.json +0 -0
  157. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/eval.html +0 -0
  158. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/index.html +0 -0
  159. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/langchain.html +0 -0
  160. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/mcp-hub.html +0 -0
  161. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/rag-architecture.md +0 -0
  162. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D01.md +0 -0
  163. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D02.md +0 -0
  164. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D03.md +0 -0
  165. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D04.md +0 -0
  166. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D05.md +0 -0
  167. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D06.md +0 -0
  168. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D07.md +0 -0
  169. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D08.md +0 -0
  170. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D09.md +0 -0
  171. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D10.md +0 -0
  172. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D11.md +0 -0
  173. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D12.md +0 -0
  174. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D13.md +0 -0
  175. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D14.md +0 -0
  176. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D15.md +0 -0
  177. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D16.md +0 -0
  178. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D17.md +0 -0
  179. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D18.md +0 -0
  180. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D19.md +0 -0
  181. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D20.md +0 -0
  182. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D21.md +0 -0
  183. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D22.md +0 -0
  184. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D23.md +0 -0
  185. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D24.md +0 -0
  186. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D25.md +0 -0
  187. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/BOOST-D26.md +0 -0
  188. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/a11y-sweep-flakes-on-color-contrast.md +0 -0
  189. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  190. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
  191. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
  192. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/agents-field-records-the-request-not-the-links.md +0 -0
  193. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
  194. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
  195. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  196. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  197. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  198. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/bm25-index-is-one-json-blob.md +0 -0
  199. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/bmad-autopilot-one-command-persona-routing.md +0 -0
  200. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/boost-first-carried-the-losing-trigger.md +0 -0
  201. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/boost-first-rule.md +0 -0
  202. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/boost-langchain-publishing.md +0 -0
  203. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  204. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  205. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  206. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/browse-could-not-search-two-words.md +0 -0
  207. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  208. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  209. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  210. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  211. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/catalogue-entries-carry-no-content-identity.md +0 -0
  212. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/chat-cites-sources-by-a-number-it-never-prints.md +0 -0
  213. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/chat-command-grounded-conversational-search.md +0 -0
  214. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
  215. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
  216. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
  217. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  218. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
  219. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
  220. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/command-carousel-page.md +0 -0
  221. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  222. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/completions-complete-only-command-names.md +0 -0
  223. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/completions-install-could-eat-your-rc-file.md +0 -0
  224. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  225. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  226. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  227. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  228. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
  229. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  230. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/crash-reports-leak-api-keys.md +0 -0
  231. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
  232. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
  233. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/demo-workflow-cancels-other-prs.md +0 -0
  234. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
  235. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
  236. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
  237. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
  238. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/dependabot-splits-multi-path-action-repos.md +0 -0
  239. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  240. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/discover-searches-github-not-a-stale-sample.md +0 -0
  241. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
  242. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  243. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  244. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/dry-run-promised-a-link-nobody-makes.md +0 -0
  245. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/efficiency-registries-ponytail-caveman.md +0 -0
  246. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  247. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/est-items-counts-agent-mirrors-as-items.md +0 -0
  248. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/eval-corpus-cannot-see-real-retrieval.md +0 -0
  249. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/eval-corpus-is-96x-smaller-than-a-real-install.md +0 -0
  250. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/eval-corpus-is-one-strangers-repo.md +0 -0
  251. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/eval-corpus-pins-have-no-refresh-path.md +0 -0
  252. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/eval-corpus-was-not-actually-pinned.md +0 -0
  253. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/eval-deduped-ranked-lists-by-name.md +0 -0
  254. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/eval-stats-could-never-publish.md +0 -0
  255. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/expanded-card-bodies-overflow.md +0 -0
  256. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  257. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  258. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  259. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  260. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  261. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  262. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  263. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  264. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  265. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/gemini-agent-frontmatter-sanitizer.md +0 -0
  266. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
  267. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/github-community-health-files.md +0 -0
  268. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  269. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/golden-set-grades-by-name-not-by-skill.md +0 -0
  270. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  271. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  272. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/heal-deleted-links-it-never-made.md +0 -0
  273. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  274. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/info-rejects-the-qualified-name-it-recommends.md +0 -0
  275. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
  276. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
  277. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/install-path-disambiguation.md +0 -0
  278. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
  279. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  280. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
  281. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  282. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
  283. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  284. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
  285. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/keyless-dense-tier-local-static-embeddings.md +0 -0
  286. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/keyless-semantic-search-for-everyone.md +0 -0
  287. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/langchain-in-the-wheel.md +0 -0
  288. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/langchain-integration-explainer-page.md +0 -0
  289. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/langchain-langgraph-langsmith-integration.md +0 -0
  290. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/langchain-retriever-metadata-and-k-floor.md +0 -0
  291. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  292. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/license-compliance-scanning.md +0 -0
  293. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  294. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/lighthouse-scored-a-page-nobody-is-served.md +0 -0
  295. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
  296. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  297. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  298. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
  299. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  300. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  301. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  302. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
  303. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
  304. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
  305. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  306. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  307. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
  308. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-already-covered-defeater.md +0 -0
  309. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-aware-skills.md +0 -0
  310. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
  311. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  312. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
  313. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  314. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-one-benefit-nameable-task.md +0 -0
  315. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  316. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
  317. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-search-cost-was-understated.md +0 -0
  318. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-search-hid-which-ranking-ran.md +0 -0
  319. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +0 -0
  320. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  321. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mcp-zero-setup-and-three-kinds.md +0 -0
  322. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  323. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
  324. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
  325. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  326. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
  327. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  328. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  329. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  330. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
  331. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
  332. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/near-duplicate-items-eat-the-result-slots.md +0 -0
  333. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
  334. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
  335. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  336. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
  337. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/one-dead-tap-broke-every-update.md +0 -0
  338. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  339. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  340. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  341. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
  342. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/pep585-604-modernization-sweep.md +0 -0
  343. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  344. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
  345. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
  346. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  347. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  348. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/prerequisites-and-semantic-search-setup.md +0 -0
  349. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
  350. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
  351. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  352. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  353. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  354. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  355. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  356. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
  357. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
  358. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
  359. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/python-floor-moves-to-312.md +0 -0
  360. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  361. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/ragas-unpin-when-upstream-ships.md +0 -0
  362. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  363. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  364. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  365. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
  366. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
  367. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
  368. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/required-checks-config-drift.md +0 -0
  369. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/resolve-vendored-duplicate-copies.md +0 -0
  370. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  371. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  372. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
  373. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/roadmap-page-weight-grows-without-bound.md +0 -0
  374. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/roadmap-perf-budget-has-no-local-guard.md +0 -0
  375. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  376. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
  377. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  378. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/rules-install-but-cannot-be-governed.md +0 -0
  379. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  380. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  381. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  382. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
  383. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  384. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
  385. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  386. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
  387. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
  388. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/scripts-under-the-lint-gate.md +0 -0
  389. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/search-never-notices-a-new-tap.md +0 -0
  390. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  391. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  392. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  393. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  394. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
  395. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/self-update-claims-up-to-date-without-asking.md +0 -0
  396. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/serve-404-reflected-the-request.md +0 -0
  397. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/serve-is-a-searchable-catalogue.md +0 -0
  398. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
  399. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/shards-pipeline-never-produced-a-shard.md +0 -0
  400. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/shareable-catalogue-bundle.md +0 -0
  401. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  402. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  403. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  404. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  405. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  406. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  407. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
  408. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  409. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  410. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/sweep-died-at-launch-not-at-a-page.md +0 -0
  411. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/sync-could-not-repair-a-gutted-skill.md +0 -0
  412. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
  413. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
  414. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/sync-reported-success-for-a-link-it-refused.md +0 -0
  415. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  416. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/taps-check-out-freight-they-never-index.md +0 -0
  417. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/the-catalogue-advertised-repos-that-no-longer-exist.md +0 -0
  418. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  419. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/tool-call-eval-tier.md +0 -0
  420. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/two-crashes-that-should-have-been-messages.md +0 -0
  421. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  422. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  423. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  424. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
  425. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  426. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/unwatched-crons-hid-a-real-fuzz-crash.md +0 -0
  427. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/update-advertises-a-flag-it-rejects.md +0 -0
  428. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  429. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/update-refreshed-rules-without-a-gate.md +0 -0
  430. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  431. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
  432. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  433. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  434. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  435. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
  436. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  437. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  438. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  439. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/workspace-scope-install.md +0 -0
  440. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/zip-strict-audit.md +0 -0
  441. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/zizmor-ignores-drift-and-make-lint-never-ran-it.md +0 -0
  442. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
  443. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/docs/superpowers/specs/2026-08-16-catalogue-content-identity-design.md +0 -0
  444. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/eslint.config.mjs +0 -0
  445. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/evals/README.md +0 -0
  446. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/evals/__init__.py +0 -0
  447. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/evals/baseline.json +0 -0
  448. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/evals/faithfulness.py +0 -0
  449. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/evals/golden_set.json +0 -0
  450. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/evals/make_corpus.py +0 -0
  451. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/evals/make_golden.py +0 -0
  452. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/evals/metrics.py +0 -0
  453. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/evals/publish_golden_dataset.py +0 -0
  454. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/evals/run_evals.py +0 -0
  455. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/examples/README.md +0 -0
  456. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/examples/adapt-demo.sh +0 -0
  457. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/examples/boost-run-prototype.sh +0 -0
  458. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/index.html +0 -0
  459. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/noxfile.py +0 -0
  460. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/pyproject.toml +0 -0
  461. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/requirements/coverage-tools.in +0 -0
  462. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/requirements/coverage-tools.txt +0 -0
  463. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/requirements/lint-tools.in +0 -0
  464. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/requirements/lint-tools.txt +0 -0
  465. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/requirements/mutation-tools.in +0 -0
  466. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/requirements/mutation-tools.txt +0 -0
  467. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/requirements/platform-pins.lock +0 -0
  468. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/requirements/release-tools.in +0 -0
  469. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/requirements/release-tools.txt +0 -0
  470. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/requirements/test-tools.in +0 -0
  471. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/requirements/test-tools.txt +0 -0
  472. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/a11y_check.py +0 -0
  473. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/bench_cli.sh +0 -0
  474. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/build_command_reference.py +0 -0
  475. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/build_demo_index.py +0 -0
  476. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/build_registries.py +0 -0
  477. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/build_roadmap.py +0 -0
  478. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/build_scale_corpus.py +0 -0
  479. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/check_anchors.py +0 -0
  480. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/check_licenses.py +0 -0
  481. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/check_required_checks.py +0 -0
  482. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/ensure_eval_corpus.sh +0 -0
  483. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/eval_corpus.py +0 -0
  484. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/eval_explain.py +0 -0
  485. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/eval_gate.py +0 -0
  486. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/eval_recommend.py +0 -0
  487. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/eval_retrieval.py +0 -0
  488. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/eval_stats_summary.py +0 -0
  489. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/import_budget.py +0 -0
  490. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/lock_toolchain.py +0 -0
  491. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/measure_registry.py +0 -0
  492. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/mutation_gate.py +0 -0
  493. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/mutation_shards.py +0 -0
  494. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/mutation_weights.json +0 -0
  495. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/page_budget.py +0 -0
  496. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/perf_gate.py +0 -0
  497. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/post_deploy_smoke.py +0 -0
  498. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/publish_eval_json.py +0 -0
  499. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/release_guard.py +0 -0
  500. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/release_preflight.py +0 -0
  501. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/scripts/serve_docs.py +0 -0
  502. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/setup.cfg +0 -0
  503. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/sonar-project.properties +0 -0
  504. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/style/README.md +0 -0
  505. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/style/boost.css +0 -0
  506. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/style/boost.js +0 -0
  507. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/style/demo.html +0 -0
  508. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/adapt.feature +0 -0
  509. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/browse.feature +0 -0
  510. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/count.feature +0 -0
  511. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/discover.feature +0 -0
  512. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/doctor.feature +0 -0
  513. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/environment.py +0 -0
  514. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/explain.feature +0 -0
  515. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/index.feature +0 -0
  516. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/install.feature +0 -0
  517. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/list.feature +0 -0
  518. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/mcp.feature +0 -0
  519. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/search.feature +0 -0
  520. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/steps/cli_steps.py +0 -0
  521. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/steps/discovery_steps.py +0 -0
  522. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/steps/mcp_steps.py +0 -0
  523. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/bdd/features/steps/quality_steps.py +0 -0
  524. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/conftest.py +0 -0
  525. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/eval/baseline.json +0 -0
  526. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/eval/explain.jsonl +0 -0
  527. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/eval/golden-natural.jsonl +0 -0
  528. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/eval/golden.jsonl +0 -0
  529. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/eval/recommend.jsonl +0 -0
  530. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/eval/taps-scale.txt +0 -0
  531. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/eval/taps.txt +0 -0
  532. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_capabilities_policy.py +0 -0
  533. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_adapt.py +0 -0
  534. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_bmad.py +0 -0
  535. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_catalog.py +0 -0
  536. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_chat.py +0 -0
  537. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_configuration.py +0 -0
  538. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_discovery.py +0 -0
  539. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_hooks.py +0 -0
  540. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_info.py +0 -0
  541. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_intelligence.py +0 -0
  542. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_pkg.py +0 -0
  543. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_quality.py +0 -0
  544. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_taps.py +0 -0
  545. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_cli_team.py +0 -0
  546. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_everyday_loop.py +0 -0
  547. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_integrity_enforce.py +0 -0
  548. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_kind_conformance.py +0 -0
  549. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_property_parsers.py +0 -0
  550. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_run.py +0 -0
  551. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_tap_signing.py +0 -0
  552. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/functional/test_workspace_scope.py +0 -0
  553. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/README.md +0 -0
  554. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
  555. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
  556. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
  557. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
  558. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
  559. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
  560. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
  561. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
  562. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
  563. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
  564. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
  565. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
  566. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
  567. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/registry/02-https.txt +0 -0
  568. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
  569. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
  570. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
  571. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/registry/06-space.txt +0 -0
  572. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
  573. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
  574. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/fuzz_frontmatter.py +0 -0
  575. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/fuzz/fuzz_registry.py +0 -0
  576. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/langchain/conftest.py +0 -0
  577. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/langchain/test_graph.py +0 -0
  578. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/langchain/test_loader.py +0 -0
  579. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/langchain/test_retriever.py +0 -0
  580. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/make_fixture.py +0 -0
  581. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/perf/test_benchmarks.py +0 -0
  582. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/smoke.sh +0 -0
  583. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_a11y_check.py +0 -0
  584. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_action_pin_lockstep.py +0 -0
  585. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_adapters.py +0 -0
  586. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_adapters_multi.py +0 -0
  587. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_adapters_runner.py +0 -0
  588. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_agents.py +0 -0
  589. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_ai.py +0 -0
  590. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_bmad_core.py +0 -0
  591. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_boost_first_offer.py +0 -0
  592. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_bootstrap.py +0 -0
  593. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_browse.py +0 -0
  594. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_builtin.py +0 -0
  595. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_capabilities.py +0 -0
  596. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_catalog.py +0 -0
  597. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_catalogbundle.py +0 -0
  598. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_chat.py +0 -0
  599. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_check_anchors.py +0 -0
  600. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_check_licenses.py +0 -0
  601. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_claude_settings.py +0 -0
  602. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_clean_internal_cache.py +0 -0
  603. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_cliparse.py +0 -0
  604. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_codeql_analysis_key.py +0 -0
  605. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_command_reference_fresh.py +0 -0
  606. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_community_health_files.py +0 -0
  607. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_compact.py +0 -0
  608. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_complete.py +0 -0
  609. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_complete_rc_block.py +0 -0
  610. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_config.py +0 -0
  611. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_content_dedupe.py +0 -0
  612. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_content_identity.py +0 -0
  613. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_crash_redaction.py +0 -0
  614. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_dedup_trust.py +0 -0
  615. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_demo_index.py +0 -0
  616. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_dense.py +0 -0
  617. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_dense_embed_dedupe.py +0 -0
  618. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_dense_fallback.py +0 -0
  619. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_dense_fix_hint.py +0 -0
  620. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_dense_shard_real_schema.py +0 -0
  621. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_dense_shard_unreadable_vectors.py +0 -0
  622. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_dense_shards.py +0 -0
  623. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_dense_status.py +0 -0
  624. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_dependabot_config.py +0 -0
  625. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_docs_pages_linked.py +0 -0
  626. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_docsite_chrome.py +0 -0
  627. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_ed25519.py +0 -0
  628. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_embed.py +0 -0
  629. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_embed_local.py +0 -0
  630. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_embed_truncated_response.py +0 -0
  631. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_entry_key.py +0 -0
  632. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_errors_and_cli_table.py +0 -0
  633. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_eval_baseline.py +0 -0
  634. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_eval_corpus.py +0 -0
  635. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_eval_faithfulness.py +0 -0
  636. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_eval_gate.py +0 -0
  637. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_eval_grading.py +0 -0
  638. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_eval_metrics.py +0 -0
  639. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_eval_stats_summary.py +0 -0
  640. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_faithfulness.py +0 -0
  641. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_frontmatter.py +0 -0
  642. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_fuzz_targets.py +0 -0
  643. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_gemini_agent_sanitize.py +0 -0
  644. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_gitleaks_config.py +0 -0
  645. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_gitutil.py +0 -0
  646. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_gitutil_lfs.py +0 -0
  647. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_gitutil_sparse.py +0 -0
  648. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_imperative.py +0 -0
  649. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_import_budget.py +0 -0
  650. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_injectscan.py +0 -0
  651. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_install_permission_error.py +0 -0
  652. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_installscan.py +0 -0
  653. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_integrity.py +0 -0
  654. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_journal.py +0 -0
  655. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_langchain_packaging.py +0 -0
  656. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_link_ownership.py +0 -0
  657. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_localembed.py +0 -0
  658. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_localembed_e2e.py +0 -0
  659. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_lockfile.py +0 -0
  660. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_logs.py +0 -0
  661. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_marketing_counts.py +0 -0
  662. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_mcp.py +0 -0
  663. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_mcp_install_scan.py +0 -0
  664. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_mcpdecl.py +0 -0
  665. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_mcphost.py +0 -0
  666. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_measure_registry.py +0 -0
  667. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_minisign.py +0 -0
  668. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_mutation_hardening.py +0 -0
  669. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_mutation_shards.py +0 -0
  670. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_mutation_subfile_shards.py +0 -0
  671. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_mutmut_source_paths.py +0 -0
  672. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_nethttp.py +0 -0
  673. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_output.py +0 -0
  674. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_page_budget.py +0 -0
  675. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_paths.py +0 -0
  676. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_perf_gate.py +0 -0
  677. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_pkg_confusions.py +0 -0
  678. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_pkg_injection.py +0 -0
  679. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_pkg_secrets.py +0 -0
  680. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_platform_pins.py +0 -0
  681. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_policy.py +0 -0
  682. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_post_deploy_smoke.py +0 -0
  683. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_project_mcp_sidecar.py +0 -0
  684. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_projectlock.py +0 -0
  685. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_provenance.py +0 -0
  686. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_publish_golden_dataset.py +0 -0
  687. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_rag.py +0 -0
  688. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_rag_fusion.py +0 -0
  689. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_registries_fresh.py +0 -0
  690. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_registry.py +0 -0
  691. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_registry_categories.py +0 -0
  692. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_release_guard.py +0 -0
  693. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_release_preflight.py +0 -0
  694. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_required_checks.py +0 -0
  695. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_resolve.py +0 -0
  696. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_roadmap_fresh.py +0 -0
  697. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_rules.py +0 -0
  698. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_scale_corpus.py +0 -0
  699. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_scopes.py +0 -0
  700. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_secretscan.py +0 -0
  701. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_selfupdate.py +0 -0
  702. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_serve.py +0 -0
  703. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_serve_docs.py +0 -0
  704. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_shards_matrix.py +0 -0
  705. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_smoke_covers_every_command.py +0 -0
  706. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_spin.py +0 -0
  707. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_stackprobe.py +0 -0
  708. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_staleness.py +0 -0
  709. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_store.py +0 -0
  710. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_store_materialize.py +0 -0
  711. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_sync_blocked_links.py +0 -0
  712. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_sync_repairs_gutted_skill.py +0 -0
  713. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_token_parity.py +0 -0
  714. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_toolchain_lock.py +0 -0
  715. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_trustaudit.py +0 -0
  716. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_typosquat.py +0 -0
  717. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_updatediff.py +0 -0
  718. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_util.py +0 -0
  719. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_version.py +0 -0
  720. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_visual_harness_flags.py +0 -0
  721. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_workflow_concurrency.py +0 -0
  722. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_workflow_concurrency_groups.py +0 -0
  723. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_workflow_timeouts.py +0 -0
  724. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_workflows.py +0 -0
  725. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/unit/test_zizmor_ignores_still_anchor.py +0 -0
  726. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/visual/a11y_check.mjs +0 -0
  727. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/visual/console_check.mjs +0 -0
  728. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/visual/package-lock.json +0 -0
  729. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/tests/visual/package.json +0 -0
  730. {boost_skill_cli-1.2.5 → boost_skill_cli-1.2.7}/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.7
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.7'
22
+ __version_tuple__ = version_tuple = (1, 2, 7)
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.7
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
@@ -413,6 +414,7 @@ docs/roadmap/items/taps-check-out-freight-they-never-index.md
413
414
  docs/roadmap/items/the-catalogue-advertised-repos-that-no-longer-exist.md
414
415
  docs/roadmap/items/theme-asset-linting-stylelint-eslint.md
415
416
  docs/roadmap/items/tool-call-eval-tier.md
417
+ docs/roadmap/items/two-ci-controls-that-could-not-act.md
416
418
  docs/roadmap/items/two-crashes-that-should-have-been-messages.md
417
419
  docs/roadmap/items/typo-detection-codespell.md
418
420
  docs/roadmap/items/typosquat-and-name-confusion-detection.md
@@ -565,6 +567,9 @@ tests/fuzz/corpus/registry/05-empty.txt
565
567
  tests/fuzz/corpus/registry/06-space.txt
566
568
  tests/fuzz/corpus/registry/07-slash.txt
567
569
  tests/fuzz/corpus/registry/08-bare-host.txt
570
+ tests/fuzz/corpus/registry/09-nul.txt
571
+ tests/fuzz/corpus/registry/10-name-too-long.txt
572
+ tests/fuzz/corpus/registry/11-long-owner-repo.txt
568
573
  tests/langchain/conftest.py
569
574
  tests/langchain/test_graph.py
570
575
  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.
@@ -0,0 +1,50 @@
1
+ ---
2
+ id: two-ci-controls-that-could-not-act
3
+ board: code
4
+ section: internals
5
+ status: shipped
6
+ category: CI · Correctness
7
+ complexity: S
8
+ impact: Medium
9
+ wow: 4
10
+ note: one publisher could never publish and one alert could never stand down — both reported success
11
+ order: 119
12
+ owner: fix/ci-controls-that-cannot-act
13
+ pr: 529
14
+ title: a publisher that could not publish, and an alert that could not stand down
15
+ ---
16
+ <b>Two controls, the same failure mode: present, running, and structurally unable to do the thing
17
+ they exist for.</b>
18
+
19
+ <b>1. <code>eval-stats</code> pushed to a branch no token can push to.</b> An earlier fix got the
20
+ credentials right &mdash; the checkout uses <code>persist-credentials: false</code>, so the push
21
+ needed its own token URL, and it got one. That took the workflow as far as a <em>different</em>
22
+ permanent failure: <code>GH013: Repository rule violations found for refs/heads/main</code>.
23
+ <code>main</code> carries a ruleset with a <code>pull_request</code> rule and an <b>empty bypass
24
+ list</b>, so no token can push to it &mdash; not <code>github.token</code>, not a PAT, not any bot.
25
+ The workflow was not misconfigured; it was impossible.
26
+
27
+ <b>The remedy is not a bypass actor.</b> Adding one would open the protection guarding every change
28
+ to main so that a docs payload can skip review. The refreshed metrics now arrive the way
29
+ <code>eval-corpus-refresh.yml</code> already lands its moved pins &mdash; as a pull request on one
30
+ long-lived <code>bot/eval-metrics</code> branch that each run updates in place, rather than a new PR
31
+ a week. Reviewable, mergeable, and no weaker than any other change to main. It carries the same
32
+ warning that workflow's PRs do: a <code>GITHUB_TOKEN</code> push never triggers workflows, so the
33
+ check list is empty until someone presses <b>Update branch</b>, and empty looks exactly like
34
+ &ldquo;not started yet&rdquo;.
35
+
36
+ <b>2. The failure tracker opened issues and never closed one.</b> Its own closing line said
37
+ &ldquo;close this once CI is green again&rdquo; &mdash; a manual step nobody had a reason to take. So
38
+ <code>visual</code> stayed open through <b>four consecutive green runs</b>, and an issue list that
39
+ mixes live outages with fixed ones makes every entry in it read as equally suspect. An alert that
40
+ cannot stand down is only half an alert. A success on main now closes the tracker for
41
+ <em>that</em> workflow, keyed on the same per-workflow marker the opener writes &mdash; a
42
+ <code>ci</code> success must never close a <code>demo</code> tracker.
43
+
44
+ <b>The second job is what made the permissions wrong.</b> <code>issues: write</code> sat at the
45
+ workflow level, where it reaches every job including any added later; zizmor's excessive-permissions
46
+ audit says so and now fails the build on it. Each job asks for its own.
47
+
48
+ <b>Both halves are pinned statically</b>, and the push guard was verified by reversion: restore the
49
+ old <code>HEAD:main</code> and the test names the exact line. The guard outlives this fix &mdash; it
50
+ is parametrised over every workflow that pushes, so the next one cannot rediscover the same wall.
@@ -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>257</b><span>Loop finds</span></div>
137
137
  <!-- /ROADMAP:stats -->
138
138
  </div>
139
139
  </section>
@@ -4120,6 +4120,98 @@ 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>
4168
+
4169
+ <article class="cap rcard" id="two-ci-controls-that-could-not-act">
4170
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">CI · Correctness</span></div>
4171
+ <h3>a publisher that could not publish, and an alert that could not stand down</h3>
4172
+ <details class="cardbody"><summary>Write-up</summary>
4173
+ <p><b>Two controls, the same failure mode: present, running, and structurally unable to do the thing
4174
+ they exist for.</b>
4175
+
4176
+ <b>1. <code>eval-stats</code> pushed to a branch no token can push to.</b> An earlier fix got the
4177
+ credentials right &mdash; the checkout uses <code>persist-credentials: false</code>, so the push
4178
+ needed its own token URL, and it got one. That took the workflow as far as a <em>different</em>
4179
+ permanent failure: <code>GH013: Repository rule violations found for refs/heads/main</code>.
4180
+ <code>main</code> carries a ruleset with a <code>pull_request</code> rule and an <b>empty bypass
4181
+ list</b>, so no token can push to it &mdash; not <code>github.token</code>, not a PAT, not any bot.
4182
+ The workflow was not misconfigured; it was impossible.
4183
+
4184
+ <b>The remedy is not a bypass actor.</b> Adding one would open the protection guarding every change
4185
+ to main so that a docs payload can skip review. The refreshed metrics now arrive the way
4186
+ <code>eval-corpus-refresh.yml</code> already lands its moved pins &mdash; as a pull request on one
4187
+ long-lived <code>bot/eval-metrics</code> branch that each run updates in place, rather than a new PR
4188
+ a week. Reviewable, mergeable, and no weaker than any other change to main. It carries the same
4189
+ warning that workflow's PRs do: a <code>GITHUB_TOKEN</code> push never triggers workflows, so the
4190
+ check list is empty until someone presses <b>Update branch</b>, and empty looks exactly like
4191
+ &ldquo;not started yet&rdquo;.
4192
+
4193
+ <b>2. The failure tracker opened issues and never closed one.</b> Its own closing line said
4194
+ &ldquo;close this once CI is green again&rdquo; &mdash; a manual step nobody had a reason to take. So
4195
+ <code>visual</code> stayed open through <b>four consecutive green runs</b>, and an issue list that
4196
+ mixes live outages with fixed ones makes every entry in it read as equally suspect. An alert that
4197
+ cannot stand down is only half an alert. A success on main now closes the tracker for
4198
+ <em>that</em> workflow, keyed on the same per-workflow marker the opener writes &mdash; a
4199
+ <code>ci</code> success must never close a <code>demo</code> tracker.
4200
+
4201
+ <b>The second job is what made the permissions wrong.</b> <code>issues: write</code> sat at the
4202
+ workflow level, where it reaches every job including any added later; zizmor's excessive-permissions
4203
+ audit says so and now fails the build on it. Each job asks for its own.
4204
+
4205
+ <b>Both halves are pinned statically</b>, and the push guard was verified by reversion: restore the
4206
+ old <code>HEAD:main</code> and the test names the exact line. The guard outlives this fix &mdash; it
4207
+ is parametrised over every workflow that pushes, so the next one cannot rediscover the same wall.</p></details>
4208
+ <div class="meta">
4209
+ <span class="m">Complexity <b>S</b></span>
4210
+ <span class="m">Impact <b>Medium</b></span>
4211
+ <span class="m">Wow <b class="wow">★★★★</b></span>
4212
+ <span class="m">one publisher could never publish and one alert could never stand down — both reported success</span>
4213
+ </div>
4214
+ </article>
4123
4215
  <!-- /ROADMAP:cards -->
4124
4216
 
4125
4217
  </div>
@@ -0,0 +1 @@
1
+ 8������������������������������������������������������������������������������������������
@@ -0,0 +1 @@
1
+ owner/rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
@@ -130,3 +130,47 @@ class TestEveryUnattendedWorkflowIsWatched:
130
130
  names = {workflow_name(p.read_text(encoding="utf-8"), p.stem)
131
131
  for p in WORKFLOWS.glob("*.yml")}
132
132
  assert watched() <= names, sorted(watched() - names)
133
+
134
+
135
+ class TestTheAlertCanStandDown:
136
+ """An alert that cannot close is only half an alert.
137
+
138
+ The tracker opened issues, commented on repeats, and never closed one — so
139
+ its own closing line, "close this once CI is green again", was a manual step
140
+ nobody had a reason to take. `visual` stayed open through four consecutive
141
+ green runs, and a list that mixes live outages with fixed ones makes every
142
+ entry in it read as equally suspect.
143
+ """
144
+
145
+ def test_a_success_on_main_closes_the_tracker(self):
146
+ text = ALERT.read_text(encoding="utf-8")
147
+ assert "conclusion == 'success'" in text, (
148
+ "nothing reacts to a watched workflow going green, so every "
149
+ "tracker this file opens stays open until someone closes it")
150
+ assert "state: 'closed'" in text
151
+
152
+ def test_closing_is_keyed_by_workflow_like_opening(self):
153
+ """A `ci` success must not close a `demo` tracker.
154
+
155
+ The opener keys its marker on the workflow name for exactly this
156
+ reason; a closer that matched any `ci-failure` issue would undo that.
157
+ """
158
+ text = ALERT.read_text(encoding="utf-8")
159
+ assert text.count("ci-failure-tracker:${run.name}") >= 2, (
160
+ "the closing half must use the same per-workflow marker the "
161
+ "opening half writes")
162
+
163
+ def test_only_main_can_close_it(self):
164
+ """`workflow_run` fires for the default branch, but the opener still
165
+ checks — and an asymmetry here would let a non-main success close a
166
+ tracker for a failure that is still live on main."""
167
+ text = ALERT.read_text(encoding="utf-8")
168
+ assert text.count("head_branch == 'main'") >= 2
169
+
170
+ def test_permissions_are_not_granted_workflow_wide(self):
171
+ """`issues: write` at the top reaches every job, including any added
172
+ later. zizmor's excessive-permissions audit fails the build on it."""
173
+ text = ALERT.read_text(encoding="utf-8")
174
+ assert re.search(r"^permissions:\s*\{\}\s*$", text, re.M), \
175
+ "workflow-level permissions must be empty; each job asks for its own"
176
+ assert text.count("issues: write") >= 2
@@ -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))