boost-skill-cli 1.0.443__tar.gz → 1.0.445__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.
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/CLAUDE.md +8 -6
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/Makefile +11 -0
- {boost_skill_cli-1.0.443/boost_skill_cli.egg-info → boost_skill_cli-1.0.445}/PKG-INFO +2 -2
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/README.md +1 -1
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/registry.py +14 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445/boost_skill_cli.egg-info}/PKG-INFO +2 -2
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_skill_cli.egg-info/SOURCES.txt +6 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/index.html +2 -2
- boost_skill_cli-1.0.445/docs/roadmap/items/unwatched-crons-hid-a-real-fuzz-crash.md +73 -0
- boost_skill_cli-1.0.445/docs/roadmap/items/zizmor-ignores-drift-and-make-lint-never-ran-it.md +54 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap.html +122 -1
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/pyproject.toml +5 -1
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/smoke.sh +5 -0
- boost_skill_cli-1.0.445/tests/unit/test_failure_alerting_covers_unattended.py +132 -0
- boost_skill_cli-1.0.445/tests/unit/test_registry_control_chars.py +113 -0
- boost_skill_cli-1.0.445/tests/unit/test_smoke_covers_every_command.py +73 -0
- boost_skill_cli-1.0.445/tests/unit/test_zizmor_ignores_still_anchor.py +118 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/.gitattributes +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/.gitignore +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/.gitleaks.toml +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/.htmlvalidate.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/.lighthouserc.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/.lycheeignore +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/.markdownlint-cli2.jsonc +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/.pre-commit-config.yaml +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/.stylelintrc.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/.vale/styles/boost/Terminology.yml +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/.vale.ini +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/CODE_OF_CONDUCT.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/LICENSE +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/MANIFEST.in +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/SECURITY.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/_common.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/configuration.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/discovery.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/info.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/intelligence.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/pkg.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/quality.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/run.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/safety.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/taps.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/commands/team.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/adapters.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/ai.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/bmad.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/bootstrap.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/builtin.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/capabilities.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/catalog.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/chat.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/claude_settings.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/complete.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/config.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/dense.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/ed25519.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/embed.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/faithfulness.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/imperative.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/injectscan.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/installscan.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/integrity.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/journal.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/localembed.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/lockfile.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/logs.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/mcp.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/mcpdecl.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/mcphost.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/minisign.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/nethttp.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/output.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/policy.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/projectlock.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/provenance.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/rag.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/resolve.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/rules.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/scopes.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/secretscan.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/selfupdate.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/serve.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/stackprobe.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/staleness.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/store.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/trustaudit.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/typosquat.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/updatediff.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/util.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/core/workflows.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/data/rules/boost-first.mdc +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_langchain/__init__.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_langchain/_compat.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_langchain/graph.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_langchain/loader.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_langchain/py.typed +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_langchain/retriever.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/codecov.yml +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/adapters.html +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/architecture/README.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/architecture/c4-components-core.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/architecture/c4-containers.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/architecture/c4-context.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/architecture/c4-dynamic-install.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/gifs/distill.gif +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/gifs/doctor.gif +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/gifs/explain.gif +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/gifs/hooks.gif +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/gifs/install.gif +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/gifs/pulse.gif +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/gifs/search.gif +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/gifs/tap.gif +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/tapes/distill.tape +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/tapes/doctor.tape +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/tapes/explain.tape +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/tapes/hooks.tape +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/tapes/install.tape +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/tapes/pulse.tape +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/tapes/search.tape +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel/tapes/tap.tape +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/carousel.html +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/chat.html +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/commands.html +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/demo-index.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/demo.gif +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/demo.html +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/demo.tape +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/eval-latest.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/eval.html +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/langchain.html +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/mcp-hub.html +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D01.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D02.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D03.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D04.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D05.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D06.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D07.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D08.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D09.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D10.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D11.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D12.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D13.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D14.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D15.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D16.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D17.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D18.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D19.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D20.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D21.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D22.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D23.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D24.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D25.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/BOOST-D26.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/a11y-sweep-flakes-on-color-contrast.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/agents-field-records-the-request-not-the-links.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/bm25-index-is-one-json-blob.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/bmad-autopilot-one-command-persona-routing.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/boost-first-carried-the-losing-trigger.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/boost-first-rule.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/boost-langchain-publishing.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/boost-run-live-agents.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/chat-cites-sources-by-a-number-it-never-prints.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/chat-command-grounded-conversational-search.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/command-carousel-page.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/command-reference-docs-site.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/completions-complete-only-command-names.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/demo-workflow-cancels-other-prs.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/dependabot-splits-multi-path-action-repos.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/discover-searches-github-not-a-stale-sample.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/dry-run-promised-a-link-nobody-makes.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/efficiency-registries-ponytail-caveman.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/est-items-counts-agent-mirrors-as-items.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/eval-corpus-cannot-see-real-retrieval.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/eval-corpus-is-96x-smaller-than-a-real-install.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/eval-corpus-is-one-strangers-repo.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/eval-corpus-pins-have-no-refresh-path.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/eval-corpus-was-not-actually-pinned.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/eval-deduped-ranked-lists-by-name.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/eval-stats-could-never-publish.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/expanded-card-bodies-overflow.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/gemini-agent-frontmatter-sanitizer.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/github-community-health-files.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/golden-set-grades-by-name-not-by-skill.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/heal-deleted-links-it-never-made.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/html-validation-html-validate.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/info-rejects-the-qualified-name-it-recommends.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/install-path-disambiguation.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/keyless-dense-tier-local-static-embeddings.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/keyless-semantic-search-for-everyone.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/langchain-in-the-wheel.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/langchain-integration-explainer-page.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/langchain-langgraph-langsmith-integration.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/langchain-retriever-metadata-and-k-floor.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/license-compliance-scanning.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/lighthouse-scored-a-page-nobody-is-served.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-already-covered-defeater.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-aware-skills.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-one-benefit-nameable-task.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-search-cost-was-understated.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-search-hid-which-ranking-ran.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mcp-zero-setup-and-three-kinds.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/near-duplicate-items-eat-the-result-slots.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/one-dead-tap-broke-every-update.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/pep585-604-modernization-sweep.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/prerequisites-and-semantic-search-setup.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/python-floor-moves-to-312.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/ragas-unpin-when-upstream-ships.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/required-checks-config-drift.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/resolve-vendored-duplicate-copies.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/roadmap-page-weight-grows-without-bound.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/roadmap-perf-budget-has-no-local-guard.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/rules-install-but-cannot-be-governed.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/scripts-under-the-lint-gate.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/search-never-notices-a-new-tap.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/serve-404-reflected-the-request.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/serve-is-a-searchable-catalogue.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/tool-call-eval-tier.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/typo-detection-codespell.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/update-advertises-a-flag-it-rejects.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/update-diff-before-apply.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/update-refreshed-rules-without-a-gate.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/workspace-scope-install.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/zip-strict-audit.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/eslint.config.mjs +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/evals/README.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/evals/__init__.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/evals/baseline.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/evals/faithfulness.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/evals/golden_set.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/evals/make_corpus.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/evals/make_golden.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/evals/metrics.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/evals/publish_golden_dataset.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/evals/run_evals.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/examples/README.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/examples/adapt-demo.sh +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/examples/boost-run-prototype.sh +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/index.html +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/noxfile.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/requirements/coverage-tools.in +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/requirements/coverage-tools.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/requirements/lint-tools.in +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/requirements/lint-tools.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/requirements/mutation-tools.in +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/requirements/mutation-tools.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/requirements/platform-pins.lock +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/requirements/release-tools.in +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/requirements/release-tools.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/requirements/test-tools.in +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/requirements/test-tools.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/a11y_check.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/bench_cli.sh +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/build_command_reference.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/build_demo_index.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/build_roadmap.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/build_scale_corpus.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/check_anchors.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/check_licenses.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/check_required_checks.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/ensure_eval_corpus.sh +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/eval_corpus.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/eval_explain.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/eval_gate.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/eval_recommend.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/eval_retrieval.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/eval_stats_summary.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/import_budget.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/lock_toolchain.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/measure_registry.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/mutation_shards.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/mutation_weights.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/page_budget.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/perf_gate.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/post_deploy_smoke.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/publish_eval_json.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/release_guard.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/release_preflight.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/scripts/serve_docs.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/setup.cfg +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/sonar-project.properties +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/style/README.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/style/boost.css +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/style/boost.js +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/style/demo.html +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/adapt.feature +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/browse.feature +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/count.feature +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/discover.feature +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/doctor.feature +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/environment.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/explain.feature +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/index.feature +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/install.feature +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/list.feature +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/mcp.feature +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/search.feature +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/steps/cli_steps.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/steps/discovery_steps.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/steps/mcp_steps.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/bdd/features/steps/quality_steps.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/conftest.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/eval/baseline.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/eval/explain.jsonl +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/eval/golden-natural.jsonl +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/eval/golden.jsonl +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/eval/recommend.jsonl +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/eval/taps-scale.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/eval/taps.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_capabilities_policy.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_cli_adapt.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_cli_chat.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_cli_configuration.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_cli_discovery.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_cli_info.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_cli_pkg.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_cli_quality.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_integrity_enforce.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_kind_conformance.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_property_parsers.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_run.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_tap_signing.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/functional/test_workspace_scope.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/README.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/registry/02-https.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/registry/06-space.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/fuzz_frontmatter.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/fuzz/fuzz_registry.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/langchain/conftest.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/langchain/test_graph.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/langchain/test_loader.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/langchain/test_retriever.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/perf/test_benchmarks.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_a11y_check.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_action_pin_lockstep.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_adapters.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_adapters_multi.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_adapters_runner.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_bmad_core.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_boost_first_offer.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_bootstrap.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_builtin.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_capabilities.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_chat.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_check_anchors.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_check_licenses.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_codeql_analysis_key.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_command_reference_fresh.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_community_health_files.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_complete.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_content_dedupe.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_dedup_trust.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_demo_index.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_dense_fallback.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_dense_fix_hint.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_dense_shards.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_dense_status.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_dependabot_config.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_docs_pages_linked.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_docsite_chrome.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_ed25519.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_embed_local.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_entry_key.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_eval_baseline.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_eval_corpus.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_eval_faithfulness.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_eval_gate.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_eval_grading.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_eval_metrics.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_eval_stats_summary.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_faithfulness.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_fuzz_targets.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_gemini_agent_sanitize.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_gitleaks_config.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_gitutil_lfs.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_imperative.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_import_budget.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_injectscan.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_installscan.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_integrity.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_langchain_packaging.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_link_ownership.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_localembed.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_localembed_e2e.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_marketing_counts.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_mcp.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_mcp_install_scan.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_mcpdecl.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_mcphost.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_measure_registry.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_minisign.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_mutation_shards.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_mutation_subfile_shards.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_mutmut_source_paths.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_nethttp.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_page_budget.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_perf_gate.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_pkg_confusions.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_pkg_injection.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_pkg_secrets.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_platform_pins.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_post_deploy_smoke.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_project_mcp_sidecar.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_projectlock.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_provenance.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_publish_golden_dataset.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_rag_fusion.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_registries_fresh.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_registry_categories.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_release_guard.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_release_preflight.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_required_checks.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_resolve.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_roadmap_fresh.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_rules.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_scale_corpus.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_scopes.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_secretscan.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_selfupdate.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_serve.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_serve_docs.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_stackprobe.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_staleness.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_store.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_toolchain_lock.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_trustaudit.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_typosquat.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_updatediff.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_util.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_version.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_workflow_concurrency.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_workflow_concurrency_groups.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_workflow_push_has_credentials.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_workflow_timeouts.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/unit/test_workflows.py +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/visual/a11y_check.mjs +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/visual/console_check.mjs +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/visual/package-lock.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/visual/package.json +0 -0
- {boost_skill_cli-1.0.443 → boost_skill_cli-1.0.445}/tests/visual/visual_check.mjs +0 -0
|
@@ -150,11 +150,13 @@ line coverage. Target `boost_cli/core` behavior with assertions, not just import
|
|
|
150
150
|
publish workflow filename must stay `publish.yml` (PyPI Trusted Publisher
|
|
151
151
|
matches on it).
|
|
152
152
|
- **Target Python ≥ 3.12** (`requires-python = ">=3.12"`). Structural pattern
|
|
153
|
-
matching and runtime `X | Y` unions are now legal. The `typing.List` →
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
153
|
+
matching and runtime `X | Y` unions are now legal. The `typing.List` → `list`
|
|
154
|
+
sweep is **done**: UP006/UP035/UP045 are selected, not ignored, and report zero
|
|
155
|
+
violations. (This entry described the sweep as deferred long after it landed —
|
|
156
|
+
measure before trusting a "not done yet" note.) `UP031` printf-formatting *is*
|
|
157
|
+
still ignored, and deliberately: it is an unsafe fix over ~1,000 call sites in
|
|
158
|
+
`boost_cli` alone. Write new code in the modern style; don't bulk-rewrite old
|
|
159
|
+
code in an unrelated PR.
|
|
158
160
|
- **Three item kinds, one scanner.** `core/catalog.scan_dir` indexes `skill`
|
|
159
161
|
(SKILL.md), `rule` (.mdc/.cursorrules/.windsurfrules/.clinerules), and
|
|
160
162
|
`workflow` (commands/agents/workflows Markdown). **All three install**, and
|
|
@@ -294,7 +296,7 @@ each agent's skills dir, and updating the lock file.
|
|
|
294
296
|
|
|
295
297
|
**Search has two engines**, both in `core/`: `rag.py` is the always-on,
|
|
296
298
|
zero-dependency BM25 engine (full-content index, auto-builds on first
|
|
297
|
-
search — this is what the required `eval` gate floors at recall@k ≥ 0.
|
|
299
|
+
search — this is what the required `eval` gate floors at recall@k ≥ 0.78).
|
|
298
300
|
`dense.py` is optional dense/vector retrieval behind the `[rag]` extra —
|
|
299
301
|
**no API key required**: `embed.py` tries Voyage, then OpenAI, then a local
|
|
300
302
|
`BAAI/bge-small-en-v1.5` that ships with the extra, so a key is a quality
|
|
@@ -73,6 +73,17 @@ lint:
|
|
|
73
73
|
fi; \
|
|
74
74
|
PATH="$(CURDIR)/$(VENV)/bin:$$PATH" actionlint; \
|
|
75
75
|
else echo "actionlint not on PATH — skipping (CI enforces it)"; fi
|
|
76
|
+
@# zizmor: workflow SAST, and it was MISSING from this recipe entirely while
|
|
77
|
+
@# CI's lint job ran it — so `make lint` could return 0 on a branch whose
|
|
78
|
+
@# lint job was already red. That happened: .github/zizmor.yml suppresses
|
|
79
|
+
@# accepted findings by file:LINE, adding a header comment to
|
|
80
|
+
@# ci-failure-issue.yml moved its `on:` block from line 12 to 28, and the
|
|
81
|
+
@# un-anchored `dangerous-triggers` finding went live. Nothing local looked.
|
|
82
|
+
@# `--offline` because the impostor/ref audits need GitHub API access the
|
|
83
|
+
@# dev sandbox proxy flakes on; CI runs it online.
|
|
84
|
+
@if [ -x $(VENV)/bin/zizmor ]; then \
|
|
85
|
+
$(VENV)/bin/zizmor --offline .github/workflows/; \
|
|
86
|
+
else echo "zizmor not in $(VENV) — skipping (CI enforces it)"; fi
|
|
76
87
|
$(PY) scripts/build_registries.py --check
|
|
77
88
|
$(PY) scripts/build_roadmap.py --check
|
|
78
89
|
$(PY) scripts/build_command_reference.py --check
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boost-skill-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.445
|
|
4
4
|
Summary: boost — Homebrew for AI coding skills
|
|
5
5
|
Author: Jonathan Reyes
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -1161,7 +1161,7 @@ Four layers, all enforced (`make check` runs the full set; CI runs the same thin
|
|
|
1161
1161
|
| Layer | What it does | Gate |
|
|
1162
1162
|
|---|---|---|
|
|
1163
1163
|
| `make test` | pytest across `tests/unit/` (every core module) and `tests/functional/` (drives all 78 commands in-process against sandboxed homes) | **≥80% line coverage** of `boost_cli` (`fail_under` in pyproject.toml) |
|
|
1164
|
-
| `make smoke` | `tests/smoke.sh` —
|
|
1164
|
+
| `make smoke` | `tests/smoke.sh` — 174 checks run through the actual `./boost` shim (`--online` also hits real registries) | all pass |
|
|
1165
1165
|
| `make mutation` | [mutmut] mutates `boost_cli/core` (~9,900 mutants) and reruns the unit suite against each one | **≥80% killed** (`scripts/mutation_gate.py`) |
|
|
1166
1166
|
| `make evals` | scores the search ranker on a graded golden set — recall@5/@10, MRR, nDCG@5/@10 | **metric floors + no statistically significant regression** (`scripts/eval_gate.py`) |
|
|
1167
1167
|
|
|
@@ -443,7 +443,7 @@ Four layers, all enforced (`make check` runs the full set; CI runs the same thin
|
|
|
443
443
|
| Layer | What it does | Gate |
|
|
444
444
|
|---|---|---|
|
|
445
445
|
| `make test` | pytest across `tests/unit/` (every core module) and `tests/functional/` (drives all 78 commands in-process against sandboxed homes) | **≥80% line coverage** of `boost_cli` (`fail_under` in pyproject.toml) |
|
|
446
|
-
| `make smoke` | `tests/smoke.sh` —
|
|
446
|
+
| `make smoke` | `tests/smoke.sh` — 174 checks run through the actual `./boost` shim (`--online` also hits real registries) | all pass |
|
|
447
447
|
| `make mutation` | [mutmut] mutates `boost_cli/core` (~9,900 mutants) and reruns the unit suite against each one | **≥80% killed** (`scripts/mutation_gate.py`) |
|
|
448
448
|
| `make evals` | scores the search ranker on a graded golden set — recall@5/@10, MRR, nDCG@5/@10 | **metric floors + no statistically significant regression** (`scripts/eval_gate.py`) |
|
|
449
449
|
|
|
@@ -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.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 0,
|
|
21
|
+
__version__ = version = '1.0.445'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 0, 445)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -43,6 +43,20 @@ def parse_spec(spec: str):
|
|
|
43
43
|
Accepts: owner/repo | full git URL | existing local path.
|
|
44
44
|
"""
|
|
45
45
|
spec = spec.strip().rstrip("/")
|
|
46
|
+
# Reject control characters HERE, at the parse boundary, rather than letting
|
|
47
|
+
# them travel. A NUL cannot appear in a GitHub owner/repo, a git URL or a
|
|
48
|
+
# usable directory name, so nothing legitimate is turned away — but accepted,
|
|
49
|
+
# it reaches a filesystem call and dies as `ValueError: lstat: embedded null
|
|
50
|
+
# character in path` from inside posixpath, naming neither the tap nor the
|
|
51
|
+
# command, and as a ValueError rather than a BoostError the CLI's error
|
|
52
|
+
# handling never gets to frame it. fuzz.yml found this and failed three
|
|
53
|
+
# scheduled runs out of three before anyone looked (2026-07-25/08-01/08-08).
|
|
54
|
+
# \x1b matters for a second reason: an escape sequence in a name is echoed
|
|
55
|
+
# by every surface that prints a tap list.
|
|
56
|
+
if any(ord(c) < 0x20 or ord(c) == 0x7F for c in spec):
|
|
57
|
+
raise BoostError(
|
|
58
|
+
"tap spec contains a control character: %r" % spec,
|
|
59
|
+
hint="use owner/repo, a git URL, or a local directory")
|
|
46
60
|
# paths.expand(), not Path.expanduser(): expanduser() consults the OS's
|
|
47
61
|
# own home-dir lookup (USERPROFILE on Windows), which ignores the $HOME
|
|
48
62
|
# override the whole test suite (and BOOST_HOME sandboxing) relies on.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boost-skill-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.445
|
|
4
4
|
Summary: boost — Homebrew for AI coding skills
|
|
5
5
|
Author: Jonathan Reyes
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -1161,7 +1161,7 @@ Four layers, all enforced (`make check` runs the full set; CI runs the same thin
|
|
|
1161
1161
|
| Layer | What it does | Gate |
|
|
1162
1162
|
|---|---|---|
|
|
1163
1163
|
| `make test` | pytest across `tests/unit/` (every core module) and `tests/functional/` (drives all 78 commands in-process against sandboxed homes) | **≥80% line coverage** of `boost_cli` (`fail_under` in pyproject.toml) |
|
|
1164
|
-
| `make smoke` | `tests/smoke.sh` —
|
|
1164
|
+
| `make smoke` | `tests/smoke.sh` — 174 checks run through the actual `./boost` shim (`--online` also hits real registries) | all pass |
|
|
1165
1165
|
| `make mutation` | [mutmut] mutates `boost_cli/core` (~9,900 mutants) and reruns the unit suite against each one | **≥80% killed** (`scripts/mutation_gate.py`) |
|
|
1166
1166
|
| `make evals` | scores the search ranker on a graded golden set — recall@5/@10, MRR, nDCG@5/@10 | **metric floors + no statistically significant regression** (`scripts/eval_gate.py`) |
|
|
1167
1167
|
|
|
@@ -404,6 +404,7 @@ docs/roadmap/items/typosquat-and-name-confusion-detection.md
|
|
|
404
404
|
docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md
|
|
405
405
|
docs/roadmap/items/uninstall-has-no-confirmation-prompt.md
|
|
406
406
|
docs/roadmap/items/untrack-generated-build-noise.md
|
|
407
|
+
docs/roadmap/items/unwatched-crons-hid-a-real-fuzz-crash.md
|
|
407
408
|
docs/roadmap/items/update-advertises-a-flag-it-rejects.md
|
|
408
409
|
docs/roadmap/items/update-diff-before-apply.md
|
|
409
410
|
docs/roadmap/items/update-refreshed-rules-without-a-gate.md
|
|
@@ -418,6 +419,7 @@ docs/roadmap/items/workflow-linting-actionlint.md
|
|
|
418
419
|
docs/roadmap/items/workflow-sast-zizmor.md
|
|
419
420
|
docs/roadmap/items/workspace-scope-install.md
|
|
420
421
|
docs/roadmap/items/zip-strict-audit.md
|
|
422
|
+
docs/roadmap/items/zizmor-ignores-drift-and-make-lint-never-ran-it.md
|
|
421
423
|
docs/roadmap/items/zizmor-pin-is-a-yanked-release.md
|
|
422
424
|
evals/README.md
|
|
423
425
|
evals/__init__.py
|
|
@@ -597,6 +599,7 @@ tests/unit/test_eval_gate.py
|
|
|
597
599
|
tests/unit/test_eval_grading.py
|
|
598
600
|
tests/unit/test_eval_metrics.py
|
|
599
601
|
tests/unit/test_eval_stats_summary.py
|
|
602
|
+
tests/unit/test_failure_alerting_covers_unattended.py
|
|
600
603
|
tests/unit/test_faithfulness.py
|
|
601
604
|
tests/unit/test_frontmatter.py
|
|
602
605
|
tests/unit/test_fuzz_targets.py
|
|
@@ -647,6 +650,7 @@ tests/unit/test_rag_fusion.py
|
|
|
647
650
|
tests/unit/test_registries_fresh.py
|
|
648
651
|
tests/unit/test_registry.py
|
|
649
652
|
tests/unit/test_registry_categories.py
|
|
653
|
+
tests/unit/test_registry_control_chars.py
|
|
650
654
|
tests/unit/test_release_guard.py
|
|
651
655
|
tests/unit/test_release_preflight.py
|
|
652
656
|
tests/unit/test_required_checks.py
|
|
@@ -659,6 +663,7 @@ tests/unit/test_secretscan.py
|
|
|
659
663
|
tests/unit/test_selfupdate.py
|
|
660
664
|
tests/unit/test_serve.py
|
|
661
665
|
tests/unit/test_serve_docs.py
|
|
666
|
+
tests/unit/test_smoke_covers_every_command.py
|
|
662
667
|
tests/unit/test_spin.py
|
|
663
668
|
tests/unit/test_stackprobe.py
|
|
664
669
|
tests/unit/test_staleness.py
|
|
@@ -675,6 +680,7 @@ tests/unit/test_workflow_concurrency_groups.py
|
|
|
675
680
|
tests/unit/test_workflow_push_has_credentials.py
|
|
676
681
|
tests/unit/test_workflow_timeouts.py
|
|
677
682
|
tests/unit/test_workflows.py
|
|
683
|
+
tests/unit/test_zizmor_ignores_still_anchor.py
|
|
678
684
|
tests/visual/a11y_check.mjs
|
|
679
685
|
tests/visual/console_check.mjs
|
|
680
686
|
tests/visual/package-lock.json
|
|
@@ -570,7 +570,7 @@
|
|
|
570
570
|
<div class="stats">
|
|
571
571
|
<div class="stat reveal"><b>70,000+</b><span>Discoverable assets</span></div>
|
|
572
572
|
<div class="stat reveal"><b>78</b><span>Commands · 8 groups</span></div>
|
|
573
|
-
<div class="stat reveal"><b>
|
|
573
|
+
<div class="stat reveal"><b>7</b><span>Pre-tapped registries</span></div>
|
|
574
574
|
<div class="stat reveal"><b>4</b><span>AI agents supported</span></div>
|
|
575
575
|
</div>
|
|
576
576
|
|
|
@@ -648,7 +648,7 @@ facilitate structured divergent thinking:
|
|
|
648
648
|
<div class="node src">
|
|
649
649
|
<span class="tag">Source</span>
|
|
650
650
|
<h3>GitHub registries</h3>
|
|
651
|
-
<p>
|
|
651
|
+
<p>7 pre-tapped registries + a 10,000-skill discovery index</p>
|
|
652
652
|
</div>
|
|
653
653
|
</div>
|
|
654
654
|
<div class="flow-arrow reveal">
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: unwatched-crons-hid-a-real-fuzz-crash
|
|
3
|
+
board: code
|
|
4
|
+
section: pipeline
|
|
5
|
+
status: shipped
|
|
6
|
+
category: Build · Bug
|
|
7
|
+
complexity: M
|
|
8
|
+
impact: High
|
|
9
|
+
wow: 5
|
|
10
|
+
note: the fuzzer found a real crash and was right for three weeks — 24 unattended workflows, 2 watched
|
|
11
|
+
order: 108
|
|
12
|
+
owner: fix/parse-spec-control-chars
|
|
13
|
+
pr:
|
|
14
|
+
title: The fuzzer found a real crash and nobody was listening
|
|
15
|
+
---
|
|
16
|
+
<code>fuzz.yml</code> runs libFuzzer over <code>registry.parse_spec</code> weekly. It has failed
|
|
17
|
+
<b>three scheduled runs out of three</b> — 2026-07-25, 08-01 and 08-08 — writing the same minimised
|
|
18
|
+
reproducer each time. It was right every time, and nobody looked for three weeks.
|
|
19
|
+
|
|
20
|
+
<b>The crash.</b> Ten bytes, <code>/\0\0\0\0\0\0\0\0A</code>. <code>parse_spec</code> accepted them
|
|
21
|
+
and returned a perfectly well-formed pair:
|
|
22
|
+
|
|
23
|
+
<code>('/\0…A', 'https://github.com//\0…A')</code>
|
|
24
|
+
|
|
25
|
+
Nothing raised, so the name travelled — into <code>config.json</code> and through
|
|
26
|
+
<code>Tap.safe_name</code> into a clone path built around a NUL byte.
|
|
27
|
+
|
|
28
|
+
<b>The diagnosis was re-done twice, and both corrections matter.</b> An automated audit first
|
|
29
|
+
reported this as "an uncaught-exception bug in <code>boost tap</code>". Running the payload showed
|
|
30
|
+
<code>parse_spec</code> returning normally, and the real traceback — from the job log — lands on
|
|
31
|
+
<code>tests/fuzz/fuzz_registry.py:85</code>, where the harness's own containment check calls
|
|
32
|
+
<code>os.path.realpath</code>. An adversarial re-check then killed the rest of the product claim, and
|
|
33
|
+
it is worth stating plainly because the first draft of this card got it wrong:
|
|
34
|
+
|
|
35
|
+
<b>A NUL can never reach the CLI at all.</b> <code>execve</code> refuses an argument containing one
|
|
36
|
+
(<code>ValueError: embedded null byte</code>), so <code>boost tap $'/\0…A'</code> is not a command
|
|
37
|
+
that can be run. And in-process the product does <i>not</i> crash either:
|
|
38
|
+
<code>pathlib</code> swallows the error, so <code>Tap.path.exists()</code> simply returns
|
|
39
|
+
<code>False</code>. Only <code>os.path.realpath</code> raises — and the sole caller of that is the
|
|
40
|
+
fuzz harness.
|
|
41
|
+
|
|
42
|
+
So the honest case for the fix is not "the CLI crashes". It is three narrower things.
|
|
43
|
+
<b>First</b>, other control characters are <i>not</i> execve-blocked — <code>\x1b</code> survives
|
|
44
|
+
<code>argv</code> intact, so an escape sequence in a tap name reaches the CLI and is echoed by every
|
|
45
|
+
surface that prints a tap list. <b>Second</b>, a NUL-bearing name yields a path whose
|
|
46
|
+
<code>exists()</code> is permanently <code>False</code> — silently wrong beats loudly broken only
|
|
47
|
+
until someone has to debug it. <b>Third</b>, and largest: the harness died on its <b>1,322nd</b>
|
|
48
|
+
unit, so the run recorded <code>new_units_added: 0</code> and
|
|
49
|
+
<code>average_exec_per_sec: 0</code> — <b>the registry parser has had no fuzz coverage at all since
|
|
50
|
+
the workflow was added on 2026-07-24</b>, while still costing a runner slot every Saturday.
|
|
51
|
+
|
|
52
|
+
<b>Fixed at the parse boundary.</b> A control character cannot appear in a GitHub
|
|
53
|
+
<code>owner/repo</code>, in a git URL, or in a usable directory name, so rejecting them turns nothing
|
|
54
|
+
legitimate away — and it converts an arbitrary later <code>ValueError</code> into the documented
|
|
55
|
+
<code>BoostError</code> rejection path, which the fuzz harness already handles and the CLI already
|
|
56
|
+
renders with a hint. <code>\x1b</code> matters for a second reason: an escape sequence in a name is
|
|
57
|
+
echoed back by every surface that prints a tap list. Verified by running the real harness over the
|
|
58
|
+
exact reproducer, which now passes.
|
|
59
|
+
|
|
60
|
+
<b>The reason it stayed hidden is the more valuable half.</b>
|
|
61
|
+
<code>ci-failure-issue.yml</code> opens a tracking issue when a watched workflow fails on
|
|
62
|
+
<code>main</code>, and its own header states the rule: <i>"Any workflow that runs on main and nobody
|
|
63
|
+
watches belongs here."</i> It watched <b>two</b>. <b>Twenty-four</b> ran unattended — fourteen on a
|
|
64
|
+
cron. The rule was written down and not applied, which is the most expensive kind of convention,
|
|
65
|
+
and it is the same blind spot that let <code>shards</code> fail both its scheduled runs and publish
|
|
66
|
+
zero artifacts.
|
|
67
|
+
|
|
68
|
+
All twenty-six are watched now, and the list is <b>enforced rather than curated</b>:
|
|
69
|
+
<code>tests/unit/test_failure_alerting_covers_unattended.py</code> fails the build when a workflow
|
|
70
|
+
runs unattended and is neither watched nor listed in an <code>EXPECTED_UNWATCHED</code> map with a
|
|
71
|
+
reason. A new scheduled workflow therefore cannot quietly join the blind spot — the same shape as
|
|
72
|
+
the action-pin lockstep guard, where the convention stays falsifiable instead of decaying the moment
|
|
73
|
+
the person who wrote it stops looking.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: zizmor-ignores-drift-and-make-lint-never-ran-it
|
|
3
|
+
board: code
|
|
4
|
+
section: pipeline
|
|
5
|
+
status: shipped
|
|
6
|
+
category: Build · Bug
|
|
7
|
+
complexity: S
|
|
8
|
+
impact: Med
|
|
9
|
+
wow: 4
|
|
10
|
+
note: a comment four lines long un-silenced a reviewed finding, and no local gate could see it
|
|
11
|
+
order: 110
|
|
12
|
+
owner: fix/parse-spec-control-chars
|
|
13
|
+
pr:
|
|
14
|
+
title: A line-anchored suppression drifted, and make lint never ran the tool
|
|
15
|
+
---
|
|
16
|
+
<code>.github/zizmor.yml</code> silences accepted workflow-SAST findings by
|
|
17
|
+
<b><code>file:LINE</code></b>. That anchor is fragile in a specific way: insert anything above the
|
|
18
|
+
construct and the ignore stops applying — or, worse, starts applying to a <i>different</i> construct
|
|
19
|
+
nobody reviewed.
|
|
20
|
+
|
|
21
|
+
It drifted here. Adding a header comment to <code>ci-failure-issue.yml</code> (explaining the
|
|
22
|
+
alerting-coverage fix) moved its <code>on:</code> block from <b>line 12 to line 28</b>, and CI's
|
|
23
|
+
<code>lint</code> job went red on <code>dangerous-triggers</code> — for a <code>workflow_run</code>
|
|
24
|
+
trigger that had been reviewed and accepted months earlier, with the reasoning written out in the
|
|
25
|
+
config right above the anchor.
|
|
26
|
+
|
|
27
|
+
<b>The config predicted it.</b> Its own note reads: <i>"these ignores are keyed by file:LINE, so
|
|
28
|
+
editing anything above a workflow's <code>on:</code> block moves it and silently un-ignores the
|
|
29
|
+
finding."</i> A warning in a comment is not a control — it depends on the next person reading the
|
|
30
|
+
file they are not editing.
|
|
31
|
+
|
|
32
|
+
<b>The second half is why nothing local caught it.</b> <code>make lint</code> <b>never ran
|
|
33
|
+
zizmor</b>. The recipe runs ruff, mypy, pyright, import-linter, vulture, xenon, interrogate, refurb,
|
|
34
|
+
codespell and actionlint — and CI's <code>lint</code> job additionally runs zizmor, which the
|
|
35
|
+
Makefile did not. So <code>make lint</code> could return <b>0</b> on a branch whose <code>lint</code>
|
|
36
|
+
job was already red, which is exactly what happened: the gate was run, it passed, and it had not
|
|
37
|
+
looked. (<code>CLAUDE.md</code> and an operator note both listed zizmor among the tools
|
|
38
|
+
<code>make lint</code> runs. Neither was true.)
|
|
39
|
+
|
|
40
|
+
Both halves are closed. zizmor now runs in <code>make lint</code>, guarded the same way actionlint
|
|
41
|
+
is — present, or an explicit "skipping (CI enforces it)" rather than silence — and
|
|
42
|
+
<code>--offline</code>, because the impostor and ref audits need GitHub API access the dev sandbox's
|
|
43
|
+
proxy flakes on.
|
|
44
|
+
|
|
45
|
+
And <code>tests/unit/test_zizmor_ignores_still_anchor.py</code> checks the cheap mechanical property
|
|
46
|
+
the line numbers depend on: every <code>dangerous-triggers</code> anchor still lands on an
|
|
47
|
+
<code>on:</code> line, no anchor points past the end of its file, no ignore names a workflow that no
|
|
48
|
+
longer exists, and no anchor is duplicated. It does not re-run zizmor — CI owns that — it asserts
|
|
49
|
+
that the anchors still mean what they say.
|
|
50
|
+
|
|
51
|
+
<b>Both fixes were verified by re-breaking the tree.</b> With the anchor put back to
|
|
52
|
+
<code>:12</code>, the new test goes red naming the drift, and <code>make lint</code> exits
|
|
53
|
+
<b>2</b> — the failure that previously only appeared in CI, now reproducible in one command before
|
|
54
|
+
the push.
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
<div class="stat"><b>16</b><span>Shipped</span></div>
|
|
134
134
|
<div class="stat"><b>1</b><span>Next up</span></div>
|
|
135
135
|
<div class="stat"><b>7</b><span>Planned</span></div>
|
|
136
|
-
<div class="stat"><b>
|
|
136
|
+
<div class="stat"><b>242</b><span>Loop finds</span></div>
|
|
137
137
|
<!-- /ROADMAP:stats -->
|
|
138
138
|
</div>
|
|
139
139
|
</section>
|
|
@@ -6112,6 +6112,76 @@ vacuously if the trigger detection silently stops matching.</p></details>
|
|
|
6112
6112
|
</div>
|
|
6113
6113
|
</article>
|
|
6114
6114
|
|
|
6115
|
+
<article class="cap rcard" id="unwatched-crons-hid-a-real-fuzz-crash">
|
|
6116
|
+
<div class="head"><span class="pill shipped">Shipped</span><span class="cat">Build · Bug</span></div>
|
|
6117
|
+
<h3>The fuzzer found a real crash and nobody was listening</h3>
|
|
6118
|
+
<details class="cardbody"><summary>Write-up</summary>
|
|
6119
|
+
<p><code>fuzz.yml</code> runs libFuzzer over <code>registry.parse_spec</code> weekly. It has failed
|
|
6120
|
+
<b>three scheduled runs out of three</b> — 2026-07-25, 08-01 and 08-08 — writing the same minimised
|
|
6121
|
+
reproducer each time. It was right every time, and nobody looked for three weeks.
|
|
6122
|
+
|
|
6123
|
+
<b>The crash.</b> Ten bytes, <code>/\0\0\0\0\0\0\0\0A</code>. <code>parse_spec</code> accepted them
|
|
6124
|
+
and returned a perfectly well-formed pair:
|
|
6125
|
+
|
|
6126
|
+
<code>('/\0…A', 'https://github.com//\0…A')</code>
|
|
6127
|
+
|
|
6128
|
+
Nothing raised, so the name travelled — into <code>config.json</code> and through
|
|
6129
|
+
<code>Tap.safe_name</code> into a clone path built around a NUL byte.
|
|
6130
|
+
|
|
6131
|
+
<b>The diagnosis was re-done twice, and both corrections matter.</b> An automated audit first
|
|
6132
|
+
reported this as "an uncaught-exception bug in <code>boost tap</code>". Running the payload showed
|
|
6133
|
+
<code>parse_spec</code> returning normally, and the real traceback — from the job log — lands on
|
|
6134
|
+
<code>tests/fuzz/fuzz_registry.py:85</code>, where the harness's own containment check calls
|
|
6135
|
+
<code>os.path.realpath</code>. An adversarial re-check then killed the rest of the product claim, and
|
|
6136
|
+
it is worth stating plainly because the first draft of this card got it wrong:
|
|
6137
|
+
|
|
6138
|
+
<b>A NUL can never reach the CLI at all.</b> <code>execve</code> refuses an argument containing one
|
|
6139
|
+
(<code>ValueError: embedded null byte</code>), so <code>boost tap $'/\0…A'</code> is not a command
|
|
6140
|
+
that can be run. And in-process the product does <i>not</i> crash either:
|
|
6141
|
+
<code>pathlib</code> swallows the error, so <code>Tap.path.exists()</code> simply returns
|
|
6142
|
+
<code>False</code>. Only <code>os.path.realpath</code> raises — and the sole caller of that is the
|
|
6143
|
+
fuzz harness.
|
|
6144
|
+
|
|
6145
|
+
So the honest case for the fix is not "the CLI crashes". It is three narrower things.
|
|
6146
|
+
<b>First</b>, other control characters are <i>not</i> execve-blocked — <code>\x1b</code> survives
|
|
6147
|
+
<code>argv</code> intact, so an escape sequence in a tap name reaches the CLI and is echoed by every
|
|
6148
|
+
surface that prints a tap list. <b>Second</b>, a NUL-bearing name yields a path whose
|
|
6149
|
+
<code>exists()</code> is permanently <code>False</code> — silently wrong beats loudly broken only
|
|
6150
|
+
until someone has to debug it. <b>Third</b>, and largest: the harness died on its <b>1,322nd</b>
|
|
6151
|
+
unit, so the run recorded <code>new_units_added: 0</code> and
|
|
6152
|
+
<code>average_exec_per_sec: 0</code> — <b>the registry parser has had no fuzz coverage at all since
|
|
6153
|
+
the workflow was added on 2026-07-24</b>, while still costing a runner slot every Saturday.
|
|
6154
|
+
|
|
6155
|
+
<b>Fixed at the parse boundary.</b> A control character cannot appear in a GitHub
|
|
6156
|
+
<code>owner/repo</code>, in a git URL, or in a usable directory name, so rejecting them turns nothing
|
|
6157
|
+
legitimate away — and it converts an arbitrary later <code>ValueError</code> into the documented
|
|
6158
|
+
<code>BoostError</code> rejection path, which the fuzz harness already handles and the CLI already
|
|
6159
|
+
renders with a hint. <code>\x1b</code> matters for a second reason: an escape sequence in a name is
|
|
6160
|
+
echoed back by every surface that prints a tap list. Verified by running the real harness over the
|
|
6161
|
+
exact reproducer, which now passes.
|
|
6162
|
+
|
|
6163
|
+
<b>The reason it stayed hidden is the more valuable half.</b>
|
|
6164
|
+
<code>ci-failure-issue.yml</code> opens a tracking issue when a watched workflow fails on
|
|
6165
|
+
<code>main</code>, and its own header states the rule: <i>"Any workflow that runs on main and nobody
|
|
6166
|
+
watches belongs here."</i> It watched <b>two</b>. <b>Twenty-four</b> ran unattended — fourteen on a
|
|
6167
|
+
cron. The rule was written down and not applied, which is the most expensive kind of convention,
|
|
6168
|
+
and it is the same blind spot that let <code>shards</code> fail both its scheduled runs and publish
|
|
6169
|
+
zero artifacts.
|
|
6170
|
+
|
|
6171
|
+
All twenty-six are watched now, and the list is <b>enforced rather than curated</b>:
|
|
6172
|
+
<code>tests/unit/test_failure_alerting_covers_unattended.py</code> fails the build when a workflow
|
|
6173
|
+
runs unattended and is neither watched nor listed in an <code>EXPECTED_UNWATCHED</code> map with a
|
|
6174
|
+
reason. A new scheduled workflow therefore cannot quietly join the blind spot — the same shape as
|
|
6175
|
+
the action-pin lockstep guard, where the convention stays falsifiable instead of decaying the moment
|
|
6176
|
+
the person who wrote it stops looking.</p></details>
|
|
6177
|
+
<div class="meta">
|
|
6178
|
+
<span class="m">Complexity <b>M</b></span>
|
|
6179
|
+
<span class="m hi">Impact <b>High</b></span>
|
|
6180
|
+
<span class="m">Wow <b class="wow">★★★★★</b></span>
|
|
6181
|
+
<span class="m">the fuzzer found a real crash and was right for three weeks — 24 unattended workflows, 2 watched</span>
|
|
6182
|
+
</div>
|
|
6183
|
+
</article>
|
|
6184
|
+
|
|
6115
6185
|
<article class="cap rcard" id="eval-stats-could-never-publish">
|
|
6116
6186
|
<div class="head"><span class="pill shipped">Shipped</span><span class="cat">Build · Bug</span></div>
|
|
6117
6187
|
<h3>The published metrics could never be published</h3>
|
|
@@ -6153,6 +6223,57 @@ verified: green on the fix, and red again when the bare push is restored.</p></d
|
|
|
6153
6223
|
<span class="m">the published-metrics file has ONE commit in its whole history — the one that created it</span>
|
|
6154
6224
|
</div>
|
|
6155
6225
|
</article>
|
|
6226
|
+
|
|
6227
|
+
<article class="cap rcard" id="zizmor-ignores-drift-and-make-lint-never-ran-it">
|
|
6228
|
+
<div class="head"><span class="pill shipped">Shipped</span><span class="cat">Build · Bug</span></div>
|
|
6229
|
+
<h3>A line-anchored suppression drifted, and make lint never ran the tool</h3>
|
|
6230
|
+
<details class="cardbody"><summary>Write-up</summary>
|
|
6231
|
+
<p><code>.github/zizmor.yml</code> silences accepted workflow-SAST findings by
|
|
6232
|
+
<b><code>file:LINE</code></b>. That anchor is fragile in a specific way: insert anything above the
|
|
6233
|
+
construct and the ignore stops applying — or, worse, starts applying to a <i>different</i> construct
|
|
6234
|
+
nobody reviewed.
|
|
6235
|
+
|
|
6236
|
+
It drifted here. Adding a header comment to <code>ci-failure-issue.yml</code> (explaining the
|
|
6237
|
+
alerting-coverage fix) moved its <code>on:</code> block from <b>line 12 to line 28</b>, and CI's
|
|
6238
|
+
<code>lint</code> job went red on <code>dangerous-triggers</code> — for a <code>workflow_run</code>
|
|
6239
|
+
trigger that had been reviewed and accepted months earlier, with the reasoning written out in the
|
|
6240
|
+
config right above the anchor.
|
|
6241
|
+
|
|
6242
|
+
<b>The config predicted it.</b> Its own note reads: <i>"these ignores are keyed by file:LINE, so
|
|
6243
|
+
editing anything above a workflow's <code>on:</code> block moves it and silently un-ignores the
|
|
6244
|
+
finding."</i> A warning in a comment is not a control — it depends on the next person reading the
|
|
6245
|
+
file they are not editing.
|
|
6246
|
+
|
|
6247
|
+
<b>The second half is why nothing local caught it.</b> <code>make lint</code> <b>never ran
|
|
6248
|
+
zizmor</b>. The recipe runs ruff, mypy, pyright, import-linter, vulture, xenon, interrogate, refurb,
|
|
6249
|
+
codespell and actionlint — and CI's <code>lint</code> job additionally runs zizmor, which the
|
|
6250
|
+
Makefile did not. So <code>make lint</code> could return <b>0</b> on a branch whose <code>lint</code>
|
|
6251
|
+
job was already red, which is exactly what happened: the gate was run, it passed, and it had not
|
|
6252
|
+
looked. (<code>CLAUDE.md</code> and an operator note both listed zizmor among the tools
|
|
6253
|
+
<code>make lint</code> runs. Neither was true.)
|
|
6254
|
+
|
|
6255
|
+
Both halves are closed. zizmor now runs in <code>make lint</code>, guarded the same way actionlint
|
|
6256
|
+
is — present, or an explicit "skipping (CI enforces it)" rather than silence — and
|
|
6257
|
+
<code>--offline</code>, because the impostor and ref audits need GitHub API access the dev sandbox's
|
|
6258
|
+
proxy flakes on.
|
|
6259
|
+
|
|
6260
|
+
And <code>tests/unit/test_zizmor_ignores_still_anchor.py</code> checks the cheap mechanical property
|
|
6261
|
+
the line numbers depend on: every <code>dangerous-triggers</code> anchor still lands on an
|
|
6262
|
+
<code>on:</code> line, no anchor points past the end of its file, no ignore names a workflow that no
|
|
6263
|
+
longer exists, and no anchor is duplicated. It does not re-run zizmor — CI owns that — it asserts
|
|
6264
|
+
that the anchors still mean what they say.
|
|
6265
|
+
|
|
6266
|
+
<b>Both fixes were verified by re-breaking the tree.</b> With the anchor put back to
|
|
6267
|
+
<code>:12</code>, the new test goes red naming the drift, and <code>make lint</code> exits
|
|
6268
|
+
<b>2</b> — the failure that previously only appeared in CI, now reproducible in one command before
|
|
6269
|
+
the push.</p></details>
|
|
6270
|
+
<div class="meta">
|
|
6271
|
+
<span class="m">Complexity <b>S</b></span>
|
|
6272
|
+
<span class="m">Impact <b>Med</b></span>
|
|
6273
|
+
<span class="m">Wow <b class="wow">★★★★</b></span>
|
|
6274
|
+
<span class="m">a comment four lines long un-silenced a reviewed finding, and no local gate could see it</span>
|
|
6275
|
+
</div>
|
|
6276
|
+
</article>
|
|
6156
6277
|
<!-- /ROADMAP:cards -->
|
|
6157
6278
|
|
|
6158
6279
|
</div>
|
|
@@ -176,7 +176,11 @@ ignore = [
|
|
|
176
176
|
# batch. Hoisting the handler out of the loop would trade that resilience
|
|
177
177
|
# for a negligible per-iteration saving.
|
|
178
178
|
"PERF203", # try-except-in-loop
|
|
179
|
-
# printf-formatting is this codebase's house style
|
|
179
|
+
# printf-formatting is this codebase's house style. Measured with
|
|
180
|
+
# `ruff check --select UP031 --statistics`: 1,005 call sites in boost_cli,
|
|
181
|
+
# 1,800 across the whole lint scope. (The figure here read "~860" for a
|
|
182
|
+
# long time — a rationale whose central number has drifted is a rationale
|
|
183
|
+
# nobody re-checked, so it is stated with the command that reproduces it.)
|
|
180
184
|
# The rewrite is an unsafe fix (`%` and `format` differ on tuples and on
|
|
181
185
|
# types with a custom `__format__`), it would rewrite nearly every file —
|
|
182
186
|
# obliterating blame and conflicting with every branch in flight — and it
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""Unit tests: every unattended workflow is watched by the failure alerting.
|
|
2
|
+
|
|
3
|
+
``ci-failure-issue.yml`` opens a tracking issue when a watched workflow fails on
|
|
4
|
+
``main``. Its own header states the rule::
|
|
5
|
+
|
|
6
|
+
Any workflow that runs on main and nobody watches belongs here.
|
|
7
|
+
|
|
8
|
+
It watched two: ``ci`` and ``demo``. Twenty-four run unattended — fourteen on a
|
|
9
|
+
cron, ten on a push to ``main`` — so the rule was written down and not applied,
|
|
10
|
+
which is the most expensive kind of convention.
|
|
11
|
+
|
|
12
|
+
Two outages measured this session are exactly what that gap costs:
|
|
13
|
+
|
|
14
|
+
* ``fuzz`` failed **three scheduled runs out of three** (2026-07-25, 08-01,
|
|
15
|
+
08-08), writing the same libFuzzer reproducer each time. It had found a real
|
|
16
|
+
defect in ``registry.parse_spec`` and been ignored for three weeks.
|
|
17
|
+
* ``shards`` failed **both** of its scheduled runs and published zero artifacts,
|
|
18
|
+
which is how a feature reached a state where it had never once worked.
|
|
19
|
+
|
|
20
|
+
Neither produced a notification, a red badge anyone looks at, or a comment on a
|
|
21
|
+
pull request. A cron job's failure is a red square on a page nobody opens.
|
|
22
|
+
|
|
23
|
+
The list is enforced rather than curated: a new scheduled workflow fails this
|
|
24
|
+
test until it is either watched or added to ``EXPECTED_UNWATCHED`` with a
|
|
25
|
+
reason. That is the same shape as ``test_action_pin_lockstep``'s parametrised
|
|
26
|
+
family check — the convention stays falsifiable instead of decaying the moment
|
|
27
|
+
the person who wrote it stops looking.
|
|
28
|
+
"""
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
import re
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
|
|
34
|
+
import pytest
|
|
35
|
+
|
|
36
|
+
WORKFLOWS = Path(__file__).resolve().parents[2] / ".github" / "workflows"
|
|
37
|
+
ALERT = WORKFLOWS / "ci-failure-issue.yml"
|
|
38
|
+
|
|
39
|
+
pytestmark = pytest.mark.skipif(
|
|
40
|
+
not ALERT.exists(),
|
|
41
|
+
reason=".github/workflows not reachable (e.g. mutation sandbox)")
|
|
42
|
+
|
|
43
|
+
#: Unattended workflows deliberately NOT watched, each with its reason.
|
|
44
|
+
#: Empty today. An entry here is a claim that a failure is expected noise
|
|
45
|
+
#: rather than news, and it should be rare enough to argue about.
|
|
46
|
+
EXPECTED_UNWATCHED: dict[str, str] = {}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def workflow_name(text: str, fallback: str) -> str:
|
|
50
|
+
"""The workflow's `name:`, which is what `workflow_run` matches on."""
|
|
51
|
+
m = re.search(r"^name:\s*(.+)$", text, re.M)
|
|
52
|
+
return m.group(1).strip().strip("\"'") if m else fallback
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def runs_unattended(text: str) -> bool:
|
|
56
|
+
"""True for a workflow that runs with nobody waiting on the result.
|
|
57
|
+
|
|
58
|
+
A cron run has no author watching by construction. A push to ``main`` runs
|
|
59
|
+
after the pull request's checks are already green and merged, so its failure
|
|
60
|
+
surfaces only on a commit list — which is how ``demo`` failed six runs out
|
|
61
|
+
of six before a manual audit found it.
|
|
62
|
+
"""
|
|
63
|
+
return bool(re.search(r"^\s*schedule:", text, re.M)
|
|
64
|
+
or re.search(r"^\s*push:", text, re.M))
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def watched() -> set[str]:
|
|
68
|
+
"""The workflow names ci-failure-issue.yml subscribes to."""
|
|
69
|
+
m = re.search(r"workflows:\s*\[([^\]]*)\]", ALERT.read_text(encoding="utf-8"))
|
|
70
|
+
assert m, "could not find the workflows: list in ci-failure-issue.yml"
|
|
71
|
+
return {w.strip().strip("\"'") for w in m.group(1).split(",") if w.strip()}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def unattended() -> dict[str, str]:
|
|
75
|
+
"""``{workflow name: file name}`` for every unattended workflow."""
|
|
76
|
+
out = {}
|
|
77
|
+
for path in sorted(WORKFLOWS.glob("*.yml")):
|
|
78
|
+
text = path.read_text(encoding="utf-8")
|
|
79
|
+
name = workflow_name(text, path.stem)
|
|
80
|
+
# The alerting workflow itself is triggered by workflow_run, never by a
|
|
81
|
+
# schedule or a push, and watching itself would be a loop.
|
|
82
|
+
if name == "ci-failure-alert":
|
|
83
|
+
continue
|
|
84
|
+
if runs_unattended(text):
|
|
85
|
+
out[name] = path.name
|
|
86
|
+
return out
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class TestTheGuardCanActuallySee:
|
|
90
|
+
"""Every assertion below is vacuous if the parsing silently breaks."""
|
|
91
|
+
|
|
92
|
+
def test_the_watch_list_is_found_and_non_empty(self):
|
|
93
|
+
assert watched(), "parsed an empty watch list"
|
|
94
|
+
|
|
95
|
+
def test_unattended_workflows_are_found(self):
|
|
96
|
+
assert len(unattended()) > 5, unattended()
|
|
97
|
+
|
|
98
|
+
def test_the_two_original_watchers_are_still_there(self):
|
|
99
|
+
# `demo` is in the list because it failed six of six runs unnoticed.
|
|
100
|
+
# Losing either entry would be a silent regression of that fix.
|
|
101
|
+
assert {"ci", "demo"} <= watched()
|
|
102
|
+
|
|
103
|
+
def test_a_known_cron_workflow_is_classified_as_unattended(self):
|
|
104
|
+
assert "fuzz" in unattended(), unattended()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class TestEveryUnattendedWorkflowIsWatched:
|
|
108
|
+
@pytest.mark.parametrize("name", sorted(unattended()))
|
|
109
|
+
def test_it_is_watched_or_documented(self, name):
|
|
110
|
+
if name in EXPECTED_UNWATCHED:
|
|
111
|
+
assert EXPECTED_UNWATCHED[name].strip(), \
|
|
112
|
+
"%s is excluded without a reason" % name
|
|
113
|
+
return
|
|
114
|
+
assert name in watched(), (
|
|
115
|
+
"%s (%s) runs unattended on main but nothing alerts when it fails "
|
|
116
|
+
"— fuzz was red for three scheduled runs and shards for two, both "
|
|
117
|
+
"unnoticed. Add it to ci-failure-issue.yml's `workflows:` list, or "
|
|
118
|
+
"to EXPECTED_UNWATCHED with a reason."
|
|
119
|
+
% (name, unattended()[name]))
|
|
120
|
+
|
|
121
|
+
def test_the_exclusion_list_has_no_stale_entries(self):
|
|
122
|
+
# An entry for a workflow that no longer runs unattended is a licence
|
|
123
|
+
# nobody re-examined.
|
|
124
|
+
stale = sorted(set(EXPECTED_UNWATCHED) - set(unattended()))
|
|
125
|
+
assert not stale, stale
|
|
126
|
+
|
|
127
|
+
def test_nothing_watched_has_disappeared(self):
|
|
128
|
+
# A watch entry naming a workflow that no longer exists silently
|
|
129
|
+
# watches nothing, and reads as coverage.
|
|
130
|
+
names = {workflow_name(p.read_text(encoding="utf-8"), p.stem)
|
|
131
|
+
for p in WORKFLOWS.glob("*.yml")}
|
|
132
|
+
assert watched() <= names, sorted(watched() - names)
|