Skip to content

Latest commit

 

History

History
158 lines (131 loc) · 9.07 KB

File metadata and controls

158 lines (131 loc) · 9.07 KB

Provider marks: sources, hashes, and terms

Left draws three marks it does not own. This file is the record of where they came from, what we checked, and what we are relying on to use them. If you are refreshing an asset, read this first and update it in the same commit.

What changed, and why

Until 2026-07-28 the app drew a cloud for Claude and a hexagonal ring for GPT — shapes invented here on the reasoning that we had no licence to redraw a trademark. The captain rejected them, and was right to: a status item exists to be recognised without reading, and an interpretation of a logo is recognised as nothing. Worse, the cloud was not merely unofficial but actively misleading — it is nobody's Claude mark, and a user seeing it had no way to know which provider the number beside it belonged to.

The app now draws exactly what each vendor publishes, unaltered.

Sources

Claude and ChatGPT were retrieved on 2026-07-28, Grok on 2026-08-19, over plain HTTPS reads of the vendors' own sites. No third-party icon repository was used, and none may be: ProviderMarkProvenanceTests fails on any origin that is not first-party.

Claude ChatGPT Grok
Vendor Anthropic PBC OpenAI OpCo, LLC X.AI LLC
Source URL https://claude.ai/favicon.svg https://chatgpt.com/cdn/assets/favicon-l4nq08hd.svg https://grok.com/images/favicon.svg
Corroborated against https://assets-proxy.anthropic.com/claude-ai/v2/assets/v1/cd02a42d9-Vq_H3mgS.svg (the <link rel="icon"> claude.ai itself serves) the <link rel="icon" type="image/svg+xml"> on https://chatgpt.com/ the <link rel="icon" type="image/svg+xml"> on https://grok.com/
Retrieved 2026-07-28T12:06:07Z 2026-07-28T12:06:07Z 2026-08-19T22:39:59Z
Vendored as Assets/provider-marks/claude-ai-favicon.svg Assets/provider-marks/chatgpt-com-favicon.svg Assets/provider-marks/grok-com-favicon.svg
Bytes 2558 4258 9758
sha256 b150888bc7257af83e3b85d3c2be4294f88986026f8168f6c12fc1fde6697350 8f2de046d22cfecfe3917cf87ff1ce49a48d79956f6b18be3b37db29148a0aeb c3db0dfaf760b702b8490c6cbefe07fd8bfe00db43cae6a0acccf768f44d6179
viewBox 0 0 248 248 0 0 180 180 0 0 512 512
Declared fill #D97757 #000 light / #fff dark, via the asset's own prefers-color-scheme block mark blades #FCFCFC on a #050505 plate

Assets/provider-marks/PROVENANCE.json carries the same facts in machine- readable form, including the sha256 of each d attribute, and is what the tests read.

Three corroborations worth recording. Anthropic's published brand accent is #d97757, which is the fill in the retrieved file — the asset is the real mark, not a lookalike. claude.ai's favicon.svg and the <link rel=icon> asset its own HTML references are byte-identical, so two independent first-party paths agree on the same bytes. grok.com's HTML names /images/favicon.svg as rel="icon" type="image/svg+xml", and that is the file vendored here. xAI also publishes a brand-asset zip from the brand guidelines; Cloudflare blocked an unauthenticated fetch of the zip on this retrieval, so the live first-party favicon is the source of record.

Retrieval used a read-only browser session (chrome-devtools-axi) for chatgpt.com, whose edge refuses non-browser clients, and a plain curl for claude.ai and grok.com. Nothing was authenticated and nothing was written.

Grok's favicon is a Figma plate, not a bare mark: a rounded square, two white blades, and a masked hairline for the 512px icon. The compiled geometry is those two unmasked #FCFCFC paths concatenated in document order — the vendor's curves, without the plate. vendor-provider-marks.py records that selection; it does not redraw the blades.

How the geometry reaches the screen

Assets/provider-marks/*.svg          the retrieved bytes, unedited
  -> scripts/vendor-provider-marks.py
  -> Sources/LeftCore/ProviderMarkGeometry.swift   the `d`, verbatim
  -> Sources/LeftCore/SVGPath.swift                parsed to a CGPath
  -> Sources/LeftCore/ProviderMark.swift           filled, never redrawn

Nothing in that chain is free to reinterpret a curve, and ProviderMarkProvenanceTests holds every link:

  1. the vendored file still hashes to what was retrieved;
  2. the compiled d string equals the file's d byte for byte;
  3. the mark actually drawn still matches a committed 32×32 fingerprint, so re-pointing the drawing code at something hand-made fails even if the constants are untouched;
  4. the retired symbols cannot return — the Claude mark must radiate into all four corners as a cloud cannot, and the GPT mark must cross ink three times from centre to edge as a single-band ring cannot.

To refresh an asset: replace the SVG with fresh first-party bytes, update RETRIEVED_AT/SOURCES in scripts/vendor-provider-marks.py, rerun it, then refresh the fingerprint by hand from the failing test. The manual fingerprint step is deliberate — a changed fingerprint means the mark on screen changed, and somebody should look at it before it ships.

What we adapt, and what we do not

Geometry is never adapted. Two rendering properties are:

  • Size. Each mark is scaled to the requested height by its own ink bounds rather than its viewBox. The vendors pad their favicons differently for their own icon plates; matching those paddings would make one mark optically smaller than the others beside the same digits. Proportions are preserved — the published marks are square within one percent, and ProviderMarkTests asserts each rendered image matches its artwork's aspect ratio.
  • Colour, in the menu bar only. macOS status items must be template images: the system inverts them for light menu bars and click highlight, and an image that opts out of that is simply broken in half the menu bars it appears in. So in the menu bar each mark is a monochrome silhouette of the official geometry. In the overlay there is no such constraint, so each mark is drawn in its vendor's own colour — Anthropic's #D97757, the #fff that chatgpt.com's favicon itself specifies for a dark background, and the #FCFCFC grok.com fills the blades with on its dark plate. All three clear WCAG 1.4.11's 3:1 non-text requirement against our surface (#131513). PaletteTests holds this, and a future asset whose colour failed would have to fall back to the template silhouette.

Negative space is preserved by construction: the paths are filled non-zero, exactly as browsers render them, so the knot's interlacing and the burst's gaps survive. The mark tests check both read at the menu bar's real 11 pt glyph height.

Trademark position

The Claude name and mark are trademarks of Anthropic PBC. The ChatGPT and OpenAI names and marks are trademarks of OpenAI OpCo, LLC. The Grok name and mark are trademarks of X.AI LLC. Left is an independent tool and is not affiliated with, endorsed by, or sponsored by any of those companies.

The marks are used nominatively: each identifies the provider whose allowance is displayed on the row it labels, which is the purpose a nominative use has to serve. Specifically:

  • Each mark appears only beside that provider's own data. Neither is used as Left's own icon, in its app icon, or anywhere it could read as the source of the software. Left's identity is its own mark (LeftMark.swift), which is what the app icon and the pre-first-reading status item carry.
  • No more of either brand is used than identifies the provider — the mark and the provider's name, nothing else. No wordmark lockup, no brand typeface, no vendor colour anywhere but the mark itself.
  • The geometry is unmodified. The two adaptations above are rendering, not redesign, and both are documented here.

Constraints we are knowingly operating under, recorded so the next person does not have to rediscover them:

  • The vendors' brand guidelines restrict recolouring their marks. The menu-bar template is a recolour — it is the platform's requirement for a status item, not a stylistic choice, and it is the narrowest form available (a monochrome silhouette of the unmodified geometry). The overlay avoids the issue entirely by using each vendor's own declared colour.
  • A favicon is published for browsers to display, which is not the same as a grant of trademark licence. The claim here is nominative fair use, not licence. That is a defensible position for an independent client that displays a user's own account data, and it is the position Left is taking.
  • If either vendor objects, the remedy is small and pre-planned: the marks are loaded through one type, so replacing them with the provider's plain name is a one-file change.

The ChatGPT mark stands for the provider, not the product. The allowance behind it is the Codex CLI's, so the overlay row is labelled ChatGPT / Codex rather than left to the mark alone, and the mark never appears without that label or the compact GPT beside it. Nothing in the app presents Codex allowance as a separate provider identity, and nothing presents it as ChatGPT subscription usage.