Skip to content

Retry-harden Dockerfile release-asset fetches; project per-class texture templates in the OSM GL renderer - #126

Merged
AdaWorldAPI merged 4 commits into
mainfrom
claude/q2-osm-map-reencoding-56p5e2
Aug 12, 2026
Merged

AdaWorldAPI merged 4 commits into
mainfrom
claude/q2-osm-map-reencoding-56p5e2

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

What

Two pieces, same deploy arc:

1. Dockerfile: retry-harden the release-asset fetches (shipped in first commit)

A Railway deploy died in [builder 8/13] with curl: (56) Connection died, tried 5 times before giving up at 0 bytes received, fetching body.20260629c.v6helix.soa.gz from the fma-body-soa-v3-v1 release. The asset itself was verified intact minutes later (full 59 MB pull, HTTP 200, 63 MB/s from another host) — the failure was transient builder egress, and the build had no way to ride out a flake window measured in seconds.

Fix: one CURL_RETRY arg applied to all three release fetches (body, v6helix, berlin). --retry-all-errors is the load-bearing flag — plain --retry only classes timeouts/5xx as transient and does NOT retry exit 56, the error that actually occurred. --retry-max-time 120 bounds the total retry window; --connect-timeout 20 stops a black-holed connect from eating it.

2. OSM cockpit: per-class procedural texture templates (in progress on this branch)

The drawn vector basemap renders grey contours when every shape classes as Other (codebook sidecar not loaded — deploy-side, see below), and even fully classed it has only 2 procedural patterns (meadow stipple, wood canopy). Coming on this branch:

  • Fragment-shader material library in drawBaseGL: hash-noise-modulated per-class templates (water ripple, building tone, wood canopy blobs, green/meadow/park/built variants), projected in vWorld space so they ride the map. Colors stay sourced from CLASS_STYLE — the single place colors live.
  • Canvas2D fallback pattern table kept in the same visual vocabulary at lower fidelity.
  • Geometry row-budget lift: GEOMETRY_CITY_BUDGET (12k) / GEOMETRY_OVERVIEW_BUDGET (1.5k) are calibrated to the retired marker-DOM cost model; the GL path handles 30M+ tris (measured on /garmin/havel: 38.78M tris, 2 draw calls). City zooms move to a transport backstop, overview rises, Morton-prefix LOD dedup stays.

Deploy-side note (not fixed by code)

The live grey map is open_books() falling back silently: the .books codebook sidecar is absent next to OSM_SLAB_PATH (or from a foreign bake). .chains loaded fine (geometry renders), so the deploy needs the matching .books shipped alongside the slab. Without it every shape is ShapeClass::Other and no styling — old or new — applies.

Verification

  • Dockerfile change is build-infra only; no Rust code affected. Asset reachability + flag semantics verified by direct probe.
  • Texture/budget work: cargo build -p cockpit-server + cargo nextest run -p cockpit-server + headless-Chromium compile check of the exact GLSL source (details to follow as commits land).

Generated by Claude Code

…ress flakes

A Railway deploy died in [builder 8/13] with 'curl: (56) Connection died,
tried 5 times before giving up' at 0 bytes received, fetching
body.20260629c.v6helix.soa.gz from the fma-body-soa-v3-v1 release. The
asset itself was verified intact minutes later (full 59 MB pull, HTTP 200,
63 MB/s from another host) — the failure was transient builder egress, and
the build had no way to ride out a flake window measured in seconds.

Fix: one CURL_RETRY arg applied to all three release fetches (body,
v6helix, berlin). --retry-all-errors is the load-bearing flag: plain
--retry only classes timeouts/5xx as transient and does NOT retry exit 56,
the error that actually occurred. --retry-max-time 120 bounds the total
retry window; --connect-timeout 20 stops a black-holed connect from eating
that window.

Dockerfile-only change; no Rust code affected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NMeiLmtDKhomJNSo2ecbJw
@coderabbitai

coderabbitai Bot commented Aug 12, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The head commit changed during the review from 509393b to 4622594.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cursor

cursor Bot commented Aug 12, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_f6a98e81-9479-46c2-83b6-7f95e8b4a9b2)

claude added 2 commits August 12, 2026 19:31
… fetch

The deploy failed repeatedly at [builder 8/13] with
`curl: (56) Connection died, tried 5 times before giving up` at 0 bytes,
fetching body.20260629c.v6helix.soa.gz. Two independent defects, both fixed
here; neither is in the asset, which pulls intact from another host
(HTTP 200, 61,787,404 bytes, 63 MB/s).

