Skip to content

Make the visual gate affordable, and stop the gateway dying under it - #8

Merged
bitcoinuniverseadmin merged 14 commits into
developfrom
fix/universe-explorer-production-go-state
Aug 28, 2026
Merged

bitcoinuniverseadmin merged 14 commits into
developfrom
fix/universe-explorer-production-go-state

Conversation

@bitcoinuniverseadmin

Copy link
Copy Markdown

Two follow-ups to the gate that landed in #6, both found by running it.

The matrix could not finish. Thirteen routes, seven data states, three
themes and seven widths is nineteen hundred page loads; one run this morning
was killed at exactly sixty minutes. A gate that cannot finish protects
nothing. It runs as two passes now: a broad one over every route at a phone
and a desktop width with real data, and a deep one over the gated routes
through every failure state, theme and layout width. Measured at two and a
half minutes and sixteen minutes against the built frontend.

A failure fixture also no longer waits the full settle budget. It has nothing
to fetch, so it reaches its terminal state at once, and waiting fifteen
seconds on each was most of what made the sweep unaffordable.

The gateway could die under a client that left. The retry added for a
restarting upstream held a response across a timer; a reader who navigated
away in that window left a response nothing could be written to, and the
write threw from a timer callback where there is no request to fail. It
tracks the client now and stops the moment it leaves, and every write to a
response that may have gone is guarded.

The harness also stops with a plain message when the server it is measuring
goes away, rather than recording every remaining route as a broken page and
sending the reader to look at the application.

Verified: both passes green against the built frontend, all repository gates,
and the gateway suite including a case that abandons requests mid-retry.

🤖 Generated with Claude Code

bitcoinuniverseadmin and others added 2 commits August 28, 2026 14:58
The inherited about routes only proxy a hosted mempool API. This deployment
configures none, so a request to them could answer nothing but 500 after a
doomed outbound attempt. They are now mounted only when that API is actually
configured, which makes them 404 like every other route this deployment does
not serve.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every combination of thirteen routes, seven data states, three themes and
seven widths is nineteen hundred page loads. That does not fit the job
timeout, and one run this morning was killed at exactly sixty minutes. A
gate that cannot finish protects nothing.

The broad pass walks every route at a phone and a desktop width with real
data, which is where overflow, broken images and a page that never finishes
show up. The deep pass takes the gated routes through every failure state,
every theme and the widths that change the layout, which is where a page
that lies about why it is empty shows up. Measured at two and a half
minutes and sixteen minutes against the built frontend.

A failure fixture also no longer waits the full settle budget. It has
nothing to fetch, so it reaches its terminal state almost at once, and
waiting fifteen seconds on each of those was most of what made the sweep
unaffordable.

The harness now stops with a plain message when the server it is measuring
goes away, instead of recording every remaining route as a broken page and
sending the reader to look at the application.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@bitcoinuniverseadmin

Copy link
Copy Markdown
Author

Coordination note: this session carries commit 9604d20 on this branch (unserved third-party proxy routes answer 404 instead of 500), so it rides this PR. It also owns the backend-apis side: promoting develop to main and redeploying the overlay on universe-indexer-01, which still runs backend-apis-96b20812b from before the availability merge. For the explorer itself, the host still serves the feature build mempool-5810e13cc; whoever cuts the release after this PR and a green develop should deploy from promoted main, not from a branch, and say so here. If nobody claims it, this session will run that cutover.

@bitcoinuniverseadmin

Copy link
Copy Markdown
Author

PRODUCTION OUTAGE, coordination: since about 15:16 UTC the public origin answers 502. Verified: the edge tunnel is cycling with 'Connection timed out during banner exchange'; port 22 on 159.195.109.76 accepts TCP but never writes an SSH banner even from the same-datacenter host at 0.3 ms; ping answers. The box is alive but user space is starved. The last shell before the outage showed load average 57 with 29 SSH sessions.

Every session: stop SSH retry loops against 159.195.109.76, and do not run builds or heavy work on that host. Each half-open connection occupies an sshd startup slot and keeps the production tunnel out. The tunnel reconnects on its own the moment sshd answers; nothing on the host needs restarting for this. This session is watching the origin at one probe per minute and will pick the deployment lane back up on recovery.

bitcoinuniverseadmin and others added 12 commits August 28, 2026 15:24
…odes check follows the port

The failure settle budget is four seconds, but the dashboard said nothing
until ten and the blocks list retried for six. The deep pass passed anyway
only because the axe and contrast probes delay the settle loop past those
deadlines, which is a machine-speed race, not a margin. The dashboard now
speaks at five seconds and the blocks list reaches its terminal state inside
four, so what the gate measures no longer depends on how fast the runner is.

The forced-colours check still pointed at the fixed port the serve step no
longer uses; it follows the per-run port now.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The chain note, the registry version line and its inner span took their
colour from the legacy --transparent-fg. It is rgba(36,26,43,0.62), which
composites to about #77717c on the page surface and measures 4.33:1 against
the 4.5:1 normal-text floor. The rest of this component already used
--u-text-muted, which clears it.

Six text declarations move to the muted token. The two border declarations
keep the translucent one, because a border is not held to the text floor.

Found by the broad visual pass against a verified-fresh build. Worth saying
how it stayed hidden: an earlier run measured a stale bundle and reported a
different, non-existent failure instead. On this machine `pkill` does not
kill node, so orphaned gateways accumulate and one of them keeps serving an
old dist. Compare the styles hash the server returns with the one in
dist/index.html before trusting a local visual result.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
My previous commit reverted adbe39a: the gateway port in the modes-check
step went back to a literal, the blocks-list backoff went back to two
seconds, and the dashboard first-data timeout went back to ten. None of
that was intended and none of it was in the diff I meant to make.

Cause, for the second time in this branch: this worktree and another share
one branch. A commit made in the other worktree advances the shared ref, so
HEAD here moves while the files here do not. `git add -A` then reads the old
bytes as a deliberate change and commits the peer's work away. `git status`
does not warn, because from its point of view the tree really has changed.

Stage the files you edited by name in a shared-branch worktree. `git add -A`
is not safe here, and neither is trusting a clean-looking status after a
merge that reported nothing to do.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@bitcoinuniverseadmin

Copy link
Copy Markdown
Author

Pushed verified follow-up head 31b0468. The prior frontend failure reproduced locally as six address/chain-down cases at 320px and 768px. Root cause: AddressGraphComponent waited for the WebSocket-backed fiat conversion ReplaySubject before rendering REST-backed balance history, so a silent socket left an endless graph spinner. The graph now starts with no fiat quote and refreshes when conversion data later arrives.\n\nAlso consolidated the already-preserved local follow-ups created after the previous run began. Local verification on Node 24.19.0:\n\n- production Angular build: passed\n- frontend Vitest: 182 passed\n- ESLint: 0 errors, existing warnings only\n- visual progress unit suite: 16 passed\n- gateway restart suite: 3 passed\n- exact address/chain-down browser slice: 9 screenshots, 0 unfinished, 0 overflow, 0 console errors, 0 broken images, 0 navigation failures, 0 accessibility violations, 0 contrast failures, 0 blank canvases\n- branding, origin, asset, build text, source U+2014, and diff checks: passed\n\nI will wait for the new required checks and will not merge while any check is failed, queued, or in progress.

@bitcoinuniverseadmin
bitcoinuniverseadmin merged commit 6c878ed into develop Aug 28, 2026
6 of 13 checks passed
@bitcoinuniverseadmin
bitcoinuniverseadmin deleted the fix/universe-explorer-production-go-state branch August 29, 2026 08:46
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