48 Commits
Author SHA1 Message Date
zeekayandHanzo Dev 981234cef8 chore: symlink AGENTS.md + GEMINI.md + CLAUDE.md -> LLM.md
Co-authored-by: Hanzo Dev <[email protected]>
2026-09-02 00:57:14 -07:00
zeekay e46658e106 fix(brand): the tab shows our mark, not the framework we built on
These favicons still shipped the upstream artwork of whatever the surface was
scaffolded from, so a customer with a few of our products open read someone
else in every tab. They are @hanzo/logo favicon.{ico,svg,png} now, one source
for the geometry.
2026-08-25 11:49:19 -07:00
zeekayandHanzo Dev 338f175a20 the note about the scrub was the last thing carrying what it scrubbed
The structural gate refuses a tracked line naming the scaffold vendor, and it
had been refusing THIS repo for three days over one line: LLM.md quoting two
forge-side commit messages as EVIDENCE that GitHub's history was rewritten to
remove that name. The document was the last carrier of the string it documents.

The forensic point is the valuable part and it survives: the forge side names
the vendor where GitHub says "drop the scaffold vendor's build plugin" and
"Update the generated project template", a rewrite changes every sha, and that
is why merge-base finds no common ancestor and every count reads as
total-commits rather than divergence. None of that needs the literal name, so
the wording is now described rather than quoted.

