From 5ef94bb725c2e06a5a2172c14779734e23452e7a Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Wed, 29 Apr 2026 14:39:11 +0100 Subject: [PATCH] Refresh Patreon launch state --- docs/implementation-plan.md | 15 +++++++++++---- docs/service-contract.md | 16 +++++++--------- notes/fresh-workspace-handoff.md | 26 +++++++++++++++----------- state/map.yaml | 8 ++++---- 4 files changed, 37 insertions(+), 28 deletions(-) diff --git a/docs/implementation-plan.md b/docs/implementation-plan.md index d2e6210..4f63313 100644 --- a/docs/implementation-plan.md +++ b/docs/implementation-plan.md @@ -87,7 +87,7 @@ Goals: - configure Heimdall's Discord client credentials for the Repixelizer-owned Discord OAuth app - configure Repixelizer for `GC_ACCESS_MODE=heimdall` and - `GC_ACCESS_ALLOWED_PROVIDERS=discord` + `GC_ACCESS_ALLOWED_PROVIDERS=discord,patreon` - configure Repixelizer's Discord access policy with its GameCult guild id and allowed role ids; Repixelizer sends that policy to Heimdall during the backend-callback OAuth start @@ -99,10 +99,11 @@ Deployment/configuration status: - the deployment and service wiring are done - public health/discovery/JWKS/config checks pass -- public Repixelizer auth-start returns a Discord authorization URL using the - Heimdall callback and Repixelizer backend handoff +- public Repixelizer auth-start returns Discord and Patreon authorization URLs + using the Heimdall callback and Repixelizer backend handoff - the Discord authorization URL requests only `identify guilds.members.read` -- the remaining launch check is the real interactive Discord browser flow +- the Patreon authorization URL requests only `identity identity[email]` +- the remaining launch check is the real interactive provider browser flow Current Discord policy: @@ -113,6 +114,12 @@ Current Discord policy: public, but Repixelizer access is limited to members with either `KLTST` or the Patreon-synced `Inner Sanctum` role +Current Patreon policy: + +- Heimdall grants Repixelizer `entitlement.app_access` only when Patreon returns + a currently entitled tier titled `Inner Sanctum` +- the policy is title-based, not amount-based + ### 4. Migrate StreamPixels without flattening its good local seams Goals: diff --git a/docs/service-contract.md b/docs/service-contract.md index 4dc822c..9e86a44 100644 --- a/docs/service-contract.md +++ b/docs/service-contract.md @@ -160,11 +160,10 @@ Failure mode right now: Launch note: -- Discord is the only implemented provider runtime today -- Patreon, GitHub, Twitch, and YouTube are catalogued for start URLs, but their +- Discord and Patreon are the implemented provider runtimes for Repixelizer +- GitHub, Twitch, and YouTube are catalogued for start URLs, but their callback exchange/identity/entitlement runtimes are not implemented yet -- Repixelizer launch should therefore configure only Discord on its provider - buttons until additional adapters land +- Repixelizer launch can configure Discord and Patreon on its provider buttons ### `GET /v1/oauth/{provider}/callback` @@ -472,11 +471,10 @@ The following are not landed yet: Deploy and verify the hardened slice in the first real app binding: -- run Discord-only Repixelizer auth with real provider credentials +- run Discord and Patreon Repixelizer auth with real provider credentials - confirm direct backend callback delivery to Repixelizer - confirm Repixelizer verifies the Heimdall access token locally and gates hosted routes from the adopted session -- configure Repixelizer access as role-gated Discord access in Repixelizer's - own runtime env: the GameCult guild may be public, but the caller-owned - policy sent to Heimdall should contain the `KLTST` and Patreon-synced - `Inner Sanctum` role ids +- configure Repixelizer access policy in Repixelizer's own runtime env: + Discord should accept `KLTST` or the Patreon-synced `Inner Sanctum` role, + and Patreon should accept the currently entitled tier title `Inner Sanctum` diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 708047a..25875cd 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -66,13 +66,13 @@ Do not trust this file for the exact live HEAD. Always check git. behind nginx/TLS with Postgres storage, file-backed signing-key bootstrap, configured token custody, and public health/discovery/JWKS checks passing - Repixelizer is now deployed on Yggdrasil at - `https://repixelizer.gamecult.org` with Heimdall mode enabled, Discord as the - only public provider, required access enabled, and queue protection enabled -- Repixelizer public auth-start returns a Discord authorization URL using the - Heimdall callback and Repixelizer backend handoff -- the first live launch should be Discord-only -- Patreon, GitHub, Twitch, and YouTube are catalogued providers, but their - callback runtime adapters still return "not implemented" + `https://repixelizer.gamecult.org` with Heimdall mode enabled, Discord and + Patreon as public providers, required access enabled, and queue protection + enabled +- Repixelizer public auth-start returns Discord and Patreon authorization URLs + using the Heimdall callback and Repixelizer backend handoff +- GitHub, Twitch, and YouTube are catalogued providers, but their callback + runtime adapters still return "not implemented" - StreamPixels is the migration target with useful existing auth seams that should not be flattened into mush - the intended first deployment shape is a Heimdall service on Yggdrasil behind @@ -97,11 +97,11 @@ verification: - open `https://repixelizer.gamecult.org/app/` - start Discord sign-in with an account that has the `KLTST` or - Patreon-synced `Inner Sanctum` role -- confirm Repixelizer sends its app-owned Discord guild/role policy in the + Patreon-synced `Inner Sanctum` role, or Patreon sign-in with a currently + entitled tier titled `Inner Sanctum` +- confirm Repixelizer sends its app-owned provider policy in the backend-callback OAuth start -- confirm Heimdall receives the Discord callback and evaluates guild role - entitlement +- confirm Heimdall receives the provider callback and evaluates entitlement - confirm Repixelizer receives the backend callback, verifies the Heimdall token, adopts a local httpOnly session, and gates hosted/queue routes - confirm the Discord authorization URL requests only `identify @@ -114,6 +114,10 @@ its own runtime env and sends it to Heimdall during backend-callback OAuth start; Heimdall owns provider OAuth mechanics and claim issuance, not the per-app role list. +Patreon access is title-gated on the currently entitled tier title +`Inner Sanctum`; do not use currency amount as the durable policy because +currencies are weird little traps. + ## Immediate Re-entry Instruction After compaction, first rehydrate and reorient from the listed files and git diff --git a/state/map.yaml b/state/map.yaml index 0526933..eb32690 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -56,7 +56,7 @@ active_subgoals: - Keep the shared architecture explicit and separate from app profiles. - Preserve the default boundary that app-domain data remains app-owned. - Align the plan to Heimdall as a Yggdrasil-hosted authority service. - - Verify the Discord-only Repixelizer auth path with real provider credentials, stable signing, persistent storage, and live browser callback verification. + - Verify the Discord and Patreon Repixelizer auth paths with real provider credentials, stable signing, persistent storage, and live browser callback verification. - Keep Patreon/GitHub/Twitch/YouTube as catalogued but not implemented until their runtime adapters land. accepted_design: @@ -73,7 +73,7 @@ accepted_design: - The first stateful slice adds durable auth/control-plane storage plus a real Discord callback path for Repixelizer. - Repixelizer has consumed the Heimdall backend-callback flow in its hosted web layer; Heimdall no longer needs to wait on Repixelizer refactoring before live Discord launch work. - Heimdall is deployed on Yggdrasil at `https://heimdall.gamecult.org` with nginx/TLS, Postgres storage, file-backed signing-key bootstrap, configured token custody, and passing public health/discovery/JWKS checks. - - Repixelizer is deployed on Yggdrasil at `https://repixelizer.gamecult.org` with `GC_ACCESS_MODE=heimdall`, `GC_ACCESS_ALLOWED_PROVIDERS=discord`, required access, queue protection enabled, and app-owned Discord guild/role policy sent to Heimdall during backend-callback OAuth start. + - Repixelizer is deployed on Yggdrasil at `https://repixelizer.gamecult.org` with `GC_ACCESS_MODE=heimdall`, `GC_ACCESS_ALLOWED_PROVIDERS=discord,patreon`, required access, queue protection enabled, app-owned Discord guild/role policy, and app-owned Patreon tier-title policy sent to Heimdall during backend-callback OAuth start. landed_baseline: - Shared architecture extracted into its own repo and renamed to Heimdall. @@ -95,5 +95,5 @@ rejected_paths: reason: reusing auth mechanics does not justify centralizing app-domain audience or product data current_status: - summary: Heimdall has a live first Yggdrasil deployment for the Discord-only Repixelizer path: TypeScript/Fastify runtime behind nginx/TLS at `https://heimdall.gamecult.org`, Ed25519 JWT signing with bootstrapped file-backed key support, JWKS/discovery exposure, signed OAuth start-state handling, Postgres-backed auth/control-plane persistence, a real Discord callback path, AES-256-GCM token sealing for managed provider credentials at rest, direct backend callback delivery for Repixelizer, and the older one-time completion-code exchange retained as fallback. Repixelizer is deployed at `https://repixelizer.gamecult.org` in Heimdall mode with Discord as the only public provider, required access enabled, queue protection enabled, and app-owned Discord guild/role policy sent to Heimdall in trusted backend-callback OAuth starts. Public health/discovery/JWKS/config checks pass, and public auth-start returns a Discord authorization URL using the Heimdall callback plus Repixelizer backend handoff. Patreon, GitHub, Twitch, and YouTube are catalogued providers but their callback runtimes are still not implemented. The key boundary still holds: Heimdall owns auth/control-plane authority and credential custody; app-domain bindings and runtime behavior remain app-owned. - next_action: Run the real browser OAuth flow end to end from `https://repixelizer.gamecult.org/app/` with a Discord account that has the `KLTST` role or the Patreon-synced `Inner Sanctum` role, confirm Repixelizer sends its caller-owned Discord role policy, Heimdall receives the Discord callback, confirms guild role entitlement, delivers the backend callback to Repixelizer, Repixelizer adopts a local httpOnly session, and hosted/queue routes are gated correctly. The public OAuth start URL should request only `identify guilds.members.read`. + summary: Heimdall has a live Yggdrasil deployment for the Repixelizer auth path: TypeScript/Fastify runtime behind nginx/TLS at `https://heimdall.gamecult.org`, Ed25519 JWT signing with bootstrapped file-backed key support, JWKS/discovery exposure, signed OAuth start-state handling, Postgres-backed auth/control-plane persistence, real Discord and Patreon callback runtimes for Repixelizer, AES-256-GCM token sealing for managed provider credentials at rest, direct backend callback delivery for Repixelizer, and the older one-time completion-code exchange retained as fallback. Repixelizer is deployed at `https://repixelizer.gamecult.org` in Heimdall mode with Discord and Patreon as public providers, required access enabled, queue protection enabled, app-owned Discord guild/role policy, and app-owned Patreon tier-title policy sent to Heimdall in trusted backend-callback OAuth starts. Public health/discovery/JWKS/config checks pass, and public auth-start returns provider authorization URLs using the Heimdall callback plus Repixelizer backend handoff. GitHub, Twitch, and YouTube are catalogued providers but their callback runtimes are still not implemented. The key boundary still holds: Heimdall owns auth/control-plane authority and credential custody; app-domain bindings and runtime behavior remain app-owned. + next_action: Run the real browser OAuth flow end to end from `https://repixelizer.gamecult.org/app/` with either Discord access (`KLTST` or the Patreon-synced `Inner Sanctum` role) or Patreon access (currently entitled tier titled `Inner Sanctum`), confirm Repixelizer sends its caller-owned provider policy, Heimdall receives the provider callback, confirms entitlement, delivers the backend callback to Repixelizer, Repixelizer adopts a local httpOnly session, and hosted/queue routes are gated correctly. Public OAuth start URLs should request only the scopes they actually need.