Ratified in views-crafdapi ADR-037 (2026-08-26). This is the upstream half; the consumer half is ours.
The problem, on our side
views-crafdapi selects what to serve by taking the most recently uploaded manifest — get_latest_manifest() returns docs[0] after sorting by $createdAt. There is no record of a choice anywhere.
So uploading any second forecast artifact to crafd_bucket — a re-run, a test, eventually a calibration or validation run — silently becomes the published CRAF'd forecast. The only control we have is a comma-separated list of file IDs in an environment variable.
The ask
When un_crafd completes a delivery, write a small document to the CRAF'd bucket's metadata collection naming the run it just published:
- the
run_id it delivered
- when, and by what
- nothing else
Why you rather than us. You already know which run you just published — that knowledge exists at the point of upload and nowhere else. The alternative we considered was a manual step in our monthly runbook, and we rejected it: a step in a runbook is a step someone can skip, and the failure would be a fresh run stored but not served, discovered whenever someone next looked at /provenance/forecast.
Writing it at delivery means a failed write fails the delivery loudly, at the point it happened.
What we do with it
We read it instead of sorting by upload time. If it is absent or names a run that is not present, we refuse rather than falling back to newest — that is our ADR-033 fail-visible guarantee, which currently rides on a cache-identity comparison and would move here.
Reading it is buildable on our side now and does not block on this. Until this lands we still select by upload order, so the hazard above stands.
Note on the collection schema
The metadata collection's attribute set is pinned by a golden test on our side (tests/test_metadata_contract.py), and PredictionMetadata is a closed value object. Adding an attribute is a deliberate contract change on both sides rather than an edit — worth agreeing the field names before either of us writes code.
Happy to take the shape of the document from you, since you are writing it.
Ratified in views-crafdapi ADR-037 (2026-08-26). This is the upstream half; the consumer half is ours.
The problem, on our side
views-crafdapi selects what to serve by taking the most recently uploaded manifest —
get_latest_manifest()returnsdocs[0]after sorting by$createdAt. There is no record of a choice anywhere.So uploading any second forecast artifact to
crafd_bucket— a re-run, a test, eventually a calibration or validation run — silently becomes the published CRAF'd forecast. The only control we have is a comma-separated list of file IDs in an environment variable.The ask
When
un_crafdcompletes a delivery, write a small document to the CRAF'd bucket's metadata collection naming the run it just published:run_idit deliveredWhy you rather than us. You already know which run you just published — that knowledge exists at the point of upload and nowhere else. The alternative we considered was a manual step in our monthly runbook, and we rejected it: a step in a runbook is a step someone can skip, and the failure would be a fresh run stored but not served, discovered whenever someone next looked at
/provenance/forecast.Writing it at delivery means a failed write fails the delivery loudly, at the point it happened.
What we do with it
We read it instead of sorting by upload time. If it is absent or names a run that is not present, we refuse rather than falling back to newest — that is our ADR-033 fail-visible guarantee, which currently rides on a cache-identity comparison and would move here.
Reading it is buildable on our side now and does not block on this. Until this lands we still select by upload order, so the hazard above stands.
Note on the collection schema
The metadata collection's attribute set is pinned by a golden test on our side (
tests/test_metadata_contract.py), andPredictionMetadatais a closed value object. Adding an attribute is a deliberate contract change on both sides rather than an edit — worth agreeing the field names before either of us writes code.Happy to take the shape of the document from you, since you are writing it.