Files
weatherreporter/docs/integrations/comparison-bundle.md

4.0 KiB

Comparison Bundle Contract

A comparison bundle is the durable, flat artifact produced when one report is executed with multiple explicit Promptkit profiles. This document is the canonical contract for consumers of those bundles. Command invocation and JSON action summaries belong to the CLI reference; destination handling and retention belong to the operations guide.

Version And Layout

The current and only supported manifest schema version is weatherreporter.comparison.v1. A bundle directory contains exactly these regular, non-symlinked files:

comparison.json
data-package.yml
NN-profile-slug.md

comparison.json is the manifest and data-package.yml is the exact YAML input supplied to every selected profile. There is one Markdown file for each successful result and none for failed results. NN is the one-based selected profile position, zero padded to at least two digits (and widened only when needed for 100 or more profiles). The profile slug preserves ASCII letters, digits, -, and _; each run of other characters becomes one -; edge - and _ characters are removed; the value is capped at 64 bytes; and an empty slug becomes profile. Logical profile IDs remain authoritative in the manifest.

All manifest paths are basenames relative to the bundle root. They never use path separators, . or ... The CLI reports absolute paths only after a bundle has been published.

Manifest Schema

The manifest is UTF-8 JSON, encoded as two-space-indented JSON with one trailing newline. Its fields appear in this order:

schemaVersion, comparisonId, startedAt, finishedAt, reportId, validPeriod,
timezone, promptId, promptVersion, promptHash, dataPackage, total, succeeded,
failed, results

validPeriod contains start and end; it is a nonempty half-open period. dataPackage contains path (always data-package.yml) and sha256 (the lowercase, 64-character SHA-256 digest of that file's exact bytes). results is in the explicit profile-selection order. Its result-object fields appear in this order:

position, profileId, backendId, modelName, status, validationStatus,
reportPath, error

startedAt and finishedAt are nonzero UTC timestamps, and the latter is not earlier than the former. validPeriod retains its resolved time offset. reportId, timezone, prompt identity, model name, and comparison ID are nonblank. promptHash and dataPackage.sha256 are lowercase SHA-256 digests.

Result Invariants

total is at least two and equals the number of results. Positions are contiguous from one, profile IDs are distinct and nonblank, and succeeded + failed == total.

A successful result has status: "succeeded", validationStatus: "passed", a unique Markdown reportPath, and no error. A failed result has status: "failed", no reportPath, and an error object with nonblank category and message. Its validation status is absent, failed, or skipped. Error messages are valid UTF-8 and no longer than 1,024 bytes. backendId and validationStatus are omitted when unavailable.

Every successful Markdown file is declared by exactly one successful result. The directory contains no extra entries. Consumers can therefore verify the data-package digest and the full manifest-to-file mapping without scanning a larger workspace.

Compatibility And Sensitivity

Weatherreporter recognizes a replaceable bundle only when it exactly satisfies the current version, schema, file set, file types, relative-path rules, and data-package digest. It rejects unknown manifest fields, multiple JSON values, extra entries, symlinks, and future or otherwise unsupported versions. Treat a bundle that fails recognition as an ordinary directory, not as a compatible bundle.

The manifest contains safe operational provenance, but data-package.yml and the generated Markdown can contain sensitive weather or location context. Do not assume these artifacts are safe for public distribution. Handle retention, access, and deletion according to the operations guide.