Stop committing 80.7 MB of generated mirrors of data/

public/assets/<name> is not a source. generate-tree.mjs:1353 rmSync's it and
copies data/<name> over it on EVERY `bun run tree`, so five directories were a
byte-identical copy of a tracked source and BOTH copies were committed:

  posters        378 files  40.9 MB
  people-groups    2 files  23.0 MB
  tables          19 files  14.2 MB
  legacy           4 files   2.0 MB
  vendor           3 files   0.6 MB

Verified identical, not assumed: same file set and matching hashes in all five.
And proven regenerable rather than argued — deleting public/assets/posters and
running `bun run tree` restored all 378 files with laos.webp md5 ea65d2f1, the
same hash the committed copy carried.

This is the Driver's "80mb of images in a public folder" almost exactly, and it
is the cheapest possible version of it: a publish was already rejected once at a
74 MB asset tree, and half that weight was a duplicate of something already in
the same repo. No feature changes, no size tradeoff, nothing regenerates
differently.

★ previews/ IS DELIBERATELY STILL TRACKED. It has no data/ source — make-previews.py
derives it from the full posters — and it is what the poster WALL renders from.
bundlePosters defaults false, so a dropped folder ships previews and NOT posters;
untracking previews would blank every wall. Treating "public/assets" as one
homogeneous pile would have removed the one directory that must stay.

The root .gitignore said "what actually ships is the exported subset in
public/assets/ (see export-public.mjs)" and BOTH HALVES were stale — which is why
the duplication looked intentional. export-public.mjs writes a SIBLING OF THE REPO
(../../../../upg-100-posters or $DOXA_PUBLIC), stating in its own header that this
is "NOT inside public/, because capacitor packages public/ whole"; and
public/assets/ is now generate-tree's mirror of data/. Comment corrected in the
same change, because a stale rationale is what restores a deleted duplicate.

Build green with the mirrors untracked: 7/7 pre, 23/23 bundles, 21/21 post.
This commit is contained in:
doxa-maps-88655c70 2026-09-24 07:35:21 +00:00
parent 2392fe0319
commit d06bf88195
408 changed files with 45 additions and 483104 deletions

17
.gitignore vendored
View file

@ -115,5 +115,18 @@ _qa-cycle/
# ── GENERATOR OUTPUT — regenerable render artifacts, never committed ──────────
# internal/<tool>/out/ holds what the poster/research generators RENDER
# (upg100-posters/out alone is ~619MB / 12,623 PNGs). The generators themselves
# are source and ARE committed; their output is derived. What actually ships is
# the exported subset in public/assets/ (see export-public.mjs).
# are source and ARE committed; their output is derived.
#
# ⚠ THIS BLOCK USED TO SAY "what actually ships is the exported subset in
# public/assets/ (see export-public.mjs)". BOTH HALVES OF THAT WERE STALE, and
# the sentence is why 80.7 MB sat committed twice:
# - export-public.mjs does NOT write public/assets/. It writes a SIBLING OF THE
# REPO (../../../../upg-100-posters, or $DOXA_PUBLIC), and says so in its own
# header — explicitly "NOT inside public/, because capacitor packages public/
# whole and these are 52 MB that must not ship in the APK".
# - public/assets/<name> is now a GENERATED MIRROR of the tracked data/<name>,
# rewritten by generate-tree.mjs on every `bun run tree`. It is derived, not
# exported, so it is ignored in public/.gitignore — which carries the
# measurements and the one exception (previews/, which has no data/ source
# and must stay tracked).
# The tracked source for shipped assets is data/<name>.

30
public/.gitignore vendored
View file

@ -6,3 +6,33 @@ token.local.js
# MACHINE'S USERNAME into the repo. Nothing reads it but the lock itself, and a
# clone that inherits a stale pid is at best noise.
.build.lock
# ── GENERATED MIRRORS OF data/ — 80.7 MB committed TWICE ─────────────────────
# generate-tree.mjs:1353 copies data/<name> -> public/assets/<name>, rmSync'ing
# the destination first, on EVERY `bun run tree`. So these five directories are
# not a source: they are a byte-identical copy of a tracked source, and both
# copies were committed.
#
# MEASURED 2026-09-24, all five verified identical file-set and hash:
# posters 378 files 40.9 MB
# people-groups 2 files 23.0 MB
# tables 19 files 14.2 MB
# legacy 4 files 2.0 MB
# vendor 3 files 0.6 MB
# Proven regenerable, not assumed: deleting public/assets/posters and running
# `bun run tree` restored all 378 files with laos.webp md5 ea65d2f1 — the same
# hash the committed copy had.
#
# This is the "80mb of images in a public folder" directly: a publish was already
# rejected once at a 74 MB asset tree, and half of that weight was a duplicate of
# something already in the same repo.
#
# ⚠ previews/ IS NOT LISTED AND MUST STAY TRACKED. It has no data/ source — it is
# generated by make-previews.py from the full posters — and it is what the poster
# WALL renders from, so a dropped folder needs it (bundlePosters defaults false,
# which ships previews and not posters). Untracking it would blank every wall.
/assets/posters/
/assets/people-groups/
/assets/tables/
/assets/legacy/
/assets/vendor/

View file

@ -1,75 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>legacy map host</title>
<style>html,body{margin:0;height:100%;background:#f3f3f1}.host{position:fixed;inset:0}</style>
</head>
<body>
<div class="host" id="host"></div>
<script>
// Sandboxed host for the LEGACY upg-neighbor IIFE (pre-bundler architecture). This page runs
// inside an IFRAME so the old engine and its dependencies cannot collide with the modern
// bundles -- the isolation pattern the roundup mandates ("add without breaking doxa-maps").
var q = new URLSearchParams(location.search);
var el = (q.get('el') || 'send-map').replace(/[^a-z0-9-]/g, '');
var tk = q.get('tk') || '';
// Token globals the legacy build may read.
window.MAPBOX_TOKEN = tk; window.MAP_TOKEN = tk; window.UPG_TOKEN = tk;
// The legacy code fetches relative "/api/people-groups/..." which only resolved on its old
// origin. Shim fetch so those calls reach the live API from ANY host (static tree, iframe).
var API = 'https://pray.doxa.life';
// The cockpit profile fails closed without a configured API base and names this global in
// its own error banner (measured: "No API base configured (apiBase / window.MAP_APP_API_URL
// / VITE_API_BASE_URL) -- failing closed").
window.MAP_APP_API_URL = API;
var origFetch = window.fetch.bind(window);
window.fetch = function (input, init) {
try {
var url = typeof input === 'string' ? input : (input && input.url) || '';
if (url.indexOf('/api/') === 0) return origFetch(API + url, init);
} catch (e) { /* fall through */ }
return origFetch(input, init);
};
// ── KEYLESS SHIM ──────────────────────────────────────────────────────────
// The legacy bundle expects a mapboxgl GLOBAL and requests mapbox://styles/mapbox/light-v11.
// MapLibre is API-compatible with the mapbox-gl v1 surface the bundle uses, and OpenFreeMap
// Positron is the keyless twin of light-v11 -- so the shim below makes every legacy map run
// WITHOUT a Mapbox token: load our self-hosted MapLibre, alias it as mapboxgl, and rewrite
// any mapbox:// style to the keyless URL inside a patched Map constructor.
var KEYLESS_STYLE = 'https://tiles.openfreemap.org/styles/positron';
var lib = document.createElement('link'); lib.rel='stylesheet'; lib.href='./maplibre-gl.css';
document.head.appendChild(lib);
var ml = document.createElement('script');
ml.src = './maplibre-gl.js';
ml.onload = function () {
var Real = window.maplibregl.Map;
function PatchedMap (opts) {
if (opts && typeof opts.style === 'string' && opts.style.indexOf('mapbox://') === 0) opts.style = KEYLESS_STYLE;
return new Real(opts);
}
PatchedMap.prototype = Real.prototype;
window.mapboxgl = Object.assign({}, window.maplibregl, { Map: PatchedMap, accessToken: '' });
loadLegacy();
};
ml.onerror = function () { loadLegacy(); };
document.head.appendChild(ml);
function loadLegacy () {
var s = document.createElement('script');
s.src = './upg-neighbor.iife.js';
s.onload = function () {
var node = document.createElement(el);
node.style.cssText = 'display:block;width:100%;height:100%';
// The legacy elements use the SAME profile-config attribute contract as the modern
// bundles (measured: without it the element renders its own usage banner).
node.setAttribute('profile-config', JSON.stringify({ profile: el, tk: tk }));
document.getElementById('host').appendChild(node);
};
s.onerror = function () { document.body.innerHTML = '<p style="font:14px system-ui;padding:20px">legacy bundle failed to load</p>'; };
document.head.appendChild(s);
}
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

Some files were not shown because too many files have changed in this diff Show more