Not an exemption in the gate. The gate was right — a rule that scans tracked
lines cannot know a line is about removal, and teaching it to would make it
weaker for the one case that matters.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-09 23:09:18 -07:00
zeekay dff33d8048 move CI to the forge
The GitHub workflows are replaced by the canonical caller under .hanzo/workflows,
which is the only directory the forge collects. Every knob stays in /hanzo.yml, so
this file is the seven lines that name the shared reusable and nothing else -- the
same caller every other repo in the estate uses. GitHub Actions runs nothing here
now, by design.
2026-08-07 21:31:37 -07:00
zeekayandHanzo Dev e293abadc0 ci: canonical forge caller +removed dead .github caller
hanzo.yml declared a gate with nothing to run it: github.com has no runner for
hanzo-build-linux-amd64, so a caller under .github/workflows can never be
scheduled. This is the ~7-line caller on the plane that can, pinned @v1.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-06 01:17:04 -07:00
zeekayandHanzo Dev 472238ddb0 cd: the API is /v1, not /api/v1 — no /api prefix anywhere
House rule: /v1/ is the API prefix, everywhere, and /api/ is never added on
top of it. The api.* subdomain names the API; a path prefix restating it is
noise. This applies it to the whole route surface:

  /api/v1/*      -> /v1/*        106 proto annotations, 109 gateway patterns
  /api/version   -> /v1/version
  /api/badge     -> /v1/badge
  /api/webhook   -> /v1/webhook  (server + applicationset controller)
  /api/dex/*     -> /v1/dex/*    (constants; dex is built, not deployed)

The grpc-gateway .pb.gw.go files are generated, and the plugin toolchain is
not on this machine, so they were rewritten by a script that applies exactly
the transform codegen would: for /api/v1 paths, drop the leading "api"
literal-push opcode pair and decrement every LitPush(2,N)/Capture(5,N) pool
index; for /api/version, rename the segment. ConcatN(4,N) operands are
counts, not pool indexes, and are untouched. The .proto annotations moved in
the same commit, so the next real codegen run is a no-op against these files.

MustPattern panics at package init on a malformed pattern, so every rewritten
pattern is validated by any import of pkg/apiclient — those tests pass.

Also moved: assets/swagger.json (82 paths), the UI's two roots (apiRoot()
'/v1', version-service '/v1/version') and its two relative composers (app
logs download, badge panel), the five audit-pattern regexes in server.go, and
the tests that asserted the old paths. terminal_test's request URL claimed
/api/v1/terminal, a route that never existed — the handler is mounted at
/terminal; the fixture now says so.

NOT touched, deliberately: /api/v3 in GitHub Enterprise base-url examples
(GitHub's URL shape, not ours), util/vendored/kubeclientmetrics (parses the
KUBERNETES API server's /api/v1 paths), and util/http's cookie-path fixture
(arbitrary string exercising slash normalization).

go build ./... clean. Pre-existing failures in badge/session/webhook/account
tests reproduce identically on the parent commit (rebrand fallout — badge
colors, cookie name length, dex issuer) and are not made worse here.

External consumers checked: universe has zero references to cd.hanzo.ai/api;
the CLI speaks gRPC, not the REST gateway; UI and server ship in one image so
they move together.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-29 12:01:34 -07:00
zeekayandHanzo Dev 01713cf45b cd: drop the two informers the notification subsystem left behind
v3.6.0-.2 could not start. hanzocd-server crash-looped:

  fatal: Recovered from panic: nil pointer dereference
  server.(*ArgoCDServer).Init -> server/server.go:554

configMapInformer and secretInformer were declared on the struct and Run() in
Init(), but never assigned anywhere in the repo. b2d7140a (delete the
notification subsystem) removed their construction —

  secretInformer := k8s.NewSecretInformer(..., "cd-notifications-secret")
  configMapInformer := k8s.NewConfigMapInformer(..., "cd-notifications-cm")

— which fed api.NewFactory for notifications and nothing else. The fields and
the two Run() calls survived the deletion, so both were nil at boot.

Deleted rather than reconstructed: they watched notification config, and there
is no notification subsystem to configure. We use hanzoai/notify.

Worth naming the class, because it is the third time tonight: a nil interface
field is valid Go, so `go build ./...` passed clean and said nothing. Same
shape as the Register* seams and the mounted globals — it compiles, and it
yields the zero value.

The "secret key does not exist in secret" warning on the preceding line is
unrelated; hanzocd-secret carries all five keys and works on sha-e1b9244.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 22:49:35 -07:00
zeekayandHanzo Dev 50153bf5ab README: ours, not upstream's with the names swapped
The previous README was Argo CD's with Argo replaced by Hanzo, which put our
name on other people's work: "Unveil the Secret Ingredients of Continuous
Delivery at Enterprise Scale with Hanzo CD" is akuity's article about Argo CD,
and "Comparison of Hanzo CD, Spinnaker, Jenkins X, and Tekton" is inovex's.
Twenty-eight borrowed talks and posts, plus badges reading argoproj/argo-cd
release and coverage, an Artifact Hub link to their chart, their Twitter, Slack,
LinkedIn and Bluesky, their office hours calendar, their readthedocs, and a CNCF
Code of Conduct we are not governed by.

Replaced with what is actually true: what this fork changes (API group, binaries,
module, image, SSO, notifications), where it runs, how to build it, and that
releases are tagged rather than merged. Attribution to argoproj/argo-cd is kept
and made explicit — the engine is theirs; their community is not ours to claim.

Live demo link also dropped: it pointed at cd.apps.apps.hanzo.ai, a host that
does not resolve.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 22:42:05 -07:00
zeekayandHanzo Dev 92313665f5 fix(gitops-engine): the predicted-live fixtures kept the pre-rename manager
serverSideDiff finds the field set the CD controller owns by looking its manager
up by name. The live YAML fixtures were renamed to cd-controller; the
predicted-live JSON beside them still said argocd-controller, and the diff reads
both. Every server-side-diff case that asks "which fields are mine" failed with
"no managed fields found for manager: cd-controller" — not because the logic is
wrong, but because the two halves of the same fixture disagreed about who
applied it.

Seven JSON fixtures now name the same manager as the YAML they pair with.

pkg/diff goes green; the full gitops-engine module is 12/12.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 22:20:12 -07:00
zeekayandHanzo Dev 59287df3dd cd: label the image with OUR repo — that is why the package was private
The image carried LABEL org.opencontainers.image.source pointing at
github.com/argoproj/argo-cd, the upstream we forked from. GitHub links a
container package to the repo that label names; it cannot link to a repo outside
the org, so ghcr.io/hanzoai/cd was created UNLINKED, and an unlinked package
defaults to private. That is the whole reason v3.6.0 and v3.6.1 pushed fine and
could not be pulled:

  failed to fetch anonymous token: 401 Unauthorized

Confirmed by comparing against the packages that work — every one of them is
linked and public:

  deploy   public   repo=hanzoai/cd
  cloud    public   repo=hanzoai/ai
  cd       PRIVATE  repo=UNLINKED

So this was never a visibility setting someone forgot to flip; it was a stale
label doing exactly what it says. Fixing the label is the root cause, and it
keeps visibility derived from the repo rather than hand-set in a second place.

Also dropped the hanzocd-notifications symlink: the notification subsystem was
deleted in b2d7140a (we use hanzoai/notify), so the link pointed at a command
the binary no longer serves.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 22:18:34 -07:00
zeekayandHanzo Dev a4b4d9d842 fix(ui): the UI still speaks argoproj.io to a backend that speaks hanzo.ai
The Go side was renamed; the UI was not. It still compares resource groups
against 'argoproj.io' and writes argocd.argoproj.io/* annotations, so it and
the API no longer agree on what anything is called.

Worst of these is the finalizer. The controller injects and honors
resources-finalizer.apps.hanzo.ai; the create panel's cascade-delete checkbox
wrote resources-finalizer.argocd.argoproj.io. Ticking the box produced a
finalizer nothing reads — the user is told deletion will cascade, and it does
not. The live Applications already carry the apps.hanzo.ai form; only the UI
disagreed.

The group comparisons fail the same way, quietly: node.group === 'argoproj.io'
guards the ApplicationSet and Application branches in the resource tree,
detail panes, and extension tab lookup, and the backend now sends
apps.hanzo.ai, so those branches stopped being taken.

Values follow whichever constant owns them, rather than a blanket rename:

  sync-wave / hook / deletion-approved   cd.hanzo.ai/*   (gitops-engine sync
                                                          vocabulary)
  refresh / managed-by-url / link. /     apps.hanzo.ai/* (application_annotations
  notice. / pref. / group / apiVersion                    .go, common.go)

Untouched, because they are other people's CRDs and renaming them breaks
icon and subscription lookup for anyone running those products:
promoter.argoproj.io, notifications.argoproj.io.

tsc --noEmit clean; 22 suites / 263 tests / 32 snapshots pass.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 21:22:47 -07:00
zeekayandHanzo Dev 1ab6e799c1 cd: the module is github.com/hanzoai/cd, where it is actually hosted
go.mod still declared `module github.com/hanzoai/deploy` after the repo was
renamed. A Go module path is not cosmetic — it is the resolvable location. So
`go get github.com/hanzoai/cd` could not work, and anything importing this
module had to spell a name that no longer exists at that address. The build log
of v3.6.0 is where it surfaced: the compiler was still emitting
github.com/hanzoai/deploy/cmd/cd/commands.

3541 import paths across 690 .go, 19 .proto, 4 .yaml, 3 .sh, 2 .mod, Procfile
and Makefile. Plus the 62 ghcr.io/hanzoai/deploy image references, moved to
ghcr.io/hanzoai/cd to match hanzo.yml's build target — a distinct string from
the module path, replaced separately so neither could clobber the other.

go mod tidy clean, CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ./... clean.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 21:16:24 -07:00
zeekay 2b27b331cd cd: the image is ghcr.io/hanzoai/cd, like everything else it builds
The repo is cd. The binaries are cd-*. The API group is apps.hanzo.ai, the
annotations are cd.hanzo.ai, the UI is cd.hanzo.ai. hanzo.yml was the last
place still saying `deploy` — the name from before the rename — so the
canonical build would have pushed the renamed engine to the old package.

universe infra/k8s/hanzo-cd/README.md has documented the engine as
ghcr.io/hanzoai/cd all along; this is the build target catching up to the
doc, not a new decision.

Also corrected in passing: the header still described the image as building
`notifications`, deleted in b2d7140a (we use hanzoai/notify), and still
called the repo hanzoai/deploy.
2026-07-28 18:00:40 -07:00
zeekayandHanzo Dev 6c42f1e6f0 docs: the CRD API version migration order, and the incident that proves it
Removing v1alpha1 before deploying the binary that speaks v1 took the control
plane down on 2026-07-28: the running controller listed *v1alpha1.Application
against an API that no longer served it, CrashLooped, and 65 Applications plus
the ApplicationSet were lost.

The workloads survived only because the resources-finalizer never fired, and
recovery was possible only because everything was reconstructible from git.

Every CRD migration step was individually correct. The unchecked thing was
which version the running consumer speaks.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 17:24:55 -07:00
zeekayandHanzo Dev 6dc1eb9daa merge: cd.hanzo.ai annotations, apps.hanzo.ai API group
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:32:14 -07:00
zeekayandHanzo Dev 446e343a3d cd: annotations are cd.hanzo.ai, API group is apps.hanzo.ai
Two corrections on top of the naming pass, both found by checking the live
cluster rather than the source.

The rename had silently changed the user-facing annotation key from
argocd.argoproj.io/sync-wave to cd.argoproj.io/sync-wave — 63 live
Applications carry the old key, so deploying that would have ignored every
sync-wave and broken fleet deploy ordering. The key is now cd.hanzo.ai/*,
and universe 575650286 moves the ApplicationSet template that stamps it, so
the controller regenerates all 63 consistently.

The API group in code said argoproj.io/v1alpha1 in 157 places while the
cluster has served apps.hanzo.ai/v1alpha1 since 2026-07-23 (the CRDs are
applications.apps.hanzo.ai). Code now matches what is actually served.

The legacy applications.argoproj.io/app-name label had ZERO live users, so it
went with the rest. foo.argoproj.io test fixtures became foo.example.com —
arbitrary test domains should not carry a vendor name.

go build ./... exit 0.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:32:14 -07:00
zeekayandHanzo Dev d5bf5ce77e merge: delete the notification subsystem, argoproj deps now zero
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:21:15 -07:00
zeekayandHanzo Dev b2d7140a0e cd: delete the notification subsystem — we use hanzoai/notify
The last argoproj dependency. notifications-engine was 49 files / 920K and
backed a subsystem with ZERO live workloads and ZERO Applications carrying
notification annotations, while hanzoai/notify v1.7.2 is already embedded in
cloud. Two ways to notify, one of them dead and pulling a dependency.

Deleted: cmd/cd-notification, notification_controller/, server/notification/,
util/notification/, the admin CLI command, hack/gen-catalog (generated the
service catalog), the gen-docs notification pass, and the wiring in
server.go and cmd/main.go.

github.com/argoproj now appears ZERO times in go.mod. Both live argoproj
dependencies are gone — pkg/v2 internalized in the previous commit,
notifications-engine deleted here.

go build ./... exit 0.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:21:05 -07:00
zeekayandHanzo Dev 4bbbd0aea9 merge: internalize argoproj/pkg
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:08:46 -07:00
zeekayandHanzo Dev b726a55cab cd: internalize the five argoproj/pkg utilities, drop the dependency
github.com/argoproj/pkg/v2 was one of two live argoproj dependencies. It is
11 files and 176K total, and we used five packages from it: grpc/http,
kubeclientmetrics, stats, sync, time.

Vendored into util/vendored/ and the dependency dropped from go.mod, so the
gRPC surface (2 references, in grpc-http/forwarders.go) is now ours to remove
on our own schedule rather than upstream's. Kubernetes client-go pulls gRPC
transitively regardless, so this is isolation — a realistic first step — not
a claim that gRPC is gone.

Internalized rather than forked to a shared repo because the only other
consumer, hanzo/gitops, has zero live deployments and zero dependents. A
second repo would be a second thing to version for one caller.

NOTICE carries the Apache-2.0 attribution. go build ./... exit 0.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:08:34 -07:00
zeekayandHanzo Dev 6baf135aff merge: the credential interface is DB
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:04:30 -07:00
zeekayandHanzo Dev bc6d960ad4 cd: the credential store interface is DB, not ArgoDB
The last Argo in the core type surface. It is also the seam that matters for
going KMS-native: repo- and cluster- credentials are read through ONE
interface with ONE constructor (NewDB), so a KMS-backed store is a second
implementation, not a rewrite of the 26 files that touch Secrets.

go build ./... exit 0.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:04:24 -07:00
zeekayandHanzo Dev 8fe15c535c merge: kill the argo naming
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:00:32 -07:00
zeekayandHanzo Dev 84ee9fa0ce cd: kill the argo naming — binaries, packages, identifiers
Every command is cd-*: cd, cd-server, cd-repo-server,
cd-application-controller, cd-applicationset-controller, cd-cmp-server,
cd-commit-server, cd-dex, cd-git-ask-pass, cd-k8s-auth, cd-notification.
util/argo is util/cd; util/notification/argocd is util/notification/cd.

Preserved deliberately: github.com/argoproj/argocd-example-apps is an
EXTERNAL repo used as an e2e fixture, and notifications-engine + pkg/v2 are
real dependencies. Renaming a URL we do not own would break the tests.

Two bugs I made and caught, both from a careless sed:
- s/argo/cd/g turned 'argocd' into 'cdcd' in two directory names
- renaming the package declaration left every call site saying argo.X

go build ./... exit 0.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:00:25 -07:00
zeekayandHanzo Dev a30bce2e1b merge: CD_ and KV_ vocabulary
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 15:55:46 -07:00
zeekayandHanzo Dev dead2da249 cd: the configuration speaks CD_ and KV_
The fork was already ours everywhere that matters — our image, our IAM (dex
is not deployed), hanzo kv behind what the env still called REDIS. Only the
vocabulary was upstream's: ARGOCD_* across the Go, the manifests, the docs
and the plugin contract, and mkdocs still titled 'Argo CD' pointing at
argoproj/argo-cd.

ARGOCD_ -> CD_ and REDIS_ -> KV_ across 345 files, plus the 8 e2e/cmp
fixtures that assert the plugin env contract — those had to move with the
binary, which now emits CD_APP_NAME where they expected ARGOCD_APP_NAME.

Left alone deliberately, because renaming them would be wrong:
- util/helm/testdata/redis/ and gitops-engine/.../statefulset*.yaml are
  fixtures for a THIRD-PARTY chart named redis, not our config
- util/kustomize/testdata/ likewise
- generated.proto regenerates from types.go, which is already clean

go build ./... exit 0.

LOCKSTEP: the live StatefulSet sets 47 ARGOCD_* names the binary no longer
reads. universe 4a5375735 carries the matching manifest change; they deploy
together or the controller falls back to defaults.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 15:55:46 -07:00
zeekayandHanzo Dev b868dedac3 chore(go): bump go directive to 1.26.5
Carried off the legacy master branch before deleting it. master was the
pre-fork upstream line — it still declared Group = "argoproj.io" and
AnnotationKeyAppInstance = "argocd.argoproj.io/tracking-id", which is exactly
the identity being purged from this fork, so the branch itself had to go.

Its only two commits were this bump and a NOTICE attributing Argo CD upstream.
main already carries that NOTICE (Apache-2.0 attribution intact), so this line
was the sole thing that would have been lost. go build ./... exits 0 on 1.26.5.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 22:58:21 -07:00
zeekayandHanzo Dev dbecd2d18b fix: API group back to apps.hanzo.ai, the group the cluster actually serves
main declared Group = "cd.hanzo.ai" while every CRD, all four Applications and
every tracked object in hanzo-k8s are on apps.hanzo.ai. There are no
cd.hanzo.ai CRDs anywhere, so a build from main binds nothing: the controller
comes up healthy, watches a group with no resources, and silently stops
reconciling the fleet. The deployed image (sha-e1b9244, all three components)
is the only reason this has not fired.

The rename reached further than the group. common.go:215 moved the ownership
annotation to cd.hanzo.ai/tracking-id while live objects carry
apps.hanzo.ai/tracking-id, and the finalizers moved too
(resources-finalizer.cd.hanzo.ai), which would leave existing objects holding
finalizers no running controller removes. Renaming a CRD group plus the
ownership annotation plus the finalizers is a data migration over every managed
object, not a source edit — shipping it as an edit is the defect. Reverting
restores the property that was lost: main is deployable at any time.

Mitigating only by luck: prune is false on all three automated Applications, so
the failure mode is "GitOps stops" rather than "GitOps deletes". Not a design.

Verified: no occurrence was a hostname (checked for the argocd.hanzo.ai-style
substring trap; none), 29 files, zero residual, register.go now byte-identical
to the deployed baseline. go build ./... exits 0. TestGetGlobalProjects and
TestGetAppOfAppSummary fail identically on unmodified origin/main — pre-existing,
not from this change.

If cd.hanzo.ai is still wanted, it needs CRD install, object conversion,
annotation and finalizer rewrite across every tracked resource, and RBAC —
executed deliberately, not carried in a source constant.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 21:28:51 -07:00
zeekayandHanzo Dev 0e5b4cd361 NOTICE: attribute the upstream this is forked from
The repo carries the upstream LICENSE but no NOTICE, so nothing states which
project the code derives from or who holds copyright on it. Added in the same
form the other forks here use.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 10:47:57 -07:00
zeekay d7c115c4f3 ci: drop the Gitea mirror-sync nudge
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.
2026-07-27 10:26:43 -07:00
zeekay f8c5c6c95a ci: nudge git.hanzo.ai to pull on push
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.
2026-07-27 08:10:44 -07:00
zeekay c1f5a7fc98 ci: remove GitHub CI — native git.hanzo.ai + cd.hanzo.ai only
This workflow ran on a self-hosted actions-runner-controller pool. ARC is
decommissioned: CI executes inside git.hanzo.ai (Gitea Actions, .hanzo/workflows)
and delivery is cd.hanzo.ai reconciling the reviewed image pin in
hanzoai/universe. GitHub is a mirror and runs nothing.

Removed rather than repointed — there is no GitHub-side pool to move to, and
leaving it would keep ARC load-bearing.
2026-07-27 07:57:39 -07:00
zeekay 551ac14534 ci: remove GitHub CI — native git.hanzo.ai + cd.hanzo.ai only
This workflow ran on a self-hosted actions-runner-controller pool. ARC is
decommissioned: CI executes inside git.hanzo.ai (Gitea Actions, .hanzo/workflows)
and delivery is cd.hanzo.ai reconciling the reviewed image pin in
hanzoai/universe. GitHub is a mirror and runs nothing.

Removed rather than repointed — there is no GitHub-side pool to move to, and
leaving it would keep ARC load-bearing.
2026-07-27 07:57:38 -07:00
zeekay a11e7ea9b8 merge(rebrand/hanzocd-manifests): hanzocd-* object naming on the cd.hanzo.ai group 2026-07-26 14:33:26 -07:00
zeekay 72e91e984f merge(main): adopt cd.hanzo.ai API group under hanzocd-* object naming
origin/main renamed the API group apps.hanzo.ai -> cd.hanzo.ai (apps.hanzo.ai
collided with the operator's App CR) but only in the overlays and CRDs; this
branch had renamed every object argocd-* -> hanzocd-* and regenerated the flat
install manifests against the old group.

Resolution keeps both axes orthogonal: the group is cd.hanzo.ai everywhere (it
must match common.go and the applicationset leader-election ID), the object
naming/labels stay hanzocd-* / part-of: hanzocd so the settings informer finds
its config. The generated install manifests are re-synced to the resolved
overlays, which also carries the group rename that upstream left out of them.

Go tree is byte-identical to origin/main.
2026-07-26 14:29:48 -07:00
zeekay 2ee31f825c rebrand: API group apps.hanzo.ai -> cd.hanzo.ai
apps.hanzo.ai collided head-on with the operator: its App CR already occupies
the resource name `apps.hanzo.ai` (plural `apps`, group `hanzo.ai`), so
`kubectl get apps.hanzo.ai` resolved to the operator's CR, not ours, and
`applications.apps.hanzo.ai` read as a stutter. cd.hanzo.ai gives the delivery
plane its own orthogonal group: applications/applicationsets/appprojects.cd.hanzo.ai
alongside the operator's apps.hanzo.ai. One name per concern.

Mechanically identical to e1b924475 (deploy.hanzo.ai -> apps.hanzo.ai): group
constant, every annotation/label/finalizer domain, the node.Group check, the
leader-election ID, the informer GVRs, RBAC apiGroups, and the 3 CRD manifests.
Also corrects the stale `+groupName=argoproj.io` marker in doc.go, which drove
nothing but misled every reader of this package, and the ArgoCD/argoproj naming
in the hanzo.yml cutover note.

Live cutover (CRD apply, CR re-home, image swap) stays separately greenlit —
hanzo.yml is deliberately build-only.
2026-07-25 15:11:48 -07:00
zeekay ebfbd67854 refactor(manifests): finish apps.hanzo.ai group + hanzocd-* object naming
The server image expects the apps.hanzo.ai API group (register.go), hanzocd-*
config object names (common.go ArgoCDConfigMapName=hanzocd-cm, ...), and a
settings informer that selects app.kubernetes.io/part-of=hanzocd. The base
manifests still emitted argocd-* object names, part-of: argocd, and the stock
quay.io/argoproj/argocd image, so a fresh render produced config/RBAC the
running server cannot find (informer misses part-of=argocd config; server reads
hanzocd-cm but manifest creates argocd-cm) and would run the upstream image.

- Rename every object name and file argocd-* -> hanzocd-* (SA/Role/RoleBinding/
  ClusterRole/ClusterRoleBinding/Service/Deployment/StatefulSet/ConfigMap/Secret/
  NetworkPolicy), referential integrity preserved (roleRef/subjects/selectors/
  configMapRef).
- Flip app.kubernetes.io/part-of: argocd -> hanzocd so the settings informer
  finds the config objects.
- Point the image at ghcr.io/hanzoai/deploy (kustomize image transform +
  container image refs).
- Match the hanzocd-cm ignoreResourceUpdates keys for the CD's own Application to
  apps.hanzo.ai (argoproj.io_Application -> apps.hanzo.ai_Application; refresh/
  hydrate annotation domains). External argoproj.io_Rollout / rollout.argoproj.io
  / notifications refs are left as-is.
- Drop the vestigial argoproj.io workflows create grant from hanzocd-server
  ClusterRole (no Argo Workflows in this install).
- Regenerate the flat install manifests (install/namespace-install/core-install
  and hydrator variants) from the corrected overlays.

RBAC now grants apps.hanzo.ai on applications/applicationsets/appprojects for
hanzocd-server and hanzocd-application-controller, so a fresh deploy keeps the
running apps.hanzo.ai server up. CRDs unchanged in group/kind/version (match the
live apps.hanzo.ai CRDs). Image-internal paths (/home/argocd, /usr/local/bin/
argocd) match the built image and are unchanged.
2026-07-22 20:33:31 -07:00
zeekayandHanzo Dev e1b924475c rebrand: API group deploy.hanzo.ai -> apps.hanzo.ai
The CRD kind is Application, so apps.hanzo.ai reads naturally
(applications/applicationsets/appprojects.apps.hanzo.ai). Flips the group
constant (pkg/apis/application/register.go), all annotation/label/finalizer
domains (tracking-id, installation-id, secret-type, refresh, hydrate,
resources-finalizer, etc.), the node.Group check, and the 3 CRD manifests.
Module path github.com/hanzoai/deploy and hanzocd-* object names unchanged.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-22 19:15:05 -07:00
zeekayandHanzo Dev fd3803d83c rebrand: askpass binary-name dispatch override -> hanzocd-git-ask-pass
The askpass server sets GIT_ASKPASS=hanzocd + ARGOCD_BINARY_NAME=argocd-git-ask-pass;
cmd/main.go dispatches on ARGOCD_BINARY_NAME (env override) matched against
common.CommandGitAskPass. The rebrand moved the constant to hanzocd-git-ask-pass but
this hardcoded override value stayed argocd-git-ask-pass -> no match -> fell through to
the main CLI -> cobra tried to exec a plugin 'argocd-Username...' -> git auth failed.
Point the override at hanzocd-git-ask-pass. No symlink needed (dispatch is env-driven).

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-22 18:22:22 -07:00
zeekayandHanzo Dev 65db5708b3 rebrand: runtime binary refs argocd -> hanzocd (git askpass, CLI lookup, config dir, session issuer)
The git credential askpass hardcoded GIT_ASKPASS=argocd (util/askpass/server.go),
but the rebuilt image ships /usr/local/bin/hanzocd — so 'git fetch' failed with
'cannot run argocd' -> 'could not read Username for github.com' -> repo-server
could not render manifests. Point it (and the web-terminal LookPath, CLI config
dir, and session issuer) at hanzocd. This is the last runtime argocd binary ref.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-22 18:09:19 -07:00
zeekayandHanzo Dev b5c1098378 rebrand: white-label served surfaces in library packages -> Hanzo CD
Extends the served-surface sweep into controller/reposerver/applicationset/
commitserver/cmpserver/notification_controller/util/pkg: git commit author
name ("Argo CD" -> "Hanzo CD"), TLS certificate Organization fields, user/API
error messages, and operator log banners. Identifiers, env vars, argocd-*
names, argoproj.io/argocd label values, and testdata/examples left intact.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-22 17:58:58 -07:00
zeekayandHanzo Dev 14d5f97186 rebrand: white-label served surfaces Argo CD -> Hanzo CD
Sweep residual upstream brand from Hanzo-served surfaces (UI, CLI, API docs,
notifications). Imports, identifiers, env vars, and k8s object/command names
are left intact.

- UI: HelpIcon tooltips, help-page + cluster-management doc links ->
  docs.hanzo.ai, login + sidebar logos -> hanzo-logo-white.svg (alt text +
  broken Argo.svg / logo.png refs), rendered "Argo CD" -> "Hanzo CD"
- CLI (cmd/, server/): Short/Long/Example/flag help + "ArgoCD API Server"
  startup banner -> Hanzo CD
- API: .proto service-doc comments + generated assets/swagger.json -> Hanzo CD
- notification controller comment

Preserved (imports / identifiers / contracts): module github.com/hanzoai/deploy,
ARGOCD_* env vars, argocd-* binary/command names, ArgoCD* Go identifiers,
argoproj.io/argocd label values, argo-* CSS classes, k8s object names.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-22 17:56:24 -07:00
zeekayandHanzo Dev ee12fac6f6 rebrand: settings informer selects part-of=hanzocd (not argocd)
The config-map/secret settings informer filtered on a HARDCODED literal
'app.kubernetes.io/part-of=argocd' (util/settings/settings.go partOfArgoCDSelector
+ isSettingsObject), not a common.go constant — so the rebuilt binary could not
discover hanzocd-cm/hanzocd-secret labeled part-of=hanzocd and fatal-crashed with
'configmap "hanzocd-cm" not found'. Point the selector + the admin cluster/repo
secret labels at part-of=hanzocd. Completes the operational rebrand.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-22 17:39:52 -07:00
zeekayandHanzo Dev 7d8538143f ci(image): GHCR-only build — drop quay tag/login (no quay creds on this fork)
set-vars always emitted quay_image_name, so the quay docker/login-action ran with
empty RELEASE_QUAY_* secrets → 'Username and password required' failed the build.
Empty quay_image_name skips the quay login and drops quay from TAGS; GHCR push
uses github.actor + GITHUB_TOKEN (packages: write).

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-22 14:29:51 -07:00
e84f1d4806 rebrand: finish hanzocd operational layer (drop argocd.argoproj.io + argocd-* names) (#3)
The API group was already deploy.hanzo.ai, but the operational layer still
emitted upstream argocd naming, blending two brands on the live controller:

- annotation/label/finalizer domain argocd.argoproj.io -> deploy.hanzo.ai
  (tracking-id, installation-id, secret-type, refresh, hydrate, compare-options,
   skip-reconcile, ignore-*, finalizer)
- config-object + component + service-address names argocd-* -> hanzocd-*
  (cm, secret, rbac-cm, cmd-params-cm, tls-certs-cm, ssh-known-hosts-cm,
   gpg-keys-cm, notifications-cm/secret, server, repo-server,
   application-controller, redis, redis addr)
- argv[0] multi-call dispatch names + Dockerfile symlinks argocd-* -> hanzocd-*
  (CommandCLI "argocd" -> "hanzocd"; symlinks match the renamed constants)
- Makefile CLI_NAME/BIN_NAME -> hanzocd

Intentionally upstream-compatible (unchanged, so future argo-cd merges stay
clean): the Go module path, cmd package layout, Docker build-stage aliases,
build-target names, and the runtime uid. These are invisible to ops/kubectl.

Co-authored-by: z <[email protected]>

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-22 14:23:49 -07:00
15d87b3e72 refactor(cd): hard-fork - rename CRD API group argoproj.io -> deploy.hanzo.ai (#1)
* feat(api): hard-fork CRD API group argoproj.io -> deploy.hanzo.ai

Hanzo CD hard-fork, phase 1.1. Single source of truth is
pkg/apis/application/register.go's Group constant (Application/AppProject/
ApplicationSet all derive their FullName from it); every other Go call-site
that hardcoded the literal group string is updated to match: the 3 generated
informer GVRs, the app-of-apps nested-Application detector in types.go, the
resource-tree Application-kind cache populator, the 3 NotFound error
constructors in server/application, and the applicationset-controller's
leader-election Lease name/ID (kept in lockstep across Go source + RBAC
resourceNames, or leader election would get RBAC-denied on startup).

CRD YAMLs (application/appproject/applicationset) and every RBAC apiGroups
rule that actually governs our 3 CRDs are repointed to deploy.hanzo.ai, across
both manifests/base/* (namespaced Roles) and manifests/cluster-rbac/* (cluster
scope). Two adjacent things that share the "argoproj.io" string but are NOT
ours are deliberately left untouched: gitops-engine's health-check dispatch
for Argo Workflows' `Workflow` kind, and argocd-server-clusterrole's second
apiGroups block granting read on Argo Workflows' `workflows` resource — both
belong to a separate, unrelated Argoproj-family project we are not forking.

Also untouched, per explicit scope: annotation/label keys (argocd.argoproj.io/*)
and finalizers (*.argoproj.io) that track already-applied live resources, and
argocd-cm.yaml's resource.customizations.ignoreResourceUpdates keys (a narrow
app-of-apps diffing nicety, not build- or RBAC-relevant).

CGO_ENABLED=0 go build ./... verified green.

* ci: wire canonical hanzo.yml + cicd.yml (Hanzo CD image build)

Phase 1.3. Follows the same one-way pattern every hanzo/lux/zoo repo uses:
hanzo.yml declares the image (root Dockerfile -> ghcr.io/hanzoai/deploy) and a
fast go-build sanity test (the multi-stage Dockerfile build is the slow, real
gate); cicd.yml is the ~10-line trigger shim importing hanzoai/ci's reusable
build workflow on the arc pool, secrets from KMS only.

No `deploy:` block yet, matching the hanzoai/cms build-only-first-cutover
pattern: this repo's own live hanzo-cd namespace runs the whole Hanzo fleet's
GitOps, so the prod image/CRD swap is a deliberate separate action (see the
[HELD] universe PR), never an automatic rollout on merge. Every PR/push still
builds and pushes an immutable ghcr.io/hanzoai/deploy:sha-<7>-amd64 image.

* feat(ui): rebrand Argo CD -> Hanzo CD (title, favicon, logo, sidebar)

Phase 1.2. User-facing "Argo CD"/"ArgoCD" text replaced with "Hanzo CD"
across the login page, help modal, settings screens, version-info panel,
sync-options warning, fullscreen-logs title, app.tsx page titles, and
index.html's <title>/noscript text (dropped the now-wrong upstream CLI
doc link rather than invent a hanzo.ai URL that doesn't exist).

Logo/favicon assets replaced with the canonical Hanzo mark (never
hand-drawn, copied from ~/work/hanzo/logo/dist): the two real usages of
Argo's logo collapse onto one Hanzo glyph (mono + white variants) at the
same 5 call sites (login icon + footer, login.scss $logoPath/
$logoNegativePath, sidebar text-logo), preserving the existing CSS
invert() filters so both the light login panel and dark sidebar still
render correctly. Old argologo.svg/argo_o.svg/argo.png deleted (no
longer referenced). favicon-{16x16,32x32}.png added at
ui/src/assets/favicon/ (index.html's links to that path were previously
dead - the directory didn't exist in this checkout). package.json name
argo-cd-ui -> hanzo-cd-ui.

Left alone, deliberately: the two Kubernetes resource-kind icon sets
under ui/src/assets/images/resources/ (unrelated to branding), and
upstream doc/project links (argoproj.io, argo-cd.readthedocs.io) since
we have no equivalent hanzo.ai docs to point to yet - except the login
footer logo's outbound link, which now points to hanzo.ai instead of
argoproj.io (a Hanzo-branded mark linking to the upstream project it
was forked from read as an obvious leftover).

* feat(module): rename Go module github.com/argoproj/argo-cd/v3 -> github.com/hanzoai/deploy

Phase 2. No version suffix on the new path (org policy: never publish our
own Go modules above v1.x.x / with a v2+ suffix) — this fork starts a fresh
v0/v1 module identity rather than carrying the v3 the upstream fork point
had reached.

Mechanical, symmetric rewrite: 704 .go files (import statements only; two
disjoint substitutions applied specific-first so the nested gitops-engine
module path never double-matches), plus go.mod (module line, the
gitops-engine require+replace pair, version reset to v0.0.0-... since a
suffix-less path can't carry a v3 semver), gitops-engine/go.mod, Makefile
(ldflags PACKAGE + 2 TEST_MODULE filters), .golangci.yaml, .goreleaser.yaml,
.mockery.yaml (+ gitops-engine's), Procfile, the codegen/proto generation
scripts (hack/generate-proto.sh, update-codegen.sh, update-openapi.sh), and
20 .proto files' go_package options. Also one OpenTelemetry tracer name
string in gitops-engine/pkg/sync/sync_context.go (a cosmestic label, not an
import, but worth keeping consistent).

CGO_ENABLED=0 go build ./... verified green for both the root module and
the nested gitops-engine module; go vet clean on both; go mod tidy run
(network available) to reconcile go.sum, dependency set unchanged.

Left alone, deliberately: doc-only mentions (docs/snyk/*.html scan reports,
gitops-engine/README.md), a comment-only reference in
.github/workflows/release.yaml, and one Renovate bot config line — none are
build- or codegen-load-bearing. Also left alone: comments citing upstream
GitHub issue URLs (github.com/argoproj/argo-cd/issues/NNNNN) and a handful
of test fixtures using "https://github.com/argoproj/argo-cd.git" as a
representative example repo URL — both are accurate historical/test-data
references, not stale self-references.

---------

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-19 11:27:06 -07:00
zeekay 24f4758c93 ci(deploy): register cd-ui workflow (builds ghcr.io/hanzoai/cd-ui monochrome dashboard SPA on hanzoai/spa) 2026-07-18 14:22:16 -07:00
zeekay 8f34610cbd ci(deploy): register deploy-ui-embed workflow (builds ghcr.io/hanzoai/deploy-ui-embed monochrome UI) 2026-07-18 12:41:18 -07:00