Files
chat/client/index.html
zooqueen a9167adb4c the corrected mark could not reach a tab that already had the old one
chat's tab showed a hollow, black-stroked outline H while hanzo.ai,
cloud.hanzo.ai and hanzo.app all served one solid mark. The file was already
fixed — `8310fbc7` replaced it, the image carries it, and the running pod serves
the right 2142 bytes. It reached nobody.

An icon goes out `public, max-age=172800`. Two days in every browser that has
one, and Cloudflare keeps its own copy besides. Measured against production
while the pod was already correct:

    through the edge   cf-cache-status: HIT   age: 63590 (17.7h)   5236 bytes
    cache-busted       cf-cache-status: MISS                       2142 bytes

So a purge alone would not have finished it either: every returning visitor
holds the outline until their own two days run out. A URL nobody has fetched
has no cache to beat, so each link now carries its file's own content hash —
which is what hanzo.ai has always done and what chat was alone in not doing.

Each file carries ITS OWN hash. Giving both links the ico's was the obvious
shortcut and it is wrong in the direction that matters: the svg is what a
modern browser actually paints, so a shared version means changing the svg
alone ships nothing, which is this bug with a different file in it.

The spec reads the declared version against the file on disk, so the two cannot
drift, and pins the mark's hash so "the same mark as the fleet" is a fact rather
than a claim. All three mutations bite — a bare path, a drifted version, and the
mark swapped for another drawing of an H.
2026-08-20 17:10:51 -07:00

66 lines
3.0 KiB
HTML

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<base href="/" />
<meta name="theme-color" content="#000000" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="description" content="AI chat platform with support for multiple AI models" />
<title>Hanzo Chat</title>
<!-- THE MARK IS VERSIONED BY ITS OWN CONTENT, and that is not decoration.
An icon is served `public, max-age=172800` — two days in every browser
that has one, and Cloudflare holds its own copy on top. So when the H
was corrected from a hollow outline to the solid mark the rest of the
fleet shows, the fix reached the pod and stopped there: the edge served
a 17-hour-old copy to everyone (measured: cf-cache-status HIT, 5236B,
against the pod's correct 2142B), and a purge would still have left
every returning visitor on the old one until its own two days ran out.
A URL nobody has fetched has no cache to beat. hanzo.ai already does
exactly this; chat was the surface still asking for a bare path. -->
<link rel="icon" href="/favicon.ico?v=9ed5d449" sizes="any" />
<link rel="icon" href="/favicon.svg?v=7c964c7f" type="image/svg+xml" />
<link rel="apple-touch-icon" href="assets/apple-touch-icon-180x180.png" />
<meta name="viewport" content="width=device-width, initial-scale=1, interactive-widget=resizes-content, viewport-fit=cover" />
<style>
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
</style>
<script>
// Hard default: true-black dark, unless the user explicitly picked light or system-light.
// Applied on <html> synchronously here to avoid any light flash before React hydrates.
const stored = localStorage.getItem('color-theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const isDark = stored === 'light' ? false : stored === 'system' ? prefersDark : true;
document.documentElement.classList.add(isDark ? 'dark' : 'light');
const loadingContainerStyle = document.createElement('style');
const backgroundColor = isDark ? '#000000' : '#ffffff';
loadingContainerStyle.innerHTML = `
#loading-container {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background-color: ${backgroundColor};
}
`;
document.head.appendChild(loadingContainerStyle);
</script>
<script defer type="module" src="/src/main.jsx"></script>
<!-- No analytics tag: telemetry is the ONE @hanzo/event client mounted in
client/src/Providers/AnalyticsProvider.tsx (POST /v1/event). -->
</head>
<body>
<div id="root">
<div id="loading-container"></div>
</div>
</body>
</html>