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
38 changes: 38 additions & 0 deletions reports/register_changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,44 @@ difference between it and everything else in this cluster.

---

## v1.12.0 deployed — three concerns get evidence, one of them uncomfortable (2026-08-13)

The release reached the server, and the redeploy was run as **all three** `server_quickref.md` steps
rather than the tag file alone — which is C-343's entire content.

**C-331 was already resolved; today it became true in production.** #423 fixed the heartbeat URL and
drilled it with a canary. But a fix merged is not a fix running: the deployed tag still carried the
old form until this release. Both halves were checked on the host — all three sites read
`printf 'url = "%s"' … | curl -K -`, and then `curl -K -` was *executed* on the box. That second
check is the one that mattered: every ping is guarded by `|| true`, so a form this machine's curl
rejected would have silenced the dead-man switch while looking identical to a working one. This is
the C-322/C-324 distinction — fixed-in-code and fixed-in-production are different claims — applied
before anyone had to learn it again.

**C-348 was measured and stays open, which is the honest disposition.** The host runs Python
**3.12.3**, resolving `tifffile 2026.5.15` / `imagecodecs 2026.5.10` — the current fork, the one
`test-py313` covers. Production has been on the right side of the floor all along.

Read the reason rather than the result: 3.12.3 is Ubuntu 24.04's system interpreter, and the guide
in force said *"Install Python 3.10+"*. **The server is correct by distro accident, not by
decision** — which is precisely what the entry says, so measuring it does not close it. One
observation is not an assertion, and the next reprovision on a distro shipping 3.11 would silently
install the March-2026 decoder.

**C-343's instance was clean before we touched anything** — tag file, HEAD and environment all said
v1.11.0. On 2026-08-08 those three disagreed for five days. The instance is remediated; the concern
is not, because #434 (the pre-flight that would *prevent* recurrence) was closed unstarted with
epic #421. Worth stating plainly rather than letting a clean reading imply a fix.

**C-347's trigger fired and was actioned.** `test-py313` reported green on `development` and on
`main` — the precondition — and was then added to the required-status-check lists on both, with the
result read back rather than assumed. That readback discipline is C-340's, and it is now applied to
branch protection as well as to merge methods. This changelog entry's own pull request is the first
to pass through the new required check, which is the only way to find out that requiring it does not
deadlock every merge.

---

## The Python floor, and a refutation that expired (2026-08-13)

`#443` lowered `requires-python` from `>=3.12` to `>=3.11`. Two entries registered: **C-347**
Expand Down
10 changes: 6 additions & 4 deletions reports/technical_risk_register.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Technical Risk Register

