rdmpw3265m changelog — App Index published, dev.ecs0.net root cause found
[2026-09-03 16:26:54 EDT · rdmpw3265m] · session start ~15:38 EDT, end 2026-09-03 16:26:54 EDT
1. Published https://eastcoastscience.net/apps — "App Index"
Rich: "I forget what a lot of names from older projects do."
The page answers that from measured state, not recall. 56
projects under rdmsm4x:~/dev/apps, one row each,
expanding on click, with a side rail filtering by last-worked-on, repo
age, status, build architecture, outstanding work, function tag and
language.
Collected on rdmsm4x, all measured:
- git lineage per project — first/last commit, author, branch, commit count, contributors, dirty files
- build system from Package.swift / Package.resolved / package.json / pyproject / Cargo / go.mod
- architecture from
lipo -archson every built product — 23 built, 17 Universal2, 6 arm64-only - libraries from resolved dependency pins, local
.package(path:)included - open tickets from each project's ISSUES.md — 191 open, 105 resolved
- GitHub repo state and open PRs via the API — 1 open PR (RTTy)
- icons: real
.icnswhere one exists (29), site product SVG otherwise (14), monogram where neither (13) - 85 function tags, hand-written from each project's own README/KICKOFF blurb
Shipped as part of the site build, not dropped into
dist/ — build.js does
fs.rmSync(DIST_DIR), so a dist-only page would have
vanished on the next build. New files
src/templates/apps.html +
src/data/apps_inventory.json; scripts/build.js
gained section 10; layout.html gained the nav link. Build
went 27 → 28 pages.
Commit 5b80161, pushed to fleet and
backup (all three refs identical). Deployed via
wrangler pages deploy. Theme: inherits the
site's design tokens, so the existing header control drives System /
Light / Dark with no palette of its own.
Two silent-wrongness defects found and fixed while building it
- GitHub column came back empty for all 56. The
collector read
~/dev/FLEET-PROJECT-POINTERS.md, which does not exist at~/devon rdmsm4x (it lives at~/dev/fleet/ops/git/). Zero was read as "no repos" rather than "lookup broken". Now reads each repo's own git remotes — ground truth — 56/56 resolved. - ISSUES.md matcher accepted a bare
OPENline, so continuation lines inside paragraphs counted as tickets. Tightened to require a real item marker. Verified in both directions: exactly 5 projects lose exactly 1 phantom each (196 → 191); no project lost a real ticket.
Verification (against reality, not the build log)
node --check on build.js; build emits 28 pages; the
embedded inventory JSON parses back to 56 apps; rendered in Chrome
light and dark, zero console errors; facet /
combined-facet / search / reset paths all return expected sets (e.g.
Credentials ∩ Universal2 = 3, correctly dropping the unbuilt
PasswordScope). Trap hit and caught: the first browser
check showed a stale page — Chrome had cached it; curl
proved the file on disk was current. A screenshot is not proof the bytes
are fresh.
Live check note:
curl https://eastcoastscience.net/apps returns HTTP
200 — but that is the Cloudflare Access sign-in page, not the
page. Verified instead through an Access-authenticated browser:
56 apps, 56 rows, correct build stamp. HTTP 200 was the wrong
measurement.
2. dev.ecs0.net — root cause found, PR #4 filed for agy
Rich reported it "still broken/not loading". It is not an outage.
Origin is healthy:
curl -H 'Host: dev.ecs0.net' http://127.0.0.1:8788/ returns
200 for /, /index.html, /issues/;
port 8788 open; gateway, wiki and tunnel containers all up 17h. The
public 302 to Cloudflare Access is the documented masker, not the
fault.
Actual fault: the shell renders and every content
pane is blank because the page's single inline
<script> does not compile —
SyntaxError: Invalid or unexpected token at
:702:222663. At that offset the script holds a JSON string
containing a harvested HTML document with a literal, unescaped
</script>. The HTML parser ends the script
there, leaving an unterminated string literal; the router never
starts.
Cause: scripts/build_site.py:571-575
interpolates seven json.dumps() blobs straight into inline
<script> tags. json.dumps escapes for
JSON, not for HTML script context. Fix given:
json.dumps(obj).replace("</", "<\\/") behind one
helper. Carried by the agy doc
agy/hss-network-070326-…-docs.html; any ingested external
HTML can do the same.
PR #4 on richhdoty/dev-ecs0-net adds
the dated ISSUES.md entry only — no generator change, left for agy per
Rich. The PR states the both-directions check: a fix
that drops or truncates the offending record clears the error by
deleting content, which is worse than the bug.
Same defect class was pre-empted in the App Index build the same
day — build.js injects its inventory with a function
replacement and .replace(/<\//g, '<\\/').
Files changed
rdmsm4x:~/dev/sites/eastcoastscience.net/— commit5b80161(src/templates/apps.html, src/data/apps_inventory.json, scripts/build.js, src/templates/layout.html, dist/)rdmsm4x:~/dev/sites/dev.ecs0.net/— branchfix/blank-content-panes-20260903, commit18a8262(ISSUES.md only); tree returned tomain