boost-skill-cli 1.0.138__tar.gz → 1.0.140__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 (290) hide show
  1. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/PKG-INFO +1 -1
  2. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/_version.py +2 -2
  3. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/cli.py +6 -0
  4. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/nethttp.py +27 -0
  5. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_skill_cli.egg-info/PKG-INFO +1 -1
  6. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_skill_cli.egg-info/SOURCES.txt +1 -0
  7. boost_skill_cli-1.0.140/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +29 -0
  8. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap.html +26 -1
  9. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_nethttp.py +35 -0
  10. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/.gitattributes +0 -0
  11. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/.gitignore +0 -0
  12. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/CLAUDE.md +0 -0
  13. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/CONTRIBUTING.md +0 -0
  14. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/LICENSE +0 -0
  15. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/MANIFEST.in +0 -0
  16. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/Makefile +0 -0
  17. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/README.md +0 -0
  18. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/SECURITY.md +0 -0
  19. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost +0 -0
  20. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/__init__.py +0 -0
  21. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/__main__.py +0 -0
  22. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/cliparse.py +0 -0
  23. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/commands/__init__.py +0 -0
  24. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/commands/bmad.py +0 -0
  25. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/commands/configuration.py +0 -0
  26. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/commands/discovery.py +0 -0
  27. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/commands/hooks.py +0 -0
  28. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/commands/info.py +0 -0
  29. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/commands/intelligence.py +0 -0
  30. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/commands/pkg.py +0 -0
  31. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/commands/quality.py +0 -0
  32. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/commands/taps.py +0 -0
  33. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/commands/team.py +0 -0
  34. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/__init__.py +0 -0
  35. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/adapters.py +0 -0
  36. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/agents.py +0 -0
  37. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/ai.py +0 -0
  38. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/catalog.py +0 -0
  39. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/claude_settings.py +0 -0
  40. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/config.py +0 -0
  41. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/dense.py +0 -0
  42. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/embed.py +0 -0
  43. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/frontmatter.py +0 -0
  44. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/gitutil.py +0 -0
  45. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/imperative.py +0 -0
  46. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/injectscan.py +0 -0
  47. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/journal.py +0 -0
  48. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/lockfile.py +0 -0
  49. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/logs.py +0 -0
  50. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/mcp.py +0 -0
  51. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/output.py +0 -0
  52. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/paths.py +0 -0
  53. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/policy.py +0 -0
  54. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/rag.py +0 -0
  55. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/registry.py +0 -0
  56. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/rules.py +0 -0
  57. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/secretscan.py +0 -0
  58. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/serve.py +0 -0
  59. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/stackprobe.py +0 -0
  60. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/staleness.py +0 -0
  61. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/store.py +0 -0
  62. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/typosquat.py +0 -0
  63. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/updatediff.py +0 -0
  64. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/util.py +0 -0
  65. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/core/workflows.py +0 -0
  66. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/data/registries.json +0 -0
  67. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/errors.py +0 -0
  68. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_cli/spin.py +0 -0
  69. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
  70. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_skill_cli.egg-info/entry_points.txt +0 -0
  71. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_skill_cli.egg-info/requires.txt +0 -0
  72. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/boost_skill_cli.egg-info/top_level.txt +0 -0
  73. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/.claude/settings.local.json +0 -0
  74. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/DEBUGGING.md +0 -0
  75. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/adapters.html +0 -0
  76. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/demo.gif +0 -0
  77. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/demo.tape +0 -0
  78. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/design-roadmap.html +0 -0
  79. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/eval.html +0 -0
  80. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/index.html +0 -0
  81. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/mcp-hub.html +0 -0
  82. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/rag-architecture.md +0 -0
  83. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D01.md +0 -0
  84. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D02.md +0 -0
  85. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D03.md +0 -0
  86. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D04.md +0 -0
  87. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D05.md +0 -0
  88. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D06.md +0 -0
  89. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D07.md +0 -0
  90. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D08.md +0 -0
  91. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D09.md +0 -0
  92. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D10.md +0 -0
  93. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D11.md +0 -0
  94. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D12.md +0 -0
  95. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D13.md +0 -0
  96. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D14.md +0 -0
  97. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D15.md +0 -0
  98. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D16.md +0 -0
  99. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D17.md +0 -0
  100. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D18.md +0 -0
  101. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D19.md +0 -0
  102. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D20.md +0 -0
  103. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D21.md +0 -0
  104. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D22.md +0 -0
  105. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D23.md +0 -0
  106. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D24.md +0 -0
  107. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D25.md +0 -0
  108. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/BOOST-D26.md +0 -0
  109. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
  110. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
  111. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
  112. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
  113. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
  114. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
  115. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
  116. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
  117. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
  118. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
  119. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
  120. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/command-reference-docs-site.md +0 -0
  121. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
  122. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
  123. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
  124. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
  125. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
  126. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
  127. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
  128. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
  129. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
  130. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
  131. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
  132. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
  133. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
  134. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
  135. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
  136. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
  137. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
  138. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
  139. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
  140. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/html-validation-html-validate.md +0 -0
  141. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
  142. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
  143. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
  144. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
  145. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
  146. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
  147. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
  148. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
  149. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
  150. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
  151. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
  152. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
  153. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
  154. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
  155. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
  156. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
  157. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
  158. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
  159. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
  160. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
  161. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
  162. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
  163. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
  164. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
  165. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
  166. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
  167. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
  168. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
  169. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
  170. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
  171. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
  172. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
  173. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
  174. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
  175. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
  176. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
  177. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
  178. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
  179. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
  180. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
  181. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
  182. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
  183. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
  184. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
  185. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
  186. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
  187. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
  188. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
  189. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
  190. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
  191. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
  192. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
  193. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
  194. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
  195. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
  196. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
  197. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/typo-detection-codespell.md +0 -0
  198. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
  199. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
  200. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
  201. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/update-diff-before-apply.md +0 -0
  202. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
  203. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
  204. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
  205. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
  206. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
  207. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
  208. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
  209. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/docs/roadmap/items/workspace-scope-install.md +0 -0
  210. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/examples/README.md +0 -0
  211. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/examples/adapt-demo.sh +0 -0
  212. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/index.html +0 -0
  213. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/pyproject.toml +0 -0
  214. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/scripts/build_registries.py +0 -0
  215. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/scripts/build_roadmap.py +0 -0
  216. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/scripts/ensure_eval_corpus.sh +0 -0
  217. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/scripts/eval_explain.py +0 -0
  218. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/scripts/eval_recommend.py +0 -0
  219. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/scripts/eval_retrieval.py +0 -0
  220. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/scripts/mutation_gate.py +0 -0
  221. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/setup.cfg +0 -0
  222. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/style/README.md +0 -0
  223. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/style/boost.css +0 -0
  224. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/style/boost.js +0 -0
  225. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/style/demo.html +0 -0
  226. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/conftest.py +0 -0
  227. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/eval/baseline.json +0 -0
  228. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/eval/explain.jsonl +0 -0
  229. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/eval/golden.jsonl +0 -0
  230. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/eval/recommend.jsonl +0 -0
  231. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/eval/taps.txt +0 -0
  232. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_cli_adapt.py +0 -0
  233. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_cli_bmad.py +0 -0
  234. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_cli_configuration.py +0 -0
  235. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_cli_discovery.py +0 -0
  236. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_cli_hooks.py +0 -0
  237. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_cli_info.py +0 -0
  238. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_cli_intelligence.py +0 -0
  239. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_cli_pkg.py +0 -0
  240. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_cli_quality.py +0 -0
  241. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_cli_taps.py +0 -0
  242. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_cli_team.py +0 -0
  243. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_everyday_loop.py +0 -0
  244. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/functional/test_property_parsers.py +0 -0
  245. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/make_fixture.py +0 -0
  246. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/smoke.sh +0 -0
  247. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_adapters.py +0 -0
  248. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_agents.py +0 -0
  249. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_ai.py +0 -0
  250. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_catalog.py +0 -0
  251. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_claude_settings.py +0 -0
  252. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_cliparse.py +0 -0
  253. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_config.py +0 -0
  254. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_dense.py +0 -0
  255. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_dense_fallback.py +0 -0
  256. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_docs_pages_linked.py +0 -0
  257. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_embed.py +0 -0
  258. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_errors_and_cli_table.py +0 -0
  259. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_frontmatter.py +0 -0
  260. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_gitutil.py +0 -0
  261. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_imperative.py +0 -0
  262. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_injectscan.py +0 -0
  263. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_journal.py +0 -0
  264. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_lockfile.py +0 -0
  265. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_logs.py +0 -0
  266. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_mcp.py +0 -0
  267. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_mutation_hardening.py +0 -0
  268. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_output.py +0 -0
  269. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_paths.py +0 -0
  270. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_pkg_confusions.py +0 -0
  271. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_pkg_injection.py +0 -0
  272. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_pkg_secrets.py +0 -0
  273. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_policy.py +0 -0
  274. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_rag.py +0 -0
  275. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_registries_fresh.py +0 -0
  276. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_registry.py +0 -0
  277. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_roadmap_fresh.py +0 -0
  278. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_rules.py +0 -0
  279. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_secretscan.py +0 -0
  280. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_serve.py +0 -0
  281. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_spin.py +0 -0
  282. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_stackprobe.py +0 -0
  283. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_staleness.py +0 -0
  284. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_store.py +0 -0
  285. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_token_parity.py +0 -0
  286. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_typosquat.py +0 -0
  287. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_updatediff.py +0 -0
  288. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_util.py +0 -0
  289. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_version.py +0 -0
  290. {boost_skill_cli-1.0.138 → boost_skill_cli-1.0.140}/tests/unit/test_workflows.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.138
