boost-skill-cli 1.0.183__tar.gz → 1.0.185__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 (335) hide show
  1. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/Makefile +1 -0
  2. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/PKG-INFO +1 -1
  3. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/_version.py +2 -2
  4. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_skill_cli.egg-info/PKG-INFO +1 -1
  5. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_skill_cli.egg-info/SOURCES.txt +2 -0
  6. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/index.html +34 -105
  7. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +3 -3
  8. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/reconcile-the-theme-drift.md +3 -3
  9. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap.html +2 -2
  10. boost_skill_cli-1.0.185/scripts/perf_gate.py +149 -0
  11. boost_skill_cli-1.0.185/tests/unit/test_perf_gate.py +64 -0
  12. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/.gitattributes +0 -0
  13. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/.gitignore +0 -0
  14. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/.gitleaks.toml +0 -0
  15. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/.htmlvalidate.json +0 -0
  16. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/.markdownlint-cli2.jsonc +0 -0
  17. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/.pre-commit-config.yaml +0 -0
  18. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/.stylelintrc.json +0 -0
  19. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/.vale/styles/boost/Terminology.yml +0 -0
  20. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
  21. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/.vale.ini +0 -0
  22. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/CLAUDE.md +0 -0
  23. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/CONTRIBUTING.md +0 -0
  24. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/LICENSE +0 -0
  25. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/MANIFEST.in +0 -0
  26. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/README.md +0 -0
  27. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/SECURITY.md +0 -0
  28. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost +0 -0
  29. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/__init__.py +0 -0
  30. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/__main__.py +0 -0
  31. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/cli.py +0 -0
  32. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/cliparse.py +0 -0
  33. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/commands/__init__.py +0 -0
  34. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/commands/bmad.py +0 -0
  35. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/commands/configuration.py +0 -0
  36. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/commands/discovery.py +0 -0
  37. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/commands/hooks.py +0 -0
  38. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/commands/info.py +0 -0
  39. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/commands/intelligence.py +0 -0
  40. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/commands/pkg.py +0 -0
  41. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/commands/quality.py +0 -0
  42. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/commands/taps.py +0 -0
  43. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/commands/team.py +0 -0
  44. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/__init__.py +0 -0
  45. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/adapters.py +0 -0
  46. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/agents.py +0 -0
  47. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/ai.py +0 -0
  48. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/catalog.py +0 -0
  49. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/claude_settings.py +0 -0
  50. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/config.py +0 -0
  51. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/dense.py +0 -0
  52. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/embed.py +0 -0
  53. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/frontmatter.py +0 -0
  54. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/gitutil.py +0 -0
  55. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/imperative.py +0 -0
  56. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/injectscan.py +0 -0
  57. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/journal.py +0 -0
  58. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/lockfile.py +0 -0
  59. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/logs.py +0 -0
  60. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/mcp.py +0 -0
  61. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/nethttp.py +0 -0
  62. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/output.py +0 -0
  63. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/paths.py +0 -0
  64. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/policy.py +0 -0
  65. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/rag.py +0 -0
  66. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/registry.py +0 -0
  67. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/rules.py +0 -0
  68. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/secretscan.py +0 -0
  69. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/serve.py +0 -0
  70. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/stackprobe.py +0 -0
  71. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/staleness.py +0 -0
  72. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/store.py +0 -0
  73. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/typosquat.py +0 -0
  74. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/updatediff.py +0 -0
  75. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/util.py +0 -0
  76. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/core/workflows.py +0 -0
  77. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/data/registries.json +0 -0
  78. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/errors.py +0 -0
  79. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_cli/spin.py +0 -0
  80. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  81. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  82. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_skill_cli.egg-info/requires.txt +0 -0
  83. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/boost_skill_cli.egg-info/top_level.txt +0 -0
  84. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/.claude/settings.local.json +0 -0
  85. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/DEBUGGING.md +0 -0
  86. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/adapters.html +0 -0
  87. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/commands.html +0 -0
  88. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/demo.gif +0 -0
  89. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/demo.tape +0 -0
  90. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/design-roadmap.html +0 -0
  91. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/eval.html +0 -0
  92. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/mcp-hub.html +0 -0
  93. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/rag-architecture.md +0 -0
  94. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D01.md +0 -0
  95. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D02.md +0 -0
  96. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D03.md +0 -0
  97. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D04.md +0 -0
  98. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D05.md +0 -0
  99. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D06.md +0 -0
  100. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D07.md +0 -0
  101. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D08.md +0 -0
  102. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D09.md +0 -0
  103. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D10.md +0 -0
  104. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D11.md +0 -0
  105. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D12.md +0 -0
  106. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D13.md +0 -0
  107. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D14.md +0 -0
  108. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D15.md +0 -0
  109. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D16.md +0 -0
  110. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D17.md +0 -0
  111. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D18.md +0 -0
  112. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D19.md +0 -0
  113. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D20.md +0 -0
  114. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D21.md +0 -0
  115. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D22.md +0 -0
  116. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D23.md +0 -0
  117. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D24.md +0 -0
  118. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D25.md +0 -0
  119. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/BOOST-D26.md +0 -0
  120. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  121. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  122. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  123. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  124. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/boost-run-live-agents.md +0 -0
  125. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  126. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  127. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  128. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  129. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  130. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  131. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  132. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  133. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  134. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  135. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  136. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  137. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  138. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  139. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  140. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  141. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  142. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  143. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  144. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  145. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  146. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  147. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  148. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
  149. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  150. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  151. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  152. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
  153. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  154. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  155. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
  156. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  157. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  158. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  159. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  160. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  161. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  162. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  163. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  164. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  165. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  166. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  167. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  168. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  169. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  170. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
  171. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  172. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  173. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  174. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  175. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  176. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  177. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  178. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  179. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  180. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  181. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  182. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  183. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  184. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  185. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  186. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  187. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  188. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
  189. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  190. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  191. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  192. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  193. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  194. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  195. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
  196. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  197. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  198. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  199. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  200. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  201. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  202. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  203. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  204. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  205. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  206. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  207. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  208. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  209. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  210. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  211. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  212. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  213. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  214. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  215. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  216. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  217. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  218. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  219. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  220. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  221. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  222. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  223. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  224. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  225. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/docs/roadmap/items/workspace-scope-install.md +0 -0
  226. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/eslint.config.mjs +0 -0
  227. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/examples/README.md +0 -0
  228. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/examples/adapt-demo.sh +0 -0
  229. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/examples/boost-run-prototype.sh +0 -0
  230. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/index.html +0 -0
  231. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/noxfile.py +0 -0
  232. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/pyproject.toml +0 -0
  233. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/scripts/bench_cli.sh +0 -0
  234. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/scripts/build_command_reference.py +0 -0
  235. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/scripts/build_registries.py +0 -0
  236. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/scripts/build_roadmap.py +0 -0
  237. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/scripts/ensure_eval_corpus.sh +0 -0
  238. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/scripts/eval_explain.py +0 -0
  239. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/scripts/eval_recommend.py +0 -0
  240. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/scripts/eval_retrieval.py +0 -0
  241. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/scripts/eval_stats_summary.py +0 -0
  242. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/scripts/import_budget.py +0 -0
  243. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/scripts/mutation_gate.py +0 -0
  244. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/setup.cfg +0 -0
  245. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/style/README.md +0 -0
  246. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/style/boost.css +0 -0
  247. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/style/boost.js +0 -0
  248. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/style/demo.html +0 -0
  249. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/adapt.feature +0 -0
  250. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/browse.feature +0 -0
  251. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/count.feature +0 -0
  252. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/discover.feature +0 -0
  253. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/doctor.feature +0 -0
  254. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/environment.py +0 -0
  255. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/explain.feature +0 -0
  256. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/index.feature +0 -0
  257. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/install.feature +0 -0
  258. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/list.feature +0 -0
  259. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/mcp.feature +0 -0
  260. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/search.feature +0 -0
  261. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/steps/cli_steps.py +0 -0
  262. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/steps/discovery_steps.py +0 -0
  263. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/steps/mcp_steps.py +0 -0
  264. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/bdd/features/steps/quality_steps.py +0 -0
  265. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/conftest.py +0 -0
  266. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/eval/baseline.json +0 -0
  267. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/eval/explain.jsonl +0 -0
  268. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/eval/golden.jsonl +0 -0
  269. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/eval/recommend.jsonl +0 -0
  270. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/eval/taps.txt +0 -0
  271. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_cli_adapt.py +0 -0
  272. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_cli_bmad.py +0 -0
  273. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_cli_configuration.py +0 -0
  274. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_cli_discovery.py +0 -0
  275. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_cli_hooks.py +0 -0
  276. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_cli_info.py +0 -0
  277. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_cli_intelligence.py +0 -0
  278. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_cli_pkg.py +0 -0
  279. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_cli_quality.py +0 -0
  280. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_cli_taps.py +0 -0
  281. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_cli_team.py +0 -0
  282. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_everyday_loop.py +0 -0
  283. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/functional/test_property_parsers.py +0 -0
  284. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/make_fixture.py +0 -0
  285. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/perf/test_benchmarks.py +0 -0
  286. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/smoke.sh +0 -0
  287. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_adapters.py +0 -0
  288. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_agents.py +0 -0
  289. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_ai.py +0 -0
  290. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_catalog.py +0 -0
  291. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_claude_settings.py +0 -0
  292. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_cliparse.py +0 -0
  293. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_command_reference_fresh.py +0 -0
  294. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_config.py +0 -0
  295. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_dense.py +0 -0
  296. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_dense_fallback.py +0 -0
  297. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_docs_pages_linked.py +0 -0
  298. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_embed.py +0 -0
  299. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_errors_and_cli_table.py +0 -0
  300. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_eval_stats_summary.py +0 -0
  301. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_frontmatter.py +0 -0
  302. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_gitleaks_config.py +0 -0
  303. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_gitutil.py +0 -0
  304. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_imperative.py +0 -0
  305. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_import_budget.py +0 -0
  306. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_injectscan.py +0 -0
  307. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_journal.py +0 -0
  308. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_lockfile.py +0 -0
  309. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_logs.py +0 -0
  310. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_mcp.py +0 -0
  311. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_mutation_hardening.py +0 -0
  312. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_nethttp.py +0 -0
  313. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_output.py +0 -0
  314. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_paths.py +0 -0
  315. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_pkg_confusions.py +0 -0
  316. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_pkg_injection.py +0 -0
  317. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_pkg_secrets.py +0 -0
  318. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_policy.py +0 -0
  319. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_rag.py +0 -0
  320. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_registries_fresh.py +0 -0
  321. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_registry.py +0 -0
  322. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_roadmap_fresh.py +0 -0
  323. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_rules.py +0 -0
  324. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_secretscan.py +0 -0
  325. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_serve.py +0 -0
  326. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_spin.py +0 -0
  327. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_stackprobe.py +0 -0
  328. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_staleness.py +0 -0
  329. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_store.py +0 -0
  330. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_token_parity.py +0 -0
  331. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_typosquat.py +0 -0
  332. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_updatediff.py +0 -0
  333. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_util.py +0 -0
  334. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_version.py +0 -0
  335. {boost_skill_cli-1.0.183 → boost_skill_cli-1.0.185}/tests/unit/test_workflows.py +0 -0
