boost-skill-cli 1.0.303__tar.gz → 1.0.305__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {boost_skill_cli-1.0.303/boost_skill_cli.egg-info → boost_skill_cli-1.0.305}/PKG-INFO +1 -1
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/_version.py +2 -2
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305/boost_skill_cli.egg-info}/PKG-INFO +1 -1
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_skill_cli.egg-info/SOURCES.txt +1 -0
- boost_skill_cli-1.0.305/docs/roadmap/items/ci-time-is-now-runner-queueing.md +71 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/dependabot-root-pip-entry-duplicates-requirements.md +24 -3
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap.html +56 -4
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_dependabot_config.py +58 -0
- boost_skill_cli-1.0.305/tests/unit/test_workflow_concurrency.py +112 -0
- boost_skill_cli-1.0.303/docs/roadmap/items/ci-time-is-now-runner-queueing.md +0 -40
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/.gitattributes +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/.gitignore +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/.gitleaks.toml +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/.htmlvalidate.json +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/.lighthouserc.json +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/.lycheeignore +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/.markdownlint-cli2.jsonc +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/.pre-commit-config.yaml +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/.stylelintrc.json +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/.vale/styles/boost/Terminology.yml +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/.vale/styles/config/vocabularies/boost/accept.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/.vale.ini +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/CLAUDE.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/CODE_OF_CONDUCT.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/CONTRIBUTING.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/LICENSE +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/MANIFEST.in +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/Makefile +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/README.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/SECURITY.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/__init__.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/__main__.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/cli.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/cliparse.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/__init__.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/_common.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/bmad.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/configuration.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/discovery.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/hooks.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/info.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/intelligence.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/pkg.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/quality.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/run.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/safety.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/taps.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/commands/team.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/__init__.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/adapters.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/agents.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/ai.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/capabilities.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/catalog.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/claude_settings.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/config.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/dense.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/ed25519.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/embed.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/faithfulness.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/frontmatter.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/gitutil.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/imperative.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/injectscan.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/installscan.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/integrity.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/journal.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/lockfile.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/logs.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/mcp.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/mcpdecl.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/mcphost.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/minisign.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/nethttp.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/output.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/paths.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/policy.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/projectlock.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/provenance.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/rag.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/registry.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/resolve.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/rules.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/scopes.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/secretscan.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/selfupdate.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/serve.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/stackprobe.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/staleness.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/store.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/trustaudit.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/typosquat.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/updatediff.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/util.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/core/workflows.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/data/registries.json +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/errors.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_cli/spin.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_skill_cli.egg-info/dependency_links.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_skill_cli.egg-info/entry_points.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_skill_cli.egg-info/requires.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/boost_skill_cli.egg-info/top_level.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/codecov.yml +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/.claude/settings.local.json +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/DEBUGGING.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/adapters.html +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/architecture/README.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/architecture/c4-components-core.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/architecture/c4-containers.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/architecture/c4-context.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/architecture/c4-dynamic-install.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/gifs/distill.gif +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/gifs/doctor.gif +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/gifs/explain.gif +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/gifs/hooks.gif +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/gifs/install.gif +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/gifs/pulse.gif +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/gifs/search.gif +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/gifs/tap.gif +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/tapes/distill.tape +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/tapes/doctor.tape +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/tapes/explain.tape +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/tapes/hooks.tape +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/tapes/install.tape +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/tapes/pulse.tape +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/tapes/search.tape +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel/tapes/tap.tape +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/carousel.html +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/commands.html +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/demo.gif +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/demo.tape +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/design-roadmap.html +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/eval.html +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/index.html +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/mcp-hub.html +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/rag-architecture.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D01.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D02.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D03.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D04.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D05.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D06.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D07.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D08.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D09.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D10.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D11.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D12.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D13.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D14.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D15.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D16.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D17.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D18.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D19.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D20.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D21.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D22.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D23.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D24.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D25.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/BOOST-D26.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/accessibility-audit-pa11y-ci-axe-core.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/actionlint-skips-shellcheck-silently.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/adapter-conformance-langgraph-leg-never-ran.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/ai-bridge-silent-failure-logging.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/ambiguous-tap-short-name-resolution.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/atomic-corruption-safe-lock-file-writes.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/atomic-skill-install-temp-dir-swap.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/autonomous-ship-workflow-and-isolated-worktree.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/boost-run-live-agents.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/bring-commands-under-mutation-testing.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/broken-link-and-anchor-checking-lychee.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/browse-crashes-selecting-a-rule-or-workflow.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/build-provenance-slsa-attestations.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/cache-the-catalog-entry-set-across-rag-queries.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/capability-manifest-and-least-privilege-policy.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/ci-job-timeout-minutes.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/ci-summary-step-fails-itself.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/clean-env-install-smoke-pip-and-pipx.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/code-scanning-rule-can-be-restored.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/codeql-job-rename-stranded-merge-protection.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/command-carousel-page.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/command-reference-docs-site.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/complexity-and-dead-code-radar-xenon-vulture.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/consolidate-skill-staleness-drift-logic-into-cor.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/coverage-dashboard-codecov-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/coverage-guided-fuzzing-atheris-oss-fuzz.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/crash-listing-branch-untested.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/crash-recorder-error-paths-core-logs-py.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/demo-cannot-open-its-own-pr.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/demo-gif-workflow-has-never-succeeded.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/dense-search-fallback-and-stale-tap-pruning.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/dependabot-missing-pip-ecosystem.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/dependabot-regeneration-drops-platform-pins.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/dependency-cve-gate-pip-audit.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/docsite-chrome-and-content-audit.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/docstring-coverage-interrogate.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/doctor-checks-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/end-of-options-guard-on-git-commands.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/extension-free-tests-core-dense-py.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/extract-mcp-http-servers-out-of-configuration-py.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/finish-mutation-hardening-across-core.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/fix-self-update-version-detection-dead-branch.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/fork-safe-network-proxy-handler.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/framework-adapter-langgraph.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/framework-adapter-multi-agent.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/framework-adapters-boost-adapt.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/frontmatter-scalar-over-coercion.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/gemini-cli-agent-target.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/github-community-health-files.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/github-pages-deploy-is-broken-every-push.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/golden-set-statistical-power.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/hash-pinned-reproducible-toolchain-uv-lock.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/html-validation-html-validate.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/install-docs-never-mentioned-upgrading.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/install-from-path-bypasses-policy-and-pin-checks.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/install-resolves-skill-dependencies.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/install-scope-user-or-project.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/installed-skill-trust-audit.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/integrity-verification-boost-verify.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/internal-architecture-diagrams.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/invocation-pid-logging-for-crash-correlation.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/journal-rotation-race-and-handle-leak.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/layering-guard-import-linter.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/license-compliance-scanning.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/lighthouse-ci-on-the-pages-site.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/lint-tap-misscopes-rule-workflow-entries.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/list-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/localize-the-stored-bm25-snippet.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/lock-invariant-cannot-parse-extras-pins.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/lockfile-enforcement-and-commit-pinning.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/log-timestamps-mislabeled-utc.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/lowest-version-resolution-uv-resolution-lowest-d.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/main-has-no-branch-protection.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/main-ruleset-ref-pattern-has-literal-quotes.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/make-lint-masks-actionlint-failures.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/make-the-roadmaps-discoverable.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/markdown-consistency-markdownlint-cli2.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/markdownlint-lints-the-fuzz-corpus.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mcp-aware-skills.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mcp-check-skills-before-starting-a-task.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mcp-hub-diagram-node-text-overflow.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mcp-install-skips-the-injection-scan.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mcp-launch-objc-fork-safety.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mcp-register-names-server-before-env.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mcp-search-before-reinventing.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mcp-servers-ignore-install-scope.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mcp-startup-self-harden-fork-safety.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/memoize-config-load-in-process.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/merge-queue-would-deadlock-most-required-checks.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/merged-loop-branches-are-never-pruned.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/modernization-smells-refurb-pyupgrade.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mutation-gate-was-the-whole-critical-path.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mutation-hardening-core-frontmatter-py.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mutation-hardening-core-gitutil-py.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mutation-hardening-core-store-py.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mutation-shard-floor-is-one-file.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/mypy-strict-mode-for-commands.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/negative-limit-inverts-log-pulse-output.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/onboard-overwrites-generated-files-without-confirm.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/one-command-every-env-nox.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/one-commit-can-cut-two-releases.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/one-shared-atomic-write-helper.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/package-metadata-validation-twine-check-friends.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/patch-coverage-gate-diff-cover.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/path-traversal-unsanitized-rule-workflow-name.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/performance-regression-gate-pytest-benchmark.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/pin-the-lint-toolchain.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/post-deploy-always-defeated-by-skipped-setup.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/post-deploy-smoke-headless-load-check.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/pre-release-python-canary-3-14t-free-threaded.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/project-scope-across-every-command.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/project-scope-symlink-escape-on-write.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/promote-nav-footer-into-the-shared-style-system.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/prompt-injection-scanning-of-skill-markdown.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/property-based-tests-hypothesis-on-the-parsers.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/prose-and-terminology-linting-vale.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/prune-ignored-dirs-during-scan-dir-walk.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/publish-gate-ignores-pip-audit-and-metadata.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/publish-trigger-was-reachable-from-a-fork.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/pytest-tmpdir-cve-blocked-by-py39-floor.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/quality-dashboard-sonarcloud-free-for-oss.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/ranx-significance-monitor.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/reconcile-the-theme-drift.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/refresh-the-marketing-surface.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/rel-time-tests-race-the-wall-clock.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/release-verifies-the-wrong-commit.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/required-checks-can-declare-a-check-that-deadlocks-prs.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/required-checks-config-drift.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/retrieval-quality-eval-harness.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/reuse-helpers-kill-minor-dead-work.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/roadmap-html-goes-stale-on-every-rebase.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/robust-tag-argument-parsing.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/ruff-016-widens-the-default-rule-set.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/rule-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/runner-egress-monitoring-stepsecurity-harden-run.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/runtime-explain-faithfulness-guardrail.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/sbom-aware-scanning-osv-scanner.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/sbom-declares-the-wrong-version.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/sbom-on-every-release-cyclonedx-syft.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/sbom-release-event-never-fires.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/scan-and-sync-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/scheduled-toolchain-lock-regeneration.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/scorecard-findings-triage.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/second-type-checker-pyright.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/secret-and-pii-scanning-of-installed-skills.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/secret-scanning-gitleaks-push-protection.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/security-linting-bandit-via-ruff-s-rules.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/self-update-broken-for-pip-pipx-installs.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/serve-py-traversal-guards-untested.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/shift-left-gate-pre-commit-pre-commit-ci.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/single-imperative-rule-extractor.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/single-tech-stack-prober.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/split-oversized-command-modules.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/startup-and-import-time-budget-x-importtime.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/stop-re-serializing-entry-meta-on-every-search.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/structured-json-log-output-mode.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/supply-chain-posture-openssf-scorecard.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/surface-every-docs-page-from-the-guide.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/sync-deletes-unowned-broken-symlinks.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/sync-relinks-into-every-agent-ignoring-scope.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/tap-signing-and-provenance-sigstore-minisign.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/theme-asset-linting-stylelint-eslint.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/typo-detection-codespell.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/typosquat-and-name-confusion-detection.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/unify-tilde-two-copies-have-a-boundary-bug.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/uninstall-has-no-confirmation-prompt.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/untrack-generated-build-noise.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/update-diff-before-apply.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/update-refreshes-rules-and-workflows.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/update-reinstall-widens-agent-scope.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/visual-regression-pass-on-the-guide.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/widen-the-ruff-rule-surface-b-sim-c4-perf-ruf.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/windows-in-the-ci-matrix.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/wire-bdd-suite-into-ci.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/workflow-install-native-materialization.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/workflow-linting-actionlint.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/workflow-sast-zizmor.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/workspace-scope-install.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/docs/roadmap/items/zizmor-pin-is-a-yanked-release.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/eslint.config.mjs +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/evals/README.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/evals/__init__.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/evals/baseline.json +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/evals/faithfulness.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/evals/golden_set.json +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/evals/make_corpus.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/evals/make_golden.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/evals/metrics.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/evals/run_evals.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/examples/README.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/examples/adapt-demo.sh +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/examples/boost-run-prototype.sh +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/index.html +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/noxfile.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/pyproject.toml +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/requirements/coverage-tools.in +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/requirements/coverage-tools.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/requirements/lint-tools.in +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/requirements/lint-tools.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/requirements/mutation-tools.in +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/requirements/mutation-tools.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/requirements/platform-pins.lock +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/requirements/release-tools.in +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/requirements/release-tools.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/requirements/test-tools.in +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/requirements/test-tools.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/a11y_check.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/bench_cli.sh +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/build_command_reference.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/build_registries.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/build_roadmap.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/check_anchors.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/check_licenses.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/check_required_checks.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/ensure_eval_corpus.sh +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/eval_explain.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/eval_gate.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/eval_recommend.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/eval_retrieval.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/eval_stats_summary.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/import_budget.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/lock_toolchain.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/mutation_gate.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/mutation_shards.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/mutation_weights.json +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/perf_gate.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/post_deploy_smoke.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/release_guard.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/scripts/release_preflight.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/setup.cfg +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/sonar-project.properties +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/style/README.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/style/boost.css +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/style/boost.js +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/style/demo.html +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/adapt.feature +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/browse.feature +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/count.feature +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/discover.feature +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/doctor.feature +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/environment.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/explain.feature +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/index.feature +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/install.feature +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/list.feature +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/mcp.feature +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/search.feature +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/steps/cli_steps.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/steps/discovery_steps.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/steps/mcp_steps.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/bdd/features/steps/quality_steps.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/conftest.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/eval/baseline.json +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/eval/explain.jsonl +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/eval/golden.jsonl +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/eval/recommend.jsonl +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/eval/taps.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_capabilities_policy.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_cli_adapt.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_cli_bmad.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_cli_configuration.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_cli_discovery.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_cli_hooks.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_cli_info.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_cli_intelligence.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_cli_pkg.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_cli_quality.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_cli_taps.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_cli_team.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_everyday_loop.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_integrity_enforce.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_property_parsers.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_run.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_tap_signing.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/functional/test_workspace_scope.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/README.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/frontmatter/01-typical.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/frontmatter/02-lossy-version.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/frontmatter/03-lossy-numbers.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/frontmatter/04-lists.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/frontmatter/05-nested.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/frontmatter/06-empty-block.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/frontmatter/07-unterminated.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/frontmatter/08-none.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/frontmatter/09-unbalanced-quote.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/frontmatter/10-keywords.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/frontmatter/11-crlf.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/frontmatter/12-bom.md +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/registry/01-shorthand.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/registry/02-https.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/registry/03-ssh.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/registry/04-traversal.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/registry/05-empty.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/registry/06-space.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/registry/07-slash.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/corpus/registry/08-bare-host.txt +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/fuzz_frontmatter.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/fuzz/fuzz_registry.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/make_fixture.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/perf/test_benchmarks.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/smoke.sh +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_a11y_check.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_adapters.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_adapters_multi.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_adapters_runner.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_agents.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_ai.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_capabilities.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_catalog.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_check_anchors.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_check_licenses.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_claude_settings.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_cliparse.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_codeql_analysis_key.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_command_reference_fresh.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_community_health_files.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_config.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_dense.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_dense_fallback.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_docs_pages_linked.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_docsite_chrome.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_ed25519.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_embed.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_errors_and_cli_table.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_eval_faithfulness.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_eval_gate.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_eval_metrics.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_eval_stats_summary.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_faithfulness.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_frontmatter.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_fuzz_targets.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_gitleaks_config.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_gitutil.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_imperative.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_import_budget.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_injectscan.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_installscan.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_integrity.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_journal.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_lockfile.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_logs.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_marketing_counts.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_mcp.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_mcp_install_scan.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_mcpdecl.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_mcphost.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_minisign.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_mutation_hardening.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_mutation_shards.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_mutation_subfile_shards.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_mutmut_source_paths.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_nethttp.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_output.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_paths.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_perf_gate.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_pkg_confusions.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_pkg_injection.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_pkg_secrets.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_platform_pins.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_policy.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_post_deploy_smoke.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_projectlock.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_provenance.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_rag.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_registries_fresh.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_registry.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_registry_categories.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_release_guard.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_release_preflight.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_required_checks.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_resolve.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_roadmap_fresh.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_rules.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_scopes.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_secretscan.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_selfupdate.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_serve.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_spin.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_stackprobe.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_staleness.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_store.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_token_parity.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_toolchain_lock.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_trustaudit.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_typosquat.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_updatediff.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_util.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_version.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_workflow_timeouts.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/unit/test_workflows.py +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/visual/a11y_check.mjs +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/visual/console_check.mjs +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/visual/package-lock.json +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/visual/package.json +0 -0
- {boost_skill_cli-1.0.303 → boost_skill_cli-1.0.305}/tests/visual/visual_check.mjs +0 -0
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.0.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 0,
|
|
21
|
+
__version__ = version = '1.0.305'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 0, 305)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -546,6 +546,7 @@ tests/unit/test_typosquat.py
|
|
|
546
546
|
tests/unit/test_updatediff.py
|
|
547
547
|
tests/unit/test_util.py
|
|
548
548
|
tests/unit/test_version.py
|
|
549
|
+
tests/unit/test_workflow_concurrency.py
|
|
549
550
|
tests/unit/test_workflow_timeouts.py
|
|
550
551
|
tests/unit/test_workflows.py
|
|
551
552
|
tests/visual/a11y_check.mjs
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: ci-time-is-now-runner-queueing
|
|
3
|
+
board: code
|
|
4
|
+
section: pipeline
|
|
5
|
+
status: shipped
|
|
6
|
+
category: CI speed
|
|
7
|
+
complexity: M
|
|
8
|
+
impact: High
|
|
9
|
+
wow: 4
|
|
10
|
+
note: 104 job-min queued vs 236 executing — 31% of CI is waiting for a runner
|
|
11
|
+
order: 62
|
|
12
|
+
owner: loop/ci-concurrency
|
|
13
|
+
pr: 350
|
|
14
|
+
title: A third of CI job time is spent waiting for a runner, not running
|
|
15
|
+
---
|
|
16
|
+
With the mutation gate no longer dominating, the largest remaining term in CI wall clock is
|
|
17
|
+
<b>queueing</b>. Measured over six consecutive successful <code>ci</code> runs: <b>104
|
|
18
|
+
job-minutes queued</b> against <b>236 job-minutes executing</b> — <b>31%</b> of all job
|
|
19
|
+
time spent waiting for a runner.
|
|
20
|
+
|
|
21
|
+
<b>The obvious metric lies.</b> A run's <code>run_started_at</code> minus
|
|
22
|
+
<code>created_at</code> is <b>0.0 for every run</b>, which reads as "no queueing anywhere".
|
|
23
|
+
Queueing happens per <em>job</em>, not per run, so it is only visible as
|
|
24
|
+
<code>job.started_at - job.created_at</code>. Anything measuring this at run level will
|
|
25
|
+
conclude, wrongly, that there is nothing to fix.
|
|
26
|
+
|
|
27
|
+
The per-run spread shows what drives it — median job queue by run:
|
|
28
|
+
<code>c36c53a7</code> 0.1 min, <code>c15ed9da</code> 0.1, <code>903b704f</code> 0.2,
|
|
29
|
+
<code>638bffeb</code> 0.7, <code>ad71ba99</code> <b>2.5</b>, <code>9e190537</code> <b>2.9</b>.
|
|
30
|
+
That is a 29× swing driven not by the change under test but by how many sibling
|
|
31
|
+
<code>loop/*</code> branches and Dependabot PRs happen to be live at the same moment. It is why
|
|
32
|
+
one merge took <b>41 minutes</b> wall clock with a max shard of only 11.4.
|
|
33
|
+
|
|
34
|
+
Sharding the mutation gate made this worse on purpose: it traded one runner slot for six. That
|
|
35
|
+
is the right trade for latency in isolation, and the wrong one to keep making blindly while a
|
|
36
|
+
dozen branches are in flight, because every concurrent PR now multiplies its footprint. Options,
|
|
37
|
+
roughly in increasing order of intrusiveness: a <code>concurrency</code> group that cancels
|
|
38
|
+
superseded PR runs; capping the shard matrix with <code>max-parallel</code>; or making the shard
|
|
39
|
+
count adaptive. Worth measuring before choosing — this item is the measurement, not the
|
|
40
|
+
fix.
|
|
41
|
+
|
|
42
|
+
<b>Shipped: the least intrusive one, and it turned out to be a plain omission rather than a
|
|
43
|
+
trade-off.</b> Seven workflows here already declare a <code>concurrency</code> group.
|
|
44
|
+
<code>ci.yml</code> — the largest by a wide margin, ~36 checks including six mutation
|
|
45
|
+
shards — declared none, so every push to a pull request left the whole previous run
|
|
46
|
+
executing against a commit nobody was waiting on. This session alone pushed four times to one PR,
|
|
47
|
+
which is 24 shard jobs of which 18 were already superseded.
|
|
48
|
+
|
|
49
|
+
Two things keep the release path out of it, and the second is easy to miss. The <b>condition</b>:
|
|
50
|
+
<code>cancel-in-progress: true</code> would also cancel a push to main, which
|
|
51
|
+
<code>publish.yml</code> gates the release on via <code>workflow_run</code> — a merge that
|
|
52
|
+
silently never ships — and a <code>merge_group</code> run, where a cancelled run never
|
|
53
|
+
reports its required contexts and the queue then waits forever on a status that is not coming.
|
|
54
|
+
Both evaluate false.
|
|
55
|
+
|
|
56
|
+
The <b>key</b>: non-PR events group on <code>github.sha</code>, not <code>github.ref</code>.
|
|
57
|
+
<code>cancel-in-progress: false</code> does not mean "never cancel" — it means a newer run
|
|
58
|
+
<i>waits</i>, and GitHub cancels the older <em>pending</em> run when a third arrives. Keying main
|
|
59
|
+
on its ref would put every main push in one group, so three quick merges would leave a middle
|
|
60
|
+
commit whose <code>ci</code> never completes, and since <code>publish.yml</code> fires on
|
|
61
|
+
<code>workflow_run</code> of <code>ci</code>, that commit would never release. A sha is unique per
|
|
62
|
+
commit, so main and the merge queue never share a group at all.
|
|
63
|
+
|
|
64
|
+
Both properties are pinned by tests rather than by the comment, and a separate assertion sweeps
|
|
65
|
+
every workflow that triggers on <code>merge_group</code> and fails if any cancels unconditionally
|
|
66
|
+
— so the deadlock cannot arrive later through a different file.
|
|
67
|
+
|
|
68
|
+
What this does <em>not</em> do is reduce the footprint of a single run, which is the other half of
|
|
69
|
+
the measurement. <code>max-parallel</code> on the shard matrix and an adaptive shard count are
|
|
70
|
+
still open, and both trade latency for footprint rather than removing waste — worth
|
|
71
|
+
re-measuring queue time after this lands before spending that trade.
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
id: dependabot-root-pip-entry-duplicates-requirements
|
|
3
3
|
board: code
|
|
4
4
|
section: internals
|
|
5
|
-
status:
|
|
5
|
+
status: shipped
|
|
6
6
|
category: Build · Gap
|
|
7
7
|
complexity: S
|
|
8
8
|
impact: Low
|
|
9
9
|
wow: 1
|
|
10
10
|
note: fallout from #289 — every toolchain bump now arrives twice
|
|
11
11
|
order: 35
|
|
12
|
-
owner:
|
|
13
|
-
pr:
|
|
12
|
+
owner: loop/dependabot-root-narrow
|
|
13
|
+
pr: 349
|
|
14
14
|
title: Dependabot raises every toolchain bump <em>twice</em>
|
|
15
15
|
---
|
|
16
16
|
PR #289 added a third Dependabot entry, <code>package-ecosystem: pip</code> with
|
|
@@ -43,3 +43,24 @@ Dependabot's file discovery is what got this wrong in the first place. <b>First<
|
|
|
43
43
|
extras bumps are genuinely wanted, that needs <code>versioning-strategy: increase</code> so open
|
|
44
44
|
lower bounds are raised at all; otherwise accept that this entry is security-only and say so in the
|
|
45
45
|
comment, which is the honest smaller change.
|
|
46
|
+
|
|
47
|
+
<b>Shipped — the second one, and <code>#342</code> changed why.</b> That change gave
|
|
48
|
+
<code>/requirements</code> <code>open-pull-requests-limit: 0</code>, which silences the duplicate on
|
|
49
|
+
one side but leaves the <code>/</code> entry as the <em>only</em> remaining path to a
|
|
50
|
+
lock-regenerating pull request — precisely the thing that cannot be done correctly on a single
|
|
51
|
+
platform. The duplicate stopped being the problem and the survivor became one.
|
|
52
|
+
|
|
53
|
+
So the version-update side of the <code>/</code> entry is off too, and the reasoning is now written
|
|
54
|
+
where the next person will look. It produces nothing wanted: every constraint under
|
|
55
|
+
<code>[project.optional-dependencies]</code> is an open lower bound or sits in the entry's own
|
|
56
|
+
ignore list, so its set of possible <code>pyproject.toml</code> version updates is <b>empty</b>
|
|
57
|
+
— none of the eight PRs in that first run touched it. And it produces one thing actively
|
|
58
|
+
harmful: four of those eight were byte-identical lock regenerations. <b>Security</b> updates ignore
|
|
59
|
+
the limit and keep firing, which is the coverage the extras genuinely gained, and
|
|
60
|
+
<code>lock_toolchain.py --audit</code> now catches a security PR that arrives having dropped a
|
|
61
|
+
marker-gated pin.
|
|
62
|
+
|
|
63
|
+
Both pip entries are pinned at <code>limit: 0</code> by
|
|
64
|
+
<code>tests/unit/test_dependabot_config.py</code>, alongside an assertion that neither entry is
|
|
65
|
+
<em>deleted</em> — removing them would give up the security coverage that is the whole
|
|
66
|
+
remaining point. Related: [[dependabot-regeneration-drops-platform-pins]].
|
|
@@ -1162,7 +1162,7 @@ every enabled agent. So narrowing is honoured and the newly-enabled-agent path i
|
|
|
1162
1162
|
</article>
|
|
1163
1163
|
|
|
1164
1164
|
<article class="cap rcard" id="dependabot-root-pip-entry-duplicates-requirements">
|
|
1165
|
-
<div class="head"><span class="pill
|
|
1165
|
+
<div class="head"><span class="pill shipped">Shipped</span><span class="cat">Build · Gap</span></div>
|
|
1166
1166
|
<h3>Dependabot raises every toolchain bump <em>twice</em></h3>
|
|
1167
1167
|
<p>PR #289 added a third Dependabot entry, <code>package-ecosystem: pip</code> with
|
|
1168
1168
|
<code>directory: /</code>, to give <code>pyproject.toml</code>'s optional extras the proactive bump
|
|
@@ -1193,7 +1193,28 @@ Dependabot's file discovery is what got this wrong in the first place. <b>First<
|
|
|
1193
1193
|
<code>/requirements</code> as the single owner of the hash-pinned lock. <b>Second</b>, if proactive
|
|
1194
1194
|
extras bumps are genuinely wanted, that needs <code>versioning-strategy: increase</code> so open
|
|
1195
1195
|
lower bounds are raised at all; otherwise accept that this entry is security-only and say so in the
|
|
1196
|
-
comment, which is the honest smaller change
|
|
1196
|
+
comment, which is the honest smaller change.
|
|
1197
|
+
|
|
1198
|
+
<b>Shipped — the second one, and <code>#342</code> changed why.</b> That change gave
|
|
1199
|
+
<code>/requirements</code> <code>open-pull-requests-limit: 0</code>, which silences the duplicate on
|
|
1200
|
+
one side but leaves the <code>/</code> entry as the <em>only</em> remaining path to a
|
|
1201
|
+
lock-regenerating pull request — precisely the thing that cannot be done correctly on a single
|
|
1202
|
+
platform. The duplicate stopped being the problem and the survivor became one.
|
|
1203
|
+
|
|
1204
|
+
So the version-update side of the <code>/</code> entry is off too, and the reasoning is now written
|
|
1205
|
+
where the next person will look. It produces nothing wanted: every constraint under
|
|
1206
|
+
<code>[project.optional-dependencies]</code> is an open lower bound or sits in the entry's own
|
|
1207
|
+
ignore list, so its set of possible <code>pyproject.toml</code> version updates is <b>empty</b>
|
|
1208
|
+
— none of the eight PRs in that first run touched it. And it produces one thing actively
|
|
1209
|
+
harmful: four of those eight were byte-identical lock regenerations. <b>Security</b> updates ignore
|
|
1210
|
+
the limit and keep firing, which is the coverage the extras genuinely gained, and
|
|
1211
|
+
<code>lock_toolchain.py --audit</code> now catches a security PR that arrives having dropped a
|
|
1212
|
+
marker-gated pin.
|
|
1213
|
+
|
|
1214
|
+
Both pip entries are pinned at <code>limit: 0</code> by
|
|
1215
|
+
<code>tests/unit/test_dependabot_config.py</code>, alongside an assertion that neither entry is
|
|
1216
|
+
<em>deleted</em> — removing them would give up the security coverage that is the whole
|
|
1217
|
+
remaining point. Related: [[dependabot-regeneration-drops-platform-pins]].</p>
|
|
1197
1218
|
<div class="meta">
|
|
1198
1219
|
<span class="m">Complexity <b>S</b></span>
|
|
1199
1220
|
<span class="m">Impact <b>Low</b></span>
|
|
@@ -2602,7 +2623,7 @@ missing file is now imputed at the measured mean rate, which keeps every weight
|
|
|
2602
2623
|
</article>
|
|
2603
2624
|
|
|
2604
2625
|
<article class="cap rcard" id="ci-time-is-now-runner-queueing">
|
|
2605
|
-
<div class="head"><span class="pill
|
|
2626
|
+
<div class="head"><span class="pill shipped">Shipped</span><span class="cat">CI speed</span></div>
|
|
2606
2627
|
<h3>A third of CI job time is spent waiting for a runner, not running</h3>
|
|
2607
2628
|
<p>With the mutation gate no longer dominating, the largest remaining term in CI wall clock is
|
|
2608
2629
|
<b>queueing</b>. Measured over six consecutive successful <code>ci</code> runs: <b>104
|
|
@@ -2628,7 +2649,38 @@ dozen branches are in flight, because every concurrent PR now multiplies its foo
|
|
|
2628
2649
|
roughly in increasing order of intrusiveness: a <code>concurrency</code> group that cancels
|
|
2629
2650
|
superseded PR runs; capping the shard matrix with <code>max-parallel</code>; or making the shard
|
|
2630
2651
|
count adaptive. Worth measuring before choosing — this item is the measurement, not the
|
|
2631
|
-
fix
|
|
2652
|
+
fix.
|
|
2653
|
+
|
|
2654
|
+
<b>Shipped: the least intrusive one, and it turned out to be a plain omission rather than a
|
|
2655
|
+
trade-off.</b> Seven workflows here already declare a <code>concurrency</code> group.
|
|
2656
|
+
<code>ci.yml</code> — the largest by a wide margin, ~36 checks including six mutation
|
|
2657
|
+
shards — declared none, so every push to a pull request left the whole previous run
|
|
2658
|
+
executing against a commit nobody was waiting on. This session alone pushed four times to one PR,
|
|
2659
|
+
which is 24 shard jobs of which 18 were already superseded.
|
|
2660
|
+
|
|
2661
|
+
Two things keep the release path out of it, and the second is easy to miss. The <b>condition</b>:
|
|
2662
|
+
<code>cancel-in-progress: true</code> would also cancel a push to main, which
|
|
2663
|
+
<code>publish.yml</code> gates the release on via <code>workflow_run</code> — a merge that
|
|
2664
|
+
silently never ships — and a <code>merge_group</code> run, where a cancelled run never
|
|
2665
|
+
reports its required contexts and the queue then waits forever on a status that is not coming.
|
|
2666
|
+
Both evaluate false.
|
|
2667
|
+
|
|
2668
|
+
The <b>key</b>: non-PR events group on <code>github.sha</code>, not <code>github.ref</code>.
|
|
2669
|
+
<code>cancel-in-progress: false</code> does not mean "never cancel" — it means a newer run
|
|
2670
|
+
<i>waits</i>, and GitHub cancels the older <em>pending</em> run when a third arrives. Keying main
|
|
2671
|
+
on its ref would put every main push in one group, so three quick merges would leave a middle
|
|
2672
|
+
commit whose <code>ci</code> never completes, and since <code>publish.yml</code> fires on
|
|
2673
|
+
<code>workflow_run</code> of <code>ci</code>, that commit would never release. A sha is unique per
|
|
2674
|
+
commit, so main and the merge queue never share a group at all.
|
|
2675
|
+
|
|
2676
|
+
Both properties are pinned by tests rather than by the comment, and a separate assertion sweeps
|
|
2677
|
+
every workflow that triggers on <code>merge_group</code> and fails if any cancels unconditionally
|
|
2678
|
+
— so the deadlock cannot arrive later through a different file.
|
|
2679
|
+
|
|
2680
|
+
What this does <em>not</em> do is reduce the footprint of a single run, which is the other half of
|
|
2681
|
+
the measurement. <code>max-parallel</code> on the shard matrix and an adaptive shard count are
|
|
2682
|
+
still open, and both trade latency for footprint rather than removing waste — worth
|
|
2683
|
+
re-measuring queue time after this lands before spending that trade.</p>
|
|
2632
2684
|
<div class="meta">
|
|
2633
2685
|
<span class="m">Complexity <b>M</b></span>
|
|
2634
2686
|
<span class="m hi">Impact <b>High</b></span>
|
|
@@ -104,3 +104,61 @@ def test_the_root_ignore_list_matches_the_ceilings_pyproject_sets():
|
|
|
104
104
|
for reqs in extras.values() for req in reqs if "<" in req}
|
|
105
105
|
assert held_back, "no upper bounds left in pyproject — drop the ignores"
|
|
106
106
|
assert set(pip_entry("/")[2]) == held_back
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def limit_for(directory: str):
|
|
110
|
+
"""The `open-pull-requests-limit` of the pip entry for `directory`, or None.
|
|
111
|
+
|
|
112
|
+
Parsed separately rather than by widening `entries()`, which several tests
|
|
113
|
+
unpack positionally.
|
|
114
|
+
"""
|
|
115
|
+
seen = None
|
|
116
|
+
for line in CONFIG.read_text(encoding="utf-8").splitlines():
|
|
117
|
+
m = _ENTRY.match(line)
|
|
118
|
+
if m:
|
|
119
|
+
seen = {"eco": m.group(1)}
|
|
120
|
+
continue
|
|
121
|
+
if seen is None:
|
|
122
|
+
continue
|
|
123
|
+
m = _FIELD.match(line)
|
|
124
|
+
if not m:
|
|
125
|
+
continue
|
|
126
|
+
seen[m.group(1)] = m.group(2)
|
|
127
|
+
if seen.get("directory") == directory and seen["eco"] == "pip" \
|
|
128
|
+
and "open-pull-requests-limit" in seen:
|
|
129
|
+
return int(seen["open-pull-requests-limit"])
|
|
130
|
+
return None
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class TestNeitherPipEntryRegeneratesTheLock:
|
|
134
|
+
"""Dependabot must not raise *version* updates for either pip entry.
|
|
135
|
+
|
|
136
|
+
Not a preference — it cannot regenerate the hash-pinned locks correctly. It
|
|
137
|
+
re-resolves on Linux and commits that resolution, dropping every pin whose
|
|
138
|
+
environment marker excludes it there, and the locks install with
|
|
139
|
+
--require-hashes on Windows and macOS too. `scripts/lock_toolchain.py`
|
|
140
|
+
resolves --universal for every supported platform, which is why it is the
|
|
141
|
+
source of truth (see its `-P` flag, and requirements/platform-pins.lock).
|
|
142
|
+
|
|
143
|
+
`open-pull-requests-limit: 0` disables version updates while leaving
|
|
144
|
+
**security** updates firing, which is what these entries are actually worth.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
def test_the_requirements_entry_raises_no_version_prs(self):
|
|
148
|
+
assert limit_for("/requirements") == 0
|
|
149
|
+
|
|
150
|
+
def test_the_root_entry_raises_no_version_prs(self):
|
|
151
|
+
# The root entry cannot deliver what it was added for: every constraint
|
|
152
|
+
# under [project.optional-dependencies] is either an open lower bound or
|
|
153
|
+
# in its own ignore list, so the set of pyproject version updates it can
|
|
154
|
+
# ever produce is EMPTY — none of the eight PRs in the first scheduled
|
|
155
|
+
# run touched pyproject.toml. What it did produce was byte-identical
|
|
156
|
+
# duplicates of the /requirements entry's lock regenerations, which is
|
|
157
|
+
# the one thing that must never be merged.
|
|
158
|
+
assert limit_for("/") == 0
|
|
159
|
+
|
|
160
|
+
def test_both_pip_entries_still_exist(self):
|
|
161
|
+
# Deleting them would give up security updates too, which ignore the
|
|
162
|
+
# limit and are the coverage these entries genuinely provide.
|
|
163
|
+
assert pip_entry("/requirements")
|
|
164
|
+
assert pip_entry("/")
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""Unit tests: superseded PR runs are cancelled, releases never are.
|
|
2
|
+
|
|
3
|
+
Measured over six consecutive successful ``ci`` runs, **31%** of all job time
|
|
4
|
+
was spent queueing rather than executing (104 job-minutes against 236). The
|
|
5
|
+
median per-job queue swung 29x between runs — 0.1 min when the repo was quiet,
|
|
6
|
+
2.9 min when a dozen ``loop/*`` branches and Dependabot PRs were live — so the
|
|
7
|
+
cost is driven by concurrent footprint, not by the change under test. Sharding
|
|
8
|
+
the mutation gate traded one runner slot for six and made that worse on purpose.
|
|
9
|
+
|
|
10
|
+
``ci.yml`` is the largest workflow in the repo by a wide margin, and it was the
|
|
11
|
+
only one with no ``concurrency`` group at all: every push to a pull request left
|
|
12
|
+
the previous run's ~36 checks (six of them mutation shards) running to
|
|
13
|
+
completion against nothing.
|
|
14
|
+
|
|
15
|
+
The dangerous half of the fix is the half these tests pin. Cancelling a
|
|
16
|
+
**pull_request** run that a newer push superseded costs nothing. Cancelling a
|
|
17
|
+
**push to main** would abandon the run ``publish.yml`` gates the release on, and
|
|
18
|
+
cancelling a **merge_group** run would leave a required check permanently
|
|
19
|
+
unreported and deadlock the queue — the exact failure mode ci.yml's own comments
|
|
20
|
+
describe. So cancellation must be conditional on the event, and that condition
|
|
21
|
+
is what a future edit is most likely to get wrong.
|
|
22
|
+
"""
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import re
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
|
|
28
|
+
import pytest
|
|
29
|
+
|
|
30
|
+
WORKFLOWS = Path(__file__).resolve().parents[2] / ".github" / "workflows"
|
|
31
|
+
CI = WORKFLOWS / "ci.yml"
|
|
32
|
+
|
|
33
|
+
pytestmark = pytest.mark.skipif(
|
|
34
|
+
not CI.exists(),
|
|
35
|
+
reason=".github/workflows not reachable (e.g. mutation sandbox)")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def concurrency_block(path: Path) -> str:
|
|
39
|
+
"""The top-level ``concurrency:`` mapping of a workflow, or ''.
|
|
40
|
+
|
|
41
|
+
Top-level only: a job-level block is indented and must not be mistaken for
|
|
42
|
+
the workflow's own policy.
|
|
43
|
+
"""
|
|
44
|
+
text = path.read_text(encoding="utf-8")
|
|
45
|
+
m = re.search(r"^concurrency:\s*$\n((?:^[ \t]+\S.*\n|^\s*#.*\n)*)", text, re.M)
|
|
46
|
+
return m.group(1) if m else ""
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class TestCiCancelsSupersededRuns:
|
|
50
|
+
def test_ci_declares_a_concurrency_group(self):
|
|
51
|
+
assert concurrency_block(CI), \
|
|
52
|
+
"ci.yml is the biggest workflow here; without a concurrency group " \
|
|
53
|
+
"every superseded push keeps ~36 checks running against nothing"
|
|
54
|
+
|
|
55
|
+
def test_the_group_is_per_pull_request(self):
|
|
56
|
+
# Keyed on the PR number so two PRs never cancel each other.
|
|
57
|
+
assert "github.event.pull_request.number" in concurrency_block(CI)
|
|
58
|
+
|
|
59
|
+
def test_non_pr_events_group_on_the_commit_not_the_ref(self):
|
|
60
|
+
# THE SUBTLE ONE. `cancel-in-progress: false` does not mean "never
|
|
61
|
+
# cancel" — it means a newer run waits, and GitHub cancels the older
|
|
62
|
+
# *pending* run when a third arrives. Keying main on `github.ref` puts
|
|
63
|
+
# every main push in one group, so three quick merges would leave a
|
|
64
|
+
# middle commit whose ci never completes; publish.yml fires on
|
|
65
|
+
# `workflow_run` of ci, so that commit would never release. A sha is
|
|
66
|
+
# unique per commit, so main and the merge queue never share a group.
|
|
67
|
+
block = concurrency_block(CI)
|
|
68
|
+
assert "github.sha" in block, block
|
|
69
|
+
assert "github.ref" not in block, \
|
|
70
|
+
"grouping non-PR runs on the ref can strand a main commit unreleased"
|
|
71
|
+
|
|
72
|
+
def test_cancellation_is_conditional_not_unconditional(self):
|
|
73
|
+
# `cancel-in-progress: true` would cancel main and merge_group runs too.
|
|
74
|
+
block = concurrency_block(CI)
|
|
75
|
+
m = re.search(r"cancel-in-progress:\s*(.+)", block)
|
|
76
|
+
assert m, "no cancel-in-progress in %r" % block
|
|
77
|
+
value = m.group(1).strip()
|
|
78
|
+
assert value not in ("true", "'true'", '"true"'), \
|
|
79
|
+
"unconditional cancel would abandon the run publish.yml gates on"
|
|
80
|
+
assert "pull_request" in value, value
|
|
81
|
+
|
|
82
|
+
def test_only_pull_request_events_are_cancelled(self):
|
|
83
|
+
# The whole safety property in one assertion: the guard names
|
|
84
|
+
# pull_request, so push-to-main and merge_group evaluate false.
|
|
85
|
+
value = re.search(r"cancel-in-progress:\s*(.+)",
|
|
86
|
+
concurrency_block(CI)).group(1)
|
|
87
|
+
assert "github.event_name == 'pull_request'" in value, value
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class TestReleasePathIsNeverCancelled:
|
|
91
|
+
def test_publish_does_not_cancel_in_progress(self):
|
|
92
|
+
# Every merge to main cuts a PyPI release; cancelling a release run
|
|
93
|
+
# mid-upload is how you get a tagged version that never shipped.
|
|
94
|
+
block = concurrency_block(WORKFLOWS / "publish.yml")
|
|
95
|
+
assert "cancel-in-progress: false" in block, block
|
|
96
|
+
|
|
97
|
+
def test_no_workflow_cancels_a_merge_group_run(self):
|
|
98
|
+
# A required context whose run is cancelled never reports, and the
|
|
99
|
+
# merge queue waits on it forever. Any workflow that both triggers on
|
|
100
|
+
# merge_group and cancels unconditionally is that deadlock waiting to
|
|
101
|
+
# happen.
|
|
102
|
+
offenders = []
|
|
103
|
+
for path in sorted(WORKFLOWS.glob("*.yml")):
|
|
104
|
+
text = path.read_text(encoding="utf-8")
|
|
105
|
+
if not re.search(r"^\s*merge_group:", text, re.M):
|
|
106
|
+
continue
|
|
107
|
+
block = concurrency_block(path)
|
|
108
|
+
if re.search(r"cancel-in-progress:\s*true\s*$", block, re.M):
|
|
109
|
+
offenders.append(path.name)
|
|
110
|
+
assert not offenders, \
|
|
111
|
+
"these cancel merge_group runs and would deadlock the queue: %s" \
|
|
112
|
+
% ", ".join(offenders)
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: ci-time-is-now-runner-queueing
|
|
3
|
-
board: code
|
|
4
|
-
section: pipeline
|
|
5
|
-
status: planned
|
|
6
|
-
category: CI speed
|
|
7
|
-
complexity: M
|
|
8
|
-
impact: High
|
|
9
|
-
wow: 4
|
|
10
|
-
note: 104 job-min queued vs 236 executing — 31% of CI is waiting for a runner
|
|
11
|
-
order: 62
|
|
12
|
-
owner:
|
|
13
|
-
pr:
|
|
14
|
-
title: A third of CI job time is spent waiting for a runner, not running
|
|
15
|
-
---
|
|
16
|
-
With the mutation gate no longer dominating, the largest remaining term in CI wall clock is
|
|
17
|
-
<b>queueing</b>. Measured over six consecutive successful <code>ci</code> runs: <b>104
|
|
18
|
-
job-minutes queued</b> against <b>236 job-minutes executing</b> — <b>31%</b> of all job
|
|
19
|
-
time spent waiting for a runner.
|
|
20
|
-
|
|
21
|
-
<b>The obvious metric lies.</b> A run's <code>run_started_at</code> minus
|
|
22
|
-
<code>created_at</code> is <b>0.0 for every run</b>, which reads as "no queueing anywhere".
|
|
23
|
-
Queueing happens per <em>job</em>, not per run, so it is only visible as
|
|
24
|
-
<code>job.started_at - job.created_at</code>. Anything measuring this at run level will
|
|
25
|
-
conclude, wrongly, that there is nothing to fix.
|
|
26
|
-
|
|
27
|
-
The per-run spread shows what drives it — median job queue by run:
|
|
28
|
-
<code>c36c53a7</code> 0.1 min, <code>c15ed9da</code> 0.1, <code>903b704f</code> 0.2,
|
|
29
|
-
<code>638bffeb</code> 0.7, <code>ad71ba99</code> <b>2.5</b>, <code>9e190537</code> <b>2.9</b>.
|
|
30
|
-
That is a 29× swing driven not by the change under test but by how many sibling
|
|
31
|
-
<code>loop/*</code> branches and Dependabot PRs happen to be live at the same moment. It is why
|
|
32
|
-
one merge took <b>41 minutes</b> wall clock with a max shard of only 11.4.
|
|
33
|
-
|
|
34
|
-
Sharding the mutation gate made this worse on purpose: it traded one runner slot for six. That
|
|
35
|
-
is the right trade for latency in isolation, and the wrong one to keep making blindly while a
|
|
36
|
-
dozen branches are in flight, because every concurrent PR now multiplies its footprint. Options,
|
|
37
|
-
roughly in increasing order of intrusiveness: a <code>concurrency</code> group that cancels
|
|
38
|
-
superseded PR runs; capping the shard matrix with <code>max-parallel</code>; or making the shard
|
|
39
|
-
count adaptive. Worth measuring before choosing — this item is the measurement, not the
|
|
40
|
-
fix.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|