boost-skill-cli 1.0.296__tar.gz → 1.0.297__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 (548) hide show
  1. {boost_skill_cli-1.0.296/boost_skill_cli.egg-info → boost_skill_cli-1.0.297}/PKG-INFO +1 -1
  2. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/_version.py +2 -2
  3. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297/boost_skill_cli.egg-info}/PKG-INFO +1 -1
  4. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_skill_cli.egg-info/SOURCES.txt +3 -0
  5. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +19 -6
  6. boost_skill_cli-1.0.297/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +45 -0
  7. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap.html +59 -5
  8. boost_skill_cli-1.0.297/requirements/platform-pins.lock +58 -0
  9. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/lock_toolchain.py +179 -0
  10. boost_skill_cli-1.0.297/tests/unit/test_platform_pins.py +383 -0
  11. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/.gitattributes +0 -0
  12. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/.gitignore +0 -0
  13. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/.gitleaks.toml +0 -0
  14. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/.htmlvalidate.json +0 -0
  15. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/.lighthouserc.json +0 -0
  16. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/.lycheeignore +0 -0
  17. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/.markdownlint-cli2.jsonc +0 -0
  18. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/.pre-commit-config.yaml +0 -0
  19. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/.stylelintrc.json +0 -0
  20. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/.vale/styles/boost/Terminology.yml +0 -0
  21. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
  22. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/.vale.ini +0 -0
  23. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/CLAUDE.md +0 -0
  24. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/CODE_OF_CONDUCT.md +0 -0
  25. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/CONTRIBUTING.md +0 -0
  26. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/LICENSE +0 -0
  27. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/MANIFEST.in +0 -0
  28. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/Makefile +0 -0
  29. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/README.md +0 -0
  30. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/SECURITY.md +0 -0
  31. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost +0 -0
  32. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/__init__.py +0 -0
  33. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/__main__.py +0 -0
  34. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/cli.py +0 -0
  35. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/cliparse.py +0 -0
  36. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/__init__.py +0 -0
  37. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/_common.py +0 -0
  38. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/bmad.py +0 -0
  39. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/configuration.py +0 -0
  40. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/discovery.py +0 -0
  41. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/hooks.py +0 -0
  42. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/info.py +0 -0
  43. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/intelligence.py +0 -0
  44. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/pkg.py +0 -0
  45. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/quality.py +0 -0
  46. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/run.py +0 -0
  47. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/safety.py +0 -0
  48. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/taps.py +0 -0
  49. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/commands/team.py +0 -0
  50. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/__init__.py +0 -0
  51. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/adapters.py +0 -0
  52. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/agents.py +0 -0
  53. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/ai.py +0 -0
  54. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/capabilities.py +0 -0
  55. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/catalog.py +0 -0
  56. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/claude_settings.py +0 -0
  57. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/config.py +0 -0
  58. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/dense.py +0 -0
  59. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/ed25519.py +0 -0
  60. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/embed.py +0 -0
  61. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/faithfulness.py +0 -0
  62. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/frontmatter.py +0 -0
  63. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/gitutil.py +0 -0
  64. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/imperative.py +0 -0
  65. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/injectscan.py +0 -0
  66. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/installscan.py +0 -0
  67. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/integrity.py +0 -0
  68. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/journal.py +0 -0
  69. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/lockfile.py +0 -0
  70. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/logs.py +0 -0
  71. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/mcp.py +0 -0
  72. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/mcpdecl.py +0 -0
  73. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/mcphost.py +0 -0
  74. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/minisign.py +0 -0
  75. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/nethttp.py +0 -0
  76. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/output.py +0 -0
  77. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/paths.py +0 -0
  78. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/policy.py +0 -0
  79. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/projectlock.py +0 -0
  80. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/provenance.py +0 -0
  81. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/rag.py +0 -0
  82. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/registry.py +0 -0
  83. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/resolve.py +0 -0
  84. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/rules.py +0 -0
  85. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/scopes.py +0 -0
  86. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/secretscan.py +0 -0
  87. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/selfupdate.py +0 -0
  88. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/serve.py +0 -0
  89. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/stackprobe.py +0 -0
  90. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/staleness.py +0 -0
  91. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/store.py +0 -0
  92. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/trustaudit.py +0 -0
  93. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/typosquat.py +0 -0
  94. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/updatediff.py +0 -0
  95. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/util.py +0 -0
  96. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/core/workflows.py +0 -0
  97. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/data/registries.json +0 -0
  98. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/errors.py +0 -0
  99. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_cli/spin.py +0 -0
  100. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  101. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  102. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_skill_cli.egg-info/requires.txt +0 -0
  103. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/boost_skill_cli.egg-info/top_level.txt +0 -0
  104. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/codecov.yml +0 -0
  105. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/.claude/settings.local.json +0 -0
  106. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/DEBUGGING.md +0 -0
  107. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/adapters.html +0 -0
  108. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/gifs/distill.gif +0 -0
  109. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/gifs/doctor.gif +0 -0
  110. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/gifs/explain.gif +0 -0
  111. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/gifs/hooks.gif +0 -0
  112. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/gifs/install.gif +0 -0
  113. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/gifs/pulse.gif +0 -0
  114. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/gifs/search.gif +0 -0
  115. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/gifs/tap.gif +0 -0
  116. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/tapes/distill.tape +0 -0
  117. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/tapes/doctor.tape +0 -0
  118. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/tapes/explain.tape +0 -0
  119. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/tapes/hooks.tape +0 -0
  120. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/tapes/install.tape +0 -0
  121. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/tapes/pulse.tape +0 -0
  122. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/tapes/search.tape +0 -0
  123. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel/tapes/tap.tape +0 -0
  124. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/carousel.html +0 -0
  125. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/commands.html +0 -0
  126. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/demo.gif +0 -0
  127. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/demo.tape +0 -0
  128. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/design-roadmap.html +0 -0
  129. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/eval.html +0 -0
  130. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/index.html +0 -0
  131. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/mcp-hub.html +0 -0
  132. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/rag-architecture.md +0 -0
  133. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D01.md +0 -0
  134. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D02.md +0 -0
  135. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D03.md +0 -0
  136. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D04.md +0 -0
  137. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D05.md +0 -0
  138. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D06.md +0 -0
  139. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D07.md +0 -0
  140. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D08.md +0 -0
  141. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D09.md +0 -0
  142. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D10.md +0 -0
  143. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D11.md +0 -0
  144. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D12.md +0 -0
  145. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D13.md +0 -0
  146. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D14.md +0 -0
  147. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D15.md +0 -0
  148. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D16.md +0 -0
  149. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D17.md +0 -0
  150. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D18.md +0 -0
  151. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D19.md +0 -0
  152. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D20.md +0 -0
  153. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D21.md +0 -0
  154. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D22.md +0 -0
  155. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D23.md +0 -0
  156. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D24.md +0 -0
  157. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D25.md +0 -0
  158. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/BOOST-D26.md +0 -0
  159. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  160. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
  161. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
  162. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
  163. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
  164. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  165. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  166. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  167. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  168. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  169. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  170. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  171. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  172. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  173. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  174. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
  175. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
  176. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
  177. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  178. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
  179. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
  180. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/command-carousel-page.md +0 -0
  181. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  182. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  183. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  184. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  185. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  186. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
  187. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  188. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
  189. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
  190. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
  191. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
  192. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
  193. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  194. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
  195. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  196. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  197. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  198. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  199. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  200. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  201. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  202. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  203. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  204. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  205. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  206. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  207. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
  208. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/github-community-health-files.md +0 -0
  209. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  210. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  211. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  212. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  213. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
  214. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
  215. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
  216. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  217. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
  218. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  219. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  220. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
  221. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  222. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/license-compliance-scanning.md +0 -0
  223. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  224. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
  225. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  226. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  227. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
  228. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  229. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  230. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  231. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
  232. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
  233. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
  234. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  235. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  236. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
  237. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mcp-aware-skills.md +0 -0
  238. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
  239. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  240. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
  241. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  242. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  243. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
  244. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  245. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  246. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
  247. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
  248. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  249. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
  250. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  251. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  252. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  253. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
  254. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
  255. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
  256. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
  257. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  258. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
  259. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  260. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  261. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  262. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
  263. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  264. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
  265. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
  266. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  267. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  268. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
  269. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
  270. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  271. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  272. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  273. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  274. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  275. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
  276. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
  277. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
  278. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  279. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  280. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  281. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  282. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
  283. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
  284. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
  285. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/required-checks-config-drift.md +0 -0
  286. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  287. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  288. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
  289. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  290. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
  291. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  292. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  293. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  294. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  295. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
  296. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  297. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
  298. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  299. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
  300. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  301. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  302. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  303. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  304. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
  305. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
  306. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  307. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  308. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  309. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  310. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  311. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  312. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
  313. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  314. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  315. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
  316. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
  317. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  318. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  319. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  320. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  321. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  322. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
  323. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  324. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  325. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  326. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
  327. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  328. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  329. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  330. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
  331. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  332. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  333. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  334. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/workspace-scope-install.md +0 -0
  335. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
  336. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/eslint.config.mjs +0 -0
  337. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/evals/README.md +0 -0
  338. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/evals/__init__.py +0 -0
  339. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/evals/baseline.json +0 -0
  340. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/evals/faithfulness.py +0 -0
  341. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/evals/golden_set.json +0 -0
  342. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/evals/make_corpus.py +0 -0
  343. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/evals/make_golden.py +0 -0
  344. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/evals/metrics.py +0 -0
  345. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/evals/run_evals.py +0 -0
  346. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/examples/README.md +0 -0
  347. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/examples/adapt-demo.sh +0 -0
  348. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/examples/boost-run-prototype.sh +0 -0
  349. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/index.html +0 -0
  350. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/noxfile.py +0 -0
  351. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/pyproject.toml +0 -0
  352. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/requirements/coverage-tools.in +0 -0
  353. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/requirements/coverage-tools.txt +0 -0
  354. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/requirements/lint-tools.in +0 -0
  355. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/requirements/lint-tools.txt +0 -0
  356. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/requirements/mutation-tools.in +0 -0
  357. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/requirements/mutation-tools.txt +0 -0
  358. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/requirements/release-tools.in +0 -0
  359. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/requirements/release-tools.txt +0 -0
  360. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/requirements/test-tools.in +0 -0
  361. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/requirements/test-tools.txt +0 -0
  362. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/a11y_check.py +0 -0
  363. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/bench_cli.sh +0 -0
  364. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/build_command_reference.py +0 -0
  365. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/build_registries.py +0 -0
  366. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/build_roadmap.py +0 -0
  367. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/check_anchors.py +0 -0
  368. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/check_licenses.py +0 -0
  369. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/check_required_checks.py +0 -0
  370. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/ensure_eval_corpus.sh +0 -0
  371. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/eval_explain.py +0 -0
  372. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/eval_gate.py +0 -0
  373. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/eval_recommend.py +0 -0
  374. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/eval_retrieval.py +0 -0
  375. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/eval_stats_summary.py +0 -0
  376. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/import_budget.py +0 -0
  377. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/mutation_gate.py +0 -0
  378. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/mutation_shards.py +0 -0
  379. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/mutation_weights.json +0 -0
  380. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/perf_gate.py +0 -0
  381. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/post_deploy_smoke.py +0 -0
  382. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/release_guard.py +0 -0
  383. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/scripts/release_preflight.py +0 -0
  384. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/setup.cfg +0 -0
  385. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/sonar-project.properties +0 -0
  386. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/style/README.md +0 -0
  387. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/style/boost.css +0 -0
  388. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/style/boost.js +0 -0
  389. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/style/demo.html +0 -0
  390. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/adapt.feature +0 -0
  391. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/browse.feature +0 -0
  392. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/count.feature +0 -0
  393. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/discover.feature +0 -0
  394. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/doctor.feature +0 -0
  395. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/environment.py +0 -0
  396. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/explain.feature +0 -0
  397. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/index.feature +0 -0
  398. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/install.feature +0 -0
  399. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/list.feature +0 -0
  400. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/mcp.feature +0 -0
  401. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/search.feature +0 -0
  402. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/steps/cli_steps.py +0 -0
  403. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/steps/discovery_steps.py +0 -0
  404. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/steps/mcp_steps.py +0 -0
  405. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/bdd/features/steps/quality_steps.py +0 -0
  406. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/conftest.py +0 -0
  407. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/eval/baseline.json +0 -0
  408. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/eval/explain.jsonl +0 -0
  409. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/eval/golden.jsonl +0 -0
  410. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/eval/recommend.jsonl +0 -0
  411. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/eval/taps.txt +0 -0
  412. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_capabilities_policy.py +0 -0
  413. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_cli_adapt.py +0 -0
  414. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_cli_bmad.py +0 -0
  415. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_cli_configuration.py +0 -0
  416. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_cli_discovery.py +0 -0
  417. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_cli_hooks.py +0 -0
  418. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_cli_info.py +0 -0
  419. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_cli_intelligence.py +0 -0
  420. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_cli_pkg.py +0 -0
  421. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_cli_quality.py +0 -0
  422. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_cli_taps.py +0 -0
  423. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_cli_team.py +0 -0
  424. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_everyday_loop.py +0 -0
  425. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_integrity_enforce.py +0 -0
  426. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_property_parsers.py +0 -0
  427. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_run.py +0 -0
  428. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_tap_signing.py +0 -0
  429. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/functional/test_workspace_scope.py +0 -0
  430. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/README.md +0 -0
  431. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
  432. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
  433. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
  434. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
  435. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
  436. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
  437. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
  438. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
  439. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
  440. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
  441. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
  442. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
  443. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
  444. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/registry/02-https.txt +0 -0
  445. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
  446. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
  447. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
  448. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/registry/06-space.txt +0 -0
  449. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
  450. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
  451. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/fuzz_frontmatter.py +0 -0
  452. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/fuzz/fuzz_registry.py +0 -0
  453. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/make_fixture.py +0 -0
  454. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/perf/test_benchmarks.py +0 -0
  455. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/smoke.sh +0 -0
  456. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_a11y_check.py +0 -0
  457. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_adapters.py +0 -0
  458. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_adapters_multi.py +0 -0
  459. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_adapters_runner.py +0 -0
  460. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_agents.py +0 -0
  461. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_ai.py +0 -0
  462. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_capabilities.py +0 -0
  463. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_catalog.py +0 -0
  464. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_check_anchors.py +0 -0
  465. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_check_licenses.py +0 -0
  466. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_claude_settings.py +0 -0
  467. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_cliparse.py +0 -0
  468. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_codeql_analysis_key.py +0 -0
  469. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_command_reference_fresh.py +0 -0
  470. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_community_health_files.py +0 -0
  471. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_config.py +0 -0
  472. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_dense.py +0 -0
  473. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_dense_fallback.py +0 -0
  474. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_dependabot_config.py +0 -0
  475. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_docs_pages_linked.py +0 -0
  476. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_docsite_chrome.py +0 -0
  477. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_ed25519.py +0 -0
  478. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_embed.py +0 -0
  479. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_errors_and_cli_table.py +0 -0
  480. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_eval_faithfulness.py +0 -0
  481. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_eval_gate.py +0 -0
  482. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_eval_metrics.py +0 -0
  483. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_eval_stats_summary.py +0 -0
  484. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_faithfulness.py +0 -0
  485. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_frontmatter.py +0 -0
  486. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_fuzz_targets.py +0 -0
  487. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_gitleaks_config.py +0 -0
  488. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_gitutil.py +0 -0
  489. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_imperative.py +0 -0
  490. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_import_budget.py +0 -0
  491. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_injectscan.py +0 -0
  492. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_installscan.py +0 -0
  493. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_integrity.py +0 -0
  494. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_journal.py +0 -0
  495. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_lockfile.py +0 -0
  496. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_logs.py +0 -0
  497. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_marketing_counts.py +0 -0
  498. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_mcp.py +0 -0
  499. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_mcp_install_scan.py +0 -0
  500. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_mcpdecl.py +0 -0
  501. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_mcphost.py +0 -0
  502. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_minisign.py +0 -0
  503. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_mutation_hardening.py +0 -0
  504. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_mutation_shards.py +0 -0
  505. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_mutmut_source_paths.py +0 -0
  506. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_nethttp.py +0 -0
  507. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_output.py +0 -0
  508. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_paths.py +0 -0
  509. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_perf_gate.py +0 -0
  510. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_pkg_confusions.py +0 -0
  511. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_pkg_injection.py +0 -0
  512. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_pkg_secrets.py +0 -0
  513. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_policy.py +0 -0
  514. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_post_deploy_smoke.py +0 -0
  515. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_projectlock.py +0 -0
  516. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_provenance.py +0 -0
  517. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_rag.py +0 -0
  518. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_registries_fresh.py +0 -0
  519. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_registry.py +0 -0
  520. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_registry_categories.py +0 -0
  521. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_release_guard.py +0 -0
  522. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_release_preflight.py +0 -0
  523. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_required_checks.py +0 -0
  524. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_resolve.py +0 -0
  525. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_roadmap_fresh.py +0 -0
  526. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_rules.py +0 -0
  527. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_scopes.py +0 -0
  528. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_secretscan.py +0 -0
  529. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_selfupdate.py +0 -0
  530. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_serve.py +0 -0
  531. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_spin.py +0 -0
  532. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_stackprobe.py +0 -0
  533. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_staleness.py +0 -0
  534. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_store.py +0 -0
  535. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_token_parity.py +0 -0
  536. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_toolchain_lock.py +0 -0
  537. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_trustaudit.py +0 -0
  538. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_typosquat.py +0 -0
  539. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_updatediff.py +0 -0
  540. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_util.py +0 -0
  541. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_version.py +0 -0
  542. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_workflow_timeouts.py +0 -0
  543. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/unit/test_workflows.py +0 -0
  544. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/visual/a11y_check.mjs +0 -0
  545. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/visual/console_check.mjs +0 -0
  546. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/visual/package-lock.json +0 -0
  547. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/tests/visual/package.json +0 -0
  548. {boost_skill_cli-1.0.296 → boost_skill_cli-1.0.297}/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.296