@@ -56,6 +56,7 @@ lint:
56
56
  $(PY) scripts/build_roadmap.py --check
57
57
  $(PY) scripts/build_command_reference.py --check
58
58
  $(PY) scripts/import_budget.py
59
+ $(PY) scripts/perf_gate.py
59
60
 
60
61
  # Supply-chain CVE gate: fail on a known OSV/PyPI advisory in the project's
61
62
  # dependency closure. Mirrors the pip-audit CI workflow; run before releasing.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.183
3
+ Version: 1.0.185
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.183'
22
- __version_tuple__ = version_tuple = (1, 0, 183)
21
+ __version__ = version = '1.0.185'
22
+ __version_tuple__ = version_tuple = (1, 0, 185)
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.183
3
+ Version: 1.0.185
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -239,6 +239,7 @@ scripts/eval_retrieval.py
239
239
  scripts/eval_stats_summary.py
240
240
  scripts/import_budget.py
241
241
  scripts/mutation_gate.py
242
+ scripts/perf_gate.py
242
243
  style/README.md
243
244
  style/boost.css
244
245
  style/boost.js
@@ -309,6 +310,7 @@ tests/unit/test_mutation_hardening.py
309
310
  tests/unit/test_nethttp.py
310
311
  tests/unit/test_output.py
