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
122 lines
4.4 KiB
YAML
122 lines
4.4 KiB
YAML
# Generated from the live lux-mainnet/api-gateway-gateway Deployment on lux-k8s
|
|
# by hack/live2values.py. Live is the source: a repo of hand-applied
|
|
# manifests has unknown currency, the running fleet does not.
|
|
replicas: 1
|
|
selectorLabels:
|
|
app.kubernetes.io/component: gateway
|
|
app.kubernetes.io/instance: api-gateway
|
|
app.kubernetes.io/managed-by: lux-operator
|
|
app.kubernetes.io/name: lux-gateway
|
|
containerName: gateway
|
|
# ⚠ THE CONFIGMAP GOES FIRST, and it is not in this file.
|
|
#
|
|
# This values file is what CD reads, and it MOUNTS `api-gateway-gateway-config`
|
|
# (see volumes, below) without carrying its contents. Those live in
|
|
# k8s/lux-mainnet/api-gateway-gateway-config.yaml, which NOTHING reconciles —
|
|
# no CD Application covers k8s/, so a change there reaches the cluster only when
|
|
# somebody applies it.
|
|
#
|
|
# DONE 2026-08-07, in the required order: the config was applied first, then
|
|
# this tag moved. Verified after: info.peers and info.getNodeID are refused on
|
|
# api.lux.network while info.getNetworkID and info.getNetworkName still answer
|
|
# 200, and /v1/chain/c/rpc is unaffected. The pod logs
|
|
# "1 preEvaluator(s) loaded" with no compile error.
|
|
#
|
|
# ⚠ A refusal surfaces as a bare 500 with an empty body, not as the rule's own
|
|
# `message`. The CEL plugin returns an error and the engine maps that to 500, so
|
|
# the "Method not allowed: only ..." text never reaches the caller. It blocks
|
|
# correctly; it just cannot say why.
|
|
#
|
|
# That split had teeth from v2.16.25 on. Up to and including 2.14.1 the gateway
|
|
# answered a CEL rule it could not compile by serving the endpoint WITHOUT the
|
|
# rule — which is why `info.peers` has been public on api.lux.network,
|
|
# api.hanzo.network, api.zoo.network, api.spc.network and api.pars.network
|
|
# behind a rule forbidding it. From v2.16.25 it refuses instead: the router logs
|
|
# at Error and registers that one endpoint with a handler answering 500.
|
|
#
|
|
# The config in the cluster today still says `has(req_body) && (…)`, which is
|
|
# not valid CEL — `has()` takes a field selection, not a bare identifier. Bump
|
|
# this tag alone and POST /v1/info answers 500 on all five hosts, taking
|
|
# info.isBootstrapped with it, not just the methods the rule denies.
|
|
#
|
|
# Order: apply k8s/lux-mainnet/api-gateway-gateway-config.yaml (already
|
|
# corrected, and a measured no-op against 2.14.1 — that build drops the rule
|
|
# either way), THEN move this tag.
|
|
image:
|
|
repository: ghcr.io/hanzoai/gateway
|
|
# Rolled 2026-08-07 after applying the corrected CEL config, in that order.
|
|
# The tag on ghcr carries a `v`; 2.14.1 did not. Both forms exist in this
|
|
# package, so pin the digest and do not assume either spelling.
|
|
tag: v2.16.25
|
|
digest: sha256:71d7632b4c6dda16758a0077ebc8c1349b3442aca5607975b612ae295dd04697
|
|
pullPolicy: IfNotPresent
|
|
component: gateway
|
|
command:
|
|
- /usr/bin/gateway
|
|
args:
|
|
- run
|
|
- -c
|
|
- /etc/gateway/gateway.json
|
|
resources:
|
|
limits:
|
|
cpu: '1'
|
|
memory: 1Gi
|
|
requests:
|
|
cpu: 100m
|
|
memory: 256Mi
|
|
volumeMounts:
|
|
- mountPath: /etc/gateway
|
|
name: config
|
|
readOnly: true
|
|
livenessProbe:
|
|
failureThreshold: 3
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 15
|
|
successThreshold: 1
|
|
tcpSocket:
|
|
port: 8080
|
|
timeoutSeconds: 1
|
|
readinessProbe:
|
|
failureThreshold: 3
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
successThreshold: 1
|
|
tcpSocket:
|
|
port: 8080
|
|
timeoutSeconds: 1
|
|
ports:
|
|
- containerPort: 8080
|
|
name: http
|
|
servicePort: 80
|
|
volumes:
|
|
- configMap:
|
|
name: api-gateway-gateway-config
|
|
name: config
|
|
rollingUpdate:
|
|
maxSurge: 25%
|
|
maxUnavailable: 25%
|
|
topologySpread:
|
|
enabled: false
|
|
lifecycle: null
|
|
terminationGracePeriodSeconds: 30
|
|
imagePullSecrets: []
|
|
# The immutable spec.selector matches app.kubernetes.io/managed-by=lux-operator, and the
|
|
# chart's app.labels helper hardcodes `Helm` for that key — so the pod template
|
|
# stops satisfying its own selector and the apply is refused. podLabels are
|
|
# rendered after app.labels, so this restores the one label the selector needs
|
|
# without touching the rest.
|
|
podLabels:
|
|
app.kubernetes.io/managed-by: lux-operator
|
|
|
|
# One amd64 manifest, so evo is the only node that can execute this. spark
|
|
# registers qemu-x86_64 binfmt, which is worse than a refusal: the pod starts,
|
|
# runs emulated, and faults at random — 2 restarts and counting. Stated rather than left
|
|
# to the scheduler, the same way trade.yaml states it. The toleration keeps the
|
|
# pin working if `hanzo.ai/no-ci` goes back on evo.
|
|
nodeSelector:
|
|
kubernetes.io/arch: amd64
|
|
tolerations:
|
|
- key: hanzo.ai/no-ci
|
|
operator: Exists
|
|
effect: NoSchedule
|