One family. Font stacks name Zen and fall back to the native faces, tokens
name the role rather than a face, and the packages that used to supply a
face now point at @hanzo/font.
Self-hosted @font-face blocks are removed rather than renamed: rewriting the
family in one would leave a src pointing at a file this repo no longer ships.
@hanzo/font carries the binaries and declares the faces, so the local copies
go with the declaration that used them.
Comments naming a face we no longer use are deleted, not reworded.
Two thousand and twenty-one packages carried more than one spec across this
estate — eslint alone in a hundred and four forms — and a package resolved twice
is two copies at run time, which is how react-hook-form came to report "two
different types with this name" from files nobody had edited. None do now.
The number lives in the catalog: a manifest names the package, the workspace
names the version. Where a manifest cannot reach a catalog it still carries the
one version, because the table is the source either way.
A version written into a manifest is written into every manifest that wants it,
which is how eslint came to exist in a hundred and four forms across this estate
and how a package came to resolve twice at run time. The catalog moves the number
out of the manifest: a manifest names the package, the workspace names the
version.
Four are held below their latest because the newer release cannot be used, and
the reason is recorded rather than the version alone: @noble/hashes 2 renamed
every subpath the web3 stack imports, @splinetool/runtime 2 depends on a package
that was never published, @dynamic-labs 5.4.1 the same, and react-resizable-panels
3 points its types condition at the bundle.
The two hosts had drifted. Taking github's commits, except the GitHub-hosted
workflow it edited: this repo already runs on .hanzo/workflows, so the file
stays deleted.
This repo is written on git.hanzo.ai and mirrored to github.com, and the two had drifted apart — 1 commits here the mirror lacked, 7 there this host lacked. Merging rather than overwriting so neither side's work is lost.
This configured a deploy platform we do not deploy on. sentry.hanzo.ai
is served by the cloud binary and its embedded console (ingress router
sentry-hanzo-ai to cloud-api-hanzo-ai), with Cloudflare in front.
The runner's system python is marked externally managed, so installing the
build requirements into it fails with PEP 668 and the pre-build never reaches
bdist_wheel. A venv outside the tree gets a writable interpreter; .dockerignore
admits only dist/, so nothing about the image context changes.
git.hanzo.ai collects .hanzo/workflows, so that is where the two lanes that
carry weight here now live:
docker.yml publishes ghcr.io/hanzoai/sentry. self-hosted/Dockerfile is
Hanzo-branded and installs the wheel built from this source, so
this repo does produce an artifact. It goes through the
hanzoai/.github reusable rather than the hanzo.yml + hanzoai/ci
pair because that Dockerfile needs dist/ populated first and the
images: schema has no pre-build hook. The pre-build now installs
node_modules before bdist_wheel, which setup.py's build_assets
requires, and copies the curated requirements-frozen.txt instead
of freezing the build venv.
frontend.yml runs tsc over static/app, tests/js and fixtures/js-stubs. It is
the widest gate needing only a checkout, and it covers what this
fork changes: the TypeScript 7 tsconfig migration and the
pkg.hanzo.ai npm route.
The other 29 workflows are removed. Most address GitHub or getsentry surfaces
that do not exist here: CodeQL and dependency-review are GitHub Advanced
Security; codecov_*, openapi, release, bump-sentry-in-getsentry and
getsentry-dispatch write into getsentry's org; lock, sync-labels,
label-pullrequest, fast-revert and sentry-pull-request-bot are issue and PR
bots; workflow-sanity calls a reusable that no longer exists.
The service-backed suites (backend, acceptance, migrations, monolith-dbs) are
dropped with their capability stated rather than stubbed: they need the
devservices stack — postgres, redis, clickhouse, kafka, snuba, symbolicator —
which this fleet does not run. mypy and jest are dropped as upstream surfaces:
they type and test upstream code, so a red result there points at code this
fork never touched. publish-dockerhub and self-hosted built and pushed
getsentry-namespaced images; docker.yml replaces them with the hanzoai one.
BEACON_URL was https://sentry.io/remote/beacon/ and every self-hosted install
POSTed to it on a schedule. The payload is not anonymous by default: alongside
install id, version and usage counts it carries get_all_package_versions() — the
full dependency inventory of the running instance — and, whenever
`beacon.anonymous` is off, "admin_email", the address in system.admin-email.
So the fork's own operators were reporting their contact details and software
inventory to a third party, and the settings page explained the arrangement as
though it were still upstream's product. It now posts to api.hanzo.ai/v1/beacon,
and the copy on that page says so, which it could not honestly do before.
Three more outbound identities went with it. USER_AGENT announced every request
this server makes as "sentry/<version> (https://sentry.io)". The Jira and
Bitbucket app descriptors named Functional Software as the vendor — that string
is what a customer reads in the Atlassian marketplace before installing. And the
MS Teams cards sent people to sentry.io/signup for an account they cannot use
here.
Left alone: comments citing upstream issues, form placeholders, and the OIDC
`iss` claim, which is a token-validation input rather than a link.
Co-authored-by: Hanzo Dev <[email protected]>
sentry-pattern.png is a doodle tile with the Sentry script wordmark drawn into
it, and it existed twice: once under images/email, once under static/images/
pattern. The email copy lost its only reference with the template pass. The other
was live — webpack aliases sentry-images to static/images, so the install wizard
and .pattern-bg were both painting the upstream mark as a page background.
Neither use is load-bearing. The wizard's ::after existed only to hold the tile,
and layout.less keeps its ground colour. Redrawing the doodle in Hanzo's marks
would be inventing an illustration to replace one nobody needs, so both files are
deleted rather than substituted.
SHOW_LOGIN_BANNER goes too: the login banner it gated was two hardcoded upstream
campaigns, and with those removed the setting had no reader left.
LLM.md said "Branded as: Hanzo Sentry", which the code no longer agrees with.
Co-authored-by: Hanzo Dev <[email protected]>
FSL-1.0-Apache-2.0 grants us the code, not the trademark. "Sentry" is a
mark of Functional Software, Inc., so every place a user reads a product
name — page titles, email subjects and bodies, integration setup pages,
issue and PR templates, logo and favicon bitmaps — now reads Sentinel and
carries the Hanzo mark instead.
Attribution is a separate thing and stays: LICENSE.md and NOTICE are
untouched, upstream copyright headers are intact, and every identifier
that is an interface rather than a brand keeps its name — the sentry
Python package, static/sentry asset paths, the X-Sentry-Context header,
window.Sentry and the JS SDK loader, @sentry/* package pins, DSNs, and
the SentryApp models and routes.
Links that pointed at sentry.io marketing, docs, and help articles now
point at the hanzo.ai equivalents where one exists; where none does, the
anchor is dropped and the sentence stands on its own rather than dead-end
at a 404. The login-page banner carried two dated upstream campaigns and
its plumbing had no other caller, so both are gone. publish-dockerhub.yml
pushed getsentry/sentry tags — the mark on a distributed artifact — and
build-ghcr.yaml already publishes ghcr.io/hanzoai/sentry.
Co-authored-by: Hanzo Dev <[email protected]>
FSL-1.0-Apache-2.0 grants us the code, not the name. "Sentry" is
Functional Software's trademark, so every place the running app says it
to a user -- page titles, onboarding, empty states, toasts, settings
copy, the self-hosted footer -- now says Sentinel.
Attribution is the other half of the deal and stays untouched: upstream
copyright headers, LICENSE, NOTICE. So does anything where the mark is a
fact rather than a brand -- @sentry/* packages, sentry-cli, the wizard
and bundler plugins, docs.sentry.io, the whole gettingStartedDocs tree.
Renaming those would leave instructions that no longer work.
Nothing structural moved. No import, identifier, route path, feature
flag, API field or test id changed; the diff is 312 lines in and 312
out. Colocated specs were updated in lockstep with the copy they assert.
Marketing and community links point at hanzo.ai, only where a real page
exists to point at.
Co-authored-by: Hanzo Dev <[email protected]>
This repo shipped Sentry's README verbatim: their wordmark hotlinked from
sentry-brand.storage.googleapis.com, four screenshots served out of
getsentry/sentry, their SDK index, their Discord, their Transifex.
The FSL grants copying and modification. It grants no trademark rights, and none
of the usual open-source licenses do. So carrying upstream's wordmark as this
project's masthead was the one part of the fork that was not ours to do —
de-branding is a licensing requirement here, not a style preference.
LICENSE and NOTICE stay exactly as they are. Those are the parts the license
does require, and they are the reason the fork is legitimate; the rebrand
removes the mark and keeps the attribution, which is the whole distinction.
The README now says what Sentinel is and states the one fact a reader needs:
it speaks the Sentry wire protocol, so existing client SDKs report to it with
nothing changed but a DSN.
Co-authored-by: Hanzo Dev <[email protected]>
github.com has no runner for hanzo-build-linux-amd64, so a caller under
.github/workflows is a gate that can never be scheduled. This is the ~7-line
caller on the plane that can (git.hanzo.ai git-runner fleet), pinned @v1.
Co-authored-by: Hanzo Dev <[email protected]>
our verdaccio proxies and caches all of npm plus @hanzo, @luxfi and @zoo.
no lockfile changes: pnpm-lock v9 records integrity not a registry host, and
npm honors .npmrc at fetch time regardless of what package-lock.json resolved.
Co-authored-by: Hanzo Dev <[email protected]>
The first pass left three classes of config that BOTH tsc 5.9 and tsc 7
reject. Each was proven against both compilers before changing:
TS5090 A `paths` target must be relative once `baseUrl` is gone. The
first pass skipped the "./" prefix wherever baseUrl pointed at
the config's own directory, reasoning it was semantically
equivalent. It is not — without baseUrl a non-relative target
is rejected outright, by 5.9 as well as 7.
TS5110 `moduleResolution: node16` requires `module: node16`. The first
pass mapped commonjs projects to node16 resolution alone, which
BROKE those configs for the current toolchain. Both are now set.
TS5102 `downlevelIteration` is also removed in TS7; it was missing from
the dead-flag list.
Verified: repos that tsc 7 previously refused (base-studio, js-sdk, kv-js)
now report zero config errors on tsc 7 AND tsc 5.9.
Co-authored-by: Hanzo Dev <[email protected]>
TypeScript 7 is the native Go compiler and removes `baseUrl` and
`moduleResolution: node|node10`. Both appear here, so `tsc` from TS7
refuses the config outright (TS5102 / TS5108) and cannot typecheck.
`paths` targets resolve relative to `baseUrl` when it is set and relative
to the tsconfig file otherwise. Every `baseUrl` folded here already
pointed at the config's own directory, so dropping it moves nothing and
the targets are left byte-identical. Where a baseUrl pointed elsewhere,
each affected target was rewritten as join(baseUrl, target).
`moduleResolution` was chosen from the declared `module`: commonjs ->
node16, esnext/preserve -> bundler. Configs whose `module` is unset or
exotic were left alone rather than guessed at.
The result is accepted by BOTH toolchains, so nothing has to upgrade
TypeScript in lockstep. Verified on hanzo/chat packages/api: tsc 5.9
779 -> 778 errors (no regression), and tsc 7.0.2 now runs the project
in 2s where it previously refused the config.
Co-authored-by: Hanzo Dev <[email protected]>
Superseded: the Hanzo GitHub App pushes a webhook, so the forge tracks GitHub
without a per-repo workflow. This file called git.hanzo.ai/api/v1/.../mirror-sync
— a Gitea API for a system we no longer drive — and would sit inert in every repo.
One mechanism, in one place, instead of ~350 copies of a cron.
git.hanzo.ai mirrors this repo by PULL on a ~10-minute interval, and arcd runs
CI/CD there — so every push waited out that interval before anything built.
This asks Gitea to pull HEAD immediately.
Latency only: the repo already mirrors via the App webhook, so a missing
HANZO_GIT_TOKEN or a failed curl is non-fatal and never fails the push.
Idempotent (mirror-sync just pulls HEAD) and concurrency-coalesced.
LICENSE-attested or repo-attested upstream is now called out at the
top of LLM.md alongside the project description, so downstream
audits (universe/docs/PRODUCTS.md) can rely on a single canonical
location for the OSS lineage statement.