Skip to content

fix(codebase-memory): stop nginx mangling the CDN font URL (blank 3D node labels)#82

Merged
AlienWalker1995 merged 1 commit into
mainfrom
fix/cbm-ui-black-screen
Jul 10, 2026
Merged

fix(codebase-memory): stop nginx mangling the CDN font URL (blank 3D node labels)#82
AlienWalker1995 merged 1 commit into
mainfrom
fix/cbm-ui-black-screen

Conversation

@AlienWalker1995

Copy link
Copy Markdown
Owner

Symptom

Operator reports the codebase-memory 3D graph UII at /codebase-memory/ shows a black screen (page loads, graph area stays dark).

Diagnosis (read-only, live evidence)

Walked every layer of the running ordo-v2-codebase-memory-ui-1 (image rebuilt today by PR #75):

Layer Result
Process supervision nginx (pid 1, :9750) + codebase-memory binary (pid 12, 127.0.0.1:9749) both running; PR #75 auto-index wrapper intact
Shell HTML (nginx) 200, asset paths correctly rewritten to /codebase-memory/...
JS / CSS assets 200, correct content-type, 0 bare/unrewritten paths in the served bundle
/rpc, /api/* 200 (JSON-RPC + REST both answer)
Auth (oauth2-proxy) operator's real Firefox gets 202 (authorized) — a burst of ~12 authed subrequests confirms the browser loads all resources
Data auto-index (PR #75) done: 539,944 nodes / 554,184 edges, /api/layout returns real 3D coordinates
Edge (Caddyfile) /codebase-memory/* route unchanged & correct; obsidian PRs (#76–81) added /obsidian/ after it without touching it

No PR #75 regression, no CBM_VERSION bump, sub_filter matches the pinned v0.8.1 bundle.

Root cause found (in scope)

The nginx sub_filter rewrote every /font-files/ in the bundle to /codebase-memory/font-files/. But the v0.8.1 bundle has exactly one /font-files/ occurrence and it is always ${base}/font-files/${id}/... where base is the external unicode-font-resolver CDN (https://cdn.jsdelivr.net/gh/lojjic/[email protected]/packages/data). The rewrite corrupts that CDN URL →
.../packages/data/codebase-memory/font-files/latin/…woff404 on jsdelivr → every 3D node label fails to load. troika-three-text logs Failure loading font and skips the glyph (graceful — geometry still renders, labels blank).

The original design comments falsely assumed the UI serves /font-files/ from its own origin. It never does.

Fix

Remove both /font-files/ sub_filter rules (upstream fix, not a per-URL workaround — there is no legitimate origin-relative /font-files/ to rewrite for this bundle). Correct the stale "serves /font-files" claims in entrypoint.sh + README.md so declared behavior matches reality.

Acceptance (live, post-recreate)

  • Served bundle now emits V+"/font-files/" (un-mangled).
  • Headless render: font requests return 200 from <CDN>/font-files/latin/sans-serif.normal.{100,400}.woff; the previous Failure loading font error is gone; 0 console errors; graph loads 50k nodes.
  • assets/rpc/api still 200 through nginx; PR fix(codebase-memory): auto-index repo on startup #75 auto-index re-fires on start and re-populates 539,944 nodes / 554,184 edges after recreate.
  • No Python changed → ruff N/A; Caddyfile untouched.

Operator should now see: the 3D graph canvas with nodes, and — the substantive fix here — legible node labels (previously blank).

Honest scope caveat + shared-edge signal (for the parallel Obsidian agent)

The whole-canvas black could not be reproduced as a build-context cause: assets, rpc, api, auth (202), process supervision, and 539k-node data are all healthy. The residual black canvas observed in headless capture is a swiftshader software-GL artifact (this three.js renderer doesn't rasterize under swiftshader), not representative of the operator's real-GPU Firefox.

Shared-edge finding (diagnosis only — Caddyfile NOT edited): the /codebase-memory/* and /obsidian/* routes are independent handle blocks behind the same forward_auth; the obsidian PRs added /obsidian/ after @codebasememory without modifying it, and today's caddy reload only reconciled the /grafana/ drift + added the obsidian route. No shared edge change degrades /codebase-memory/* handling, headers, or route ordering. So the two black screens most likely do not share an edge-layer root cause — Obsidian's is in its own (selkies/websocket/GUI) scope, which the parallel agent owns.

🤖 Generated with Claude Code

…node labels)

The codebase-memory-ui nginx sub_filter rewrote every `/font-files/` occurrence
in the served SPA bundle to `/codebase-memory/font-files/`. But the pinned v0.8.1
bundle NEVER requests `/font-files/` from its own origin: the only occurrence is
`${base}/font-files/${id}/...` where `base` is the EXTERNAL unicode-font-resolver
CDN (https://cdn.jsdelivr.net/gh/lojjic/[email protected]/packages/data).

So the rewrite could only corrupt that CDN URL, producing
`.../packages/data/codebase-memory/font-files/latin/...woff` -> 404 on jsdelivr ->
every 3D graph node label silently failed to load (troika-three-text logs
"Failure loading font" and skips the glyph; the failure is non-fatal/graceful, so
the graph geometry still renders, but labels are blank).

Root cause: the two `/font-files/` sub_filter rules were based on the false premise
(carried in the original design comments) that the UI serves fonts from its own
origin. It does not. Removing the rules is the upstream fix — not a per-URL
workaround — because there is no legitimate origin-relative `/font-files/` request
to rewrite for this bundle.

Fix: drop both `/font-files/` sub_filter rules; document precisely why re-adding
them is wrong; correct the stale "serves /font-files" claims in entrypoint.sh and
README.md so the declared behavior matches reality.

Evidence (live, 2026-07-09):
- served bundle: single `"/font-files/` occurrence, always `V+"/font-files/"` where
  V = the jsdelivr CDN base (grep verified before/after).
- before: headless render logged
  `Failure loading font https://cdn.jsdelivr.net/.../packages/data/codebase-memory/font-files/latin/sans-serif.normal.100.woff`
- after recreate: the same font requests return `200` from `<CDN>/font-files/latin/
  sans-serif.normal.{100,400}.woff`; zero console errors; graph loads 50k nodes.
- assets/rpc/api still 200 through nginx; PR #75 auto-index still fires on start and
  re-populates 539,944 nodes / 554,184 edges after the recreate.

Scope note: this removes the one reproducible in-scope defect. The operator's
whole-canvas black screen could NOT be reproduced as a build-context cause (assets,
rpc, api, auth 202, process supervision, and 539k-node data all verified healthy);
the residual black canvas seen headlessly is a swiftshader software-GL artifact,
not representative of a real-GPU browser. See PR body for the shared-edge findings.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
@AlienWalker1995
AlienWalker1995 merged commit 8c8241d into main Jul 10, 2026
6 checks passed
@AlienWalker1995
AlienWalker1995 deleted the fix/cbm-ui-black-screen branch July 10, 2026 03:36
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