3
+ Version: 1.0.140
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.138'
22
- __version_tuple__ = version_tuple = (1, 0, 138)
21
+ __version__ = version = '1.0.140'
22
+ __version_tuple__ = version_tuple = (1, 0, 140)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -14,6 +14,7 @@ from typing import List
14
14
 
15
15
  from . import PRODUCT, TAGLINE, __version__
16
16
  from .core import logs
17
+ from .core import nethttp
17
18
  from .core import output as out
18
19
  from .errors import BoostError
19
20
 
@@ -223,6 +224,11 @@ def _extract_globals(argv: List[str]) -> tuple[dict, List[str]]:
223
224
 
224
225
  def main(argv: List[str] | None = None) -> int:
225
226
  argv = list(sys.argv[1:] if argv is None else argv)
227
+ # Belt-and-suspenders fork safety: a host may fork() into `boost mcp
228
+ # --stdio` without the no_proxy env boost injects at registration, leaving
229
+ # the process one default getproxies() away from a macOS _scproxy SIGABRT.
230
+ # Seed the guard for every invocation before any code path can trip it.
231
+ nethttp.harden_fork_safety()
226
232
  opts, argv = _extract_globals(argv)
227
233
  logs.configure(verbose=opts["verbose"], debug=opts["debug"],
228
234
  quiet=opts["quiet"])
