ID-68 {68.13} A — Client-Branding Deploy-Overlay Design
ID-68 {68.13} A — Client-Branding Deploy-Overlay Design
Section titled “ID-68 {68.13} A — Client-Branding Deploy-Overlay Design”Type: Implementation design (companion to
PRE-FLIP-DEID-PLAN.md§2 A). Authored: 2026-06-03 (S301a-next) by the relocation Orchestrator. Status: DESIGN — the public-source removal (A steps 1–2) is implemented onid68-relocation-phase23; the overlay mechanism below is not yet built and is a hard pre-requisite of any deployed client build (see §5).
1. Problem
Section titled “1. Problem”PRE-FLIP-DEID-PLAN.md §2 A ratified “untrack → deploy-inject” for the first
client’s branding. As of this design:
git rm lib/branding/clients/phew.json+public/clients/phew/*(5 assets) — done.lib/client-config.tsno longer statically importsphew.json;CLIENT_BRANDING_MAPships{ default }only; the loader falls back todefault(verifiedloadBranding,?? CLIENT_BRANDING_MAP.default) — done.
So the public repo now carries only the generic default branding, and a client
deploy that sets NEXT_PUBLIC_CLIENT_ID=phew resolves default (loses branding) until
an overlay re-supplies the client config + assets. This document specifies that overlay.
2. Constraint that shapes the design
Section titled “2. Constraint that shapes the design”The pre-de-ID loader used static import + a hardcoded map entry. Webpack resolves
static imports at build time, so simply dropping a phew.json file back into
lib/branding/clients/ at deploy does not make the loader pick it up — nothing imports
it, and the map has no phew key. Therefore “data injection, mechanism unchanged” is only
literally true if the map is generated rather than hand-maintained, or the loader reads
the config dynamically by id. The overlay design must close this gap.
3. Options
Section titled “3. Options”| # | Mechanism | How the client build gets branding | Verdict |
|---|---|---|---|
| 1 — overlay + source patch | Deploy step copies phew.json into lib/branding/clients/ + assets into public/clients/phew/, and applies a codemod that re-adds the import + map entry to client-config.ts. | Re-introduces the exact pattern removed; brittle (source patching in CI). | ✗ interim only |
| 2 — codegen map (RECOMMENDED) | A build-time prestep globs lib/branding/clients/*.json and emits a generated client-branding-map.generated.ts consumed by client-config.ts. Public repo globs { default }; the client deploy drops phew.json (+ assets) via the overlay → the glob picks it up with no source edit. | Clean “data injection, mechanism preserved”; mirrors the existing inlined.generated.ts codegen idiom already in the repo. | ✓ |
| 3 — dynamic id-keyed read | Refactor the loader to read lib/branding/clients/${id}.json via a server-context fs read / Next dynamic import keyed by NEXT_PUBLIC_CLIENT_ID. | Works, but NEXT_PUBLIC_* is build-inlined and the JSON must still ship in the build context; more moving parts than codegen. | ◑ fallback |
Recommendation: Option 2 (codegen map). It keeps the loader, the schema validation, and
the brandAssetExists refine exactly as they are; the only change is that
CLIENT_BRANDING_MAP becomes generated from the directory contents rather than a
hand-maintained literal. The private overlay then only ever adds files (<id>.json +
public/clients/<id>/*) — never patches source.
4. Overlay delivery (where the client files come from)
Section titled “4. Overlay delivery (where the client files come from)”The client phew.json + 5 assets live in the private knowledge-hub-internal repo (or
a dedicated private client-overlays/ path). The client deploy pipeline:
- Checks out the public app repo.
- Overlays the private client files into
lib/branding/clients/phew.json+public/clients/phew/{logo.webp,logo-dark.png,logo-dark.svg,favicon.svg,favicon.png}. - Sets
NEXT_PUBLIC_CLIENT_ID=phew. - Runs the codegen prestep (Option 2) →
CLIENT_BRANDING_MAP = { default, phew }in the generated module. next build— schema + contrast validation +brandAssetExistsall run against the now-present files exactly as before.
The overlay source is the same private-repo bridge the operator-move ({68.12}) already
needs the installed GitHub App for, so no new credential surface.
5. Sequencing / risk (carry into the flip gate)
Section titled “5. Sequencing / risk (carry into the flip gate)”- Reversible now: on
id68-relocation-phase23(unmerged, undeployed) the public-source removal is safe — no deployed build consumes it yet. - Hard pre-req: the overlay mechanism (Option 2 codegen + the private overlay files +
the deploy step) MUST exist before the first client build deploys off the de-identified
HEAD — otherwise the client deploy renders with
defaultbranding. This is a named dependency of{68.9}flip → client redeploy, not of the worker-safe de-ID itself. brandAssetExistsonly runs for loaded configs; because the overlay supplies assets beforenext build, the refine stays green. No client-facing 404 risk introduced by the removal alone (the public build never loads a phew config).
6. Acceptance (for the future overlay-implementation subtask)
Section titled “6. Acceptance (for the future overlay-implementation subtask)”- Public
next buildwithNEXT_PUBLIC_CLIENT_ID=phewset but no overlay present → resolvesdefault, build green (today’s behaviour — regression guard). - With the overlay applied →
loadBranding('phew')resolves the client config, assets validate, contrast checks pass; the header/title/favicon render client branding. - No
phew/client string in the public repo HEAD attributable to branding (AC-DEID §A).