**Date:** 2026-03-17 (updated 2026-07-27)
**Last update:** 2026-08-13 — the Python floor dropped to `>=3.11` (#443/#444), registering C-347 (the required CI check decodes with a different codec build than the server), C-348 (nothing asserts the server's interpreter) and C-349 (a config value restated in prose has nothing binding it back). Full narrative history, including corrections and retractions, is in [`register_changelog.md`](register_changelog.md). Keep this line to one sentence: the header is an index, and the search-window guard (`test_falsification_merge_readiness.py`, 8000 chars) is what it protects. New narrative goes in the changelog, never here (#404).
**Last update:** 2026-08-13 — v1.12.0 released and deployed: the Python floor is `>=3.11` on PyPI, C-331 is now exercised on the host rather than only merged, C-347's trigger fired and `test-py313` is a required check on both branches, and C-348 was measured (the server runs 3.12.3, correct by distro accident) but stays open. Full narrative history, including corrections and retractions, is in [`register_changelog.md`](register_changelog.md). Keep this line to one sentence: the header is an index, and the search-window guard (`test_falsification_merge_readiness.py`, 8000 chars) is what it protects. New narrative goes in the changelog, never here (#404).
**Source:** 71 audits, reviews, and incidents — multi-expert engineering review, repo assimilation, falsification audits, test reviews, security sweeps, and production incidents. Full list in [`register_changelog.md`](register_changelog.md#where-the-findings-came-from). Add new sources there, not here (#404).
**Status:** 349 concern IDs assigned (C-28 merged into C-31, C-107 merged into C-60, C-183 merged into C-44, C-44 merged into C-164, C-03 merged into C-176): 304 resolved-or-demoted, 42 open concerns (0 Tier 1, 4 Tier 2, 12 Tier 3, 20 Tier 4, 6 deferred by design; 4 with fired trigger); 5 demoted to tech-debt backlog 2026-08-04, 8 open disagreements. 167 resolved concerns as full entries + 19 early-archive reference rows + 120 struck-through in active register (299 unique after dedup — 5 appear in both archive and active) + 32 resolved disagreements in archive. 42 disagreement IDs total: 34 resolved, 8 open.
**Archive:** Resolved concerns and disagreements are in `archive/technical_risk_register_resolved.md`.
Expand Down Expand Up @@ -164,7 +164,7 @@
| C-346 | 4 | Four copies of `test_version_not_already_tagged` use a conditional `xfail` that reads as rigorous and is circular — the test runs only when the version is untagged, then asserts it is untagged. Measured green in every reachable state | **Before trusting any `xfail`-marked test as a gate**: name the state that makes it fail. If none does, it is decoration | Test infra |
| C-345 | 2 | Verification tooling reported a green suite that was red, twice in one session — a piped `pytest \| tail; echo $?` yields the pipe's status, and a task notification reported "exit code 0" for a run that exited 1 | **When capturing a long-running check's result** — piping it, backgrounding it, or reading a notification instead of an unpiped `$?`. Redirect to a file, capture `$?` unpiped, and grep `^FAILED` as a second reader | Test infra |
| ~~C-344~~ | ~~2~~ | ~~`views-deploy`'s `~/.profile` was mode 644 inside a 751 home — every harvest credential (`UCDP_API_TOKEN`, `ACLED_*`, `GDL_API_TOKEN`, `HEARTBEAT_URL`) readable by all four accounts, continuously~~ | Registered and resolved 2026-08-10 (#432): `chmod 600`, verified unreadable from a second account and still readable by the owner. Rotation considered and **declined** by the operator 2026-08-10 — a judgement about who holds the three accounts, not evidence of non-access; revisit if a new shell account appears (C-88) | Credential hygiene |
| ~~C-331~~ | ~~4~~ | ~~`HEARTBEAT_URL` capability URL passed on the curl command line — readable via `/proc`~~ | Resolved 2026-08-10 (#423): all three pings take the URL on stdin via `-K -`; drilled with a canary and a negative control. The entry's own suggested unquoted form was superseded — it truncates at whitespace and sends anyway | Operational monitoring |
| ~~C-331~~ | ~~4~~ | ~~`HEARTBEAT_URL` capability URL passed on the curl command line — readable via `/proc`~~ | Resolved 2026-08-10 (#423): all three pings take the URL on stdin via `-K -`; drilled with a canary and a negative control. The entry's own suggested unquoted form was superseded — it truncates at whitespace and sends anyway. **Deployed and exercised on the host 2026-08-13** with v1.12.0: all three sites verified in the checked-out script, and `curl -K -` itself run on the box — a deployed-but-rejected form would have silenced every ping behind `|| true`, so shipping the fix and running it are different claims (C-322/C-324) | Operational monitoring |
| C-332 | 3 | Credential redaction incomplete — `_redact_url` ignores URL userinfo, `zarr_path` interpolated raw into 7 messages, netrc exceptions log contents, `BasicAuth`/`_TokenState` reprs | **Before interpolating any URL, path, or credential-bearing value into a log line or exception message** — that is the act that creates the exposure, not editing these files | Credential hygiene |
| C-334 | 3 | Removing a runtime dependency from a published library breaks dependents relying on it transitively — caught pre-release (matplotlib/views-hydranet) | **Before removing any runtime dependency**, grep sibling repos for module-level imports; "nothing under src/ imports it" is not sufficient evidence | Dependency policy |
| ~~C-335~~ | ~~2~~ | ~~Nothing watches the data-serving path — green while every consumer gets nothing~~ | Resolved 2026-08-03: Better Stack monitor live and verified (Up, ~27ms, test alert delivered) + serving-freshness.yml for the content half | Operational monitoring |
Expand All @@ -176,8 +176,8 @@
| ~~C-341~~ | ~~4~~ | ~~Deploy gates only run where someone types pytest — C-320's fix made them skip-with-reason in CI, so they assure only whoever runs the suite at the right moment | **When adding a deploy gate, or relying on one for release assurance:** ~~ | Resolved 2026-08-11 (#424 gave the answerable gates a scheduled runner; #425 deleted the one that could never answer and replaced it with a publish-time guard) | Test infra |
| ~~C-342~~ | ~~3~~ | ~~A stale committed `uv.lock` is invisible — `uv sync` (ci.yml:24,42,60,99) rewrites it in place, so CI goes green on a lock that does not match the committed `pyproject.toml` and the stale one stays in git~~ | Resolved 2026-08-11 (#424): `uv lock --check` in the `test` job, before `uv sync`; drilled both directions and the ordering is itself guarded by `tests/test_ci_gates.py` | Dependency policy |
| C-343 | 2 | Writing `~/.views-deploy-tag` is not deploying — the server ran v1.10.0 for five days while the tag file said v1.11.0 and views-frames stayed at the frozen 1.0.0. The in-script `git checkout` cannot fix the running script (bash has buffered it) and never runs `uv sync` | **At the next release** — deploy with all three `server_quickref.md` steps, then verify tag file, `git describe --tags` and installed version all agree | Deployment |
| C-347 | 3 | The required CI check exercises a different raster decoder than production — since the 3.11 floor the lock forks, so `test` decodes with `imagecodecs 2026.3.6` while the server uses `2026.5.10`. `test-py313` covers the production line but is **not a required check**, and a red nobody must satisfy is ignorable | **Before the next release tag, and whenever `tifffile` or `imagecodecs` moves in either fork** — confirm `test-py313` is green, and whether it has been added to the required lists on `main` and `development`. Resolved when it is required on both | Test infra |
| C-348 | 3 | Nothing asserts which Python the production server runs, and the floor now admits one that installs a **different raster line**. `preflight.py`, `check_health.py` and `refresh_pipeline.sh` contain no `sys.version_info` check of any kind. Created by #443 — this risk did not exist under `>=3.12` | **At the next server provisioning, Python upgrade on the Hetzner host, or any runbook edit that says `apt install python3`** — pin the interpreter explicitly and record which raster fork it resolves | Server hardening |
| C-347 | 3 | The required CI check exercises a different raster decoder than production — since the 3.11 floor the lock forks, so `test` decodes with `imagecodecs 2026.3.6` while the server uses `2026.5.10`. `test-py313` covers the production line but is **not a required check**, and a red nobody must satisfy is ignorable | **Fired and actioned 2026-08-13.** `test-py313` reported green on `development` and on `main`, and was then added to the required-status-check lists on both (readback verified). Re-opens if the job is renamed or the requirement dropped | Test infra |
| C-348 | 3 | Nothing asserts which Python the production server runs, and the floor now admits one that installs a **different raster line**. `preflight.py`, `check_health.py` and `refresh_pipeline.sh` contain no `sys.version_info` check of any kind. Created by #443 — this risk did not exist under `>=3.12`. **Measured 2026-08-13: the host runs Python 3.12.3 (Ubuntu 24.04's system interpreter), so it resolves `tifffile 2026.5.15` / `imagecodecs 2026.5.10` — the current fork.** Reassuring, and it is an accident: the guide said "Install Python 3.10+" and this distro happened to hand it 3.12. Still OPEN because one observation is not an assertion | **At the next server provisioning, Python upgrade on the Hetzner host, or any runbook edit that says `apt install python3`** — pin the interpreter explicitly and record which raster fork it resolves | Server hardening |
| C-349 | 4 | A config value restated in prose has nothing binding it back — `hetzner_deployment_guide.md` said "Install Python 3.10+" for the three months `pyproject.toml` declared `>=3.12`, an instruction producing an environment where the package could not install. The #444 pin guard binds *workflow* pins to `requires-python`; nothing binds *prose* | **When writing a Python version, or any pyproject value, into a guide or ADR** — link to the declaration instead of restating it, or accept that the copy will not be checked | Documentation drift |
| C-333 | 4 | UCDP's custom auth header survives a cross-host redirect (`requests` strips only `Authorization`) — credential egress, not log leakage | **Before the next harvester auth review**, or if UCDP announces a host or redirect change — whichever is first | Credential hygiene |
| ~~C-303~~ | ~~4~~ | ~~ADR-049 §Validation mandates 3 provenance counters; builder logs only 1~~ | Resolved 2026-06-28 (added `n_excluded_where_prec` and `n_passthrough_where_prec` to builder ledger entry) | ADR-049 provenance |
Expand Down Expand Up @@ -3279,6 +3279,8 @@ Cross-ref: C-348 (the server-side half of the same question), C-320 (a check tha

The deployment guide made this concrete: it said *"Install Python 3.10+"* for the three months the project declared `>=3.12` — an instruction that produced an uninstallable environment, and nothing noticed, because the guide and `pyproject.toml` were each internally consistent and never compared. Fixed in #443 by naming an explicit interpreter.

**Measured, 2026-08-13, during the v1.12.0 redeploy.** `.venv/bin/python` on the host reports **3.12.3**, with `tifffile 2026.5.15` and `imagecodecs 2026.5.10` — the current fork, the same one `test-py313` covers. So production has been on the right side of the floor throughout. Read the *reason* rather than the result: 3.12.3 is Ubuntu 24.04's system Python, and the guide in force said "Install Python 3.10+". The box is correct by distro accident, not by decision, which is the whole content of this entry. **Not resolved:** an observation on one day is not an assertion, and the next reprovision on a distro shipping 3.11 would silently install the March-2026 decoder.

**Tier 3, not 2.** No evidence of a wrong number today, and the two codec lines are two months apart on a mature library rather than a semantic rewrite. But it is a silent, unrecorded determinant of production numeric output, which is why it is not Tier 4.

**Note for whoever closes this.** If it becomes a check, it must **skip with a reason** when run off-server rather than pass trivially (C-320). A test that quietly passes everywhere except the one machine it is about would be a new instance of the class it is meant to close.
Expand Down
Loading