1. CACHE ORDERING (the reason it kept re-rolling the dice). All three
   release fetches sat BELOW `COPY . /build/q2`. Docker invalidates from
   the changed layer onward and that COPY changes on EVERY commit, so every
   deploy — including doc-only ones — re-pulled ~180 MB. Moved above the
   COPY into one RUN keyed only on the URLs; a code-only commit now reuses
   the layer and downloads nothing. The placement into cockpit/dist/ stays
   below the COPY as a local file copy.

2. HTTP/2 CONNECTION DEATH. `Connection died, tried N times before giving
   up` is emitted by curl's HTTP/2 code path when the h2 connection dies
   mid-stream. `--http1.1` avoids that path. Retry flags are kept and
   corrected: plain `--retry` does NOT cover exit 56 (curl classes only
   timeouts/5xx as transient), so `--retry-all-errors` is what makes them
   apply to the error that actually occurred.

The fetch line itself dates to f9a3ad6 (2026-06-29) and is unchanged in
substance — same three URLs, same destinations, same same-origin/CORS
contract for /body, /helix and /geo.

Dockerfile-only; no Rust code affected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NMeiLmtDKhomJNSo2ecbJw
…try budgets

The drawn vector basemap is the map we own — nothing downloaded, no
attribution, no third-party tile server on a default load. This makes it
look like it. Same recipe the /garmin scenes already prove at scale:
material is COMPUTED, never fetched (havel measures 38.78M tris / 19.40M
verts in 2 draw calls with a procedural height palette).

TEXTURE TEMPLATES (drawBaseGL fragment shader). Two hand-written patterns
(meadow stipple, wood canopy) become a per-class library, projected in
vWorld space so every pattern rides the map instead of crawling under it:
water gets noise-warped ripple bands, building a coarse per-block tone so
a block field reads as masses rather than one slab, wood two-octave
canopy blobs (shadowed floor, lit crowns), green/park/built their own
tone, stripe and fleck reads. Discipline kept: colours come ONLY from
uFill/uStroke, so CLASS_STYLE stays the single place colours live and the
basemap and selection cannot drift; templates modulate, never introduce,
colour. Every frequency is an integer number of cycles per the 256-px
fold and the value-noise lattice wraps at the same period, so the fold is
seam-free with mediump-safe coordinates. The Canvas2D fallback gains
matching waves/stripes/speckle patterns — same vocabulary, lower fidelity.

GEOMETRY BUDGETS. GEOMETRY_CITY_BUDGET (12k) and GEOMETRY_OVERVIEW_BUDGET
(1.5k) inherited the DOM-marker cost model that OVERVIEW_ROW_BUDGET's own
history documents (177,963 retained nodes = the measured ceiling, 1.77M =
a hung page). The geometry wire has not rendered that way since the GL
port: shapes land in retained per-tile VBOs and draw as two GL calls per
tile. City zooms become complete (the CITY_ROW_CEILING transport backstop,
provably unreachable for a Berlin-class bake at 246,016 rows max);
overview keeps its Morton-cell LOD with 8x the room. The dot wire's
budget is untouched — dots are points, geometry is the map.

Verified: cargo check clean; cargo test -p cockpit-server 114 passed /
0 failed. The shader is only a string literal to rustc, so it was
compiled separately in a real headless-Chromium WebGL2 context, extracted
verbatim from osm.rs rather than retyped — program links, all uniforms
and attribs present. That check was confirmed falsifiable against two
mutants: a GLSL syntax error reports 'FAIL: fragment COMPILE: ERROR:
0:8', and a removed uniform reports 'MISSING UNIFORMS: uFill'.

Not verified: the live visual result, which needs the .books codebook
sidecar deployed next to OSM_SLAB_PATH. Without it every shape classes as
ShapeClass::Other and no styling applies — old or new.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NMeiLmtDKhomJNSo2ecbJw
@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review August 12, 2026 19:40
rustc writes rustc-ice-<timestamp>-<pid>.txt into the CWD when it crashes.
It is an artifact of the crash, never source, so it should never be
committed. One appeared here at 0 bytes — the crash was a full disk
(ENOSPC), which also defeated the dump write itself, so the file carried
no information at all.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NMeiLmtDKhomJNSo2ecbJw
@AdaWorldAPI
AdaWorldAPI merged commit 73ce105 into main Aug 12, 2026
2 checks passed
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.

2 participants