boost-skill-cli 1.0.402__tar.gz → 1.0.403__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 (629) hide show
  1. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/PKG-INFO +1 -1
  2. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/_version.py +2 -2
  3. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/quality.py +131 -13
  4. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_skill_cli.egg-info/PKG-INFO +1 -1
  5. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_skill_cli.egg-info/SOURCES.txt +2 -0
  6. boost_skill_cli-1.0.403/docs/roadmap/items/heal-deleted-links-it-never-made.md +54 -0
  7. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap.html +52 -1
  8. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_cli_quality.py +39 -0
  9. boost_skill_cli-1.0.403/tests/unit/test_link_ownership.py +108 -0
  10. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/.gitattributes +0 -0
  11. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/.gitignore +0 -0
  12. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/.gitleaks.toml +0 -0
  13. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/.htmlvalidate.json +0 -0
  14. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/.lighthouserc.json +0 -0
  15. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/.lycheeignore +0 -0
  16. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/.markdownlint-cli2.jsonc +0 -0
  17. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/.pre-commit-config.yaml +0 -0
  18. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/.stylelintrc.json +0 -0
  19. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/.vale/styles/boost/Terminology.yml +0 -0
  20. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
  21. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/.vale.ini +0 -0
  22. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/CLAUDE.md +0 -0
  23. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/CODE_OF_CONDUCT.md +0 -0
  24. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/CONTRIBUTING.md +0 -0
  25. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/LICENSE +0 -0
  26. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/MANIFEST.in +0 -0
  27. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/Makefile +0 -0
  28. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/README.md +0 -0
  29. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/SECURITY.md +0 -0
  30. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost +0 -0
  31. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/__init__.py +0 -0
  32. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/__main__.py +0 -0
  33. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/cli.py +0 -0
  34. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/cliparse.py +0 -0
  35. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/__init__.py +0 -0
  36. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/_common.py +0 -0
  37. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/bmad.py +0 -0
  38. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/configuration.py +0 -0
  39. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/discovery.py +0 -0
  40. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/hooks.py +0 -0
  41. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/info.py +0 -0
  42. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/intelligence.py +0 -0
  43. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/pkg.py +0 -0
  44. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/run.py +0 -0
  45. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/safety.py +0 -0
  46. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/taps.py +0 -0
  47. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/commands/team.py +0 -0
  48. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/__init__.py +0 -0
  49. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/adapters.py +0 -0
  50. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/agents.py +0 -0
  51. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/ai.py +0 -0
  52. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/capabilities.py +0 -0
  53. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/catalog.py +0 -0
  54. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/chat.py +0 -0
  55. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/claude_settings.py +0 -0
  56. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/complete.py +0 -0
  57. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/config.py +0 -0
  58. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/dense.py +0 -0
  59. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/ed25519.py +0 -0
  60. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/embed.py +0 -0
  61. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/faithfulness.py +0 -0
  62. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/frontmatter.py +0 -0
  63. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/gitutil.py +0 -0
  64. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/imperative.py +0 -0
  65. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/injectscan.py +0 -0
  66. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/installscan.py +0 -0
  67. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/integrity.py +0 -0
  68. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/journal.py +0 -0
  69. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/localembed.py +0 -0
  70. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/lockfile.py +0 -0
  71. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/logs.py +0 -0
  72. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/mcp.py +0 -0
  73. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/mcpdecl.py +0 -0
  74. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/mcphost.py +0 -0
  75. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/minisign.py +0 -0
  76. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/nethttp.py +0 -0
  77. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/output.py +0 -0
  78. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/paths.py +0 -0
  79. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/policy.py +0 -0
  80. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/projectlock.py +0 -0
  81. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/provenance.py +0 -0
  82. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/rag.py +0 -0
  83. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/registry.py +0 -0
  84. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/resolve.py +0 -0
  85. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/rules.py +0 -0
  86. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/scopes.py +0 -0
  87. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/secretscan.py +0 -0
  88. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/selfupdate.py +0 -0
  89. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/serve.py +0 -0
  90. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/stackprobe.py +0 -0
  91. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/staleness.py +0 -0
  92. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/store.py +0 -0
  93. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/trustaudit.py +0 -0
  94. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/typosquat.py +0 -0
  95. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/updatediff.py +0 -0
  96. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/util.py +0 -0
  97. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/core/workflows.py +0 -0
  98. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/data/registries.json +0 -0
  99. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/errors.py +0 -0
  100. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_cli/spin.py +0 -0
  101. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  102. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  103. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_skill_cli.egg-info/requires.txt +0 -0
  104. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/boost_skill_cli.egg-info/top_level.txt +0 -0
  105. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/codecov.yml +0 -0
  106. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/.claude/settings.local.json +0 -0
  107. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/DEBUGGING.md +0 -0
  108. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/adapters.html +0 -0
  109. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/architecture/README.md +0 -0
  110. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/architecture/c4-components-core.md +0 -0
  111. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/architecture/c4-containers.md +0 -0
  112. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/architecture/c4-context.md +0 -0
  113. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/architecture/c4-dynamic-install.md +0 -0
  114. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/gifs/distill.gif +0 -0
  115. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/gifs/doctor.gif +0 -0
  116. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/gifs/explain.gif +0 -0
  117. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/gifs/hooks.gif +0 -0
  118. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/gifs/install.gif +0 -0
  119. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/gifs/pulse.gif +0 -0
  120. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/gifs/search.gif +0 -0
  121. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/gifs/tap.gif +0 -0
  122. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/tapes/distill.tape +0 -0
  123. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/tapes/doctor.tape +0 -0
  124. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/tapes/explain.tape +0 -0
  125. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/tapes/hooks.tape +0 -0
  126. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/tapes/install.tape +0 -0
  127. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/tapes/pulse.tape +0 -0
  128. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/tapes/search.tape +0 -0
  129. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel/tapes/tap.tape +0 -0
  130. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/carousel.html +0 -0
  131. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/chat.html +0 -0
  132. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/commands.html +0 -0
  133. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/demo-index.json +0 -0
  134. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/demo.gif +0 -0
  135. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/demo.html +0 -0
  136. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/demo.tape +0 -0
  137. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/design-roadmap.html +0 -0
  138. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/eval-latest.json +0 -0
  139. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/eval.html +0 -0
  140. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/index.html +0 -0
  141. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/mcp-hub.html +0 -0
  142. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/rag-architecture.md +0 -0
  143. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D01.md +0 -0
  144. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D02.md +0 -0
  145. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D03.md +0 -0
  146. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D04.md +0 -0
  147. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D05.md +0 -0
  148. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D06.md +0 -0
  149. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D07.md +0 -0
  150. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D08.md +0 -0
  151. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D09.md +0 -0
  152. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D10.md +0 -0
  153. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D11.md +0 -0
  154. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D12.md +0 -0
  155. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D13.md +0 -0
  156. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D14.md +0 -0
  157. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D15.md +0 -0
  158. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D16.md +0 -0
  159. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D17.md +0 -0
  160. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D18.md +0 -0
  161. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D19.md +0 -0
  162. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D20.md +0 -0
  163. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D21.md +0 -0
  164. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D22.md +0 -0
  165. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D23.md +0 -0
  166. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D24.md +0 -0
  167. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D25.md +0 -0
  168. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/BOOST-D26.md +0 -0
  169. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/a11y-sweep-flakes-on-color-contrast.md +0 -0
  170. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  171. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
  172. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
  173. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/agents-field-records-the-request-not-the-links.md +0 -0
  174. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
  175. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
  176. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  177. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  178. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  179. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/bm25-index-is-one-json-blob.md +0 -0
  180. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  181. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  182. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  183. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  184. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  185. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  186. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  187. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/chat-cites-sources-by-a-number-it-never-prints.md +0 -0
  188. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/chat-command-grounded-conversational-search.md +0 -0
  189. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
  190. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
  191. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
  192. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  193. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
  194. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
  195. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/command-carousel-page.md +0 -0
  196. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  197. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/completions-complete-only-command-names.md +0 -0
  198. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  199. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  200. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  201. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  202. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
  203. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  204. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
  205. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
  206. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
  207. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
  208. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
  209. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
  210. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  211. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
  212. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  213. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  214. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  215. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/eval-corpus-cannot-see-real-retrieval.md +0 -0
  216. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/eval-corpus-is-96x-smaller-than-a-real-install.md +0 -0
  217. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/eval-corpus-is-one-strangers-repo.md +0 -0
  218. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/eval-corpus-pins-have-no-refresh-path.md +0 -0
  219. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/eval-corpus-was-not-actually-pinned.md +0 -0
  220. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/eval-deduped-ranked-lists-by-name.md +0 -0
  221. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  222. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  223. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  224. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  225. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  226. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  227. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  228. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  229. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  230. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
  231. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/github-community-health-files.md +0 -0
  232. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  233. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/golden-set-grades-by-name-not-by-skill.md +0 -0
  234. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  235. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  236. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  237. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/info-rejects-the-qualified-name-it-recommends.md +0 -0
  238. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
  239. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
  240. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
  241. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  242. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
  243. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  244. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
  245. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  246. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
  247. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/keyless-dense-tier-local-static-embeddings.md +0 -0
  248. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/keyless-semantic-search-for-everyone.md +0 -0
  249. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/langchain-integration-explainer-page.md +0 -0
  250. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/langchain-langgraph-langsmith-integration.md +0 -0
  251. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  252. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/license-compliance-scanning.md +0 -0
  253. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  254. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/lighthouse-scored-a-page-nobody-is-served.md +0 -0
  255. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
  256. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  257. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  258. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
  259. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  260. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  261. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  262. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
  263. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
  264. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
  265. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  266. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  267. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
  268. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mcp-aware-skills.md +0 -0
  269. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
  270. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  271. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
  272. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  273. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mcp-one-benefit-nameable-task.md +0 -0
  274. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  275. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
  276. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mcp-search-cost-was-understated.md +0 -0
  277. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +0 -0
  278. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  279. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  280. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
  281. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
  282. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  283. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
  284. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  285. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  286. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  287. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
  288. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
  289. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/near-duplicate-items-eat-the-result-slots.md +0 -0
  290. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
  291. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
  292. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  293. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
  294. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/one-dead-tap-broke-every-update.md +0 -0
  295. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  296. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  297. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  298. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
  299. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/pep585-604-modernization-sweep.md +0 -0
  300. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  301. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
  302. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
  303. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  304. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  305. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/prerequisites-and-semantic-search-setup.md +0 -0
  306. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
  307. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
  308. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  309. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  310. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  311. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  312. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  313. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
  314. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
  315. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
  316. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/python-floor-moves-to-312.md +0 -0
  317. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  318. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  319. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  320. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  321. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
  322. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
  323. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
  324. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/required-checks-config-drift.md +0 -0
  325. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/resolve-vendored-duplicate-copies.md +0 -0
  326. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  327. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  328. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
  329. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/roadmap-page-weight-grows-without-bound.md +0 -0
  330. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/roadmap-perf-budget-has-no-local-guard.md +0 -0
  331. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  332. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
  333. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  334. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/rules-install-but-cannot-be-governed.md +0 -0
  335. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  336. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  337. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  338. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
  339. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  340. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
  341. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  342. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
  343. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
  344. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/search-never-notices-a-new-tap.md +0 -0
  345. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  346. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  347. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  348. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  349. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
  350. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
  351. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  352. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  353. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  354. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  355. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  356. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  357. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
  358. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  359. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  360. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
  361. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
  362. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  363. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  364. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  365. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  366. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  367. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
  368. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  369. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/update-advertises-a-flag-it-rejects.md +0 -0
  370. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  371. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/update-refreshed-rules-without-a-gate.md +0 -0
  372. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  373. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
  374. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  375. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  376. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  377. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
  378. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  379. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  380. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  381. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/workspace-scope-install.md +0 -0
  382. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/zip-strict-audit.md +0 -0
  383. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
  384. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/eslint.config.mjs +0 -0
  385. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/evals/README.md +0 -0
  386. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/evals/__init__.py +0 -0
  387. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/evals/baseline.json +0 -0
  388. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/evals/faithfulness.py +0 -0
  389. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/evals/golden_set.json +0 -0
  390. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/evals/make_corpus.py +0 -0
  391. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/evals/make_golden.py +0 -0
  392. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/evals/metrics.py +0 -0
  393. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/evals/run_evals.py +0 -0
  394. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/examples/README.md +0 -0
  395. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/examples/adapt-demo.sh +0 -0
  396. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/examples/boost-run-prototype.sh +0 -0
  397. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/index.html +0 -0
  398. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/noxfile.py +0 -0
  399. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/pyproject.toml +0 -0
  400. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/requirements/coverage-tools.in +0 -0
  401. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/requirements/coverage-tools.txt +0 -0
  402. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/requirements/lint-tools.in +0 -0
  403. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/requirements/lint-tools.txt +0 -0
  404. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/requirements/mutation-tools.in +0 -0
  405. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/requirements/mutation-tools.txt +0 -0
  406. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/requirements/platform-pins.lock +0 -0
  407. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/requirements/release-tools.in +0 -0
  408. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/requirements/release-tools.txt +0 -0
  409. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/requirements/test-tools.in +0 -0
  410. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/requirements/test-tools.txt +0 -0
  411. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/a11y_check.py +0 -0
  412. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/bench_cli.sh +0 -0
  413. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/build_command_reference.py +0 -0
  414. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/build_demo_index.py +0 -0
  415. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/build_registries.py +0 -0
  416. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/build_roadmap.py +0 -0
  417. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/build_scale_corpus.py +0 -0
  418. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/check_anchors.py +0 -0
  419. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/check_licenses.py +0 -0
  420. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/check_required_checks.py +0 -0
  421. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/ensure_eval_corpus.sh +0 -0
  422. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/eval_corpus.py +0 -0
  423. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/eval_explain.py +0 -0
  424. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/eval_gate.py +0 -0
  425. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/eval_recommend.py +0 -0
  426. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/eval_retrieval.py +0 -0
  427. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/eval_stats_summary.py +0 -0
  428. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/import_budget.py +0 -0
  429. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/lock_toolchain.py +0 -0
  430. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/mutation_gate.py +0 -0
  431. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/mutation_shards.py +0 -0
  432. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/mutation_weights.json +0 -0
  433. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/page_budget.py +0 -0
  434. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/perf_gate.py +0 -0
  435. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/post_deploy_smoke.py +0 -0
  436. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/publish_eval_json.py +0 -0
  437. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/release_guard.py +0 -0
  438. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/release_preflight.py +0 -0
  439. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/scripts/serve_docs.py +0 -0
  440. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/setup.cfg +0 -0
  441. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/sonar-project.properties +0 -0
  442. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/style/README.md +0 -0
  443. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/style/boost.css +0 -0
  444. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/style/boost.js +0 -0
  445. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/style/demo.html +0 -0
  446. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/adapt.feature +0 -0
  447. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/browse.feature +0 -0
  448. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/count.feature +0 -0
  449. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/discover.feature +0 -0
  450. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/doctor.feature +0 -0
  451. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/environment.py +0 -0
  452. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/explain.feature +0 -0
  453. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/index.feature +0 -0
  454. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/install.feature +0 -0
  455. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/list.feature +0 -0
  456. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/mcp.feature +0 -0
  457. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/search.feature +0 -0
  458. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/steps/cli_steps.py +0 -0
  459. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/steps/discovery_steps.py +0 -0
  460. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/steps/mcp_steps.py +0 -0
  461. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/bdd/features/steps/quality_steps.py +0 -0
  462. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/conftest.py +0 -0
  463. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/eval/baseline.json +0 -0
  464. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/eval/explain.jsonl +0 -0
  465. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/eval/golden-natural.jsonl +0 -0
  466. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/eval/golden.jsonl +0 -0
  467. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/eval/recommend.jsonl +0 -0
  468. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/eval/taps-scale.txt +0 -0
  469. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/eval/taps.txt +0 -0
  470. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_capabilities_policy.py +0 -0
  471. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_cli_adapt.py +0 -0
  472. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_cli_bmad.py +0 -0
  473. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_cli_chat.py +0 -0
  474. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_cli_configuration.py +0 -0
  475. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_cli_discovery.py +0 -0
  476. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_cli_hooks.py +0 -0
  477. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_cli_info.py +0 -0
  478. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_cli_intelligence.py +0 -0
  479. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_cli_pkg.py +0 -0
  480. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_cli_taps.py +0 -0
  481. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_cli_team.py +0 -0
  482. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_everyday_loop.py +0 -0
  483. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_integrity_enforce.py +0 -0
  484. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_property_parsers.py +0 -0
  485. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_run.py +0 -0
  486. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_tap_signing.py +0 -0
  487. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/functional/test_workspace_scope.py +0 -0
  488. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/README.md +0 -0
  489. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
  490. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
  491. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
  492. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
  493. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
  494. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
  495. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
  496. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
  497. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
  498. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
  499. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
  500. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
  501. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
  502. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/registry/02-https.txt +0 -0
  503. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
  504. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
  505. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
  506. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/registry/06-space.txt +0 -0
  507. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
  508. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
  509. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/fuzz_frontmatter.py +0 -0
  510. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/fuzz/fuzz_registry.py +0 -0
  511. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/make_fixture.py +0 -0
  512. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/perf/test_benchmarks.py +0 -0
  513. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/smoke.sh +0 -0
  514. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_a11y_check.py +0 -0
  515. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_adapters.py +0 -0
  516. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_adapters_multi.py +0 -0
  517. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_adapters_runner.py +0 -0
  518. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_agents.py +0 -0
  519. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_ai.py +0 -0
  520. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_capabilities.py +0 -0
  521. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_catalog.py +0 -0
  522. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_chat.py +0 -0
  523. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_check_anchors.py +0 -0
  524. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_check_licenses.py +0 -0
  525. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_claude_settings.py +0 -0
  526. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_cliparse.py +0 -0
  527. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_codeql_analysis_key.py +0 -0
  528. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_command_reference_fresh.py +0 -0
  529. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_community_health_files.py +0 -0
  530. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_complete.py +0 -0
  531. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_config.py +0 -0
  532. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_content_dedupe.py +0 -0
  533. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_dedup_trust.py +0 -0
  534. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_demo_index.py +0 -0
  535. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_dense.py +0 -0
  536. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_dense_fallback.py +0 -0
  537. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_dense_fix_hint.py +0 -0
  538. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_dense_shards.py +0 -0
  539. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_dense_status.py +0 -0
  540. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_dependabot_config.py +0 -0
  541. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_docs_pages_linked.py +0 -0
  542. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_docsite_chrome.py +0 -0
  543. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_ed25519.py +0 -0
  544. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_embed.py +0 -0
  545. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_embed_local.py +0 -0
  546. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_entry_key.py +0 -0
  547. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_errors_and_cli_table.py +0 -0
  548. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_eval_baseline.py +0 -0
  549. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_eval_corpus.py +0 -0
  550. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_eval_faithfulness.py +0 -0
  551. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_eval_gate.py +0 -0
  552. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_eval_grading.py +0 -0
  553. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_eval_metrics.py +0 -0
  554. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_eval_stats_summary.py +0 -0
  555. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_faithfulness.py +0 -0
  556. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_frontmatter.py +0 -0
  557. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_fuzz_targets.py +0 -0
  558. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_gitleaks_config.py +0 -0
  559. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_gitutil.py +0 -0
  560. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_imperative.py +0 -0
  561. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_import_budget.py +0 -0
  562. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_injectscan.py +0 -0
  563. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_installscan.py +0 -0
  564. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_integrity.py +0 -0
  565. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_journal.py +0 -0
  566. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_localembed.py +0 -0
  567. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_localembed_e2e.py +0 -0
  568. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_lockfile.py +0 -0
  569. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_logs.py +0 -0
  570. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_marketing_counts.py +0 -0
  571. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_mcp.py +0 -0
  572. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_mcp_install_scan.py +0 -0
  573. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_mcpdecl.py +0 -0
  574. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_mcphost.py +0 -0
  575. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_minisign.py +0 -0
  576. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_mutation_hardening.py +0 -0
  577. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_mutation_shards.py +0 -0
  578. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_mutation_subfile_shards.py +0 -0
  579. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_mutmut_source_paths.py +0 -0
  580. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_nethttp.py +0 -0
  581. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_output.py +0 -0
  582. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_page_budget.py +0 -0
  583. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_paths.py +0 -0
  584. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_perf_gate.py +0 -0
  585. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_pkg_confusions.py +0 -0
  586. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_pkg_injection.py +0 -0
  587. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_pkg_secrets.py +0 -0
  588. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_platform_pins.py +0 -0
  589. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_policy.py +0 -0
  590. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_post_deploy_smoke.py +0 -0
  591. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_project_mcp_sidecar.py +0 -0
  592. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_projectlock.py +0 -0
  593. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_provenance.py +0 -0
  594. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_rag.py +0 -0
  595. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_rag_fusion.py +0 -0
  596. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_registries_fresh.py +0 -0
  597. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_registry.py +0 -0
  598. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_registry_categories.py +0 -0
  599. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_release_guard.py +0 -0
  600. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_release_preflight.py +0 -0
  601. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_required_checks.py +0 -0
  602. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_resolve.py +0 -0
  603. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_roadmap_fresh.py +0 -0
  604. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_rules.py +0 -0
  605. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_scale_corpus.py +0 -0
  606. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_scopes.py +0 -0
  607. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_secretscan.py +0 -0
  608. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_selfupdate.py +0 -0
  609. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_serve.py +0 -0
  610. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_serve_docs.py +0 -0
  611. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_spin.py +0 -0
  612. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_stackprobe.py +0 -0
  613. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_staleness.py +0 -0
  614. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_store.py +0 -0
  615. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_token_parity.py +0 -0
  616. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_toolchain_lock.py +0 -0
  617. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_trustaudit.py +0 -0
  618. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_typosquat.py +0 -0
  619. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_updatediff.py +0 -0
  620. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_util.py +0 -0
  621. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_version.py +0 -0
  622. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_workflow_concurrency.py +0 -0
  623. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_workflow_timeouts.py +0 -0
  624. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/unit/test_workflows.py +0 -0
  625. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/visual/a11y_check.mjs +0 -0
  626. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/visual/console_check.mjs +0 -0
  627. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/visual/package-lock.json +0 -0
  628. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/visual/package.json +0 -0
  629. {boost_skill_cli-1.0.402 → boost_skill_cli-1.0.403}/tests/visual/visual_check.mjs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.402
3
+ Version: 1.0.403
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.0.402'
22
- __version_tuple__ = version_tuple = (1, 0, 402)
21
+ __version__ = version = '1.0.403'
22
+ __version_tuple__ = version_tuple = (1, 0, 403)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -76,17 +76,120 @@ _STACK_MARKERS = [
76
76
  _tilde = paths.tilde
77
77
 
78
78
 
79
- def _broken_links() -> List[Path]:
80
- """Broken (dangling) symlinks across every enabled agent dir."""
81
- broken: List[Path] = []
82
- for adir in agents.enabled_agents().values():
79
+ def _resolve_as_far_as_it_exists(path: Path) -> Path:
80
+ """Absolute ``path``, symlinks resolved down to its deepest real ancestor.
81
+
82
+ Plain ``resolve()`` is wrong on both sides of this comparison. The link's
83
+ target does not exist — that is what makes the link broken — and the store
84
+ dir does, so resolving only the one that can be resolved compares a real
85
+ path against a nominal one. On macOS that is not hypothetical: ``/tmp`` is
86
+ itself a symlink to ``/private/tmp``, so a genuine boost link read as
87
+ foreign and `heal` declined to repair anything.
88
+ """
89
+ path = Path(os.path.abspath(str(path)))
90
+ tail: List[str] = []
91
+ cur = path
92
+ while cur != cur.parent and not cur.exists():
93
+ tail.append(cur.name)
94
+ cur = cur.parent
95
+ with suppress(OSError):
96
+ cur = cur.resolve()
97
+ return cur.joinpath(*reversed(tail))
98
+
99
+
100
+ def _norm(path: Path) -> str:
101
+ """``path`` as a comparable string, without resolving anything.
102
+
103
+ Strips Windows' extended-length prefix — ``os.readlink`` returns
104
+ ``\\\\?\\C:\\...`` for a link the store created while ``store_dir()`` is
105
+ spelled the ordinary way, so the two name one location with two strings —
106
+ and applies `os.path.normcase`, which folds case on Windows (where the
107
+ filesystem is case-insensitive) and is a no-op on POSIX.
108
+ """
109
+ # Strip BEFORE abspath: on a POSIX host a backslash path is not absolute,
110
+ # so abspath would prepend the cwd and move the prefix out of position —
111
+ # which matters because this must be testable off Windows.
112
+ text = str(path)
113
+ for prefix in ("\\\\?\\UNC\\", "\\\\?\\"):
114
+ if text.startswith(prefix):
115
+ text = text[len(prefix):]
116
+ break
117
+ return os.path.normcase(os.path.abspath(text))
118
+
119
+
120
+ def _within(target: str, parent: str) -> bool:
121
+ """True if normalised ``target`` is ``parent`` or sits under it."""
122
+ return target == parent or target.startswith(parent.rstrip(os.sep) + os.sep)
123
+
124
+
125
+ def _link_key(path: Path) -> str:
126
+ """``path`` resolved, then normalised into a comparable string.
127
+
128
+ Comparing `Path` objects directly is wrong on Windows, in two ways that
129
+ both read as "boost does not own its own link" and left `heal` refusing to
130
+ repair anything at all there:
131
+
132
+ * ``os.readlink`` returns the extended-length form (``\\\\?\\C:\\...``) for
133
+ a link the store created, while ``store_dir()`` is spelled the ordinary
134
+ way — same location, different string.
135
+ * The filesystem is case-insensitive, so ``C:\\Users`` and ``c:\\users``
136
+ are one directory and two unequal `Path`s.
137
+
138
+ `os.path.normcase` is a no-op on POSIX, so this stays exact where case is.
139
+ """
140
+ return _norm(_resolve_as_far_as_it_exists(path))
141
+
142
+
143
+ def _owned_link(link: Path) -> bool:
144
+ """True if ``link`` points into boost's canonical store.
145
+
146
+ Ownership is read off the link itself rather than the lock, so it still
147
+ answers correctly for a skill uninstalled mid-sweep or a lock that has gone
148
+ missing — the two cases where a dangling link is most likely to exist.
149
+ """
150
+ try:
151
+ raw = Path(os.readlink(str(link)))
152
+ except OSError:
153
+ return False
154
+ target = raw if raw.is_absolute() else link.parent / raw
155
+ store = paths.store_dir()
156
+ # Spelled form first. A link boost made carries the store's own path, so
157
+ # this settles the ordinary case without resolving anything — and every
158
+ # platform quirk lives in resolution. Windows alone supplies three: the
159
+ # extended-length prefix, 8.3 short names, and case-insensitivity.
160
+ if _within(_norm(target), _norm(store)):
161
+ return True
162
+ # Resolved form second, for a store genuinely reached through a symlinked
163
+ # parent — macOS `/tmp` -> `/private/tmp` is the case that made this
164
+ # necessary rather than theoretical.
165
+ return _within(_link_key(target), _link_key(store))
166
+
167
+
168
+ def _broken_links() -> Tuple[List[Path], List[Path]]:
169
+ """``(ours, theirs)`` — dangling symlinks in the dirs boost links into.
170
+
171
+ Two things this deliberately does NOT do.
172
+
173
+ **It does not look in a native-store agent's dir.** `linking_agents`, not
174
+ `enabled_agents`: boost never links into `~/.gemini/skills`, so anything
175
+ dangling there belongs to someone else and is none of this command's
176
+ business. The rest of `cmd_heal` already had this right.
177
+
178
+ **It does not report a link boost did not create as ours.** `heal` deletes
179
+ what this returns first, and a broken link is not necessarily garbage — a
180
+ skill on an unmounted volume dangles until the volume comes back. Removing
181
+ a link the user made themselves is not a repair, it is data loss with a
182
+ reassuring name, so those are reported and left alone.
183
+ """
184
+ ours: List[Path] = []
185
+ theirs: List[Path] = []
186
+ for adir in agents.linking_agents().values():
83
187
  if not adir.is_dir():
84
188
  continue
85
- broken.extend(
86
- link for link in sorted(adir.iterdir())
87
- if link.is_symlink() and not link.exists()
88
- )
89
- return broken
189
+ for link in sorted(adir.iterdir()):
190
+ if link.is_symlink() and not link.exists():
191
+ (ours if _owned_link(link) else theirs).append(link)
192
+ return ours, theirs
90
193
 
91
194
 
92
195
  def _read_skill(skill_dir: Path) -> Tuple[dict, str]:
@@ -365,10 +468,18 @@ def cmd_doctor(argv):
365
468
  bad("%d orphaned store dir%s (%s) — run `boost sync`"
366
469
  % (len(orphans), _s(len(orphans)), ", ".join(orphans[:5])))
367
470
 
368
- broken = _broken_links()
471
+ broken, foreign = _broken_links()
369
472
  if broken:
370
473
  bad("%d broken symlink%s in agent dirs — run `boost heal`"
371
474
  % (len(broken), _s(len(broken))))
475
+ if foreign:
476
+ # `out.info`, not `bad`: this does not raise the issue count, because
477
+ # boost will not fix it and `heal` deliberately leaves it — counting it
478
+ # would leave doctor permanently red on something no boost command can
479
+ # clear, which is how a health check stops being read.
480
+ out.info("%d broken symlink%s in agent dirs not created by boost — "
481
+ "left alone; yours to remove or repair"
482
+ % (len(foreign), _s(len(foreign))))
372
483
 
373
484
  for adir in enabled.values():
374
485
  if adir.is_dir() and not os.access(str(adir), os.W_OK):
@@ -691,13 +802,19 @@ def cmd_heal(argv):
691
802
  % (len(missing), "y" if len(missing) == 1 else "ies"))
692
803
  actions.append("mkdir %d" % len(missing))
693
804
 
694
- for link in _broken_links():
805
+ ours, theirs = _broken_links()
806
+ for link in ours:
695
807
  if dry:
696
808
  out.info("would remove broken link %s" % _tilde(link))
697
809
  else:
698
810
  link.unlink()
699
811
  out.ok("removed broken link %s" % _tilde(link))
700
812
  actions.append("unlink %s" % link.name)
813
+ for link in theirs:
814
+ # Named, never touched: it is in a directory boost writes to, so the
815
+ # user should know it is dangling — but boost did not put it there.
816
+ out.warn("broken link %s does not point into %s — left alone"
817
+ % (_tilde(link), _tilde(paths.store_dir())))
701
818
 
702
819
  plan = store.sync_plan()
703
820
  if dry:
@@ -920,8 +1037,9 @@ def cmd_health(argv):
920
1037
  decay_n = sum(1 for r in _decay_rows(Path.cwd()) if r["verdict"] == "decay")
921
1038
  out.kv("decay", "%d candidate%s" % (decay_n, _s(decay_n)))
922
1039
 
923
- broken = _broken_links()
924
- out.kv("broken links", str(len(broken)))
1040
+ broken, foreign = _broken_links()
1041
+ out.kv("broken links", "%d%s" % (
1042
+ len(broken), " (+%d not ours)" % len(foreign) if foreign else ""))
925
1043
 
926
1044
  last_sync = "never"
927
1045
  if cloned and gitutil.has_git():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.402
3
+ Version: 1.0.403
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -235,6 +235,7 @@ docs/roadmap/items/github-pages-deploy-is-broken-every-push.md
235
235
  docs/roadmap/items/golden-set-grades-by-name-not-by-skill.md
236
236
  docs/roadmap/items/golden-set-statistical-power.md
237
237
  docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md
238
+ docs/roadmap/items/heal-deleted-links-it-never-made.md
238
239
  docs/roadmap/items/html-validation-html-validate.md
239
240
  docs/roadmap/items/info-rejects-the-qualified-name-it-recommends.md
240
241
  docs/roadmap/items/install-docs-never-mentioned-upgrading.md
@@ -560,6 +561,7 @@ tests/unit/test_injectscan.py
560
561
  tests/unit/test_installscan.py
561
562
  tests/unit/test_integrity.py
562
563
  tests/unit/test_journal.py
564
+ tests/unit/test_link_ownership.py
563
565
  tests/unit/test_localembed.py
564
566
  tests/unit/test_localembed_e2e.py
565
567
  tests/unit/test_lockfile.py
@@ -0,0 +1,54 @@
1
+ ---
2
+ id: heal-deleted-links-it-never-made
3
+ board: code
4
+ section: internals
5
+ status: shipped
6
+ category: Safety · Correctness
7
+ complexity: S
8
+ impact: Medium
9
+ wow: 4
10
+ note: a dangling link is not garbage — an unmounted volume comes back, and heal deleted it anyway
11
+ order: 99
12
+ owner: fix/heal-only-removes-links-it-owns
13
+ pr: 459
14
+ title: heal removed symlinks boost never created
15
+ ---
16
+ <b><code>boost heal</code> deleted a symlink boost did not make, does not track, and has no claim
17
+ to.</b> Reproduced against a sandbox: plant
18
+ <code>~/.claude/skills/my-own-skill&nbsp;&rarr;&nbsp;~/elsewhere/my-own-skill</code>, run
19
+ <code>boost heal</code>, and it reports <i>"removed broken link ~/.claude/skills/my-own-skill"</i>.
20
+ Same scenario on the fixed build leaves it exactly where it was.
21
+
22
+ <b>A broken link is not the same as garbage.</b> <code>~/.claude/skills/</code> is the user's own
23
+ directory that boost happens to link into. A dangling entry there can be a skill on an unmounted
24
+ volume, a repo checked out somewhere else for the afternoon, or a link into a detached drive
25
+ &mdash; all of which come back. Removing one is not a repair; it is data loss under a reassuring
26
+ name, from a command whose entire promise is that it is safe to run.
27
+
28
+ <b>Ownership is legible from the link itself.</b> Every link boost creates points into the canonical
29
+ store, <code>~/.agents/skills/&lt;name&gt;</code>. Reading the target beats consulting the lock,
30
+ because the two moments a dangling link is most likely to exist &mdash; a skill uninstalled
31
+ mid-sweep, a lock file that has gone missing &mdash; are exactly the moments the lock cannot answer.
32
+ Links into the store are swept; everything else is <i>named</i> and left alone, because the user
33
+ should still know it is dangling.
34
+
35
+ <b>The scan was also looking somewhere it has no business.</b> <code>_broken_links</code> iterated
36
+ <code>agents.enabled_agents()</code>, which includes Gemini &mdash; and boost never links into
37
+ <code>~/.gemini/skills</code> at all, because Gemini CLI reads the canonical store directly.
38
+ CLAUDE.md states the rule outright: iterate <code>linking_agents()</code> "for anything
39
+ symlink-shaped (link, unlink, stale-link sweeps, coverage counts)". The <i>same function</i> already
40
+ had it right eleven lines further down, where <code>cmd_heal</code> builds its list of missing
41
+ directories and comments on precisely this distinction.
42
+
43
+ <b>A macOS-only trap sat inside the fix.</b> The first attempt compared
44
+ <code>store_dir().resolve()</code> against a normalised link target &mdash; resolving the side that
45
+ exists and not the side that does not. On macOS <code>/tmp</code> is itself a symlink to
46
+ <code>/private/tmp</code>, so a genuine boost link read as foreign and <code>heal</code> declined to
47
+ repair anything at all. Both sides are now resolved down to their deepest real ancestor, which is
48
+ the only comparison that is correct when one path is dangling by definition.
49
+
50
+ <b><code>doctor</code> reports it without going red.</b> A foreign broken link is printed as
51
+ information, not counted as an issue: <code>heal</code> deliberately will not fix it, so counting it
52
+ would leave <code>doctor</code> permanently red on something no boost command can clear &mdash;
53
+ which is how a health check stops being read. Two tests pin the behaviour and both fail with the
54
+ ownership check reverted.
@@ -125,7 +125,7 @@
125
125
  <div class="stat"><b>16</b><span>Shipped</span></div>
