Governance & Provenance. Every Soup run is procurement-ready. ML-BOMs, SLSA-3 attestations, EU AI Act Annex XI/XII auto-docs, HIPAA/SOC2 audit log, SR 11-7 reproducibility receipts. The compliance story no SaaS can tell because the operator is the only one who sees weights, dataset, eval, and cost together. Pure orchestration on top of v0.26 Registry + v0.34 cost tracker + v0.56 diagnose — no new training code, just structured exporters that emit the formats procurement demands.
What's New
soup bom emit --format cyclonedx|spdx|both— CycloneDX 1.6 ML-BOM + SPDX 2.3 + AI-profile dual emitter from any RegistryEntry. Base-model SHA, config SHA, data SHA, parent lineage, license-chain (SPDX id), and SLSA-style material list. Atomic write under cwd containment +os.lstatsymlink rejection (TOCTOU-safe).soup attest emit --stage train --subject <name> --sha <64hex>— in-toto v1 Statement wrapping a SLSA-3 provenance v1 predicate. Stage allowlist (extract/train/eval/export/publish). Sigstore + ed25519 signing arrive in v0.59.1; the schema + atomic-write surface ships now so CI can integrate.soup train --annex-xi <out.md>— EU AI Act Annex XI Section 1+2 (technical documentation) + Annex XII Article 53(1)(d) (public training summary) markdown renderer. Top-10 domains, modality breakdown, FLOPs / kWh / CO₂. Markdown-active chars in operator-controlled fields are escape-neutralised — defends against forged-heading / Markdown-link injection in downstream PDF/HTML renderers.soup audit-log tail / rotate— append-only JSONL audit at~/.soup/audit.jsonl(override viaSOUP_AUDIT_LOG_PATH, containment-checked to$HOME / $CWD / $TMPDIR). Splunk/ELK ingestion-ready. PII redaction across every string field via the v0.40.3_SECRET_REpolicy. POSIXO_NOFOLLOW+0o600perms; rotation at 100 MiB with symlink rejection at the backup path.soup train --repro-receipt <out.json>— SR 11-7-style receipt: seeds (torch / numpy / python), Python version, OS + arch, Soup version, kernel versions (CUDA / cuDNN / NCCL — best-effort from torch when available), GPU model + driver.- CO₂ + energy schema —
EnergyMeasurementfrozen dataclass with PUE adjustment, electricityMap SSRF-hardened endpoint validator (scheme allowlist + loopback-only HTTP + private-IP rejection — full parity with v0.51.0validate_hub_endpoint). CodeCarbon hook lands in v0.59.1. - Shared
atomic_write_texthelper — all four v0.59 atomic writes (BOM / attest / Annex / repro) now go through onepaths.atomic_write_text— single-source-of-truth so a future contributor cannot accidentally drop the symlink check (mirrors v0.40.6 / v0.53.5 centralisation policy).
Install / Upgrade
```bash
pip install --upgrade soup-cli
soup version # should print soup v0.59.0
```
Security
3 HIGH + 5 MEDIUM + 4 LOW fixes across four review waves before tag:
- HIGH: audit-log
lstat-before-write TOCTOU (nolexistsrace); POSIXO_NOFOLLOWon log append; redaction extended from args-only to every string field (command / host_id / operator_id);SOUP_AUDIT_LOG_PATHenv override containment to$HOME / $CWD / $TMPDIR; BOM artifactsize_bytesvalidation (TypeError surface fix);BomEntry.attach_energytype-hint viaTYPE_CHECKING;default_log_pathexported as public symbol; duplicated seeds validation removed. - MEDIUM: Annex markdown injection escape (
|[](){}!<>+ newline / CR / tab in every operator-controlled field); sharedpaths.atomic_write_texthelper centralising four duplicated TOCTOU patterns;energy.measure_run_energyinconsistent-return-type fixed;urlsplitIPv6 hostname stripping cleanup; SLSAstartedOn/finishedOnseparable via invocation mapping;_format_flopsbool/NaN/Inf guard.
Known Limitations
- Sigstore + ed25519 signing deferred to v0.59.1.
UNSIGNEDbackend live;--sign sigstore/--sign ed25519raiseNotImplementedErrorwith explicit marker. - Live CodeCarbon hook deferred to v0.59.1.
measure_run_energyreturnsNoneeven with codecarbon installed. The SSRF-hardened electricityMap validator ships now so v0.59.1 wiring is additive. - PDF rendering deferred to v0.59.1.
soup train --annex-xiemits Markdown;reportlabintegration later. - Soup Can manifest v3 attestations field deferred to v0.59.1. Attest emit is a standalone surface for now; embedding under a manifest-version bump is the v0.59.1 deliverable.
- Audit-log auto-instrumentation NOT shipped. Every command does NOT yet auto-emit a line via the Typer top-level callback; only the reader + write API + redaction + rotation are live.
- Top-10 domain auto-population NOT shipped.
AnnexXIData.top_domainsaccepts an operator-supplied tuple but--annex-xicurrently passes empty. Auto-extraction from thedata.trainJSONL manifest is the v0.59.1 deliverable. --annex-xi+--repro-receiptfire only onLOCAL_RANK=0. Single-node multi-GPU correct; multi-nodeRANK-aware guard tracked separately.
Test count: 9193 → 9294 (+101 net). Four review waves: 0 CRITICAL + 8 HIGH + 12 MEDIUM + 4 LOW resolved.