Point hosted access docs at gamecult-access
This commit is contained in:
parent
ef58b509cf
commit
9d08b9d98a
5 changed files with 43 additions and 566 deletions
18
AGENTS.md
18
AGENTS.md
|
|
@ -21,11 +21,15 @@ diagnostics good enough to catch when we are lying to ourselves.
|
|||
- Treat `docs/implementation-plan.md` as the forward plan.
|
||||
- Treat `docs/lean-optimizer-algorithm-map.md` as the source-grounded live
|
||||
algorithm map.
|
||||
- Treat `docs/gamecult-hosted-access-architecture.md` as the future shared
|
||||
access architecture for GameCult-hosted experiments, not as proof that auth
|
||||
machinery already exists here already.
|
||||
- Treat `docs/repixelizer-hosted-access-profile.md` as the Repixelizer-specific
|
||||
binding onto that future shared access architecture.
|
||||
- Treat `E:\Projects\gamecult-access\docs\architecture.md` as the canonical
|
||||
future shared access architecture for GameCult-hosted experiments, not as
|
||||
proof that auth machinery already exists here already.
|
||||
- Treat `E:\Projects\gamecult-access\docs\app-profiles\repixelizer.md` as the
|
||||
canonical Repixelizer-specific binding onto that future shared access
|
||||
architecture.
|
||||
- Treat local `docs/gamecult-hosted-access-architecture.md` and
|
||||
`docs/repixelizer-hosted-access-profile.md` as redirect stubs, not the real
|
||||
design notes.
|
||||
- Update `state/map.yaml` when project understanding changes.
|
||||
- Add evidence after meaningful research, implementation, verification, or
|
||||
rejected paths, but keep it distilled. Routine "I just did this" proof belongs
|
||||
|
|
@ -37,8 +41,8 @@ diagnostics good enough to catch when we are lying to ourselves.
|
|||
- Project root: `E:\Projects\repixelizer`
|
||||
- Implementation plan: `E:\Projects\repixelizer\docs\implementation-plan.md`
|
||||
- Algorithm map: `E:\Projects\repixelizer\docs\lean-optimizer-algorithm-map.md`
|
||||
- Shared hosted access architecture: `E:\Projects\repixelizer\docs\gamecult-hosted-access-architecture.md`
|
||||
- Repixelizer hosted access profile: `E:\Projects\repixelizer\docs\repixelizer-hosted-access-profile.md`
|
||||
- Shared hosted access architecture: `E:\Projects\gamecult-access\docs\architecture.md`
|
||||
- Repixelizer hosted access profile: `E:\Projects\gamecult-access\docs\app-profiles\repixelizer.md`
|
||||
- Handoff summary: `E:\Projects\repixelizer\notes\fresh-workspace-handoff.md`
|
||||
- State CLI: `E:\Projects\repixelizer\tools\repixelizer_state.py`
|
||||
- Pre-compaction helper: `E:\Projects\repixelizer\tools\repixelizer_prepare_compaction.py`
|
||||
|
|
|
|||
|
|
@ -1,399 +1,20 @@
|
|||
# GameCult Hosted Access Architecture
|
||||
|
||||
## What this file is
|
||||
This shared design moved.
|
||||
|
||||
This file is a future shared architecture note for GameCult-hosted experiments
|
||||
that need the same basic promise:
|
||||
Canonical location:
|
||||
|
||||
- let people sign in with Discord and/or Patreon
|
||||
- decide access from GameCult/community entitlements
|
||||
- keep app runtimes tied to local sessions and local accounts, not provider ids
|
||||
- `E:\Projects\gamecult-access\docs\architecture.md`
|
||||
|
||||
It is not a map of currently landed auth code in this repo.
|
||||
Repixelizer-specific binding:
|
||||
|
||||
## Problem
|
||||
- `E:\Projects\gamecult-access\docs\app-profiles\repixelizer.md`
|
||||
|
||||
Repixelizer is probably not the last hosted experiment that wants this shape.
|
||||
This local file remains only as a redirect stub so old notes and links do not
|
||||
pretend the shared access plan still lives inside Repixelizer.
|
||||
|
||||
If every experiment re-implements:
|
||||
Current repo truth is unchanged:
|
||||
|
||||
- provider OAuth
|
||||
- identity linking
|
||||
- entitlement refresh
|
||||
- session cookies
|
||||
- queue/job ownership
|
||||
- "Discord role OR Patreon tier" logic
|
||||
|
||||
then we will end up with five damp little auth pits that are all almost the
|
||||
same and all annoying in slightly different ways.
|
||||
|
||||
The reusable move is to build one GameCult hosted-access layer and let each app
|
||||
bind its own policy and runtime seams onto it.
|
||||
|
||||
## Design goals
|
||||
|
||||
- one reusable local account/session model across hosted experiments
|
||||
- provider login and linking owned by one shared access layer
|
||||
- per-app capability policies instead of hard-coded one-off gate checks
|
||||
- host runtimes consume signed local session claims, not raw provider tokens
|
||||
- keep app-domain data separate unless there is a deliberate reason to share it
|
||||
- reusable enough as a shared package first, with room to graduate into a
|
||||
shared service later if that pain actually materializes
|
||||
|
||||
## Non-goals
|
||||
|
||||
- becoming a general public identity provider
|
||||
- building multi-tenant SaaS auth machinery
|
||||
- inventing global billing analytics because we got bored
|
||||
- forcing cross-app single sign-on on day one before a second app exists
|
||||
|
||||
## Core concepts
|
||||
|
||||
- `Account`
|
||||
one GameCult-local person record independent of external providers
|
||||
- `LinkedIdentity`
|
||||
one external provider identity attached to exactly one local account
|
||||
- `EntitlementSnapshot`
|
||||
cached result from a provider or grant source saying whether some claim is
|
||||
currently true
|
||||
- `CapabilityGrant`
|
||||
a reusable local grant such as `global_member`, `app_access`, or
|
||||
`admin_access`, scoped either globally or to one app
|
||||
- `AppAccessProfile`
|
||||
the per-app binding that names capabilities, allowed provider sources, and
|
||||
policy rules
|
||||
- `Session`
|
||||
signed local app/browser session; the browser gets this, not provider tokens
|
||||
- `AuditEvent`
|
||||
durable record for login, link, unlink, refresh, denial, and admin overrides
|
||||
|
||||
## System shape
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["Browser / app web UI"] --> B["Hosted experiment web surface"]
|
||||
B --> C["GameCult access layer"]
|
||||
C --> D["Discord OAuth + guild role checks"]
|
||||
C --> E["Patreon OAuth + campaign/tier checks"]
|
||||
C --> F["Local account/session/grant store"]
|
||||
C --> G["Signed access claims"]
|
||||
G --> H["Hosted experiment runtime"]
|
||||
```
|
||||
|
||||
The important split:
|
||||
|
||||
- the access layer owns provider OAuth, identity linking, entitlement refresh,
|
||||
and signed local sessions
|
||||
- the host experiment owns its actual workload, queue, editor, render path, or
|
||||
whatever weird machine it is
|
||||
|
||||
Do not smear provider logic directly through every host runtime.
|
||||
|
||||
## Backbone reuse is not data merging
|
||||
|
||||
Using the same auth backbone does **not** mean all hosted experiments should
|
||||
pour their user data into one communal bucket.
|
||||
|
||||
The reusable thing is:
|
||||
|
||||
- provider OAuth plumbing
|
||||
- signed local session mechanics
|
||||
- linked-identity primitives
|
||||
- entitlement refresh
|
||||
- capability evaluation
|
||||
|
||||
The non-reusable-by-default thing is:
|
||||
|
||||
- app-domain user data
|
||||
- creator data
|
||||
- audience data
|
||||
- queue/job payloads
|
||||
- inventories, scenes, outputs, or other product state
|
||||
|
||||
Recommended default:
|
||||
|
||||
- shared auth/access **code**
|
||||
- separate app databases or at least separate app-owned schemas/tables for
|
||||
domain data
|
||||
- if a shared access store exists at all, keep it limited to auth/control-plane
|
||||
truth such as identities, grants, entitlement snapshots, and audit events
|
||||
|
||||
Do not let "same auth backbone" quietly mutate into "same user-data swamp."
|
||||
|
||||
## Reusable data model
|
||||
|
||||
Suggested durable core:
|
||||
|
||||
- `accounts`
|
||||
- `id`
|
||||
- `created_at`
|
||||
- `last_seen_at`
|
||||
- `display_name`
|
||||
- `primary_email` nullable
|
||||
- `linked_identities`
|
||||
- `id`
|
||||
- `account_id`
|
||||
- `provider`
|
||||
- `provider_user_id`
|
||||
- `username`
|
||||
- `access_token_encrypted`
|
||||
- `refresh_token_encrypted`
|
||||
- `token_expires_at`
|
||||
- `profile_json`
|
||||
- unique on `(provider, provider_user_id)`
|
||||
- `entitlement_snapshots`
|
||||
- `id`
|
||||
- `account_id`
|
||||
- `provider`
|
||||
- `scope`
|
||||
- `evaluated_at`
|
||||
- `is_allowed`
|
||||
- `reason_code`
|
||||
- `reason_detail`
|
||||
- `raw_summary_json`
|
||||
- `capability_grants`
|
||||
- `id`
|
||||
- `account_id`
|
||||
- `scope_type` enum: `global`, `app`
|
||||
- `scope_id` nullable app slug
|
||||
- `capability`
|
||||
- `source` enum: `manual`, `invite`, `migration`, `operator`
|
||||
- `status`
|
||||
- `expires_at` nullable
|
||||
- `note`
|
||||
- `sessions`
|
||||
- `id`
|
||||
- `account_id`
|
||||
- `app_slug`
|
||||
- `created_at`
|
||||
- `last_seen_at`
|
||||
- `expires_at`
|
||||
- `claims_json`
|
||||
- `access_revision`
|
||||
- `audit_events`
|
||||
- `id`
|
||||
- `account_id` nullable
|
||||
- `session_id` nullable
|
||||
- `app_slug` nullable
|
||||
- `event_type`
|
||||
- `event_payload_json`
|
||||
- `created_at`
|
||||
|
||||
Important invariants:
|
||||
|
||||
- one provider identity belongs to one local account only
|
||||
- provider tokens stay server-side only
|
||||
- session cookies represent local sessions, not provider trust directly
|
||||
- app-specific capability checks read local claims, not Discord or Patreon on
|
||||
every route
|
||||
|
||||
## Provider adapters
|
||||
|
||||
Shared provider/gate adapters should be boring and reusable:
|
||||
|
||||
- `DiscordRoleEntitlementProvider`
|
||||
- login via Discord OAuth
|
||||
- entitlement check via guild membership and role ids, ideally through the
|
||||
GameCult bot token server-side
|
||||
- `PatreonMembershipEntitlementProvider`
|
||||
- login via Patreon OAuth
|
||||
- entitlement check via campaign membership and tier ids
|
||||
- `ManualGrantProvider`
|
||||
- local override for staff, migrations, experiments, or emergency access
|
||||
- `InviteGrantProvider`
|
||||
- reusable invite-issued app or role grants where that pattern makes sense
|
||||
|
||||
This is the good kind of bureaucracy: one place to keep the provider sludge.
|
||||
|
||||
## Policy model
|
||||
|
||||
The reusable core should not hard-code "Repixelizer access". It should evaluate
|
||||
capabilities against an app profile.
|
||||
|
||||
Suggested app-profile shape:
|
||||
|
||||
```text
|
||||
AppAccessProfile {
|
||||
appSlug: string
|
||||
displayName: string
|
||||
capabilities: string[]
|
||||
policyRules: CapabilityRule[]
|
||||
publicRoutes: string[]
|
||||
explanationStrings: map[string]string
|
||||
}
|
||||
```
|
||||
|
||||
Example rule style:
|
||||
|
||||
```text
|
||||
app_access = discord.allowed_role || patreon.allowed_tier || grant.global_member || grant.app_access
|
||||
queue_submit = app_access
|
||||
admin_access = grant.operator || grant.admin_access
|
||||
```
|
||||
|
||||
This gives reuse in the right place:
|
||||
|
||||
- the shared layer knows how to link identities, refresh entitlements, and
|
||||
evaluate capabilities
|
||||
- each experiment only defines which capabilities it wants and what qualifies
|
||||
|
||||
## Auth and linking flow
|
||||
|
||||
The generic flow should be the same across hosted experiments:
|
||||
|
||||
1. user starts OAuth from the host app UI
|
||||
2. shared access layer signs OAuth `state`
|
||||
3. provider callback resolves the provider identity
|
||||
4. shared layer finds or creates the local account
|
||||
5. if the user was already signed in locally, the identity may link onto the
|
||||
existing account instead of creating a new one
|
||||
6. shared layer refreshes entitlements and capability claims
|
||||
7. shared layer issues or updates the local session cookie
|
||||
|
||||
The browser should never be the custodian of provider tokens. It is a goblin
|
||||
with JavaScript.
|
||||
|
||||
## App integration contract
|
||||
|
||||
Every hosted experiment should integrate through the same seams:
|
||||
|
||||
- define an `app_slug`
|
||||
- define the app capability profile
|
||||
- mark which routes are:
|
||||
- public
|
||||
- authenticated
|
||||
- capability-gated
|
||||
- attach `account_id`, `session_id`, and `access_revision` to owned resources
|
||||
such as jobs, drafts, uploads, or queue entries
|
||||
- require resource-owner checks on private read/update/delete paths
|
||||
|
||||
If an app has a queue or job system:
|
||||
|
||||
- queue entries belong to local account/session ids, not provider ids
|
||||
- entitlement refresh should block new submissions after access loss
|
||||
- active-job cancellation policy is app-specific, but the recommended first cut
|
||||
is still "let the active job finish, block new work"
|
||||
|
||||
## Deployment modes
|
||||
|
||||
This is where we avoid building the cathedral first.
|
||||
|
||||
### Mode 1: Embedded shared package
|
||||
|
||||
Recommended first cut.
|
||||
|
||||
- one shared `gamecult_access` package/module
|
||||
- each hosted experiment embeds it
|
||||
- each app keeps its own runtime and route integration
|
||||
- sessions may still be app-local
|
||||
- each app keeps its own domain-data store
|
||||
|
||||
Why this is the right first cut:
|
||||
|
||||
- reusable without forcing a separate always-on dependency
|
||||
- small blast radius
|
||||
- easy to evolve while only one or two apps use it
|
||||
|
||||
### Mode 2: Same-host shared access service
|
||||
|
||||
Use this when multiple apps on the same server want one shared access store and
|
||||
session issuer, but full centralization still feels premature.
|
||||
|
||||
### Mode 3: Dedicated GameCult access service
|
||||
|
||||
Only do this when multiple independently deployed apps genuinely need:
|
||||
|
||||
- shared cross-app sessions
|
||||
- central grant administration
|
||||
- one callback origin for all providers
|
||||
- enough auth churn that duplicated embedded deployments become the bigger pain
|
||||
|
||||
Do not build this first because it sounds important.
|
||||
|
||||
Even in this mode, the dedicated service should own auth/control-plane data, not
|
||||
absorb every app's audience or product data. If it starts trying to become the
|
||||
warehouse for StreamPixels viewer profiles, Repixelizer jobs, and whatever comes
|
||||
next, we have built a larger and more expensive mistake.
|
||||
|
||||
## Configuration split
|
||||
|
||||
Reusable shared config should stop pretending each app needs its own provider
|
||||
stack.
|
||||
|
||||
Suggested generic env surface:
|
||||
|
||||
- `GC_ACCESS_ENABLED=1`
|
||||
- `GC_ACCESS_SESSION_SECRET=...`
|
||||
- `GC_ACCESS_BASE_URL=https://access.gamecult.org` or host-app local equivalent
|
||||
- `GC_ACCESS_DISCORD_CLIENT_ID=...`
|
||||
- `GC_ACCESS_DISCORD_CLIENT_SECRET=...`
|
||||
- `GC_ACCESS_DISCORD_BOT_TOKEN=...`
|
||||
- `GC_ACCESS_DISCORD_GUILD_ID=...`
|
||||
- `GC_ACCESS_PATREON_CLIENT_ID=...`
|
||||
- `GC_ACCESS_PATREON_CLIENT_SECRET=...`
|
||||
- `GC_ACCESS_PATREON_CAMPAIGN_ID=...`
|
||||
- `GC_ACCESS_ENTITLEMENT_CACHE_TTL_SECONDS=900`
|
||||
- `GC_ACCESS_PROVIDER_FAILURE_GRACE_SECONDS=3600`
|
||||
|
||||
Per-app binding should live in code or profile config, not in a hundred cloned
|
||||
provider env names:
|
||||
|
||||
- app slug
|
||||
- hostnames
|
||||
- allowed Discord role ids
|
||||
- allowed Patreon tier ids
|
||||
- capability rules
|
||||
- public queue-summary policy, if any
|
||||
|
||||
## Recommended extraction path
|
||||
|
||||
1. Keep the repixelizer-specific note as an app profile, not the whole world.
|
||||
2. Extract the shared ideas into a reusable `gamecult_access` package or sibling
|
||||
repo once the first real implementation starts.
|
||||
3. Move provider OAuth, signed session handling, identity linking, entitlement
|
||||
refresh, and capability evaluation into that shared layer.
|
||||
4. Leave app-specific route gating and runtime ownership fields in the host app.
|
||||
5. Only consider a dedicated shared access service after a second hosted
|
||||
experiment proves the need.
|
||||
|
||||
## StreamPixels boundary example
|
||||
|
||||
StreamPixels is the obvious case where reuse must not become data mixing.
|
||||
|
||||
What StreamPixels can likely reuse:
|
||||
|
||||
- signed local session mechanics
|
||||
- linked-identity and OAuth-state patterns
|
||||
- creator/operator capability evaluation
|
||||
- provider adapter structure
|
||||
- grant/invite primitives where they fit
|
||||
|
||||
What StreamPixels should keep separate:
|
||||
|
||||
- viewer audience profiles
|
||||
- creator memberships tied to streamer spaces
|
||||
- creator connector credentials
|
||||
- overlay/runtime state
|
||||
- audience-facing app data in general
|
||||
|
||||
In plain terms:
|
||||
|
||||
- the same backbone can authenticate and authorize the control plane
|
||||
- StreamPixels audience data should remain StreamPixels data
|
||||
|
||||
If a future shared access store exists, it should not become the canonical home
|
||||
for streamer-audience identity and product data. That stays with StreamPixels.
|
||||
|
||||
## Audit Result
|
||||
|
||||
Yes, this can be made reusable.
|
||||
|
||||
The correct reusable seam is:
|
||||
|
||||
- shared provider/session/entitlement/capability machinery
|
||||
- thin per-app access profiles and runtime bindings
|
||||
|
||||
The incorrect reusable seam is:
|
||||
|
||||
- cloning a Repixelizer-specific auth blob into every future experiment and
|
||||
changing a few strings with a kitchen knife.
|
||||
- the hosted demo here still only has queue and limit machinery
|
||||
- no Discord login, Patreon login, linked identities, local sessions, or access
|
||||
gates are landed in `E:\Projects\repixelizer`
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ This file moved.
|
|||
|
||||
Use:
|
||||
|
||||
- `docs/gamecult-hosted-access-architecture.md` for the reusable shared design
|
||||
- `docs/repixelizer-hosted-access-profile.md` for the Repixelizer-specific binding
|
||||
- `E:\Projects\gamecult-access\docs\architecture.md` for the reusable shared design
|
||||
- `E:\Projects\gamecult-access\docs\app-profiles\repixelizer.md` for the Repixelizer-specific binding
|
||||
|
|
|
|||
|
|
@ -1,172 +1,22 @@
|
|||
# Repixelizer Hosted Access Profile
|
||||
|
||||
## What this file is
|
||||
This app-binding note moved.
|
||||
|
||||
This file binds Repixelizer onto the shared future design in
|
||||
`docs/gamecult-hosted-access-architecture.md`.
|
||||
Canonical location:
|
||||
|
||||
It is still future design, not a claim that the hosted demo already has auth.
|
||||
- `E:\Projects\gamecult-access\docs\app-profiles\repixelizer.md`
|
||||
|
||||
## Current repo boundary
|
||||
Shared architecture note:
|
||||
|
||||
Current live hosted-demo behavior is still just:
|
||||
- `E:\Projects\gamecult-access\docs\architecture.md`
|
||||
|
||||
- hosted-demo runtime limits and UI flags in `src/repixelizer/gui.py`
|
||||
- the local single-process queue in `src/repixelizer/gui.py`
|
||||
- frontend runtime-config consumption in `frontend/src/app.ts`
|
||||
This local file remains only as a redirect stub so Repixelizer does not keep a
|
||||
second copy of the same future auth plan fermenting in a corner.
|
||||
|
||||
No Discord login, Patreon login, linked identities, local sessions, or access
|
||||
gates are landed yet.
|
||||
Current repo truth is unchanged:
|
||||
|
||||
## App identity
|
||||
|
||||
- `app_slug`: `repixelizer`
|
||||
- primary hostname: `repixelizer.gamecult.org`
|
||||
- runtime shape: one hosted GUI plus one queue-backed worker loop inside the app
|
||||
|
||||
## Capabilities
|
||||
|
||||
Repixelizer does not need a baroque permission lattice.
|
||||
|
||||
The likely first-cut capabilities are:
|
||||
|
||||
- `app_access`
|
||||
- may load the protected hosted GUI
|
||||
- `queue_submit`
|
||||
- may create a repixelizer job
|
||||
- `job_read_own`
|
||||
- may read own job state, event stream, and final output
|
||||
- `job_cancel_own`
|
||||
- may cancel own queued or running job
|
||||
- `admin_access`
|
||||
- may inspect operational or grant/admin surfaces later
|
||||
|
||||
For the first cut:
|
||||
|
||||
```text
|
||||
queue_submit = app_access
|
||||
job_read_own = app_access + resource ownership check
|
||||
job_cancel_own = app_access + resource ownership check
|
||||
```
|
||||
|
||||
## Access policy
|
||||
|
||||
Repixelizer should inherit the generic GameCult access pattern:
|
||||
|
||||
```text
|
||||
app_access =
|
||||
discord.allowed_role
|
||||
|| patreon.allowed_tier
|
||||
|| grant.global_member
|
||||
|| grant.app_access
|
||||
|
||||
queue_submit = app_access
|
||||
|
||||
admin_access =
|
||||
grant.operator
|
||||
|| grant.admin_access
|
||||
```
|
||||
|
||||
Likely Discord-allowed examples:
|
||||
|
||||
- Patreon supporter role
|
||||
- founder role
|
||||
- moderator role
|
||||
- explicit alpha-tester role
|
||||
|
||||
Likely Patreon-allowed examples:
|
||||
|
||||
- any paid GameCult membership
|
||||
- or one configured subset of tiers if the experiment needs a stricter gate
|
||||
|
||||
## Repixelizer runtime binding
|
||||
|
||||
When this lands, the shared access layer should integrate with the current queue
|
||||
shape rather than replace it.
|
||||
|
||||
Suggested queue/job additions:
|
||||
|
||||
- `jobs.account_id`
|
||||
- `jobs.session_id`
|
||||
- `jobs.access_revision`
|
||||
- `jobs.entitlement_checked_at`
|
||||
|
||||
Route policy:
|
||||
|
||||
- public:
|
||||
- `/api/health`
|
||||
- `/api/config`
|
||||
- public or capability-gated by policy choice:
|
||||
- `/api/queue`
|
||||
- requires `queue_submit`:
|
||||
- `POST /api/jobs`
|
||||
- requires ownership:
|
||||
- `GET /api/jobs/{job_id}`
|
||||
- `GET /api/jobs/{job_id}/events`
|
||||
- `POST /api/jobs/{job_id}/heartbeat`
|
||||
- `DELETE /api/jobs/{job_id}`
|
||||
|
||||
Important invariant:
|
||||
|
||||
- job ownership must resolve from the local session/account, not from raw
|
||||
Discord or Patreon identifiers
|
||||
|
||||
## UI binding
|
||||
|
||||
Once access exists, the hosted landing flow should become:
|
||||
|
||||
- anonymous visitor sees:
|
||||
- `Log in with Discord`
|
||||
- `Log in with Patreon`
|
||||
- signed-in but denied visitor sees:
|
||||
- plain-English denial reason
|
||||
- what qualifies
|
||||
- link-the-other-provider affordance
|
||||
- allowed visitor sees:
|
||||
- the normal hosted GUI and queue flow
|
||||
|
||||
The queue/progress UI itself should stay as close as possible to the current
|
||||
runtime. The auth layer should gate entry, not rewrite the machine for fun.
|
||||
|
||||
## Config mapping
|
||||
|
||||
Repixelizer-specific auth config should not grow a separate provider jungle.
|
||||
|
||||
Keep:
|
||||
|
||||
- existing runtime/queue/limit env vars under `REPIXELIZER_*`
|
||||
|
||||
Add shared access config under `GC_ACCESS_*`.
|
||||
|
||||
Repixelizer-specific app-profile config can live under either:
|
||||
|
||||
- code constants, or
|
||||
- a small profile/config surface such as:
|
||||
- `GC_ACCESS_REPIXELIZER_ALLOWED_DISCORD_ROLE_IDS=...`
|
||||
- `GC_ACCESS_REPIXELIZER_ALLOWED_PATREON_TIER_IDS=...`
|
||||
- `GC_ACCESS_REPIXELIZER_PUBLIC_QUEUE_SUMMARY=1`
|
||||
|
||||
The exact encoding can be decided later. The important thing is not cloning the
|
||||
provider credentials into a second app-specific namespace.
|
||||
|
||||
## Recommended implementation order
|
||||
|
||||
1. Extract or embed the shared `gamecult_access` layer described in
|
||||
`docs/gamecult-hosted-access-architecture.md`.
|
||||
2. Gate `POST /api/jobs` plus per-job read/cancel/event routes through local
|
||||
sessions and ownership checks.
|
||||
3. Add login/link/denied-state UI around the existing hosted GUI shell.
|
||||
4. Decide whether `/api/queue` stays public summary or moves behind `app_access`.
|
||||
5. Only after a second hosted experiment exists, decide whether the shared
|
||||
access layer should leave embedded-package mode and become a shared service.
|
||||
|
||||
## Invariants
|
||||
|
||||
- Repixelizer should consume the shared access layer; it should not become the
|
||||
template that future experiments copy by hand.
|
||||
- The queue remains owned by local session/account ids.
|
||||
- Provider tokens stay server-side only.
|
||||
- Capability checks belong at route boundaries and resource ownership seams, not
|
||||
scattered through queue internals.
|
||||
- Auth should gate the hosted demo, not mutate the solver model or pretend to be
|
||||
the product.
|
||||
- hosted-demo runtime limits and UI flags still live in `E:\Projects\repixelizer\src\repixelizer\gui.py`
|
||||
- the queue is still the local single-process queue in that same module
|
||||
- frontend runtime-config consumption still lives in `E:\Projects\repixelizer\frontend\src\app.ts`
|
||||
- no Discord login, Patreon login, linked identities, local sessions, or access
|
||||
gates are landed here yet
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ Do not trust this file for the exact live HEAD. Always check git.
|
|||
- The current tracked weakness is the widened dark contour near the badge sword tip on tapered shapes.
|
||||
- `source_structure` exists because lattice-only `source_fidelity` could call visibly better outputs worse.
|
||||
- The old tray optimizer is dead and should stay dead unless the entire machine map changes for a real reason.
|
||||
- `docs/gamecult-hosted-access-architecture.md` is the future shared design for reusable GameCult-hosted access across experiments.
|
||||
- `docs/repixelizer-hosted-access-profile.md` is the Repixelizer-specific binding onto that future shared access layer.
|
||||
- `E:\Projects\gamecult-access\docs\architecture.md` is the future shared design for reusable GameCult-hosted access across experiments.
|
||||
- `E:\Projects\gamecult-access\docs\app-profiles\repixelizer.md` is the Repixelizer-specific binding onto that future shared access layer.
|
||||
- current hosted-demo truth is still just the queue and limit machinery in `src/repixelizer/gui.py` plus the frontend runtime-config plumbing.
|
||||
|
||||
## Critical Doctrine
|
||||
|
|
@ -92,8 +92,10 @@ Rules now in force:
|
|||
- this handoff is a compact re-entry packet.
|
||||
- `docs/implementation-plan.md` is the forward plan.
|
||||
- `docs/lean-optimizer-algorithm-map.md` is the source-grounded control-flow map.
|
||||
- `docs/gamecult-hosted-access-architecture.md` is future shared auth/access design, not live implementation truth.
|
||||
- `docs/repixelizer-hosted-access-profile.md` is the app-specific future binding, also not live implementation truth.
|
||||
- `E:\Projects\gamecult-access\docs\architecture.md` is future shared auth/access design, not live implementation truth.
|
||||
- `E:\Projects\gamecult-access\docs\app-profiles\repixelizer.md` is the app-specific future binding, also not live implementation truth.
|
||||
- local `docs/gamecult-hosted-access-architecture.md` and
|
||||
`docs/repixelizer-hosted-access-profile.md` are redirect stubs.
|
||||
|
||||
Do not let any one note become all of those things. That is how the tower grows
|
||||
sideways and starts calling itself architecture.
|
||||
|
|
|
|||
Loading…
Reference in a new issue