311
312
  tests/unit/test_paths.py
313
+ tests/unit/test_perf_gate.py
312
314
  tests/unit/test_pkg_confusions.py
313
315
  tests/unit/test_pkg_injection.py
314
316
  tests/unit/test_pkg_secrets.py
@@ -4,35 +4,12 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>boost — Homebrew for AI coding skills</title>
7
+ <!-- Canonical Aurora tokens + primitives (single source of truth). The
8
+ inline block below carries ONLY page-specific layout, and wins ties
9
+ by coming later in the cascade. -->
10
+ <link rel="stylesheet" href="../style/boost.css">
7
11
  <style>
8
- :root {
9
- /* ---- Aurora reskin: neon-tech living glass (matches style/ + portfolio) ---- */
10
- --bg: #07080f;
11
- --panel: rgba(255,255,255,.035);
12
- --panel-solid: #0f1120;
13
- --line: rgba(255,255,255,.09);
14
- --line-soft: rgba(255,255,255,.05);
15
- --line-hi: rgba(255,255,255,.22);
16
- --text: #e9ebf5;
17
- --text-2: #9298b0;
18
- --text-3: #676d86;
19
- --amber: #22d3ee; /* primary accent → cyan */
20
- --orange: #38bdf8; /* cyan-blue */
21
- --pink: #f472d0;
22
- --violet: #a855f7;
23
- --blue: #38bdf8;
24
- --sky: #7dd3fc;
25
- --green: #4ade80;
26
- --yellow: #facc15;
27
- --term-bg: #0d1024;
28
- --term-bar: #171a33;
29
- --cyan: #22d3ee;
30
- --grad: linear-gradient(96deg, #22d3ee 0%, #a855f7 52%, #f472d0 100%);
31
- --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
32
- --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
33
- }
34
12
  * { box-sizing: border-box; margin: 0; padding: 0; }
35
- html { scroll-behavior: smooth; scroll-padding-top: 84px; }
36
13
  @media (prefers-reduced-motion: reduce) {
37
14
  html { scroll-behavior: auto; }
38
15
  .reveal { transition: none !important; transform: none !important; opacity: 1 !important; }
@@ -74,9 +51,7 @@
74
51
  50% { transform: translate3d(2.5vmax,-2vmax,0) scale(1.08); }
75
52
  }
76
53
  .wrap { max-width: 1120px; margin: 0 auto; padding: 0 24px; position: relative; z-index: 1; }
77
- a { color: inherit; }
78
- code { font-family: var(--mono); }
79
- :focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; border-radius: 4px; }
54
+ :focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; border-radius: 4px; }
80
55
 
81
56
  /* ---------- nav ---------- */
82
57
  header {
@@ -86,40 +61,26 @@
86
61
  -webkit-backdrop-filter: blur(12px);
87
62
  border-bottom: 1px solid var(--line-soft);
88
63
  }
89
- .nav { display: flex; align-items: center; gap: 24px; height: 64px; }
64
+ header .nav { display: flex; align-items: center; gap: 24px; height: 64px; }
90
65
  .logo { display: flex; align-items: baseline; gap: 10px; text-decoration: none; }
91
- .logo b { font-family: var(--mono); font-size: 20px; font-weight: 700; color: var(--amber); letter-spacing: -.02em; }
66
+ .logo b { font-family: var(--mono); font-size: 20px; font-weight: 700; color: var(--cyan); letter-spacing: -.02em; }
92
67
  .logo span { font-size: 10.5px; letter-spacing: .24em; color: var(--text-2); text-transform: uppercase; }