3
+ Version: 1.0.297
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.296'
22
- __version_tuple__ = version_tuple = (1, 0, 296)
21
+ __version__ = version = '1.0.297'
22
+ __version_tuple__ = version_tuple = (1, 0, 297)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.296
3
+ Version: 1.0.297
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -297,6 +297,7 @@ docs/roadmap/items/sbom-declares-the-wrong-version.md
297
297
  docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md
298
298
  docs/roadmap/items/sbom-release-event-never-fires.md
299
299
  docs/roadmap/items/scan-and-sync-rules-and-workflows.md
300
+ docs/roadmap/items/scheduled-toolchain-lock-regeneration.md
300
301
  docs/roadmap/items/scorecard-findings-triage.md
301
302
  docs/roadmap/items/second-type-checker-pyright.md
302
303
  docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md
@@ -352,6 +353,7 @@ requirements/lint-tools.in
352
353
  requirements/lint-tools.txt
353
354
  requirements/mutation-tools.in
354
355
  requirements/mutation-tools.txt
356
+ requirements/platform-pins.lock
355
357
  requirements/release-tools.in
356
358
  requirements/release-tools.txt
357
359
  requirements/test-tools.in
@@ -506,6 +508,7 @@ tests/unit/test_perf_gate.py
506
508
  tests/unit/test_pkg_confusions.py
