Skip to content

Serve the federated remote same-origin under the host shell (/apps/fuzeagent) instead of a public *.prod.fuzefront.com host #154

Description

@izzywdev

@claude

Why

The FuzeFront host shell loads this app's remote from the browser. It is currently registered as:

https://fuzeagent.prod.fuzefront.com/remoteEntry.js

That is a separate public hostname, so every load hairpins back out through Cloudflare. Worse, hosts under *.prod.fuzefront.com sit behind the Cloudflare Access admin wall, which answers an asset request with an HTML login page rather than JavaScript — the federation runtime then fails with Failed to fetch dynamically imported module, which reads like a build problem and is not one. This is exactly how the Quality tile broke.

Cluster-internal DNS cannot fix this: the browser cannot resolve *.svc.cluster.local, and prod terminates TLS at Cloudflare (ingress.tls.enabled: false), so redirecting *.prod.fuzefront.com in-cluster would break in-cluster https:// calls.

The fix, already landed for FuzeQuality in izzywdev/FuzeFront#701, is to serve the remote from the host shell's own origin at /apps/fuzeagent/* and proxy it in-cluster.

Acceptance criteria

  1. Ingress — add an Ingress in this app's own namespace (a k8s Ingress may only target a Service in its own namespace; Traefik watches all namespaces and merges rules per host) that:
    • serves host app.fuzefront.com, path prefix /apps/fuzeagent,
    • strips the /apps/fuzeagent prefix (Traefik Middleware of kind stripPrefix, referenced as <namespace>-<middleware-name>@kubernetescrd),
    • targets this app's frontend ClusterIP Service,
    • declares no tls: block — the shared host terminates TLS at Cloudflare, and a second cert claim for the same hostname would race cert-manager.
    • Gate it behind a values flag (federatedMount.enabled, default false; true only in values-prod.yaml).
  2. Build base — set Vite base: '/apps/fuzeagent/'. Without it remoteEntry.js loads and then every chunk it imports 404s against the host shell's own bundle. This is the single most common way this change appears to work and does not.
  3. Shared React must match the host EXACTLY{ react: { singleton: true, requiredVersion: '^19.0.0' } } and the same for react-dom. The bare shared: ['react','react-dom'] shorthand does not set singleton, which lets the remote load its own React copy and die on "Invalid hook call" in the browser with nothing in CI to catch it. FuzeQuality had exactly this drift.
  4. Registration manifest — update remoteEntry (or url for iframe) to the same-origin path /apps/fuzeagent/assets/remoteEntry.js. Verify scope and module match what the build actually emits (federation({ name }) and the exposes key) — FuzeQuality had these registered wrong and it would have stayed broken after the URL fix.
  5. Confirm the tile loads in the shell with a clean browser console (0 errors, 0 CSP/mixed-content violations).

Dependency / ordering

Gated on izzywdev/FuzeFront#701, which relaxes the frozen app-registry contract to accept a same-origin absolute path. Until that merges, a relative remoteEntry is rejected at registration. Do the Ingress + base + React work now; flip the registered URL once #701 is in.

Do not hand-deploy: prod is GitOps.

STATE

  • Done: nothing in this repo yet.
  • Remaining: all 5 acceptance criteria above.
  • Decisions already made (do not relitigate): same-origin path over per-app hostname; Ingress owned by the app's own chart, not the FuzeFront umbrella chart; relative path over absolute app-host URL.
  • Originating work: feat(app-registry): serve in-cluster federated remotes same-origin (no Cloudflare hairpin) FuzeFront#701 (branch claude/fuze-cluster-internal-dns-dbc111); reference implementation is FuzeQuality/deploy/helm/fuzequality/templates/ingress.yaml + FuzeQuality/apps/web/vite.config.ts in that PR.

If blocked, post @izzywdev BLOCKED: <question> with an updated STATE: block rather than idling. Finish with DONE: <PR link>.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions