agentbundle 0.35.0__tar.gz → 0.35.1__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 (552) hide show
  1. {agentbundle-0.35.0/agentbundle.egg-info → agentbundle-0.35.1}/PKG-INFO +1 -1
  2. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue.py +120 -29
  3. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/system_trust.py +82 -14
  4. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/version.py +1 -1
  5. {agentbundle-0.35.0 → agentbundle-0.35.1/agentbundle.egg-info}/PKG-INFO +1 -1
  6. {agentbundle-0.35.0 → agentbundle-0.35.1}/pyproject.toml +1 -1
  7. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_trust_fallback_tls.py +4 -4
  8. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_trust_fallback.py +162 -8
  9. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_system_trust.py +81 -7
  10. {agentbundle-0.35.0 → agentbundle-0.35.1}/MANIFEST.in +0 -0
  11. {agentbundle-0.35.0 → agentbundle-0.35.1}/README-pypi.md +0 -0
  12. {agentbundle-0.35.0 → agentbundle-0.35.1}/README.md +0 -0
  13. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/__init__.py +0 -0
  14. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/__main__.py +0 -0
  15. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/adapter.schema.json +0 -0
  16. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/adapter.toml +0 -0
  17. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/guides/_shared/reference/catalogue-authoring-standards.md +0 -0
  18. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/guides/_shared/reference/catalogue-ci-contract.md +0 -0
  19. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/manifest.json +0 -0
  20. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/packs/AGENTS.md +0 -0
  21. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/packs/README.md +0 -0
  22. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/packs/_example/.apm/skills/example-skill/SKILL.md +0 -0
  23. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/packs/_example/.apm/skills/example-skill/evals/eval_queries.json +0 -0
  24. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/packs/_example/.claude-plugin/plugin.json +0 -0
  25. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/packs/_example/README.md +0 -0
  26. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/packs/_example/pack.toml +0 -0
  27. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/profiles/AGENTS.md +0 -0
  28. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/profiles/README.md +0 -0
  29. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/profiles/_example/README.md +0 -0
  30. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/profiles/_example/profile.toml +0 -0
  31. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/tests/conformance/test_gemini_admissibility.py +0 -0
  32. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/tests/conformance/test_pack_metadata.py +0 -0
  33. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue-scaffold/tests/conformance/test_shared_library_boundaries.py +0 -0
  34. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/catalogue.schema.json +0 -0
  35. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/guide.schema.json +0 -0
  36. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/install-defaults.toml +0 -0
  37. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/install-marker.py +0 -0
  38. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/marketplace-entry.schema.json +0 -0
  39. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/pack.schema.json +0 -0
  40. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/plugin-manifest.derived.schema.json +0 -0
  41. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/plugin-manifest.schema.json +0 -0
  42. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/profile.schema.json +0 -0
  43. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/public-contracts.txt +0 -0
  44. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/skill-manifest.schema.json +0 -0
  45. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/skill.schema.json +0 -0
  46. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/target-vocab.toml +0 -0
  47. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/_data/workspace_status_engine.py +0 -0
  48. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/__init__.py +0 -0
  49. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/__main__.py +0 -0
  50. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/adapter_root_bins.py +0 -0
  51. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/adapters/__init__.py +0 -0
  52. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/adapters/claude_code.py +0 -0
  53. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/adapters/codex.py +0 -0
  54. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/adapters/copilot.py +0 -0
  55. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/adapters/cursor.py +0 -0
  56. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/adapters/gemini.py +0 -0
  57. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/adapters/kiro.py +0 -0
  58. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/adapters/kiro_cli.py +0 -0
  59. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/adapters/kiro_ide.py +0 -0
  60. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/contract.py +0 -0
  61. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/hook_wiring_rules.py +0 -0
  62. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/lint_packs.py +0 -0
  63. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/main.py +0 -0
  64. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/phase_order.py +0 -0
  65. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projection_io.py +0 -0
  66. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projections/__init__.py +0 -0
  67. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projections/codex_agent_toml.py +0 -0
  68. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projections/copilot_agent_md.py +0 -0
  69. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projections/copilot_hooks_json.py +0 -0
  70. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projections/direct_directory.py +0 -0
  71. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projections/gemini_command_toml.py +0 -0
  72. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projections/hook_id.py +0 -0
  73. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projections/kiro_ide_hook.py +0 -0
  74. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projections/merge_into_agent_json.py +0 -0
  75. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projections/merge_json.py +0 -0
  76. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projections/plugin_hooks.py +0 -0
  77. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/projections/user_merge_json.py +0 -0
  78. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/recipes/composite-agents-md.toml +0 -0
  79. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/recipes/composite-marketplace.toml +0 -0
  80. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/recipes/marketplace.toml +0 -0
  81. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/recipes/per-pack-apm-package.toml +0 -0
  82. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/recipes/per-pack-claude-plugin.toml +0 -0
  83. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/recipes/per-pack-overlay.toml +0 -0
  84. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/recipes/self-host.toml +0 -0
  85. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/scope_rails.py +0 -0
  86. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/self_host.py +0 -0
  87. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/shared_libs.py +0 -0
  88. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/target_resolver.py +0 -0
  89. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/user_libs.py +0 -0
  90. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/build/validate.py +0 -0
  91. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/__init__.py +0 -0
  92. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/archive.py +0 -0
  93. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/build.py +0 -0
  94. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/config.py +0 -0
  95. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/contracts_inspector.py +0 -0
  96. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/defaults.py +0 -0
  97. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/diagnostics.py +0 -0
  98. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/file_safety.py +0 -0
  99. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/identity.py +0 -0
  100. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/initialise.py +0 -0
  101. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/initialise_self_hosted.py +0 -0
  102. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/lint.py +0 -0
  103. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/package.py +0 -0
  104. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/results.py +0 -0
  105. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/self_host.py +0 -0
  106. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/self_host_windows.py +0 -0
  107. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/skill_spec_lint.py +0 -0
  108. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/toml_emit.py +0 -0
  109. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/catalogue_tooling/verify.py +0 -0
  110. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/categories.py +0 -0
  111. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/cli.py +0 -0
  112. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/__init__.py +0 -0
  113. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/_common.py +0 -0
  114. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/_drop_warning.py +0 -0
  115. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/adapt.py +0 -0
  116. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/catalogue_build.py +0 -0
  117. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/catalogue_contracts.py +0 -0
  118. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/catalogue_init.py +0 -0
  119. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/catalogue_lint.py +0 -0
  120. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/catalogue_package.py +0 -0
  121. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/catalogue_self_host.py +0 -0
  122. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/catalogue_sync_defaults.py +0 -0
  123. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/catalogue_tooling_stub.py +0 -0
  124. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/catalogue_verify.py +0 -0
  125. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/config.py +0 -0
  126. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/diff.py +0 -0
  127. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/docs.py +0 -0
  128. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/init_state.py +0 -0
  129. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/install.py +0 -0
  130. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/list_installed.py +0 -0
  131. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/list_packs.py +0 -0
  132. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/list_profiles.py +0 -0
  133. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/list_targets.py +0 -0
  134. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/oplog_cmd.py +0 -0
  135. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/pack_config_cmd.py +0 -0
  136. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/pack_evals.py +0 -0
  137. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/package_catalogue.py +0 -0
  138. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/profile.py +0 -0
  139. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/reconcile.py +0 -0
  140. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/render.py +0 -0
  141. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/scaffold.py +0 -0
  142. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/show.py +0 -0
  143. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/uninstall.py +0 -0
  144. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/upgrade.py +0 -0
  145. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/commands/validate.py +0 -0
  146. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/config.py +0 -0
  147. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/https_catalogue.py +0 -0
  148. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/local_exclude.py +0 -0
  149. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/oplog.py +0 -0
  150. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/pack_inventory.py +0 -0
  151. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/render.py +0 -0
  152. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/safety.py +0 -0
  153. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/scaffold.py +0 -0
  154. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/scope.py +0 -0
  155. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/source_defaults.py +0 -0
  156. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/statelock.py +0 -0
  157. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/user_config.py +0 -0
  158. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle/workspace_mcp.py +0 -0
  159. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle.egg-info/SOURCES.txt +0 -0
  160. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle.egg-info/dependency_links.txt +0 -0
  161. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle.egg-info/entry_points.txt +0 -0
  162. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle.egg-info/requires.txt +0 -0
  163. {agentbundle-0.35.0 → agentbundle-0.35.1}/agentbundle.egg-info/top_level.txt +0 -0
  164. {agentbundle-0.35.0 → agentbundle-0.35.1}/conftest.py +0 -0
  165. {agentbundle-0.35.0 → agentbundle-0.35.1}/setup.cfg +0 -0
  166. {agentbundle-0.35.0 → agentbundle-0.35.1}/templates/install-marker.py +0 -0
  167. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/__init__.py +0 -0
  168. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/_support.py +0 -0
  169. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/__init__.py +0 -0
  170. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/README.md +0 -0
  171. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/claude-code-2.1.226-hook-events.json +0 -0
  172. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/claude-code-2.1.228-hook-events.json +0 -0
  173. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/core/.apm/agents/bar.md +0 -0
  174. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/core/.apm/commands/qux.md +0 -0
  175. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/core/.apm/hook-wiring/baz.toml +0 -0
  176. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/core/.apm/hook-wiring/qux.toml +0 -0
  177. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/core/.apm/hooks/baz.py +0 -0
  178. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/core/.apm/hooks/baz.sh +0 -0
  179. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/core/.apm/skills/example/SKILL.md +0 -0
  180. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/core/.claude-plugin/plugin.json +0 -0
  181. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/core/pack.toml +0 -0
  182. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/governance-extras/.apm/skills/example/SKILL.md +0 -0
  183. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/governance-extras/.claude-plugin/plugin.json +0 -0
  184. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/governance-extras/pack.toml +0 -0
  185. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/monorepo-extras/.apm/skills/example/SKILL.md +0 -0
  186. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/monorepo-extras/.claude-plugin/plugin.json +0 -0
  187. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/monorepo-extras/pack.toml +0 -0
  188. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/product-documentation/.apm/skills/example/SKILL.md +0 -0
  189. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/product-documentation/.claude-plugin/plugin.json +0 -0
  190. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/product-documentation/pack.toml +0 -0
  191. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/user-guide-diataxis/.apm/skills/example/SKILL.md +0 -0
  192. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/user-guide-diataxis/.claude-plugin/plugin.json +0 -0
  193. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/packs/user-guide-diataxis/pack.toml +0 -0
  194. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/fixtures/recipes/bogus-target.toml +0 -0
  195. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_adapter_claude_code.py +0 -0
  196. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_adapter_codex.py +0 -0
  197. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_adapter_copilot.py +0 -0
  198. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_adapter_cursor.py +0 -0
  199. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_adapter_gemini.py +0 -0
  200. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_adapter_kiro.py +0 -0
  201. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_adapter_kiro_alias.py +0 -0
  202. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_adapter_kiro_cli.py +0 -0
  203. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_adapter_kiro_ide.py +0 -0
  204. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_adapter_root_bins_projection.py +0 -0
  205. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_build_ships_seeds.py +0 -0
  206. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_contract.py +0 -0
  207. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_contract_scope.py +0 -0
  208. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_contract_v07.py +0 -0
  209. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_contract_v08.py +0 -0
  210. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_direct_directory_cleanup.py +0 -0
  211. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_end_to_end_build.py +0 -0
  212. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_hook_wiring_rules.py +0 -0
  213. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_lint_packs.py +0 -0
  214. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_load_pack_hook_wiring_safely.py +0 -0
  215. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_pack_schema.py +0 -0
  216. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_pack_schema_allowed_adapters.py +0 -0
  217. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_pack_schema_install.py +0 -0
  218. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_pipeline.py +0 -0
  219. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_plugin_hooks.py +0 -0
  220. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_plugin_manifest_schema.py +0 -0
  221. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_plugin_publication_gates.py +0 -0
  222. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_projectable_subset.py +0 -0
  223. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_projection_io.py +0 -0
  224. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_projections_merge_json.py +0 -0
  225. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_scope_rails.py +0 -0
  226. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_security.py +0 -0
  227. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_self_host_check.py +0 -0
  228. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_self_host_fixture_guard.py +0 -0
  229. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_self_host_metadata_policy.py +0 -0
  230. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_self_host_recipe_config.py +0 -0
  231. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_shared_libs_projection.py +0 -0
  232. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_shared_prefix_contract.py +0 -0
  233. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_user_libs_projection.py +0 -0
  234. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_validate.py +0 -0
  235. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/build_pipeline/test_writers_emit_lf.py +0 -0
  236. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/conftest.py +0 -0
  237. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/adapt/.adapt-discovery.toml +0 -0
  238. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/adapt/values.toml +0 -0
  239. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/blank_catalogue/.claude-plugin/marketplace.json +0 -0
  240. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/blank_catalogue/catalogue.toml +0 -0
  241. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/blank_catalogue/packs/.gitkeep +0 -0
  242. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/blank_catalogue/packs/_example/.apm/skills/example-skill/SKILL.md +0 -0
  243. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/blank_catalogue/packs/_example/.claude-plugin/plugin.json +0 -0
  244. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/blank_catalogue/packs/_example/README.md +0 -0
  245. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/blank_catalogue/packs/_example/evals/eval_queries.json +0 -0
  246. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/blank_catalogue/packs/_example/pack.toml +0 -0
  247. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/blank_catalogue/profiles/.gitkeep +0 -0
  248. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/blank_catalogue/profiles/_example/README.md +0 -0
  249. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/blank_catalogue/profiles/_example/profile.toml +0 -0
  250. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/brownfield/values.toml +0 -0
  251. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/brownfield-adapt/AGENTS.md +0 -0
  252. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/brownfield-adapt/AGENTS.upstream.md +0 -0
  253. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/brownfield-adapt/DESIGN.md +0 -0
  254. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/brownfield-adapt/EXPECTED_TREE.md +0 -0
  255. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/brownfield-adapt/docs/CHARTER.md +0 -0
  256. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/brownfield-adapt/docs/guides/how-to/index.md +0 -0
  257. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/brownfield-adapt/docs/howto/getting-started.md +0 -0
  258. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/brownfield-adapt-expected/AGENTS.md +0 -0
  259. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/brownfield-adapt-expected/docs/CHARTER.md +0 -0
  260. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/brownfield-adapt-user-home/.agentbundle/.adapt-discovery.toml +0 -0
  261. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/brownfield-adapt-user-home/.agentbundle/state.toml +0 -0
  262. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/argv-flag/SKILL.md +0 -0
  263. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/argv-flag/scripts/cli.py +0 -0
  264. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/argv-flag-derived/SKILL.md +0 -0
  265. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/argv-flag-derived/scripts/cli.py +0 -0
  266. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/argv-flag-normalised/SKILL.md +0 -0
  267. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/argv-flag-normalised/scripts/cli.py +0 -0
  268. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/conforming/SKILL.md +0 -0
  269. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/conforming/scripts/cli.py +0 -0
  270. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/dotfile-grep/SKILL.md +0 -0
  271. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/dotfile-grep/scripts/leak.py +0 -0
  272. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/dotfile-with-optout/SKILL.md +0 -0
  273. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/dotfile-with-optout/scripts/legit.py +0 -0
  274. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/mcp-server-headers/SKILL.md +0 -0
  275. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/mcp-server-headers/scripts/cli.py +0 -0
  276. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/creds/skills/missing-dont-block/SKILL.md +0 -0
  277. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/install/catalogue/packs/alpha/.apm/agents/helper.md +0 -0
  278. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/install/catalogue/packs/alpha/.apm/commands/cmd.md +0 -0
  279. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/install/catalogue/packs/alpha/.apm/hook-wiring/run.toml +0 -0
  280. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/install/catalogue/packs/alpha/.apm/hooks/run.sh +0 -0
  281. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/install/catalogue/packs/alpha/.apm/skills/example/SKILL.md +0 -0
  282. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/install/catalogue/packs/alpha/.claude-plugin/plugin.json +0 -0
  283. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/install/catalogue/packs/alpha/pack.toml +0 -0
  284. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/kiro_ide_hook/ask_agent_basic.kiro.hook +0 -0
  285. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/kiro_ide_hook/run_command_with_placeholder.kiro.hook +0 -0
  286. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/lint_packs/clean/pack.toml +0 -0
  287. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/lint_packs/clean/seeds/README.md +0 -0
  288. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/list-installed/golden_120col.txt +0 -0
  289. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/list-installed/golden_80col.txt +0 -0
  290. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/list_packs/catalogue/packs/alpha/pack.toml +0 -0
  291. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/list_packs/catalogue/packs/beta/pack.toml +0 -0
  292. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/local_scope/catalogue/packs/local-test-pack/.apm/skills/local-test/SKILL.md +0 -0
  293. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/local_scope/catalogue/packs/local-test-pack/pack.toml +0 -0
  294. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/cc-user-hooks/.apm/hook-wiring/on-prompt.toml +0 -0
  295. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/cc-user-hooks/.apm/hooks/on-prompt.sh +0 -0
  296. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/cc-user-hooks/pack.toml +0 -0
  297. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/kiro-repo-hooks/.apm/agents/reviewer.md +0 -0
  298. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/kiro-repo-hooks/.apm/hook-wiring/on-spawn.toml +0 -0
  299. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/kiro-repo-hooks/.apm/hooks/on-spawn.sh +0 -0
  300. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/kiro-repo-hooks/pack.toml +0 -0
  301. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/kiro-user-hooks/.apm/agents/reviewer.md +0 -0
  302. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/kiro-user-hooks/.apm/hook-wiring/on-spawn.toml +0 -0
  303. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/kiro-user-hooks/.apm/hooks/on-spawn.sh +0 -0
  304. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/kiro-user-hooks/pack.toml +0 -0
  305. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/malformed-kiro-missing-attach/.apm/agents/reviewer.md +0 -0
  306. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/malformed-kiro-missing-attach/.apm/hook-wiring/on-spawn.toml +0 -0
  307. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/malformed-kiro-missing-attach/.apm/hooks/on-spawn.sh +0 -0
  308. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/malformed-kiro-missing-attach/pack.toml +0 -0
  309. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/malformed-kiro-pascal-events/.apm/agents/reviewer.md +0 -0
  310. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/malformed-kiro-pascal-events/.apm/hook-wiring/on-spawn.toml +0 -0
  311. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/malformed-kiro-pascal-events/.apm/hooks/on-spawn.sh +0 -0
  312. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/malformed-kiro-pascal-events/pack.toml +0 -0
  313. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/malformed-kiro-unknown-agent/.apm/agents/reviewer.md +0 -0
  314. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/malformed-kiro-unknown-agent/.apm/hook-wiring/on-spawn.toml +0 -0
  315. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/malformed-kiro-unknown-agent/.apm/hooks/on-spawn.sh +0 -0
  316. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/packs/malformed-kiro-unknown-agent/pack.toml +0 -0
  317. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/scaffold/test-pack/seeds/AGENTS.md +0 -0
  318. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/scaffold/test-pack/seeds/_agents-footer.md +0 -0
  319. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/scaffold/test-pack/seeds/docs/CHARTER.md +0 -0
  320. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v1/packs/core/.apm/agents/reviewer.md +0 -0
  321. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v1/packs/core/.apm/commands/deploy.md +0 -0
  322. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v1/packs/core/.apm/hook-wiring/pre-commit.toml +0 -0
  323. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v1/packs/core/.apm/hooks/lint.py +0 -0
  324. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v1/packs/core/.apm/hooks/pre-commit.sh +0 -0
  325. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v1/packs/core/.apm/skills/work-loop/SKILL.md +0 -0
  326. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v1/packs/core/.claude-plugin/plugin.json +0 -0
  327. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v1/packs/core/pack.toml +0 -0
  328. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v2/packs/core/.apm/agents/reviewer.md +0 -0
  329. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v2/packs/core/.apm/commands/deploy.md +0 -0
  330. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v2/packs/core/.apm/hook-wiring/pre-commit.toml +0 -0
  331. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v2/packs/core/.apm/hooks/lint.py +0 -0
  332. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v2/packs/core/.apm/hooks/pre-commit.sh +0 -0
  333. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v2/packs/core/.apm/skills/work-loop/SKILL.md +0 -0
  334. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v2/packs/core/.claude-plugin/plugin.json +0 -0
  335. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v2/packs/core/pack.toml +0 -0
  336. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v3/packs/core/.apm/agents/reviewer.md +0 -0
  337. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v3/packs/core/.apm/commands/deploy.md +0 -0
  338. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v3/packs/core/.apm/hook-wiring/pre-commit.toml +0 -0
  339. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v3/packs/core/.apm/hooks/lint.py +0 -0
  340. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v3/packs/core/.apm/hooks/pre-commit.sh +0 -0
  341. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v3/packs/core/.apm/skills/work-loop/SKILL.md +0 -0
  342. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v3/packs/core/.claude-plugin/plugin.json +0 -0
  343. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/upgrade/catalogue_v3/packs/core/pack.toml +0 -0
  344. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/validate/bad_recipe_pack/pack.toml +0 -0
  345. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/validate/malformed_pack/pack.toml +0 -0
  346. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/validate/valid_pack/pack.toml +0 -0
  347. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/fixtures/validate/version_mismatch_pack/pack.toml +0 -0
  348. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/__init__.py +0 -0
  349. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_adapt_cmd.py +0 -0
  350. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_adapt_dual_scope.py +0 -0
  351. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_adapt_preflight_detection.py +0 -0
  352. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_adapt_schema_migration.py +0 -0
  353. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_apm_install_route.py +0 -0
  354. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_blank_catalogue.py +0 -0
  355. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_brownfield_adapt_end_to_end.py +0 -0
  356. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_brownfield_round_trip.py +0 -0
  357. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_brownfield_user_home_fixture.py +0 -0
  358. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_build_check_drift_gates.py +0 -0
  359. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_build_derivation_apm.py +0 -0
  360. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_build_derivation_claude_plugins.py +0 -0
  361. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_catalogue_init.py +0 -0
  362. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_cc_user_hooks_fixture.py +0 -0
  363. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_claude_plugins_install_route.py +0 -0
  364. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_config_cascade.py +0 -0
  365. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_credential_brokers_pack_install.py +0 -0
  366. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_credentials_wheel.py +0 -0
  367. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_discovery_schema_cross_consumer.py +0 -0
  368. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_editable_source_detection.py +0 -0
  369. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_fixtures_validate.py +0 -0
  370. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_hook_wiring_ingress.py +0 -0
  371. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_adapt_chain.py +0 -0
  372. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_cmd.py +0 -0
  373. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_converters_user_scope.py +0 -0
  374. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_copilot_full_parity.py +0 -0
  375. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_core_smoke.py +0 -0
  376. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_default_source.py +0 -0
  377. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_dependencies_gate.py +0 -0
  378. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_dropped_primitives_warning.py +0 -0
  379. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_dual_scope.py +0 -0
  380. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_orphan_reshape.py +0 -0
  381. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_pack_metadata_shape.py +0 -0
  382. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_profile.py +0 -0
  383. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_profile_live.py +0 -0
  384. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_repo_scope_per_adapter.py +0 -0
  385. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_research_user_scope.py +0 -0
  386. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_seed_delivery.py +0 -0
  387. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_session_start_wiring.py +0 -0
  388. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_upgrade_offer.py +0 -0
  389. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_user_hooks.py +0 -0
  390. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_install_user_scope_allowed_adapters.py +0 -0
  391. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_kiro_ide_hook_e2e.py +0 -0
  392. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_kiro_repo_hooks_fixture.py +0 -0
  393. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_kiro_user_hooks_fixture.py +0 -0
  394. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_list_packs_cmd.py +0 -0
  395. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_local_scope_install.py +0 -0
  396. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_marketplace_entry_validation.py +0 -0
  397. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_marketplace_manifest_regression.py +0 -0
  398. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_multi_pack_install.py +0 -0
  399. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_orphan_cleanup_respects_foreign_state.py +0 -0
  400. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_plugin_route_membership.py +0 -0
  401. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_recommends_cross_scope.py +0 -0
  402. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_reconcile.py +0 -0
  403. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_reserved_path_filter.py +0 -0
  404. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_scaffold_projection.py +0 -0
  405. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_self_host_schema_migration.py +0 -0
  406. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_self_host_sweep_respects_state.py +0 -0
  407. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_shared_prefix_coexistence.py +0 -0
  408. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_show_cmd.py +0 -0
  409. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_tier_invariants.py +0 -0
  410. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_uninstall_cmd.py +0 -0
  411. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_uninstall_user_hooks.py +0 -0
  412. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_upgrade_attach_to_agent.py +0 -0
  413. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_upgrade_cmd.py +0 -0
  414. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_upgrade_user_hooks.py +0 -0
  415. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_version_gate_matrix.py +0 -0
  416. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_workspace_mcp_git_fsm.py +0 -0
  417. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/integration/test_zipapp.py +0 -0
  418. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/test_adapter_permissions_projection.py +0 -0
  419. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/test_workspace_mcp_elicit.py +0 -0
  420. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/test_workspace_mcp_event_bridge.py +0 -0
  421. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/test_workspace_mcp_git.py +0 -0
  422. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/test_workspace_mcp_lifecycle.py +0 -0
  423. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/test_workspace_mcp_stdin.py +0 -0
  424. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/test_workspace_mcp_tools.py +0 -0
  425. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/__init__.py +0 -0
  426. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_adapt_discovery_schema.py +0 -0
  427. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_append_layout_section.py +0 -0
  428. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_architect_readme_install_command.py +0 -0
  429. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_ci_contract.py +0 -0
  430. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_curation_deps.py +0 -0
  431. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_init_cli_self_hosted.py +0 -0
  432. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_pack_defaults.py +0 -0
  433. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_self_hosted_export_removal.py +0 -0
  434. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_skill_spec_lint.py +0 -0
  435. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_tooling_archive.py +0 -0
  436. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_tooling_build.py +0 -0
  437. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_tooling_defaults.py +0 -0
  438. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_tooling_foundation.py +0 -0
  439. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_tooling_identity.py +0 -0
  440. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_tooling_init.py +0 -0
  441. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_tooling_lint.py +0 -0
  442. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_tooling_package.py +0 -0
  443. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_tooling_self_host.py +0 -0
  444. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_tooling_self_hosted_init.py +0 -0
  445. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_tooling_source_package.py +0 -0
  446. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_tooling_verify.py +0 -0
  447. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_wave2_schema.py +0 -0
  448. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_wave2_validation.py +0 -0
  449. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_wave3_contracts_cli.py +0 -0
  450. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_wave3_contracts_inspector.py +0 -0
  451. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_wave3_init_nextsteps.py +0 -0
  452. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_catalogue_wave3_offline_navigation.py +0 -0
  453. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_cli_catalogue_optional.py +0 -0
  454. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_cli_help_lists_config.py +0 -0
  455. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_cli_path_normalisation.py +0 -0
  456. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_cli_profile_surface.py +0 -0
  457. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_cli_scope_flags.py +0 -0
  458. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_codex_agent_toml.py +0 -0
  459. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_codex_projection_modes.py +0 -0
  460. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_common_classify_seeds.py +0 -0
  461. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_config.py +0 -0
  462. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_config_cmd.py +0 -0
  463. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_configured_adapter.py +0 -0
  464. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_confirm_helper.py +0 -0
  465. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_contract_parity.py +0 -0
  466. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_contract_v0_3_schema.py +0 -0
  467. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_copilot_agent_md.py +0 -0
  468. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_copilot_hooks_json.py +0 -0
  469. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_copilot_user_scope_wiring.py +0 -0
  470. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_credbroker_lint_hardening.py +0 -0
  471. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_dependencies_batch.py +0 -0
  472. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_diff_cmd.py +0 -0
  473. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_footprint_ownership.py +0 -0
  474. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_https_catalogue.py +0 -0
  475. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_init_state_cmd.py +0 -0
  476. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_install_argparse_adapter_flag.py +0 -0
  477. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_install_argparse_emit_install_routes.py +0 -0
  478. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_install_defaults_preferred_adapter.py +0 -0
  479. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_install_dropped_primitives_warning.py +0 -0
  480. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_install_event_dropped_wirings.py +0 -0
  481. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_install_first_value_handoff.py +0 -0
  482. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_install_force_help.py +0 -0
  483. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_install_inband_detection.py +0 -0
  484. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_install_messages.py +0 -0
  485. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_install_messages_repo_scope.py +0 -0
  486. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_install_refusal_ordering.py +0 -0
  487. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_install_state_provenance.py +0 -0
  488. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_kiro_ide_hook_projection.py +0 -0
  489. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_kiro_ide_hook_rail.py +0 -0
  490. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_kiro_ide_hook_schema.py +0 -0
  491. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_lint_agent_artifacts_metadata_auth.py +0 -0
  492. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_list_installed_cmd.py +0 -0
  493. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_list_installed_status.py +0 -0
  494. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_list_targets_cmd.py +0 -0
  495. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_local_scope_schema.py +0 -0
  496. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_local_scope_t10_uninstall.py +0 -0
  497. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_local_scope_t12_show.py +0 -0
  498. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_local_scope_t2_resolve.py +0 -0
  499. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_local_scope_t3_config.py +0 -0
  500. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_local_scope_t4_state_path.py +0 -0
  501. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_local_scope_t5_list_installed.py +0 -0
  502. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_local_scope_t7_install_gates.py +0 -0
  503. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_local_scope_t8_install.py +0 -0
  504. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_local_scope_t9_exclude.py +0 -0
  505. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_marker_schema_version_parity.py +0 -0
  506. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_merge_into_agent_json.py +0 -0
  507. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_multi_adapter_disambiguator.py +0 -0
  508. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_nested_symlink_hardening.py +0 -0
  509. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_org_bootstrap.py +0 -0
  510. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_pack_config_api.py +0 -0
  511. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_pack_inventory.py +0 -0
  512. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_package_catalogue.py +0 -0
  513. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_packstate_source_provenance.py +0 -0
  514. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_pipeline_phase_order.py +0 -0
  515. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_plugin_scope_filter.py +0 -0
  516. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_profile_reader.py +0 -0
  517. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_render.py +0 -0
  518. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_render_cmd.py +0 -0
  519. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_render_table.py +0 -0
  520. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_resolve_state_path.py +0 -0
  521. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_resolve_target_adapter_user_config.py +0 -0
  522. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_resolve_user_scope_target_adapter.py +0 -0
  523. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_safety.py +0 -0
  524. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_safety_repo_scope_prefixes.py +0 -0
  525. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_safety_scan_per_pack_scoping.py +0 -0
  526. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_scaffold_cmd.py +0 -0
  527. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_scope.py +0 -0
  528. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_self_host_windows.py +0 -0
  529. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_shared_prefix_disclosure.py +0 -0
  530. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_source_conflict_guard.py +0 -0
  531. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_source_defaults.py +0 -0
  532. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_state_v01_refuse_write.py +0 -0
  533. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_state_v02.py +0 -0
  534. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_state_v0_4_schema.py +0 -0
  535. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_statelock.py +0 -0
  536. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_target_resolver.py +0 -0
  537. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_toml_emitters.py +0 -0
  538. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_unresolved_markers.py +0 -0
  539. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_upgrade_bulk_all.py +0 -0
  540. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_upgrade_recap.py +0 -0
  541. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_upgrade_source_inference.py +0 -0
  542. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_user_config_io.py +0 -0
  543. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_user_config_isolation.py +0 -0
  544. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_user_config_path.py +0 -0
  545. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_user_config_source.py +0 -0
  546. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_user_merge_json.py +0 -0
  547. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_validate_attach_to_agent.py +0 -0
  548. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_validate_categories.py +0 -0
  549. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_validate_cmd.py +0 -0
  550. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_validate_hook_wiring_per_file_compatibility.py +0 -0
  551. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_values_from_shapes.py +0 -0
  552. {agentbundle-0.35.0 → agentbundle-0.35.1}/tests/unit/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentbundle
3
- Version: 0.35.0
3
+ Version: 0.35.1
4
4
  Summary: npm for your coding agent. Install packs of skills, subagents, and hooks into any repo, for every major agent.
5
5
  Author-email: eugenelim <eugenelim@users.noreply.github.com>
6
6
  License-Expression: Apache-2.0 OR MIT
@@ -182,6 +182,7 @@ def _verification_failure_message(
182
182
  *,
183
183
  fallback_note: str,
184
184
  offer_opt_out: bool = True,
185
+ empty_store: bool = False,
185
186
  ) -> str:
186
187
  """Explain a verification failure in terms of the adopter's next action.
187
188
 
@@ -196,13 +197,35 @@ def _verification_failure_message(
196
197
  the message never advises setting a variable that is already set.
197
198
  """
198
199
  host = urllib.parse.urlsplit(url).netloc
199
- steps = [
200
- " 1. Install from a local clone — needs no HTTPS at all:\n"
200
+
201
+ # Numbered at render time: the empty-store step only appears when it applies,
202
+ # and a hardcoded list would misnumber every step after it.
203
+ steps: list[str] = []
204
+ if empty_store:
205
+ # Almost certainly, not certainly: a populated capath is excluded before
206
+ # we get here, but the store could still be empty *and* the network
207
+ # inspected.
208
+ remedy = (
209
+ ' open "/Applications/Python 3.x/Install Certificates.command"\n'
210
+ " Or point it at the system bundle:\n"
211
+ " export SSL_CERT_FILE=/etc/ssl/cert.pem"
212
+ if sys.platform == "darwin"
213
+ else " install your certificate authorities into this "
214
+ "interpreter's trust\n"
215
+ " store, or set SSL_CERT_FILE to a PEM bundle containing them"
216
+ )
217
+ steps.append(
218
+ "This Python trusts ZERO certificate authorities, so every HTTPS\n"
219
+ " request from it fails — almost certainly not a corporate-proxy\n"
220
+ " problem. Fix the interpreter's trust store:\n" + remedy
221
+ )
222
+ steps += [
223
+ "Install from a local clone — needs no HTTPS at all:\n"
201
224
  " git clone <catalogue-repo> && agentbundle install --pack "
202
225
  "<pack> ./<clone>",
203
- " 2. Ask your IT team for the corporate CA bundle, then:\n"
226
+ "Ask your IT team for the corporate CA bundle, then:\n"
204
227
  " export AGENTBUNDLE_CA_BUNDLE=/path/to/corporate-ca.pem",
205
- " 3. Check whether a different Python already trusts this network. "
228
+ "Check whether a different Python already trusts this network. "
206
229
  "Interpreters\n"
207
230
  " do not share a certificate store, so one may work where another "
208
231
  "fails:\n"
@@ -212,7 +235,7 @@ def _verification_failure_message(
212
235
  " SSL_CERT_FILE at its cafile. Creating a virtualenv does NOT "
213
236
  "change trust —\n"
214
237
  " a venv inherits its base interpreter's store unchanged.",
215
- " 4. Confirm your proxy allows every host in the redirect chain. A "
238
+ "Confirm your proxy allows every host in the redirect chain. A "
216
239
  "GitHub\n"
217
240
  " archive fetch redirects github.com to codeload.github.com; an "
218
241
  "allowlist\n"
@@ -221,16 +244,24 @@ def _verification_failure_message(
221
244
  ]
222
245
  if offer_opt_out:
223
246
  steps.append(
224
- " 5. Set AGENTBUNDLE_NO_SYSTEM_TRUST=1 to see the raw "
225
- "verification error."
247
+ "Set AGENTBUNDLE_NO_SYSTEM_TRUST=1 to see the raw verification error."
248
+ )
249
+ body = "\n\n".join(f" {n}. {s}" for n, s in enumerate(steps, start=1))
250
+
251
+ if empty_store:
252
+ diagnosis = (
253
+ f"The certificate for {host} could not be verified. {fallback_note}"
254
+ )
255
+ else:
256
+ diagnosis = (
257
+ f"The certificate for {host} could not be verified. {fallback_note} On "
258
+ "a corporate network this usually means a TLS-inspecting proxy "
259
+ "re-signs traffic with a private root CA that Python does not read."
226
260
  )
227
- body = "\n\n".join(steps)
228
261
  return (
229
262
  f"Failed to fetch catalogue archive: {url} — {detail}\n"
230
263
  "\n"
231
- f"The certificate for {host} could not be verified. {fallback_note} On a "
232
- "corporate network this usually means a TLS-inspecting proxy re-signs "
233
- "traffic with a private root CA that Python does not read.\n"
264
+ f"{diagnosis}\n"
234
265
  "\n"
235
266
  "Troubleshooting, cheapest first:\n"
236
267
  "\n"
@@ -253,15 +284,29 @@ def _fetch_and_extract(url: str, dest: Path) -> None:
253
284
  system_trust = _system_trust_module()
254
285
 
255
286
  def attempt(context: ssl.SSLContext) -> None:
287
+ # Buffer to a seekable temporary file rather than extracting straight
288
+ # from the response, because "r|gz" is forward-only and that breaks on
289
+ # Windows. A catalogue carries symlinks (CLAUDE.md -> AGENTS.md); when
290
+ # os.symlink is unavailable — the default on Windows without Developer
291
+ # Mode or SeCreateSymbolicLink — tarfile falls back to copying the link
292
+ # target, which means re-reading a member the stream has already passed.
293
+ # On a forward-only stream that raises
294
+ # "seeking backwards is not allowed"; "r:gz" over a real file lets the
295
+ # fallback do its job. Observed in the field on Windows; macOS and Linux
296
+ # never hit it because os.symlink succeeds there.
297
+ #
256
298
  # B310: constant github.com archive base assembled from parsed owner/repo/ref.
257
299
  with urllib.request.urlopen( # nosec B310
258
300
  url, timeout=_FETCH_TIMEOUT_S, context=context
259
- ) as resp, tarfile.open(fileobj=resp, mode="r|gz") as tf:
260
- # filter="data" rejects unsafe members (absolute paths, ..
261
- # links, devices, setuid bits) — Python 3.12+ default but
262
- # explicit for 3.11 compatibility and to silence the 3.14
263
- # DeprecationWarning. Path-jail is belt; this is braces.
264
- tf.extractall(path=dest, filter="data")
301
+ ) as resp, tempfile.TemporaryFile() as spool:
302
+ shutil.copyfileobj(resp, spool)
303
+ spool.seek(0)
304
+ with tarfile.open(fileobj=spool, mode="r:gz") as tf:
305
+ # filter="data" rejects unsafe members (absolute paths, ..
306
+ # links, devices, setuid bits) — Python 3.12+ default but
307
+ # explicit for 3.11 compatibility and to silence the 3.14
308
+ # DeprecationWarning. Path-jail is belt; this is braces.
309
+ tf.extractall(path=dest, filter="data")
265
310
 
266
311
  try:
267
312
  attempt(system_trust.build_context())
@@ -292,7 +337,13 @@ def _fetch_and_extract(url: str, dest: Path) -> None:
292
337
  # administrator trust store to read, a second connection against an
293
338
  # identical context would be pure noise, and claiming the anchors "did
294
339
  # not complete the chain" would send the adopter after the wrong cause.
295
- anchors = system_trust.system_anchor_pem()
340
+ # An interpreter with an empty trust store is a different fault from an
341
+ # inspected network: nothing verifies, and the administrator keychain
342
+ # alone cannot repair it because it holds private roots, not public ones.
343
+ # Observed in the field on a python.org macOS build whose
344
+ # Install Certificates.command was never run.
345
+ empty_store = system_trust.default_store_is_empty()
346
+ anchors = system_trust.system_anchor_pem(include_public_roots=empty_store)
296
347
  if not anchors:
297
348
  # Two different causes, and conflating them misdirects the adopter.
298
349
  # Off macOS the fallback does not apply at all. *On* macOS it applied
@@ -314,9 +365,11 @@ def _fetch_and_extract(url: str, dest: Path) -> None:
314
365
  "the operating system's trust store."
315
366
  )
316
367
  raise CatalogueError(
317
- _verification_failure_message(url, detail, fallback_note=note)
368
+ _verification_failure_message(
369
+ url, detail, fallback_note=note, empty_store=empty_store
370
+ )
318
371
  ) from exc
319
- _retry_with_system_trust(url, dest, attempt, anchors)
372
+ _retry_with_system_trust(url, dest, attempt, anchors, empty_store=empty_store)
320
373
  except tarfile.TarError as exc:
321
374
  raise CatalogueError(
322
375
  f"Failed to extract tarball from {url}: {exc}"
@@ -328,6 +381,8 @@ def _retry_with_system_trust(
328
381
  dest: Path,
329
382
  attempt: Callable[[ssl.SSLContext], None],
330
383
  anchors: str,
384
+ *,
385
+ empty_store: bool = False,
331
386
  ) -> None:
332
387
  """Retry *attempt* once against operating-system trust *anchors*.
333
388
 
@@ -339,14 +394,48 @@ def _retry_with_system_trust(
339
394
  """
340
395
  system_trust = _system_trust_module()
341
396
  host = urllib.parse.urlsplit(url).netloc
342
- print(
343
- f"agentbundle: certificate verification failed for {host}; "
344
- "retrying with operating-system trust anchors",
345
- file=sys.stderr,
346
- )
347
- exhausted = (
348
- "The operating-system trust anchors did not complete the chain either."
349
- )
397
+ if empty_store:
398
+ # Recovering the fetch is not the same as fixing the interpreter: the
399
+ # anchors are loaded in memory for this process only. Saying so is the
400
+ # difference between a one-off rescue and quietly masking a broken
401
+ # Python that will fail the adopter's next pip or requests call.
402
+ # Name the wider trust set explicitly. The narrow decision was already
403
+ # auditable; this one adds a public root set on top, and a trust decision
404
+ # the adopter cannot see is one they cannot audit.
405
+ extra = (
406
+ "the administrator keychain plus the system public certificate "
407
+ "bundle" if sys.platform == "darwin" else "operating-system trust anchors"
408
+ )
409
+ fix = (
410
+ ' open "/Applications/Python 3.x/Install Certificates.command"\n'
411
+ " (or: export SSL_CERT_FILE=/etc/ssl/cert.pem)"
412
+ if sys.platform == "darwin"
413
+ else " install your certificate authorities into this interpreter's\n"
414
+ " trust store, or set SSL_CERT_FILE to a PEM bundle"
415
+ )
416
+ print(
417
+ f"agentbundle: this Python trusts no certificate authorities, so "
418
+ f"verification failed for {host}. Retrying against {extra} — this "
419
+ "rescues the install but does not fix the interpreter, so every "
420
+ "other tool will keep failing. To stop that:\n" + fix,
421
+ file=sys.stderr,
422
+ )
423
+ else:
424
+ print(
425
+ f"agentbundle: certificate verification failed for {host}; "
426
+ "retrying with operating-system trust anchors",
427
+ file=sys.stderr,
428
+ )
429
+ if empty_store:
430
+ exhausted = (
431
+ "This Python trusts no certificate authority at all — its trust store "
432
+ "is empty — and the operating-system anchors did not complete the "
433
+ "chain either."
434
+ )
435
+ else:
436
+ exhausted = (
437
+ "The operating-system trust anchors did not complete the chain either."
438
+ )
350
439
  # Attempt 1 may have extracted part of the archive before failing mid-stream.
351
440
  # Clearing the destination keeps the retry from layering a second download
352
441
  # over the first and producing a catalogue that is a mix of both.
@@ -359,7 +448,9 @@ def _retry_with_system_trust(
359
448
  # wrapped by urlopen and would otherwise escape as a bare exception.
360
449
  detail = getattr(exc, "reason", None) or exc
361
450
  raise CatalogueError(
362
- _verification_failure_message(url, detail, fallback_note=exhausted)
451
+ _verification_failure_message(
452
+ url, detail, fallback_note=exhausted, empty_store=empty_store
453
+ )
363
454
  ) from exc
364
455
  except tarfile.TarError as exc:
365
456
  raise CatalogueError(
@@ -58,22 +58,36 @@ from pathlib import Path
58
58
 
59
59
  from agentbundle.catalogue import CatalogueError
60
60
 
61
- # One keychain, deliberately. ``System.keychain`` needs administrator or MDM
62
- # rights to write, and it is where a corporate proxy root actually lands — so it
63
- # is the only store that holds the material this feature exists to find.
64
- #
65
- # Apple's ``SystemRootCertificates.keychain`` is *not* read. The retry context
66
- # already starts from ``create_default_context()``, so the public roots are
67
- # present; adding Apple's root program on top would widen trust to a second,
68
- # independently curated set for no gain. Measured on a corporate host: reading
69
- # System.keychain alone produced exactly the same anchor count as reading both,
70
- # i.e. Apple's keychain contributed nothing while enlarging the trust surface on
71
- # the one fetch path with no post-transport integrity check.
61
+ # The administrator keychain, always. It needs administrator or MDM rights to
62
+ # write, and it is where a corporate proxy root actually lands — so it is the
63
+ # store that holds the material this feature exists to find.
72
64
  #
73
65
  # The user's ``login.keychain-db`` is absent and must stay absent: it is writable
74
66
  # without administrator rights, so a root landing there is not an IT decision.
75
67
  _ADMIN_KEYCHAINS = ("/Library/Keychains/System.keychain",)
76
68
 
69
+ # Apple's public TLS roots, read **only** when the default trust store holds no
70
+ # anchors — see ``system_anchor_pem``. RFC-0086 D4 excluded Apple's material
71
+ # outright; the erratum narrows that to this one state, where an interpreter
72
+ # trusts nothing and the administrator keychain cannot repair it because it holds
73
+ # private roots.
74
+ #
75
+ # Read the *file*, not the keychain, and the distinction is load-bearing.
76
+ # ``/etc/ssl/cert.pem`` is Apple's own TLS-purpose export: root-owned, and
77
+ # measured on a current host it carries 128 certificates and **zero**
78
+ # Apple-operated roots. Dumping ``SystemRootCertificates.keychain`` instead
79
+ # yields 158, of which 14 are Apple-operated and several are single-purpose —
80
+ # ``Apple Platform Code Signing {ECC,RSA} Root CA``, ``Developer ID
81
+ # Certification Authority``, ``Apple Platform Bootstrap ECC Root CA``. None of
82
+ # those carry an EKU extension, so OpenSSL's server-auth purpose check does not
83
+ # exclude them; Apple confines them through trust settings, which
84
+ # ``find-certificate`` discards. Trusting code-signing roots for TLS is not what
85
+ # an unconfigured interpreter was missing. The file also needs no subprocess.
86
+ _APPLE_TLS_BUNDLE = "/etc/ssl/cert.pem"
87
+
88
+ # Fallback only, if the export above is absent on some macOS version.
89
+ _APPLE_ROOT_KEYCHAIN = "/System/Library/Keychains/SystemRootCertificates.keychain"
90
+
77
91
  _SECURITY_BIN = "/usr/bin/security"
78
92
 
79
93
  _PEM_MARKER = "BEGIN CERTIFICATE"
@@ -136,8 +150,47 @@ def resolve_trust_paths(env: dict | None = None) -> tuple[str | None, str | None
136
150
  return (cafile or None, capath or None)
137
151
 
138
152
 
139
- def system_anchor_pem() -> str | None:
140
- """Return administrator-keychain certificates as PEM text, or ``None``.
153
+ def default_store_is_empty(env: dict | None = None) -> bool:
154
+ """True when this interpreter trusts no certificate authority at all.
155
+
156
+ Distinct from a corporate-network failure and far more common than it looks:
157
+ a python.org macOS interpreter whose ``Install Certificates.command`` was
158
+ never run reports ``cafile=None`` and loads zero anchors, so *every* HTTPS
159
+ request fails, not just ones crossing an inspecting proxy.
160
+
161
+ Zero is the trigger, deliberately — not a threshold. A small store may be a
162
+ legitimate pinned bundle; an empty one cannot verify anything and is always
163
+ a broken or unconfigured interpreter.
164
+
165
+ A populated ``capath`` disqualifies the interpreter from this diagnosis even
166
+ when the count reads zero: OpenSSL loads a hashed directory lazily, so
167
+ ``get_ca_certs()`` reports nothing until a certificate from it has been used.
168
+ Such an interpreter may well be verifying fine, and calling it empty would
169
+ both widen its trust and tell an adopter behind a real proxy that their
170
+ problem is something else.
171
+ """
172
+ # One try around everything: resolve_trust_paths raises CatalogueError (a
173
+ # ValueError) on a bundle path that vanished between the caller's first
174
+ # attempt and this check, and this helper is called from inside an `except`
175
+ # block where an escape would mask the original error.
176
+ try:
177
+ capath = resolve_trust_paths(env)[1] or ssl.get_default_verify_paths().capath
178
+ if capath:
179
+ with contextlib.suppress(OSError):
180
+ if any(Path(capath).iterdir()):
181
+ return False
182
+ return not build_context(env).get_ca_certs()
183
+ except (OSError, ssl.SSLError, ValueError):
184
+ return False
185
+
186
+
187
+ def system_anchor_pem(*, include_public_roots: bool = False) -> str | None:
188
+ """Return operating-system keychain certificates as PEM text, or ``None``.
189
+
190
+ Reads the administrator keychain. When *include_public_roots* is set — which
191
+ the caller decides by asking ``default_store_is_empty`` — Apple's root
192
+ program is read as well, because an interpreter that trusts nothing cannot be
193
+ repaired from private roots alone.
141
194
 
142
195
  macOS only, because it is the only platform where Python does not already
143
196
  consult the operating system's trust store — see the module docstring. Every
@@ -157,8 +210,23 @@ def system_anchor_pem() -> str | None:
157
210
  if sys.platform != "darwin":
158
211
  return None
159
212
 
213
+ keychains = _ADMIN_KEYCHAINS
160
214
  chunks: list[str] = []
161
- for keychain in _ADMIN_KEYCHAINS:
215
+
216
+ if include_public_roots:
217
+ bundle = Path(_APPLE_TLS_BUNDLE)
218
+ loaded = False
219
+ with contextlib.suppress(OSError):
220
+ text = bundle.read_text(encoding="utf-8", errors="replace")
221
+ if _PEM_MARKER in text:
222
+ chunks.append(text)
223
+ loaded = True
224
+ if not loaded:
225
+ # The export is missing; fall back to the keychain rather than
226
+ # leaving an interpreter that trusts nothing with no route at all.
227
+ keychains = (*_ADMIN_KEYCHAINS, _APPLE_ROOT_KEYCHAIN)
228
+
229
+ for keychain in keychains:
162
230
  argv = [_SECURITY_BIN, "find-certificate", "-a", "-p", keychain]
163
231
  try:
164
232
  out = _RUNNER(argv)
@@ -14,7 +14,7 @@ import tomllib
14
14
  from importlib.resources import files
15
15
  from pathlib import Path
16
16
 
17
- CLI_VERSION = "0.35.0"
17
+ CLI_VERSION = "0.35.1"
18
18
 
19
19
  _HERE = Path(__file__).resolve().parent
20
20
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentbundle
3
- Version: 0.35.0
3
+ Version: 0.35.1
4
4
  Summary: npm for your coding agent. Install packs of skills, subagents, and hooks into any repo, for every major agent.
5
5
  Author-email: eugenelim <eugenelim@users.noreply.github.com>
6
6
  License-Expression: Apache-2.0 OR MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "agentbundle"
7
- version = "0.35.0"
7
+ version = "0.35.1"
8
8
  description = "npm for your coding agent. Install packs of skills, subagents, and hooks into any repo, for every major agent."
9
9
  requires-python = ">=3.11"
10
10
  dependencies = []
@@ -128,7 +128,7 @@ def test_attempt_one_genuinely_fails_against_an_unknown_authority(
128
128
  tls_server, tmp_path, monkeypatch
129
129
  ):
130
130
  """The premise: without the authority, real TLS verification fails."""
131
- monkeypatch.setattr(system_trust, "system_anchor_pem", lambda: None)
131
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: None)
132
132
  with pytest.raises(CatalogueError) as exc:
133
133
  catalogue._fetch_and_extract(tls_server, tmp_path)
134
134
  assert "could not be verified" in str(exc.value)
@@ -145,7 +145,7 @@ def test_the_fallback_recovers_a_real_failing_handshake(
145
145
  import agentbundle.system_trust as st
146
146
 
147
147
  original = st.system_anchor_pem
148
- st.system_anchor_pem = lambda: tls_fixtures["ca_pem"]
148
+ st.system_anchor_pem = lambda **k: tls_fixtures["ca_pem"]
149
149
  try:
150
150
  catalogue._fetch_and_extract(tls_server, tmp_path)
151
151
  finally:
@@ -166,7 +166,7 @@ def test_a_dirty_dump_still_recovers(tls_server, tls_fixtures, tmp_path):
166
166
 
167
167
  garbage = "-----BEGIN CERTIFICATE-----\nnot base64\n-----END CERTIFICATE-----\n"
168
168
  original = st.system_anchor_pem
169
- st.system_anchor_pem = lambda: garbage + tls_fixtures["ca_pem"] + garbage
169
+ st.system_anchor_pem = lambda **k: garbage + tls_fixtures["ca_pem"] + garbage
170
170
  try:
171
171
  catalogue._fetch_and_extract(tls_server, tmp_path)
172
172
  finally:
@@ -181,7 +181,7 @@ def test_opt_out_refuses_to_recover(tls_server, tls_fixtures, tmp_path, monkeypa
181
181
  import agentbundle.system_trust as st
182
182
 
183
183
  original = st.system_anchor_pem
184
- st.system_anchor_pem = lambda: tls_fixtures["ca_pem"]
184
+ st.system_anchor_pem = lambda **k: tls_fixtures["ca_pem"]
185
185
  try:
186
186
  with pytest.raises(CatalogueError) as exc:
187
187
  catalogue._fetch_and_extract(tls_server, tmp_path)
@@ -11,6 +11,7 @@ only, per the convention in test_https_catalogue.py.
11
11
  from __future__ import annotations
12
12
 
13
13
  import io
14
+ import os
14
15
  import ssl
15
16
  import sys
16
17
  import tarfile
@@ -104,7 +105,7 @@ def test_verification_failure_retries_once_with_system_anchors(
104
105
  ):
105
106
  stub = _Stub([_verify_error(), _tarball()])
106
107
  monkeypatch.setattr(urllib.request, "urlopen", stub)
107
- monkeypatch.setattr(system_trust, "system_anchor_pem", _an_anchor_pem)
108
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: _an_anchor_pem())
108
109
 
109
110
  catalogue._fetch_and_extract(URL, tmp_path)
110
111
 
@@ -125,7 +126,7 @@ def test_retry_uses_a_different_context_carrying_the_anchors(
125
126
  """
126
127
  stub = _Stub([_verify_error(), _tarball()])
127
128
  monkeypatch.setattr(urllib.request, "urlopen", stub)
128
- monkeypatch.setattr(system_trust, "system_anchor_pem", _an_anchor_pem)
129
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: _an_anchor_pem())
129
130
 
130
131
  catalogue._fetch_and_extract(URL, tmp_path)
131
132
 
@@ -147,7 +148,7 @@ def test_no_retry_when_no_system_anchors_are_available(
147
148
  monkeypatch.setattr(sys, "platform", "linux")
148
149
  stub = _Stub([_verify_error()])
149
150
  monkeypatch.setattr(urllib.request, "urlopen", stub)
150
- monkeypatch.setattr(system_trust, "system_anchor_pem", lambda: None)
151
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: None)
151
152
 
152
153
  with pytest.raises(CatalogueError) as exc:
153
154
  catalogue._fetch_and_extract(URL, tmp_path)
@@ -168,7 +169,7 @@ def test_empty_admin_keychain_on_macos_names_the_real_cause(
168
169
  monkeypatch.setattr(sys, "platform", "darwin")
169
170
  stub = _Stub([_verify_error()])
170
171
  monkeypatch.setattr(urllib.request, "urlopen", stub)
171
- monkeypatch.setattr(system_trust, "system_anchor_pem", lambda: None)
172
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: None)
172
173
 
173
174
  with pytest.raises(CatalogueError) as exc:
174
175
  catalogue._fetch_and_extract(URL, tmp_path)
@@ -182,7 +183,7 @@ def test_empty_admin_keychain_on_macos_names_the_real_cause(
182
183
  def test_fallback_notice_fires_once(monkeypatch, tmp_path, capsys, no_env):
183
184
  stub = _Stub([_verify_error(), _tarball()])
184
185
  monkeypatch.setattr(urllib.request, "urlopen", stub)
185
- monkeypatch.setattr(system_trust, "system_anchor_pem", _an_anchor_pem)
186
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: _an_anchor_pem())
186
187
  catalogue._fetch_and_extract(URL, tmp_path)
187
188
  err = capsys.readouterr().err
188
189
  assert err.count("retrying with operating-system trust anchors") == 1, err
@@ -218,7 +219,7 @@ def test_opt_out_suppresses_the_retry(monkeypatch, tmp_path, no_env):
218
219
  def test_retry_failure_raises_catalogue_error(monkeypatch, tmp_path, no_env):
219
220
  stub = _Stub([_verify_error(), _verify_error()])
220
221
  monkeypatch.setattr(urllib.request, "urlopen", stub)
221
- monkeypatch.setattr(system_trust, "system_anchor_pem", _an_anchor_pem)
222
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: _an_anchor_pem())
222
223
  with pytest.raises(CatalogueError):
223
224
  catalogue._fetch_and_extract(URL, tmp_path)
224
225
  assert len(stub.calls) == 2
@@ -232,7 +233,7 @@ def test_retry_failure_raises_catalogue_error(monkeypatch, tmp_path, no_env):
232
233
  def test_unrepairable_failure_names_cause_and_next_action(monkeypatch, tmp_path, no_env):
233
234
  stub = _Stub([_verify_error(), _verify_error()])
234
235
  monkeypatch.setattr(urllib.request, "urlopen", stub)
235
- monkeypatch.setattr(system_trust, "system_anchor_pem", _an_anchor_pem)
236
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: _an_anchor_pem())
236
237
  with pytest.raises(CatalogueError) as exc:
237
238
  catalogue._fetch_and_extract(URL, tmp_path)
238
239
  message = str(exc.value)
@@ -252,7 +253,7 @@ def test_message_does_not_recommend_a_virtualenv_as_a_fix(monkeypatch, tmp_path,
252
253
  """
253
254
  stub = _Stub([_verify_error(), _verify_error()])
254
255
  monkeypatch.setattr(urllib.request, "urlopen", stub)
255
- monkeypatch.setattr(system_trust, "system_anchor_pem", _an_anchor_pem)
256
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: _an_anchor_pem())
256
257
  with pytest.raises(CatalogueError) as exc:
257
258
  catalogue._fetch_and_extract(URL, tmp_path)
258
259
  message = str(exc.value)
@@ -293,3 +294,156 @@ def test_read_phase_failures_are_wrapped_not_leaked(monkeypatch, tmp_path, no_en
293
294
  catalogue._fetch_and_extract(URL, tmp_path)
294
295
  assert URL in str(exc.value)
295
296
  assert len(stub.calls) == 1, "a non-certificate failure must not retry"
297
+
298
+
299
+ def test_empty_store_message_names_the_real_cause(monkeypatch, tmp_path, no_env):
300
+ """Your user's exact state: zero anchors, no proxy, admin keychain no help.
301
+
302
+ The old message blamed a TLS-inspecting proxy, which was actively
303
+ misleading — nothing was intercepting them.
304
+ """
305
+ monkeypatch.setattr(sys, "platform", "darwin")
306
+ monkeypatch.setattr(system_trust, "default_store_is_empty", lambda *a, **k: True)
307
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: _an_anchor_pem())
308
+ stub = _Stub([_verify_error(), _verify_error()])
309
+ monkeypatch.setattr(urllib.request, "urlopen", stub)
310
+
311
+ with pytest.raises(CatalogueError) as exc:
312
+ catalogue._fetch_and_extract(URL, tmp_path)
313
+
314
+ message = str(exc.value)
315
+ assert "trusts ZERO certificate authorities" in message
316
+ assert "Install Certificates.command" in message
317
+ # Softened from an absolute after security review: a populated capath is
318
+ # excluded before we get here, but a store can still be empty AND the
319
+ # network inspected.
320
+ assert "almost certainly not a corporate-proxy" in message
321
+ assert "TLS-inspecting proxy" not in message, "must not blame a proxy here"
322
+
323
+
324
+ def test_empty_store_asks_for_public_roots(monkeypatch, tmp_path, no_env):
325
+ """The fallback must widen to Apple's roots only in the empty-store case."""
326
+ calls: list[bool] = []
327
+
328
+ def anchors(*, include_public_roots: bool = False):
329
+ calls.append(include_public_roots)
330
+ return _an_anchor_pem()
331
+
332
+ monkeypatch.setattr(system_trust, "system_anchor_pem", anchors)
333
+ monkeypatch.setattr(urllib.request, "urlopen", _Stub([_verify_error(), _tarball()]))
334
+
335
+ monkeypatch.setattr(system_trust, "default_store_is_empty", lambda *a, **k: True)
336
+ catalogue._fetch_and_extract(URL, tmp_path)
337
+ assert calls == [True], "empty store must request the public roots"
338
+
339
+ calls.clear()
340
+ monkeypatch.setattr(system_trust, "default_store_is_empty", lambda *a, **k: False)
341
+ monkeypatch.setattr(urllib.request, "urlopen", _Stub([_verify_error(), _tarball()]))
342
+ catalogue._fetch_and_extract(URL, tmp_path)
343
+ assert calls == [False], "intact store must not request the public roots"
344
+
345
+
346
+ def test_successful_empty_store_recovery_still_tells_the_adopter(
347
+ monkeypatch, tmp_path, capsys, no_env
348
+ ):
349
+ """Recovering the fetch must not silently mask a broken interpreter.
350
+
351
+ The anchors are loaded in memory for this process only, so the adopter's
352
+ next pip or requests call fails the same way. A green install with no
353
+ explanation is how that goes unnoticed.
354
+ """
355
+ monkeypatch.setattr(system_trust, "default_store_is_empty", lambda *a, **k: True)
356
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: _an_anchor_pem())
357
+ monkeypatch.setattr(urllib.request, "urlopen", _Stub([_verify_error(), _tarball()]))
358
+
359
+ monkeypatch.setattr(sys, "platform", "darwin")
360
+ catalogue._fetch_and_extract(URL, tmp_path)
361
+
362
+ err = capsys.readouterr().err
363
+ assert "trusts no certificate authorities" in err
364
+ assert "does not fix the interpreter" in err
365
+ # Pin the platform: the remedy is macOS-specific, so asserting it without
366
+ # pinning passes on a developer's Mac and fails on a Linux runner.
367
+ assert "Install Certificates.command" in err
368
+ assert (tmp_path / "repo-main" / "pack.toml").exists(), "install must still succeed"
369
+
370
+
371
+ def test_empty_store_notice_off_macos_omits_mac_only_advice(
372
+ monkeypatch, tmp_path, capsys, no_env
373
+ ):
374
+ """The same misdirection this change removes, in the other direction.
375
+
376
+ Telling a Linux adopter to open an /Applications path is the macOS-only
377
+ remedy leaking onto a platform that cannot use it.
378
+ """
379
+ monkeypatch.setattr(sys, "platform", "linux")
380
+ monkeypatch.setattr(system_trust, "default_store_is_empty", lambda *a, **k: True)
381
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: _an_anchor_pem())
382
+ monkeypatch.setattr(urllib.request, "urlopen", _Stub([_verify_error(), _tarball()]))
383
+
384
+ catalogue._fetch_and_extract(URL, tmp_path)
385
+
386
+ err = capsys.readouterr().err
387
+ assert "trusts no certificate authorities" in err
388
+ assert "Install Certificates.command" not in err
389
+ assert "SSL_CERT_FILE" in err
390
+
391
+
392
+ def test_intact_store_recovery_keeps_the_short_notice(
393
+ monkeypatch, tmp_path, capsys, no_env
394
+ ):
395
+ """The corporate case is not an unconfigured interpreter — don't say it is."""
396
+ monkeypatch.setattr(system_trust, "default_store_is_empty", lambda *a, **k: False)
397
+ monkeypatch.setattr(system_trust, "system_anchor_pem", lambda **k: _an_anchor_pem())
398
+ monkeypatch.setattr(urllib.request, "urlopen", _Stub([_verify_error(), _tarball()]))
399
+
400
+ catalogue._fetch_and_extract(URL, tmp_path)
401
+
402
+ err = capsys.readouterr().err
403
+ assert "retrying with operating-system trust anchors" in err
404
+ assert "trusts no certificate authorities" not in err
405
+
406
+
407
+ def _tarball_with_symlink() -> bytes:
408
+ """A catalogue-shaped archive: a regular file, then a symlink pointing back.
409
+
410
+ This is the real shape — the catalogue carries CLAUDE.md -> AGENTS.md, and
411
+ the target precedes the link in the archive.
412
+ """
413
+ buf = io.BytesIO()
414
+ with tarfile.open(fileobj=buf, mode="w:gz") as tf:
415
+ payload = b"# agents\n"
416
+ target = tarfile.TarInfo("repo-main/AGENTS.md")
417
+ target.size = len(payload)
418
+ tf.addfile(target, io.BytesIO(payload))
419
+ link = tarfile.TarInfo("repo-main/CLAUDE.md")
420
+ link.type = tarfile.SYMTYPE
421
+ link.linkname = "AGENTS.md"
422
+ tf.addfile(link)
423
+ return buf.getvalue()
424
+
425
+
426
+ def test_symlink_archive_extracts_where_symlinks_cannot_be_created(
427
+ monkeypatch, tmp_path, no_env
428
+ ):
429
+ """Windows regression: os.symlink fails, so tarfile copies the target instead.
430
+
431
+ That fallback re-reads a member that already went past, which a forward-only
432
+ stream cannot do — the field error was
433
+ 'seeking backwards is not allowed'. Simulated here by making os.symlink
434
+ fail, so the case is covered on every platform rather than only on Windows.
435
+ """
436
+ def no_symlinks(*a, **k):
437
+ raise OSError("symbolic link privilege not held")
438
+
439
+ monkeypatch.setattr(os, "symlink", no_symlinks)
440
+ monkeypatch.setattr(
441
+ urllib.request, "urlopen", _Stub([_tarball_with_symlink()])
442
+ )
443
+
444
+ catalogue._fetch_and_extract(URL, tmp_path)
445
+
446
+ assert (tmp_path / "repo-main" / "AGENTS.md").exists()
447
+ claude = tmp_path / "repo-main" / "CLAUDE.md"
448
+ assert claude.exists(), "the link target must be copied when links are unavailable"
449
+ assert claude.read_text() == "# agents\n", "copy must carry the target's content"