zoo-vote: declare zoo.vote where zoo-fleet reads

zoo.vote was declared in lux/universe deploy/zoo-mainnet/zoo-vote.yaml. zoo-fleet's
generator reads THIS repository (hanzo/universe infra/k8s/hanzo-cd/project-zoo.yaml,
path deploy/*/*.yaml), so the workload had a declaration in a fleet that does not
serve it and none in the one that does. Declared here, deleted there.

The image is ghcr.io/zooai/vote, built by luxfi/vote's Image workflow: one source
builds lux.vote, zoo.vote and hanzo.vote, each into its own org's registry, so
this pod pulls with Zoo's credential and no other org's access can strand it. The
tenant is a build-arg and the host settles it again at runtime, which is why the
ingress names zoo.vote and www.zoo.vote — the app reads the hostname to know
which DAO it is, so what is routed here is part of its behaviour.

The tag is what the live Deployment runs, with a TODO to pin the first tag the
workflow prints. It could not be verified from a workstation, so it stays a tag
rather than becoming a digest that was guessed.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_015g5a1mCWuuSQTBZZywNnET
This commit is contained in:
Hanzo AI
2026-09-04 00:23:19 -07:00
co-authored by Claude Fable 5.1
parent a986b507ec
commit ace46f80af
+91
View File
@@ -0,0 +1,91 @@
# zoo.vote — the governance interface, on Zoo's own fleet.
#
# It was declared in lux/universe deploy/zoo-mainnet/zoo-vote.yaml, which
# lux-fleet reads. zoo-fleet reads THIS repository (hanzo/universe
# infra/k8s/hanzo-cd/project-zoo.yaml, generator path deploy/*/*.yaml), so a
# Zoo service declared in Lux's universe is a second Application for one
# workload. Declared here, deleted there.
replicas: 1
selectorLabels:
app: zoo-vote
containerName: spa
image:
repository: ghcr.io/zooai/vote
# ONE source: luxfi/vote. Its `.hanzo/workflows/image.yml` builds that tree
# three times — lux, zoo, hanzo — each into its own org's registry, so this
# image is Zoo's and is pulled with Zoo's credential. The tenant is a
# build-arg (VITE_VOTE_HOME=zoo) and the site is settled at runtime by the
# host, so the bundle here is Zoo's by both.
#
# TODO: pin the first tag that workflow publishes, with
# `deploy/pin.sh zoo-mainnet/zoo-vote <version>` so the digest is written
# beside it. The tag below predates the workflow: it is what the live
# Deployment is running, kept because naming a tag the registry does not have
# takes zoo.vote down. It could not be verified from a workstation — ghcr.io
# refuses an anonymous pull token for this repository — so it is a tag and
# not a digest.
tag: votesguard-zoo2
pullPolicy: Always
partOf: zoo
labels:
app.kubernetes.io/cluster: zoo-k8s
app.kubernetes.io/env: mainnet
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 50m
memory: 32Mi
livenessProbe:
failureThreshold: 3
httpGet:
path: /health
port: 3000
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /health
port: 3000
scheme: HTTP
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
ports:
- containerPort: 3000
name: http
servicePort: 80
imagePullSecrets:
- name: ghcr-zooai
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
topologySpread:
enabled: false
lifecycle: null
terminationGracePeriodSeconds: 30
# The host is what tells the bundle it is Zoo — every label of the hostname is
# read against the tenants it knows — so the names routed here are part of the
# app's behaviour and not only of its reachability. www included, because the
# app resolves it to the same tenant and a visitor who types it should not land
# on a certificate error.
ingress:
enabled: true
hosts:
- zoo.vote
- www.zoo.vote
tls: true
className: ingress
# Enforcement switch, read by the zoo-fleet ApplicationSet's templatePatch --
# not by the chart. selfHeal returns a hand-edited object to what is written
# here; prune stays off, so nothing is ever deleted.
cd:
automated: true