@@ -15,12 +15,39 @@ fork-safe while still honoring ``HTTP(S)_PROXY`` and ``NO_PROXY``.
15
15
  """
16
16
  from __future__ import annotations
17
17
 
18
+ import os
18
19
  import urllib.request
19
20
  from typing import Union
20
21
 
21
22
  _Request = Union[str, urllib.request.Request]
22
23
 
23
24
 
25
+ def harden_fork_safety() -> bool:
26
+ """Neutralize the macOS Obj-C fork-safety abort for *this whole process*.
27
+
28
+ :func:`build_opener` keeps boost's own requests off the fork-unsafe
29
+ ``getproxies()`` sysconf path, but that only covers calls that go through
30
+ this module. A host that ``fork()``s into ``boost mcp --stdio`` from a
31
+ stale or hand-written config (one that lacks the ``no_proxy=*`` launch env
32
+ boost injects at registration), or any stray *default*-opener call inside
33
+ the process, can still reach ``getproxies_macosx_sysconf()`` → ``_scproxy``
34
+ and ``SIGABRT`` on the child side of a fork.
35
+
36
+ Seed ``no_proxy`` so the stdlib default ``getproxies()`` short-circuits on
37
+ ``getproxies_environment()`` and never consults SystemConfiguration — but
38
+ only when the user has configured *no* proxy at all, so a real
39
+ ``HTTP(S)_PROXY`` is never clobbered (in that case ``getproxies_environment``
40
+ already wins and the sysconf branch is unreachable anyway). Idempotent.
41
+
42
+ Returns ``True`` when it installed the guard, ``False`` when it left the
43
+ environment untouched (a proxy was already configured).
44
+ """
45
+ if urllib.request.getproxies_environment():
46
+ return False # user has a proxy set — respect it, and sysconf is unreached
47
+ os.environ.setdefault("no_proxy", "*")
48
+ return True
49
+
50
+
24
51
  def build_opener() -> urllib.request.OpenerDirector:
25
52
  """Build an opener whose proxy config comes only from the environment.
26
53
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boost-skill-cli
3
- Version: 1.0.138
3
+ Version: 1.0.140
4
4
  Summary: boost — Homebrew for AI coding skills
5
5
  Author: Jonathan Reyes
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -152,6 +152,7 @@ docs/roadmap/items/markdown-consistency-markdownlint-cli2.md
152
152
  docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md
153
153
  docs/roadmap/items/mcp-launch-objc-fork-safety.md
154
154
  docs/roadmap/items/mcp-register-names-server-before-env.md
155
+ docs/roadmap/items/mcp-startup-self-harden-fork-safety.md
155
156
  docs/roadmap/items/memoize-config-load-in-process.md
156
157
  docs/roadmap/items/modernization-smells-refurb-pyupgrade.md
157
158
  docs/roadmap/items/mutation-hardening-core-frontmatter-py.md
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: mcp-startup-self-harden-fork-safety
3
+ board: code
4
+ section: compat
5
+ status: shipped
6
+ category: Compatibility · macOS
7
+ complexity: S
8
+ impact: Med
9
+ wow: 3
10
+ note: self-seed no_proxy at startup
11
+ order: 9
12
+ owner: loop/mcp-startup-fork-safety
13
+ pr: 162
14
+ title: Self-harden every boost process against the macOS fork-safety abort
15
+ ---
16
+ The launch-env fix (<a href="#mcp-launch-objc-fork-safety">#119</a>) only
17
+ protects hosts that register boost <em>through boost</em>, which
18
+ injects <code>no_proxy=*</code>. A host that <code>fork()</code>s into
19
+ <code>boost mcp --stdio</code> from a stale or hand-written config —
20
+ or any stray default-opener call inside the process — is still one
21
+ <code>getproxies()</code> away from the macOS <code>_scproxy</code>
22
+ Obj-C <code>SIGABRT</code>. Close the gap from inside: at the top of
23
+ <code>main()</code>, seed <code>no_proxy</code> for the current
24
+ process (only when no <code>*_proxy</code> env is already set, so a
25
+ real proxy is never clobbered) so the stdlib default
26
+ <code>getproxies()</code> short-circuits on
27
+ <code>getproxies_environment()</code> and never consults
28
+ SystemConfiguration. Belt-and-suspenders atop the
29
+ <code>nethttp</code> opener (<a href="#fork-safe-network-proxy-handler">#115</a>).
@@ -118,7 +118,7 @@
118
118
  <div class="stat"><b>16</b><span>Shipped</span></div>
119
119
  <div class="stat"><b>1</b><span>Next up</span></div>
120
120
  <div class="stat"><b>4</b><span>Planned</span></div>
121
- <div class="stat"><b>101</b><span>Loop finds</span></div>
121
+ <div class="stat"><b>102</b><span>Loop finds</span></div>
122
122
  <!-- /ROADMAP:stats -->
123
123
  </div>
124
124
  </section>
@@ -1785,6 +1785,31 @@ and the work stays visible.</p>
1785
1785
  </div>
1786
1786
  </article>
1787
1787
 
1788
+ <article class="cap rcard">
1789
+ <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Compatibility · macOS</span></div>
1790
+ <h3>Self-harden every boost process against the macOS fork-safety abort</h3>
1791
+ <p>The launch-env fix (<a href="#mcp-launch-objc-fork-safety">#119</a>) only
1792
+ protects hosts that register boost <em>through boost</em>, which
1793
+ injects <code>no_proxy=*</code>. A host that <code>fork()</code>s into
1794
+ <code>boost mcp --stdio</code> from a stale or hand-written config —
1795
+ or any stray default-opener call inside the process — is still one
1796
+ <code>getproxies()</code> away from the macOS <code>_scproxy</code>
1797
+ Obj-C <code>SIGABRT</code>. Close the gap from inside: at the top of
1798
+ <code>main()</code>, seed <code>no_proxy</code> for the current
1799
+ process (only when no <code>*_proxy</code> env is already set, so a
1800
+ real proxy is never clobbered) so the stdlib default
1801
+ <code>getproxies()</code> short-circuits on
1802
+ <code>getproxies_environment()</code> and never consults
1803
+ SystemConfiguration. Belt-and-suspenders atop the
1804
+ <code>nethttp</code> opener (<a href="#fork-safe-network-proxy-handler">#115</a>).</p>
1805
+ <div class="meta">
1806
+ <span class="m">Complexity <b>S</b></span>
1807
+ <span class="m">Impact <b>Med</b></span>
1808
+ <span class="m">Wow <b class="wow">★★★</b></span>
1809
+ <span class="m">self-seed no_proxy at startup</span>
1810
+ </div>
1811
+ </article>
1812
+
1788
1813
  <article class="cap rcard">
1789
1814
  <div class="head"><span class="pill shipped">Shipped</span><span class="cat">Bug · MCP</span></div>
1790
1815
  <h3>Order the server name before -e flags in `boost mcp register`</h3>
@@ -5,6 +5,7 @@ The whole point of the module is to keep proxy resolution on the pure-env
5
5
  (``getproxies()`` / ``getproxies_macosx_sysconf()``), which aborts on the child
6
6
  side of a ``fork()``. These tests pin that contract.
7
7
  """
8
+ import os
8
9
  import urllib.request
9
10
 
10
11
  import pytest
@@ -83,3 +84,37 @@ class TestUrlopen:
83
84
  def test_timeout_is_required(self):
84
85
  with pytest.raises(TypeError):
85
86
  nethttp.urlopen("http://x.invalid") # type: ignore[call-arg]
87
+
88
+
89
+ class TestHardenForkSafety:
90
+ def test_seeds_no_proxy_when_no_env_proxy(self, monkeypatch):
91
+ # No *_proxy vars configured -> the default getproxies() would fall
92
+ # through to the fork-unsafe macOS sysconf path. harden seeds no_proxy
93
+ # so getproxies_environment() wins instead.
94
+ monkeypatch.setattr(urllib.request, "getproxies_environment", dict)
95
+ monkeypatch.delenv("no_proxy", raising=False)
96
+ assert nethttp.harden_fork_safety() is True
97
+ assert os.environ["no_proxy"] == "*"
98
+
99
+ def test_respects_existing_proxy_config(self, monkeypatch):
100
+ # A real proxy is set -> getproxies_environment() already wins and the
101
+ # sysconf branch is unreachable, so harden must not touch the env.
102
+ monkeypatch.setattr(urllib.request, "getproxies_environment",
103
+ lambda: {"https": "http://proxy.example:8080"})
104
+ monkeypatch.delenv("no_proxy", raising=False)
105
+ assert nethttp.harden_fork_safety() is False
106
+ assert "no_proxy" not in os.environ
107
+
108
+ def test_does_not_clobber_existing_no_proxy(self, monkeypatch):
109
+ # setdefault semantics: a user's own no_proxy value survives untouched.
110
+ monkeypatch.setattr(urllib.request, "getproxies_environment", dict)
111
+ monkeypatch.setenv("no_proxy", "example.com")
112
+ assert nethttp.harden_fork_safety() is True
113
+ assert os.environ["no_proxy"] == "example.com"
114
+
115
+ def test_idempotent(self, monkeypatch):
116
+ monkeypatch.setattr(urllib.request, "getproxies_environment", dict)
117
+ monkeypatch.delenv("no_proxy", raising=False)
118
+ assert nethttp.harden_fork_safety() is True
119
+ assert nethttp.harden_fork_safety() is True
120
+ assert os.environ["no_proxy"] == "*"