Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 17 additions & 11 deletions docs/ADRs/013_sampled_forecast_wire_contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ means, and cleanup of the internal store has no owner yet.*)
it defines the ensembles and launches the runs that enter the wire (using
pipeline-core's machinery); it owns the **delivery pointer** — the declaration of
*which source ships to which partner* (as of adoption, the `postprocessors/un_fao`
launch config naming the ensemble; their ADR-017 proposes making it first-class — see
launch config naming the ensemble; their `vmo_017` (views-models ADR-017) proposes making it first-class — see
§4.2a for how the pointer meets this contract); it owns the run-0 end-to-end
verification (views-models#230, §11.1–§11.2); and it hosts the platform's decision
record (this contract was ratified on views-models#149).
Expand Down Expand Up @@ -942,13 +942,19 @@ record execution progress against it.
version is written by the release that built it, so it cannot disagree with the code
beside it. In force now, for 3.0.0 onward.

**`"unknown"` when the producer ran an editable install** — and this half is **not yet in
any released version**, which is the part the originating request (#228) stated too
strongly. An editable install's recorded version is fixed at the moment `pip install -e`
last ran and never tracks the source afterwards; pipeline-core#403 makes that case report
`"unknown"` instead of a stale number. That fix merged **2026-08-04**, a day and a half
*after* 3.0.0 was uploaded (2026-08-03 02:06 UTC), so **no released version contains it.**
It becomes true of producers at pipeline-core's next release.
**`"unknown"` when the producer ran an editable install** — this half was **not in any
released version when E3 was written**, which is the part the originating request (#228)
stated too strongly. An editable install's recorded version is fixed at the moment
`pip install -e` last ran and never tracks the source afterwards; pipeline-core#403 makes
that case report `"unknown"` instead of a stale number. That fix merged **2026-08-04**, a
day and a half *after* 3.0.0 was uploaded (2026-08-03 02:06 UTC).

**Discharged 2026-08-13: it is now released.** views-pipeline-core **3.0.1** was uploaded
to PyPI on **2026-08-11 13:40 UTC** and contains the fix — verified at the tag rather than
taken on trust: at 3.0.0 `_pipeline_core_version()` is `return version("views_pipeline_core")`
with no editable detection at all, and at 3.0.1 it reads `direct_url.json`, checks
`dir_info.editable`, and returns `"unknown"` when it is set. Both halves of the lift are
therefore in force, the second for producers running 3.0.1 or later.

Verified here rather than taken on trust, 2026-08-10: in this repository's development
environment `importlib.metadata` reports pipeline-core **2.3.0** while the source beside
Expand All @@ -958,9 +964,9 @@ record execution progress against it.

**What consumers must do, and it is the operational point.** Treat `"unknown"` as *"do
not infer the producing version"*, never as an error. The set of runs producing
`"unknown"` will **widen** at pipeline-core's next release, because every developer run
joins it. A consumer that starts rejecting `"unknown"` on the strength of this lift would
break exactly those runs.
`"unknown"` **has now widened**, as this erratum predicted it would: every developer run
on 3.0.1 or later joins it. A consumer that starts rejecting `"unknown"` on the strength
of this lift would break exactly those runs.

This repository does not produce the value — Hop-B re-embeds the Hop-A header untouched
(`contract/wire/sink.py`) — so nothing here changes. The field is declared by this
Expand Down
9 changes: 8 additions & 1 deletion docs/ADRs/017_facts_across_a_private_boundary.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# ADR-017: Facts shared with a repository we cannot read
# vpp_017 (ADR-017): Facts shared with a repository we cannot read

**Status:** Accepted

> **Cite this as `vpp_017` outside this repository.** views-models and views-crafdapi each
> have their own ADR-017 (*Forecast Sources, Composition, and Delivery*, and *Reference Data
> in Repository*), so a bare "ADR-017" resolves to the wrong document for a reader sitting
> in either of them (#264). The number is unchanged and every existing citation stays valid
> — the prefix is additive.

**Date:** 2026-08-10
**Decider:** Simon Polichinel von der Maase
**Scope:** what this repository does when it depends on a fact held in a repository it
Expand Down
36 changes: 33 additions & 3 deletions docs/ADRs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,16 +104,46 @@ These ADRs form the architectural constitution of the repository.
for a dated declaration rather than prose. The credential for the one genuinely private
sibling is deferred with a named trigger.

- **ADR-017** — Facts Shared With a Repository We Cannot Read
- **[vpp_017](017_facts_across_a_private_boundary.md)** — Facts Shared With a Repository We Cannot Read
The delivery label this repository writes is owned by the consuming API and mirrored here;
if the two drift the upload succeeds, the file is stored, and the consumer's endpoint is
empty with no error anywhere. Verifying the mirror currently means reading the consumer's
empty with no error anywhere. Verifying the mirror used to mean reading the consumer's
source, which is impossible in CI when that consumer is private — and private consumer APIs
are a standing category, not a one-off. Decides that such a fact is declared in the public
are a standing category, not a one-off. *(That reading is gone: #248 deleted both source
reads on 2026-08-12 after two consumers broke them in a day by improving their own code.)* Decides that such a fact is declared in the public
coordinate registry and each side verifies itself against it, so neither reads the other's
source. No credential, for any number of private APIs. States plainly the half it does not
cover: the consumer's own code against its own declaration.

### Why one of these carries a `vpp_` prefix

Three repositories each numbered an ADR **017**, and a bare "ADR-017" in a cross-repo
sentence resolves to the wrong document for a reader sitting in either of the other two:

| Repo | Prefix | ADR-017 |
|---|---|---|
| views-models | `vmo_` | *Forecast Sources, Composition, and Delivery* |
| **views-postprocessing** | **`vpp_`** | ***Facts shared with a repository we cannot read*** |
| views-crafdapi | `vcr_` | *Reference Data in Repository* |

**The prefix is additive.** The number does not change and no existing citation breaks.

**The usage rule** (adopted from views-models, which landed this first in its #393):
intra-repo prose may stay bare; write `vpp_017` wherever the sentence is read from, or
could be read from, another repository.

This is not yet a platform-wide convention — these three issues are its first application,
driven by an active collision rather than a sweep. views-postprocessing#264,
views-models#393 (landed), views-crafdapi#58.

*Audited when adopting: this repository has **no wrong referents** — no sentence here is
about the wrong decision, which is the defect the collision causes elsewhere. It has **one
bare foreign citation**: ADR-013 §7(d) writes "their ADR-017" of views-models', qualified
only by an antecedent two sentences earlier. Now `vmo_017`. Every other reference to
views-models' 017 already named it, and every bare `ADR-017` here means this document. The
prefix is for readers arriving from another repo.*


ADRs numbered 010 and above define:

- Domain-specific decisions
Expand Down
2 changes: 1 addition & 1 deletion docs/CICs/UNFAOPostProcessorManager.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ that cannot raise — and "accessing `_enricher` directly", an attribute removed
- **Beige tests:** Missing ensemble name in config; None environment variables; empty forecast bucket; DataFrames with unexpected index structure
- **Red tests:** Corrupted parquet downloads; network timeouts during upload; DataFrames where all cells map to None (all-ocean input)

Currently: the manager cannot be instantiated without `views-pipeline-core`, so its stage logic is covered by **source-scan and seam tests** — `tests/test_validation.py` (the metadata null-gate, tested against `contract/historical.assert_metadata_complete` where it fires, plus pins that it has not drifted back into `_validate`), `tests/test_launch_config.py` (the refusals), `tests/test_gaul_lookup_access.py` (one lookup read, threaded). There is no longer a replica of any manager method: `tests/test_validation.py` held one until S4 (#185) and it had diverged from `_validate` since #149, while `tests/test_append_metadata.py` was deleted in #149 with the method it mirrored. <!-- legacy-ok: retirement record --> A full end-to-end test against the **live manager** still requires a production-like environment and is tracked as **#18**; þing-02 **D2** forbids integration tests against the production Appwrite project, no non-production one existing.
Currently: the manager cannot be instantiated without `views-pipeline-core`, so its stage logic is covered by **source-scan and seam tests** — `tests/test_validation.py` (the metadata null-gate, tested against `contract/historical.assert_metadata_complete` where it fires, plus pins that it has not drifted back into `_validate`), `tests/test_launch_config.py` (the refusals), `tests/test_gaul_lookup_access.py` (one lookup read, threaded). There is no longer a replica of any manager method: `tests/test_validation.py` held one until S4 (#185) and it had diverged from `_validate` since #149, while `tests/test_append_metadata.py` was deleted in #149 with the method it mirrored. <!-- legacy-ok: retirement record --> A full end-to-end test against the **live manager** still requires a production-like environment and is tracked as **#18**; **þing-01 D2** forbids *integration* tests against the production Appwrite project while no non-production one exists — conditionally, and it **permits read-only preflight validation** (register C-95, C-96).

The input-integrity guards (S0–S6, epic #51) are representation-free invariants in `views_postprocessing/delivery/` that the manager **calls** (never inherits). Each has primitives unit tests — `tests/test_delivery_coverage.py` (S1/S4), `tests/test_delivery_observed_range.py` (S2), `tests/test_provenance.py` (S5), `tests/test_frame_extraction.py` (the seam), `tests/test_store_metadata.py` (store identity) — and `tests/test_input_integrity_e2e.py` drives the invariants on **primitives**, which is how the manager calls them. S3's forecast-identity rule moved to the wire layer (#150) and is covered by `tests/test_wire_source_selection.py`. The design contract (representation-free, called-not-inherited) is pinned by `tests/test_input_integrity_design_contract.py`.

Expand Down
6 changes: 3 additions & 3 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading