Skip to content

chore(deps): lift the views-frames cap to <4 — measured, not assumed (#324) - #325

Merged
Polichinel merged 3 commits into
developmentfrom
chore/views-frames-cap-324
Nov 2, 2026
Merged

Polichinel merged 3 commits into
developmentfrom
chore/views-frames-cap-324

Conversation

@Polichinel

@Polichinel Polichinel commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #324.

Review correction (5f9b3d5). The first commit offered a check that could not fail as its headline proof, and this description repeated it. git diff v2.0.0..v3.0.0 -- views_frames/io/ matches nothing — views-frames uses a src layout — so it returns empty whatever changed. Corrected throughout to src/views_frames/io/, with a control command added to the fixture README. The underlying claim was true; the evidence for it was not. Detail at the bottom.

What #324 asked, and why the answer is shorter than expected

Can views-frames 2.x read and re-emit shards that were published by views-frames 3.x / views-pipeline-core 3.4.0?

The premise does not hold: Hop-A does not read through views_frames at all. contract/track_a_source.py:82-86 decodes the Track-A archive with zipfile + np.load + json.loads — stdlib and numpy. views_frames is used only to construct the in-process PredictionFrame from the already-decoded arrays. Inbound shard bytes are a views-pipeline-core archive contract, not a views-frames format, so no views-frames version can make this repo unable to read them.

There is exactly one views-frames serialization call in this repository, and it is outbound: contract/wire/shard.py:34, vf_arrow.save(...).

Two corrections to the issue's reading of this repo

#324 says Measured
"11 modules import it" 4 production modules do: contract/frames.py, contract/frame_extraction.py, contract/track_a_source.py, contract/wire/shard.py. The other seven mention the string in prose — and three of them (delivery/__init__.py:5, delivery/draws.py:5, delivery/coverage.py:4) mention it to say they must not import it.
"two of them sit directly on the wire path: shard.py … and contract/wire/header.py the header" One. contract/wire/header.py does not import views_frames; its only mention is a docstring at line 4.

Stated without any edge, because this is the same error class as the grep-as-repository-state mistake made here on 2026-10-30: a grep for a module name reported as an import list. This PR then made a cousin of it, below.

So the pod run is not needed to answer it — but the cap still had to go

Not because of correctness. Because of the sentence in the middle of #324:

views-postprocessing cannot currently run on the stack that produces the forecasts it postprocesses.

That is right, and it is the whole cost. >=2.0.0,<3 blocked co-installation with the ensemble lane for no benefit:

  • The 3.0.0 MAJOR's behavioural change is confined to views_frames_reconcile (donor fill for empty-grid draws, views-frames ADR-030). This repo has zero importers of that package — reconciliation left in C2 — Retire views_postprocessing/reconciliation/ (moved to views_frames_reconcile) #62.
  • It is not the only file the MAJOR touches: views_frames/conformance/__init__.py moves its published CONFORMANCE_FLOOR from 2.0.0 to 3.0.0. Inert here — grep -rn CONFORMANCE_FLOOR over this repo returns nothing.
  • views_frames/io/arrow.py is byte-identical across the boundary. git diff v2.0.0..v3.0.0 -- src/views_frames/io/ is empty, and the control -- src/views_frames/ is not.

Proved the way the fixture README requires

tests/fixtures/wire_contract/README.md already set the standard for this exact move — "Raising it again does not require regenerating the fixture — but it does require proving that, the same way."

Regenerating the ADR-013 §10 golden fixture with scripts/build_wire_fixture.py under views-frames 3.0.0 at the pinned toolchain (pyarrow 16.1.0) reproduces all five artifacts byte-identically: SHA256SUMS unchanged, arrow shard still 203650fd…12c54. The fixture directory was then restored and the tree confirmed clean.

Full suite on Python 3.11 (what CI uses) with the resulting locked set — views-frames 3.0.0, views-pipeline-core 3.4.0, pandas 1.5.3, pyarrow 16.1.0:

527 passed, 3 skipped, 41 xfailed, 0 failed

ruff check . clean, poetry check --lock clean. No import contracts are declared in this repo.

Why the lock carries pipeline-core 3.4.0 too

views-frames 3.x is not reachable alone. views-pipeline-core 3.3.0 declares views-frames >=1.10.2,<3.0.0, so only 3.4.0 permits frames 3.x. Both land inside ranges pyproject.toml already declares, so no second constraint changed.

The lock moves deliberately rather than being left at 2.0.0: a ceiling no CI run exercises is a claim, not a fact, and production runs on frames 3.x.

Floors stay put — views-frames at 2.0.0, views-pipeline-core at 3.0.0. Nothing here needs 3.x, and (frames 2.x + pipeline-core 3.3.x) remains a coherent resolution worth keeping installable.

The review correction, in full

Two defects, both in this change's own prose rather than in its effect.

1. A check that could not fail. Both changed files quoted git diff v2.0.0..v3.0.0 -- views_frames/io/ as the evidence that the arrow writer is unchanged. views-frames has a src layout, so that pathspec matches nothing in either tree and git diff prints nothing and exits 0 — empty whether or not arrow.py changed. Demonstrated by aiming the same form at views_frames/conformance/, a directory that did change in 3.0.0: also empty.

The placement is what makes this more than a typo. The fixture README exists so that "the byte question is not re-opened", so the next person raising this pin would have re-run a command that cannot fail and read it as a pass — a guard that cannot fire, in the document whose job is to be re-run. Fixed to src/views_frames/io/, and the README now carries the control line and the reason an empty git diff is ambiguous. The paragraph says plainly that its own first draft had the bug.

2. "Confined to views_frames_reconcile" was overstated — see the CONFORMANCE_FLOOR bullet above. The non-import claim was correct as written and is unchanged.

5c8a08a's commit message still quotes the bad pathspec. History is not being rewritten to hide it: force-pushing is the operator's call in this repository, and the record of the correction is worth more than a clean one.

Not addressed here, deliberately

#324's two environment observations are views-models' to act on, and one needs the operator:

  1. envs/views-postprocessing holds views-frames 1.10.2 — below this repo's own >=2.0.0 floor. Worth knowing that this does not become correct merely because the ceiling moved; the floor is still unmet in that prefix.
  2. The duplicate lib/python3.1/site-packages/ tree (note python3.1, not 3.11). Untouched. It sits in a prefix that un_fao's armed delivery shares, so pruning it is an operator call, not a delivery-path one.

Related: views-frames#283, views-models#659, views-models#663, views-crafdapi#180.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ANY1CCy9Xo7zjMY4XJ69v9

Polichinel and others added 3 commits November 2, 2026 08:55
…324)

`pyproject.toml` pinned `views-frames = ">=2.0.0,<3"`. views-models' pod runners
require views-frames >= 3.0.0, so the cap meant this repository could not be
installed alongside the ensemble lane that produces its input. That is the real
cost; it is not a correctness problem.

The cap excluded a release that changes nothing here. The whole 3.0.0 MAJOR is in
`views_frames_reconcile` (donor fill for empty-grid draws, views-frames ADR-030),
which this repository does not import — reconciliation left in #62.
`views_frames/io/arrow.py`, the only views_frames module that produces bytes we
publish (`contract/wire/shard.py:34`), is byte-identical across the boundary:
`git diff v2.0.0..v3.0.0 -- views_frames/io/` is empty.

Proved the way the fixture README requires, rather than argued. Regenerating the
ADR-013 §10 golden fixture under views-frames 3.0.0 at the pinned toolchain
reproduces all five artifacts byte-identically — SHA256SUMS unchanged, the arrow
shard still `203650fd…12c54`. Full suite on Python 3.11 with the resulting locked
set: 527 passed, 3 skipped, 41 xfailed, 0 failed.

The lock moves so CI asserts the new ceiling instead of leaving it a claim, and it
carries views-pipeline-core 3.3.0 -> 3.4.0 with it: 3.3.0 capped
`views-frames <3.0.0`, so frames 3.x is not reachable alone. Both land inside
ranges already declared here. Floors stay at views-frames 2.0.0 and
views-pipeline-core 3.0.0 deliberately — (frames 2.x + pipeline-core 3.3.x) is
still a coherent resolution and nothing here needs 3.x.

