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