Skip to content

Promote develop to main: Universe Explorer release - #2

Merged
bitcoinuniverseadmin merged 17 commits into
mainfrom
develop
Aug 26, 2026
Merged

bitcoinuniverseadmin merged 17 commits into
mainfrom
develop

Conversation

@bitcoinuniverseadmin

Copy link
Copy Markdown

Promotes develop to main so the release branch matches what is deployed at
explorer.bitcoinuniverse.io.

Deployed commit: 67e968b0b, reported by /api/v1/backend-info and by the
public /source page.

Universe CI passed on that commit: frontend build, backend build and test, and
the documentation, branding, origin, text, and gateway routing gates.

Full change summary and the known limitation are in #1.

bitcoinuniverseadmin and others added 17 commits August 26, 2026 19:41
Four discovery passes across mempool explorers, protocol explorers, live
visualizers, privacy explorers, alerting products, and agent data interfaces.
The last two passes surfaced new product names but no new competitor category,
capability class, user expectation, or trend, which is the closure condition
recorded in market-lessons.md.

Adds the deliverables that make the research accountable: the lessons that
each produced a specific build decision, the patterns deliberately rejected
and why, an emerging-trends brief, a user jobs and pain-point synthesis, a
claim-to-source ledger, and the experience brief that turns all of it into one
sentence the implementation can be measured against.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The explorer could already prove what one transaction did. This adds the
surfaces that make that useful.

Universal search classifies outpoints, inscription ids and numbers, rune names
and ids, satoshis, and protocol names entirely in the browser, so a query never
leaves the device to be understood. Base Bitcoin identifiers still belong to
the upstream matcher, and a bare integer is still a block height: nothing here
steals the most common search in the product.

New pages: an output is addressable at /outpoint/:txid/:vout, because an output
is the unit that actually carries protocol assets; /inscription, /rune, and
/sat resolve through the overlay's asset lookups; /protocols/:id explains a
protocol, its authority, and what is not shown about it and why; /pulse
publishes live protocol activity with the denominator it was measured against;
/saved is everything this browser remembers, with one button that erases it.

The transaction page now opens with a sentence a non-expert can act on, built
only from actions the authority reported and worded so it never implies a
trade. Block and address pages gained protocol panels that state their own
coverage rather than implying completeness.

Personalization is local storage only: recent items, saved pages, pinned
protocols. No account, no server-side list, no profile.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three checks that make rules enforceable instead of remembered, each runnable
over the source tree and over a built bundle, because an unreachable lazy chunk
still ships.

The branding gate bans the upstream product marks outside a path allowlist that
records why each exemption exists, plus two attribution sentences that are
permitted anywhere because publishing them is the point of them. The origin
gate bans hosted blockchain APIs, public explorers, analytics, and asset CDNs,
matching on host boundaries so a filename like btc.component.html is not read as
a host and a specification citation is not read as a data source. The text gate
bans U+2014.

All three run in CI, and the frontend job runs the first two again against
frontend/dist after the production build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ty origins

The fork keeps the upstream code and the upstream licence. It does not keep the
upstream product identity, and until now it still shipped it.

Deleted, because they exist only to present the upstream product: the about and
trademark policy pages, the acceleration checkout, the upstream Lightning node
group page, the sponsor index variants, and the upstream node fleet scripts.
Rewritten as this deployment's own documents: the privacy and terms pages, and
the API documentation.

Two runtime behaviours mattered more than the copy. The hosted analytics path is
now a documented no-op, so no tracker loads on any hostname. The enterprise
service no longer redirects an unknown subdomain to a third-party site, and no
hostname is treated as an enterprise subdomain. Cross-network links, the
services API, the Electrum failover Host header, and the sample and proxy
configuration all point at this deployment or are unset, and the build no longer
rewrites asset downloads to a hosted mirror.

The Goggles trademark is gone from identifiers as well as from copy, so it does
not survive minification. The remaining upstream references are the ones the
licence requires: the preserved notices, the fork provenance record, and two
attribution sentences.

The 33 upstream translation catalogues still carry upstream copy. They are not
built: the production script omits localization, so only the English build
ships. Re-enabling locales means regenerating them from the rebranded sources.

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

The deployment document described an intended stack. This records the one that
exists: the public origin, the forward-only tunnel restricted to a single
destination port, the gateway, and the three units behind it, with the ports
each listens on and the user each runs as.

It also records two decisions honestly rather than silently. The database is
disabled, because it only powers historical indexing and mining statistics
while the live explorer and the whole protocol layer work without it, and the
host it runs on is also rebuilding an index. Asset synchronization and
localization are omitted from the production build, so nothing is fetched from
a third party at build time.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The text gates could not see these: 24 upstream logo, sponsor, promo, and
screenshot assets were still being copied into every build, along with the
preview cards eight pages set as their own og:image. Those cards carry upstream
trade dress, so pages now fall back to the Universe card defined once in the
page head. The accelerated-transaction badge uses an icon from the bundled set
instead of the upstream sparkles mark.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Angular asset entry for src/resources is inert; the upstream build relies on
the sync-assets step to copy it. The Universe build skipped that step to avoid
downloading anything from a third party, and lost the resources directory with
it, including the file that carries the release commit hash. It now copies the
directory and still downloads nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ng up

Two things the first deployment made obvious.

The backend bound every interface, so the API answered on the host's public
address as well as the one the gateway uses. It now takes MEMPOOL.HTTP_HOST and
defaults to loopback; a deployment that wants a wider bind has to ask for it.
The docker template keeps the previous behaviour so a container still works.

More importantly, the node this explorer reads can be behind the chain that
exists, and until now the explorer would have presented its tip as the present
without comment. That is the one failure this whole product is built to avoid.
The backend now publishes the node's own sync state on /api/v1/backend-info,
and a notice at the top of every page states how far behind the data is and by
how many blocks. Ordinary propagation lag stays quiet; a node in initial block
download does not.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The explorer backend registers every route under its own /api/v1/ prefix, while
the frontend and the Esplora-compatible surface address them as /api/. Upstream
resolves that in nginx. The gateway did not, so the whole chain API returned 404
while the site itself loaded perfectly, which is precisely the kind of failure
that survives a smoke test.

Rewritten, tested, and the routing table is now covered directly: overlay paths
pass through, explicit v1 paths pass through, unprefixed paths are rewritten
with the query string intact, and anything outside the API tree is left for the
static handler. WebSocket upgrades go to the backend unchanged, because its
socket server attaches to the whole HTTP server rather than to one path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The guard compared process.argv[1] against the module's own resolved path so a
test could import the routing table without opening a socket. The release
directory is reached through a symlink, so those two paths never match there:
the gateway started, decided it was being imported, and exited cleanly. A clean
exit with no error is the worst possible way for a service to fail.

Listening is now the default and a test opts out with an environment flag.

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

Found by auditing the deployed site rather than the source.

Eight navigation links and the search submit button were icon only with no
accessible name, so a screen reader announced them as bare links and buttons.
Each now carries a name and a tooltip. Target spacing was measured at the same
time and clears the 24 pixel minimum through the spacing exception, so no
layout changed for that.

On a 375 pixel viewport the protocol directory pushed its state chips past the
edge of the screen with nothing to scroll, which hid the very thing the page
exists to show. The state column wraps now, and below 576 pixels the row
stacks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The origin sent no content policy, no frame protection, and no referrer policy.
A page URL here contains an address, a transaction, or an output, so a default
referrer would have leaked exactly the thing a visitor came here to look up
privately, to every site they clicked through to. That is now no-referrer,
alongside a content policy that permits nothing off this origin.

The build injects one inline script whose content changes every build, so the
gateway hashes it at start-up and allows it by name rather than opening the
policy to inline script.

Two more things the deployed site showed. The blockchain toggles had no
accessible name. And the incoming transactions panel rendered a heading over
empty space, because this deployment keeps no historical statistics; it now
says so, which is what every other empty state on the site already does.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
UPSTREAM.md listed the overlay and the first branding pass. It now lists the
backend binding and sync-state additions, the analytics and redirect removals,
the deleted and rewritten upstream surfaces, the renamed identifiers, and the
accessibility fixes, along with the two new classes of merge conflict a sync
should expect.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Measured against the deployed site: the largest layout shift on every page was
the footer, 0.48 on the protocols page. The column holding the page has a
spacer meant to push the footer down, but with no floor on that column the
spacer had nothing to expand into, so the footer rendered just under a nearly
empty page and jumped the moment data arrived. Worse on the pages that load
fastest, because their content arrives later relative to first paint.

A viewport-height floor holds the footer at the bottom until real content
exceeds it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A floor on the page column parked the footer exactly on the viewport edge,
which is the worst starting point: when the page grew, the region the footer
swept through covered almost the whole screen, and the protocols page still
scored 0.45. Giving the router outlet its own viewport-height floor starts the
footer below the fold, so later growth moves it entirely outside the viewport.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Audited both projects with development dependencies excluded. The frontend
carried 3 critical and 40 high advisories, the backend 4 high.

Frontend: the Angular toolchain moves within 20.3.x to the patched releases,
which clears the two sanitization bypasses in core and compiler, the date
formatting denial of service in common, and the server-side request forgery in
platform-server. 62 advisories become 11, with no criticals and no highs that
reach the browser; the six that remain are build tooling whose only offered
fix is a major downgrade.

Backend: axios and ws move to their patched releases, which clears the request
forgery bypass and the uninitialized memory disclosure in the WebSocket server.
The backend now audits clean.

Every version change is patch level within the same major. The frontend builds
and its suite passes; the backend compiles.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…I gates (#1)

Universe Explorer: protocol product surfaces, branding cleanup, and CI gates
@bitcoinuniverseadmin
bitcoinuniverseadmin merged commit 92d7300 into main Aug 26, 2026
10 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.

1 participant