soup-cli 0.71.1__tar.gz → 0.71.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 (773) hide show
  1. {soup_cli-0.71.1 → soup_cli-0.71.2}/CHANGELOG.md +39 -0
  2. {soup_cli-0.71.1 → soup_cli-0.71.2}/CONTRIBUTING.md +3 -1
  3. {soup_cli-0.71.1 → soup_cli-0.71.2}/PKG-INFO +17 -14
  4. {soup_cli-0.71.1 → soup_cli-0.71.2}/README.md +13 -13
  5. {soup_cli-0.71.1 → soup_cli-0.71.2}/docs/adapters-and-governance.md +54 -14
  6. {soup_cli-0.71.1 → soup_cli-0.71.2}/docs/commands.md +5 -3
  7. {soup_cli-0.71.1 → soup_cli-0.71.2}/pyproject.toml +6 -2
  8. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/__init__.py +1 -1
  9. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/adapters.py +110 -21
  10. soup_cli-0.71.2/src/soup_cli/commands/attest.py +226 -0
  11. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_sign.py +154 -11
  12. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/attest.py +47 -11
  13. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/hubs.py +101 -2
  14. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/license_matrix.py +185 -0
  15. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/namespace_pin.py +79 -9
  16. soup_cli-0.71.2/src/soup_cli/utils/signing.py +247 -0
  17. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0538.py +8 -1
  18. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0570_part_b.py +4 -0
  19. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0600_part_b.py +8 -3
  20. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0600_part_e.py +7 -4
  21. soup_cli-0.71.2/tests/test_v0712.py +1554 -0
  22. soup_cli-0.71.1/src/soup_cli/commands/attest.py +0 -90
  23. {soup_cli-0.71.1 → soup_cli-0.71.2}/.dockerignore +0 -0
  24. {soup_cli-0.71.1 → soup_cli-0.71.2}/.github/FUNDING.yml +0 -0
  25. {soup_cli-0.71.1 → soup_cli-0.71.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  26. {soup_cli-0.71.1 → soup_cli-0.71.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  27. {soup_cli-0.71.1 → soup_cli-0.71.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  28. {soup_cli-0.71.1 → soup_cli-0.71.2}/.github/pull_request_template.md +0 -0
  29. {soup_cli-0.71.1 → soup_cli-0.71.2}/.github/workflows/ci.yml +0 -0
  30. {soup_cli-0.71.1 → soup_cli-0.71.2}/.github/workflows/docker.yml +0 -0
  31. {soup_cli-0.71.1 → soup_cli-0.71.2}/.github/workflows/publish.yml +0 -0
  32. {soup_cli-0.71.1 → soup_cli-0.71.2}/.github/workflows/recipe-validation.yml +0 -0
  33. {soup_cli-0.71.1 → soup_cli-0.71.2}/.gitignore +0 -0
  34. {soup_cli-0.71.1 → soup_cli-0.71.2}/.pre-commit-config.yaml +0 -0
  35. {soup_cli-0.71.1 → soup_cli-0.71.2}/AGENTS.md +0 -0
  36. {soup_cli-0.71.1 → soup_cli-0.71.2}/CODEOWNERS +0 -0
  37. {soup_cli-0.71.1 → soup_cli-0.71.2}/CODE_OF_CONDUCT.md +0 -0
  38. {soup_cli-0.71.1 → soup_cli-0.71.2}/Dockerfile +0 -0
  39. {soup_cli-0.71.1 → soup_cli-0.71.2}/LICENSE +0 -0
  40. {soup_cli-0.71.1 → soup_cli-0.71.2}/NOTICE +0 -0
  41. {soup_cli-0.71.1 → soup_cli-0.71.2}/SECURITY.md +0 -0
  42. {soup_cli-0.71.1 → soup_cli-0.71.2}/docker-compose.yml +0 -0
  43. {soup_cli-0.71.1 → soup_cli-0.71.2}/docs/README.md +0 -0
  44. {soup_cli-0.71.1 → soup_cli-0.71.2}/docs/backends-and-ops.md +0 -0
  45. {soup_cli-0.71.1 → soup_cli-0.71.2}/docs/data.md +0 -0
  46. {soup_cli-0.71.1 → soup_cli-0.71.2}/docs/evaluation.md +0 -0
  47. {soup_cli-0.71.1 → soup_cli-0.71.2}/docs/models.md +0 -0
  48. {soup_cli-0.71.1 → soup_cli-0.71.2}/docs/peft-and-efficiency.md +0 -0
  49. {soup_cli-0.71.1 → soup_cli-0.71.2}/docs/performance-and-quantization.md +0 -0
  50. {soup_cli-0.71.1 → soup_cli-0.71.2}/docs/serving-and-export.md +0 -0
  51. {soup_cli-0.71.1 → soup_cli-0.71.2}/docs/training.md +0 -0
  52. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/README.md +0 -0
  53. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/configs/dpo_chat.yaml +0 -0
  54. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/configs/dpo_example.yaml +0 -0
  55. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/configs/grpo_reasoning.yaml +0 -0
  56. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/configs/rlhf_step1_sft.yaml +0 -0
  57. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/configs/rlhf_step2_reward.yaml +0 -0
  58. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/configs/rlhf_step3_ppo.yaml +0 -0
  59. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/configs/sft_basic.yaml +0 -0
  60. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/configs/vision_llama.yaml +0 -0
  61. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/data/alpaca_tiny.jsonl +0 -0
  62. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/data/chat_preferences.jsonl +0 -0
  63. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/data/dpo_sample.jsonl +0 -0
  64. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/data/reasoning_math.jsonl +0 -0
  65. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/synthetic_workflow.md +0 -0
  66. {soup_cli-0.71.1 → soup_cli-0.71.2}/examples/synthetic_workflow.yaml +0 -0
  67. {soup_cli-0.71.1 → soup_cli-0.71.2}/soup.png +0 -0
  68. {soup_cli-0.71.1 → soup_cli-0.71.2}/soup_logo_svg.svg +0 -0
  69. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/__main__.py +0 -0
  70. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/autopilot/__init__.py +0 -0
  71. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/autopilot/analyzer.py +0 -0
  72. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/autopilot/decisions.py +0 -0
  73. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/autopilot/generate_config.py +0 -0
  74. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/cans/__init__.py +0 -0
  75. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/cans/pack.py +0 -0
  76. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/cans/publish.py +0 -0
  77. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/cans/run.py +0 -0
  78. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/cans/schema.py +0 -0
  79. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/cans/unpack.py +0 -0
  80. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/cans/verify.py +0 -0
  81. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/cli.py +0 -0
  82. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/__init__.py +0 -0
  83. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/_eval_v0550.py +0 -0
  84. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/_eval_v0610.py +0 -0
  85. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/_eval_v0650.py +0 -0
  86. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/ab.py +0 -0
  87. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/active_sample.py +0 -0
  88. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/advise.py +0 -0
  89. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/agent.py +0 -0
  90. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/airgap.py +0 -0
  91. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/apple_adapter.py +0 -0
  92. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/audit_log.py +0 -0
  93. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/autopilot.py +0 -0
  94. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/bench.py +0 -0
  95. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/bom.py +0 -0
  96. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/build.py +0 -0
  97. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/can.py +0 -0
  98. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/chat.py +0 -0
  99. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/compile_cmd.py +0 -0
  100. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/compile_tools.py +0 -0
  101. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/completions.py +0 -0
  102. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/cost.py +0 -0
  103. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/data.py +0 -0
  104. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/data_forge.py +0 -0
  105. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/data_mix.py +0 -0
  106. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/data_score.py +0 -0
  107. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/delinearize_llama4.py +0 -0
  108. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/deploy.py +0 -0
  109. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/diagnose.py +0 -0
  110. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/diff.py +0 -0
  111. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/distill_prompt.py +0 -0
  112. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/doctor.py +0 -0
  113. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/drift_alarm.py +0 -0
  114. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/edit.py +0 -0
  115. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/env.py +0 -0
  116. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/eval.py +0 -0
  117. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/expect.py +0 -0
  118. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/export.py +0 -0
  119. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/fetch.py +0 -0
  120. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/generate.py +0 -0
  121. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/history.py +0 -0
  122. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/infer.py +0 -0
  123. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/ingest.py +0 -0
  124. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/init.py +0 -0
  125. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/iterative_dpo.py +0 -0
  126. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/license_advisor.py +0 -0
  127. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/llama.py +0 -0
  128. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/local_rl.py +0 -0
  129. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/lock.py +0 -0
  130. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/loop.py +0 -0
  131. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/merge.py +0 -0
  132. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/merge_sharded_fsdp_weights.py +0 -0
  133. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/migrate.py +0 -0
  134. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/monitor.py +0 -0
  135. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/plan.py +0 -0
  136. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/plugins.py +0 -0
  137. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/probe.py +0 -0
  138. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/profile.py +0 -0
  139. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/prune_prompt.py +0 -0
  140. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/push.py +0 -0
  141. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/quantize.py +0 -0
  142. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/quickstart.py +0 -0
  143. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/recipes.py +0 -0
  144. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/registry.py +0 -0
  145. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/runs.py +0 -0
  146. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/serve.py +0 -0
  147. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/steer.py +0 -0
  148. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/sweep.py +0 -0
  149. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/tokenizer.py +0 -0
  150. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/train.py +0 -0
  151. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/tui.py +0 -0
  152. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/tunability.py +0 -0
  153. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/ui.py +0 -0
  154. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/commands/why.py +0 -0
  155. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/config/__init__.py +0 -0
  156. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/config/loader.py +0 -0
  157. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/config/schema.py +0 -0
  158. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/__init__.py +0 -0
  159. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/alpaca_tiny.jsonl +0 -0
  160. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/behavior/elephant.jsonl +0 -0
  161. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/behavior/harmbench.jsonl +0 -0
  162. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/behavior/jailbreakbench.jsonl +0 -0
  163. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/behavior/syceval.jsonl +0 -0
  164. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/behavior/xstest.jsonl +0 -0
  165. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/chat_preferences.jsonl +0 -0
  166. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/dpo_sample.jsonl +0 -0
  167. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/reasoning_math.jsonl +0 -0
  168. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/unlearning/muse_demo.jsonl +0 -0
  169. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/unlearning/tofu_demo.jsonl +0 -0
  170. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/_fixtures/unlearning/wmdp_demo.jsonl +0 -0
  171. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/augment.py +0 -0
  172. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/chat_templates.py +0 -0
  173. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/collators.py +0 -0
  174. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/formats.py +0 -0
  175. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/loader.py +0 -0
  176. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/loss_mask.py +0 -0
  177. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/providers/__init__.py +0 -0
  178. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/providers/_utils.py +0 -0
  179. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/providers/anthropic.py +0 -0
  180. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/providers/ollama.py +0 -0
  181. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/providers/vllm.py +0 -0
  182. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/sft_format.py +0 -0
  183. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/templates/__init__.py +0 -0
  184. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/templates/code.py +0 -0
  185. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/templates/conversation.py +0 -0
  186. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/templates/preference.py +0 -0
  187. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/templates/qa.py +0 -0
  188. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/templates/reasoning.py +0 -0
  189. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/templates/tool_calling.py +0 -0
  190. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/templates/verifiable.py +0 -0
  191. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/traces/__init__.py +0 -0
  192. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/traces/pair_builder.py +0 -0
  193. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/traces/parsers.py +0 -0
  194. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/traces/quality.py +0 -0
  195. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/data/validator.py +0 -0
  196. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/eval/__init__.py +0 -0
  197. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/eval/arena.py +0 -0
  198. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/eval/benchmarks_v0_43.py +0 -0
  199. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/eval/calibrate.py +0 -0
  200. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/eval/checkpoint_intelligence.py +0 -0
  201. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/eval/custom.py +0 -0
  202. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/eval/forgetting.py +0 -0
  203. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/eval/gate.py +0 -0
  204. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/eval/human.py +0 -0
  205. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/eval/judge.py +0 -0
  206. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/eval/leaderboard.py +0 -0
  207. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/eval/quant_check.py +0 -0
  208. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/experiment/__init__.py +0 -0
  209. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/experiment/tracker.py +0 -0
  210. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/migrate/__init__.py +0 -0
  211. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/migrate/axolotl.py +0 -0
  212. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/migrate/common.py +0 -0
  213. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/migrate/llamafactory.py +0 -0
  214. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/migrate/unsloth.py +0 -0
  215. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/monitoring/__init__.py +0 -0
  216. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/monitoring/callback.py +0 -0
  217. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/monitoring/curriculum_callback.py +0 -0
  218. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/monitoring/display.py +0 -0
  219. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/monitoring/grpo_stability_callback.py +0 -0
  220. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/monitoring/hf_push.py +0 -0
  221. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/monitoring/plugin_callback.py +0 -0
  222. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/monitoring/trace_logger.py +0 -0
  223. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/plugins/__init__.py +0 -0
  224. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/py.typed +0 -0
  225. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/recipes/__init__.py +0 -0
  226. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/recipes/catalog.py +0 -0
  227. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/registry/__init__.py +0 -0
  228. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/registry/attach.py +0 -0
  229. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/registry/diff.py +0 -0
  230. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/registry/hashing.py +0 -0
  231. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/registry/store.py +0 -0
  232. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/__init__.py +0 -0
  233. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/audio.yaml +0 -0
  234. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/bco.yaml +0 -0
  235. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/chat.yaml +0 -0
  236. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/code.yaml +0 -0
  237. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/embedding.yaml +0 -0
  238. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/fetch_examples/llama-3.1-8b-lora.yaml +0 -0
  239. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/fetch_examples/qwen2.5-7b-dpo.yaml +0 -0
  240. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/fetch_examples/zero3-cpu-offload.json +0 -0
  241. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/ipo.yaml +0 -0
  242. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/kto.yaml +0 -0
  243. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/longcontext.yaml +0 -0
  244. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/manifest.json +0 -0
  245. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/medical.yaml +0 -0
  246. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/moe.yaml +0 -0
  247. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/orpo.yaml +0 -0
  248. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/pretrain.yaml +0 -0
  249. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/reasoning.yaml +0 -0
  250. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/rlhf.yaml +0 -0
  251. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/simpo.yaml +0 -0
  252. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/tool-calling.yaml +0 -0
  253. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/templates/vision.yaml +0 -0
  254. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/__init__.py +0 -0
  255. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/bco.py +0 -0
  256. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/classifier.py +0 -0
  257. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/distill.py +0 -0
  258. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/dpo.py +0 -0
  259. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/embedding.py +0 -0
  260. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/grpo.py +0 -0
  261. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/ipo.py +0 -0
  262. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/kto.py +0 -0
  263. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/mlx_dpo.py +0 -0
  264. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/mlx_grpo.py +0 -0
  265. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/mlx_routing.py +0 -0
  266. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/mlx_sft.py +0 -0
  267. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/orpo.py +0 -0
  268. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/ppo.py +0 -0
  269. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/preference.py +0 -0
  270. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/pretrain.py +0 -0
  271. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/prm.py +0 -0
  272. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/reward_model.py +0 -0
  273. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/rewards.py +0 -0
  274. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/sft.py +0 -0
  275. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/simpo.py +0 -0
  276. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/trainer/unlearn.py +0 -0
  277. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/tui_app.py +0 -0
  278. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/ui/__init__.py +0 -0
  279. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/ui/app.py +0 -0
  280. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/ui/plugins/__init__.py +0 -0
  281. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/ui/static/app.js +0 -0
  282. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/ui/static/index.html +0 -0
  283. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/ui/static/logo.png +0 -0
  284. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/ui/static/logo.svg +0 -0
  285. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/ui/static/style.css +0 -0
  286. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/__init__.py +0 -0
  287. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/_eval_text.py +0 -0
  288. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/ab_test.py +0 -0
  289. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/activation_offload.py +0 -0
  290. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/active_sampler.py +0 -0
  291. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_bisect.py +0 -0
  292. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_branch.py +0 -0
  293. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_diff.py +0 -0
  294. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_merge.py +0 -0
  295. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_pr.py +0 -0
  296. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/adapter_scan.py +0 -0
  297. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/advanced_precision.py +0 -0
  298. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/advise.py +0 -0
  299. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/advise_history.py +0 -0
  300. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/agent_forge.py +0 -0
  301. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/agent_rollout.py +0 -0
  302. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/airgap_bundle.py +0 -0
  303. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/annex_xi.py +0 -0
  304. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/anthropic_messages.py +0 -0
  305. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/apple_adapter.py +0 -0
  306. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/audit_log.py +0 -0
  307. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/auto_quant.py +0 -0
  308. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/backend_detect.py +0 -0
  309. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/batch_probe.py +0 -0
  310. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/behavior_battery.py +0 -0
  311. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/bitnet.py +0 -0
  312. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/blame.py +0 -0
  313. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/block_expansion.py +0 -0
  314. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/bom.py +0 -0
  315. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/brain_rot.py +0 -0
  316. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/brain_rot_lang.py +0 -0
  317. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/build_dag.py +0 -0
  318. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/canary_discovery.py +0 -0
  319. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/canary_router.py +0 -0
  320. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/capability_suite.py +0 -0
  321. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/checklist_dsl.py +0 -0
  322. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/checkpoint_trigger.py +0 -0
  323. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/citation_faithful.py +0 -0
  324. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/classifier.py +0 -0
  325. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/cmaes_merge.py +0 -0
  326. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/compile_tools.py +0 -0
  327. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/completions.py +0 -0
  328. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/constants.py +0 -0
  329. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/convergence.py +0 -0
  330. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/crash.py +0 -0
  331. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/cross_doc_attn.py +0 -0
  332. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/curriculum.py +0 -0
  333. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/curriculum_dynamic.py +0 -0
  334. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/cut_ce.py +0 -0
  335. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/data_forge.py +0 -0
  336. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/data_mix.py +0 -0
  337. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/data_pipeline.py +0 -0
  338. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/data_score.py +0 -0
  339. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/deepspeed.py +0 -0
  340. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/delinearize_llama4.py +0 -0
  341. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/demo_bundles.py +0 -0
  342. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/deploy_autopilot.py +0 -0
  343. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/deploy_measure.py +0 -0
  344. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/__init__.py +0 -0
  345. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/_common.py +0 -0
  346. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/badge.py +0 -0
  347. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/contamination.py +0 -0
  348. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/forgetting.py +0 -0
  349. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/format.py +0 -0
  350. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/memorization.py +0 -0
  351. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/mode_collapse.py +0 -0
  352. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/refusal.py +0 -0
  353. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/report.py +0 -0
  354. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/diagnose/runner.py +0 -0
  355. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/distill.py +0 -0
  356. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/dpo_variants.py +0 -0
  357. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/drift_alarm.py +0 -0
  358. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/ebft_gdpo.py +0 -0
  359. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/echo_trap.py +0 -0
  360. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/edit_diff.py +0 -0
  361. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/edit_governor.py +0 -0
  362. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/encoding.py +0 -0
  363. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/energy.py +0 -0
  364. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/env_lock.py +0 -0
  365. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/errors.py +0 -0
  366. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/eval_design.py +0 -0
  367. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/eval_gate_hook.py +0 -0
  368. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/eval_lock_coverage.py +0 -0
  369. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/expectations.py +0 -0
  370. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/fetch_examples.py +0 -0
  371. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/flash_attn.py +0 -0
  372. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/fp8.py +0 -0
  373. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/freeze.py +0 -0
  374. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/fsdp.py +0 -0
  375. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/fsdp_consolidate.py +0 -0
  376. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/galore.py +0 -0
  377. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/gguf_quant.py +0 -0
  378. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/gpu.py +0 -0
  379. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/gpu_monitor.py +0 -0
  380. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/grace_codebook.py +0 -0
  381. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/graceful_save.py +0 -0
  382. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/grad_accum.py +0 -0
  383. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/gradient_ckpt.py +0 -0
  384. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/grpo_long_context.py +0 -0
  385. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/grpo_variants.py +0 -0
  386. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/hardware_fit.py +0 -0
  387. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/hf.py +0 -0
  388. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/hf_space.py +0 -0
  389. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/ingest_sources.py +0 -0
  390. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/integrations.py +0 -0
  391. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/interference.py +0 -0
  392. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/irt.py +0 -0
  393. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/iterative_dpo.py +0 -0
  394. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/jinja_analyzer.py +0 -0
  395. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/kernel_picker.py +0 -0
  396. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/knowledge_edit.py +0 -0
  397. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/kv_cache.py +0 -0
  398. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/launcher.py +0 -0
  399. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/license_advisor.py +0 -0
  400. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/liger.py +0 -0
  401. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/llama_proxy.py +0 -0
  402. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/llama_server_timings.py +0 -0
  403. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/local_rl.py +0 -0
  404. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/loftq_init.py +0 -0
  405. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/log_level.py +0 -0
  406. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/long_context.py +0 -0
  407. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/longlora.py +0 -0
  408. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/loop_budget.py +0 -0
  409. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/loop_daemon.py +0 -0
  410. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/loop_iteration.py +0 -0
  411. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/loop_state.py +0 -0
  412. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/lr_finder.py +0 -0
  413. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/lr_groups.py +0 -0
  414. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/magpie.py +0 -0
  415. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/metrics.py +0 -0
  416. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/mii.py +0 -0
  417. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/minillm.py +0 -0
  418. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/mix_proxy.py +0 -0
  419. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/mixed_precision.py +0 -0
  420. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/mlx.py +0 -0
  421. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/moe.py +0 -0
  422. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/moe_quant.py +0 -0
  423. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/mole_routing.py +0 -0
  424. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/multipack.py +0 -0
  425. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/multipack_sampler.py +0 -0
  426. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/multipack_trainer.py +0 -0
  427. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/neat_packing.py +0 -0
  428. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/ngram_spec.py +0 -0
  429. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/nlg_metrics.py +0 -0
  430. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/ollama.py +0 -0
  431. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/onboarding.py +0 -0
  432. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/optimizer_zoo.py +0 -0
  433. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/paths.py +0 -0
  434. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/peft_builder.py +0 -0
  435. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/peft_patches.py +0 -0
  436. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/peft_wiring.py +0 -0
  437. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/persona_hub.py +0 -0
  438. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/pipeline.py +0 -0
  439. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/preference_combine.py +0 -0
  440. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/prm.py +0 -0
  441. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/probe_pack.py +0 -0
  442. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/profiler.py +0 -0
  443. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/profiling.py +0 -0
  444. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/profiling_v0_43.py +0 -0
  445. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/prompt_compile.py +0 -0
  446. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/prompt_distill.py +0 -0
  447. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/prune_prompt.py +0 -0
  448. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/qat.py +0 -0
  449. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/qr_url.py +0 -0
  450. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/quality.py +0 -0
  451. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/quant_menu.py +0 -0
  452. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/ra_dit.py +0 -0
  453. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/reasoning_effort.py +0 -0
  454. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/reasoning_parser.py +0 -0
  455. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/recipe_dag.py +0 -0
  456. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/recipe_run.py +0 -0
  457. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/registry.py +0 -0
  458. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/relora.py +0 -0
  459. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/replay.py +0 -0
  460. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/repro_receipt.py +0 -0
  461. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/reward_hacking.py +0 -0
  462. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/ring_attention.py +0 -0
  463. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/rl_checkpoint.py +0 -0
  464. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/run_cost.py +0 -0
  465. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/sae_diff.py +0 -0
  466. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/save_formats.py +0 -0
  467. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/server_tools.py +0 -0
  468. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/sglang.py +0 -0
  469. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/shortcuts.py +0 -0
  470. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/sleeper_probe.py +0 -0
  471. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/soup_lock.py +0 -0
  472. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/spec_pairing.py +0 -0
  473. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/spike_recovery.py +0 -0
  474. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/sse_train_stream.py +0 -0
  475. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/steering.py +0 -0
  476. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/strict_safetensors.py +0 -0
  477. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/structured_output.py +0 -0
  478. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/sweep_config.py +0 -0
  479. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/tail_latency.py +0 -0
  480. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/terraform_plan.py +0 -0
  481. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/tool_outputs.py +0 -0
  482. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/topology.py +0 -0
  483. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/tracing.py +0 -0
  484. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/trackers.py +0 -0
  485. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/train_event_buffer.py +0 -0
  486. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/trainer_plugins.py +0 -0
  487. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/trust_remote.py +0 -0
  488. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/tts.py +0 -0
  489. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/tunability.py +0 -0
  490. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/ui_env.py +0 -0
  491. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/uld.py +0 -0
  492. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/unlearning.py +0 -0
  493. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/unlearning_eval.py +0 -0
  494. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/unsloth.py +0 -0
  495. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/v028_features.py +0 -0
  496. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/vector_bank.py +0 -0
  497. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/vllm.py +0 -0
  498. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/vscode_setup.py +0 -0
  499. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/warmup.py +0 -0
  500. {soup_cli-0.71.1 → soup_cli-0.71.2}/src/soup_cli/utils/why.py +0 -0
  501. {soup_cli-0.71.1 → soup_cli-0.71.2}/templates/chat.yaml +0 -0
  502. {soup_cli-0.71.1 → soup_cli-0.71.2}/templates/code.yaml +0 -0
  503. {soup_cli-0.71.1 → soup_cli-0.71.2}/templates/medical.yaml +0 -0
  504. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/__init__.py +0 -0
  505. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/conftest.py +0 -0
  506. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/qa/v053_qa.md +0 -0
  507. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_adapters.py +0 -0
  508. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_advanced_peft.py +0 -0
  509. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_assistant_mask.py +0 -0
  510. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_audio.py +0 -0
  511. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_auto_tuning.py +0 -0
  512. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_autopilot.py +0 -0
  513. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_awq_gptq_export.py +0 -0
  514. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_batch_probe.py +0 -0
  515. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_bco.py +0 -0
  516. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_bench.py +0 -0
  517. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_brain_rot_multilingual.py +0 -0
  518. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_bugfixes.py +0 -0
  519. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_callback.py +0 -0
  520. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_cans.py +0 -0
  521. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_chat.py +0 -0
  522. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_chat_template.py +0 -0
  523. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_cli.py +0 -0
  524. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_cli_subprocess.py +0 -0
  525. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_config.py +0 -0
  526. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_cost.py +0 -0
  527. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_crash_reporter.py +0 -0
  528. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_curriculum.py +0 -0
  529. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_data.py +0 -0
  530. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_data_augment.py +0 -0
  531. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_data_sample.py +0 -0
  532. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_data_split.py +0 -0
  533. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_data_tools.py +0 -0
  534. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_dataset_hub.py +0 -0
  535. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_dataset_registry.py +0 -0
  536. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_deepspeed.py +0 -0
  537. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_deploy_ollama.py +0 -0
  538. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_diff.py +0 -0
  539. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_display.py +0 -0
  540. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_doctor.py +0 -0
  541. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_dpo_example.py +0 -0
  542. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_dpo_variants.py +0 -0
  543. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_embedding.py +0 -0
  544. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_errors.py +0 -0
  545. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_eval.py +0 -0
  546. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_eval_gate.py +0 -0
  547. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_eval_platform.py +0 -0
  548. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_export.py +0 -0
  549. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_formats.py +0 -0
  550. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_fp8_recipe.py +0 -0
  551. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_freeze_training.py +0 -0
  552. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_generate.py +0 -0
  553. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_gpu.py +0 -0
  554. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_grpo.py +0 -0
  555. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_hf_integration.py +0 -0
  556. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_infer.py +0 -0
  557. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_inference_advanced.py +0 -0
  558. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_init.py +0 -0
  559. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_ipo.py +0 -0
  560. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_jinja_analyzer.py +0 -0
  561. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_kto.py +0 -0
  562. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_loader.py +0 -0
  563. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_log_level.py +0 -0
  564. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_loss_watchdog.py +0 -0
  565. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_merge.py +0 -0
  566. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_migrate.py +0 -0
  567. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_mlx_backend.py +0 -0
  568. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_moe.py +0 -0
  569. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_multi_adapter.py +0 -0
  570. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_multi_gpu.py +0 -0
  571. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_multipack_config.py +0 -0
  572. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_multipack_invariants.py +0 -0
  573. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_multipack_sampler.py +0 -0
  574. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_neat_packing.py +0 -0
  575. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_neftune_rslora.py +0 -0
  576. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_onnx_tensorrt_export.py +0 -0
  577. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_orpo.py +0 -0
  578. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_packing.py +0 -0
  579. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_part_a_wave1.py +0 -0
  580. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_part_a_wave2.py +0 -0
  581. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_part_b.py +0 -0
  582. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_part_c.py +0 -0
  583. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_part_d.py +0 -0
  584. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_part_e.py +0 -0
  585. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_part_f_hardening.py +0 -0
  586. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_peft_methods.py +0 -0
  587. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_peft_patches.py +0 -0
  588. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_performance.py +0 -0
  589. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_pissa_init.py +0 -0
  590. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_ppo.py +0 -0
  591. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_preference_dispatcher.py +0 -0
  592. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_preference_multi.py +0 -0
  593. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_preference_multi_runtime.py +0 -0
  594. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_pretrain.py +0 -0
  595. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_profile.py +0 -0
  596. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_profiling.py +0 -0
  597. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_progress.py +0 -0
  598. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_push.py +0 -0
  599. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_qat.py +0 -0
  600. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_quality_filter.py +0 -0
  601. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_quant_check.py +0 -0
  602. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_quant_menu.py +0 -0
  603. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_quickstart.py +0 -0
  604. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_rank_pattern.py +0 -0
  605. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_recipes.py +0 -0
  606. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_recipes_v031.py +0 -0
  607. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_refusal_multilingual.py +0 -0
  608. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_registry.py +0 -0
  609. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_relora.py +0 -0
  610. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_replay.py +0 -0
  611. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_resume.py +0 -0
  612. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_rlvr.py +0 -0
  613. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_run_cost.py +0 -0
  614. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_runs.py +0 -0
  615. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_serve.py +0 -0
  616. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_server_generate.py +0 -0
  617. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_sglang_serve.py +0 -0
  618. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_simpo.py +0 -0
  619. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_smoke_train.py +0 -0
  620. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_speculative_decoding.py +0 -0
  621. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_sweep.py +0 -0
  622. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_synth_data_pro.py +0 -0
  623. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_templates_yaml.py +0 -0
  624. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_tensorboard.py +0 -0
  625. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_tool_calling.py +0 -0
  626. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_trace_to_pref.py +0 -0
  627. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_tracker.py +0 -0
  628. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_trainer_coverage_v035.py +0 -0
  629. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_trainer_init.py +0 -0
  630. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_training_intelligence.py +0 -0
  631. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_training_speed.py +0 -0
  632. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_trust_remote_code.py +0 -0
  633. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_tui.py +0 -0
  634. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_ui.py +0 -0
  635. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_ui_chat.py +0 -0
  636. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_ui_config_builder.py +0 -0
  637. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_ui_live_monitor.py +0 -0
  638. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_ui_metrics.py +0 -0
  639. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_unsloth.py +0 -0
  640. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0401_part_c.py +0 -0
  641. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0401_part_d.py +0 -0
  642. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0401_part_e.py +0 -0
  643. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0402_part_a.py +0 -0
  644. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0402_part_b.py +0 -0
  645. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0403_part_a.py +0 -0
  646. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0403_part_b.py +0 -0
  647. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0403_part_c.py +0 -0
  648. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0404_part_a.py +0 -0
  649. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0404_part_b.py +0 -0
  650. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0405_part_a.py +0 -0
  651. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0406_part_a.py +0 -0
  652. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0410_part_a.py +0 -0
  653. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0410_part_b.py +0 -0
  654. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0410_part_c.py +0 -0
  655. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0420.py +0 -0
  656. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0430_part_a.py +0 -0
  657. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0430_part_b.py +0 -0
  658. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0430_part_c.py +0 -0
  659. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0430_part_d.py +0 -0
  660. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0440_part_a.py +0 -0
  661. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0440_part_b.py +0 -0
  662. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0440_part_c.py +0 -0
  663. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0440_part_d.py +0 -0
  664. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0440_review_followups.py +0 -0
  665. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0450.py +0 -0
  666. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0460_part_a.py +0 -0
  667. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0460_part_b.py +0 -0
  668. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0470_part_a.py +0 -0
  669. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0470_part_b.py +0 -0
  670. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0480_part_a.py +0 -0
  671. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0480_part_b.py +0 -0
  672. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0490.py +0 -0
  673. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0500_part_a.py +0 -0
  674. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0500_part_b.py +0 -0
  675. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0500_part_c.py +0 -0
  676. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0500_part_d.py +0 -0
  677. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0500_part_e.py +0 -0
  678. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0510.py +0 -0
  679. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0520.py +0 -0
  680. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0530.py +0 -0
  681. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v05310.py +0 -0
  682. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v05311.py +0 -0
  683. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0531_109.py +0 -0
  684. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0531_139.py +0 -0
  685. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0531_142.py +0 -0
  686. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0531_82.py +0 -0
  687. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0532.py +0 -0
  688. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0533.py +0 -0
  689. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0534.py +0 -0
  690. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0535.py +0 -0
  691. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0536.py +0 -0
  692. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0537.py +0 -0
  693. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0539.py +0 -0
  694. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0540.py +0 -0
  695. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0550.py +0 -0
  696. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0550_followups.py +0 -0
  697. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0560.py +0 -0
  698. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0570_part_a.py +0 -0
  699. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0570_part_c.py +0 -0
  700. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0570_part_d.py +0 -0
  701. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0580.py +0 -0
  702. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0590.py +0 -0
  703. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0600_part_a.py +0 -0
  704. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0600_part_c.py +0 -0
  705. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0600_part_d.py +0 -0
  706. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0600_part_f.py +0 -0
  707. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0610_part_a.py +0 -0
  708. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0610_part_b.py +0 -0
  709. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0610_part_c.py +0 -0
  710. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0610_part_d.py +0 -0
  711. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0610_part_e.py +0 -0
  712. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0620_followups.py +0 -0
  713. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0620_part_a.py +0 -0
  714. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0620_part_b.py +0 -0
  715. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0620_part_c.py +0 -0
  716. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0620_part_d.py +0 -0
  717. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0620_part_e.py +0 -0
  718. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0630_followups.py +0 -0
  719. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0630_part_a.py +0 -0
  720. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0630_part_b.py +0 -0
  721. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0630_part_c.py +0 -0
  722. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0630_part_d.py +0 -0
  723. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0630_part_e.py +0 -0
  724. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0631_206.py +0 -0
  725. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0640_followups.py +0 -0
  726. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0640_part_a.py +0 -0
  727. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0640_part_b.py +0 -0
  728. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0640_part_c.py +0 -0
  729. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0640_part_d.py +0 -0
  730. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0640_part_e.py +0 -0
  731. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0640_part_f.py +0 -0
  732. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0650_followups.py +0 -0
  733. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0650_part_a.py +0 -0
  734. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0650_part_b.py +0 -0
  735. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0650_part_c.py +0 -0
  736. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0650_part_d.py +0 -0
  737. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0650_part_e.py +0 -0
  738. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0660_cli.py +0 -0
  739. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0660_followups.py +0 -0
  740. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0660_part_a.py +0 -0
  741. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0660_part_b.py +0 -0
  742. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0660_part_c.py +0 -0
  743. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0660_part_d.py +0 -0
  744. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0660_part_e.py +0 -0
  745. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0670_followups.py +0 -0
  746. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0670_part_a.py +0 -0
  747. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0670_part_b.py +0 -0
  748. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0670_part_c.py +0 -0
  749. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0670_part_d.py +0 -0
  750. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0670_part_e.py +0 -0
  751. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0670_part_f.py +0 -0
  752. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0680_followups.py +0 -0
  753. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0680_part_a.py +0 -0
  754. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0680_part_b.py +0 -0
  755. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0680_part_c.py +0 -0
  756. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0680_part_d.py +0 -0
  757. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0680_part_e.py +0 -0
  758. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0690_part_a.py +0 -0
  759. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0690_part_b.py +0 -0
  760. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0690_part_c.py +0 -0
  761. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0690_part_d.py +0 -0
  762. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0690_part_e.py +0 -0
  763. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0700_part_a.py +0 -0
  764. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0700_part_b.py +0 -0
  765. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0700_part_c.py +0 -0
  766. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0700_part_d.py +0 -0
  767. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0700_part_e.py +0 -0
  768. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_v0700_part_f.py +0 -0
  769. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_validator.py +0 -0
  770. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_vision.py +0 -0
  771. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_vllm_serve.py +0 -0
  772. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_why.py +0 -0
  773. {soup_cli-0.71.1 → soup_cli-0.71.2}/tests/test_windows_encoding.py +0 -0
@@ -12,6 +12,45 @@ reproducing 70+ versions of notes.
12
12
 
13
13
  ## [Unreleased]
14
14
 
15
+ ## [0.71.2] - 2026-06-01
16
+
17
+ ### Added
18
+ - **ed25519 signing for `soup adapters sign` / `soup attest`** — real detached
19
+ signatures (over the adapter Merkle root / the in-toto statement) via a new
20
+ `[sign]` extra (`pip install soup-cli[sign]`, pulling `cryptography`).
21
+ `soup adapters sign --backend ed25519 --key <priv.pem>` (or `--generate-key
22
+ <out.pem>`, or `SOUP_SIGNING_KEY`); `soup adapters verify [--public-key
23
+ <trusted.pem>]` does a cryptographic verify and, with a trusted key, genuine
24
+ authentication. `soup attest emit --sign ed25519 --key <priv.pem>` writes a
25
+ `<output>.sig` sidecar; new `soup attest verify <statement> --signature <sig>`
26
+ verifies it (canonical-JSON, so it's platform/newline-independent). Sigstore
27
+ keyless signing stays infra-blocked (needs an OIDC provider + Fulcio/Rekor
28
+ network — can't be honestly validated offline).
29
+ - **Anti-AI-Jacking namespace pin on Hub downloads** — HF model fetches now
30
+ consult a trust-on-first-use pin store: a repo whose author changes (or whose
31
+ `created_at` jumps backward) is refused unless the namespace shift is explicitly
32
+ allowed. Fails open when repo metadata is unavailable.
33
+ - **License auto-detection at `soup adapters merge`** — when `--license` isn't
34
+ given, the license is read from each adapter's `adapter_config.json` /
35
+ `config.json` / model-card frontmatter (HF `llama3.1`-style ids mapped to
36
+ canonical) and the conflict gate runs automatically.
37
+ - **Backdoor-scan gate at `soup adapters merge`** — refuses to merge any input
38
+ whose `soup adapters scan` returns FAIL (or can't be scanned) unless
39
+ `--allow-unscanned` is passed; WARN is advisory.
40
+
41
+ ### Changed
42
+ - License-conflict overrides (`--license-override <reason>`) are now recorded to
43
+ the audit log for legal review.
44
+ - The namespace-pin store now uses SQLite WAL + busy-timeout and a cross-process
45
+ file lock around its get+insert, so concurrent writers don't lose the trust
46
+ anchor.
47
+
48
+ ### Security
49
+ - ed25519 verification fails closed (any tamper / wrong key / missing key ⇒
50
+ invalid). Signing keys + trusted public keys are symlink-rejected and
51
+ size-capped via a shared reader (no cwd-containment — keys live outside the
52
+ project). `--generate-key` refuses to overwrite any existing path.
53
+
15
54
  ## [0.71.1] - 2026-06-01
16
55
 
17
56
  ### Added
@@ -31,6 +31,8 @@ This installs:
31
31
  - the full training stack — `[dev]` self-references `[train]`, so `torch`,
32
32
  `transformers`, `peft`, `trl`, `datasets`, `bitsandbytes`, `accelerate` are
33
33
  pulled in too (since v0.71.0 these are an opt-in extra, not core deps)
34
+ - `cryptography` — `[dev]` also pulls it in (it's the `[sign]` extra) so the
35
+ ed25519 signing tests (`soup adapters sign` / `soup attest`) run in CI
34
36
 
35
37
  ### 3. Verify Setup
36
38
 
@@ -116,7 +118,7 @@ src/soup_cli/
116
118
  templates/ - 17 built-in soup.yaml templates (YAML + manifest.json) with load_template loader (v0.39.0, +bco v0.40.0)
117
119
  ui/ - Web UI (FastAPI + HTML/JS SPA)
118
120
 
119
- tests/ - Test suite (271 files, 12153 tests)
121
+ tests/ - Test suite (272 files, 12259 tests)
120
122
  examples/ - Real-world config examples and datasets
121
123
  ```
122
124
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: soup-cli
3
- Version: 0.71.1
3
+ Version: 0.71.2
4
4
  Summary: Fine-tune LLMs in one command. No SSH, no config hell.
5
5
  Project-URL: Homepage, https://github.com/MakazhanAlpamys/Soup
6
6
  Project-URL: Repository, https://github.com/MakazhanAlpamys/Soup
@@ -51,6 +51,7 @@ Requires-Dist: deepspeed>=0.12.0; extra == 'deepspeed'
51
51
  Provides-Extra: dev
52
52
  Requires-Dist: accelerate>=0.25.0; extra == 'dev'
53
53
  Requires-Dist: bitsandbytes>=0.41.0; extra == 'dev'
54
+ Requires-Dist: cryptography>=41.0.0; extra == 'dev'
54
55
  Requires-Dist: datasets>=2.14.0; extra == 'dev'
55
56
  Requires-Dist: httpx>=0.24.0; extra == 'dev'
56
57
  Requires-Dist: mypy>=1.8.0; extra == 'dev'
@@ -99,6 +100,8 @@ Provides-Extra: sglang
99
100
  Requires-Dist: fastapi>=0.104.0; extra == 'sglang'
100
101
  Requires-Dist: sglang>=0.2.0; extra == 'sglang'
101
102
  Requires-Dist: uvicorn>=0.24.0; extra == 'sglang'
103
+ Provides-Extra: sign
104
+ Requires-Dist: cryptography>=41.0.0; extra == 'sign'
102
105
  Provides-Extra: tensorrt
103
106
  Requires-Dist: tensorrt-llm>=0.9.0; extra == 'tensorrt'
104
107
  Provides-Extra: trackers
@@ -175,19 +178,19 @@ infrastructure instead of improving models. Soup fixes that.
175
178
 
176
179
  ## What's New
177
180
 
178
- **v0.71.1Quick wins + wiring.** Seven small-but-sharp closures:
179
-
180
- - **`soup env fix`** renders a reproducible install plan (copy/paste `uv pip` commands or a
181
- `requirements.txt`) straight from `soup-env.lock` print-only, no surprise package-manager calls.
182
- - **`soup lock write --env-lock`** auto-derives the env hash from `soup-env.lock` so you never
183
- hand-copy a 64-hex string after `soup env lock`.
184
- - **`soup serve --record-thumbs <db>`** captures 👍/👎 feedback into a local-RL SQLite, plus a new
185
- `POST /v1/thumbs` endpoint the start of an on-box feedback flywheel.
186
- - **Judge calibration persistence** — write/load a `JudgeCalibrationReport` as JSON, backed by a new
187
- `judge_calibration` registry artifact kind.
188
- - **Bundled MUSE + WMDP unlearning eval fixtures** so `soup eval unlearning --benchmark muse|wmdp`
189
- runs out of the box (WMDP forget-set probes ship **redacted** never verbatim hazardous content).
190
- - **`soup completions`** now introspects a cached base model's real LoRA target modules.
181
+ **v0.71.2Governance & supply-chain live.** Real signatures and supply-chain gates:
182
+
183
+ - **ed25519 signing** `soup adapters sign --backend ed25519 --key priv.pem` (or `--generate-key`)
184
+ produces a real detached signature over the adapter's Merkle root; `soup adapters verify
185
+ --public-key trusted.pem` does cryptographic authentication. Same for `soup attest emit
186
+ --sign ed25519` + the new `soup attest verify`. Install with `pip install soup-cli[sign]`.
187
+ - **Anti-AI-Jacking namespace pin** Hub model downloads now refuse a repo whose author silently
188
+ changed (or whose creation date jumped backward), the classic namespace-re-creation attack.
189
+ - **License-conflict gate at merge** — `soup adapters merge` auto-detects each adapter's license
190
+ (from `adapter_config.json` / model card) and refuses incompatible combinations unless you pass
191
+ `--license-override <reason>` (logged to the audit trail).
192
+ - **Backdoor-scan gate at merge** refuses to merge any adapter that `soup adapters scan` flags
193
+ FAIL unless you pass `--allow-unscanned`.
191
194
 
192
195
  Full history: [CHANGELOG.md](CHANGELOG.md) &middot; [GitHub Releases](https://github.com/MakazhanAlpamys/Soup/releases).
193
196
 
@@ -49,19 +49,19 @@ infrastructure instead of improving models. Soup fixes that.
49
49
 
50
50
  ## What's New
51
51
 
52
- **v0.71.1Quick wins + wiring.** Seven small-but-sharp closures:
53
-
54
- - **`soup env fix`** renders a reproducible install plan (copy/paste `uv pip` commands or a
55
- `requirements.txt`) straight from `soup-env.lock` print-only, no surprise package-manager calls.
56
- - **`soup lock write --env-lock`** auto-derives the env hash from `soup-env.lock` so you never
57
- hand-copy a 64-hex string after `soup env lock`.
58
- - **`soup serve --record-thumbs <db>`** captures 👍/👎 feedback into a local-RL SQLite, plus a new
59
- `POST /v1/thumbs` endpoint the start of an on-box feedback flywheel.
60
- - **Judge calibration persistence** — write/load a `JudgeCalibrationReport` as JSON, backed by a new
61
- `judge_calibration` registry artifact kind.
62
- - **Bundled MUSE + WMDP unlearning eval fixtures** so `soup eval unlearning --benchmark muse|wmdp`
63
- runs out of the box (WMDP forget-set probes ship **redacted** never verbatim hazardous content).
64
- - **`soup completions`** now introspects a cached base model's real LoRA target modules.
52
+ **v0.71.2Governance & supply-chain live.** Real signatures and supply-chain gates:
53
+
54
+ - **ed25519 signing** `soup adapters sign --backend ed25519 --key priv.pem` (or `--generate-key`)
55
+ produces a real detached signature over the adapter's Merkle root; `soup adapters verify
56
+ --public-key trusted.pem` does cryptographic authentication. Same for `soup attest emit
57
+ --sign ed25519` + the new `soup attest verify`. Install with `pip install soup-cli[sign]`.
58
+ - **Anti-AI-Jacking namespace pin** Hub model downloads now refuse a repo whose author silently
59
+ changed (or whose creation date jumped backward), the classic namespace-re-creation attack.
60
+ - **License-conflict gate at merge** — `soup adapters merge` auto-detects each adapter's license
61
+ (from `adapter_config.json` / model card) and refuses incompatible combinations unless you pass
62
+ `--license-override <reason>` (logged to the audit trail).
63
+ - **Backdoor-scan gate at merge** refuses to merge any adapter that `soup adapters scan` flags
64
+ FAIL unless you pass `--allow-unscanned`.
65
65
 
66
66
  Full history: [CHANGELOG.md](CHANGELOG.md) &middot; [GitHub Releases](https://github.com/MakazhanAlpamys/Soup/releases).
67
67
 
@@ -336,7 +336,20 @@ soup attest emit \
336
336
 
337
337
  Stages are a closed allowlist: `extract` / `train` / `eval` / `export` / `publish`.
338
338
  Subject SHA must be 64-hex (sha256). The default `--sign unsigned` backend ships now;
339
- Sigstore (OIDC-via-GitHub) and ed25519 air-gap signing arrive in v0.59.1.
339
+ the **`ed25519` backend is live** (`pip install soup-cli[sign]`):
340
+
341
+ ```bash
342
+ soup attest emit --stage train --subject adapter-v1 --sha aaaa...64hex \
343
+ --sign ed25519 --key signing.pem --output att.json # writes att.json.sig
344
+ soup attest verify att.json --signature att.json.sig # exit 0 valid
345
+ soup attest verify att.json --signature att.json.sig --public-key trusted.pub
346
+ ```
347
+
348
+ `verify` re-canonicalises the statement JSON (so it's platform/newline-independent)
349
+ and checks the ed25519 signature — exit 3 on tamper, key mismatch, or a sidecar with
350
+ no public key. A valid signature proves the signer *asserted* the statement; it does
351
+ not re-verify the subject digest against an artifact. Sigstore keyless signing remains
352
+ infra-blocked (needs an OIDC identity provider + Fulcio/Rekor network).
340
353
 
341
354
 
342
355
  ## EU AI Act Annex XI/XII Auto-Doc (`soup train --annex-xi`)
@@ -397,12 +410,29 @@ v0.57.0 `adapter_diff` loader so the on-disk surface stays single-source.
397
410
 
398
411
  Deterministic Merkle-root manifest over every file in the adapter dir
399
412
  (including nested `tokenizer/` / `processor/` subdirs). Tamper any file
400
- and `verify` fails. The `unsigned` backend ships live for offline tamper
401
- detection (the Merkle-root hash is the trust anchor); `sigstore` and
402
- `ed25519` backends raise `NotImplementedError` with v0.60.1 marker so CI
403
- pipelines can integrate the schema today. Signature persists as
404
- `.soup-signature.json` written atomically via the shared
405
- `atomic_write_text` helper. `--strict` mode exits 3 on any verify
413
+ and `verify` fails. The `unsigned` backend gives offline tamper detection
414
+ (the Merkle-root hash is the trust anchor). The **`ed25519` backend is live**
415
+ (`pip install soup-cli[sign]`): it adds a real detached signature over the
416
+ Merkle root for *authentication* — proof the signer holds the private key.
417
+
418
+ ```bash
419
+ # generate a keypair + sign in one shot
420
+ soup adapters sign ./adapter --backend ed25519 --generate-key signing.pem
421
+ # or sign with an existing key (or set SOUP_SIGNING_KEY)
422
+ soup adapters sign ./adapter --backend ed25519 --key signing.pem
423
+ # self-consistency verify (embedded public key)
424
+ soup adapters verify ./adapter
425
+ # genuine authentication: require the signer's key match a trusted one
426
+ soup adapters verify ./adapter --public-key trusted.pub
427
+ ```
428
+
429
+ `verify` fails closed — any tamper, wrong/missing/unreadable key, or a
430
+ signature from an untrusted key marks the adapter invalid. Signing keys and
431
+ trusted public keys are symlink-rejected and size-capped but **not**
432
+ cwd-contained (keys are secrets that live outside the project). Signature
433
+ persists as `.soup-signature.json` (atomic write). `sigstore` keyless signing
434
+ stays infra-blocked (needs an OIDC identity provider + Fulcio/Rekor network —
435
+ it can't be honestly validated offline). `--strict` mode exits 3 on any verify
406
436
  failure (CI gate code distinct from generic errors).
407
437
 
408
438
 
@@ -428,9 +458,12 @@ bool rejected so callers can't smuggle a free-for-all bypass). Threat
428
458
  model: an attacker watches a popular repo, waits for the original owner
429
459
  to delete or expire it, then re-creates the same `owner/name` with
430
460
  malicious weights. Without this control, anyone with Soup pinned to that
431
- namespace silently pulls poison on the next run. Live wiring into
432
- `utils/hubs.download_repo` lands in v0.60.1; today the helpers are
433
- operator-callable via the Python API.
461
+ namespace silently pulls poison on the next run. **The gate is wired into
462
+ Hub model downloads** it consults the pin before fetching and refuses a
463
+ mismatch (raising before any weights land). It fails **open** when repo
464
+ metadata can't be fetched (offline / rate-limited) so a transient hiccup
465
+ never blocks a legitimate download. The pin store uses SQLite WAL + a
466
+ cross-process file lock so concurrent fetches don't lose the trust anchor.
434
467
 
435
468
 
436
469
  ## License-Conflict Matrix at Merge
@@ -440,10 +473,17 @@ MIT / BSD / LGPL / MPL / GPL / AGPL / CC-BY / CC-BY-NC / Llama-2/3.x /
440
473
  Gemma / Qwen-research / Mistral-research / OpenRAIL / OpenAI-ToS /
441
474
  Anthropic-AUP. `soup adapters merge --license apache-2.0 --license
442
475
  cc-by-nc-4.0 -o merged` refuses (non-commercial cannot combine with
443
- permissive). To proceed past a flagged conflict, pass
444
- `--license-override "legal-cleared 2026-05-19 by alice"` (8-char min,
445
- 4096-char max reason). The override reason surfaces in the merge panel;
446
- audit-log integration lands in v0.60.1.
476
+ permissive). When you don't pass `--license`, the license is
477
+ **auto-detected** from each adapter's `adapter_config.json` / `config.json`
478
+ / model-card frontmatter (HF `llama3.1`-style ids map to canonical) and the
479
+ gate runs automatically when every adapter resolves to a known license. To
480
+ proceed past a flagged conflict, pass `--license-override "legal-cleared
481
+ 2026-05-19 by alice"` (8-char min, 4096-char max reason) — the decision is
482
+ **recorded to the audit log** for later legal review.
483
+
484
+ Merge is additionally gated by the backdoor scanner: any input that
485
+ `soup adapters scan` flags FAIL (or that can't be scanned) refuses the
486
+ merge with exit 3 unless you pass `--allow-unscanned`.
447
487
 
448
488
 
449
489
  ## Airgap Bundle (`soup airgap-bundle`)
@@ -151,10 +151,12 @@ soup serve --reasoning-parser deepseek-r1 Strip <think> blocks from response
151
151
  soup doctor [--nccl] Check environment (optionally check NCCL bandwidth)
152
152
  soup quickstart [--dry-run] Full demo
153
153
  soup adapters scan <adapter> Spectral backdoor scan (rank-1 dominance + outlier detection)
154
- soup adapters sign <adapter> [--backend X] Compute Merkle-root manifest (.soup-signature.json)
155
- soup adapters verify <adapter> [--strict] Verify manifest against current files
154
+ soup adapters sign <adapter> [--backend unsigned|ed25519] [--key <pem>|--generate-key <pem>] Merkle manifest + ed25519 sign
155
+ soup adapters verify <adapter> [--strict] [--public-key <pem>] Verify manifest + ed25519 signature
156
156
  soup adapters check-safetensors <adapter> [--strict] Refuse pickle / PyTorch-classic weights
157
- soup adapters merge ... --license <id> --license-override <reason> License-conflict gate
157
+ soup adapters merge ... [--license <id>] [--license-override <reason>] [--allow-unscanned] License + backdoor-scan gates (auto-detect license; scan FAIL refused)
158
+ soup attest emit ... [--sign ed25519 --key <pem>] [-o att.json] in-toto/SLSA-3 attestation (+ .sig sidecar)
159
+ soup attest verify <statement> --signature <sig> [--public-key <pem>] Verify ed25519 attestation signature
158
160
  soup airgap-bundle --model <m> --output <out.tar> Signed tarball for data-diode transfer
159
161
  soup eval unlearning <run-id> --benchmark tofu|muse|wmdp Forget Quality + Model Utility + PrivLeak verdict
160
162
  soup edit set --base <m> --method rome|memit|alphaedit --subject "..." --target "..." Surgical knowledge edit (--plan-only available)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "soup-cli"
7
- version = "0.71.1"
7
+ version = "0.71.2"
8
8
  description = "Fine-tune LLMs in one command. No SSH, no config hell."
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -54,7 +54,7 @@ wandb = ["wandb>=0.15.0,<0.18.0"]
54
54
  # Self-references `[train]` so CI / contributors get the full training stack
55
55
  # (CI runs `pip install -e ".[dev]"`; without this every test would fail at
56
56
  # `import torch`).
57
- dev = ["soup-cli[train]", "pytest>=7.0", "ruff>=0.1.0", "pytest-cov>=4.0", "httpx>=0.24.0", "mypy>=1.8.0", "pre-commit>=3.5.0"]
57
+ dev = ["soup-cli[train]", "cryptography>=41.0.0", "pytest>=7.0", "ruff>=0.1.0", "pytest-cov>=4.0", "httpx>=0.24.0", "mypy>=1.8.0", "pre-commit>=3.5.0"]
58
58
  ui = ["fastapi>=0.104.0", "uvicorn>=0.24.0"]
59
59
  serve = ["fastapi>=0.104.0", "uvicorn>=0.24.0"]
60
60
  serve-fast = ["vllm>=0.4.0", "fastapi>=0.104.0", "uvicorn>=0.24.0"]
@@ -85,6 +85,10 @@ mix = ["scikit-optimize>=0.9.0"]
85
85
  # presidio-analyzer (PII). Llama-Guard-3-1B is documented as a manual recipe
86
86
  # (license + ~600 MB weight blob too large to bundle by default).
87
87
  data-pro = ["langdetect>=1.0.9", "presidio-analyzer>=2.2.0"]
88
+ # v0.71.2 #179/#185 — ed25519 detached signing for `soup attest` / `soup
89
+ # adapters sign`. Pure-offline; Sigstore keyless (OIDC + Fulcio/Rekor network)
90
+ # stays infra-blocked and is NOT bundled here.
91
+ sign = ["cryptography>=41.0.0"]
88
92
 
89
93
  [project.scripts]
90
94
  soup = "soup_cli.cli:run"
@@ -1,3 +1,3 @@
1
1
  """Soup CLI — Fine-tune LLMs in one command."""
2
2
 
3
- __version__ = "0.71.1"
3
+ __version__ = "0.71.2"
@@ -371,7 +371,15 @@ def merge(
371
371
  None, "--license-override",
372
372
  help=(
373
373
  "Free-text justification (>=8 chars) to merge across a license "
374
- "conflict. Logged for legal review."
374
+ "conflict. Logged to the audit log for legal review (v0.71.2)."
375
+ ),
376
+ ),
377
+ allow_unscanned: bool = typer.Option(
378
+ False, "--allow-unscanned",
379
+ help=(
380
+ "Skip the v0.71.2 backdoor-scan gate. By default `adapters merge` "
381
+ "refuses to merge an input whose `adapters scan` returns FAIL (or "
382
+ "that cannot be scanned)."
375
383
  ),
376
384
  ),
377
385
  ):
@@ -379,6 +387,8 @@ def merge(
379
387
  from soup_cli.utils.adapter_merge import SUPPORTED_STRATEGIES, merge_adapters
380
388
  from soup_cli.utils.license_matrix import (
381
389
  check_license_compat,
390
+ extract_license_from_adapter,
391
+ record_license_override,
382
392
  validate_license_override_reason,
383
393
  )
384
394
 
@@ -435,8 +445,44 @@ def merge(
435
445
  console.print(panel)
436
446
  return
437
447
 
438
- # v0.60.0 Part E: license-conflict gate. Operators MUST declare a
439
- # license per adapter (or pass --license-override <reason>).
448
+ # v0.71.2 #192 backdoor-scan gate. Refuse to merge any input whose
449
+ # spectral scan returns FAIL (or that cannot be scanned at all) unless the
450
+ # operator passes --allow-unscanned. WARN is advisory-only. Runs AFTER the
451
+ # cmaes plan-only branch (which doesn't merge weights) so it gates only the
452
+ # strategies that actually write a merged adapter.
453
+ if not allow_unscanned:
454
+ from soup_cli.utils.adapter_scan import scan_adapter
455
+
456
+ for adapter_path in adapters:
457
+ try:
458
+ scan_report = scan_adapter(adapter_path)
459
+ except (FileNotFoundError, ValueError, TypeError, RuntimeError) as exc:
460
+ console.print(
461
+ f"[red]Could not scan {escape(adapter_path)} "
462
+ f"({escape(str(exc))}).[/]\n"
463
+ "[dim]Pass --allow-unscanned to merge anyway.[/]"
464
+ )
465
+ raise typer.Exit(3) from exc
466
+ if scan_report.overall == "FAIL":
467
+ console.print(
468
+ f"[red]Backdoor scan FAILED for {escape(adapter_path)}: "
469
+ f"{escape(scan_report.summary)}[/]\n"
470
+ "[dim]Pass --allow-unscanned to merge anyway "
471
+ "(not recommended).[/]"
472
+ )
473
+ raise typer.Exit(3)
474
+ if scan_report.overall == "WARN":
475
+ console.print(
476
+ f"[yellow]Backdoor scan WARN for {escape(adapter_path)}: "
477
+ f"{escape(scan_report.summary)} — proceeding.[/]"
478
+ )
479
+
480
+ # v0.60.0 Part E: license-conflict gate. Operators may declare a license
481
+ # per adapter (--license, repeatable) OR rely on v0.71.2 #187
482
+ # auto-extraction from adapter_config.json / config.json / model-card
483
+ # frontmatter. On a conflict, --license-override <reason> proceeds and the
484
+ # decision is recorded to the audit log (#190).
485
+ gate_licenses: Optional[list[str]] = None
440
486
  if license_ids:
441
487
  if len(license_ids) != len(adapters):
442
488
  console.print(
@@ -444,8 +490,26 @@ def merge(
444
490
  f"adapter count {len(adapters)}[/]"
445
491
  )
446
492
  raise typer.Exit(2)
493
+ gate_licenses = list(license_ids)
494
+ else:
495
+ # #187 — auto-detect. Only run the gate if EVERY adapter resolves to a
496
+ # known license; partial info would make the conflict check misleading.
497
+ extracted = [extract_license_from_adapter(a) for a in adapters]
498
+ if all(e is not None for e in extracted):
499
+ gate_licenses = [str(e) for e in extracted]
500
+ console.print(
501
+ "[dim]Auto-detected licenses: "
502
+ f"{escape(', '.join(gate_licenses))}[/]"
503
+ )
504
+ elif license_override is not None:
505
+ console.print(
506
+ "[yellow]--license-override given but licenses could not be "
507
+ "auto-detected for every adapter; no conflict gate triggered.[/]"
508
+ )
509
+
510
+ if gate_licenses is not None:
447
511
  try:
448
- license_report = check_license_compat(license_ids)
512
+ license_report = check_license_compat(gate_licenses)
449
513
  except (TypeError, ValueError) as exc:
450
514
  console.print(f"[red]License check failed: {escape(str(exc))}[/]")
451
515
  raise typer.Exit(2) from exc
@@ -467,16 +531,13 @@ def merge(
467
531
  f"[red]Invalid --license-override: {escape(str(exc))}[/]"
468
532
  )
469
533
  raise typer.Exit(2) from exc
534
+ # #190 — persist the override decision for legal review.
535
+ record_license_override(gate_licenses, cleared)
470
536
  console.print(
471
537
  f"[yellow]License conflict overridden:[/] "
472
538
  f"{escape(license_report.reason)}\n"
473
- f"[dim]Reason: {escape(cleared)}[/]"
539
+ f"[dim]Reason: {escape(cleared)} (recorded to audit log)[/]"
474
540
  )
475
- elif license_override is not None:
476
- console.print(
477
- "[yellow]--license-override given without --license declarations; "
478
- "no conflict gate triggered.[/]"
479
- )
480
541
 
481
542
  parsed_weights = None
482
543
  if weights:
@@ -762,19 +823,32 @@ def sign(
762
823
  adapter: str = typer.Argument(..., help="Path to adapter directory"),
763
824
  backend: str = typer.Option(
764
825
  "unsigned", "--backend",
765
- help="Signing backend: unsigned | ed25519 | sigstore (v0.60.0 ships unsigned only)",
826
+ help="Signing backend: unsigned | ed25519 (sigstore is infra-blocked)",
827
+ ),
828
+ key: Optional[str] = typer.Option(
829
+ None, "--key",
830
+ help="ed25519 private-key PEM path (or set SOUP_SIGNING_KEY).",
831
+ ),
832
+ generate_key: Optional[str] = typer.Option(
833
+ None, "--generate-key",
834
+ help="Generate a fresh ed25519 keypair, persist the private key here "
835
+ "(PEM, 0600), and sign with it.",
766
836
  ),
767
837
  ):
768
- """Compute manifest + write ``.soup-signature.json`` (v0.60.0).
838
+ """Compute manifest + write ``.soup-signature.json`` (v0.60.0, ed25519 v0.71.2).
769
839
 
770
- Default backend is ``unsigned`` provides offline tamper detection
771
- via Merkle-root hash. Sigstore + ed25519 backends raise NotImplementedError
772
- until v0.60.1.
840
+ ``unsigned`` (default) gives offline tamper detection via a Merkle-root
841
+ hash. ``ed25519`` (v0.71.2 #185) adds a real detached signature over that
842
+ root — pass ``--key <priv.pem>``, set ``SOUP_SIGNING_KEY``, or use
843
+ ``--generate-key <out.pem>``. ``sigstore`` keyless signing is infra-blocked
844
+ (needs an OIDC identity provider + Fulcio/Rekor network).
773
845
  """
774
846
  from soup_cli.utils.adapter_sign import sign_adapter
775
847
 
776
848
  try:
777
- record = sign_adapter(adapter, backend=backend)
849
+ record = sign_adapter(
850
+ adapter, backend=backend, key_path=key, generate_key_path=generate_key
851
+ )
778
852
  except FileNotFoundError as exc:
779
853
  console.print(f"[red]{escape(str(exc))}[/]")
780
854
  raise typer.Exit(1) from exc
@@ -785,6 +859,12 @@ def sign(
785
859
  console.print(f"[red]{escape(str(exc))}[/]")
786
860
  raise typer.Exit(2) from exc
787
861
 
862
+ if generate_key and record.backend == "ed25519":
863
+ console.print(
864
+ f"[yellow]Generated ed25519 private key -> {escape(generate_key)} "
865
+ "(keep it secret; verify with the matching public key).[/]"
866
+ )
867
+
788
868
  console.print(
789
869
  Panel(
790
870
  f"Adapter: [bold]{escape(record.manifest.adapter)}[/]\n"
@@ -804,8 +884,18 @@ def verify(
804
884
  False, "--strict",
805
885
  help="Exit 3 on any verification failure (CI-friendly)",
806
886
  ),
887
+ public_key: Optional[str] = typer.Option(
888
+ None, "--public-key",
889
+ help="Trusted ed25519 public-key PEM. When set, the embedded signing "
890
+ "key must match it (genuine authentication, not just consistency).",
891
+ ),
807
892
  ):
808
- """Verify ``.soup-signature.json`` against current files (v0.60.0).
893
+ """Verify ``.soup-signature.json`` against current files (v0.60.0, ed25519 v0.71.2).
894
+
895
+ For ``ed25519``-signed adapters the detached signature is verified against
896
+ the embedded public key (self-consistency); pass ``--public-key
897
+ <trusted.pem>`` to additionally require the signer's key match a key you
898
+ trust out of band.
809
899
 
810
900
  Exit codes:
811
901
  0 signature present and matches
@@ -815,10 +905,9 @@ def verify(
815
905
  from soup_cli.utils.adapter_sign import verify_adapter
816
906
 
817
907
  try:
818
- if strict:
819
- report = verify_adapter(adapter, strict=True)
820
- else:
821
- report = verify_adapter(adapter, strict=False)
908
+ report = verify_adapter(
909
+ adapter, strict=strict, trusted_public_key=public_key
910
+ )
822
911
  except FileNotFoundError as exc:
823
912
  console.print(f"[red]{escape(str(exc))}[/]")
824
913
  raise typer.Exit(1) from exc