93
- .nav ul {
68
+ header .nav ul {
94
69
  display: flex; gap: 4px; list-style: none; margin-left: auto;
95
70
  overflow-x: auto; scrollbar-width: none;
96
71
  }
97
- .nav ul::-webkit-scrollbar { display: none; }
98
- .nav ul a {
72
+ header .nav ul::-webkit-scrollbar { display: none; }
73
+ header .nav ul a {
99
74
  display: block; padding: 8px 12px; border-radius: 8px;
100
75
  font-size: 14px; color: var(--text-2); text-decoration: none; white-space: nowrap;
101
76
  }
102
- .nav ul a:hover { color: var(--text); background: var(--panel); }
103
- .nav ul a.cta { color: var(--text); font-weight: 600; }
77
+ header .nav ul a:hover { color: var(--text); background: var(--panel); }
78
+ header .nav ul a.cta { color: var(--text); font-weight: 600; }
104
79
 
105
80
  /* ---------- shared section chrome ---------- */
106
81
  section { padding: 110px 0 20px; }
107
- .eyebrow {
108
- font-family: var(--mono); font-size: 12px; font-weight: 700;
109
- letter-spacing: .24em; text-transform: uppercase;
110
- background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
111
- display: block; text-align: center; margin-bottom: 18px;
112
- }
113
- .sec-title {
114
- font-size: clamp(30px, 4.5vw, 50px); font-weight: 800; letter-spacing: -.025em;
115
- line-height: 1.1; text-align: center; text-wrap: balance;
116
- }
117
- .sec-sub {
118
- max-width: 640px; margin: 18px auto 0; text-align: center;
119
- color: var(--text-2); font-size: 17.5px; text-wrap: balance;
120
- }
121
82
  .sec-sub code {
122
- color: var(--amber); background: rgba(34,211,238,.09);
83
+ color: var(--cyan); background: rgba(34,211,238,.09);
123
84
  padding: 1px 7px; border-radius: 6px; font-size: .88em;
124
85
  }
125
86
  .reveal { opacity: 0; transform: translateY(16px); transition: opacity .6s ease, transform .6s ease; }
@@ -149,14 +110,12 @@
149
110
  padding: 14px 26px; border-radius: 12px; border: 1px solid transparent;
150
111
  transition: transform .15s ease, box-shadow .15s ease;
151
112
  }
152
- .btn:hover { transform: translateY(-1px); }
153
113
  .btn-grad {
154
114
  color: #05141a;
155
- background: linear-gradient(92deg, var(--orange), var(--pink));
115
+ background: linear-gradient(92deg, var(--blue), var(--pink));
156
116
  box-shadow: 0 8px 30px rgba(236,72,153,.28);
157
117
  }
158
118
  .btn-grad:hover { box-shadow: 0 10px 36px rgba(236,72,153,.4); }
159
- .btn-ghost { color: var(--text); border-color: var(--line); background: var(--panel); }
160
119
  .btn-ghost:hover { border-color: rgba(255,255,255,.2); }
161
120
  .stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 72px; }
162
121
  .stat {
@@ -168,22 +127,13 @@
168
127
  transition: border-color .2s ease;
169
128
  }
170
129
  .stat:hover { border-color: var(--line-hi); }
171
- .stat b {
172
- display: block; font-size: clamp(28px, 3.4vw, 42px); font-weight: 800; letter-spacing: -.02em;
173
- background: var(--grad); -webkit-background-clip: text; background-clip: text; color: transparent;
174
- font-variant-numeric: tabular-nums;
175
- }
176
- .stat span {
177
- display: block; margin-top: 8px; font-size: 11px; font-weight: 650;
178
- letter-spacing: .16em; text-transform: uppercase; color: var(--text-2);
179
- }
180
130
 
181
131
  /* ---------- concept ---------- */
182
132
  .concept-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; margin-top: 64px; }
183
133
  .concept-copy p { color: var(--text-2); margin-bottom: 22px; font-size: 17.5px; }
184
134
  .concept-copy p b { color: var(--text); font-weight: 650; }
185
135
  .concept-copy .chip-code {
186
- font-family: var(--mono); font-size: .86em; color: var(--amber);
136
+ font-family: var(--mono); font-size: .86em; color: var(--cyan);
187
137
  background: rgba(34,211,238,.09); padding: 1px 7px; border-radius: 6px;
188
138
  }
189
139
  .analogy { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; }
@@ -192,7 +142,7 @@
192
142
  font-size: 13.5px; color: var(--text-2);
193
143
  border: 1px solid var(--line); border-radius: 999px; padding: 8px 16px; background: var(--panel);
194
144
  }
195
- .analogy b { font-family: var(--mono); font-size: 13px; color: var(--amber); font-weight: 700; }
145
+ .analogy b { font-family: var(--mono); font-size: 13px; color: var(--cyan); font-weight: 700; }
196
146
  .analogy .arr { color: var(--text-3); }
197
147
 
198
148
  /* mac-style window */
@@ -208,30 +158,12 @@
208
158
  display: flex; align-items: center; height: 38px; padding: 0 14px;
209
159
  background: var(--term-bar); border-bottom: 1px solid rgba(0,0,0,.25);
210
160
  }
