The two mains shared no history, so this is a per-file three-way merge:
for each file the 65 forge-only commits touched (by patch-id), the base is
the newest version both histories held. 105 files merged or took one side
cleanly, 48 were already identical, and the 45 true conflicts and 31
modify/delete pairs were resolved by what runs on the cluster:
- The forge wins where it is live: explorer 1.5.56 (digest 45db11ff) and
its archive readers, explore-fe-hanzo's ConfigMap env (AI coin,
/v1/indexer/hanzo, /v1/chain/hanzo/rpc), exchange-api reading
luxd-archive, and explore-fe-{lux,zoo}-testnet, pinned to what they run
(v2.8.5-lux / v2.8.4-lux).
- GitHub wins where it is live: explore-fe-lux v2.8.5-lux, explore-fe-zoo
v2.8.4-lux, bankd v1.0.18, lux-build's routes.
- The forge's retirement of workloads that run nowhere stands: lux-mainnet
dex, lux-hb2, lux-market, traffic, wallet-web; the lux-testnet frontends,
indexer, exchange and gateways; lux-operator. deploy/lux-testnet/luxd.yaml
stays, since roll_luxd.sh reads it.
- GitHub's deletions stand: lux-finance and lux-financial (static sites
now), the k8s/ operator manifests, .hanzo/workflows/cicd.yml.
- Paths are /v1/chain/C/rpc where the forge had written /v1/chain/c. All
four spellings answer; this one is the documented form. The forge's
/{network}/v1 doc lines are dropped: a network is a host, and the prefix
404s.
Dry-run against the running objects (server-side, as CD applies), the
merged explorer shows no change where GitHub's showed 152 lines, and no
other live workload moves further from what runs. Every deploy/*/*.yaml
renders with charts/app; price.yaml, which failed on GitHub, now renders.
Claude-Session: https://claude.ai/code/session_01TzirYkGmD88w4GipqivUtV
explorer 1.5.56 embeds indexer v1.5.12: a null block from a lagging hanzod
seat is retried rather than stored as an empty block, and a start-up audit
indexed the 525 Hanzo heights earlier runs had skipped.
Chain 36963's native coin is AI, never HANZO: the Hanzo explorer page and the
compose explorers for Hanzo mainnet, testnet and devnet now say so.
Co-authored-by: Hanzo Dev <[email protected]>
The Hanzo explorer was re-applied twice on 2026-09-24 from outside this repo
(v1.1.30, then v1.1.32), after this file had pinned v2.8.5-lux. explore.hanzo.ai
and explore.hanzo.network are Hanzo's names and explore-hanzo.lux.network now
redirects to explore.hanzo.ai, so this pin follows the running image rather than
the Lux release.
Co-authored-by: Hanzo Dev <[email protected]>
k8s/dns is re-exported from the live zones: bridge.lux.network, the ACME TXT
left for bridge, bridge-api, mpc and api.mpc, lux.chat's Azure asuid records and
the GoDaddy _domainconnect CNAMEs on lux.review and lux.training are gone, and
lux.build lists the AWS ingress it has pointed at since 2026-09-19.
kms.lux.cloud has no AWS backend: Lux's own KMS (lux-kms-go) runs on no cluster
here. kms-gen-validator-keys.sh and kms-seed.sh no longer default to it; they
require KMS_API_URL, because a default that does not resolve turned every key
push into a "SKIP" line. NETWORKS.yaml stops listing mpc-api.lux.network,
mpc.lux.network and kms.lux.cloud for the MPC topology.
explore-fe-lux and explore-fe-zoo run one replica each; with maxUnavailable 1 a
rollout stopped the only pod before its replacement was Ready, and the explorer
answered 503 until it was. maxUnavailable is 0 now, as applied live.
Co-authored-by: Hanzo Dev <[email protected]>
hanzod runs Hanzo's own committee and no P-Chain, so every platform.* read
v1.1.30 sent answered "no such chain: P". v1.1.32 (luxfi/explore 546ed00dc)
sends none there and drops the validators and chains pages and nav entries.
Applied to lux-mainnet; the live Deployment matches this file.
Claude-Session: https://claude.ai/code/session_011Ge9UnfkEK37Lapx5nfPQK
deploy/lux-{mainnet,testnet}/luxd-archive.yaml are charts/app values for
the two luxd archives that serve api.lux.network, api.lux.cloud and
api.lux-test.network. They replace the hand-applied k8s/ manifests and
deploy/lux-api/route.yaml, which declared the same objects.
Rendered and dry-run against the running objects (server-side, the way
CD applies), a sync adds the chart's labels, its config checksum and
HANZO_VERSION, and nothing else: same container, genesis, chain config,
volumes and routes. So cd.automated is off until someone syncs one.
Co-authored-by: Hanzo Dev <[email protected]>
bridge.lux.network points at the AWS ingress again, where it redirects to the
bridge in the Lux wallet; forty-nine Lux pages link to it. ama.lux.network
forwarded to a Calendly URL that Calendly reports as not valid, and no page
links to it; the record and its page rule are deleted.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
v2.8.5-lux lists only chains that have an explorer: the SPC and Pars cards
linked names that do not resolve, and every page load asked api.pars.network
for validators and got 502. The Hanzo explorer was still on v1.1.30; it runs
the same image as Lux and Zoo now, from ghcr.io/hanzoai. The Lux testnet
explorer (explore-fe-lux-testnet, not declared here) runs the same image.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
On the Zoo explorer the validators page counts only Zoo, /dex answers 404, and
the footer links point at the zooai org and Zoo's own accounts. Applied on AWS
with the same image digest and env.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
An RPC that answers eth_chainId says nothing about whether the chain still makes
blocks, and the status page could not tell a halted chain from a live one.
chain-tip answers /v1/tip/<chain> with height, timestamp and age_seconds for
lux-mainnet and lux-testnet, read from their luxd-archive Services. The chains
are fixed in its env; a request names a chain, never a URL. ClusterIP only.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The Service and route were live with no Deployment behind them, so every
/v1/trade path on api.lux.network and api.lux.cloud answered 503. lux-chain,
the in-cluster name LUX_RPC used, no longer exists; luxd-archive is the Service
the public /v1/chain route serves. The pods run on the apps node, beside the
other lux-mainnet frontends.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
explore, api-explore and cdn.lux.cloud were answered only through *.lux.cloud,
which also answered admin, kms and s3.lux.cloud with a 404 after their own
records were deleted. The three served hosts now have records of their own.
Co-authored-by: Hanzo Dev <[email protected]>
lux-ci is a service client (client_credentials only) in org lux. A KMS
login with it yields an org-lux token, so bin/kms reads /orgs/lux
HANZO_DEPLOY_TOKEN and a site publishes under lux/<slug>. It is set as a
repo-level secret where a repo must stop inheriting the lux forge org's
KMS_CLIENT_ID/SECRET, which are a Hanzo identity.
lux-cloud's live registration also holds https://lux.id/callback, which
its hosts do not derive. The upsert replaces the URI list, so it is
declared as a redirect exception rather than deleted by this converge.
Co-authored-by: Hanzo Dev <[email protected]>
Every web record names the AWS ingress, and names with nothing behind them
are gone: dead Cloudflare tunnels (dchain, 01-05.luxno.de), disabled Vercel
and Netlify deployments, the Stripe checkout, GoDaddy parking, unactivated
Google custom URLs, the devnet hosts (no Lux devnet runs), bridge, mpc,
liquid, the SPC and Pars explorers, kms/s3/admin.lux.cloud and
v1.lux.exchange. status.lux.financial is new.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
api.lux-test.network/ returned 404 while api.lux.network/ is the C-chain
endpoint; the testnet route now carries the same root rule.
explore-fe-spc and explore-fe-pars (lux-mainnet) are gone: neither chain has
a node for the explorer to index. lux-fleet keeps running with no public
host: api.cloud.lux.network was two labels under lux.network, past the edge
certificate, so no browser could complete a handshake.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
hanzoai/universe charts/app/values/hanzo/hanzo-domains.yaml routes lux.tel,
www.lux.tel and console.lux.tel to cloud, which serves project tel. Two
more claims lived here: deploy/lux-tel (a static route off /var/www/tel,
priority 100) and k8s/lux-k8s/tel (Deployment + Ingress on
ghcr.io/luxfi/tel:0.1.1, referenced by no kustomization). Both go, so one
declaration claims those hosts.
lux-fleet deletes the Application with preserveResourcesOnDeletion and
no delete verb on the cluster, so removing the file removes nothing live.
Co-authored-by: Hanzo Dev <[email protected]>
The door existed to keep mainnet's admin API off the public path while its
import needed it on and a restart was not yet safe. Both are over: the
import finished at 1,082,780 and 1.37.9 restarts cleanly, so mainnet now runs
with the admin API off like the others. luxd itself refuses admin_, debug_,
personal_ and txpool_ (none are enabled) and answers CORS, which is
everything the door did.
Routes name luxd-archive:9630. Mainnet restarted into this shape at the tip
and was answering at 1,082,780 with history, state and every sampled
transaction intact. The door had capped an in-cluster indexer at 2.5 blocks/s
against 167 direct.
Co-authored-by: Hanzo Dev <[email protected]>
The lockfile pins Playwright 1.58.2; the runner image carries 1.58.0's
chromium in /opt/playwright, read-only to the job, so installing the pinned
build failed with EACCES there. PLAYWRIGHT_BROWSERS_PATH=0 puts it in
node_modules, which the job owns, on any runner.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The fleet mints a runner only for a job that names self-hosted or a
linux-<arch> label. A job asking for lux-build-amd64 alone was never given
one, and it still matched runners minted for other jobs that named
[self-hosted, lux-build-amd64], so it took theirs and left them queued.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
setup-node v4 reads `cache` as a package-manager name, so `cache: false`
asked it to cache for a manager called "false" and it failed the step
with "Caching for 'false' is not supported". Leaving the input unset is how
v4 caches nothing, which is what the setting meant.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
GitHub fails any job that references actions/upload-artifact v3 at
"Set up job", before a step runs, so every E2E leg failed without
testing anything. v4 takes the same name, path and retention-days.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
get-helm-3 installs into HELM_INSTALL_DIR and then runs `helm` from PATH to
check the install, so with the directory not yet on PATH it reported
"helm not found" and failed a good install.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
bankd v1.0.18 takes only a lux.id access token issued to lux-financial for
the lux org, maps only a member of the admin org to _superusers, and listens
on HTTP alone. Its pod reads none of the bank-secrets keys, so the five env
references to them are gone.
bank-docs states the amd64 node selector its pod already runs with.
e2e/40-lux-financial proves the one way in: neither console serves a password
input or ships a credential in its JS; every sign-in screen hands off to lux.id
with client lux-financial, PKCE S256 and the console's /auth/callback; bankd
answers 404 on every password and Base sign-in route, the code exchange takes
only lux-financial by code or refresh, and a token lux.id did not issue to
lux-financial reads as anonymous. The password-form sign-in and the seeded
ledger totals it asserted are deleted: neither exists.
k8s/lux-k8s/{bank-api,bank-dash,bank-docs,bank-sandbox,bankd,financial} and
scripts/seed-bank-admin.ts are deleted. deploy/lux-bank declares the bank,
lux.financial is a static site, and no host those files name resolves.
Co-authored-by: Hanzo Dev <[email protected]>
The render job piped get-helm-3 into bash, which reaches /usr/local/bin through
sudo, and then imported yaml from a system python that has none; on the lux
fleet the runner is unprivileged and sudo cannot work, so the job failed at its
first step. helm now lands in RUNNER_TEMP and PyYAML in a venv there.
E2E jobs asked for lux-build-amd64 alone. The fleet mints a runner only for a
job naming self-hosted or a linux-<arch> label, so those jobs were never
picked up. They name [self-hosted, lux-build-amd64], as render does, and
install chromium without --with-deps: the runner image carries its libraries.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
1.37.8 wrote the acceptor tip for a whole import round before committing that
round's tries one block at a time, so a restart partway through left a tip
above the last accepted block, naming blocks with no state, and the C-Chain
could not initialize ("required historical state unavailable (reexec=2)").
1.37.9 (luxfi/evm v1.104.56) writes tip and trie together per block, and moves
a stale tip back to the accepted block on boot.
Measured on live lux-mainnet: stopped mid-import on 1.37.8 at 217,500 with the
tip at 220,000; on 1.37.9 the C-Chain came up at 217,500 immediately and the
luxd-import Job resumed with no wipe. The pod may now be restarted at any point.
Co-authored-by: Hanzo Dev <[email protected]>
luxfi/evm#152's cause was the import skipping the per-block accept step (tx
index and trie commit), so every 1.37.7-imported chain answered about one
transaction in two hundred by hash and could not survive a restart. On
1.37.8 lux-testnet answers all 219 by hash, with receipts.
Mainnet is re-imported from an empty database under 1.37.8, driven by the
luxd-import Job, which is a one-off and not in the kustomization. The pod
must not be deleted while it runs: 1.37.8 still cannot initialize a C-Chain
restarted DURING an import. After a completed import, restarts are safe.
The mainnet node asks for 1000m. The chains node is shared, and under
contention CPU divides by request; at 300m the import got a tenth of a core.
Co-authored-by: Hanzo Dev <[email protected]>
The customer app and the admin console share one public PKCE client,
lux-financial, registered for app.lux.financial and admin.lux.financial with
tokens that live an hour and refresh for a day. lux.financial itself is static
files with no sign-in, so its redirect goes. lux-bank stays bankd's service
identity.
bankd and bank-dash are pinned to v1.0.16 by digest: no password route, no
password form. bank-dash carries only the env its server reads. admin is a
static site, so the Deployment declarations for a bank-admin pod go, in deploy/
and in the k8s/ reference tree.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
WLUX, both factories, the quoter and the router are the addresses with code on
96369 now that its history is the one imported from luxfi/state.
Co-authored-by: Hanzo Dev <[email protected]>
Both hosts are one static export of luxfi/financial, served from
s3://hanzo-sites/lux/financial by the lux-financial router in the edge's
sites table (hanzoai/universe infra/lan/ingress.yaml).
lux-finance served lux.finance from a September export in the node-local
/var/www store, and that build crashed in every browser ("Cannot read
properties of undefined (reading 'type')"). lux-financial ran the same era
as a Next server pod behind lux.financial. Both are gone from the cluster.
The canonical C-Chains are the RLP archives, 1,082,781 blocks on mainnet and
218 on testnet. Each runs as luxd-archive on the chains node and answers
publicly through the rpc door, which passes only eth_/net_/web3_ methods and
answers admin_, debug_, personal_ and txpool_ itself.
Testnet is frozen: its database is an emptyDir rebuilt from the archive
inside VM initialization on every boot, so its admin API is never on and no
restart depends on state surviving one. Mainnet is too large for that and
is imported once with admin_importChain; its admin API is behind the door,
and the pod is OnDelete and must not be deleted until luxfi/evm#152 is fixed
(after an import, a restart leaves the C-Chain unable to initialize).
Genesis is declared. The luxd-genesis ConfigMaps now hold the documents the
archives chain to: mainnet block 0 0x3f4fa2a0…, testnet 0x1c5fe377…,
each verified by booting it. The testnet document here before was a
different one (gasLimit 0x3b9aca00) that refuses every archived block, and
the mainnet one carried a C-Chain genesis that hashes to 0x43befc4e….
api.lux.network and api.lux.cloud route /v1/chain and / to the door at
priority 300, above the unified api-* router, and no longer point at
validators on the LAN.
The five-validator luxd sets are 0. They start from a genesis the archive
does not chain to and import nothing, so any block they made would fork
it. They come back on the canonical genesis once #152 is fixed.
lux-bank/bankd serves ghcr.io/luxfi/bank:v1.0.15, a single linux/amd64
manifest at sha256:a1197959: v1.0.14 with the sandbox login bounded per
client address and per account, answering 429 with Retry-After past
either budget.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_016dDw5Lp9sZFctwvZLn4nVz
safe-cgw.lux.network is served by two replicas on AWS, declared by the overlay
hanzoai/universe infra/aws/values/hanzo/lux-safe-cgw.yaml over this file, which
also pins v0.1.6 by digest.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_016dDw5Lp9sZFctwvZLn4nVz
Declare the container port, /health probes, requests, and the
docs.lux.network route. Drop the ghcr-luxfi-fresh pull secret, which
no cluster holds.
Co-authored-by: Hanzo Dev <[email protected]>
The backend's values were deleted as a copy while it was paused for the lux
mainnet import; it kept running from a live config with one chain, because on
09-09 only lux answered. Zoo (200200) and hanzo (36963) answer in-cluster now,
so they get rows: zoo's venue contracts and 2T genesis are read on its chain,
hanzo's new chain has no venue yet.
The frontends' wallet RPC pointed at api.zoo.ngo (served by cloud, not the
chain) and /v1/chain/hanzo (a 404); both now name the chain endpoint.
Co-authored-by: Hanzo Dev <[email protected]>
latest now names sha256:d34e9c1c (amd64+arm64); the digest fixes which
bytes run. ghcr-pull exists in no cluster; ghcr-secret is the credential
the other lux apps pull with.
Co-authored-by: Hanzo Dev <[email protected]>