Merge feat/per-app-cmd-binaries: subsystems/ -> apps/ rename + per-app cmd binaries

# Conflicts:
#	apps/wire_seams.go
This commit is contained in:
2026-07-15 09:39:39 -07:00
100 changed files with 1750 additions and 37 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ package under `clients/<name>` that obeys these seams — nothing more.
types.CommerceClient` (`GetOrgConfig` + `CheckEntitlement`). Consumers depend on
the interface, never the implementation; the seam rides zap-proto/zip. Keep each
interface minimal — add a method only when a consumer needs it.
- **Composition root.** `subsystems/subsystems.go` blank-imports every subsystem
- **Composition root.** `apps/apps.go` blank-imports every subsystem
(its init runs `cloud.Register`), populating `cloud.Registry`. `MountAll`
(build.go) sorts the registry by `Order` and calls `Mount` on each ENABLED
subsystem (`cfg.Enabled`). That ordered blank-import set IS the wiring — there
+22 -2
View File
@@ -1,6 +1,7 @@
// Package subsystems is the composition root: the single, explicit list of which
// Package apps is the composition root: the single, explicit list of which
// Hanzo cloud subsystems are linked into the binary AND the order they mount in.
//
//go:generate go run ../cmd/gen-app-cmds
// Wire() returns []cloud.MountSpec in mount order (slice position == order). There
// is no init()-registry and no order-int: adding, removing, or reordering a
// subsystem is a one-line edit to Wire(), read top-to-bottom. cmd/cloud and
@@ -27,7 +28,7 @@
// composition root fixes). They are wired back at their order-int slots — o11y-ext
// kept adjacent to the in-repo o11y read-plane (@69); ai as the last /v1/* catch-all
// before plugins (@900). Do not re-sort; edit positions deliberately.
package subsystems
package apps
import (
"context"
@@ -346,6 +347,25 @@ func Wire() []cloud.MountSpec {
}
}
// ServeSingle is the ONE way to run a single app standalone: validate `name`
// against Wire(), then serve exactly it (cloud.Serve with a one-name enable
// list — MountAll mounts only it). It is the path `hanzo <name>` already uses;
// promoting it here lets each cmd/<app>/main.go stub reuse it instead of
// re-implementing the dispatch, so adding an app in Wire() is still the one edit
// and its standalone binary comes for free (generated). Returns an error for an
// unknown name rather than booting a no-op.
func ServeSingle(name string) error {
if name == "" {
return fmt.Errorf("ServeSingle: empty app name")
}
for _, spec := range Wire() {
if spec.Name == name {
return cloud.Serve(Wire(), []string{name})
}
}
return fmt.Errorf("ServeSingle: unknown app %q — run `hanzo code ls`/`hanzo` for the list", name)
}
// mountMetrics adapts hanzoai/metrics into a cloud.MountFunc. Unlike the other
// externals, metrics declares its OWN narrow Deps (Logger, DataDir, Brand) and does
// not import hanzoai/cloud, so cloud.Typed cannot bridge it: the composition root
+1 -1
View File
@@ -13,7 +13,7 @@
//
// FAIL-SOFT. A broken Embed does NOT crash the binary: commerce degrades to a 503
// on its own prefixes while every co-resident subsystem stays up.
package subsystems
package apps
import (
"context"
@@ -1,6 +1,6 @@
// Copyright © 2026 Hanzo AI. MIT License.
package subsystems
package apps
import (
"io"
@@ -1,4 +1,4 @@
package subsystems
package apps
import (
"testing"
@@ -10,7 +10,7 @@ import (
// (cms/erp/help) against silent removal. They are not mount subsystems, so they
// never appear in Wire(); they register their DocTypes and — for erp — the
// ledger-posting lifecycle hooks into the framework engine from a package
// init(), reached ONLY via the blank imports in subsystems.go. #248 dropped
// init(), reached ONLY via the blank imports in apps.go. #248 dropped
// those imports, which stripped the erp ledger hooks from the binary with no
// mount change and no failing mount test. This asserts the engine's module
// registry carries each lane, so that money-adjacent regression cannot recur.
@@ -21,7 +21,7 @@ func TestFrameworkContentModulesLinked(t *testing.T) {
}
for _, want := range []string{"cms", "erp", "help"} {
if !got[want] {
t.Errorf("framework content module %q not registered — a blank import in subsystems.go is missing (erp drop = ledger hooks gone from the binary)", want)
t.Errorf("framework content module %q not registered — a blank import in apps.go is missing (erp drop = ledger hooks gone from the binary)", want)
}
}
// The module registry proves DocTypes are linked, but erp's ledger-posting
@@ -1,4 +1,4 @@
package subsystems
package apps
import (
"github.com/hanzoai/cloud/clients/coding"
@@ -1,4 +1,4 @@
package subsystems
package apps
import "testing"
+1 -1
View File
@@ -1,6 +1,6 @@
// Copyright 2026 Hanzo AI Inc. All Rights Reserved.
package subsystems
package apps
import (
"context"
+6 -6
View File
@@ -504,7 +504,7 @@ func EmitLifecycle(ctx context.Context, ev LifecycleEvent) {
// pickCommerceClient resolves deps.Commerce — the typed inter-subsystem client the
// entitlements/licensing tier calls (GetOrgConfig, CheckEntitlement). When the
// commerce subsystem is co-resident (Enabled("commerce")) it returns the IN-PROCESS
// client via the factory subsystems/commerce.go registers in init() — a direct Go
// client via the factory apps/commerce.go registers in init() — a direct Go
// call that reads the embedded commerce datastore (hanzoai/commerce MODULE, since
// the un-fork) + the @hanzo/plans vocabulary, no network hop (the HIP-0106
// co-resident default). The factory inversion stays because the concrete client
@@ -533,14 +533,14 @@ func pickCommerceClient(cfg *Config, log luxlog.Logger) CommerceClient {
}
// commerceClientFactory constructs the embedded in-process Commerce client.
// subsystems/commerce.go registers it in init(); pickCommerceClient calls it so
// apps/commerce.go registers it in init(); pickCommerceClient calls it so
// package cloud depends on the CommerceClient interface + this hook, never the
// concrete commerceinproc package (whose entitlement client pulls clients/plan,
// which imports cloud — the hook is what keeps the package graph acyclic).
var commerceClientFactory func(cfg *Config, log luxlog.Logger) CommerceClient
// RegisterCommerceClientFactory installs the embedded-Commerce client constructor.
// subsystems/commerce.go calls this from its init(); exactly one registration.
// apps/commerce.go calls this from its init(); exactly one registration.
func RegisterCommerceClientFactory(f func(cfg *Config, log luxlog.Logger) CommerceClient) {
commerceClientFactory = f
}
@@ -658,7 +658,7 @@ func pickVaultClient(cfg *Config, log luxlog.Logger) VaultClient {
// MountFunc is a subsystem's mount contract. app is `any`, not *zip.App, and that
// is load-bearing: some external modules expose Mount as func(any, Deps) error
// (e.g. hanzoai/licensing), which subsystems.Wire references DIRECTLY — a
// (e.g. hanzoai/licensing), which apps.Wire references DIRECTLY — a
// func(any,…) value is not assignable to a func(*zip.App,…) parameter, so
// narrowing the type would break them at compile time. The concrete value is
// always a *zip.App; strongly-typed Mounts (func(*zip.App, Deps) error, what every
@@ -688,7 +688,7 @@ func Typed(mount func(*zip.App, Deps) error) MountFunc {
type ShutdownFunc func(ctx context.Context) error
// MountSpec describes one subsystem to mount. There is NO Order field: the slice
// position in subsystems.Wire() IS the mount order — the composition root lists
// position in apps.Wire() IS the mount order — the composition root lists
// subsystems in the exact sequence they mount (and, reversed, tear down), so order
// is data read top-to-bottom in one file, not ints scattered across the tree.
type MountSpec struct {
@@ -703,7 +703,7 @@ type MountSpec struct {
}
// MountAll mounts every ENABLED subsystem in specs, in slice order — the order is
// the composition root's (subsystems.Wire()); MountAll does NOT sort. app is the
// the composition root's (apps.Wire()); MountAll does NOT sort. app is the
// concrete *zip.App from Serve; the MountFunc accepts it as `any` and in-repo
// subsystems recover it via Typed.
//
+1 -1
View File
@@ -39,7 +39,7 @@ import (
// drive the SAME single implementation. The subsystem is a stateless orchestrator over
// framework (which holds the state) + the AI/social edges — it opens no store of its own.
//
// Registration is a one-line cloud.MountSpec in subsystems.Wire() (after framework +
// Registration is a one-line cloud.MountSpec in apps.Wire() (after framework +
// knowledge, before the AI /v1/* catch-all); the module fixtures + lifecycle hooks are
// registered in doctypes.go's init(), process-global and mount-order-independent.
+1 -1
View File
@@ -83,7 +83,7 @@ issues SQL against it — column names are the coupling, so keep them in sync.
## Leaf wiring (register)
Register the leaf and blank-import it in `subsystems/subsystems.go`. It mounts
Register the leaf and blank-import it in `apps/apps.go`. It mounts
under the mount-all default (empty `CLOUD_ENABLE`) — the captable/sign/dataroom
folds are NOT staged (their standalone apps are retired/empty, so the one binary
is authoritative from first write):
+1 -1
View File
@@ -47,7 +47,7 @@ func masterKeyB64(t *testing.T) string {
}
// mountSpecs is the kms subsystem's composition-root entry, built locally so these
// tests mount exactly kms (the same spec subsystems.Wire() carries) without linking
// tests mount exactly kms (the same spec apps.Wire() carries) without linking
// the whole bundle. cfg.Enable still gates it, exactly as in production.
func mountSpecs() []cloud.MountSpec {
return []cloud.MountSpec{{Name: "kms", Mount: cloud.Typed(kms.Mount), OwnsHealth: true}}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the account-bridge app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("account-bridge"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the account app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("account"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the admin app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("admin"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the ads app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("ads"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the affiliates app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("affiliates"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the agents app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("agents"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the agentskills app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("agentskills"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the ai app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("ai"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the analytics app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("analytics"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the audit app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("audit"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the authors app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("authors"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the authz app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("authz"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the automations app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("automations"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the base app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("base"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the billing app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("billing"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the bot app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("bot"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the bots app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("bots"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the captable app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("captable"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the catalogsync app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("catalogsync"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+3 -3
View File
@@ -17,18 +17,18 @@ import (
"github.com/hanzoai/cloud"
// The subsystem set is defined ONCE in the subsystems bundle (shared with
// cmd/hanzo). subsystems.Wire() returns it in mount order; main threads that
// cmd/hanzo). apps.Wire() returns it in mount order; main threads that
// slice into cloud.Serve — the composition root, no init()-registry. Linking
// subsystems also links clients/o11y, whose init() registers the telemetry
// bootstrap cloud.Serve runs (cloud.RegisterTelemetryInstaller).
"github.com/hanzoai/cloud/subsystems"
"github.com/hanzoai/cloud/apps"
)
func main() {
// Telemetry is bootstrapped inside cloud.Serve (one site, every entrypoint —
// cmd/cloud AND every `hanzo <svc>`), so main() is just the full-surface
// entrypoint. nil ⇒ honor cfg.Enable from flags/env (empty = all subsystems).
if err := cloud.Serve(subsystems.Wire(), nil); err != nil {
if err := cloud.Serve(apps.Wire(), nil); err != nil {
fmt.Fprintf(os.Stderr, "cloud: %v\n", err)
os.Exit(1)
}
+6 -6
View File
@@ -2,7 +2,7 @@ package main
// Real integration tests for the unified Hanzo Cloud binary (HIP-0106).
// These exercise the actual orchestrator path — BuildDeps -> MountAll over
// subsystems.Wire() -> serve via the real zip/fiber + jsonenc stack —
// apps.Wire() -> serve via the real zip/fiber + jsonenc stack —
// not a hand-rolled smoke harness. app.Fiber().Test drives requests in-process,
// no listener or external services.
@@ -11,12 +11,12 @@ import (
"testing"
"github.com/hanzoai/cloud"
"github.com/hanzoai/cloud/subsystems"
"github.com/hanzoai/cloud/apps"
"github.com/zap-proto/zip"
"github.com/zap-proto/zip/middleware"
)
// every subsystem the unified binary wires must appear in subsystems.Wire() — this
// every subsystem the unified binary wires must appear in apps.Wire() — this
// is the proof Wire() actually assembles the whole matrix.
var wantSubsystems = []string{
"metrics", "base", "authz", "o11y",
@@ -24,14 +24,14 @@ var wantSubsystems = []string{
}
func TestRegistryAssemblesSubsystems(t *testing.T) {
wire := subsystems.Wire()
wire := apps.Wire()
got := map[string]bool{}
for _, s := range wire {
got[s.Name] = true
}
for _, name := range wantSubsystems {
if !got[name] {
t.Errorf("subsystem %q missing from subsystems.Wire()", name)
t.Errorf("subsystem %q missing from apps.Wire()", name)
}
}
t.Logf("Wire() assembled %d subsystems", len(wire))
@@ -52,7 +52,7 @@ func newTestApp(t *testing.T, enable ...string) *zip.App {
app.Use(middleware.Recover())
app.Use(middleware.RequestID())
app.Use(middleware.Logger(deps.Logger))
if err := cloud.MountAll(app, subsystems.Wire(), cfg, deps); err != nil {
if err := cloud.MountAll(app, apps.Wire(), cfg, deps); err != nil {
t.Fatalf("MountAll(%v): %v", enable, err)
}
return app
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the code app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("code"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the commerce app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("commerce"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the company app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("company"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the content app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("content"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the crm app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("crm"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the cron app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("cron"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the dataroom app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("dataroom"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the do app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("do"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the entitlements app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("entitlements"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the evals app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("evals"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the exec app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("exec"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the featureflags app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("featureflags"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the framework app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("framework"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the functions app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("functions"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the gateway app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("gateway"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+135
View File
@@ -0,0 +1,135 @@
// Command gen-app-cmds generates one cmd/<app>/main.go stub per app in apps.Wire
// so each app builds as its own standalone binary AND still mounts into the
// unified cloud binary. Adding an app in apps.Wire() is the one edit; this
// regenerates its cmd/<app> stub. Run via the go:generate directive in
// apps/apps.go: `go generate ./apps`.
package main
import (
"bytes"
"fmt"
"go/ast"
"go/parser"
"go/token"
"os"
"path/filepath"
"strings"
)
func main() {
// Resolve the repo root from this generator's own location (cmd/gen-app-cmds
// under it), so the tool works whether run from the repo root or via
// `go generate ./apps` (which runs it from apps/).
root, err := repoRoot()
if err != nil {
fmt.Fprintln(os.Stderr, "gen-app-cmds:", err)
os.Exit(1)
}
names := wireNames(filepath.Join(root, "apps", "apps.go"))
if len(names) == 0 {
fmt.Fprintln(os.Stderr, "gen-app-cmds: no apps found in apps.Wire()")
os.Exit(1)
}
// cmd/<app>/main.go is a thin stub: validate the app name, ServeSingle it.
// Generated, not hand-maintained — the app names come from apps.Wire(), the
// one source of truth. A re-run writes only when content would change, so
// it is idempotent.
const stub = `package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the %s app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle(%q); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
`
for _, name := range names {
dir := filepath.Join(root, "cmd", name)
if err := os.MkdirAll(dir, 0o755); err != nil {
fmt.Fprintln(os.Stderr, "gen-app-cmds:", err)
os.Exit(1)
}
path := filepath.Join(dir, "main.go")
want := fmt.Sprintf(stub, name, name)
if cur, err := os.ReadFile(path); err == nil && bytes.Equal(cur, []byte(want)) {
continue // idempotent: no change
}
if err := os.WriteFile(path, []byte(want), 0o644); err != nil {
fmt.Fprintln(os.Stderr, "gen-app-cmds:", err)
os.Exit(1)
}
fmt.Println("wrote", path)
}
}
// wireNames parses apps.go and returns the {Name: "..."} string literals from
// Wire()'s returned []MountSpec composite literal — the app names, in mount
// order. It is a light parse (no type-check), so it stays fast and depends only
// on the literal shape, which TestWireOrderMatchesFrozen already pins.
func wireNames(path string) []string {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, path, nil, parser.ParseComments)
if err != nil {
fmt.Fprintln(os.Stderr, "gen-app-cmds: parse:", err)
os.Exit(1)
}
var names []string
ast.Inspect(f, func(n ast.Node) bool {
fn, ok := n.(*ast.FuncDecl)
if !ok || fn.Name.Name != "Wire" {
return true
}
ast.Inspect(fn.Body, func(e ast.Node) bool {
kv, ok := e.(*ast.KeyValueExpr)
if !ok {
return true
}
key, ok := kv.Key.(*ast.Ident)
if !ok || key.Name != "Name" {
return true
}
lit, ok := kv.Value.(*ast.BasicLit)
if !ok || lit.Kind != token.STRING {
return true
}
names = append(names, strings.Trim(lit.Value, "\""))
return true
})
return false
})
return names // mount order, exactly as Wire() lists them
}
// repoRoot finds the module root by walking up from the working directory for
// a go.mod. It anchors both apps/apps.go (read) and cmd/<app>/ (write) so the
// tool works regardless of the CWD `go generate` hands it (it runs the generator
// from the package dir, apps/ — the executable itself lives under a throwaway
// /tmp/go-build cache with no go.mod ancestor, so CWD is the reliable anchor).
func repoRoot() (string, error) {
dir, err := os.Getwd()
if err != nil {
return "", err
}
for {
if _, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil {
return dir, nil
}
parent := filepath.Dir(dir)
if parent == dir {
return "", fmt.Errorf("no go.mod above %s", dir)
}
dir = parent
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the git app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("git"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the gitops app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("gitops"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the graph app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("graph"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the guide app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("guide"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+5 -5
View File
@@ -12,7 +12,7 @@
// the fused cloud control plane.
//
// Design — one mechanism, not many. The subsystem set is the explicit list
// subsystems.Wire() returns — []cloud.MountSpec in mount order (kms first-tier,
// apps.Wire() returns — []cloud.MountSpec in mount order (kms first-tier,
// iam 50, commerce 100, …, ai last), no init()-registry. A subcommand is just a
// *selection* over that slice:
//
@@ -74,9 +74,9 @@ import (
"github.com/hanzoai/iam/iamserver"
// The subsystem set is defined ONCE in the subsystems bundle (shared with
// cmd/cloud). subsystems.Wire() returns it in mount order; main threads that
// cmd/cloud). apps.Wire() returns it in mount order; main threads that
// slice through dispatch/usage/Serve. Inert at load — see THE BEEGO CRUX.
"github.com/hanzoai/cloud/subsystems"
"github.com/hanzoai/cloud/apps"
)
// version is overridden at build time via -ldflags "-X main.version=...".
@@ -102,8 +102,8 @@ func main() {
cli.Version = version
// The composition root's subsystem list, threaded through usage + dispatch +
// Serve. Defined ONCE (subsystems.Wire()); cloud never imports it (cycle).
specs := subsystems.Wire()
// Serve. Defined ONCE (apps.Wire()); cloud never imports it (cycle).
specs := apps.Wire()
if len(os.Args) < 2 {
usage(os.Stdout, specs)
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the iam app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("iam"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the ingress app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("ingress"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the integrations app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("integrations"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the kafka app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("kafka"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the kms app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("kms"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the knowledge app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("knowledge"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the licensing app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("licensing"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the marketing app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("marketing"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the marketplace app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("marketplace"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the metrics app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("metrics"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the ml app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("ml"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the notify app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("notify"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the o11y app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("o11y"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the paas app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("paas"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the plans app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("plans"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the platform app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("platform"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the plugins app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("plugins"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the pricing app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("pricing"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the product app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("product"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the projects app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("projects"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the prompts app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("prompts"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the provisioning app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("provisioning"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the pubsub app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("pubsub"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the referrals app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("referrals"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the sbom app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("sbom"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the security app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("security"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the settings app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("settings"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the sign app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("sign"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the social app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("social"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the storage app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("storage"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the tasks app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("tasks"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the team app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("team"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the templates app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("templates"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the tools app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("tools"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the tracker app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("tracker"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the treasury app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("treasury"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the usage app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("usage"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the visor app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("visor"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the wallets app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("wallets"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the websearch app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("websearch"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the world app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("world"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the x402 app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("x402"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the zen app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("zen"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"fmt"
"os"
"github.com/hanzoai/cloud/apps"
)
// Standalone entry for the zero-trust app — generated by cmd/gen-app-cmds (the
// go:generate directive in apps/apps.go). do not hand-edit; the app is the one
// edit in apps.Wire(), this binary is regenerated. The same app also mounts into
// the unified cloud binary via apps.Wire().
func main() {
if err := apps.ServeSingle("zero-trust"); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+2 -2
View File
@@ -19,7 +19,7 @@ tasks wave below, which had to reconcile with an in-flight `durable.go`).
The contract for a `mount`: a package exposing `Mount(app *zip.App, deps
cloud.Deps) error` that registers `/v1/<name>/*` and returns; registered in
`subsystems/subsystems.go` with an order < 150 (before ai's `/v1/*` catch-all).
`apps/apps.go` with an order < 150 (before ai's `/v1/*` catch-all).
Heavy/legacy HTTP frameworks (Beego, Gin) can be adapted with
`zip.AdaptNetHTTP`, but dragging their ORM/auth/DB substrate into this binary is
a rewrite, not a mount — see visor.
@@ -60,7 +60,7 @@ tasksvc, templates, visor, websearch, zt.
| Service | Reason |
|---|---|
| **iam** (`hanzoai/iam`) | Identity control plane; isolated blast radius by design (subsystems.go: "iam → iam.hanzo.ai, isolated control plane"). The binary CONSUMES it (JWT validation), never hosts it. |
| **iam** (`hanzoai/iam`) | Identity control plane; isolated blast radius by design (apps.go: "iam → iam.hanzo.ai, isolated control plane"). The binary CONSUMES it (JWT validation), never hosts it. |
| **gateway** (`hanzoai/gateway/v2`), **ingress** | The edge — they route *to* this binary. Traefik/krakend substrate; fusing the edge into the app defeats the tier separation. |
| **kms** (`luxfi/kms`, EMBEDDED) | KMS is now embedded in this binary (`clients/kms` store + `/v1/kms`, fail-closed) — the standalone KMS Deployment is collapsed into cloud. Only the MPC signing ring (`luxfi/mpc`) stays a separate node set, the root of trust. |
| **registry** (`hanzoai/registry`) | OCI distribution data plane (S3-backed fleet registry); a Docker registry protocol server, not a `/v1` control surface. |
+1 -1
View File
@@ -26,7 +26,7 @@ import (
// surface) and every `hanzo <svc>` subcommand share it; no boot logic is
// duplicated per entrypoint.
//
// specs is the composition root's subsystem list (subsystems.Wire()), threaded
// specs is the composition root's subsystem list (apps.Wire()), threaded
// in by the caller so cloud never imports subsystems (which would cycle). Serve
// mounts it in slice order and tears it down in reverse.
//