kanon-cli 3.3.0__tar.gz → 3.3.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1035) hide show
  1. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.github/actions/setup-kanon/action.yml +36 -32
  2. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.github/workflows/main-validation.yml +28 -27
  3. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.github/workflows/pr-validation.yml +9 -12
  4. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.github/workflows/publish.yml +8 -9
  5. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.gitignore +3 -0
  6. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.tool-versions +1 -0
  7. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/CHANGELOG.md +353 -0
  8. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/CONTRIBUTING.md +6 -0
  9. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/Makefile +21 -14
  10. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/PKG-INFO +8 -2
  11. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/README.md +6 -0
  12. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/integration-testing.md +191 -0
  13. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/testing/matrix-traceability.md +2 -2
  14. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/git-hooks/pre-push +5 -5
  15. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/pyproject.toml +20 -2
  16. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/__init__.py +1 -1
  17. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/install.py +0 -59
  18. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/marketplace.py +5 -3
  19. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/marketplace_validator.py +210 -30
  20. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/progress.py +2 -2
  21. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/project.py +1 -1
  22. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/conftest.py +55 -0
  23. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_validate_marketplace.py +50 -5
  24. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_ci_validation.py +17 -10
  25. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_clean_lifecycle.py +12 -7
  26. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_full_lifecycle_synthetic.py +8 -3
  27. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_after_add.py +5 -1
  28. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_marketplace_registration.py +90 -19
  29. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_marketplace_orphan_prune.py +19 -6
  30. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_validate_marketplace.py +10 -5
  31. kanon_cli-3.3.3/tests/regression/test_linkfile_samefile_regression.py +233 -0
  32. kanon_cli-3.3.3/tests/scenarios/test_et.py +445 -0
  33. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_marketplace_direct_checkout.py +7 -8
  34. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_medium_files_boost.py +31 -27
  35. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_progress.py +35 -8
  36. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_ci_workflows.py +115 -38
  37. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_marketplace_validator.py +223 -10
  38. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_pre_push_hook.py +8 -5
  39. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_pyproject_build_config.py +42 -0
  40. kanon_cli-3.3.3/tests/unit/test_toolchain_isolation.py +243 -0
  41. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/uv.lock +876 -2
  42. kanon_cli-3.3.0/requirements-dev.txt +0 -11
  43. kanon_cli-3.3.0/requirements.txt +0 -1
  44. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.claude/settings.json +0 -0
  45. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/.devcontainer.postcreate.sh +0 -0
  46. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/VERSION +0 -0
  47. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/catalog-entry.json +0 -0
  48. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/devcontainer-functions.sh +0 -0
  49. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/devcontainer.json +0 -0
  50. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/fix-line-endings.py +0 -0
  51. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/nix-family-os/README.md +0 -0
  52. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/nix-family-os/tinyproxy-daemon.sh +0 -0
  53. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/nix-family-os/tinyproxy.conf.template +0 -0
  54. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/postcreate-wrapper.sh +0 -0
  55. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/project-setup.sh +0 -0
  56. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/wsl-family-os/README.md +0 -0
  57. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/wsl-family-os/tinyproxy-daemon.sh +0 -0
  58. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.devcontainer/wsl-family-os/tinyproxy.conf.template +0 -0
  59. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.github/CODEOWNERS +0 -0
  60. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.github/workflows/codeql-analysis.yml +0 -0
  61. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.markdownlint.json +0 -0
  62. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.pre-commit-config.yaml +0 -0
  63. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/.yamllint +0 -0
  64. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/CLAUDE.md +0 -0
  65. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/LICENSE +0 -0
  66. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/architecture.md +0 -0
  67. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/catalog-author-guide.md +0 -0
  68. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/catalog-format-versioning.md +0 -0
  69. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/catalogs-explained.md +0 -0
  70. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/claude-marketplaces-guide.md +0 -0
  71. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/cli/catalog-audit.md +0 -0
  72. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/cli/doctor.md +0 -0
  73. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/cli/validate.md +0 -0
  74. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/cli-reference.md +0 -0
  75. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/cli.md +0 -0
  76. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/coming-from-pip-npm-cargo.md +0 -0
  77. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/configuration.md +0 -0
  78. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/contributing.md +0 -0
  79. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/creating-manifest-repos.md +0 -0
  80. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/creating-packages.md +0 -0
  81. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/doctor.md +0 -0
  82. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/exit-codes.md +0 -0
  83. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/git-auth-setup.md +0 -0
  84. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/how-it-works.md +0 -0
  85. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/installation.md +0 -0
  86. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/lifecycle.md +0 -0
  87. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/list-and-add.md +0 -0
  88. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/lockfile.md +0 -0
  89. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/migrating-existing-kanon-files.md +0 -0
  90. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/migration-to-add.md +0 -0
  91. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/multi-source-guide.md +0 -0
  92. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/outdated-and-why.md +0 -0
  93. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/pipeline-integration.md +0 -0
  94. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/privacy.md +0 -0
  95. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/repo/README.md +0 -0
  96. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/repo/internal-fs-layout.md +0 -0
  97. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/repo/manifest-format.md +0 -0
  98. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/repo/python-support.md +0 -0
  99. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/repo/repo-hooks.md +0 -0
  100. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/repo/smart-sync.md +0 -0
  101. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/repo/windows.md +0 -0
  102. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/security-model.md +0 -0
  103. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/setup-guide.md +0 -0
  104. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/shell-completion.md +0 -0
  105. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/test-coverage.md +0 -0
  106. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/troubleshooting.md +0 -0
  107. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/url-canonicalization.md +0 -0
  108. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/docs/version-resolution.md +0 -0
  109. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/git-hooks/pre-commit +0 -0
  110. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/link +0 -0
  111. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/scripts/check_archive_no_duplicates.py +0 -0
  112. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/__main__.py +0 -0
  113. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/cli.py +0 -0
  114. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/__init__.py +0 -0
  115. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/add.py +0 -0
  116. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/catalog.py +0 -0
  117. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/clean.py +0 -0
  118. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/completion.py +0 -0
  119. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/doctor.py +0 -0
  120. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/install.py +0 -0
  121. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/list.py +0 -0
  122. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/marketplace.py +0 -0
  123. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/outdated.py +0 -0
  124. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/remove.py +0 -0
  125. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/repo.py +0 -0
  126. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/search.py +0 -0
  127. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/validate.py +0 -0
  128. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/commands/why.py +0 -0
  129. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/__init__.py +0 -0
  130. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/cache.py +0 -0
  131. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/cached_catalogs.py +0 -0
  132. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/catalog_entries.py +0 -0
  133. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/catalog_versions.py +0 -0
  134. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/lockfile_names.py +0 -0
  135. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/midtoken.py +0 -0
  136. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/pep440_filter.py +0 -0
  137. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/powershell.py +0 -0
  138. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/preamble.py +0 -0
  139. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/project_versions.py +0 -0
  140. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/sanitize.py +0 -0
  141. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/completions/source_names.py +0 -0
  142. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/constants.py +0 -0
  143. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/__init__.py +0 -0
  144. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/catalog.py +0 -0
  145. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/clean.py +0 -0
  146. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/cli_args.py +0 -0
  147. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/discover.py +0 -0
  148. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/git_runner.py +0 -0
  149. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/include_walker.py +0 -0
  150. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/kanon_hash.py +0 -0
  151. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/kanonenv.py +0 -0
  152. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/kanonenv_writer.py +0 -0
  153. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/lockfile.py +0 -0
  154. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/manifest.py +0 -0
  155. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/manifest_vars.py +0 -0
  156. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/metadata.py +0 -0
  157. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/remote_url.py +0 -0
  158. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/telemetry.py +0 -0
  159. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/update_check.py +0 -0
  160. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/url.py +0 -0
  161. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/core/xml_validator.py +0 -0
  162. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/__init__.py +0 -0
  163. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/color.py +0 -0
  164. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/command.py +0 -0
  165. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/editor.py +0 -0
  166. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/error.py +0 -0
  167. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/event_log.py +0 -0
  168. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/fetch.py +0 -0
  169. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/git_command.py +0 -0
  170. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/git_config.py +0 -0
  171. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/git_refs.py +0 -0
  172. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/git_ssh +0 -0
  173. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/git_superproject.py +0 -0
  174. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/git_trace2_event_log.py +0 -0
  175. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/git_trace2_event_log_base.py +0 -0
  176. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/hooks/commit-msg +0 -0
  177. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/hooks/pre-auto-gc +0 -0
  178. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/hooks.py +0 -0
  179. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/main.py +0 -0
  180. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/manifest_xml.py +0 -0
  181. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/pager.py +0 -0
  182. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/platform_utils.py +0 -0
  183. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/platform_utils_win32.py +0 -0
  184. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/repo +0 -0
  185. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/repo_logging.py +0 -0
  186. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/repo_trace.py +0 -0
  187. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/requirements.jsonc +0 -0
  188. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/ssh.py +0 -0
  189. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/__init__.py +0 -0
  190. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/abandon.py +0 -0
  191. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/branches.py +0 -0
  192. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/checkout.py +0 -0
  193. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/cherry_pick.py +0 -0
  194. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/diff.py +0 -0
  195. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/diffmanifests.py +0 -0
  196. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/download.py +0 -0
  197. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/envsubst.py +0 -0
  198. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/forall.py +0 -0
  199. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/gc.py +0 -0
  200. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/grep.py +0 -0
  201. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/help.py +0 -0
  202. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/info.py +0 -0
  203. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/init.py +0 -0
  204. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/list.py +0 -0
  205. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/manifest.py +0 -0
  206. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/overview.py +0 -0
  207. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/prune.py +0 -0
  208. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/rebase.py +0 -0
  209. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/selfupdate.py +0 -0
  210. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/smartsync.py +0 -0
  211. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/stage.py +0 -0
  212. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/start.py +0 -0
  213. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/status.py +0 -0
  214. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/sync.py +0 -0
  215. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/subcmds/upload.py +0 -0
  216. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/version_constraints.py +0 -0
  217. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/repo/wrapper.py +0 -0
  218. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/utils/__init__.py +0 -0
  219. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/utils/concurrency.py +0 -0
  220. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/utils/levenshtein.py +0 -0
  221. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/utils/lock_file_path.py +0 -0
  222. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/utils/spawn.py +0 -0
  223. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/src/kanon_cli/version.py +0 -0
  224. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/__init__.py +0 -0
  225. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/duplicate-child-marketplace.xml +0 -0
  226. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/missing-recommended-marketplace.xml +0 -0
  227. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/missing-required-marketplace.xml +0 -0
  228. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-1/repo-specs/multiple-blocks-marketplace.xml +0 -0
  229. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-2/repo-specs/dotted-name-marketplace.xml +0 -0
  230. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-2/repo-specs/hyphenated-name-marketplace.xml +0 -0
  231. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-2/repo-specs/uppercase-name-marketplace.xml +0 -0
  232. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-a-1-marketplace.xml +0 -0
  233. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-a-2-marketplace.xml +0 -0
  234. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-b-1-marketplace.xml +0 -0
  235. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-3/repo-specs/group-b-2-marketplace.xml +0 -0
  236. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-4/repo-specs/file-url-marketplace.xml +0 -0
  237. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-4/repo-specs/query-string-marketplace.xml +0 -0
  238. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/broken-soft-spot-4/repo-specs/unresolvable-marketplace.xml +0 -0
  239. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/legacy-catalog-dir/catalog/sample-entry/.kanon +0 -0
  240. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalog/legacy-catalog-dir/repo-specs/sample.xml +0 -0
  241. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalogs/zero-pep440-tags/README.md +0 -0
  242. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/catalogs/zero-pep440-tags/repo-specs/entry-a/entry-a-marketplace.xml +0 -0
  243. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/completion/__init__.py +0 -0
  244. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/completion/expected-bash.sh +0 -0
  245. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/completion/expected-powershell.ps1 +0 -0
  246. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/completion/expected-zsh.sh +0 -0
  247. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/errors/README.md +0 -0
  248. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/errors/conflict-detected.txt +0 -0
  249. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/errors/entry-not-found.txt +0 -0
  250. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/errors/lockfile-hash-mismatch.txt +0 -0
  251. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/errors/lockfile-sha-unreachable.txt +0 -0
  252. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/errors/missing-catalog-source.txt +0 -0
  253. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/errors/missing-required-metadata-field.txt +0 -0
  254. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/errors/source-collision.txt +0 -0
  255. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/errors/zero-pep440-tags-under-prefix.txt +0 -0
  256. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/README.md +0 -0
  257. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-add.txt +0 -0
  258. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-catalog-audit.txt +0 -0
  259. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-catalog.txt +0 -0
  260. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-clean.txt +0 -0
  261. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-completion.txt +0 -0
  262. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-doctor.txt +0 -0
  263. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-install.txt +0 -0
  264. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-list.txt +0 -0
  265. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-marketplace.txt +0 -0
  266. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-outdated.txt +0 -0
  267. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-remove.txt +0 -0
  268. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-search.txt +0 -0
  269. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-toplevel.txt +0 -0
  270. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/help/kanon-why.txt +0 -0
  271. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/repo/.gitignore +0 -0
  272. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/repo/README.md +0 -0
  273. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/repo/linter-test-bad.invalid-yaml +0 -0
  274. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/repo/linter-test-bad.md +0 -0
  275. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/repo/linter-test-bad.py +0 -0
  276. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/repo/sample-manifest.xml +0 -0
  277. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/repo/sample-project-config.json +0 -0
  278. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/repo/test.gitconfig +0 -0
  279. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/fixtures/repo/version_constraints_data.json +0 -0
  280. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/__init__.py +0 -0
  281. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/conftest.py +0 -0
  282. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_add_alias_journey.py +0 -0
  283. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_alias_consumer_journey.py +0 -0
  284. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_argparse_errors.py +0 -0
  285. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_argparse_help.py +0 -0
  286. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_ci_runs_operator_path_tests.py +0 -0
  287. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_clean_lifecycle.py +0 -0
  288. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_cli_entry_point.py +0 -0
  289. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_completion_snapshots.py +0 -0
  290. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_default_branch_journey.py +0 -0
  291. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_env_int_guard_journey.py +0 -0
  292. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_error_snapshots.py +0 -0
  293. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_exit_code_matrix.py +0 -0
  294. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_groups_filter.py +0 -0
  295. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_help_snapshots.py +0 -0
  296. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_help_text_contract.py +0 -0
  297. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_home_flag_unwritable_journey.py +0 -0
  298. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_init_default_branch_prerequisite_journey.py +0 -0
  299. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_install_hermetic_journey.py +0 -0
  300. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_install_lifecycle.py +0 -0
  301. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_install_real_kanon.py +0 -0
  302. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_install_v3_lock_fail_fast_journey.py +0 -0
  303. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_kanon_home_store_journey.py +0 -0
  304. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_kanon_repo_cli.py +0 -0
  305. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_kanon_repo_e2e.py +0 -0
  306. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_kanon_repo_lifecycle_journey.py +0 -0
  307. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_lifecycle_journey.py +0 -0
  308. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_list.py +0 -0
  309. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_list_telemetry.py +0 -0
  310. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_make_operator_path_targets.py +0 -0
  311. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_marketplace_journey.py +0 -0
  312. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_matrix_traceability_complete.py +0 -0
  313. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_provider_agnostic.py +0 -0
  314. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_abandon_errors.py +0 -0
  315. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_abandon_flags.py +0 -0
  316. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_abandon_happy.py +0 -0
  317. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_branches_errors.py +0 -0
  318. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_branches_flags.py +0 -0
  319. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_branches_happy.py +0 -0
  320. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_checkout_errors.py +0 -0
  321. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_checkout_flags.py +0 -0
  322. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_checkout_happy.py +0 -0
  323. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_cherry_pick_errors.py +0 -0
  324. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_cherry_pick_flags.py +0 -0
  325. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_cherry_pick_happy.py +0 -0
  326. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_diff_errors.py +0 -0
  327. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_diff_flags.py +0 -0
  328. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_diff_happy.py +0 -0
  329. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_diffmanifests_errors.py +0 -0
  330. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_diffmanifests_flags.py +0 -0
  331. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_diffmanifests_happy.py +0 -0
  332. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_dir_override.py +0 -0
  333. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_download_errors.py +0 -0
  334. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_download_flags.py +0 -0
  335. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_download_happy.py +0 -0
  336. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_envsubst_errors.py +0 -0
  337. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_envsubst_flags.py +0 -0
  338. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_envsubst_happy.py +0 -0
  339. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_exit_codes.py +0 -0
  340. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_forall_errors.py +0 -0
  341. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_forall_flags.py +0 -0
  342. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_forall_happy.py +0 -0
  343. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_gc_errors.py +0 -0
  344. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_gc_flags.py +0 -0
  345. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_gc_happy.py +0 -0
  346. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_grep_errors.py +0 -0
  347. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_grep_flags.py +0 -0
  348. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_grep_happy.py +0 -0
  349. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_help_errors.py +0 -0
  350. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_help_flags.py +0 -0
  351. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_help_happy.py +0 -0
  352. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_info_errors.py +0 -0
  353. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_info_flags.py +0 -0
  354. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_info_happy.py +0 -0
  355. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_init_errors.py +0 -0
  356. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_init_flags.py +0 -0
  357. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_init_happy.py +0 -0
  358. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_init_mirror.py +0 -0
  359. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_list_errors.py +0 -0
  360. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_list_flags.py +0 -0
  361. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_list_happy.py +0 -0
  362. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_manifest_errors.py +0 -0
  363. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_manifest_flags.py +0 -0
  364. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_manifest_happy.py +0 -0
  365. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_manifest_revision_as_tag.py +0 -0
  366. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_overview_errors.py +0 -0
  367. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_overview_flags.py +0 -0
  368. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_overview_happy.py +0 -0
  369. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_passthrough.py +0 -0
  370. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_prune_errors.py +0 -0
  371. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_prune_flags.py +0 -0
  372. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_prune_happy.py +0 -0
  373. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_rebase_errors.py +0 -0
  374. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_rebase_flags.py +0 -0
  375. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_rebase_happy.py +0 -0
  376. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_selfupdate_disabled.py +0 -0
  377. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_selfupdate_errors.py +0 -0
  378. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_selfupdate_flags.py +0 -0
  379. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_selfupdate_happy.py +0 -0
  380. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_smartsync_errors.py +0 -0
  381. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_smartsync_flags.py +0 -0
  382. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_smartsync_happy.py +0 -0
  383. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_stage_errors.py +0 -0
  384. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_stage_flags.py +0 -0
  385. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_stage_happy.py +0 -0
  386. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_start_errors.py +0 -0
  387. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_start_flags.py +0 -0
  388. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_start_happy.py +0 -0
  389. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_status_errors.py +0 -0
  390. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_status_flags.py +0 -0
  391. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_status_happy.py +0 -0
  392. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_sync_errors.py +0 -0
  393. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_sync_flags.py +0 -0
  394. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_sync_happy.py +0 -0
  395. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_upload_errors.py +0 -0
  396. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_upload_flags.py +0 -0
  397. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_repo_upload_happy.py +0 -0
  398. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_singular_catalog_source_inert.py +0 -0
  399. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_stdout_stderr_discipline.py +0 -0
  400. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_telemetry_journey.py +0 -0
  401. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_update_alert_journey.py +0 -0
  402. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_validate_journey.py +0 -0
  403. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_validate_lifecycle.py +0 -0
  404. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_validate_lockfile.py +0 -0
  405. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_validate_xml_errors.py +0 -0
  406. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_validate_xml_repo_root.py +0 -0
  407. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/functional/test_zero_source_clean_error.py +0 -0
  408. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/__init__.py +0 -0
  409. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/conftest.py +0 -0
  410. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/fixtures/__init__.py +0 -0
  411. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/fixtures/synthetic/__init__.py +0 -0
  412. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/fixtures/synthetic/conftest.py +0 -0
  413. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/fixtures/synthetic/drift.py +0 -0
  414. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/fixtures/synthetic/test_synthetic_pytest_fixtures.py +0 -0
  415. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/fixtures/synthetic/upgrade_versioned.py +0 -0
  416. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/provider_allowlist.txt +0 -0
  417. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/__init__.py +0 -0
  418. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/conftest.py +0 -0
  419. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_bug_fixes.py +0 -0
  420. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_consolidated_constraints_e2e.py +0 -0
  421. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_envsubst_integration.py +0 -0
  422. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_import_functional.py +0 -0
  423. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_linkfile_copyfile.py +0 -0
  424. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_linkfile_exclude_journey.py +0 -0
  425. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_manifest_parsing.py +0 -0
  426. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_process_isolation.py +0 -0
  427. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_repo_module_smoke.py +0 -0
  428. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_repo_pipeline.py +0 -0
  429. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_repo_run_lifecycle.py +0 -0
  430. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_repo_sync_lifecycle.py +0 -0
  431. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_version_constraints_integration.py +0 -0
  432. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_annotation_roundtrip.py +0 -0
  433. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_contactinfo_roundtrip.py +0 -0
  434. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_copyfile_roundtrip.py +0 -0
  435. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_default_roundtrip.py +0 -0
  436. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_extend_project_roundtrip.py +0 -0
  437. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_include_roundtrip.py +0 -0
  438. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_linkfile_roundtrip.py +0 -0
  439. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_manifest_roundtrip.py +0 -0
  440. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_manifest_server_roundtrip.py +0 -0
  441. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_notice_roundtrip.py +0 -0
  442. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_project_roundtrip.py +0 -0
  443. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_remote_roundtrip.py +0 -0
  444. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_remove_project_roundtrip.py +0 -0
  445. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_repo_hooks_roundtrip.py +0 -0
  446. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_submanifest_roundtrip.py +0 -0
  447. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/repo/test_xml_superproject_roundtrip.py +0 -0
  448. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_add_core.py +0 -0
  449. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_add_dry_run.py +0 -0
  450. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_add_env_var_detection.py +0 -0
  451. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_add_zero_tags.py +0 -0
  452. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_auto_discovery.py +0 -0
  453. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_background_refresh.py +0 -0
  454. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_cache_clock_skew.py +0 -0
  455. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_cache_layout.py +0 -0
  456. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_catalog_audit_entry_uniqueness.py +0 -0
  457. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_catalog_audit_framework.py +0 -0
  458. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_catalog_audit_legacy_dir.py +0 -0
  459. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_catalog_audit_metadata.py +0 -0
  460. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_catalog_audit_remote_url.py +0 -0
  461. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_catalog_audit_source_name.py +0 -0
  462. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_catalog_audit_strict.py +0 -0
  463. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_catalog_audit_tag_format.py +0 -0
  464. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_catalog_constraints.py +0 -0
  465. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_clean_env_override_cleanup.py +0 -0
  466. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_clean_paths.py +0 -0
  467. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_cli_entry_points.py +0 -0
  468. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_complete_cached_catalogs.py +0 -0
  469. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_complete_catalog_entries.py +0 -0
  470. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_complete_catalog_versions.py +0 -0
  471. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_complete_lockfile_names.py +0 -0
  472. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_complete_project_versions.py +0 -0
  473. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_complete_source_names.py +0 -0
  474. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_completion_bash.py +0 -0
  475. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_completion_powershell_subcommand.py +0 -0
  476. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_completion_subcommand.py +0 -0
  477. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_completion_zsh.py +0 -0
  478. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_concurrency.py +0 -0
  479. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_concurrency_serialization.py +0 -0
  480. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_copyfile_fs_effects.py +0 -0
  481. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_cross_platform_contract.py +0 -0
  482. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_doc_validation.py +0 -0
  483. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_doctor_cache_flags.py +0 -0
  484. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_doctor_cache_flags_workspace_independent.py +0 -0
  485. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_doctor_consistency.py +0 -0
  486. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_doctor_default_subcheck_output.py +0 -0
  487. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_doctor_effective_source.py +0 -0
  488. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_doctor_prune_cache.py +0 -0
  489. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_doctor_remote_check.py +0 -0
  490. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_envsubst_command.py +0 -0
  491. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_fs_fault_extended.py +0 -0
  492. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_fs_fault_injection.py +0 -0
  493. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_full_user_journey.py +0 -0
  494. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_git_fault_injection.py +0 -0
  495. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_git_retry_env.py +0 -0
  496. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_gitignore_idempotency.py +0 -0
  497. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_home_flag_store_relocation.py +0 -0
  498. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_command.py +0 -0
  499. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_env_var_resolution.py +0 -0
  500. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_errors.py +0 -0
  501. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_include_cycle.py +0 -0
  502. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_include_diamond.py +0 -0
  503. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_lifecycle.py +0 -0
  504. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_lock_file_derivation.py +0 -0
  505. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_lockfile_replay.py +0 -0
  506. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_no_kanon_remediation.py +0 -0
  507. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_optional_vars.py +0 -0
  508. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_path_conflict_integration.py +0 -0
  509. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_paths.py +0 -0
  510. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_per_alias_gitbase.py +0 -0
  511. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_reconcile.py +0 -0
  512. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_refresh_lock.py +0 -0
  513. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_refresh_lock_source.py +0 -0
  514. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_remote_url_policy.py +0 -0
  515. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_required_vars.py +0 -0
  516. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_install_strict.py +0 -0
  517. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_json_output_stream_discipline.py +0 -0
  518. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_kanon_add_placeholder_handling.py +0 -0
  519. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_kanon_clean_embedded.py +0 -0
  520. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_kanon_dir_collision.py +0 -0
  521. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_kanon_full_lifecycle.py +0 -0
  522. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_kanon_install_embedded.py +0 -0
  523. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_kanonenv_parsing.py +0 -0
  524. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_lifecycle_recovery.py +0 -0
  525. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_linkfile_fs_effects.py +0 -0
  526. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_list_all_versions.py +0 -0
  527. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_list_all_versions_canonical.py +0 -0
  528. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_list_all_versions_malformed_revision_resilience.py +0 -0
  529. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_list_command_json.py +0 -0
  530. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_list_default.py +0 -0
  531. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_list_detail.py +0 -0
  532. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_list_filter.py +0 -0
  533. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_list_format_json.py +0 -0
  534. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_list_synthetic_catalog_variants.py +0 -0
  535. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_list_tree.py +0 -0
  536. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_lockfile_roundtrip.py +0 -0
  537. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_marketplace_install.py +0 -0
  538. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_marketplace_lifecycle.py +0 -0
  539. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_midtoken_bash.py +0 -0
  540. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_midtoken_zsh.py +0 -0
  541. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_misc_features.py +0 -0
  542. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_multi_source_aggregation.py +0 -0
  543. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_no_bundled_catalog.py +0 -0
  544. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_no_default_catalog.py +0 -0
  545. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_no_hardcoded_org_values.py +0 -0
  546. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_observability.py +0 -0
  547. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_outdated.py +0 -0
  548. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_outdated_branch_drift.py +0 -0
  549. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_outdated_fail_on_upgrade.py +0 -0
  550. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_outdated_format_json.py +0 -0
  551. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_outdated_refs_tags_revision_parsing.py +0 -0
  552. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_platform_parity.py +0 -0
  553. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_preamble_bash.py +0 -0
  554. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_preamble_zsh.py +0 -0
  555. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_remove_core.py +0 -0
  556. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_remove_dry_run.py +0 -0
  557. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_remove_force_integration.py +0 -0
  558. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_signal_handling.py +0 -0
  559. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_synthetic_drift_fixture.py +0 -0
  560. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_synthetic_upgrade_versioned_fixture.py +0 -0
  561. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_unicode_encoding.py +0 -0
  562. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_validate_marketplace_revision_existence.py +0 -0
  563. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_validate_metadata.py +0 -0
  564. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_validate_xml.py +0 -0
  565. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_version_resolution.py +0 -0
  566. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_version_widened_bare_pep440.py +0 -0
  567. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_wheel_e2e.py +0 -0
  568. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_why_ambiguous.py +0 -0
  569. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_why_chain_walker.py +0 -0
  570. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_why_format_json.py +0 -0
  571. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_why_live_resolve.py +0 -0
  572. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_why_not_found_suggestion.py +0 -0
  573. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/integration/test_workspace_dir_env.py +0 -0
  574. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f1_s2_t5_regression.py +0 -0
  575. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f5_s2_t7_regression.py +0 -0
  576. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f6_s1_t1_regression.py +0 -0
  577. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f6_s1_t2_regression.py +0 -0
  578. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f6_s1_t3_regression.py +0 -0
  579. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f6_s1_t4_regression.py +0 -0
  580. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f6_s2_t1_regression.py +0 -0
  581. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f6_s2_t2_regression.py +0 -0
  582. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f6_s2_t3_regression.py +0 -0
  583. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f6_s2_t4_regression.py +0 -0
  584. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f6_s2_t5_regression.py +0 -0
  585. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f6_s2_t6_regression.py +0 -0
  586. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f6_s3_t1_regression.py +0 -0
  587. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_f6_s3_t2_regression.py +0 -0
  588. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/regression/test_e0_install_relative_regression.py +0 -0
  589. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/__init__.py +0 -0
  590. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/_rp_helpers.py +0 -0
  591. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/conftest.py +0 -0
  592. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_ad.py +0 -0
  593. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_bs.py +0 -0
  594. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_cd.py +0 -0
  595. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_content_pins.py +0 -0
  596. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_cs.py +0 -0
  597. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_doctor_cache.py +0 -0
  598. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_doctor_journey.py +0 -0
  599. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_ec.py +0 -0
  600. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_ep.py +0 -0
  601. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_ev.py +0 -0
  602. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_hv.py +0 -0
  603. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_ic.py +0 -0
  604. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_id.py +0 -0
  605. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_install_graph_capture.py +0 -0
  606. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_ks.py +0 -0
  607. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_lf.py +0 -0
  608. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_list_journey.py +0 -0
  609. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_lockfile_lifecycle.py +0 -0
  610. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_mk.py +0 -0
  611. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_ms.py +0 -0
  612. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_ns_marketplace_and_global_flags.py +0 -0
  613. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_outdated_two_source.py +0 -0
  614. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_pk.py +0 -0
  615. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rc.py +0 -0
  616. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_refresh_lock_existing_checkout.py +0 -0
  617. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rls_exact_vs_range.py +0 -0
  618. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_abandon.py +0 -0
  619. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_branches.py +0 -0
  620. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_checkout.py +0 -0
  621. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_cherry_pick.py +0 -0
  622. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_diff.py +0 -0
  623. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_diffmanifests.py +0 -0
  624. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_download.py +0 -0
  625. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_envsubst.py +0 -0
  626. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_forall.py +0 -0
  627. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_gc.py +0 -0
  628. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_grep.py +0 -0
  629. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_help.py +0 -0
  630. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_info.py +0 -0
  631. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_init.py +0 -0
  632. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_list.py +0 -0
  633. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_manifest.py +0 -0
  634. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_overview.py +0 -0
  635. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_prune.py +0 -0
  636. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_rebase.py +0 -0
  637. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_smartsync.py +0 -0
  638. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_stage.py +0 -0
  639. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_start.py +0 -0
  640. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_status.py +0 -0
  641. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_sync.py +0 -0
  642. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_upload.py +0 -0
  643. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rp_wrap.py +0 -0
  644. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_rx.py +0 -0
  645. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_scenario_coverage_meta.py +0 -0
  646. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_search_multi_source.py +0 -0
  647. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_tc_bootstrap.py +0 -0
  648. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_tc_clean.py +0 -0
  649. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_tc_install.py +0 -0
  650. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_tc_validate.py +0 -0
  651. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_uj.py +0 -0
  652. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_va.py +0 -0
  653. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_va_validate_lockfile.py +0 -0
  654. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_why_surface_query.py +0 -0
  655. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_why_url_path.py +0 -0
  656. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/scenarios/test_why_url_path_placeholder.py +0 -0
  657. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/security/__init__.py +0 -0
  658. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/security/test_security_hardening.py +0 -0
  659. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/test_wheel_layout.py +0 -0
  660. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/__init__.py +0 -0
  661. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/commands/test_repo_dir_resolution.py +0 -0
  662. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/conftest.py +0 -0
  663. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/__init__.py +0 -0
  664. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/conftest.py +0 -0
  665. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/fixtures/.gitignore +0 -0
  666. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/fixtures/README.md +0 -0
  667. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/fixtures/sample-manifest.xml +0 -0
  668. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/fixtures/sample-project-config.json +0 -0
  669. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/fixtures/test.gitconfig +0 -0
  670. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/fixtures/version_constraints_data.json +0 -0
  671. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/functional/__init__.py +0 -0
  672. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/functional/test_features.py +0 -0
  673. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/subcmds/__init__.py +0 -0
  674. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/subcmds/test_init_mirror.py +0 -0
  675. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/subcmds/test_manifest_revision_as_tag.py +0 -0
  676. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/subcmds/test_manifest_revision_as_tag_pep440.py +0 -0
  677. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/subcmds/test_selfupdate_stub.py +0 -0
  678. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_abandon_massive.py +0 -0
  679. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_branches_coverage.py +0 -0
  680. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug10_selfupdate_incompatible.py +0 -0
  681. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug11_race_condition.py +0 -0
  682. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug12_backup_preserved.py +0 -0
  683. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug13_init_reinit_warning.py +0 -0
  684. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug14_non_tty_log.py +0 -0
  685. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug15_prerelease_docs.py +0 -0
  686. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug16_nested_var_warning.py +0 -0
  687. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug18_envsubst_double_parse.py +0 -0
  688. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug19_glob_src_error.py +0 -0
  689. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug1_envsubst_malformed_xml.py +0 -0
  690. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug20_glob_dest_file.py +0 -0
  691. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug2_linkfile_errors.py +0 -0
  692. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug3_execv_replaces_process.py +0 -0
  693. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug4_symlink_overwrite.py +0 -0
  694. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug5_empty_envsubst_list.py +0 -0
  695. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug6_undefined_env_vars.py +0 -0
  696. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug7_git_ls_remote_retry.py +0 -0
  697. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug8_ls_remote_stderr.py +0 -0
  698. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_bug9_constraint_resolution_cache.py +0 -0
  699. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_checklocalpath_rules_1_5.py +0 -0
  700. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_checklocalpath_rules_6_11.py +0 -0
  701. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_checkout_massive.py +0 -0
  702. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_cherrypick_coverage.py +0 -0
  703. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_color.py +0 -0
  704. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_command.py +0 -0
  705. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_conftest_fixtures.py +0 -0
  706. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_diffmanifests_deep.py +0 -0
  707. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_doc_validate_git_preconditions.py +0 -0
  708. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_download_coverage.py +0 -0
  709. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_editor.py +0 -0
  710. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_embedded_mode.py +0 -0
  711. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_envsubst_basic.py +0 -0
  712. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_envsubst_edge.py +0 -0
  713. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_envsubst_massive.py +0 -0
  714. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_error.py +0 -0
  715. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_event_log.py +0 -0
  716. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_event_log_massive.py +0 -0
  717. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_fetch.py +0 -0
  718. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_fixture_files.py +0 -0
  719. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_forall_deep.py +0 -0
  720. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_git_command.py +0 -0
  721. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_git_config.py +0 -0
  722. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_git_refs.py +0 -0
  723. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_git_superproject.py +0 -0
  724. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_git_trace2_event_log.py +0 -0
  725. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_gitconfig_coverage.py +0 -0
  726. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_grep_deep.py +0 -0
  727. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_harness_smoke.py +0 -0
  728. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_hooks.py +0 -0
  729. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_import_verification.py +0 -0
  730. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_imports.py +0 -0
  731. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_include_path_resolution.py +0 -0
  732. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_info_deep.py +0 -0
  733. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_init_deep.py +0 -0
  734. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_list_massive.py +0 -0
  735. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_main.py +0 -0
  736. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_main_coverage.py +0 -0
  737. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_main_init_download_boost.py +0 -0
  738. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_makefile_lint_format.py +0 -0
  739. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_makefile_structure.py +0 -0
  740. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_makefile_test_targets.py +0 -0
  741. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_manifest_coverage_boost.py +0 -0
  742. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_manifest_deep.py +0 -0
  743. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_manifest_doc_rp_flags.py +0 -0
  744. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_manifest_massive.py +0 -0
  745. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_manifest_subcmd_massive.py +0 -0
  746. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_manifest_xml.py +0 -0
  747. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_manifest_xml_pep440.py +0 -0
  748. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_mkdtemp_cleanup.py +0 -0
  749. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_overview_massive.py +0 -0
  750. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_package_structure.py +0 -0
  751. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_pager.py +0 -0
  752. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_parselist.py +0 -0
  753. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_pep440_edge_1.py +0 -0
  754. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_pep440_edge_2.py +0 -0
  755. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_pep440_ops_ge.py +0 -0
  756. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_pep440_ops_rest.py +0 -0
  757. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_platform_utils.py +0 -0
  758. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_process_isolation.py +0 -0
  759. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_project.py +0 -0
  760. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_project_coverage_boost.py +0 -0
  761. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_project_coverage_threshold.py +0 -0
  762. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_project_deep.py +0 -0
  763. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_project_deep_boost.py +0 -0
  764. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_project_final_boost.py +0 -0
  765. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_project_integration.py +0 -0
  766. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_project_massive.py +0 -0
  767. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_project_metaproject_boost.py +0 -0
  768. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_project_methods.py +0 -0
  769. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_project_sync.py +0 -0
  770. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_prune_massive.py +0 -0
  771. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_rebase_coverage.py +0 -0
  772. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_remaining_coverage_boost.py +0 -0
  773. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_repo_envsubst_api.py +0 -0
  774. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_repo_logging.py +0 -0
  775. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_repo_run_api.py +0 -0
  776. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_repo_sync_api.py +0 -0
  777. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_repo_trace.py +0 -0
  778. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_revision_inheritance.py +0 -0
  779. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_revision_tag_branch_sha.py +0 -0
  780. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_ruff_config.py +0 -0
  781. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_selfupdate_embedded.py +0 -0
  782. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_selfupdate_massive.py +0 -0
  783. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_small_files_boost.py +0 -0
  784. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_ssh.py +0 -0
  785. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_ssh_deep.py +0 -0
  786. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_stage_coverage.py +0 -0
  787. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_stage_massive.py +0 -0
  788. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_start_coverage.py +0 -0
  789. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_status_coverage.py +0 -0
  790. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_status_gaps.py +0 -0
  791. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_status_massive.py +0 -0
  792. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmd_imports.py +0 -0
  793. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds.py +0 -0
  794. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_abandon.py +0 -0
  795. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_branches.py +0 -0
  796. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_checkout.py +0 -0
  797. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_cherry_pick.py +0 -0
  798. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_diff.py +0 -0
  799. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_diffmanifests.py +0 -0
  800. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_download.py +0 -0
  801. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_envsubst.py +0 -0
  802. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_forall.py +0 -0
  803. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_gc.py +0 -0
  804. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_grep.py +0 -0
  805. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_help.py +0 -0
  806. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_info.py +0 -0
  807. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_init.py +0 -0
  808. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_list.py +0 -0
  809. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_manifest.py +0 -0
  810. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_overview.py +0 -0
  811. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_prune.py +0 -0
  812. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_rebase.py +0 -0
  813. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_selfupdate.py +0 -0
  814. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_smartsync.py +0 -0
  815. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_stage.py +0 -0
  816. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_start.py +0 -0
  817. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_status.py +0 -0
  818. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_sync.py +0 -0
  819. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_subcmds_upload.py +0 -0
  820. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_superproject_deep.py +0 -0
  821. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_sync_coverage_boost.py +0 -0
  822. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_sync_deep.py +0 -0
  823. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_sync_deep_boost.py +0 -0
  824. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_sync_massive.py +0 -0
  825. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_upload_deep.py +0 -0
  826. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_version_consolidation.py +0 -0
  827. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_version_constraints.py +0 -0
  828. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_wheel_contents.py +0 -0
  829. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_wrapper.py +0 -0
  830. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_annotation_attributes.py +0 -0
  831. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_annotation_crossref.py +0 -0
  832. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_annotation_happy.py +0 -0
  833. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_contactinfo_attributes.py +0 -0
  834. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_contactinfo_crossref.py +0 -0
  835. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_contactinfo_happy.py +0 -0
  836. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_copyfile_attributes.py +0 -0
  837. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_copyfile_crossref.py +0 -0
  838. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_copyfile_happy.py +0 -0
  839. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_default_attributes.py +0 -0
  840. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_default_crossref.py +0 -0
  841. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_default_happy.py +0 -0
  842. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_extend_project_attributes.py +0 -0
  843. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_extend_project_crossref.py +0 -0
  844. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_extend_project_happy.py +0 -0
  845. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_fault_malformed.py +0 -0
  846. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_fault_structural.py +0 -0
  847. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_include_attributes.py +0 -0
  848. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_include_crossref.py +0 -0
  849. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_include_cycles.py +0 -0
  850. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_include_happy.py +0 -0
  851. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_linkfile_attributes.py +0 -0
  852. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_linkfile_crossref.py +0 -0
  853. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_linkfile_happy.py +0 -0
  854. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_manifest_attributes.py +0 -0
  855. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_manifest_crossref.py +0 -0
  856. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_manifest_happy.py +0 -0
  857. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_manifest_server_attributes.py +0 -0
  858. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_manifest_server_crossref.py +0 -0
  859. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_manifest_server_flow.py +0 -0
  860. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_manifest_server_happy.py +0 -0
  861. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_notice_attributes.py +0 -0
  862. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_notice_crossref.py +0 -0
  863. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_notice_happy.py +0 -0
  864. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_project_attributes.py +0 -0
  865. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_project_crossref.py +0 -0
  866. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_project_happy.py +0 -0
  867. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_remote_attributes.py +0 -0
  868. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_remote_crossref.py +0 -0
  869. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_remote_happy.py +0 -0
  870. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_remove_project_attributes.py +0 -0
  871. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_remove_project_crossref.py +0 -0
  872. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_remove_project_happy.py +0 -0
  873. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_repo_hooks_attributes.py +0 -0
  874. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_repo_hooks_crossref.py +0 -0
  875. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_repo_hooks_happy.py +0 -0
  876. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_submanifest_attributes.py +0 -0
  877. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_submanifest_crossref.py +0 -0
  878. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_submanifest_happy.py +0 -0
  879. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_superproject_attributes.py +0 -0
  880. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_superproject_crossref.py +0 -0
  881. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_superproject_flow.py +0 -0
  882. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xml_superproject_happy.py +0 -0
  883. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xmlbool.py +0 -0
  884. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_xmlint.py +0 -0
  885. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/repo/test_yamllint_config.py +0 -0
  886. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_accessed_at_coalescing.py +0 -0
  887. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_add.py +0 -0
  888. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_add_collision.py +0 -0
  889. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_add_zero_tags.py +0 -0
  890. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_background_refresh.py +0 -0
  891. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_bare_semver_to_tag.py +0 -0
  892. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_build_project_entries.py +0 -0
  893. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_cache.py +0 -0
  894. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_cache_layout.py +0 -0
  895. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_cache_ttl.py +0 -0
  896. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_cached_catalogs.py +0 -0
  897. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_catalog.py +0 -0
  898. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_catalog_audit_check_parser.py +0 -0
  899. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_catalog_audit_entry_uniqueness.py +0 -0
  900. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_catalog_audit_framework.py +0 -0
  901. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_catalog_audit_legacy_dir.py +0 -0
  902. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_catalog_audit_metadata.py +0 -0
  903. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_catalog_audit_project_tag_format.py +0 -0
  904. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_catalog_audit_remote_url.py +0 -0
  905. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_catalog_audit_source_name.py +0 -0
  906. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_catalog_audit_strict.py +0 -0
  907. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_catalog_audit_tag_format.py +0 -0
  908. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_catalog_source_parsing.py +0 -0
  909. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_check_no_comments.py +0 -0
  910. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_clean.py +0 -0
  911. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_clean_command.py +0 -0
  912. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_cli.py +0 -0
  913. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_cli_args.py +0 -0
  914. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_cli_help_format.py +0 -0
  915. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_cli_json_stream_discipline.py +0 -0
  916. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_complete_cached_catalogs.py +0 -0
  917. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_complete_catalog_entries.py +0 -0
  918. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_complete_catalog_versions.py +0 -0
  919. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_complete_lockfile_names.py +0 -0
  920. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_complete_project_versions.py +0 -0
  921. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_complete_source_names.py +0 -0
  922. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_completion.py +0 -0
  923. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_completion_sanitization.py +0 -0
  924. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_completion_subcommand.py +0 -0
  925. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_concurrency.py +0 -0
  926. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_conftest_scrubber.py +0 -0
  927. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_constants.py +0 -0
  928. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_constants_doctor_subcheck.py +0 -0
  929. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_constants_env_int.py +0 -0
  930. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_constants_install_after_add.py +0 -0
  931. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_constants_list.py +0 -0
  932. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_constants_outdated_refs_tags.py +0 -0
  933. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_constants_why_lockfile.py +0 -0
  934. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_coverage_gaps.py +0 -0
  935. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_derive_source_name.py +0 -0
  936. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_discover.py +0 -0
  937. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_discover_source_names_missing_url.py +0 -0
  938. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_docs_embedded_architecture.py +0 -0
  939. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_docs_remaining_and_catalog.py +0 -0
  940. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_doctor.py +0 -0
  941. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_doctor_cache_flags.py +0 -0
  942. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_doctor_completion_errors.py +0 -0
  943. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_doctor_completion_staleness.py +0 -0
  944. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_doctor_consistency.py +0 -0
  945. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_doctor_coverage_gaps.py +0 -0
  946. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_doctor_effective_source.py +0 -0
  947. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_doctor_remote_reachability.py +0 -0
  948. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_env_isolation.py +0 -0
  949. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_envsubst_subcommand.py +0 -0
  950. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_git_runner.py +0 -0
  951. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_home_flag.py +0 -0
  952. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_include_walker.py +0 -0
  953. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_install.py +0 -0
  954. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_install_color_default.py +0 -0
  955. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_install_command.py +0 -0
  956. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_install_conflict_detection.py +0 -0
  957. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_install_https_enforcement.py +0 -0
  958. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_install_placeholder_validation.py +0 -0
  959. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_install_reconcile_decision.py +0 -0
  960. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_install_refresh_lock.py +0 -0
  961. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_install_refresh_lock_source.py +0 -0
  962. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_install_state_matrix.py +0 -0
  963. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_install_strict_flags.py +0 -0
  964. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_install_strict_lock_orphan_naming.py +0 -0
  965. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_integration_testing_doc_manifest_paths.py +0 -0
  966. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_integration_testing_doc_s2_t14.py +0 -0
  967. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_integration_testing_doc_s2_t4.py +0 -0
  968. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_integration_testing_doc_s2_t5.py +0 -0
  969. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_integration_testing_doc_s2_t6.py +0 -0
  970. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_integration_testing_doc_s2_t7.py +0 -0
  971. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_integration_testing_doc_s2_tier1.py +0 -0
  972. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_isolation_fixtures.py +0 -0
  973. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_kanon_hash.py +0 -0
  974. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_kanonenv.py +0 -0
  975. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_kanonenv_advanced_edge_cases.py +0 -0
  976. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_kanonenv_edge_cases.py +0 -0
  977. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_kanonenv_writer.py +0 -0
  978. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_levenshtein.py +0 -0
  979. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_list.py +0 -0
  980. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_lock_file_path.py +0 -0
  981. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_lockfile.py +0 -0
  982. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_lockfile_coverage_gaps.py +0 -0
  983. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_lockfile_reconcile.py +0 -0
  984. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_lockfile_schema_migration.py +0 -0
  985. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_manifest.py +0 -0
  986. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_marketplace.py +0 -0
  987. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_marketplace_cmd.py +0 -0
  988. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_marketplace_install.py +0 -0
  989. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_marketplace_non_plugin_skip.py +0 -0
  990. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_metadata.py +0 -0
  991. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_midtoken_splitter.py +0 -0
  992. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_outdated.py +0 -0
  993. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_outdated_branch_pinned.py +0 -0
  994. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_outdated_fail_on_upgrade.py +0 -0
  995. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_outdated_format_json.py +0 -0
  996. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_pep440_filter.py +0 -0
  997. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_powershell.py +0 -0
  998. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_preamble.py +0 -0
  999. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_preamble_semver_tags.py +0 -0
  1000. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_provider_agnosticism.py +0 -0
  1001. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_remote_url.py +0 -0
  1002. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_remove.py +0 -0
  1003. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_remove_dry_run.py +0 -0
  1004. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_remove_force.py +0 -0
  1005. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_remove_line_endings.py +0 -0
  1006. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_repo.py +0 -0
  1007. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_repo_abspath.py +0 -0
  1008. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_repo_command.py +0 -0
  1009. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_resolve_catalog_dir.py +0 -0
  1010. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_revision_resolve.py +0 -0
  1011. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_rx_catalog_sub_repo.py +0 -0
  1012. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_sanitize.py +0 -0
  1013. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_search.py +0 -0
  1014. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_search_all_versions.py +0 -0
  1015. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_search_coverage_gaps.py +0 -0
  1016. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_search_detail.py +0 -0
  1017. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_search_filter.py +0 -0
  1018. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_search_format_json.py +0 -0
  1019. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_search_tree.py +0 -0
  1020. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_spawn.py +0 -0
  1021. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_telemetry.py +0 -0
  1022. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_update_check.py +0 -0
  1023. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_url.py +0 -0
  1024. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_validate.py +0 -0
  1025. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_validate_command.py +0 -0
  1026. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_validate_metadata.py +0 -0
  1027. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_version.py +0 -0
  1028. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_version_constraint_errors.py +0 -0
  1029. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_why.py +0 -0
  1030. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_why_ambiguity.py +0 -0
  1031. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_why_format_json.py +0 -0
  1032. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_why_suggestions.py +0 -0
  1033. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tests/unit/test_xml_validator.py +0 -0
  1034. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tools/lint/check_no_comments.py +0 -0
  1035. {kanon_cli-3.3.0 → kanon_cli-3.3.3}/tools/test_tmp_monitor.py +0 -0
@@ -3,11 +3,17 @@ description: |
3
3
  Composite action shared by every job in pr-validation.yml and
4
4
  main-validation.yml. Handles checkout, optional simulate-merge,
5
5
  Python install, asdf bootstrap (plus plugin install per
6
- .tool-versions), pip dependency cache, dev dependency install via
7
- `make install-dev`, and uv install. Each parallel CI job calls this
8
- action once before invoking its own singular Make target / pytest
9
- invocation, so the per-job step list stays minimal and the setup
10
- drift between jobs is impossible.
6
+ .tool-versions), uv install with an uv.lock-keyed cache, and the
7
+ dependency install itself (`uv sync --locked --all-groups`). Each
8
+ parallel CI job calls this action once before invoking its own
9
+ singular Make target, so the per-job step list stays minimal and
10
+ setup drift between jobs is impossible.
11
+
12
+ Every job resolves dependencies from uv.lock and nowhere else. Jobs
13
+ must invoke Make targets rather than calling pytest/ruff/bandit
14
+ directly, because those targets run tools through `uv run`; a bare
15
+ invocation picks up whatever is on PATH and reintroduces the drift
16
+ this action exists to prevent.
11
17
 
12
18
  inputs:
13
19
  base-ref:
@@ -108,15 +114,20 @@ runs:
108
114
  asdf install
109
115
  asdf reshim
110
116
 
111
- - name: Cache Python dependencies
112
- uses: actions/cache@v5
117
+ - name: Install uv
118
+ # uv must be installed BEFORE the dependency step, because that step is
119
+ # now `uv sync`. It is also required at test time:
120
+ # `tests/unit/repo/test_wheel_contents.py`,
121
+ # `tests/integration/test_wheel_e2e.py`, and
122
+ # `tests/integration/test_ci_validation.py` shell out to `uv build` to
123
+ # produce the wheel under test.
124
+ # `enable-cache` replaces the previous actions/cache pip step; keying on
125
+ # uv.lock means the cache is invalidated by exactly the file that decides
126
+ # which versions get installed.
127
+ uses: astral-sh/setup-uv@v6
113
128
  with:
114
- path: |
115
- ~/.cache/pip
116
- ~/.local/lib/python*/site-packages
117
- key: ${{ runner.os }}-pip-${{ hashFiles('requirements-dev.txt', 'pyproject.toml') }}
118
- restore-keys: |
119
- ${{ runner.os }}-pip-
129
+ enable-cache: true
130
+ cache-dependency-glob: uv.lock
120
131
 
121
132
  - name: Install zsh (for shell-completion integration tests)
122
133
  if: runner.os == 'Linux'
@@ -140,22 +151,15 @@ runs:
140
151
  shell: bash
141
152
  run: |
142
153
  set -euo pipefail
143
- pip install --upgrade pip
144
- # `make install-dev` is `pip install -r requirements-dev.txt`. GNU make
145
- # is not guaranteed on the windows-latest runner image, so the Windows
146
- # leg invokes pip directly (same dependency set, no make dependency)
147
- # while Linux keeps the make target for parity with local dev.
148
- if [ "$RUNNER_OS" = "Linux" ]; then
149
- make install-dev
150
- else
151
- pip install -r requirements-dev.txt
152
- fi
153
-
154
- - name: Install uv
155
- # `tests/unit/repo/test_wheel_contents.py`,
156
- # `tests/integration/test_wheel_e2e.py`, and
157
- # `tests/integration/test_ci_validation.py` shell out to
158
- # `uv build` to produce the wheel under test; uv must be on
159
- # PATH for any job that runs those suites (including the
160
- # full-suite regression job that runs every test together).
161
- uses: astral-sh/setup-uv@v6
154
+ # Single dependency-resolution path for every job. Previously this was
155
+ # `pip install -r requirements-dev.txt`, which resolved from PyPI at run
156
+ # time and ignored uv.lock, while `make test` / `make test-scenarios`
157
+ # ran under `uv run` and honoured it. The two disagreed -- the pip leg
158
+ # installed pytest 8.3 and an unbounded shtab, so a shtab release broke
159
+ # the completion golden fixtures in the pip-based jobs only.
160
+ #
161
+ # `--locked` fails the job if uv.lock is stale rather than silently
162
+ # re-resolving, so a dependency change cannot reach CI unlocked.
163
+ # `uv sync` needs no GNU make, so the Windows leg no longer needs a
164
+ # separate branch.
165
+ uv sync --locked --all-groups
@@ -103,17 +103,14 @@ jobs:
103
103
  with:
104
104
  fetch-depth: 0
105
105
  - uses: ./.github/actions/setup-kanon
106
- - name: Run unit tests with 90% coverage gate
106
+ - name: Run unit tests with coverage gate
107
107
  shell: bash
108
- run: |
109
- python -m pytest -n auto --dist loadscope -m "unit" --cov=kanon_cli --cov-report=term-missing
110
- coverage json
111
- coverage_percent=$(python -c "import json; f=open('coverage.json'); print(json.load(f)['totals']['percent_covered'])")
112
- echo "Coverage: $coverage_percent%"
113
- if (( $(echo "$coverage_percent < 90" | bc -l) )); then
114
- echo "Error: Code coverage is below 90% threshold ($coverage_percent%)"
115
- exit 1
116
- fi
108
+ # Delegates to the Make target so the threshold lives in one place
109
+ # (Makefile: COVERAGE_MIN) instead of being duplicated across both
110
+ # workflow files, and so the run resolves from uv.lock like every other
111
+ # job. pytest-cov's own --cov-fail-under replaces the hand-rolled
112
+ # coverage-json + bc comparison.
113
+ run: make test-unit-cov
117
114
 
118
115
  integration-tests-linux:
119
116
  name: Integration tests (Linux)
@@ -127,7 +124,7 @@ jobs:
127
124
  - uses: ./.github/actions/setup-kanon