126
126
  <div class="stat"><b>1</b><span>Next up</span></div>
127
127
  <div class="stat"><b>8</b><span>Planned</span></div>
128
- <div class="stat"><b>215</b><span>Loop finds</span></div>
128
+ <div class="stat"><b>216</b><span>Loop finds</span></div>
129
129
  <!-- /ROADMAP:stats -->
130
130
  </div>
131
131
  </section>
@@ -3470,6 +3470,57 @@ brake anyone can see, not a policy anyone can set.</p></details>
3470
3470
  <span class="m">install scanned rule content; update did not — and the scanner could not see concealment anyway</span>
3471
3471
  </div>
3472
3472
  </article>
3473
+
3474
+ <article class="cap rcard" id="heal-deleted-links-it-never-made">
3475
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Safety · Correctness</span></div>
3476
+ <h3>heal removed symlinks boost never created</h3>
3477
+ <details class="cardbody"><summary>Write-up</summary>
3478
+ <p><b><code>boost heal</code> deleted a symlink boost did not make, does not track, and has no claim
3479
+ to.</b> Reproduced against a sandbox: plant
3480
+ <code>~/.claude/skills/my-own-skill&nbsp;&rarr;&nbsp;~/elsewhere/my-own-skill</code>, run
3481
+ <code>boost heal</code>, and it reports <i>"removed broken link ~/.claude/skills/my-own-skill"</i>.
3482
+ Same scenario on the fixed build leaves it exactly where it was.
3483
+
3484
+ <b>A broken link is not the same as garbage.</b> <code>~/.claude/skills/</code> is the user's own
3485
+ directory that boost happens to link into. A dangling entry there can be a skill on an unmounted
3486
+ volume, a repo checked out somewhere else for the afternoon, or a link into a detached drive
3487
+ &mdash; all of which come back. Removing one is not a repair; it is data loss under a reassuring
3488
+ name, from a command whose entire promise is that it is safe to run.
3489
+
3490
+ <b>Ownership is legible from the link itself.</b> Every link boost creates points into the canonical
3491
+ store, <code>~/.agents/skills/&lt;name&gt;</code>. Reading the target beats consulting the lock,
3492
+ because the two moments a dangling link is most likely to exist &mdash; a skill uninstalled
3493
+ mid-sweep, a lock file that has gone missing &mdash; are exactly the moments the lock cannot answer.
3494
+ Links into the store are swept; everything else is <i>named</i> and left alone, because the user
3495
+ should still know it is dangling.
3496
+
3497
+ <b>The scan was also looking somewhere it has no business.</b> <code>_broken_links</code> iterated
3498
+ <code>agents.enabled_agents()</code>, which includes Gemini &mdash; and boost never links into
3499
+ <code>~/.gemini/skills</code> at all, because Gemini CLI reads the canonical store directly.
3500
+ CLAUDE.md states the rule outright: iterate <code>linking_agents()</code> "for anything
3501
+ symlink-shaped (link, unlink, stale-link sweeps, coverage counts)". The <i>same function</i> already
3502
+ had it right eleven lines further down, where <code>cmd_heal</code> builds its list of missing
3503
+ directories and comments on precisely this distinction.
3504
+
3505
+ <b>A macOS-only trap sat inside the fix.</b> The first attempt compared
3506
+ <code>store_dir().resolve()</code> against a normalised link target &mdash; resolving the side that
3507
+ exists and not the side that does not. On macOS <code>/tmp</code> is itself a symlink to
3508
+ <code>/private/tmp</code>, so a genuine boost link read as foreign and <code>heal</code> declined to
3509
+ repair anything at all. Both sides are now resolved down to their deepest real ancestor, which is
3510
+ the only comparison that is correct when one path is dangling by definition.
3511
+
3512
+ <b><code>doctor</code> reports it without going red.</b> A foreign broken link is printed as
3513
+ information, not counted as an issue: <code>heal</code> deliberately will not fix it, so counting it
3514
+ would leave <code>doctor</code> permanently red on something no boost command can clear &mdash;
3515
+ which is how a health check stops being read. Two tests pin the behaviour and both fail with the
3516
+ ownership check reverted.</p></details>
3517
+ <div class="meta">
3518
+ <span class="m">Complexity <b>S</b></span>
3519
+ <span class="m">Impact <b>Medium</b></span>
3520
+ <span class="m">Wow <b class="wow">★★★★</b></span>
3521
+ <span class="m">a dangling link is not garbage — an unmounted volume comes back, and heal deleted it anyway</span>
3522
+ </div>
3523
+ </article>
3473
3524
  <!-- /ROADMAP:cards -->
3474
3525
 
3475
3526
  </div>
@@ -79,6 +79,17 @@ class TestDoctor:
79
79
  assert "1 skill installed · 1 tap synced · 1 broken link" in r.out
80
80
  assert "need attention" in r.out # verdict flips on issues
81
81
 
82
+ def test_a_foreign_broken_link_is_reported_but_not_an_issue(
83
+ self, boost, installed):
84
+ # `heal` deliberately will not fix this, so counting it would leave
85
+ # doctor permanently red on something no boost command can clear.
86
+ mine = paths.home() / ".claude" / "skills" / "my-own-skill"
87
+ mine.symlink_to(paths.home() / "elsewhere" / "my-own-skill")
88
+ r = boost("doctor") # rc 0, not 1
89
+ assert "not created by boost" in r.out
90
+ assert "0 broken links" in r.out # none of boost's are broken
91
+ assert "need attention" not in r.out
92
+
82
93
  def test_missing_store_rc1(self, boost, installed):
83
94
  shutil.rmtree(paths.store_dir() / "brainstorming")
84
95
  r = boost("doctor", expect=1)
@@ -545,6 +556,34 @@ class TestHeal:
545
556
  r = boost("heal")
546
557
  assert "nothing to heal" in r.out
547
558
 
559
+ def test_a_link_boost_did_not_create_is_left_alone(self, boost, installed):
560
+ """`heal` deleted these. A broken link is not necessarily garbage.
561
+
562
+ `~/.claude/skills/` is a directory the user owns and boost merely links
563
+ into, so a dangling entry there can be a skill on an unmounted volume or
564
+ a repo temporarily moved — both of which come back. Removing it is not a
565
+ repair, it is data loss with a reassuring name.
566
+ """
567
+ mine = paths.home() / ".claude" / "skills" / "my-own-skill"
568
+ mine.symlink_to(paths.home() / "elsewhere" / "my-own-skill")
569
+
570
+ r = boost("heal")
571
+ assert "does not point into" in r.out
572
+ assert "left alone" in r.out
573
+ assert mine.is_symlink() # still there, still dangling
574
+ assert "removed broken link ~/.claude/skills/my-own-skill" not in r.out
575
+
576
+ def test_a_relative_link_into_the_store_is_still_ours(self, boost, installed):
577
+ # Ownership is decided by where the link points, not by how it is
578
+ # spelled — a relative target resolves against the link's own dir.
579
+ rel = paths.home() / ".claude" / "skills" / "relghost"
580
+ import os as _os
581
+ rel.symlink_to(_os.path.relpath(str(paths.store_dir() / "nowhere"),
582
+ str(rel.parent)))
583
+ r = boost("heal")
584
+ assert "removed broken link ~/.claude/skills/relghost" in r.out
585
+ assert not rel.is_symlink()
586
+
548
587
  def test_restores_missing_store_from_tap(self, boost, installed):
549
588
  shutil.rmtree(paths.store_dir() / "brainstorming")
550
589
  r = boost("heal")
@@ -0,0 +1,108 @@
1
+ """Unit tests: the link-ownership helpers behind `boost heal`.
2
+
3
+ `heal` deletes what it decides it owns, so the decision is worth pinning
4
+ directly rather than only through the command. These run on every platform
5
+ because they are string logic — the Windows shapes below are exactly what
6
+ made a genuine boost link read as foreign on `windows-latest` while passing
7
+ on Linux and macOS.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import os
12
+ from pathlib import Path
13
+
14
+ import pytest
15
+
16
+ from boost_cli.commands import quality
17
+
18
+
19
+ class TestNorm:
20
+ def test_it_folds_case_the_way_the_platform_does(self):
21
+ # A no-op on POSIX, case-folding on Windows. Asserting against
22
+ # os.path.normcase rather than a literal keeps this true on both.
23
+ assert quality._norm(Path("/A/B")) == os.path.normcase(
24
+ os.path.abspath("/A/B"))
25
+
26
+ def test_it_makes_a_relative_path_absolute(self):
27
+ assert os.path.isabs(quality._norm(Path("rel/ative")))
28
+
29
+ @pytest.mark.parametrize("prefixed,plain", [
30
+ ("\\\\?\\C:\\x\\y", "C:\\x\\y"),
31
+ ("\\\\?\\UNC\\srv\\share\\x", "srv\\share\\x"),
32
+ ])
33
+ def test_it_strips_windows_extended_length_prefixes(self, prefixed, plain):
34
+ """`os.readlink` returns this form; `store_dir()` never does.
35
+
36
+ One location, two strings — which is how `heal` concluded it did not
37
+ own a link it had created itself, and repaired nothing on Windows.
38
+ """
39
+ got = quality._norm(Path(prefixed))
40
+ assert "?" not in got # the prefix is gone, on any host
41
+ assert got.endswith(os.path.normcase(plain))
42
+
43
+
44
+ class TestWithin:
45
+ def test_a_path_is_within_itself(self):
46
+ assert quality._within("/a/b", "/a/b")
47
+
48
+ def test_a_child_is_within(self):
49
+ assert quality._within(os.sep.join(["", "a", "b", "c"]),
50
+ os.sep.join(["", "a", "b"]))
51
+
52
+ def test_a_sibling_with_a_shared_prefix_is_not(self):
53
+ # The bug a bare `startswith` would introduce: `/a/bc` is not under
54
+ # `/a/b`, and treating it as owned would delete a stranger's link.
55
+ assert not quality._within(os.sep.join(["", "a", "bc"]),
56
+ os.sep.join(["", "a", "b"]))
57
+
58
+ def test_a_parent_is_not_within_its_child(self):
59
+ assert not quality._within(os.sep.join(["", "a"]),
60
+ os.sep.join(["", "a", "b"]))
61
+
62
+ def test_a_trailing_separator_on_the_parent_does_not_break_it(self):
63
+ assert quality._within(os.sep.join(["", "a", "b", "c"]),
64
+ os.sep.join(["", "a", "b"]) + os.sep)
65
+
66
+
67
+ class TestOwnedLink:
68
+ def test_a_link_into_the_store_is_ours(self, tmp_path, monkeypatch):
69
+ store = tmp_path / "store"
70
+ store.mkdir()
71
+ monkeypatch.setattr(quality.paths, "store_dir", lambda: store)
72
+ link = tmp_path / "link"
73
+ link.symlink_to(store / "gone") # dangling, but ours
74
+ assert quality._owned_link(link)
75
+
76
+ def test_a_link_somewhere_else_is_not(self, tmp_path, monkeypatch):
77
+ store = tmp_path / "store"
78
+ store.mkdir()
79
+ monkeypatch.setattr(quality.paths, "store_dir", lambda: store)
80
+ link = tmp_path / "link"
81
+ link.symlink_to(tmp_path / "elsewhere" / "thing")
82
+ assert not quality._owned_link(link)
83
+
84
+ def test_a_relative_link_resolves_against_its_own_directory(
85
+ self, tmp_path, monkeypatch):
86
+ # Ownership is about where a link points, not how it is spelled.
87
+ store = tmp_path / "store"
88
+ store.mkdir()
89
+ monkeypatch.setattr(quality.paths, "store_dir", lambda: store)
90
+ link = tmp_path / "link"
91
+ link.symlink_to(os.path.join("store", "gone"))
92
+ assert quality._owned_link(link)
93
+
94
+ def test_a_sibling_directory_sharing_a_prefix_is_not_ours(
95
+ self, tmp_path, monkeypatch):
96
+ store = tmp_path / "skills"
97
+ store.mkdir()
98
+ monkeypatch.setattr(quality.paths, "store_dir", lambda: store)
99
+ link = tmp_path / "link"
100
+ link.symlink_to(tmp_path / "skills-backup" / "thing")
101
+ assert not quality._owned_link(link)
102
+
103
+ def test_something_that_is_not_a_link_is_not_ours(self, tmp_path,
104
+ monkeypatch):
105
+ monkeypatch.setattr(quality.paths, "store_dir", lambda: tmp_path)
106
+ plain = tmp_path / "file"
107
+ plain.write_text("x", encoding="utf-8")
108
+ assert not quality._owned_link(plain) # readlink raises; no crash