507
509
  tests/unit/test_pkg_injection.py
508
510
  tests/unit/test_pkg_secrets.py
511
+ tests/unit/test_platform_pins.py
509
512
  tests/unit/test_policy.py
510
513
  tests/unit/test_post_deploy_smoke.py
511
514
  tests/unit/test_projectlock.py
@@ -2,15 +2,15 @@
2
2
  id: dependabot-regeneration-drops-platform-pins
3
3
  board: code
4
4
  section: internals
5
- status: planned
5
+ status: shipped
6
6
  category: Build · Bug
7
7
  complexity: M
8
8
  impact: High
9
9
  wow: 3
10
10
  note: every pip bump PR is unmergeable — 2 of 2 observed, both red on the install step
11
11
  order: 36
12
- owner:
13
- pr:
12
+ owner: loop/dependabot-lock-guard
13
+ pr: 342
14
14
  title: Dependabot cannot regenerate the hash-pinned locks
15
15
  ---
16
16
  <b>Every Dependabot PR that touches <code>requirements/*.txt</code> is unmergeable</b>, and the
@@ -49,6 +49,19 @@ Dependabot bump can be <i>reproduced</i> rather than merged — take the version
49
49
  re-resolve that one package universally, and every other pin (markers included) stays as committed.
50
50
  Both open bumps were landed that way: <code>hypothesis</code> 6.161.6 to 6.163.0 and
51
51
  <code>twine</code> 6.2.0 to 7.0.0, four changed lines across five locks, with
52
- <code>colorama</code> and <code>pywin32-ctypes</code> intact. What remains is the config half —
53
- stopping Dependabot raising these at all — which is deliberately still open because its effect is
54
- only observable on the next scheduled run.
52
+ <code>colorama</code> and <code>pywin32-ctypes</code> intact.
53
+ <b>Shipped:</b> both remaining halves. The <code>/requirements</code> entry now carries
54
+ <code>open-pull-requests-limit: 0</code>, which switches off <i>version</i> updates — the ones that
55
+ regenerate the lock — while <b>security</b> updates ignore the limit and keep firing, so the entry
56
+ still earns its place. The <code>/</code> entry is untouched; narrowing that one is
57
+ [[dependabot-root-pip-entry-duplicates-requirements]].
58
+ And the guard the card asked for exists: <code>requirements/platform-pins.lock</code> records every
59
+ marker-gated pin <b>by name and marker but not version</b>, so a routine bump leaves it untouched
60
+ and only a change in the <i>shape</i> of a resolution moves a line.
61
+ <code>lock_toolchain.py --audit</code> diffs the locks against it and <b>runs first inside
62
+ <code>--check</code></b>, before uv is invoked at all — it reads only committed files, so it also
63
+ runs in the unit suite and on a runner that could not resolve. A lost pin now fails naming the
64
+ package, the group and the marker it lost, and prints the <code>-P</code> command that reproduces
65
+ the bump properly. A <i>lost</i> pin and a <i>new</i> pin are reported differently on purpose: the
66
+ same textual drift, but one is a broken install on a platform CI never resolves on and the other is
67
+ routine — collapsing them into one "stale" message is how this stayed invisible the first time.
@@ -0,0 +1,45 @@
1
+ ---
2
+ id: scheduled-toolchain-lock-regeneration
3
+ board: code
4
+ section: internals
5
+ status: planned
6
+ category: Build · Gap
7
+ complexity: M
8
+ impact: Med
9
+ wow: 2
10
+ note: the toolchain lock now has no proactive update path — by choice, but nothing replaces it yet
11
+ order: 36
12
+ owner:
13
+ pr:
14
+ title: The toolchain lock has no proactive update path any more
15
+ ---
16
+ <code>#342</code> set <code>open-pull-requests-limit: 0</code> on the <code>/requirements</code>
17
+ Dependabot entry, because Dependabot cannot regenerate a hash-pinned universal lock without dropping
18
+ the pins whose environment markers exclude them on the resolving platform (see
19
+ [[dependabot-regeneration-drops-platform-pins]]). That was the right call — every pip bump it raised
20
+ was unmergeable — but it reverses the reason the entry was added in the first place: <b>a pin with no
21
+ update path is only half the job</b>, and the dev/CI toolchain now has none.
22
+
23
+ The trade is bounded rather than silent, which is why this is <code>Med</code> and not
24
+ <code>High</code>. Dependabot <b>security</b> updates ignore the limit and still fire;
25
+ <code>pip-audit.yml</code> runs weekly against the resolved closure and <b>blocks</b> on a live CVE
26
+ (Dependabot only ever opened a PR); and <code>osv-scanner.yml</code> covers what a PR introduces. So
27
+ the exposure is not "a vulnerable pin sits there unnoticed" — it is
28
+ <b>stale-but-not-vulnerable tooling</b>, drifting further from upstream every week until something
29
+ forces a bump.
30
+
31
+ The replacement the card already named: regenerate on a schedule with
32
+ <code>scripts/lock_toolchain.py --upgrade</code> and open the PR from that, so the resolution stays
33
+ universal and every conditional pin survives. Four points worth getting right rather than guessing.
34
+ <b>First</b>, it needs <code>uv</code> and the network — the required gate's <code>--check</code>
35
+ already assumes both on CI, but no scheduled job currently sets them up. <b>Second</b>,
36
+ <code>--upgrade</code> re-resolves all five groups, so a weekly cadence would land large multi-group
37
+ diffs; per-group jobs, or a lower cadence, keep a bump reviewable, and the reason <code>-P</code>
38
+ exists at all is that a bare <code>--upgrade</code> buries one package in unrelated churn.
39
+ <b>Third</b>, a new workflow is not free in this repo: it must be zizmor-clean with every
40
+ <code>uses:</code> pinned to a <i>peeled</i> commit SHA, carry narrow <code>permissions</code>, and
41
+ — if it is ever made a required context — grow a <code>merge_group:</code> trigger, which
42
+ <code>check_required_checks.py</code> enforces. <b>Fourth</b>, nothing needs to guard the output:
43
+ <code>lock_toolchain.py --audit</code> and <code>requirements/platform-pins.lock</code> already fail
44
+ closed on a lost marker-gated pin, so a regeneration job that got it wrong would be caught the same
45
+ way a Dependabot PR now is.
@@ -111,7 +111,7 @@
111
111
  <div class="stat"><b>16</b><span>Shipped</span></div>
112
112
  <div class="stat"><b>1</b><span>Next up</span></div>
113
113
  <div class="stat"><b>4</b><span>Planned</span></div>
114
- <div class="stat"><b>178</b><span>Loop finds</span></div>
114
+ <div class="stat"><b>179</b><span>Loop finds</span></div>
115
115
  <!-- /ROADMAP:stats -->
116
116
  </div>
117
117
  </section>
@@ -1219,7 +1219,7 @@ lock file silently clobbers it and still reports "created," even though it overw
1219
1219
  </article>
1220
1220
 
1221
1221
  <article class="cap rcard" id="dependabot-regeneration-drops-platform-pins">
1222
- <div class="head"><span class="pill planned">Planned</span><span class="cat">Build · Bug</span></div>
1222
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Build · Bug</span></div>
1223
1223
  <h3>Dependabot cannot regenerate the hash-pinned locks</h3>
1224
1224
  <p><b>Every Dependabot PR that touches <code>requirements/*.txt</code> is unmergeable</b>, and the
1225
1225
  failure is not in the bumped package. Dependabot re-resolves the lock on Linux and writes that
@@ -1257,9 +1257,22 @@ Dependabot bump can be <i>reproduced</i> rather than merged — take the version
1257
1257
  re-resolve that one package universally, and every other pin (markers included) stays as committed.
1258
1258
  Both open bumps were landed that way: <code>hypothesis</code> 6.161.6 to 6.163.0 and
1259
1259
  <code>twine</code> 6.2.0 to 7.0.0, four changed lines across five locks, with
1260
- <code>colorama</code> and <code>pywin32-ctypes</code> intact. What remains is the config half —
1261
- stopping Dependabot raising these at all — which is deliberately still open because its effect is
1262
- only observable on the next scheduled run.</p>
1260
+ <code>colorama</code> and <code>pywin32-ctypes</code> intact.
1261
+ <b>Shipped:</b> both remaining halves. The <code>/requirements</code> entry now carries
1262
+ <code>open-pull-requests-limit: 0</code>, which switches off <i>version</i> updates — the ones that
1263
+ regenerate the lock — while <b>security</b> updates ignore the limit and keep firing, so the entry
1264
+ still earns its place. The <code>/</code> entry is untouched; narrowing that one is
1265
+ [[dependabot-root-pip-entry-duplicates-requirements]].
1266
+ And the guard the card asked for exists: <code>requirements/platform-pins.lock</code> records every
1267
+ marker-gated pin <b>by name and marker but not version</b>, so a routine bump leaves it untouched
1268
+ and only a change in the <i>shape</i> of a resolution moves a line.
1269
+ <code>lock_toolchain.py --audit</code> diffs the locks against it and <b>runs first inside
1270
+ <code>--check</code></b>, before uv is invoked at all — it reads only committed files, so it also
1271
+ runs in the unit suite and on a runner that could not resolve. A lost pin now fails naming the
1272
+ package, the group and the marker it lost, and prints the <code>-P</code> command that reproduces
1273
+ the bump properly. A <i>lost</i> pin and a <i>new</i> pin are reported differently on purpose: the
1274
+ same textual drift, but one is a broken install on a platform CI never resolves on and the other is
1275
+ routine — collapsing them into one "stale" message is how this stayed invisible the first time.</p>
1263
1276
  <div class="meta">
1264
1277
  <span class="m">Complexity <b>M</b></span>
1265
1278
  <span class="m hi">Impact <b>High</b></span>
@@ -1284,6 +1297,47 @@ validator that rejects values below 1; reuse it here.</p>
1284
1297
  </div>
1285
1298
  </article>
1286
1299
 
1300
+ <article class="cap rcard" id="scheduled-toolchain-lock-regeneration">
1301
+ <div class="head"><span class="pill planned">Planned</span><span class="cat">Build · Gap</span></div>
1302
+ <h3>The toolchain lock has no proactive update path any more</h3>
1303
+ <p><code>#342</code> set <code>open-pull-requests-limit: 0</code> on the <code>/requirements</code>
1304
+ Dependabot entry, because Dependabot cannot regenerate a hash-pinned universal lock without dropping
1305
+ the pins whose environment markers exclude them on the resolving platform (see
1306
+ [[dependabot-regeneration-drops-platform-pins]]). That was the right call — every pip bump it raised
1307
+ was unmergeable — but it reverses the reason the entry was added in the first place: <b>a pin with no
1308
+ update path is only half the job</b>, and the dev/CI toolchain now has none.
1309
+
1310
+ The trade is bounded rather than silent, which is why this is <code>Med</code> and not
1311
+ <code>High</code>. Dependabot <b>security</b> updates ignore the limit and still fire;
1312
+ <code>pip-audit.yml</code> runs weekly against the resolved closure and <b>blocks</b> on a live CVE
1313
+ (Dependabot only ever opened a PR); and <code>osv-scanner.yml</code> covers what a PR introduces. So
1314
+ the exposure is not "a vulnerable pin sits there unnoticed" — it is
1315
+ <b>stale-but-not-vulnerable tooling</b>, drifting further from upstream every week until something
1316
+ forces a bump.
1317
+
1318
+ The replacement the card already named: regenerate on a schedule with
1319
+ <code>scripts/lock_toolchain.py --upgrade</code> and open the PR from that, so the resolution stays
1320
+ universal and every conditional pin survives. Four points worth getting right rather than guessing.
1321
+ <b>First</b>, it needs <code>uv</code> and the network — the required gate's <code>--check</code>
1322
+ already assumes both on CI, but no scheduled job currently sets them up. <b>Second</b>,
1323
+ <code>--upgrade</code> re-resolves all five groups, so a weekly cadence would land large multi-group
1324
+ diffs; per-group jobs, or a lower cadence, keep a bump reviewable, and the reason <code>-P</code>
1325
+ exists at all is that a bare <code>--upgrade</code> buries one package in unrelated churn.
1326
+ <b>Third</b>, a new workflow is not free in this repo: it must be zizmor-clean with every
1327
+ <code>uses:</code> pinned to a <i>peeled</i> commit SHA, carry narrow <code>permissions</code>, and
1328
+ — if it is ever made a required context — grow a <code>merge_group:</code> trigger, which
1329
+ <code>check_required_checks.py</code> enforces. <b>Fourth</b>, nothing needs to guard the output:
1330
+ <code>lock_toolchain.py --audit</code> and <code>requirements/platform-pins.lock</code> already fail
1331
+ closed on a lost marker-gated pin, so a regeneration job that got it wrong would be caught the same
1332
+ way a Dependabot PR now is.</p>
1333
+ <div class="meta">
1334
+ <span class="m">Complexity <b>M</b></span>
1335
+ <span class="m">Impact <b>Med</b></span>
1336
+ <span class="m">Wow <b class="wow">★★</b></span>
1337
+ <span class="m">the toolchain lock now has no proactive update path — by choice, but nothing replaces it yet</span>
1338
+ </div>
1339
+ </article>
1340
+
1287
1341
  <article class="cap rcard" id="crash-listing-branch-untested">
1288
1342
  <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Testing · Bug</span></div>
1289
1343
  <h3><code>boost log --crashes</code> listing branch has no non-empty test</h3>
@@ -0,0 +1,58 @@
1
+ # GENERATED by scripts/lock_toolchain.py — DO NOT EDIT.
2
+ #
3
+ # NOT a requirements file — there are no versions and no hashes here,
4
+ # and nothing installs it. It records which pins in requirements/*.txt
5
+ # carry an environment marker, so that LOSING one is a red gate.
6
+ #
7
+ # Why: a lock re-resolved on a single platform (which is what
8
+ # Dependabot commits) silently drops every pin whose marker excludes it
9
+ # there. The locks install with --require-hashes on Windows and macOS
10
+ # too, so a dropped pin is an install failure on the platform that
11
+ # needed it — reported against the install step, never naming the
12
+ # package. `lock_toolchain.py --audit` diffs the locks against this
13
+ # file and names it.
14
+ #
15
+ # Versions are deliberately absent: a routine bump must not churn this
16
+ # file, or regenerating it becomes reflexive and it stops being a
17
+ # tripwire. Only a change in the SHAPE of the resolution moves a line.
18
+
19
+ [lint-tools]
20
+ librt ; platform_python_implementation != 'PyPy'
21
+
22
+ [test-tools]
23
+ attrs ; python_full_version < '3.10'
24
+ colorama ; sys_platform == 'win32'
25
+ coverage ; python_full_version < '3.10'
26
+ coverage ; python_full_version >= '3.10'
27
+ exceptiongroup ; python_full_version < '3.11'
28
+ hypothesis ; python_full_version < '3.10'
29
+ hypothesis ; python_full_version >= '3.10'
30
+ iniconfig ; python_full_version < '3.10'
31
+ iniconfig ; python_full_version >= '3.10'
32
+ pytest ; python_full_version < '3.10'
33
+ pytest ; python_full_version >= '3.10'
34
+ tomli ; python_full_version <= '3.11'
35
+ typing-extensions ; python_full_version < '3.11'
36
+
37
+ [mutation-tools]
38
+ colorama ; sys_platform == 'win32'
39
+ pyyaml ; python_full_version != '3.13.*'
40
+ pyyaml-ft ; python_full_version == '3.13.*'
41
+ tomli ; python_full_version <= '3.11'
42
+
43
+ [coverage-tools]
44
+ colorama ; sys_platform == 'win32'
45
+
46
+ [release-tools]
47
+ cffi ; platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_python_implementation != 'PyPy' and sys_platform == 'linux'
48
+ colorama ; os_name == 'nt' or sys_platform == 'win32'
49
+ cryptography ; platform_machine != 'ppc64le' and platform_machine != 's390x' and sys_platform == 'linux'
50
+ jaraco-classes ; platform_machine != 'ppc64le' and platform_machine != 's390x'
51
+ jaraco-context ; platform_machine != 'ppc64le' and platform_machine != 's390x'
52
+ jaraco-functools ; platform_machine != 'ppc64le' and platform_machine != 's390x'
53
+ jeepney ; platform_machine != 'ppc64le' and platform_machine != 's390x' and sys_platform == 'linux'
54
+ keyring ; platform_machine != 'ppc64le' and platform_machine != 's390x'
55
+ more-itertools ; platform_machine != 'ppc64le' and platform_machine != 's390x'
56
+ pycparser ; implementation_name != 'PyPy' and platform_machine != 'ppc64le' and platform_machine != 's390x' and platform_python_implementation != 'PyPy' and sys_platform == 'linux'
57
+ pywin32-ctypes ; platform_machine != 'ppc64le' and platform_machine != 's390x' and sys_platform == 'win32'
58
+ secretstorage ; platform_machine != 'ppc64le' and platform_machine != 's390x' and sys_platform == 'linux'
@@ -3,6 +3,7 @@
3
3
 
4
4
  python3 scripts/lock_toolchain.py # regenerate requirements/*.txt
5
5
  python3 scripts/lock_toolchain.py --check # fail (exit 1) on drift
6
+ python3 scripts/lock_toolchain.py --audit # fail on a LOST platform pin
6
7
  python3 scripts/lock_toolchain.py --upgrade # re-resolve to newest allowed
7
8
  python3 scripts/lock_toolchain.py -P twine # re-resolve ONE package
8
9
 
@@ -31,6 +32,15 @@ The ``--check`` form runs in CI's lint job and in ``make lint``, exactly like
31
32
  ``build_registries.py --check`` / ``build_roadmap.py --check``: the generated
32
33
  file is committed, and a stale one is a red gate rather than a surprise later.
33
34
 
35
+ ``--audit`` is the guard for the failure above, and it runs *first* inside
36
+ ``--check``. ``requirements/platform-pins.lock`` records every marker-gated pin
37
+ by **name and marker but not version**, so a routine bump leaves it untouched
38
+ and only a change in the *shape* of the resolution moves it. Losing a pin then
39
+ fails here, naming the package and the marker, instead of surfacing three jobs
40
+ later as an install-step error that never mentions it. Unlike ``--check`` the
41
+ audit reads only committed files — no uv, no network — so it also runs in the
42
+ unit suite (``tests/unit/test_platform_pins.py``) and on any runner.
43
+
34
44
  Why hash-pinned requirements rather than ``uv.lock``:
35
45
 
36
46
  * ``[project].dependencies`` is empty and must stay that way — boost's runtime
@@ -63,6 +73,12 @@ from pathlib import Path
63
73
  ROOT = Path(__file__).resolve().parent.parent
64
74
  REQS = ROOT / "requirements"
65
75
 
76
+ # The committed memory of which pins are conditional. Deliberately NOT a .txt:
77
+ # tests/unit/test_toolchain_lock.py requires every requirements/*.txt to have a
78
+ # matching .in declaration, and the suffix also keeps pip and OSV-Scanner from
79
+ # mistaking a hashless manifest for something installable.
80
+ PLATFORM_PINS = REQS / "platform-pins.lock"
81
+
66
82
  # (stem, python-version) for each group. Every group resolves --universal.
67
83
  #
68
84
  # Universal is not optional for a *committed* lock. Without it uv resolves for
@@ -117,6 +133,134 @@ def _uv() -> str:
117
133
  return str(local) if local.exists() else (shutil.which("uv") or "uv")
118
134
 
119
135
 
136
+ def _manifest_header() -> str:
137
+ """The stable banner for requirements/platform-pins.lock."""
138
+ return (
139
+ "# GENERATED by scripts/lock_toolchain.py — DO NOT EDIT.\n"
140
+ "#\n"
141
+ "# NOT a requirements file — there are no versions and no hashes here,\n"
142
+ "# and nothing installs it. It records which pins in requirements/*.txt\n"
143
+ "# carry an environment marker, so that LOSING one is a red gate.\n"
144
+ "#\n"
145
+ "# Why: a lock re-resolved on a single platform (which is what\n"
146
+ "# Dependabot commits) silently drops every pin whose marker excludes it\n"
147
+ "# there. The locks install with --require-hashes on Windows and macOS\n"
148
+ "# too, so a dropped pin is an install failure on the platform that\n"
149
+ "# needed it — reported against the install step, never naming the\n"
150
+ "# package. `lock_toolchain.py --audit` diffs the locks against this\n"
151
+ "# file and names it.\n"
152
+ "#\n"
153
+ "# Versions are deliberately absent: a routine bump must not churn this\n"
154
+ "# file, or regenerating it becomes reflexive and it stops being a\n"
155
+ "# tripwire. Only a change in the SHAPE of the resolution moves a line.\n"
156
+ )
157
+
158
+
159
+ def marker_pins(text: str) -> tuple[tuple[str, str], ...]:
160
+ """The (name, marker) of every marker-gated pin in one compiled lock.
161
+
162
+ Sorted and de-duplicated so the result depends on the resolution, not on the
163
+ order uv happened to emit — that keeps ``render``/``parse`` exactly
164
+ reciprocal and stops a cosmetic reshuffle reading as drift.
165
+
166
+ Unmarked pins are ignored on purpose: they install everywhere, so losing one
167
+ is ordinary drift that ``--check`` already catches. This guard is only about
168
+ the conditional pins, which are invisible to a single-platform resolve.
169
+ """
170
+ pins = set()
171
+ for raw in text.splitlines():
172
+ # Every uv pin line ends in ` \` before its indented --hash block.
173
+ line = raw.strip().rstrip("\\").strip()
174
+ if not line or line.startswith("#") or line.startswith("-"):
175
+ continue # comment, --hash, -r, --index-url
176
+ head, sep, marker = line.partition(";")
177
+ if not sep or "==" not in head:
178
+ continue # unmarked, or not a pin at all
179
+ name = head.split("==")[0].strip() # keeps any `[extra]`
180
+ if name:
181
+ # Collapse whitespace so cosmetic spacing is not a change.
182
+ pins.add((name, " ".join(marker.split())))
183
+ return tuple(sorted(pins))
184
+
185
+
186
+ def render_platform_pins(locks: "dict[str, str]") -> str:
187
+ """The manifest text recording the marker-gated pins of `locks`.
188
+
189
+ A group with no conditional pins still gets its section header, so the
190
+ manifest states "none here" rather than staying silent about it.
191
+ """
192
+ out = [_manifest_header()]
193
+ for stem, _python_version in GROUPS:
194
+ if stem not in locks:
195
+ continue
196
+ out.append("\n[%s]\n" % stem)
197
+ for name, marker in marker_pins(locks[stem]):
198
+ out.append("%s ; %s\n" % (name, marker))
199
+ return "".join(out)
200
+
201
+
202
+ def parse_platform_pins(text: str) -> "dict[str, tuple[tuple[str, str], ...]]":
203
+ """`{group: ((name, marker), ...)}` as recorded by a manifest."""
204
+ out: "dict[str, list[tuple[str, str]]]" = {}
205
+ stem = None
206
+ for raw in text.splitlines():
207
+ line = raw.strip()
208
+ if not line or line.startswith("#"):
209
+ continue
210
+ if line.startswith("[") and line.endswith("]"):
211
+ stem = line[1:-1]
212
+ out.setdefault(stem, [])
213
+ continue
214
+ if stem is None:
215
+ continue
216
+ name, _sep, marker = line.partition(";")
217
+ out[stem].append((name.strip(), " ".join(marker.split())))
218
+ return {k: tuple(v) for k, v in out.items()}
219
+
220
+
221
+ def read_locks() -> "dict[str, str]":
222
+ """The committed text of every group's generated lock."""
223
+ return {stem: (REQS / ("%s.txt" % stem)).read_text(encoding="utf-8")
224
+ for stem, _python_version in GROUPS}
225
+
226
+
227
+ def audit_platform_pins(locks: "dict[str, str]",
228
+ manifest_text: str) -> "list[str]":
229
+ """Problems found comparing `locks` against the recorded manifest.
230
+
231
+ A LOST pin and a NEW pin are reported differently on purpose. They are the
232
+ same textual drift but opposite in meaning: one is a broken install on a
233
+ platform CI never resolves on, the other is a routine addition that only
234
+ needs the manifest regenerating. Collapsing them into one "stale" message is
235
+ how the original failure stayed invisible.
236
+ """
237
+ recorded = parse_platform_pins(manifest_text)
238
+ problems = []
239
+ for stem, _python_version in GROUPS:
240
+ if stem not in locks:
241
+ continue
242
+ want = set(recorded.get(stem, ()))
243
+ have = set(marker_pins(locks[stem]))
244
+ for name, marker in sorted(want - have):
245
+ problems.append(
246
+ "%s: LOST %s ; %s\n"
247
+ " The lock no longer carries this marker-gated pin, so a\n"
248
+ " --require-hashes install fails on the platform the marker\n"
249
+ " selects. This is what a lock re-resolved on one platform\n"
250
+ " looks like — do not merge it. Reproduce the bump instead:\n"
251
+ " python3 scripts/lock_toolchain.py -P %s"
252
+ % (stem, name, marker, name))
253
+ for name, marker in sorted(have - want):
254
+ problems.append(
255
+ "%s: NEW %s ; %s\n"
256
+ " A marker-gated pin that requirements/platform-pins.lock\n"
257
+ " does not record. If this addition is intended, run\n"
258
+ " python3 scripts/lock_toolchain.py\n"
259
+ " and commit the regenerated manifest."
260
+ % (stem, name, marker))
261
+ return problems
262
+
263
+
120
264
  def compile_group(stem: str, python_version: str, upgrade: bool,
121
265
  packages: Sequence[str] = ()) -> str:
122
266
  """Resolve one group and return the file contents we want on disk.
@@ -167,6 +311,9 @@ def main() -> int:
167
311
  ap = argparse.ArgumentParser(description=__doc__)
168
312
  ap.add_argument("--check", action="store_true",
169
313
  help="exit 1 if any generated file is stale")
314
+ ap.add_argument("--audit", action="store_true",
315
+ help="exit 1 if a lock has lost a marker-gated pin "
316
+ "(no uv, no network — runs first inside --check)")
170
317
  ap.add_argument("--upgrade", action="store_true",
171
318
  help="re-resolve to the newest versions the .in files allow")
172
319
  ap.add_argument("-P", "--upgrade-package", action="append", default=[],
@@ -183,6 +330,30 @@ def main() -> int:
183
330
  # --upgrade already re-resolves everything, so naming a package on top
184
331
  # of it reads as a narrowing that is not happening.
185
332
  raise SystemExit("lock_toolchain: --upgrade and -P are exclusive")
333
+ if args.audit and (args.upgrade or args.upgrade_package):
334
+ # The audit reads what is committed; re-resolving in the same breath
335
+ # would audit a file the caller is in the middle of replacing.
336
+ raise SystemExit(
337
+ "lock_toolchain: --audit cannot be combined with --upgrade/-P")
338
+
339
+ # Before anything that needs uv or the network. A lost platform pin is the
340
+ # failure that costs three Windows jobs and never names the package, so it
341
+ # is reported here even on a runner that could not resolve at all.
342
+ if args.audit or args.check:
343
+ problems = audit_platform_pins(
344
+ read_locks(),
345
+ PLATFORM_PINS.read_text(encoding="utf-8")
346
+ if PLATFORM_PINS.exists() else "")
347
+ if problems:
348
+ print("platform-pin audit FAILED:\n")
349
+ for problem in problems:
350
+ print(" %s\n" % problem)
351
+ return 1
352
+ print("platform pins intact.")
353
+ if args.audit and not args.check:
354
+ return 0
355
+ # `--check --audit` asked for both, so fall through to the drift check
356
+ # rather than letting the cheaper flag silently swallow the other.
186
357
 
187
358
  stale = []
188
359
  for stem, python_version in GROUPS:
@@ -197,6 +368,14 @@ def main() -> int:
197
368
  target.write_text(want, encoding="utf-8")
198
369
  print("wrote %s" % target.relative_to(ROOT))
199
370
 
371
+ if not args.check:
372
+ # Recorded from what was just written, so the manifest and the locks
373
+ # can only ever disagree when something regenerated the locks WITHOUT
374
+ # going through this script — which is precisely the case to catch.
375
+ PLATFORM_PINS.write_text(render_platform_pins(read_locks()),
376
+ encoding="utf-8")
377
+ print("wrote %s" % PLATFORM_PINS.relative_to(ROOT))
378
+
200
379
  if args.check:
201
380
  if stale:
202
381
  print("toolchain lock is STALE for: %s" % ", ".join(stale))