211
- .window .dots { display: flex; gap: 7px; }
212
- .window .dots i { width: 12px; height: 12px; border-radius: 50%; }
213
- .window .dots i:nth-child(1) { background: #ff5f57; }
214
- .window .dots i:nth-child(2) { background: #febc2e; }
215
- .window .dots i:nth-child(3) { background: #28c840; }
216
- .window .bar-title {
217
- flex: 1; text-align: center; font-family: var(--mono); font-size: 12.5px; color: #b8b8d0;
218
- margin-right: 47px; /* balance the dots */
219
- }
220
- .window pre {
221
- padding: 22px 24px; overflow-x: auto;
222
- font-family: var(--mono); font-size: 13.5px; line-height: 1.75; color: #dcdcf0;
223
- }
224
- .yk { color: var(--amber); } /* yaml key */
161
+ .yk { color: var(--cyan); } /* yaml key */
225
162
  .yv { color: var(--yellow); } /* yaml value */
226
163
  .yd { color: #8888aa; } /* delimiter/dim */
227
- .mh { color: #f5a9d8; font-weight: 700; } /* markdown heading */
228
- .cm { color: #9d9dbd; font-style: italic; } /* comment */
229
- .tp { color: #8888aa; } /* terminal prompt $ */
230
- .tv { color: #7ee787; font-weight: 700; } /* the word `boost` */
231
- .tc { color: var(--yellow); font-weight: 700; } /* subcommand */
232
- .tok { color: var(--green); } /* ✓ */
233
- .tstar { color: var(--amber); }
234
- .tdim { color: #9d9dbd; }
164
+ .mh { color: #f5a9d8; font-weight: 700; } /* markdown heading */ /* comment */
165
+ .tp { color: #8888aa; } /* terminal prompt $ */ /* the word `boost` */ /* subcommand */ /* ✓ */
166
+ .tstar { color: var(--cyan); }
235
167
  .tacc { color: var(--cyan); font-weight: 700; } /* Aurora accent: meters, names, ==> */
236
168
  .tbox { color: var(--green); } /* framed-card border (panel hue=green) */
237
169
 
@@ -253,7 +185,7 @@
253
185
  letter-spacing: .2em; text-transform: uppercase; color: var(--text-2);
254
186
  }
255
187
  .node h4 { font-size: 18px; font-weight: 750; margin-top: 8px; letter-spacing: -.01em; }
256
- .node h4 code { font-size: 15.5px; color: var(--amber); }
188
+ .node h4 code { font-size: 15.5px; color: var(--cyan); }
257
189
  .node p { font-size: 13.5px; color: var(--text-2); margin-top: 6px; }
258
190
  .node.src { border-color: rgba(96,165,250,.5); box-shadow: 0 0 32px rgba(96,165,250,.07); }
259
191
  .node.mid { border-color: rgba(255,255,255,.14); }
@@ -263,7 +195,7 @@
263
195
  .node.agent h4 { color: #d9fbe5; }
264
196
  .flow-arrow {
265
197
  display: flex; flex-direction: column; align-items: center; gap: 4px;
266
- padding: 14px 0; color: var(--amber);
198
+ padding: 14px 0; color: var(--cyan);
267
199
  }
268
200
  .flow-arrow svg { display: block; }
269
201
  .flow-arrow span {
@@ -288,7 +220,7 @@
288
220
  transition: color .15s, background .15s, border-color .15s;
289
221
  }
290
222
  .pill:hover { color: var(--text); border-color: rgba(255,255,255,.2); }
291
- .pill.on { background: var(--amber); border-color: var(--amber); color: #201705; }
223
+ .pill.on { background: var(--cyan); border-color: var(--cyan); color: #201705; }
292
224
  .cmd-count { text-align: center; margin: 30px 0 6px; font-size: 14.5px; color: var(--text-2); }
293
225
  .group { margin-top: 46px; }
294
226
  .group-head { display: flex; align-items: center; gap: 14px; }
@@ -314,16 +246,16 @@
314
246
  }
315
247
  .cmd::before {
316
248
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
317
- background: var(--gc, var(--amber)); opacity: .85; border-radius: 3px 0 0 3px;
249
+ background: var(--gc, var(--cyan)); opacity: .85; border-radius: 3px 0 0 3px;
318
250
  }
319
251
  .cmd:hover { border-color: var(--line); }
320
252
  .cmd .name { font-family: var(--mono); font-size: 14.5px; }
321
253
  .cmd .name .v { color: #85859c; }
322
- .cmd .name b { color: var(--amber); font-weight: 700; }
254
+ .cmd .name b { color: var(--cyan); font-weight: 700; }
323
255
  .cmd p { font-size: 13.5px; color: var(--text-2); margin-top: 6px; line-height: 1.5; }
324
256
  .cmd mark { background: rgba(34,211,238,.25); color: var(--text); border-radius: 3px; padding: 0 1px; }
325
257
  .no-results { text-align: center; color: var(--text-2); padding: 60px 0 30px; display: none; }
326
- .no-results code { color: var(--amber); }
258
+ .no-results code { color: var(--cyan); }
327
259
 
328
260
  /* ---------- capabilities ---------- */
329
261
  .caps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 64px; }
@@ -343,9 +275,6 @@
343
275
  background: var(--ic-bg, rgba(255,255,255,.06)); color: var(--ic-fg, var(--text));
344
276
  border: 1px solid var(--line-soft);
345
277
  }
346
- .cap h3 { font-size: 19.5px; font-weight: 750; letter-spacing: -.01em; }
347
- .cap p { font-size: 14.5px; color: var(--text-2); margin-top: 10px; }
348
- .cap .tags { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 18px; }
349
278
  .cap .tags code {
350
279
  font-size: 12px; color: #d5d5e2; background: rgba(255,255,255,.06);
351
280
  border: 1px solid var(--line-soft); border-radius: 7px; padding: 3px 9px;
@@ -364,13 +293,13 @@
364
293
  .reg tbody td { padding: 15px 20px; border-bottom: 1px solid var(--line-soft); font-size: 14.5px; vertical-align: middle; }
365
294
  .reg tbody tr:last-child td { border-bottom: none; }
366
295
  .reg .tapname {
367
- font-family: var(--mono); font-size: 13px; font-weight: 700; color: var(--amber);
296
+ font-family: var(--mono); font-size: 13px; font-weight: 700; color: var(--cyan);
368
297
  background: rgba(34,211,238,.09); border: 1px solid rgba(34,211,238,.25);
369
298
  border-radius: 8px; padding: 4px 11px; white-space: nowrap;
370
299
  }
371
300
  .reg .repo { font-family: var(--mono); font-size: 13px; color: var(--text-2); }
372
301
  .reg .cnt {
373
- font-family: var(--mono); font-size: 13px; font-weight: 700; color: var(--amber);
302
+ font-family: var(--mono); font-size: 13px; font-weight: 700; color: var(--cyan);
374
303
  border: 1px solid rgba(34,211,238,.35); border-radius: 999px; padding: 4px 12px;
375
304
  font-variant-numeric: tabular-nums; white-space: nowrap;
376
305
  }
@@ -379,7 +308,7 @@
379
308
  .reg tr.dim .tapname { color: var(--text-2); background: var(--panel); border-color: var(--line); }
380
309
  .reg tr.dim .cnt { color: var(--text-2); border-color: var(--line); }
381
310
  .reg-note { text-align: center; font-size: 13.5px; color: var(--text-3); margin-top: 18px; }
382
- .reg-note code { color: var(--amber); font-size: .92em; }
311
+ .reg-note code { color: var(--cyan); font-size: .92em; }
383
312
 
384
313
  /* ---------- get started ---------- */
385
314
  .install-box { max-width: 760px; margin: 56px auto 0; }
@@ -391,7 +320,7 @@
391
320
  .install-box .bar .label::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--grad); }
392
321
  .copy-btn {
393
322
  font-family: var(--sans); font-size: 12.5px; font-weight: 700; color: #201705;
394
- background: var(--amber); border: none; border-radius: 8px; padding: 6px 14px; cursor: pointer;
323
+ background: var(--cyan); border: none; border-radius: 8px; padding: 6px 14px; cursor: pointer;
395
324
  }
396
325
  .copy-btn:hover { filter: brightness(1.08); }
397
326
  .mini { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; max-width: 860px; margin: 40px auto 0; }
@@ -400,14 +329,14 @@
400
329
  background: var(--panel-solid); border: 1px solid var(--line-soft); border-radius: 12px; padding: 18px 20px;
401
330
  }
402
331
  .mini a:hover { border-color: var(--line); }
403
- .mini .name { font-family: var(--mono); font-size: 14px; font-weight: 700; color: var(--amber); }
332
+ .mini .name { font-family: var(--mono); font-size: 14px; font-weight: 700; color: var(--cyan); }
404
333
  .mini .name .v { color: #85859c; font-weight: 400; }
405
334
  .mini p { font-size: 13px; color: var(--text-2); margin-top: 5px; }
406
335
 
407
336
  /* ---------- footer ---------- */
408
337
  footer { margin-top: 130px; border-top: 1px solid var(--line-soft); padding: 44px 0 60px; text-align: center; }
409
338
  footer .brand { font-size: 15px; color: var(--text-2); }
410
- footer .brand b { font-family: var(--mono); color: var(--amber); }
339
+ footer .brand b { font-family: var(--mono); color: var(--cyan); }
411
340
  footer .meta { margin-top: 10px; font-size: 13.5px; color: var(--text-3); }
412
341
  footer .meta code {
413
342
  color: var(--text-2); background: var(--panel); border: 1px solid var(--line-soft);
@@ -701,7 +630,7 @@ facilitate structured divergent thinking:
701
630
  <div class="ic">⇄</div>
702
631
  <h3>Multi-agent &amp; integration</h3>
703
632
  <p>Install once, land in Claude Code, Windsurf, and Cursor. Run as a
704
- native MCP server, register a <code style="color:var(--amber)">boost://</code> one-click
633
+ native MCP server, register a <code style="color:var(--cyan)">boost://</code> one-click
705
634
  protocol, serve a catalog over HTTP, or auto-sync on a schedule.</p>
706
635
  <div class="tags"><code>migrate</code><code>mcp</code><code>protocol</code><code>serve</code><code>schedule</code></div>
707
636
  </div>
@@ -775,7 +704,7 @@ facilitate structured divergent thinking:
775
704
  <td><span class="tapname">your-org/skills</span></td>
776
705
  <td class="repo">any repo with SKILL.md files</td>
777
706
  <td><span class="cnt">∞</span></td>
778
- <td class="focus">Your team’s registry — <code style="color:var(--amber);font-size:.92em">boost tap your-org/skills</code> (private repos work over ssh)</td>
707
+ <td class="focus">Your team’s registry — <code style="color:var(--cyan);font-size:.92em">boost tap your-org/skills</code> (private repos work over ssh)</td>
779
708
  </tr>
780
709
  </tbody>
781
710
  </table>
@@ -2,15 +2,15 @@
2
2
  id: performance-regression-gate-pytest-benchmark
3
3
  board: code
4
4
  section: dx
5
- status: planned
5
+ status: shipped
6
6
  category: Testing · Perf
7
7
  complexity: M
8
8
  impact: Med
9
9
  wow: 3
10
10
  note: scan &amp; registry
11
11
  order: 6
12
- owner:
13
- pr:
12
+ owner: loop/perfgate
13
+ pr: 207
14
14
  title: Performance-regression gate — <code>pytest-benchmark</code>
15
15
  ---
16
16
  Benchmark the hot paths — a catalog scan over a large skills tree, a
@@ -2,15 +2,15 @@
2
2
  id: reconcile-the-theme-drift
3
3
  board: code
4
4
  section: next
5
- status: next
5
+ status: shipped
6
6
  category: Design
7
7
  complexity: M
8
8
  impact: Med
9
9
  wow: 3
10
10
  note:
11
11
  order: 3
12
- owner:
13
- pr:
12
+ owner: loop/themedrift
13
+ pr: 208
14
14
  title: Reconcile the theme drift
15
15
  ---
16
16
  <code>docs/index.html</code> inlines its own amber/orange palette
@@ -432,7 +432,7 @@ message, so routing it through the helper would change user-facing errors.</p>
432
432
 
433
433
  <!-- ROADMAP:cards section=next -->
434
434
  <article class="cap rcard">
435
- <div class="head"><span class="pill next">Next</span><span class="cat">Design</span></div>
435
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Design</span></div>
436
436
  <h3>Reconcile the theme drift</h3>
437
437
  <p><code>docs/index.html</code> inlines its own amber/orange palette
438
438
  instead of the canonical <em>Aurora</em> cyan→violet→pink system in
@@ -1387,7 +1387,7 @@ improvement is real (or isn't)."</p>
1387
1387
  </article>
1388
1388
 
1389
1389
  <article class="cap rcard">
1390
- <div class="head"><span class="pill planned">Planned</span><span class="cat">Testing · Perf</span></div>
1390
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Testing · Perf</span></div>
1391
1391
  <h3>Performance-regression gate — <code>pytest-benchmark</code></h3>
1392
1392
  <p>Benchmark the hot paths — a catalog scan over a large skills tree, a
1393
1393
  registry load — and fail the build when a change regresses them past a
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env python3
2
+ """Performance-regression gate: complexity scaling, not wall-clock baselines.
3
+
4
+ A saved-baseline benchmark compare flakes on shared CI runners — machine speed
5
+ varies run to run, so absolute thresholds either false-alarm or sandbag. What
6
+ a gate CAN assert robustly is *how cost grows with input size*: time the hot
7
+ paths at two catalog sizes on the SAME machine in the SAME process, and fail
8
+ when the big/small ratio blows past the size ratio times a slack factor. An
9
+ accidental O(n²) (size ratio 8 → time ratio ~64×) is caught decisively; noise
10
+ and slow runners cancel out of the ratio. One generous absolute backstop
11
+ catches only catch-fire regressions.
12
+
13
+ Paths gated (the ones `boost search`/`tap` lean on):
14
+ * catalog.scan_dir — walking + classifying a tap tree
15
+ * rag.build — BM25 indexing of the scanned entries
16
+ * rag.retrieve — query over the built index
17
+
18
+ Usage:
19
+ PYTHONPATH=. python3 scripts/perf_gate.py # run the gate
20
+ PYTHONPATH=. python3 scripts/perf_gate.py -v # per-path timings
21
+
22
+ Deliberately NOT part of `make check`'s five-gate contract (v1 blast-radius);
23
+ CI runs it in the lint job. The opt-in micro-benchmarks (tests/perf, `make
24
+ bench`) remain the profiling tool; this is the regression tripwire.
25
+ """
26
+ from __future__ import annotations
27
+
28
+ import argparse
29
+ import os
30
+ import sys
31
+ import tempfile
32
+ import time
33
+ from pathlib import Path
34
+
35
+ # Run from a source checkout without an install (same shim as the eval gate).
36
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
37
+
38
+ SMALL, BIG = 64, 512 # catalog sizes; 8× input
39
+ SLACK = 3.0 # fail when time-ratio > size-ratio × SLACK (24×)
40
+ ABS_BACKSTOP_S = 30.0 # any single big-size op slower than this fails
41
+ MIN_SAMPLE_S = 0.05 # repeat an op until a sample is ≥ 50ms (jitter)
42
+ BEST_OF = 3
43
+
44
+
45
+ def _mk_catalog(root: Path, n: int) -> None:
46
+ """Materialize a synthetic tap tree with n skills + n rules + n workflows.
47
+
48
+ Content scales with the tree so indexing has real text to chew on, and
49
+ names are unique per size so nothing is accidentally shared or cached.
50
+ """
51
+ lorem = ["retrieval", "augmentation", "index", "tokens", "ranking", "corpus", "recall", "precision", "embedding", "catalog", "skill", "agent", "workflow", "rule"]
52
+ for i in range(n):
53
+ d = root / ("skill-%04d" % i)
54
+ d.mkdir(parents=True)
55
+ words = " ".join(lorem[(i + j) % len(lorem)] for j in range(60))
56
+ (d / "SKILL.md").write_text(
57
+ "---\nname: skill-%04d\ndescription: synthetic skill %d for the "
58
+ "perf gate\n---\n\n# skill-%04d\n\n%s\n" % (i, i, i, words),
59
+ encoding="utf-8")
60
+ (root / "rules" / ("rule-%04d.mdc" % i)).parent.mkdir(exist_ok=True)
61
+ (root / "rules" / ("rule-%04d.mdc" % i)).write_text(
62
+ "---\ndescription: synthetic rule %d\n---\nAlways %s.\n"
63
+ % (i, " ".join(lorem[i % len(lorem)] for _ in range(20))),
64
+ encoding="utf-8")
65
+ (root / "commands" / ("wf-%04d.md" % i)).parent.mkdir(exist_ok=True)
66
+ (root / "commands" / ("wf-%04d.md" % i)).write_text(
67
+ "# wf-%04d\n\nRun the synthetic workflow %d: %s\n"
68
+ % (i, i, words[:120]), encoding="utf-8")
69
+
70
+
71
+ def _time(fn) -> float:
72
+ """Best-of-BEST_OF timing; each sample loops fn until ≥ MIN_SAMPLE_S."""
73
+ best = float("inf")
74
+ for _ in range(BEST_OF):
75
+ reps = 0
76
+ t0 = time.perf_counter()
77
+ while True:
78
+ fn()
79
+ reps += 1
80
+ dt = time.perf_counter() - t0
81
+ if dt >= MIN_SAMPLE_S:
82
+ break
83
+ best = min(best, dt / reps)
84
+ return best
85
+
86
+
87
+ def _measure(size: int, verbose: bool) -> dict:
88
+ """Time the three hot paths against a fresh synthetic catalog of `size`."""
89
+ from boost_cli.core import catalog, rag
90
+
91
+ with tempfile.TemporaryDirectory(prefix="perfgate-") as tmp:
92
+ tap = Path(tmp) / "tap"
93
+ _mk_catalog(tap, size)
94
+ os.environ["BOOST_HOME"] = str(Path(tmp) / "home")
95
+ os.environ["HOME"] = tmp
96
+
97
+ out = {"scan": _time(lambda: catalog.scan_dir(tap, "perf"))}
98
+ entries = catalog.scan_dir(tap, "perf")
99
+ if len(entries) != 3 * size: # a generator bug would invalidate ratios
100
+ raise SystemExit("perf-gate: generator drift: %d entries for n=%d"
101
+ % (len(entries), size))
102
+
103
+ # build is once-per-corpus in real life — time single builds (forced).
104
+ best = float("inf")
105
+ for _ in range(BEST_OF):
106
+ t0 = time.perf_counter()
107
+ rag.build(entries, force=True)
108
+ best = min(best, time.perf_counter() - t0)
109
+ out["build"] = best
110
+
111
+ out["retrieve"] = _time(
112
+ lambda: rag.retrieve("ranking corpus recall skill", k=20))
113
+ if verbose:
114
+ for k, v in out.items():
115
+ print(" n=%-4d %-9s %8.1f ms" % (size, k, v * 1000))
116
+ return out
117
+
118
+
119
+ def main(argv=None) -> int:
120
+ ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
121
+ ap.add_argument("-v", "--verbose", action="store_true")
122
+ args = ap.parse_args(argv)
123
+
124
+ small = _measure(SMALL, args.verbose)
125
+ big = _measure(BIG, args.verbose)
126
+
127
+ size_ratio = BIG / SMALL
128
+ limit = size_ratio * SLACK
129
+ failed = []
130
+ for path in ("scan", "build", "retrieve"):
131
+ ratio = big[path] / small[path] if small[path] > 0 else float("inf")
132
+ line = "%-9s %7.1fms -> %8.1fms ratio %5.1fx (limit %.0fx)" % (
133
+ path, small[path] * 1000, big[path] * 1000, ratio, limit)
134
+ ok = ratio <= limit and big[path] <= ABS_BACKSTOP_S
135
+ print((" PASS " if ok else " FAIL ") + line)
136
+ if not ok:
137
+ failed.append(path)
138
+
139
+ if failed:
140
+ print("perf-gate: FAILED — superlinear scaling (or >%ds backstop) on: %s"
141
+ % (int(ABS_BACKSTOP_S), ", ".join(failed)), file=sys.stderr)
142
+ return 1
143
+ print("perf-gate: OK — all paths scale within %.0fx of linear at %dx input"
144
+ % (SLACK, int(size_ratio)))
145
+ return 0
146
+
147
+
148
+ if __name__ == "__main__":
149
+ raise SystemExit(main())
@@ -0,0 +1,64 @@
1
+ """Unit tests for scripts/perf_gate.py — the scaling-ratio decision logic."""
2
+ from __future__ import annotations
3
+
4
+ import importlib.util
5
+ from pathlib import Path
6
+
7
+ import pytest
8
+
9
+ _SCRIPT = Path(__file__).resolve().parents[2] / "scripts" / "perf_gate.py"
10
+
11
+ _skip = pytest.mark.skipif(not _SCRIPT.exists(), reason="script not reachable")
12
+
13
+
14
+ def _mod():
15
+ spec = importlib.util.spec_from_file_location("perf_gate", _SCRIPT)
16
+ assert spec and spec.loader
17
+ module = importlib.util.module_from_spec(spec)
18
+ spec.loader.exec_module(module)
19
+ return module
20
+
21
+
22
+ @_skip
23
+ def test_linear_scaling_passes(monkeypatch, capsys):
24
+ pg = _mod()
25
+ fake = {64: {"scan": .01, "build": .01, "retrieve": .001},
26
+ 512: {"scan": .08, "build": .08, "retrieve": .008}} # exactly 8x
27
+ monkeypatch.setattr(pg, "_measure", lambda n, v: fake[n])
28
+ assert pg.main([]) == 0
29
+ assert "perf-gate: OK" in capsys.readouterr().out
30
+
31
+
32
+ @_skip
33
+ def test_quadratic_scaling_fails(monkeypatch, capsys):
34
+ pg = _mod()
35
+ fake = {64: {"scan": .01, "build": .01, "retrieve": .001},
36
+ 512: {"scan": .64, "build": .08, "retrieve": .008}} # scan at 64x
37
+ monkeypatch.setattr(pg, "_measure", lambda n, v: fake[n])
38
+ assert pg.main([]) == 1
39
+ out = capsys.readouterr()
40
+ assert "FAIL scan" in out.out
41
+ assert "superlinear" in out.err
42
+
43
+
44
+ @_skip
45
+ def test_absolute_backstop_fails_even_at_linear_ratio(monkeypatch, capsys):
46
+ pg = _mod()
47
+ fake = {64: {"scan": 5.0, "build": .01, "retrieve": .001},
48
+ 512: {"scan": 40.0, "build": .08, "retrieve": .008}} # 8x but 40s
49
+ monkeypatch.setattr(pg, "_measure", lambda n, v: fake[n])
50
+ assert pg.main([]) == 1
51
+ assert "FAIL scan" in capsys.readouterr().out
52
+
53
+
54
+ @_skip
55
+ def test_synthetic_catalog_has_expected_entry_count(tmp_path):
56
+ pg = _mod()
57
+ pg._mk_catalog(tmp_path, 5)
58
+ import boost_cli.core.catalog as catalog
59
+ entries = catalog.scan_dir(tmp_path, "t")
60
+ kinds = sorted(e.get("kind", "skill") for e in entries)
61
+ assert len(entries) == 15
62
+ assert kinds.count("skill") == 5
63
+ assert kinds.count("rule") == 5
64
+ assert kinds.count("workflow") == 5