Skip to content

docs: Stack Auth → Hexclave rebrand plan#1468

Closed
BilalG1 wants to merge 5 commits into
devfrom
docs/hexclave-rename-plan
Closed

docs: Stack Auth → Hexclave rebrand plan#1468
BilalG1 wants to merge 5 commits into
devfrom
docs/hexclave-rename-plan

Conversation

@BilalG1
Copy link
Copy Markdown
Collaborator

@BilalG1 BilalG1 commented May 21, 2026

Summary

Adds the v6 rebrand plan (RENAME-TO-HEXCLAVE.md) covering every renameable identifier across the codebase and how each one is handled.

Highlights:

  • Tier 0 — wire identifiers (dual-accept / dual-emit / dual-write): 21 request headers, 3 response headers, Bearer stackauth_* prefix, all stack-* cookies (auth + OAuth state + low-risk UI), 3 JWT issuer variants, mobile OAuth URL scheme, MCP tool name, config filename. Each old form stays readable indefinitely; new form is preferred and emitted by new code.
  • Tier 1 — SDK aliases: every public Stack* class/component/hook/type gets a Hexclave* alias via re-exports in packages/template; codegen propagates to react/stack/js. Swift SDK split into two separate SPM packages (frozen StackAuth + new Hexclave).
  • Tier 2 — NPM packages: 10 @stackframe/* packages dual-published as @hexclave/* via a rewrite-then-republish step appended to .github/workflows/npm-publish.yaml.
  • Env var taxonomy with 5 categories — customer-facing dual-read, framework-internal dual-read, self-host operator vars out of scope, GitHub onboarding split into secret names vs process env vars, build/dev/test stays as-is.
  • Customer-facing surfaces the plan covers: @stackframe/emails virtual module, dashboard sandbox window.Stack* globals + iframe message types, KnownErrors message templates, init wizard, dashboard setup snippets.
  • Implementation realities section documents architectural mismatches discovered during pre-PR-1 review (route-level header schemas, JWT validator URL-builder pattern, npm publish workspace lockfile issue, etc.).
  • PR 1 verification matrix covers auth wire, cookies, env vars, JWT, MCP, CLI/config, packages, Swift, docs, migrations, tests + CI.
  • 2-PR rollout: PR 1 ships every dual-support shim additively; PR 2 (12+ months later) removes only the safely-removable fallbacks. Wire identifiers stay indefinitely; PR 3+ could remove specific shims once telemetry shows usage drops to zero.

Review focus

  • Anything in the codebase that touches stack/Stack/stackframe and isn't covered.
  • Any implementation pattern proposed in the plan that won't drop in cleanly against the current code.
  • Disagreements on classification (which identifiers should stay vs. dual-support vs. rebrand cosmetically).

Test plan

  • No code changes; review the document for completeness and correctness against the actual codebase.

Captures the v6 rebrand plan: dual-support strategy for wire identifiers
(HTTP headers, cookies, JWT issuers, Bearer prefix, OAuth state),
SDK alias re-exports, npm dual-publish via rewrite-then-republish,
Swift split into separate StackAuth/Hexclave packages, env var taxonomy,
verification matrix, and 2-PR rollout.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
stack-auth-hosted-components Ready Ready Preview, Comment May 23, 2026 7:04pm
stack-auth-mcp Ready Ready Preview, Comment May 23, 2026 7:04pm
stack-auth-skills Ready Ready Preview, Comment May 23, 2026 7:04pm
stack-backend Ready Ready Preview, Comment May 23, 2026 7:04pm
stack-dashboard Ready Ready Preview, Comment May 23, 2026 7:04pm
stack-demo Ready Ready Preview, Comment May 23, 2026 7:04pm
stack-docs Ready Ready Preview, Comment May 23, 2026 7:04pm
stack-preview-backend Ready Ready Preview, Comment May 23, 2026 7:04pm
stack-preview-dashboard Error Error May 23, 2026 7:04pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2519a3a6-c4e2-4953-a9d4-3571ad3ce985

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/hexclave-rename-plan

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…n rebrand plan

Addresses review gaps in the Hexclave rename plan:
- Storage keys: add the missed localStorage keys `_STACK_AUTH.lastUsed`,
  `stack:session-replay:v1:*`, `__stack-dev-tool-state`, and
  `stack-devtool-trigger-position`, with per-key compat risk notes.
- Query parameters: new Tier 0 category — `stack_response_mode`, the four
  `stack_cross_domain_*` handoff params, and `stack-init-id` are
  wire-compat-sensitive and were previously uncovered.
- Custom DOM events: `stack-platform-change` / `stack-framework-change`.
- Dev tool: dev-tool-core.ts is its own brand surface (storage keys,
  header-emit site, DOM identifiers, brand strings).
- Tier 1: internal-only symbols (SDK interfaces, StackAssertionError)
  renamed outright with no alias; user-facing symbols keep aliases
- Tier 2: @hexclave/* starts at 1.0.0, lockstep versioning; add
  npm deprecate + runtime warn for old packages; drop @hexclave/init
- Env vars: all categories dual-read (incl. operator/internal);
  NEXT_PUBLIC_STACK_PORT_PREFIX renamed outright
- Emails: noreply moves to sent-with-hexclave.com sending domain
- CHIPS test cookies out of scope (unused feature)
- Rollout split into 3 PRs: invisible compat layer, visible rebrand,
  far-future fallback removal
- Add "PR 1 implementation guide" section resolving every open item
  with concrete file:line references and chosen approach per work-area
- Correction: Bearer stackauth_ prefix is SDK-internal, never parsed by
  the backend (was wrongly listed as a backend wire identifier)
- Request headers: normalize at the existing empty proxy.tsx:114 hook
  (no readDualHeader helper, no per-route schema edits)
- Env vars: hybrid dual-read (central getEnvVariable transform + two
  client files + per-site tail)
- Symbol.for: four symbols, not three; only one needs dual-attach
- Query params: add the two nested cross-domain params
Grep confirms x-stack-auth has zero references in apps/backend and
packages/stack-shared. It is produced by the deprecated getAuthHeaders()/
useAuthHeaders() SDK methods and consumed by the SDK tokenStore parser
(client-app-impl.ts) — the Stack backend never parses it. Reframed from
"backend read-only wire identifier" to "SDK-internal legacy identifier",
corrected the false "no current writer" claim, and resolved the open
verification item.
@BilalG1 BilalG1 closed this May 23, 2026
BilalG1 added a commit that referenced this pull request May 24, 2026
## Summary

**Stacked on #1468** (`docs/hexclave-rename-plan` — the plan doc). Diff
vs that base = the actual PR 1 code.

This is **PR 1 of the Hexclave rebrand: the invisible compatibility
layer**. Everything is additive. Old SDKs, old wire identifiers, and old
env var names keep working unchanged. The backend dual-accepts and
dual-emits; new SDK code emits `x-hexclave-*` headers and the
`hexclave_` Bearer prefix; cookies dual-write; env vars dual-read across
every category. **No user-visible rebranding lands here** — that's PR 2.

See [`RENAME-TO-HEXCLAVE.md`](./RENAME-TO-HEXCLAVE.md) → *"PR 1
implementation guide"* for the full per-work-area spec, file pointers,
and chosen approach.

## What's implemented (all 14 PR-1 work-areas)

- **SDK export aliases** — `Hexclave*` aliases for the user-facing
`Stack*` exports added in `packages/template`; codegen propagates them
to `@stackframe/{js,stack,react,tanstack-start}`. React-only aliases
correctly excluded from `@stackframe/js`. (`e60550a2`)
- **JWT issuer dual-accept** — `decodeAccessToken` accepts both
`api.stack-auth.com` and `api.hexclave.com` issuers. Signing unchanged.
(`fc781def`)
- **Request-header dual-accept** — backend + dashboard proxies normalize
`x-hexclave-*` → `x-stack-*` at the existing empty proxy hook (so
`smart-request.tsx` and every route schema keep working unchanged); CORS
allowlists extended via a derive-once helper. (`2a056eac`)
- **MCP `ask_hexclave`** — registered alongside `ask_stack_auth` via a
shared helper; `ask_stack_auth` behavior byte-identical. (`30ffd604`)
- **Dev-tool** — DOM ids + header emit switched.
`window.HexclaveDevTool` exposed alongside `window.StackDevTool`.
(`32131ea7`)
- **The big consolidated commit** (`7fed864a`):
- **Env vars** — central `getEnvVariable` prefix-transform (HEXCLAVE
first, STACK fallback); dashboard + template client env files dual-read;
`turbo.json` globalEnv; `NEXT_PUBLIC_STACK_PORT_PREFIX` renamed outright
across ~82 files including docker.
- **Cookies** — dual-write/dual-read auth (`stack-access`/`-refresh-*`
and custom-domain variants), OAuth-state
(`stack-oauth-{inner,outer}-*`), and low-risk cookies (`stack-is-https`,
`stack-last-seen-changelog-version`). Bypass sites patched (backend
OAuth callback, dashboard remote-dev auth route, impersonation snippets,
snapshot serializer).
- **Bearer prefix** — SDK token parser accepts both `stackauth_` and
`hexclave_`; emits `hexclave_`. Discovery correction: this is purely
SDK-internal — the backend never parses it.
- **Response headers** — backend dual-emits
`x-hexclave-{request-id,actual-status,known-error}`; SDKs dual-read (new
first, stack fallback).
- **SDK request-header emit switch** —
`client/server/admin-interface.ts` + dashboard `api-headers.ts` +
`internal-project-headers.ts` + `feedback-form.tsx` switched to
`x-hexclave-*`. Plus `stack_response_mode` query param.
- **Storage keys** — dev-tool / cli-auth / oauth-button / docs keys
renamed (straight); `stack:session-replay:v1` dual-read so in-progress
recordings survive SDK upgrades; `stack_mfa_attempt_code` dual-read.
- **Query params** — cross-domain params dual-emit/dual-accept via
shared helpers; backend `oauth/authorize` accepts
`hexclave_response_mode` and `stack_response_mode`; `stack-init-id`
renamed.
- **`Symbol.for`** — app-internals symbol gets a parallel
`Symbol.for("Hexclave--app-internals")` getter on each attach site (no
read-site churn — old symbol still attached). 3 file-private symbols
renamed outright.
- **Config discovery** — prefer `hexclave.config.ts`, fall back to
`stack.config.ts` at every discovery site (CLI / dashboard / backend /
local-emulator); `init` writes the new filename; CLI credentials path
migrates.
- **Internal renames** — `StackAssertionError`,
`StackClient/Server/AdminInterface` renamed outright (no alias, per the
"internal-only → rename" rule). ~264 files touched.
- **Review-pass fixes** (`21217fbe`) — three real bugs found by parallel
review agents and fixed:
- `snapshot-serializer.ts` was interpolating the whole
`keyedCookieNamePrefixes` array (`${arr}`) — adding a second prefix
would have corrupted **every** OAuth-cookie snapshot, not just new ones.
- **Docker port-prefix producer/consumer mismatch** —
`entrypoint.sh`/`run-emulator.sh`/cloud-init `user-data` were still
producing `NEXT_PUBLIC_STACK_PORT_PREFIX` while the dashboard sentinel +
consumers had been renamed; silent self-host regression (custom port
prefix would be ignored).
- **Missing `hexclave-oauth-inner-*` dual-write** in the OAuth authorize
route — callback's fallback masked it but the dual-write was specified
by the plan.
- Plus: `mcp.test.ts` tool-list assertions updated to include
`ask_hexclave`; two dashboard header-emit sites switched to
`x-hexclave-*` for consistency.
- **E2E snapshot serializer follow-up** (`4b16cc5d`) —
`x-hexclave-request-id` added to the hidden-headers list (mirroring
`x-stack-request-id` treatment), and 2 sample inline snapshots
regenerated in `projects.test.ts` to include the new dual-emitted
headers.

## Verification

- **`pnpm typecheck`** — clean (the fresh-worktree `@/.source` / Prisma
codegen gap in `stack-docs` is pre-existing and unrelated).
- **`pnpm lint`** — 29/29 packages green.
- **`pnpm exec turbo run build --filter=./packages/*`** — 13/13 packages
build (including `@stackframe/stack-cli` once the dashboard standalone
is present).
- **Live E2E** against a running backend on `cl/hexclave-pr1`:
- `pnpm test run
apps/e2e/tests/backend/endpoints/api/v1/internal/mcp.test.ts` — **6/6
pass** (verifies the new `ask_hexclave` tool — the hand-written inline
snapshot matched actual MCP server output).
- `pnpm test run
apps/e2e/tests/backend/endpoints/api/v1/internal/projects.test.ts` —
**11/11 pass** (verifies wire dual-accept + dual-emit end-to-end; the
snapshot serializer fix was found and applied during this check).

A four-agent parallel **review pass** also audited the full diff for
logic/runtime bugs across the work-areas (wire headers + JWT, cookies +
bearer + symbols, env vars, query params + config + MCP + aliases). All
in-slice review verdicts were ✓ except the three bugs listed above,
which are now fixed.

## Known follow-ups (out of scope for this PR)

- **E2E snapshots across the rest of the suite** — backend now
dual-emits `x-hexclave-{known-error,actual-status}` alongside
`x-stack-*`, which legitimately appears in inline snapshots throughout
`apps/e2e`. Two were regenerated here as a sample; the rest should regen
with `vitest -u` in CI.
- **Docker shell env vars beyond `PORT_PREFIX`** — `entrypoint.sh` still
reads `STACK_*` env vars directly (the JS-side `getEnvVariable`
transform doesn't help the shell). JS consumers dual-read so it works in
practice; full shell-level dual-read is a deeper self-host follow-up.
- **`@stackframe/stack-cli` build ordering** — pre-existing; needs
`build:rde-standalone` first. Not affected by this PR.

## Test plan

- [ ] CI runs full e2e suite (with `vitest -u` to absorb dual-emit
snapshot deltas, then committed back)
- [ ] Spot-check: an old SDK build (emitting only `x-stack-*`) still
authenticates against the new backend
- [ ] Spot-check: a new SDK (emitting `x-hexclave-*` / `Bearer
hexclave_*`) still authenticates against an old backend during deploy
ordering
- [ ] Manual: `npx @stackframe/stack-cli@latest init` (new onboarding
entrypoint) generates `hexclave.config.ts`
- [ ] Manual: existing `stack.config.ts`-only project still resolves (no
migration required)

---------

Co-authored-by: bilal <bilal@stack-auth.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant