boost-skill-cli 1.2.79__tar.gz → 1.2.80__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.2.79 → boost_skill_cli-1.2.80}/.vale/styles/config/vocabularies/boost/accept.txt +1 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/CLAUDE.md +20 -0
- {boost_skill_cli-1.2.79/boost_skill_cli.egg-info → boost_skill_cli-1.2.80}/PKG-INFO +1 -1
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/configuration.py +48 -8
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/config.py +37 -6
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/policy.py +66 -6
- boost_skill_cli-1.2.80/boost_cli/core/typedvalue.py +217 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80/boost_skill_cli.egg-info}/PKG-INFO +1 -1
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_skill_cli.egg-info/SOURCES.txt +2 -0
- boost_skill_cli-1.2.80/docs/demo.gif +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-config-policy-set-store-type-unchecked-values-consumers-cras.md +5 -3
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap.html +5 -2
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_configuration.py +127 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_config.py +94 -1
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_policy.py +116 -1
- boost_skill_cli-1.2.80/tests/unit/test_typedvalue.py +249 -0
- boost_skill_cli-1.2.79/docs/demo.gif +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/.gitattributes +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/.gitignore +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/.gitleaks.toml +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/.htmlvalidate.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/.lighthouserc.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/.lycheeignore +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/.markdownlint-cli2.jsonc +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/.pre-commit-config.yaml +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/.stylelintrc.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/.vale/styles/boost/AIWriting.yml +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/.vale/styles/boost/Terminology.yml +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/.vale.ini +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/CODE_OF_CONDUCT.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/DCO +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/GOVERNANCE.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/LICENSE +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/MAINTAINERS.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/MANIFEST.in +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/Makefile +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/README.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/SECURITY.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/SUPPORT.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/_common.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/discovery.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/info.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/intelligence.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/pkg.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/quality.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/quickstart.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/run.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/safety.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/taps.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/commands/team.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/adapters.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/ai.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/aihost.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/bmad.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/bootstrap.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/browse.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/builtin.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/capabilities.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/catalog.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/catalogbundle.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/chat.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/claude_settings.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/complete.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/dense.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/ed25519.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/embed.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/faithfulness.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/hookhost.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/imperative.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/injectscan.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/installscan.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/integrity.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/journal.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/localembed.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/lockfile.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/logs.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/mcp.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/mcpdecl.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/mcphost.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/minisign.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/nethttp.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/output.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/projectlock.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/provenance.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/rag.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/registry.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/resolve.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/rules.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/scopes.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/secretscan.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/selfupdate.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/serve.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/shards.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/stackprobe.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/staleness.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/store.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/trustaudit.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/typosquat.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/updatediff.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/util.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/core/workflows.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/data/rules/boost-first.mdc +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_langchain/__init__.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_langchain/_compat.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_langchain/graph.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_langchain/loader.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_langchain/py.typed +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_langchain/retriever.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/codecov.yml +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/adapters.html +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/architecture/README.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/architecture/c4-components-core.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/architecture/c4-containers.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/architecture/c4-context.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/architecture/c4-dynamic-install.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/bmad.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/gifs/distill.gif +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/gifs/doctor.gif +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/gifs/explain.gif +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/gifs/hooks.gif +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/gifs/install.gif +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/gifs/pulse.gif +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/gifs/search.gif +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/gifs/tap.gif +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/tapes/distill.tape +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/tapes/doctor.tape +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/tapes/explain.tape +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/tapes/hooks.tape +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/tapes/install.tape +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/tapes/pulse.tape +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/tapes/search.tape +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel/tapes/tap.tape +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/carousel.html +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/chat.html +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/code-review.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/commands.html +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/commit-audit.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/demo-index.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/demo.html +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/demo.tape +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/dependencies.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/eval-latest.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/eval.html +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/index.html +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/langchain.html +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/mcp-hub.html +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/openssf-badge.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/openssf-playbook.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D01.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D02.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D03.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D04.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D05.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D06.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D07.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D08.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D09.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D10.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D11.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D12.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D13.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D14.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D15.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D16.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D17.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D18.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D19.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D20.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D21.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D22.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D23.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D24.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D25.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D26.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/BOOST-D27.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/a11y-sweep-flakes-on-color-contrast.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/agents-field-records-the-request-not-the-links.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/ai-backend-fanout.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-absorb-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-adapt-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-adapt-renders-every-sibling-of-a-flat-agents-dir-workflow-as.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-adapt-run-stats-edit-tag-export-reject-the-tap-name-qualifie.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-ai-degrade-note-blames-path-api-keys-regardless-of-cause-sev.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-attest-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-audit-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-bmad-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-browse-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-bundle-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-catalog-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-catalog-resolve-one-s-duplicate-name-hint-advertises-path-to.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-changelog-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-chat-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-clean-counts-failed-removals-as-cleaned-journals-the-inflate.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-cli-py-commands-summaries-and-parser-help-contradict-behavio.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-cohort-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-completions-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-config-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-context-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-corrupt-settings-config-state-json-silently-read-as-empty-th.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-create-distill-infer-absorb-install-silently-replace-an-inst.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-create-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-declined-confirms-never-name-y-boost-assume-yes-snapshot-cle.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-deps-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-discover-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-distill-s-heuristic-merge-drops-repeated-fences-braces-writi.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-doctor-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-drift-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-dry-runs-disagree-with-the-real-run-compact-counts-bytes-it.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-edit-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-evolve-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-explain-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-export-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-export-o-cohort-create-and-profile-save-silently-overwrite-e.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-fingerprint-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-five-exit-70-crashes-on-bad-paths-data-catalog-export-serve.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-focus-profile-sideline-by-unlinking-without-recording-it-lis.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-git-operations-never-set-git-terminal-prompt-0-so-a-404-priv.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-health-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-hooks-remove-n-cannot-find-hooks-boost-itself-added-unknown.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-import-all-skips-the-injection-secret-scans-and-the-per-skil.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-import-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-index-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-info-stats-explain-render-a-different-smaller-shape-for-rule.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-install-dry-run-promises-agents-the-real-install-never-write.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-install-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-install-local-writes-empties-the-repo-s-mcp-json-silently-of.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-json-accepted-but-ignored-on-many-branches-cohort-config-pol.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-lint-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-log-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-log-simulate-changelog-headings-echo-the-raw-qualified-argum.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-mcp-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-mcp-register-s-boost-first-consent-names-only-the-registered.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-missing-json-on-doctor-test-health-changelog-trending-log-ho.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-name-miss-errors-unknown-tap-qualifier-unnamed-no-close-matc.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-onboard-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-out-table-clips-data-columns-to-an-assumed-80-columns-when-s.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-out-warn-defaults-to-stdout-infer-absorb-corrupt-skill-md-se.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-outdated-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-output-wrap-tokens-splits-punctuation-off-backtick-spans-ins.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-pinned-taps-silently-moved-to-head-by-update-re-clone-and-co.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-policy-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-preview-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-profile-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-project-scope-seams-uninstall-verify-list-info-reinstall-dis.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-protocol-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-pulse-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-quarantine-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-quarantine-pin-state-invisible-list-info-doctor-report-links.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-quickstart-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-recommend-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-reindex-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-reinstall-sync-repair-and-audit-resolve-by-name-tap-ignoring.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-replay-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-root-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-rules-workflows-reported-as-skills-uninstall-claims-a-store.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-run-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-schedule-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-search-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-simulate-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-singular-plural-misses-1-skills-1-issue-need-1-skill-pass-ac.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-six-count-flags-tap-chat-absorb-lint-changelog-hooks-skip-ut.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-skill-profile-name-slugging-is-inconsistent-distill-o-accept.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-snapshot-restore-replaces-the-lock-wholesale-orphaning-newer.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-stale-prose-after-shipped-changes-catalog-export-live-discov.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-stray-positionals-and-inapplicable-flags-silently-ignored-ac.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-sweep-positionals-json-lack-help-strings-and-no-command-help.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-sync-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-tag-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-tap-dry-run-is-silently-ignored-outside-catalog-spec-and-def.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-tap-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-taps-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-taps-outdated-decay-policy-snapshot-json-emit-display-string.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-test-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-trust-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-trust-verify-labels-a-manifest-tampered-after-signing-by-a-t.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-unpin-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-untap-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-update-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-verify-drift-say-nothing-installed-exit-0-and-doctor-says-lo.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-verify-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/audit-who-findings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/bm25-has-no-stemming.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/bm25-index-is-one-json-blob.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/bmad-autopilot-one-command-persona-routing.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/bmad-hooks-all-hosts.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/boost-first-carried-the-losing-trigger.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/boost-first-rule.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/boost-langchain-publishing.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/boost-run-live-agents.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/branch-current-gate.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/browse-could-not-search-two-words.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/capability-policy-skips-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/catalog-categories-beyond-curated.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/catalogue-entries-carry-no-content-identity.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/chat-cites-sources-by-a-number-it-never-prints.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/chat-command-grounded-conversational-search.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/cli-audit-2026-08-full-sweep.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/cli-command-audit.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/cli-output-ignored-the-terminal.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/cold-search-reads-the-whole-catalogue.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/command-carousel-page.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/command-reference-docs-site.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/completions-complete-only-command-names.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/completions-install-could-eat-your-rc-file.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/crash-reports-leak-api-keys.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/delay-true-defeats-the-log-suppress.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/demo-workflow-cancels-other-prs.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/dense-reindex-has-no-progress-or-durability.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/dense-reindex-reuses-whole-taps.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/dense-search-rescans-every-vector.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/dense-store-holds-every-vector-once-per-copy.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/dependabot-splits-multi-path-action-repos.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/discover-searches-github-not-a-stale-sample.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/dry-run-promised-a-link-nobody-makes.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/efficiency-registries-ponytail-caveman.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/est-items-counts-agent-mirrors-as-items.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/eval-corpus-cannot-see-real-retrieval.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/eval-corpus-is-96x-smaller-than-a-real-install.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/eval-corpus-is-one-strangers-repo.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/eval-corpus-pins-have-no-refresh-path.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/eval-corpus-was-not-actually-pinned.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/eval-deduped-ranked-lists-by-name.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/eval-stats-could-never-publish.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/expanded-card-bodies-overflow.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/gemini-agent-frontmatter-sanitizer.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/gemini-duplicate-skill-discovery.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/gemini-hooks-host-aware.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/gemini-mcp-parity.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/github-community-health-files.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/golden-set-grades-by-name-not-by-skill.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/gstack-tap-first-then-coexistence.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/heal-deleted-links-it-never-made.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/html-validation-html-validate.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/info-rejects-the-qualified-name-it-recommends.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/install-path-disambiguation.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/keyless-dense-tier-local-static-embeddings.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/keyless-semantic-search-for-everyone.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/langchain-in-the-wheel.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/langchain-integration-explainer-page.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/langchain-langgraph-langsmith-integration.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/langchain-retriever-metadata-and-k-floor.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/license-compliance-scanning.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/lighthouse-scored-a-page-nobody-is-served.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/long-hints-overflow-narrow-panes.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/marketing-crm-domain-had-no-category.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-already-covered-defeater.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-aware-skills.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-cannot-read-a-skill-before-installing.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-one-benefit-nameable-task.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-search-cost-was-understated.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-search-hid-which-ranking-ran.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mcp-zero-setup-and-three-kinds.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mutation-shards-rerun-full-set-every-push.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/near-duplicate-items-eat-the-result-slots.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/near-identical-copies-still-eat-the-slots.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/one-dead-tap-broke-every-update.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/openssf-best-practices-badge.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/openssf-gold-ceiling.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/openssf-playbook.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/openssf-silver.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/osps-baseline-levels.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/pathlib-exists-is-not-total.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/pep585-604-modernization-sweep.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/prerequisites-and-semantic-search-setup.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/publish-the-keyword-index.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/published-shards-have-no-consumer.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/python-floor-moves-to-312.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/ragas-unpin-when-upstream-ships.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/readme-prune-and-search-guide.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/relicence-apache-2.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/reproducible-release-artifacts.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/required-checks-config-drift.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/resolve-vendored-duplicate-copies.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/roadmap-page-weight-grows-without-bound.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/roadmap-perf-budget-has-no-local-guard.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/rules-install-but-cannot-be-governed.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/scripts-under-the-lint-gate.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/search-and-browse-visual-refresh.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/search-never-notices-a-new-tap.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/self-update-claims-up-to-date-without-asking.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/serve-404-reflected-the-request.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/serve-is-a-searchable-catalogue.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/shard-refresh-skips-processed-commits.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/shard-runs-reembed-everything-weekly.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/shards-pipeline-never-produced-a-shard.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/shareable-catalogue-bundle.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/shrink-the-published-index.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/smart-rerank-pays-per-novel-query.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/sweep-died-at-launch-not-at-a-page.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/sync-could-not-repair-a-gutted-skill.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/sync-reported-success-for-a-link-it-refused.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/taps-check-out-freight-they-never-index.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/the-catalogue-advertised-repos-that-no-longer-exist.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/the-scale-corpus-refreshed-the-wrong-rows.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/the-shard-job-that-could-not-finish.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/tool-call-eval-tier.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/two-ci-controls-that-could-not-act.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/two-crashes-that-should-have-been-messages.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/typo-detection-codespell.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/unwatched-crons-hid-a-real-fuzz-crash.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/update-advertises-a-flag-it-rejects.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/update-diff-before-apply.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/update-refreshed-rules-without-a-gate.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/vex-openvex-feed.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/weekly-vectors-had-no-ingestion-path.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/workspace-scope-install.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/zip-strict-audit.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/zizmor-ignores-drift-and-make-lint-never-ran-it.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/security-design.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/semantic-search.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/superpowers/specs/2026-08-16-catalogue-content-identity-design.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/verifying-releases.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/vex/meta.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/vex/openvex.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/vex/statements/gitleaks-secretscan-test-fixtures.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/vex/statements/quality-trust-fingerprint-not-sensitive.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/vex/statements/zizmor-adhoc-packages-lint-runners.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/docs/vex/statements/zizmor-dangerous-triggers-workflow-run.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/eslint.config.mjs +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/evals/README.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/evals/__init__.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/evals/baseline.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/evals/faithfulness.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/evals/golden_set.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/evals/make_corpus.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/evals/make_golden.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/evals/metrics.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/evals/publish_golden_dataset.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/evals/run_evals.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/examples/README.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/examples/adapt-demo.sh +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/examples/boost-run-prototype.sh +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/index.html +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/noxfile.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/pyproject.toml +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/requirements/coverage-tools.in +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/requirements/coverage-tools.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/requirements/lint-tools.in +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/requirements/lint-tools.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/requirements/mutation-tools.in +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/requirements/mutation-tools.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/requirements/platform-pins.lock +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/requirements/release-tools.in +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/requirements/release-tools.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/requirements/test-tools.in +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/requirements/test-tools.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/a11y_check.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/add_spdx_headers.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/bench_cli.sh +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/build_command_reference.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/build_demo_index.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/build_roadmap.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/build_scale_corpus.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/build_vex.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/check_anchors.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/check_branch_current.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/check_dco.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/check_licenses.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/check_reproducible.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/check_required_checks.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/ensure_eval_corpus.sh +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/eval_corpus.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/eval_explain.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/eval_gate.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/eval_recommend.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/eval_retrieval.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/eval_stats_summary.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/eval_tools.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/import_budget.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/lock_toolchain.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/measure_near_duplicate_bound.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/measure_registry.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/mutation_shards.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/mutation_weights.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/normalize_sdist.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/page_budget.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/perf_gate.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/post_deploy_smoke.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/publish_eval_json.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/publish_shards.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/release_guard.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/release_preflight.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/serve_docs.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/scripts/shard_plan.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/setup.cfg +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/sonar-project.properties +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/style/README.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/style/boost.css +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/style/boost.js +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/style/demo.html +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/adapt.feature +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/browse.feature +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/count.feature +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/discover.feature +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/doctor.feature +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/environment.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/explain.feature +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/index.feature +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/install.feature +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/list.feature +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/mcp.feature +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/search.feature +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/steps/cli_steps.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/steps/discovery_steps.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/steps/mcp_steps.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/bdd/features/steps/quality_steps.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/conftest.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/eval/baseline.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/eval/explain.jsonl +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/eval/fixtures/claude_init_event.jsonl +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/eval/golden-natural.jsonl +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/eval/golden.jsonl +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/eval/recommend.jsonl +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/eval/taps-scale.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/eval/taps.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/eval/tool_calls.jsonl +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_bmad_all_hosts.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_capabilities_policy.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_adapt.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_catalog.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_chat.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_discovery.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_hooks_gemini.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_info.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_pane_width.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_pkg.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_quality.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_quickstart.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_tap_pins.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_integrity_enforce.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_kind_conformance.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_property_parsers.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_run.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_tap_signing.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/functional/test_workspace_scope.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/README.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/registry/02-https.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/registry/06-space.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/registry/09-nul.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/registry/10-name-too-long.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/corpus/registry/11-long-owner-repo.txt +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/fuzz_frontmatter.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/fuzz/fuzz_registry.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/langchain/conftest.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/langchain/test_graph.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/langchain/test_loader.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/langchain/test_retriever.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/perf/test_benchmarks.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_a11y_check.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_action_pin_lockstep.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_adapters.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_adapters_multi.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_adapters_runner.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_aihost.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_bmad_core.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_boost_first_offer.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_bootstrap.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_bot_pr_dco.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_branch_current.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_browse.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_builtin.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_capabilities.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_catalogbundle.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_chat.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_check_anchors.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_check_dco.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_check_licenses.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_check_reproducible.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_clean_internal_cache.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_cli_update_shards.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_codeql_analysis_key.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_command_reference_fresh.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_community_health_files.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_compact.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_complete.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_complete_rc_block.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_content_dedupe.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_content_identity.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_crash_redaction.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dedup_trust.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_demo_index.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_boilerplate_cluster.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_embed_dedupe.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_entry_reuse.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_entry_vectors.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_fallback.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_fix_hint.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_progress.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_quantized.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_ready_order.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_shard_real_schema.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_shard_unreadable_vectors.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_shards.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_status.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_status_cheap.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dense_vector_dedupe.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_dependabot_config.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_distill_merge.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_docs_pages_linked.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_docsite_chrome.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_doctor_output_polish.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_ed25519.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_embed_local.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_embed_truncated_response.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_entry_key.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_eval_baseline.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_eval_corpus.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_eval_faithfulness.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_eval_gate.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_eval_grading.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_eval_metrics.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_eval_stats_summary.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_eval_tools.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_eval_tools_probe.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_failure_alerting_covers_unattended.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_faithfulness.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_fuzz_targets.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_gemini_agent_sanitize.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_gitleaks_config.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_gitutil_lfs.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_gitutil_sparse.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_gstack_coexistence.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_hook_settings_hosts.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_hookhost.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_imperative.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_import_budget.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_injectscan.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_install_permission_error.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_installscan.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_integrity.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_langchain_packaging.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_link_ownership.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_localembed.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_localembed_e2e.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_marketing_counts.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_mcp.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_mcp_install_scan.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_mcp_read.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_mcpdecl.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_mcphost.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_measure_registry.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_minisign.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_mutation_shards.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_mutation_subfile_shards.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_mutmut_source_paths.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_near_duplicate_collapse.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_nethttp.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_normalize_sdist.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_page_budget.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_perf_gate.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_pkg_confusions.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_pkg_injection.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_pkg_secrets.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_platform_pins.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_post_deploy_smoke.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_project_mcp_sidecar.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_projectlock.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_provenance.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_publish_golden_dataset.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_rag_fastpath.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_rag_fusion.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_registries_fresh.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_registry_categories.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_registry_control_chars.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_registry_parallel.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_release_guard.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_release_preflight.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_required_checks.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_rerank_cache.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_resolve.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_retrieve_any_near_duplicates.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_roadmap_fresh.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_rules.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_scale_corpus.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_scopes.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_secretscan.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_selfupdate.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_serve.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_serve_docs.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_shard_plan.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_shards.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_shards_incremental.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_shards_ingest.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_shards_matrix.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_smoke_covers_every_command.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_spdx_headers.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_stackprobe.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_staleness.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_store.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_store_materialize.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_sync_blocked_links.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_sync_repairs_gutted_skill.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_tap_pins.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_toolchain_lock.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_trustaudit.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_typosquat.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_updatediff.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_util.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_version.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_version_tags.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_vex.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_visual_harness_flags.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_workflow_concurrency.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_workflow_concurrency_groups.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_workflow_push_has_credentials.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_workflow_timeouts.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_workflows.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/unit/test_zizmor_ignores_still_anchor.py +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/visual/a11y_check.mjs +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/visual/console_check.mjs +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/visual/package-lock.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/visual/package.json +0 -0
- {boost_skill_cli-1.2.79 → boost_skill_cli-1.2.80}/tests/visual/visual_check.mjs +0 -0
|
@@ -251,6 +251,26 @@ line coverage. Target `boost_cli/core` behavior with assertions, not just import
|
|
|
251
251
|
a workflow is rendered per agent (TOML for Gemini, see
|
|
252
252
|
`workflows.TOML_COMMAND_AGENTS`). Installing a rule therefore edits a file the
|
|
253
253
|
user reads every session — treat it as more invasive than a skill, not less.
|
|
254
|
+
- **A settable value is read at the type its `DEFAULTS` entry already declares.**
|
|
255
|
+
`core/typedvalue.py` turns `config.DEFAULTS` / `policy.DEFAULTS` into a
|
|
256
|
+
parser (`config.spec_for`, `policy.spec_for`), so a new key needs no
|
|
257
|
+
validation code — only a default of the right type. Four rules, each a bug
|
|
258
|
+
that shipped: **`bool` is tested before `int`**, because in Python a `bool`
|
|
259
|
+
*is* an `int` and the natural order types every `bool` key as a number;
|
|
260
|
+
**a list key never raises**, because its documented surface is a comma list,
|
|
261
|
+
which is what turns `policy set blocked_skills 42` from a stored `42` (and
|
|
262
|
+
`TypeError: argument of type 'int' is not iterable` out of the next install)
|
|
263
|
+
into `["42"]`; **a key `DEFAULTS` has never heard of keeps the old lenient
|
|
264
|
+
parse**, because `boost config set` accepts keys integrations invent; and
|
|
265
|
+
**`policy.load()` coerces and reports, it never raises** — a hand-edited
|
|
266
|
+
value it cannot read falls back to the default and is named by
|
|
267
|
+
`policy.invalid_values()` in `policy list`/`check`,
|
|
268
|
+
because a traceback from inside an install is not a remedy and a silent
|
|
269
|
+
substitution is not honest. The failure this closes was not the crash but the
|
|
270
|
+
inversion: `policy set pin_only no` stored the *string* `"no"`, which is
|
|
271
|
+
truthy, so boost reported "pin-only mode is on" and froze every install for a
|
|
272
|
+
user who had just turned it off.
|
|
273
|
+
|
|
254
274
|
- **A long line is either chrome or data, and only chrome may be wrapped.**
|
|
255
275
|
`out.wrap()` folds prose to the pane, and the emitters take it opt-in —
|
|
256
276
|
`warn`/`info`/`dim`/`kv` accept `wrap=True` and each pays for its own prefix,
|
|
@@ -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.2.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 2,
|
|
21
|
+
__version__ = version = '1.2.80'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 2, 80)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -41,6 +41,7 @@ from ..core import (
|
|
|
41
41
|
selfupdate,
|
|
42
42
|
serve,
|
|
43
43
|
store,
|
|
44
|
+
typedvalue,
|
|
44
45
|
util,
|
|
45
46
|
)
|
|
46
47
|
from ..core import output as out
|
|
@@ -50,6 +51,17 @@ from ._common import _s
|
|
|
50
51
|
_tilde = paths.tilde
|
|
51
52
|
|
|
52
53
|
|
|
54
|
+
def _bad_value(e: typedvalue.ValueTypeError, retry: str) -> BoostError:
|
|
55
|
+
"""Frame a type mismatch as a user-facing error naming the expected type.
|
|
56
|
+
|
|
57
|
+
The whole point of the typed setters is that the user hears about a bad
|
|
58
|
+
value here, holding the keyboard, instead of as `exit 70` plus a crash
|
|
59
|
+
report out of the next `install`.
|
|
60
|
+
"""
|
|
61
|
+
return BoostError("%s expects %s" % (e.key, e.expected),
|
|
62
|
+
hint="got %s — try `%s`" % (json.dumps(e.raw), retry))
|
|
63
|
+
|
|
64
|
+
|
|
53
65
|
# ---------------------------------------------------------------- config
|
|
54
66
|
|
|
55
67
|
def cmd_config(argv) -> int:
|
|
@@ -100,6 +112,9 @@ def cmd_config(argv) -> int:
|
|
|
100
112
|
if args.action == "set":
|
|
101
113
|
try:
|
|
102
114
|
config.set_value(args.key, args.value)
|
|
115
|
+
except typedvalue.ValueTypeError as e:
|
|
116
|
+
raise _bad_value(e, "boost config set %s <%s>"
|
|
117
|
+
% (args.key, config.spec_for(args.key))) from e
|
|
103
118
|
except TypeError as e:
|
|
104
119
|
raise BoostError(str(e),
|
|
105
120
|
hint="the parent key holds a plain value — "
|
|
@@ -391,13 +406,30 @@ def cmd_create(argv) -> int:
|
|
|
391
406
|
# ---------------------------------------------------------------- policy
|
|
392
407
|
|
|
393
408
|
def _parse_policy_value(key: str, raw: str):
|
|
409
|
+
"""Read `raw` at the key's declared type, or raise a framed BoostError.
|
|
410
|
+
|
|
411
|
+
Thin glue over `core.policy.parse_value` — the parsing itself lives in
|
|
412
|
+
core, where the mutation gate can reach it.
|
|
413
|
+
"""
|
|
394
414
|
try:
|
|
395
|
-
return
|
|
396
|
-
except
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
415
|
+
return policy.parse_value(key, raw)
|
|
416
|
+
except typedvalue.ValueTypeError as e:
|
|
417
|
+
raise _bad_value(e, "boost policy set %s <%s>"
|
|
418
|
+
% (key, policy.spec_for(key))) from e
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
def _warn_invalid_policy_values() -> None:
|
|
422
|
+
"""Name every stored policy value boost had to ignore, and why.
|
|
423
|
+
|
|
424
|
+
`policy.load()` substitutes the default for a value it cannot read at the
|
|
425
|
+
key's type, which is the right thing to do in the middle of an install and
|
|
426
|
+
the wrong thing to do silently. This is where it stops being silent.
|
|
427
|
+
"""
|
|
428
|
+
for key, value, expected in policy.invalid_values():
|
|
429
|
+
out.warn("ignoring %s = %s in policy.json — expects %s"
|
|
430
|
+
% (key, json.dumps(value), expected))
|
|
431
|
+
out.dim(" using the default; fix it with `boost policy set %s <%s>`"
|
|
432
|
+
% (key, policy.spec_for(key)))
|
|
401
433
|
|
|
402
434
|
|
|
403
435
|
def cmd_policy(argv) -> int:
|
|
@@ -426,6 +458,7 @@ def cmd_policy(argv) -> int:
|
|
|
426
458
|
pol = policy.load()
|
|
427
459
|
print(json.dumps(pol, indent=2))
|
|
428
460
|
if not args.json:
|
|
461
|
+
_warn_invalid_policy_values()
|
|
429
462
|
diff = sorted(k for k in policy.DEFAULTS
|
|
430
463
|
if pol.get(k) != policy.DEFAULTS[k])
|
|
431
464
|
out.dim(" modified from defaults: %s" % ", ".join(diff)
|
|
@@ -501,6 +534,7 @@ def cmd_policy(argv) -> int:
|
|
|
501
534
|
}, indent=2))
|
|
502
535
|
return 1 if violations else 0
|
|
503
536
|
|
|
537
|
+
_warn_invalid_policy_values()
|
|
504
538
|
if pol["pin_only"]:
|
|
505
539
|
out.info("pin-only mode is on — installs/updates are frozen"
|
|
506
540
|
+ (" (%d unpinned item(s): %s)"
|
|
@@ -1012,11 +1046,17 @@ def cmd_schedule(argv) -> int:
|
|
|
1012
1046
|
|
|
1013
1047
|
def cmd_serve(argv) -> int:
|
|
1014
1048
|
"""boost serve [--port N] [--host H] — thin wrapper over core.serve."""
|
|
1049
|
+
# The default is read BEFORE argparse runs, so a hand-edited
|
|
1050
|
+
# `serve.port: "abc"` used to crash even `boost serve --help` with a bare
|
|
1051
|
+
# ValueError and exit 70. Framed, it is one line naming the key.
|
|
1052
|
+
try:
|
|
1053
|
+
default_port = config.get_int("serve.port", 8787) or 8787
|
|
1054
|
+
except typedvalue.ValueTypeError as e:
|
|
1055
|
+
raise _bad_value(e, "boost config set serve.port <int>") from e
|
|
1015
1056
|
p = cliparse.parser(
|
|
1016
1057
|
prog="boost serve",
|
|
1017
1058
|
description="Browse the catalogue in a browser: search, facets and a tap graph")
|
|
1018
|
-
p.add_argument("--port", type=int,
|
|
1019
|
-
default=int(config.get("serve.port", 8787) or 8787),
|
|
1059
|
+
p.add_argument("--port", type=int, default=default_port,
|
|
1020
1060
|
help="port to listen on (default: config serve.port)")
|
|
1021
1061
|
p.add_argument("--host", default="127.0.0.1",
|
|
1022
1062
|
help="address to bind (default: 127.0.0.1)")
|
|
@@ -7,7 +7,7 @@ import json
|
|
|
7
7
|
from copy import deepcopy
|
|
8
8
|
from typing import Any
|
|
9
9
|
|
|
10
|
-
from . import paths, util
|
|
10
|
+
from . import paths, typedvalue, util
|
|
11
11
|
|
|
12
12
|
DEFAULTS = {
|
|
13
13
|
"agents": {
|
|
@@ -269,12 +269,43 @@ def get(dotted: str, default=None):
|
|
|
269
269
|
return deepcopy(node)
|
|
270
270
|
|
|
271
271
|
|
|
272
|
+
def spec_for(dotted: str) -> str:
|
|
273
|
+
"""The value type of a dotted key, derived from :data:`DEFAULTS`.
|
|
274
|
+
|
|
275
|
+
A key DEFAULTS does not describe types as :data:`typedvalue.ANY`: `boost
|
|
276
|
+
config set` accepts keys boost has never heard of (integrations write their
|
|
277
|
+
own), and inventing a type for those would refuse values that work today.
|
|
278
|
+
"""
|
|
279
|
+
node: Any = DEFAULTS
|
|
280
|
+
for part in dotted.split("."):
|
|
281
|
+
if not isinstance(node, dict) or part not in node:
|
|
282
|
+
return typedvalue.ANY
|
|
283
|
+
node = node[part]
|
|
284
|
+
return typedvalue.spec_for(node)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def get_int(dotted: str, default: int) -> int:
|
|
288
|
+
"""Read a config key as an int, or raise :class:`typedvalue.ValueTypeError`.
|
|
289
|
+
|
|
290
|
+
The consumers of a numeric setting used to call `int()` on whatever was
|
|
291
|
+
stored, so a hand-edited `serve.port: "abc"` crashed `boost serve --help`
|
|
292
|
+
with a traceback and exit 70 — before argparse had even run. Callers catch
|
|
293
|
+
this and frame it instead.
|
|
294
|
+
"""
|
|
295
|
+
value = get(dotted, default)
|
|
296
|
+
if value is None:
|
|
297
|
+
return default
|
|
298
|
+
return typedvalue.adapt(dotted, value, typedvalue.INT)
|
|
299
|
+
|
|
300
|
+
|
|
272
301
|
def set_value(dotted: str, raw: str) -> None:
|
|
273
|
-
"""Set a dotted key
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
302
|
+
"""Set a dotted key, reading the value at the type :data:`DEFAULTS` declares.
|
|
303
|
+
|
|
304
|
+
Raises :class:`typedvalue.ValueTypeError` when the text cannot be read at
|
|
305
|
+
that type. Keys with no default keep the old lenient behaviour: JSON when
|
|
306
|
+
it parses, the string otherwise.
|
|
307
|
+
"""
|
|
308
|
+
value = typedvalue.coerce(dotted, raw, spec_for(dotted))
|
|
278
309
|
cfg = load()
|
|
279
310
|
node: Any = cfg
|
|
280
311
|
parts = dotted.split(".")
|
|
@@ -10,7 +10,7 @@ from __future__ import annotations
|
|
|
10
10
|
import contextlib
|
|
11
11
|
import json
|
|
12
12
|
|
|
13
|
-
from . import config, paths
|
|
13
|
+
from . import config, paths, typedvalue
|
|
14
14
|
|
|
15
15
|
DEFAULTS = {
|
|
16
16
|
"blocked_skills": [], # names never allowed
|
|
@@ -31,20 +31,80 @@ DEFAULTS = {
|
|
|
31
31
|
"require_signed_taps": False,
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
# Per-key value types, derived from DEFAULTS so the two can never disagree.
|
|
35
|
+
# `max_skills` is the one key whose default (None) names no type, so it says
|
|
36
|
+
# so explicitly: a cap is a number, and "no cap" is null.
|
|
37
|
+
VALUE_TYPES: dict[str, str] = {k: typedvalue.spec_for(v) for k, v in DEFAULTS.items()}
|
|
38
|
+
VALUE_TYPES["max_skills"] = typedvalue.INT_OR_NONE
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def spec_for(key: str) -> str:
|
|
42
|
+
"""The value type of a policy key; :data:`typedvalue.ANY` if unknown."""
|
|
43
|
+
return VALUE_TYPES.get(key, typedvalue.ANY)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def parse_value(key: str, raw: str):
|
|
47
|
+
"""Read a typed value for `key` out of the string a user typed.
|
|
48
|
+
|
|
49
|
+
Raises :class:`typedvalue.ValueTypeError` when the text cannot be read at
|
|
50
|
+
the key's type — at the setter, where the user can still fix it, rather
|
|
51
|
+
than as a traceback out of the middle of the next install.
|
|
52
|
+
"""
|
|
53
|
+
return typedvalue.coerce(key, raw, spec_for(key))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _read_file() -> dict:
|
|
57
|
+
"""The raw contents of policy.json; ``{}`` when missing or unparseable."""
|
|
58
|
+
p = paths.policy_path()
|
|
59
|
+
if not p.exists():
|
|
60
|
+
return {}
|
|
61
|
+
with contextlib.suppress(json.JSONDecodeError, OSError):
|
|
62
|
+
data = json.loads(p.read_text(encoding="utf-8"))
|
|
63
|
+
if isinstance(data, dict):
|
|
64
|
+
return data
|
|
65
|
+
return {}
|
|
66
|
+
|
|
34
67
|
|
|
35
68
|
def load() -> dict:
|
|
36
69
|
"""Return the effective policy: DEFAULTS overlaid with policy.json.
|
|
37
70
|
|
|
38
|
-
A missing or unparseable file silently yields the defaults.
|
|
71
|
+
A missing or unparseable file silently yields the defaults. Every stored
|
|
72
|
+
value is read at its declared type, so a hand-edited (or older-boost)
|
|
73
|
+
``"pin_only": "no"`` is the boolean the user meant and not a truthy string
|
|
74
|
+
that freezes the machine. A value that cannot be read at its type falls
|
|
75
|
+
back to the default and is reported by :func:`invalid_values` — never
|
|
76
|
+
raised into the middle of an install, and never silently obeyed either.
|
|
39
77
|
"""
|
|
40
|
-
p = paths.policy_path()
|
|
41
78
|
base = DEFAULTS.copy()
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
base
|
|
79
|
+
for key, value in _read_file().items():
|
|
80
|
+
if key not in DEFAULTS:
|
|
81
|
+
base[key] = value
|
|
82
|
+
continue
|
|
83
|
+
try:
|
|
84
|
+
base[key] = typedvalue.adapt(key, value, spec_for(key))
|
|
85
|
+
except typedvalue.ValueTypeError:
|
|
86
|
+
base[key] = DEFAULTS[key]
|
|
45
87
|
return base
|
|
46
88
|
|
|
47
89
|
|
|
90
|
+
def invalid_values() -> list[tuple[str, object, str]]:
|
|
91
|
+
"""Stored policy values that could not be read at their declared type.
|
|
92
|
+
|
|
93
|
+
Each row is ``(key, stored value, expected phrase)``. :func:`load` has
|
|
94
|
+
already substituted the default for these, so this is what lets `boost
|
|
95
|
+
policy` say which keys are being ignored and why.
|
|
96
|
+
"""
|
|
97
|
+
bad: list[tuple[str, object, str]] = []
|
|
98
|
+
for key, value in _read_file().items():
|
|
99
|
+
if key not in DEFAULTS:
|
|
100
|
+
continue
|
|
101
|
+
try:
|
|
102
|
+
typedvalue.adapt(key, value, spec_for(key))
|
|
103
|
+
except typedvalue.ValueTypeError as e:
|
|
104
|
+
bad.append((key, value, e.expected))
|
|
105
|
+
return bad
|
|
106
|
+
|
|
107
|
+
|
|
48
108
|
def save(pol: dict) -> None:
|
|
49
109
|
"""Write `pol` to policy.json, restricted to the known DEFAULTS keys.
|
|
50
110
|
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# Copyright the boost contributors.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
"""Read a command-line string at the type its key already declares.
|
|
4
|
+
|
|
5
|
+
``boost config set`` and ``boost policy set`` both took *any* string for *any*
|
|
6
|
+
known key and stored whatever ``json.loads`` made of it. The damage landed
|
|
7
|
+
later and elsewhere: ``policy set max_skills abc`` exited 0, and the next
|
|
8
|
+
``install`` died with ``ValueError: invalid literal for int()`` and a crash
|
|
9
|
+
report. The nastiest shape was not a crash at all — ``policy set pin_only no``
|
|
10
|
+
stored the *string* ``"no"``, which is truthy, so boost reported "pin-only mode
|
|
11
|
+
is on" and froze every install for a user who had just turned it off.
|
|
12
|
+
|
|
13
|
+
Both modules already ship a ``DEFAULTS`` table, and a default value names its
|
|
14
|
+
own type. This module turns that table into a parser: ``coerce("pin_only",
|
|
15
|
+
"no", BOOL)`` is ``False``, and ``coerce("max_skills", "abc", INT_OR_NONE)``
|
|
16
|
+
raises :class:`ValueTypeError` at the setter instead of exit 70 at the next
|
|
17
|
+
install.
|
|
18
|
+
|
|
19
|
+
The one deliberate asymmetry is :data:`LIST`, which never raises. A list key's
|
|
20
|
+
documented surface is a comma list (``blocked_skills a,b``), so anything that
|
|
21
|
+
is not already a JSON array is split on commas rather than refused — which is
|
|
22
|
+
also what turns ``blocked_skills 42`` from a stored ``42`` (and a later
|
|
23
|
+
``TypeError: argument of type 'int' is not iterable``) into ``["42"]``.
|
|
24
|
+
"""
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
import json
|
|
28
|
+
from typing import Any
|
|
29
|
+
|
|
30
|
+
#: Spec names. A spec is a plain string so the tables that use it stay readable
|
|
31
|
+
#: and JSON-dumpable, and so it can be printed straight into a hint the user
|
|
32
|
+
#: retypes (``boost policy set pin_only <bool>``). An unrecognised spec is the
|
|
33
|
+
#: lenient :data:`ANY`, never an error — see :func:`describe` for why.
|
|
34
|
+
BOOL = "bool"
|
|
35
|
+
INT = "int"
|
|
36
|
+
INT_OR_NONE = "int-or-null"
|
|
37
|
+
LIST = "list"
|
|
38
|
+
STR = "str"
|
|
39
|
+
DICT = "dict"
|
|
40
|
+
ANY = "any"
|
|
41
|
+
|
|
42
|
+
#: Strings accepted for a true boolean, lower-cased and stripped.
|
|
43
|
+
TRUE_WORDS = frozenset({"true", "yes", "on", "1"})
|
|
44
|
+
#: Strings accepted for a false boolean. ``no``/``off``/``0`` are the three
|
|
45
|
+
#: that used to store a truthy string and invert the setting.
|
|
46
|
+
FALSE_WORDS = frozenset({"false", "no", "off", "0"})
|
|
47
|
+
#: Strings accepted as "no value" for :data:`INT_OR_NONE`.
|
|
48
|
+
NONE_WORDS = frozenset({"", "null", "none"})
|
|
49
|
+
|
|
50
|
+
_DESCRIPTIONS = {
|
|
51
|
+
BOOL: "a boolean (true/false, yes/no, on/off, 1/0)",
|
|
52
|
+
INT: "a whole number",
|
|
53
|
+
INT_OR_NONE: "a whole number, or null for no limit",
|
|
54
|
+
LIST: "a comma-separated list, or a JSON array",
|
|
55
|
+
STR: "a string",
|
|
56
|
+
DICT: "a JSON object",
|
|
57
|
+
ANY: "any value",
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class ValueTypeError(ValueError):
|
|
62
|
+
"""A raw string that cannot be read at its key's declared type.
|
|
63
|
+
|
|
64
|
+
Carries the parts a caller needs to word its own error: which ``key`` was
|
|
65
|
+
being set, the ``raw`` value that failed, and an ``expected`` phrase naming
|
|
66
|
+
the type in the words a user can retype. ``raw`` is a string when the value
|
|
67
|
+
was typed and can be any JSON scalar when it was read back off disk.
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
def __init__(self, key: str, raw: Any, spec: str):
|
|
71
|
+
self.key = key
|
|
72
|
+
self.raw = raw
|
|
73
|
+
self.spec = spec
|
|
74
|
+
self.expected = describe(spec)
|
|
75
|
+
super().__init__("%s expects %s, got %r" % (key, self.expected, raw))
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def describe(spec: str) -> str:
|
|
79
|
+
"""The human phrase for a spec, e.g. ``"a whole number"``.
|
|
80
|
+
|
|
81
|
+
An unknown spec describes as :data:`ANY` rather than raising: a wrong hint
|
|
82
|
+
must never be the thing that turns a working setter into a crash.
|
|
83
|
+
"""
|
|
84
|
+
return _DESCRIPTIONS.get(spec, _DESCRIPTIONS[ANY])
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def spec_for(default: Any) -> str:
|
|
88
|
+
"""Derive a spec from a key's default value.
|
|
89
|
+
|
|
90
|
+
``bool`` is tested before ``int`` on purpose — ``bool`` is a subclass of
|
|
91
|
+
``int``, so the natural order would type every boolean key as a number and
|
|
92
|
+
happily store ``pin_only = 2``. ``None`` carries no type and yields
|
|
93
|
+
:data:`ANY`; a key defaulting to ``None`` that *does* have a type (policy's
|
|
94
|
+
``max_skills``) declares it explicitly in its own table.
|
|
95
|
+
"""
|
|
96
|
+
if isinstance(default, bool):
|
|
97
|
+
return BOOL
|
|
98
|
+
if isinstance(default, int):
|
|
99
|
+
return INT
|
|
100
|
+
if isinstance(default, list):
|
|
101
|
+
return LIST
|
|
102
|
+
if isinstance(default, dict):
|
|
103
|
+
return DICT
|
|
104
|
+
if isinstance(default, str):
|
|
105
|
+
return STR
|
|
106
|
+
return ANY
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _as_bool(key: str, raw: str) -> bool:
|
|
110
|
+
word = raw.strip().lower()
|
|
111
|
+
if word in TRUE_WORDS:
|
|
112
|
+
return True
|
|
113
|
+
if word in FALSE_WORDS:
|
|
114
|
+
return False
|
|
115
|
+
raise ValueTypeError(key, raw, BOOL)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _as_int(key: str, raw: str, spec: str) -> int:
|
|
119
|
+
try:
|
|
120
|
+
return int(raw.strip())
|
|
121
|
+
except (TypeError, ValueError) as e:
|
|
122
|
+
raise ValueTypeError(key, raw, spec) from e
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _as_list(raw: str) -> list:
|
|
126
|
+
"""A JSON array as written, else the comma split. Never raises."""
|
|
127
|
+
try:
|
|
128
|
+
parsed = json.loads(raw)
|
|
129
|
+
except (json.JSONDecodeError, TypeError):
|
|
130
|
+
parsed = None
|
|
131
|
+
if isinstance(parsed, list):
|
|
132
|
+
return parsed
|
|
133
|
+
return [s.strip() for s in raw.split(",") if s.strip()]
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _as_dict(key: str, raw: str) -> dict:
|
|
137
|
+
try:
|
|
138
|
+
parsed = json.loads(raw)
|
|
139
|
+
except (json.JSONDecodeError, TypeError) as e:
|
|
140
|
+
raise ValueTypeError(key, raw, DICT) from e
|
|
141
|
+
if not isinstance(parsed, dict):
|
|
142
|
+
raise ValueTypeError(key, raw, DICT)
|
|
143
|
+
return parsed
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def _as_any(raw: str) -> Any:
|
|
147
|
+
"""The old lenient behaviour: JSON when it parses, the string otherwise.
|
|
148
|
+
|
|
149
|
+
Kept for keys no ``DEFAULTS`` table describes — ``boost config set`` accepts
|
|
150
|
+
keys boost has never heard of, and inventing a type for those would refuse
|
|
151
|
+
values that work today.
|
|
152
|
+
"""
|
|
153
|
+
try:
|
|
154
|
+
return json.loads(raw)
|
|
155
|
+
except (json.JSONDecodeError, TypeError):
|
|
156
|
+
return raw
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def coerce(key: str, raw: str, spec: str) -> Any:
|
|
160
|
+
"""Read ``raw`` at ``spec``, or raise :class:`ValueTypeError`.
|
|
161
|
+
|
|
162
|
+
``raw`` is what argv handed over, so it is always a string here; the
|
|
163
|
+
already-typed sibling for values read back off disk is :func:`adapt`.
|
|
164
|
+
"""
|
|
165
|
+
if spec == BOOL:
|
|
166
|
+
return _as_bool(key, raw)
|
|
167
|
+
if spec == INT:
|
|
168
|
+
return _as_int(key, raw, INT)
|
|
169
|
+
if spec == INT_OR_NONE:
|
|
170
|
+
return None if raw.strip().lower() in NONE_WORDS else _as_int(key, raw, INT_OR_NONE)
|
|
171
|
+
if spec == LIST:
|
|
172
|
+
return _as_list(raw)
|
|
173
|
+
if spec == STR:
|
|
174
|
+
return raw
|
|
175
|
+
if spec == DICT:
|
|
176
|
+
return _as_dict(key, raw)
|
|
177
|
+
return _as_any(raw)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def matches(value: Any, spec: str) -> bool:
|
|
181
|
+
"""True when an already-typed ``value`` is acceptable for ``spec``.
|
|
182
|
+
|
|
183
|
+
Deliberately stricter than :func:`coerce`: this judges a value that is
|
|
184
|
+
already sitting in a JSON file, where ``"no"`` is a string and not a
|
|
185
|
+
keystroke. ``bool`` is rejected for the numeric specs for the same reason
|
|
186
|
+
:func:`spec_for` tests it first.
|
|
187
|
+
"""
|
|
188
|
+
if spec == BOOL:
|
|
189
|
+
return isinstance(value, bool)
|
|
190
|
+
if spec == INT:
|
|
191
|
+
return isinstance(value, int) and not isinstance(value, bool)
|
|
192
|
+
if spec == INT_OR_NONE:
|
|
193
|
+
return value is None or (isinstance(value, int) and not isinstance(value, bool))
|
|
194
|
+
if spec == LIST:
|
|
195
|
+
return isinstance(value, list)
|
|
196
|
+
if spec == STR:
|
|
197
|
+
return isinstance(value, str)
|
|
198
|
+
if spec == DICT:
|
|
199
|
+
return isinstance(value, dict)
|
|
200
|
+
return True
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def adapt(key: str, value: Any, spec: str) -> Any:
|
|
204
|
+
"""Return ``value`` at ``spec``, or raise :class:`ValueTypeError`.
|
|
205
|
+
|
|
206
|
+
The entry point for values read back from a file rather than typed: a
|
|
207
|
+
value that already matches is returned untouched, and a *string* gets one
|
|
208
|
+
chance to be re-read through :func:`coerce`, which is what rescues a
|
|
209
|
+
``"pin_only": "no"`` written by an older boost or by hand. Anything else
|
|
210
|
+
(a list where a number belongs) is refused — guessing there would be
|
|
211
|
+
inventing data, not reading it.
|
|
212
|
+
"""
|
|
213
|
+
if matches(value, spec):
|
|
214
|
+
return value
|
|
215
|
+
if isinstance(value, str):
|
|
216
|
+
return coerce(key, value, spec)
|
|
217
|
+
raise ValueTypeError(key, value, spec)
|
|
@@ -107,6 +107,7 @@ boost_cli/core/stackprobe.py
|
|
|
107
107
|
boost_cli/core/staleness.py
|
|
108
108
|
boost_cli/core/store.py
|
|
109
109
|
boost_cli/core/trustaudit.py
|
|
110
|
+
boost_cli/core/typedvalue.py
|
|
110
111
|
boost_cli/core/typosquat.py
|
|
111
112
|
boost_cli/core/updatediff.py
|
|
112
113
|
boost_cli/core/util.py
|
|
@@ -933,6 +934,7 @@ tests/unit/test_tap_pins.py
|
|
|
933
934
|
tests/unit/test_token_parity.py
|
|
934
935
|
tests/unit/test_toolchain_lock.py
|
|
935
936
|
tests/unit/test_trustaudit.py
|
|
937
|
+
tests/unit/test_typedvalue.py
|
|
936
938
|
tests/unit/test_typosquat.py
|
|
937
939
|
tests/unit/test_updatediff.py
|
|
938
940
|
tests/unit/test_util.py
|
|
Binary file
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
id: audit-config-policy-set-store-type-unchecked-values-consumers-cras
|
|
3
3
|
board: code
|
|
4
4
|
section: dx
|
|
5
|
-
status:
|
|
5
|
+
status: shipped
|
|
6
6
|
category: CLI · Bug
|
|
7
7
|
complexity: M
|
|
8
8
|
impact: High
|
|
9
9
|
wow: 2
|
|
10
10
|
note: '`policy set pin_only no` stores the truthy string "no" — pin-only ON, installs frozen'
|
|
11
11
|
order: 202
|
|
12
|
-
owner:
|
|
13
|
-
pr:
|
|
12
|
+
owner: loop/typed-config-values
|
|
13
|
+
pr: 683
|
|
14
14
|
title: "<code>config</code>/<code>policy set</code> store type-unchecked values; consumers crash exit 70 and <code>pin_only no</code> freezes installs"
|
|
15
15
|
---
|
|
16
16
|
Both setters accept any value for any known key and the damage lands later, elsewhere. <code>policy set max_skills abc</code> → <em>“✓ set max_skills = "abc"”</em> exit 0; the next <code>install brainstorming</code> → <em>“Error: boost hit an unexpected error: ValueError: invalid literal for int() with base 10: 'abc'”</em> exit 70 plus a crash report. <code>config set serve.port abc</code> then crashes even <code>serve --help</code> with the same ValueError — before argparse runs. <code>policy set blocked_skills 42</code> → <em>“TypeError: argument of type 'int' is not iterable”</em> from <code>policy check</code> and <code>install</code>.
|
|
@@ -20,3 +20,5 @@ The nastiest shape is silent inversion, not a crash: <code>policy set pin_only n
|
|
|
20
20
|
Fix per the verified recommendation: in <code>_parse_policy_value</code> (<code>boost_cli/commands/configuration.py:382-390</code>) and <code>config.set_value</code> (<code>boost_cli/core/config.py:246-258</code>), derive a per-key type from <code>policy.DEFAULTS</code> (<code>boost_cli/core/policy.py:15-34</code>) / <code>config.DEFAULTS</code>: map bools from {true,yes,on,1}/{false,no,off,0} case-insensitively, ints via <code>int()</code>, lists via <code>json.loads</code>, treat <code>max_skills</code> as int|None, and reject mismatches with a BoostError naming the expected type. Wrap the consumers (<code>cmd_serve</code>'s port read, <code>policy.load</code>) so a hand-edited bad value is a framed error with a hint, never a traceback. Regenerate <code>docs/commands.html</code> if the help epilogs gain the valid-value lists.
|
|
21
21
|
|
|
22
22
|
Found by the 2026-08 CLI audit (cluster <code>config-policy-set-validation</code>); repro in the audit log. Verified 2026-08-31: reproduced end to end, including the pin_only inversion and the exit-70 consumers.
|
|
23
|
+
|
|
24
|
+
<b>Shipped in #683.</b> The per-key type lives in one place, <code>core/typedvalue.py</code>, derived from the two <code>DEFAULTS</code> tables through <code>config.spec_for</code> / <code>policy.spec_for</code> — so a new key needs a default of the right type and no validation code. Four invariants carry the fix and each was a bug waiting: <b>bool is tested before int</b> (a <code>bool</code> <i>is</i> an <code>int</code> in Python, so the natural order types every boolean key as a number); <b>a list key never raises</b>, because its documented surface is a comma list, which is what turns <code>blocked_skills 42</code> into <code>["42"]</code> rather than a stored <code>42</code>; <b>a key <code>DEFAULTS</code> has never heard of keeps the old lenient parse</b>, because <code>config set</code> accepts keys integrations invent; and <b><code>policy.load()</code> coerces and reports rather than raising</b> — a hand-edited <code>"pin_only": "no"</code> reads as the boolean the user meant, and anything unreadable falls back to the default and is named by <code>policy.invalid_values()</code> in <code>policy list</code>/<code>check</code>, because a traceback from inside an install is not a remedy and a silent substitution is not honest. <code>cmd_serve</code> reads its default through <code>config.get_int()</code> and frames the failure, so <code>serve --help</code> on a bad port is one line instead of exit 70. The help epilogs gained no valid-value lists — the type travels in the error hint (<code>try `boost policy set pin_only <bool>`</code>), which the tests pin verbatim — so <code>docs/commands.html</code> is unchanged.
|
|
@@ -11573,15 +11573,18 @@ Found by the 2026-08 CLI audit (cluster <code>clean-failure-accounting</code>);
|
|
|
11573
11573
|
</article>
|
|
11574
11574
|
|
|
11575
11575
|
<article class="cap rcard" id="audit-config-policy-set-store-type-unchecked-values-consumers-cras">
|
|
11576
|
-
<div class="head"><span class="pill
|
|
11576
|
+
<div class="head"><span class="pill shipped">Shipped</span><span class="cat">CLI · Bug</span></div>
|
|
11577
11577
|
<h3><code>config</code>/<code>policy set</code> store type-unchecked values; consumers crash exit 70 and <code>pin_only no</code> freezes installs</h3>
|
|
11578
|
+
<details class="cardbody"><summary>Write-up</summary>
|
|
11578
11579
|
<p>Both setters accept any value for any known key and the damage lands later, elsewhere. <code>policy set max_skills abc</code> → <em>“✓ set max_skills = "abc"”</em> exit 0; the next <code>install brainstorming</code> → <em>“Error: boost hit an unexpected error: ValueError: invalid literal for int() with base 10: 'abc'”</em> exit 70 plus a crash report. <code>config set serve.port abc</code> then crashes even <code>serve --help</code> with the same ValueError — before argparse runs. <code>policy set blocked_skills 42</code> → <em>“TypeError: argument of type 'int' is not iterable”</em> from <code>policy check</code> and <code>install</code>.
|
|
11579
11580
|
|
|
11580
11581
|
The nastiest shape is silent inversion, not a crash: <code>policy set pin_only no</code> stores the <em>string</em> <code>"no"</code>, which is truthy — <code>policy check</code> reports <em>“pin-only mode is on — installs/updates are frozen”</em> and <code>install</code> refuses with <em>“environment is pin-only (frozen)”</em>. Same for <code>yes</code>, <code>off</code>, <code>0</code>, and every boolean policy key (<code>require_version</code>, <code>require_signed_taps</code>, …). Verification narrowed the claim honestly: key <em>names</em> are validated (<code>policy set nonsense_key x</code> exits 1 with the key list) — the gap is value types only, and <code>DEFAULTS</code> tables already exist in both modules to derive them from.
|
|
11581
11582
|
|
|
11582
11583
|
Fix per the verified recommendation: in <code>_parse_policy_value</code> (<code>boost_cli/commands/configuration.py:382-390</code>) and <code>config.set_value</code> (<code>boost_cli/core/config.py:246-258</code>), derive a per-key type from <code>policy.DEFAULTS</code> (<code>boost_cli/core/policy.py:15-34</code>) / <code>config.DEFAULTS</code>: map bools from {true,yes,on,1}/{false,no,off,0} case-insensitively, ints via <code>int()</code>, lists via <code>json.loads</code>, treat <code>max_skills</code> as int|None, and reject mismatches with a BoostError naming the expected type. Wrap the consumers (<code>cmd_serve</code>'s port read, <code>policy.load</code>) so a hand-edited bad value is a framed error with a hint, never a traceback. Regenerate <code>docs/commands.html</code> if the help epilogs gain the valid-value lists.
|
|
11583
11584
|
|
|
11584
|
-
Found by the 2026-08 CLI audit (cluster <code>config-policy-set-validation</code>); repro in the audit log. Verified 2026-08-31: reproduced end to end, including the pin_only inversion and the exit-70 consumers
|
|
11585
|
+
Found by the 2026-08 CLI audit (cluster <code>config-policy-set-validation</code>); repro in the audit log. Verified 2026-08-31: reproduced end to end, including the pin_only inversion and the exit-70 consumers.
|
|
11586
|
+
|
|
11587
|
+
<b>Shipped in #683.</b> The per-key type lives in one place, <code>core/typedvalue.py</code>, derived from the two <code>DEFAULTS</code> tables through <code>config.spec_for</code> / <code>policy.spec_for</code> — so a new key needs a default of the right type and no validation code. Four invariants carry the fix and each was a bug waiting: <b>bool is tested before int</b> (a <code>bool</code> <i>is</i> an <code>int</code> in Python, so the natural order types every boolean key as a number); <b>a list key never raises</b>, because its documented surface is a comma list, which is what turns <code>blocked_skills 42</code> into <code>["42"]</code> rather than a stored <code>42</code>; <b>a key <code>DEFAULTS</code> has never heard of keeps the old lenient parse</b>, because <code>config set</code> accepts keys integrations invent; and <b><code>policy.load()</code> coerces and reports rather than raising</b> — a hand-edited <code>"pin_only": "no"</code> reads as the boolean the user meant, and anything unreadable falls back to the default and is named by <code>policy.invalid_values()</code> in <code>policy list</code>/<code>check</code>, because a traceback from inside an install is not a remedy and a silent substitution is not honest. <code>cmd_serve</code> reads its default through <code>config.get_int()</code> and frames the failure, so <code>serve --help</code> on a bad port is one line instead of exit 70. The help epilogs gained no valid-value lists — the type travels in the error hint (<code>try `boost policy set pin_only <bool>`</code>), which the tests pin verbatim — so <code>docs/commands.html</code> is unchanged.</p></details>
|
|
11585
11588
|
<div class="meta">
|
|
11586
11589
|
<span class="m">Complexity <b>M</b></span>
|
|
11587
11590
|
<span class="m hi">Impact <b>High</b></span>
|