128
125
  - name: Run integration tests
129
126
  shell: bash
130
- run: python -m pytest -n auto --dist loadscope -m "integration"
127
+ run: make test-integration
131
128
 
132
129
  functional-tests-linux:
133
130
  name: Functional tests (Linux)
@@ -141,7 +138,7 @@ jobs:
141
138
  - uses: ./.github/actions/setup-kanon
142
139
  - name: Run functional tests
143
140
  shell: bash
144
- run: SMOKE_TEST_TIMEOUT=300 python -m pytest -n auto --dist loadscope -m "functional"
141
+ run: make test-functional
145
142
 
146
143
  scenario-tests-linux:
147
144
  name: Scenario tests (Linux, docs/integration-testing.md)
@@ -276,22 +273,19 @@ jobs:
276
273
  asdf install
277
274
  asdf reshim
278
275
 
279
- - name: Cache Python dependencies for release
280
- uses: actions/cache@v5
276
+ - name: Install uv
277
+ # Same single resolution path as .github/actions/setup-kanon: deps come
278
+ # from uv.lock via `make install-dev` (`uv sync --locked`). Replaces the
279
+ # previous pip cache, which keyed on a requirements-dev.txt that no
280
+ # longer exists.
281
+ uses: astral-sh/setup-uv@v6
281
282
  with:
282
- path: |
283
- ~/.cache/pip
284
- ~/.local/lib/python*/site-packages
285
- key: ${{ runner.os }}-pip-release-${{ hashFiles('requirements-dev.txt', 'pyproject.toml') }}
286
- restore-keys: |
287
- ${{ runner.os }}-pip-release-
288
- ${{ runner.os }}-pip-
283
+ enable-cache: true
284
+ cache-dependency-glob: uv.lock
289
285
 
290
286
  - name: Install dependencies
291
287
  shell: bash
292
- run: |
293
- pip install --upgrade pip
294
- make install-dev
288
+ run: make install-dev
295
289
 
296
290
  - name: Compute next version
297
291
  id: semantic-release
@@ -299,7 +293,7 @@ jobs:
299
293
  GH_TOKEN: ${{ steps.generate_token.outputs.token }}
300
294
  shell: bash
301
295
  run: |
302
- NEW_VERSION=$(python -m semantic_release version --print | sed 's/^v//')
296
+ NEW_VERSION=$(uv run python -m semantic_release version --print | sed 's/^v//')
303
297
  echo "New version: $NEW_VERSION"
304
298
  if [[ -z "$NEW_VERSION" ]]; then
305
299
  echo "No new version detected, using current version"
@@ -313,7 +307,7 @@ jobs:
313
307
  GH_TOKEN: ${{ steps.generate_token.outputs.token }}
314
308
  shell: bash
315
309
  run: |
316
- python -m semantic_release version --no-push --no-vcs-release --no-commit
310
+ uv run python -m semantic_release version --no-push --no-vcs-release --no-commit
317
311
 
318
312
  NEW_VERSION=$(grep '^version = ' pyproject.toml | sed 's/.*version = "\([^"]*\)".*/\1/')
319
313
  echo "Updated version: $NEW_VERSION"
@@ -321,6 +315,13 @@ jobs:
321
315
  sed -i "s/__version__ = \"[^\"]*\"/__version__ = \"$NEW_VERSION\"/" src/kanon_cli/__init__.py
322
316
  echo "Updated __init__.py to version: $NEW_VERSION"
323
317
 
318
+ # uv.lock records the project's own version, so a bump leaves it stale.
319
+ # Every job installs with `uv sync --locked`, which refuses a stale lock,
320
+ # so the refresh has to land in the same commit as the version bump --
321
+ # otherwise the tag build fails in "Build and publish to PyPI".
322
+ uv lock
323
+ echo "Refreshed uv.lock to version: $NEW_VERSION"
324
+
324
325
  sed -i 's/[[:space:]]*$//' CHANGELOG.md pyproject.toml src/kanon_cli/__init__.py
325
326
 
326
327
  rm -rf dist/ build/ src/kanon_cli.egg-info/
@@ -346,7 +347,7 @@ jobs:
346
347
  echo "Git status before staging:"
347
348
  git status --porcelain
348
349
 
349
- git add CHANGELOG.md pyproject.toml src/kanon_cli/__init__.py
350
+ git add CHANGELOG.md pyproject.toml src/kanon_cli/__init__.py uv.lock
350
351
 
351
352
  echo "Git status after staging:"
352
353
  STAGED=$(git status --porcelain)
@@ -130,17 +130,14 @@ jobs:
130
130
  with:
131
131
  base-ref: ${{ github.base_ref }}
132
132
  head-sha: ${{ github.event.pull_request.head.sha }}
133
- - name: Run unit tests with 90% coverage gate
133
+ - name: Run unit tests with coverage gate
134
134
  shell: bash
135
- run: |
136
- python -m pytest -n auto --dist loadscope -m "unit" --cov=kanon_cli --cov-report=term-missing
137
- coverage json
138
- coverage_percent=$(python -c "import json; f=open('coverage.json'); print(json.load(f)['totals']['percent_covered'])")
139
- echo "Coverage: $coverage_percent%"
140
- if (( $(echo "$coverage_percent < 90" | bc -l) )); then
141
- echo "Error: Code coverage is below 90% threshold ($coverage_percent%)"
142
- exit 1
143
- fi
135
+ # Delegates to the Make target so the threshold lives in one place
136
+ # (Makefile: COVERAGE_MIN) instead of being duplicated across both
137
+ # workflow files, and so the run resolves from uv.lock like every other
138
+ # job. pytest-cov's own --cov-fail-under replaces the hand-rolled
139
+ # coverage-json + bc comparison.
140
+ run: make test-unit-cov
144
141
 
145
142
  integration-tests-linux:
146
143
  name: Integration tests (Linux)
@@ -157,7 +154,7 @@ jobs:
157
154
  head-sha: ${{ github.event.pull_request.head.sha }}
158
155
  - name: Run integration tests
159
156
  shell: bash
160
- run: python -m pytest -n auto --dist loadscope -m "integration"
157
+ run: make test-integration
161
158
 
162
159
  functional-tests-linux:
163
160
  name: Functional tests (Linux)
@@ -174,7 +171,7 @@ jobs:
174
171
  head-sha: ${{ github.event.pull_request.head.sha }}
175
172
  - name: Run functional tests
176
173
  shell: bash
177
- run: SMOKE_TEST_TIMEOUT=300 python -m pytest -n auto --dist loadscope -m "functional"
174
+ run: make test-functional
178
175
 
179
176
  scenario-tests-linux:
180
177
  name: Scenario tests (Linux, docs/integration-testing.md)
@@ -84,19 +84,18 @@ jobs:
84
84
  with:
85
85
  python-version: '3.14'
86
86
 
87
- - name: Cache Python dependencies
88
- uses: actions/cache@v5
87
+ - name: Install uv
88
+ # Same single resolution path as .github/actions/setup-kanon: deps come
89
+ # from uv.lock via `make install-dev` (`uv sync --locked`). Replaces the
90
+ # previous pip cache, which keyed on a requirements-dev.txt that no
91
+ # longer exists.
92
+ uses: astral-sh/setup-uv@v6
89
93
  with:
90
- path: |
91
- ~/.cache/pip
92
- ~/.local/lib/python*/site-packages
93
- key: ${{ runner.os }}-pip-${{ hashFiles('requirements-dev.txt', 'pyproject.toml') }}
94
- restore-keys: |
95
- ${{ runner.os }}-pip-
94
+ enable-cache: true
95
+ cache-dependency-glob: uv.lock
96
96
 
97
97
  - name: Install build dependencies
98
98
  run: |
99
- pip install --upgrade pip
100
99
  make install-dev
101
100
  asdf reshim
102
101
  shell: bash
@@ -31,3 +31,6 @@ tmp/
31
31
 
32
32
  # Deleted bundled catalog -- guard against accidental re-addition (E6-F2-S1-T1)
33
33
  src/kanon_cli/catalog/
34
+
35
+ # Local settings files
36
+ *.local.json
@@ -1,2 +1,3 @@
1
1
  jq 1.8.1
2
2
  pre-commit 4.3.0
3
+ uv 0.12.1
@@ -2,8 +2,355 @@
2
2
 
3
3
 
4
4
 
5
+ ## v3.3.3 (2026-08-06)
6
+
7
+ ### Fix
8
+
9
+ * fix: scope linkfile dest rule by entry type, exempt direct-checkout marketplaces (#109)
10
+
11
+ * fix: scope marketplace linkfile dest rule to claude-marketplace entries
12
+
13
+ validate_linkfile_dest required every &lt;linkfile dest&gt; in every catalog
14
+ entry to start with ${CLAUDE_MARKETPLACES_DIR}/, ignoring the declared
15
+ &lt;catalog-metadata&gt;&lt;type&gt;. Non-marketplace entries that install correctly
16
+ could not pass validation.
17
+
18
+ Closes #94
19
+
20
+ * fix: exempt direct-checkout entries, de-duplicate errors, align tests
21
+
22
+ Builds on ryano144&#39;s 0e75e27 (#99), which correctly identified issue #94:
23
+ validate_linkfile_dest required every &lt;linkfile dest&gt; to start with
24
+ ${CLAUDE_MARKETPLACES_DIR}/ regardless of &lt;catalog-metadata&gt;&lt;type&gt;, so a
25
+ non-marketplace entry that `kanon install` places correctly could not pass
26
+ validation. Scoping that rule by entry type is right and is kept as is.
27
+
28
+ Three problems remained.
29
+
30
+ 1. The new &#34;a claude-marketplace entry must land a dest under
31
+ ${CLAUDE_MARKETPLACES_DIR}/&#34; rule rejected an entry that declares no
32
+ &lt;linkfile&gt; at all. That is the direct-checkout shape:
33
+ register_direct_checkout_marketplaces registers a project whose checkout
34
+ carries .claude-plugin/marketplace.json and which has no &lt;linkfile&gt;
35
+ children, covered end to end by test_marketplace_direct_checkout.py. The
36
+ old validator accepted it, so the rule as written was a regression, and it
37
+ reproduced the very validator/install contradiction #94 reports, aimed at a
38
+ different entry shape. The rule now applies only when the entry declares at
39
+ least one &lt;linkfile&gt;; an entry declaring none is exempt. The useful half is
40
+ unchanged: an entry whose links all land elsewhere is still caught, and the
41
+ diagnostic now names the direct-checkout way out.
42
+
43
+ 2. Linkfile checks follow each entry&#39;s &lt;include&gt; chain, so a defect in a
44
+ manifest shared by several entries was reported once per consumer. Three
45
+ entries including one broken packages.xml produced three identical errors
46
+ and a count of three for a single defect. Errors are de-duplicated within a
47
+ call (a manifest reachable by two include paths) and across the run.
48
+ Identical message text means the same file, project and reason, so
49
+ collapsing exact duplicates cannot hide a second real defect.
50
+
51
+ 3. tests/functional/test_validate_marketplace.py still asserted the old
52
+ contract and was not touched by #99, so three parametrized cases failed:
53
+ relative/path, CLAUDE_MARKETPLACES_DIR/missing-dollar-brace and
54
+ ${OTHER_VAR}/proj are contained dests on an entry with no &lt;type&gt; and are
55
+ now legal. Rather than delete the coverage, the class is split: the three
56
+ contained dests assert exit 0, and a new negative case asserts exit 1 for
57
+ the three shapes that escape the workspace (absolute, &#39;..&#39;, empty).
58
+
59
+ Adds docs/integration-testing.md Category 11b (ET-01..ET-07) with runnable
60
+ manual reproductions, and tests/scenarios/test_et.py automating them through
61
+ the real `kanon validate marketplace` subprocess: the full 3x4 entry-type by
62
+ linkfile-shape matrix, containment across all three entry types, a linkfile
63
+ inside an &lt;include&gt;, a marketplace dest supplied by an include, single
64
+ reporting of a shared-include defect, and the mixed plugin-plus-standards
65
+ package from #94 with its negative counterpart.
66
+
67
+ Every documented scenario was also executed by hand against the built CLI and
68
+ matched its stated pass criteria.
69
+
70
+ Closes #94
71
+
72
+ * test: guard the single dependency-resolution path
73
+
74
+ Adds automated coverage for four invariants that were only ever verified by
75
+ hand while diagnosing the shtab CI drift and the 3.3.1 publish failure. Each
76
+ corresponds to a defect this repository actually hit, and none had a test.
77
+
78
+ 1. A tool invoked through `uv run` is declared in [dependency-groups].
79
+ `make security-scan` was `uv run bandit` while bandit was declared nowhere,
80
+ so uv fell through to PATH and silently ran a system-wide bandit -- an
81
+ undeclared dependency deciding a security gate. `uv run` does not fail on an
82
+ undeclared executable, so nothing surfaced it.
83
+
84
+ 2. No Make recipe invokes a tool directly. A bare `ruff check .` or
85
+ `pytest -m unit` resolves from PATH rather than uv.lock, which is precisely
86
+ the two-path split that let shtab 1.9.0 break the tiered CI jobs while the
87
+ uv-based jobs stayed green. Only the scenario target was previously guarded.
88
+
89
+ 3. A dependency whose generated output is byte-compared against a committed
90
+ fixture carries an upper bound. `shtab&gt;=1.7.0` allowed 1.9.0 to change its
91
+ completion output and break CI with no change to this repository.
92
+
93
+ 4. The release job re-locks and stages uv.lock. semantic-release bumps
94
+ pyproject.toml and __init__.py but knows nothing about uv.lock, so without
95
+ the explicit refresh every release leaves the lock a version behind and
96
+ `uv sync --locked` fails on the tag -- how 3.3.1 failed to publish. Its
97
+ symptom is already guarded by test_uv_lock_records_the_declared_project_version;
98
+ this guards the mechanism that prevents it.
99
+
100
+ Each was verified RED by reverting the invariant it protects: removing bandit
101
+ from the dev group, rewriting `uv run ruff` as `ruff`, restoring `shtab&gt;=1.7.0`,
102
+ dropping `uv lock` from the release job, and dropping uv.lock from its `git add`.
103
+ All five produce a message naming the file and the remedy.
104
+
105
+ * fix(test): replace the uv-run regex with linear tokenization
106
+
107
+ CodeQL flagged py/redos (high) on the pattern added in the previous commit:
108
+
109
+ \buv\s+run\s+(?:--[\w-]+(?:[= ]\S+)?\s+)*([A-Za-z][\w.-]*)
110
+
111
+ The repeated group holds an optional sub-match, so input with many repetitions
112
+ of &#39; --- ---&#39; backtracks exponentially. Skipping uv&#39;s own flags is awkward to
113
+ express as a pattern and easy to get wrong in exactly this way.
114
+
115
+ Walking tokens does the same job in linear time and reads more plainly: find
116
+ `uv run`, skip following tokens that begin with &#39;-&#39;, take the next one. A flag
117
+ with a detached value would misreport that value as the tool; no target uses
118
+ that form, and the assertion names the offending line, so it would be obvious
119
+ rather than silent. Documented on the helper.
120
+
121
+ Not suppressed: CLAUDE.md forbids annotating away a security finding, and the
122
+ finding was correct. Both guards were re-verified RED afterwards, and the
123
+ tokenizer returns in single-digit milliseconds on 40k adversarial tokens.
124
+
125
+ ---------
126
+
127
+ Co-authored-by: Ryan Gross &lt;ryan.gross@caylent.com&gt; ([`ccfdfec`](https://github.com/caylent-solutions/kanon/commit/ccfdfecdbd7b3e366e1ca9c0579bd84aa70e66ae))
128
+
129
+
130
+ ## v3.3.2 (2026-08-05)
131
+
132
+ ### Chore
133
+
134
+ * chore(release): 3.3.2 ([`6f5ffe7`](https://github.com/caylent-solutions/kanon/commit/6f5ffe7c01553820a2e091cdc996151b5100c6cb))
135
+
136
+ ### Fix
137
+
138
+ * fix(ci): refresh uv.lock during the release version bump (#107)
139
+
140
+ `Build and publish to PyPI` failed on the 3.3.1 tag:
141
+
142
+ uv sync --locked --all-groups
143
+ error: The lockfile at `uv.lock` needs to be updated, but `--locked` was provided.
144
+
145
+ uv.lock records the project&#39;s own version alongside its dependencies.
146
+ semantic-release bumps `pyproject.toml` and `src/kanon_cli/__init__.py`
147
+ via version_toml / version_variable, but knows nothing about uv.lock, and
148
+ the release job staged only those two files plus CHANGELOG.md. Every
149
+ release therefore left uv.lock one version behind: after 3.3.1,
150
+ pyproject.toml said 3.3.1 and uv.lock still said 3.3.0.
151
+
152
+ The drift is not new -- before #97, uv.lock said 2.1.0 against a
153
+ pyproject at 3.3.0, six releases of silent skew. What is new is that
154
+ `make install-dev` is now `uv sync --locked`, which refuses a stale lock
155
+ instead of quietly re-resolving, so a latent inconsistency became a hard
156
+ failure at tag-build time.
157
+
158
+ The release job now runs `uv lock` immediately after the version bump and
159
+ stages uv.lock with the other version files, so the release commit is
160
+ self-consistent and the tag it points at can be installed. Verified that
161
+ `uv lock` against the current tree changes exactly one line
162
+ (kanon-cli 3.3.0 -&gt; 3.3.1) with no dependency churn, so this does not turn
163
+ a release into an unrelated dependency update.
164
+
165
+ uv.lock is also corrected here so main is self-consistent again.
166
+
167
+ Adds `test_uv_lock_records_the_declared_project_version`, which compares
168
+ the kanon-cli entry in uv.lock against `[project] version`. Verified RED
169
+ against the stale lock, failing with the same mismatch the publish job
170
+ hit. It has to be run without `uv run` to fail, which is the reason this
171
+ class of drift stays invisible in local development: `uv run` implicitly
172
+ re-locks before executing, so a developer never sees the inconsistency
173
+ that a `--locked` install in CI rejects.
174
+
175
+ Note the existing 3.3.1 tag still points at a commit carrying the stale
176
+ lock, so republishing that exact tag will keep failing until the tag is
177
+ moved or a further release is cut. ([`00714e6`](https://github.com/caylent-solutions/kanon/commit/00714e648a42bea706945e7a38a66fa6dca8df28))
178
+
179
+ ### Unknown
180
+
181
+ * Merge pull request #108 from caylent-solutions/release-3.3.2
182
+
183
+ Release 3.3.2 ([`fc48540`](https://github.com/caylent-solutions/kanon/commit/fc48540a5fc082e64c81ef9809f68d583a3a16e8))
184
+
185
+
186
+ ## v3.3.1 (2026-08-04)
187
+
188
+ ### Chore
189
+
190
+ * chore(release): 3.3.1 ([`71621d5`](https://github.com/caylent-solutions/kanon/commit/71621d50a72c412cae40b1886f6c73adc08e9fc0))
191
+
192
+ * chore(git): ignore local settings files ([`61ceade`](https://github.com/caylent-solutions/kanon/commit/61ceade79f79a73b11316866572a71b3abce3052))
193
+
194
+ * chore: add uv to toolchain via asdf
195
+
196
+ Pin uv 0.12.1 in .tool-versions alongside the project&#39;s existing
197
+ asdf-managed tools, and refresh uv.lock&#39;s kanon-cli editable entry
198
+ to match the current pyproject.toml version. ([`300b979`](https://github.com/caylent-solutions/kanon/commit/300b979ae0dae98f200efd21be99fad0b5106658))
199
+
200
+ ### Fix
201
+
202
+ * fix: let repo sync own &lt;linkfile&gt;, removing the duplicate copy pass (#105)
203
+
204
+ * fix: skip linkfile copy when dest already resolves to src
205
+
206
+ repo sync materializes every &lt;linkfile&gt; as a symlink before
207
+ _process_manifest_linkfiles runs. For a file-level src the helper then
208
+ called shutil.copy2 on the same inode pair, raising SameFileError and
209
+ aborting the install with exit 1.
210
+
211
+ Closes #93
212
+
213
+ * fix: let repo sync own &lt;linkfile&gt;, removing the duplicate copy pass
214
+
215
+ `_process_manifest_linkfiles` re-processed the same `&lt;linkfile&gt;` elements
216
+ `repo sync` had just materialized. It read only the root manifest&#39;s direct
217
+ `&lt;project&gt;` children (no `&lt;include&gt;` traversal) and skipped any non-file
218
+ `src`, so in a real install it covered a strict subset of what sync had
219
+ already done. Its three possible outcomes were: crash on the same inode
220
+ (issue 93), write through a foreign symlink and clobber that link&#39;s target,
221
+ or nothing. It had no branch that produced a correct result sync had not
222
+ already produced.
223
+
224
+ It existed to compensate for tests that replace `repo_sync` with a no-op,
225
+ which its own docstring stated. The compensation belongs in the double, not
226
+ in production, so it moves to `tests.conftest.materialize_linkfiles_for_sync`
227
+ -- delegating to the production `_LinkFile` so the double cannot drift from
228
+ what `repo` does. Mocked-sync tests now leave a symlink where a real sync
229
+ leaves one, instead of a copy.
230
+
231
+ Runtime behaviour is unchanged for every input except the crash: with
232
+ `repo sync` succeeding, the deleted pass was already a no-op. No exported
233
+ symbol is removed; `__all__` is byte-identical.
234
+
235
+ Replaces the unit-level regression test, which imported the deleted
236
+ function, with one that drives a real `repo init` + `repo sync` against
237
+ local file:// fixtures. Verified RED against the pre-fix code: it reproduces
238
+ `shutil.SameFileError` on the flagged/file-src case only, matching the scope
239
+ table in issue 93.
240
+
241
+ `test_only_flagged_source_registers_marketplace` asserted that an unflagged
242
+ source cannot register a marketplace. Under a sync that behaves like the real
243
+ one it registers anyway: `run_repo_sync` is unconditional, `_LinkFile._Link`
244
+ knows nothing about kanon flags, `CLAUDE_MARKETPLACES_DIR` is exported to
245
+ every source, and `install_marketplace_plugins` scans the directory once with
246
+ no per-source attribution. The flag genuinely gates only
247
+ `register_direct_checkout_marketplaces`, so the fixture now uses
248
+ direct-checkout entries and the docstring records what the flag does not gate.
249
+
250
+ Closes #93
251
+
252
+ * ci: resolve every job from uv.lock, deleting the pip dependency path
253
+
254
+ CI resolved dependencies two ways. The tiered test jobs ran bare
255
+ `python -m pytest` against a `pip install -r requirements-dev.txt`
256
+ environment, which resolves from PyPI at run time; `make test` and
257
+ `make test-scenarios` ran under `uv run`, which honours uv.lock. The two
258
+ manifests disagreed -- requirements-dev.txt pinned pytest ~=8.3.0 while
259
+ [dependency-groups] dev asked for &gt;=9.0.3, so the same suite ran on two
260
+ different runners depending on the job.
261
+
262
+ That split is what let a shtab release break CI. `shtab&gt;=1.7.0` had no
263
+ upper bound, shtab 1.9.0 (2026-07-31) changed its generated output, and
264
+ the pip-based jobs installed 1.9.3 against completion golden fixtures
265
+ generated with 1.8.0. The uv-based jobs stayed on uv.lock&#39;s 1.8.0 and
266
+ passed. main has not run CI since 2026-07-17, before that release, so it
267
+ is green in history and broken in fact; every PR branched from it fails
268
+ the same two tests.
269
+
270
+ Reproduced directly: a venv built from requirements-dev.txt resolves
271
+ shtab 1.9.3 and pytest 8.3.5, and fails
272
+ test_completion_stdout_matches_committed_golden[bash,zsh] with the same
273
+ 16098-vs-15657 byte mismatch CI reports. Installing shtab==1.8.0 into
274
+ that same venv turns it green.
275
+
276
+ 9869ee7 pins shtab, which fixes the instance. This removes the cause:
277
+
278
+ - [dependency-groups] dev absorbs ruff, bandit, twine, pre-commit and
279
+ python-semantic-release, the tools only requirements-dev.txt declared.
280
+ Existing pins carry over unchanged. ruff stays ~=0.11.0 for the same
281
+ reason shtab is pinned: `ruff format --check` is a byte-level gate.
282
+ - requirements-dev.txt is deleted rather than kept in sync.
283
+ - requirements.txt is deleted too. It declared packaging and nothing
284
+ else, one of three runtime dependencies, and `make install` was
285
+ referenced nowhere; pyproject&#39;s [project] dependencies supersedes it.
286
+ - Every Makefile target invokes its tools through `uv run`. Previously
287
+ `make security-scan` was `uv run bandit` with bandit in no dependency
288
+ group, so uv fell through to PATH and silently ran a system-wide
289
+ bandit -- verified resolving to /usr/local/py-utils/bin/bandit.
290
+ - The unit coverage gate moves into `make test-unit-cov` behind a
291
+ COVERAGE_MIN variable, replacing the coverage-json + bc comparison
292
+ duplicated across both workflow files with pytest-cov&#39;s own
293
+ --cov-fail-under.
294
+ - setup-kanon installs uv before dependencies and runs
295
+ `uv sync --locked --all-groups`; --locked fails the job on a stale
296
+ lock instead of silently re-resolving. setup-uv&#39;s cache, keyed on
297
+ uv.lock, replaces the pip cache. The Windows leg no longer needs its
298
+ own branch because uv sync does not require GNU make.
299
+ - The release and publish jobs move to the same path, and
300
+ `python -m semantic_release` becomes `uv run python -m semantic_release`.
301
+
302
+ The CI-shape tests are updated rather than loosened. The tier assertions
303
+ followed the existing `make test-scenarios` precedent and now check both
304
+ halves of the contract: the workflow invokes the tier&#39;s Make target
305
+ exactly once with no per-OS override, and that target selects the bare
306
+ marker. Previously the marker was asserted but the delegation was not;
307
+ now both are. test_ci_includes_repo_tests searches the Makefile as well,
308
+ since --cov=kanon_cli moved there.
309
+
310
+ Verified from a clean `uv sync --locked --all-groups`: ruff, bandit,
311
+ twine, pre-commit and pytest all resolve inside .venv with no PATH
312
+ fallthrough. All ten CI jobs pass locally with counts identical to the
313
+ pre-change baseline -- full suite 17168 passed / 0 failed / 95%, unit
314
+ 11712 passed / 93.22%, integration 1947, functional 3089, scenario 413.
315
+
316
+ ---------
317
+
318
+ Co-authored-by: Ryan Gross &lt;ryan.gross@caylent.com&gt; ([`23b320e`](https://github.com/caylent-solutions/kanon/commit/23b320e7818bf564cbc3b9dcb65acc3e7f4626ef))
319
+
320
+ * fix: pin shtab to exact version to stop completion-fixture CI drift
321
+
322
+ pyproject.toml declared shtab&gt;=1.7.0 with no upper bound. CI installs
323
+ dependencies via `pip install -r requirements-dev.txt` (-e .), resolving
324
+ shtab independently of uv.lock&#39;s exact pin; PyPI&#39;s latest shtab (1.9.2)
325
+ changed its generated output, breaking the byte-for-byte comparison
326
+ against the committed completion golden fixtures in both the
327
+ integration and functional test suites. Exact-pinning to 1.8.0 (already
328
+ locked in uv.lock) makes both install paths deterministic. ([`9869ee7`](https://github.com/caylent-solutions/kanon/commit/9869ee7b720829c329ad3c1afdcf2057a14427aa))
329
+
330
+ * fix(test): put safeguards in place for pre-commit failures in devcontainer environment on macos ([`1f38b25`](https://github.com/caylent-solutions/kanon/commit/1f38b25ea3205cac983c0952baed76c4a976b3ee))
331
+
332
+ * fix(tests): patch to avoid ioctl environment issues when running tests in devcontainer under uv ([`4931c10`](https://github.com/caylent-solutions/kanon/commit/4931c101c4cec06e778958e62b1af68ee9ada022))
333
+
334
+ ### Unknown
335
+
336
+ * Merge pull request #106 from caylent-solutions/release-3.3.1
337
+
338
+ Release 3.3.1 ([`35f709f`](https://github.com/caylent-solutions/kanon/commit/35f709f1f5e0c26a2bcf6317e573ca56303e49bd))
339
+
340
+ * Merge pull request #97 from caylent-solutions/chore/add-uv-tool-version
341
+
342
+ chore: add uv toolchain support and fix progress-bar ioctl crash
343
+
344
+ Includes the issue-93 linkfile fix and the CI dependency-resolution
345
+ consolidation merged into this branch via #105. ([`bfab7a3`](https://github.com/caylent-solutions/kanon/commit/bfab7a319ade76111057696ee049b6d6ab5c41ab))
346
+
347
+
5
348
  ## v3.3.0 (2026-07-17)
6
349
 
350
+ ### Chore
351
+
352
+ * chore(release): 3.3.0 ([`5100db5`](https://github.com/caylent-solutions/kanon/commit/5100db56a01818a5914474d7ddb95c96b7ab6de9))
353
+
7
354
  ### Feature
8
355
 
9
356
  * feat: kanon list command + usage telemetry, full install-graph capture, and update-warning enhancement (#91)
@@ -100,6 +447,12 @@ subprocess tests do not need coverage of the child; the 90% coverage gate is
100
447
  measured in-process on the unit tier, which uses its own runner and is
101
448
  unaffected. ([`57246f8`](https://github.com/caylent-solutions/kanon/commit/57246f8a8a46b99ad2b35a954289d7a9e7d1966c))
102
449
 
450
+ ### Unknown
451
+
452
+ * Merge pull request #92 from caylent-solutions/release-3.3.0
453
+
454
+ Release 3.3.0 ([`56f49b9`](https://github.com/caylent-solutions/kanon/commit/56f49b9c98b2dfd9b5fac5d847fcb6350a6fafe4))
455
+
103
456
 
104
457
  ## v3.2.0 (2026-07-13)
105
458