zeekayandHanzo Dev 826ff1a773 ui: the console is the kit's, and the policy is proven rather than asserted
The console now renders through @hanzo/gui — the Hanzo design system — instead
of a set of primitives written here over the raw tokens. Layout, surfaces,
controls and type are the kit's. Two things deliberately are not: the four state
colours, which must not change with a theme because a supervisor's copy of a
screenshot has to mean what the screen meant, and the meter, which is drawn in
SVG so a width that varies with data is an attribute rather than a style.

The kit is imported at the part rather than at the barrel. @hanzo/gui's index
re-exports every component it has, including ones built on react-native
primitives this bundle never renders — Sheet's pan responder and the spinner's
ActivityIndicator are the two that pulled a native runtime into a browser build.
It is still one kit at one version.

The whole CSP question is now in ui/src/gui.ts, stated once. GuiProvider would
write the config's stylesheet as an inline <style>, which style-src governs and
which would need 'unsafe-inline' or a hash that moves whenever the theme does.
disableInjectCSS turns that off and the same CSS goes on through a constructed
stylesheet — CSP does not govern the CSSOM, because the script that reached it
had already passed script-src. The kit's per-component rules take the same route
into empty <style> holders, which the SHA-256 of the empty string allows and
which allows nothing else.

ui/e2e is the part that was previously a claim. It builds the bundle, serves it
under ui/csp.txt — byte-identical to the chart's HANZO_STATIC_CSP — seeds a
session before the first script runs, and drives Chromium through every screen
the rail offers. It carries a positive control: a style attribute parsed from
markup is asserted to be REFUSED, because "no violations" means nothing without
evidence that a violation would have been noticed. Writing it found two things a
claim would not have: the kit's theme root does carry a style attribute (React
writes it through element.style, so it applies and raises nothing — which is the
distinction that matters and is now written down), and a stray server on the
default preview port had been answering for a build nobody was testing.

origin() is now apiOrigin(protocol, host), a pure function with a table for a
test. It requires the first label to be `aml`, so evil.aml.hanzo.ai — a
four-label host the old rule read as a domain to derive from, and one that
resolves inside *.hanzo.ai — derives nothing. The certificate and the ingress
host rule were the only things standing there before.

@hanzo/iam is 0.21.5: logout ends the session (credentials + RFC 7009
revocation) and the callback error branch checks state before it reads the query
string. The console-side proof of the second is in the harness.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-01 11:19:55 -07:00
S
Description
Real-time AML/CFT transaction monitoring, sanctions screening and case management
2.1 MiB
Languages
Go 88.1%
TypeScript 9.3%
CSS 1.2%
Python 0.7%
JavaScript 0.4%
Other 0.2%