Also corrects the fixture README, which recorded pipeline-core's `<2.0.0` cap as a
live blocker. It is not one any more, and a comment asserting a blocker that has
been lifted is the shape that manufactured three false findings in this platform
two days ago.

Answers #324's question as asked ("can 2.x read shards published by 3.x?") by
noting its premise does not hold: Hop-A does not read through views_frames at all.
`contract/track_a_source.py:82-86` decodes the Track-A archive with zipfile +
np.load + json.loads, so inbound shard bytes are a pipeline-core contract. The one
views-frames serialization call in this repository is outbound.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ANY1CCy9Xo7zjMY4XJ69v9
Review found two factual defects in 5c8a08a's own prose. Both are real.

**1. The proof command was vacuous.** Both files quoted

    git diff v2.0.0..v3.0.0 -- views_frames/io/     # "is empty"

as the evidence that the arrow writer is unchanged. views-frames uses a **src
layout**: the package is at `src/views_frames/io/`. That pathspec matches nothing
in either tree, so git prints nothing and exits 0 — it returns empty whether or
not arrow.py changed. Demonstrated: the same form aimed at
`views_frames/conformance/`, a directory that definitely changed in 3.0.0, is also
empty.

This is the guards-that-cannot-fire family, and the placement makes it worse than
a typo. The fixture README exists so "the byte question is not re-opened", so the
next person raising this pin would have re-run a command that cannot fail and read
it as a pass. Corrected to `src/views_frames/io/`, and the README now carries a
**control** line (`-- src/views_frames/`, which must be NON-empty) with the reason:
an empty result from `git diff` does not distinguish "nothing changed" from
"nothing matched". The paragraph says plainly that its own first draft had the bug.

The underlying claim was true. `git diff v2.0.0..v3.0.0 -- src/views_frames/io/`
is genuinely empty; arrow.py is byte-identical across the tags. The byte-parity
conclusion and the regenerated fixture stand.

**2. "The 3.0.0 MAJOR is confined to `views_frames_reconcile`" was overstated.**
The MAJOR also touches `views_frames/conformance/__init__.py`, which moves its
published `CONFORMANCE_FLOOR` from 2.0.0 to 3.0.0. Accurate claim, now written:
the *behavioural* change is confined to the reconcile package; the floor constant
also moves, and is inert here because nothing in this repo reads it
(`grep -rn CONFORMANCE_FLOOR` returns nothing). The non-import claim was correct
as written and is unchanged — `views_frames_reconcile` has no importer here.

Not rewriting history to fix this: 5c8a08a's message still quotes the bad
pathspec. Force-pushing is the operator's call in this repository, and the record
of the correction is more useful than a clean one.

Unchanged: 527 passed, 3 skipped, 41 xfailed, 0 failed on Python 3.11 with the
locked set; ruff clean; `poetry check --lock` clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ANY1CCy9Xo7zjMY4XJ69v9
/review-diff finding (Category D, duplication): the 3.0.0 rationale was stated in
full twice — once in the `pyproject.toml` pin comment and once in
`tests/fixtures/wire_contract/README.md`. Two copies of one explanation, which is
the shape this repo has been moving away from.

The fixture README is the right home and already says so: it carries the 1.10.2 and
2.0.0 byte measurements as a series and exists specifically so "the byte question is
not re-opened". So the pin comment now states the decision and its pin-specific
facts — the operational reason the cap had to go, the pipeline-core 3.4.0 coupling,
why the floors stay — and points at that file for the evidence, with the instruction
to read it before raising the pin again.

Drops the duplicated arrow.py / CONFORMANCE_FLOOR paragraph and the test counts from
`pyproject.toml`; both live in the README, dated, where a stale number is legible as
history rather than read as a current claim. 28 comment lines to 18.

No behaviour change; the constraint is untouched. Still 527 passed, 3 skipped,
41 xfailed, 0 failed on Python 3.11 with the locked set; ruff and
`poetry check --lock` clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ANY1CCy9Xo7zjMY4XJ69v9
@Polichinel
Polichinel merged commit 3801693 into development Nov 2, 2026
4 checks passed
@Polichinel
Polichinel deleted the chore/views-frames-cap-324 branch November 2, 2026 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant