4 Commits
Author SHA1 Message Date
zeekayandHanzo Dev d86f10847a feat(iam): Zoo's own app graph — 5 clients, one issuer, proven end to end
Zoo had exactly one working OAuth client (zoo-cloud) and no declaration of it
anywhere. This ports the Lux shape into this repo: the brand-neutral mechanism
stays in hanzoai/iam (internal/provision), Zoo owns its DATA here, and
`make iam-provision` is the only supported way that data reaches the IdP.

ISSUER. id.zoo.network serves iss=https://zoolabs.id — host and issuer really do
disagree, and it is resolved in favour of zoolabs.id: IAM_ISSUER_MAP already
maps all three Zoo hosts to it, discovery agrees from either host, every sibling
brand's issuer is its <brand>.id apex (hanzo.id / lux.id / pars.id) with
id.<brand>.network as the alias, and zoo.id has no DNS at all so it cannot be
the issuer. The remaining defect is the DISCOVERY DOCUMENT (OIDC Discovery §4.3
wants issuer == fetch prefix), which is a frontend/ingress fix, not a data one.
Reasoning is in the file header, not just here.

Five clients, each declared only on evidence measured against the live surface:
zoo-cloud, zoo-wallet, zoo-dao, zoo-explore, zoo-id. Hosts that carry no OAuth
wiring, hosts served by shared Hanzo backends, and hosts with no DNS are listed
too, so each omission is a recorded decision.

Two defects fixed rather than described:

  cert. The upsert copies req.Cert verbatim on CREATE, so an omitted cert means
  an EMPTY cert, and a client with no cert cannot mint an id_token — the login
  dies AFTER a successful code exchange. Four Zoo clients were in exactly that
  state. Every app now names cert-zoo (convention cert-<org>: lux-cloud has
  cert-lux, hanzo-cloud has cert-hanzo); for zoo-cloud it is a no-op.

  cloud.zoo.network is no longer declared. It has an ingress but NO DNS record
  at 1.1.1.1 or 8.8.8.8, so no browser can reach it; a redirect URI for a host
  that cannot exist is the drift this document exists to prevent. Lux keeps
  cloud.lux.network because that host does resolve.

Image pin moved forward to sha-f9813f6: sha-4bec5ef predates the `cert` field
and the strict parser rejects the document outright. f9813f6 is a strict
descendant of the public-client fixes and of 4b0f4e93, and is the newest sha-
tag in GHCR that resolves to a known commit.

PROVEN, not asserted:
  - converge run twice; the five records are byte-identical apart from
    updatedAt, and no client secret was issued (all five stay public/PKCE)
  - real login as [email protected] -> authorization code -> PKCE token exchange with
    NO client secret, on all five clients
  - id_token minted for each: kid=cert-zoo, iss=https://zoolabs.id,
    aud=<the client>, and the signature verifies against the published JWKS
  - the dropped redirect now correctly 400s: invalid redirect_uri

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-26 19:02:15 -07:00
zeekay f907239098 universe: sovereign-L1 chain.yaml + 5-line Makefile + lux CLI flow
Migrate Zoo from L2-on-Lux to sovereign L1. Per-env primary networkID
equals per-env EVM chainID (200200 / 200201 / 200202 / 200203).
Explicit httpPort + stakingPort per env (no collisions; the old 9680
dev/local clash is gone — now 9720 / 9730).

chain.yaml:
  * networks.<env>.{networkID, primaryEvmChainID, httpPort, stakingPort,
    genesisFile, rpcUrl, cluster, namespace} explicit per env
  * runtime: block — dataDir / snapshotName / serviceLabel templates
    that the lux CLI (pkg/brand) expands per (network, env)

Makefile: collapsed from 16 hardcoded targets (4 verbs × 4 envs with
NID_MAIN := 200200 duplication) to 6 parametric lines:
    make up    env=devnet     ≡  lux up    zoo/devnet
    make cycle env=mainnet    ≡  lux cycle zoo/mainnet
    make cycle-all
Per-env constants live in chain.yaml — single source of truth.

deploy.sh removed: replaced by `lux <verb>` calls via Makefile.

LLM.md: documents the new sovereign-L1 model, CLI grammar
(`lux up/down/snap/cycle <network>/<env>`), chain.lock invariant,
per-brand DOKS cluster topology, and the zoo-private/universe sibling.
2026-06-16 21:03:25 -07:00
Hanzo AI f518621f63 universe: full DX collapse — kill dead auth subnet, SQLite + Litestream, fix CI drift
Major collapses across 61 files (-2394 / +642, net -1752):

- Killed Zoo Auth Subnet: parallel auth chain contradicts hanzo.id Casdoor as canonical IAM
  (deleted k8s/zoo-auth/, compose.auth.yml, auth-gateway/, chain-configs/auth-subnet-genesis.json)
- Postgres StatefulSet → SQLite + Litestream + MinIO replication (per memory no_postgres_sqlite_only)
  Bridge becomes single-writer (replicas: 1) with restore init + replicate sidecar
- Plaintext Cloudflare API token in .env wiped; .env added to .gitignore
- 7× <your-domain> CI placeholders → kms.hanzo.ai
- 3 per-env manifests (3 × 130 lines, 90% dup) → 1 canonical manifests/services.yml (89 lines)
- 6 floating tags (:latest / :main) → :main-amd64 immutable per-arch
- Broken org refs ghcr.io/zoolabs/* + @zoolabs npm → ghcr.io/zooai/* + @zooai
- Workflow runner pool zoo-build-amd64 (wrong) → zoo-build-linux-amd64 (canonical)
- ENV var conflation ZOO_NETWORK_ID → LUX_NETWORK_ID + ZOO_EVM_CHAIN_ID
- Stale dev scripts (start/stop/status/setup.sh), convert-to-submodules.sh, Dockerfile.dev,
  .gitmodules, zoo.id/ static page, retired ARC values, k8s/patches/ all removed
- Duplicate deploy.yml workflow (shadows ci.yml) killed
- Makefile extended with remote-ops targets (deploy-{dev,test,main}, pods-{dev,test,main}, verify)

Tier-1 metrics all zero: plaintext secrets, Postgres in source, /api/ in own routes, brand contamination.

Zoo L2 EVM on Lux mainnet remains GREEN (chainId 0x30e08, balance 5e27 wei).
All 4 kustomize overlays render clean (system=35, devnet=36, testnet=36, mainnet=39).
2026-06-03 11:12:00 -07:00
Hanzo AI c3655e13c9 feat: make up/down/status for zoo subnet on lux localnet 2026-04-04 13:19:44 -07:00