No description
  • TypeScript 92.2%
  • C++ 5.6%
  • Python 2.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Meta Vens ca2366cecf Schema check: validity is the rule; pin the printed predicates
The mutations dropping indisvalid or indisready each survived alone,
because a failed CREATE INDEX CONCURRENTLY clears both. Postgres never
marks an index valid before it is ready (DROP INDEX CONCURRENTLY clears
validity first), so indisready adds nothing and is deleted. A fixture now
holds an index that is ready but not valid, the state an interrupted DROP
INDEX CONCURRENTLY leaves, set directly in pg_index by the admin role.

Comparing the raw declared predicate instead of Postgres's printing of it
survived too: the schema's one predicate splits into the same conditions
either way. A live test now pins printedDeclaredPredicates to the printed
predicate of the applied attempt index, so the printing itself is
checked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 21:28:50 +02:00
.voidbot/state Seed Heimdall social interpretation biases 2026-05-24 20:39:24 +01:00
assets Add Heimdall profile avatar 2026-05-20 18:52:21 +01:00
deployment/idunn Pin the recipe's secret declarations, and declare every app secret file 2026-09-30 14:40:21 +02:00
docs Docs: secrets are _FILE names; drop the unread Spotiverse secret 2026-09-30 14:40:21 +02:00
notes Docs: secrets are _FILE names; drop the unread Spotiverse secret 2026-09-30 14:40:21 +02:00
plugins/gamecult.heimdall.access Resume browser sign-in by attempt id, not the completion code 2026-09-23 20:50:28 +02:00
schemas Bind auth completions to their attempt handles 2026-08-22 12:01:56 +02:00
src Schema check: validity is the rule; pin the printed predicates 2026-09-30 21:28:50 +02:00
state REC-114: delete completed emergency-compaction scratch 2026-09-13 14:15:37 +02:00
tests Schema check: validity is the rule; pin the printed predicates 2026-09-30 21:28:50 +02:00
tools Rename repo to Heimdall 2026-04-26 11:41:27 +01:00
vendor Bump vendored CultLib for the bounded fragment reassembly map 2026-09-10 11:50:49 +02:00
.env.example Docs: secrets are _FILE names; drop the unread Spotiverse secret 2026-09-30 14:40:21 +02:00
.gitignore Ignore local secret files 2026-04-29 12:23:45 +01:00
.gitmodules Vendor CultLib as a gitlink so Heimdall's source can be sealed 2026-09-06 00:42:45 +02:00
AGENTS.md Name the Linux deploy target for the auth authority 2026-09-08 12:23:44 +02:00
CLAUDE.md Drop the Codex framing from the doctrine import 2026-09-06 00:39:45 +02:00
LICENSE Add MIT license 2026-09-05 21:54:09 +02:00
package.json Follow CultLib's package rename and select workspaces by path 2026-09-07 22:26:24 +02:00
pnpm-lock.yaml Follow CultLib's package rename and select workspaces by path 2026-09-07 22:26:24 +02:00
README.md Record Odin-discovered access deployment 2026-08-22 04:08:36 +02:00
tsconfig.json Resume Heimdall auth from browser return witness 2026-08-22 11:42:28 +02:00
vitest.config.ts Limit Vitest to source test tree 2026-04-26 12:25:53 +01:00

Heimdall

Heimdall is the shared auth authority taking shape for GameCult-hosted experiments.

The point is painfully simple:

  • stop rebuilding Discord/Patreon login glue in every app
  • keep provider OAuth, linked identities, grants, entitlements, and session issuance in one place
  • let app runtimes verify signed claims locally so "shared auth" does not become "everything phones home for every request"
  • keep app-domain data separate so "shared auth" does not become "shared swamp"

Current Shape

This repo now has a stateful first slice instead of a decorative skeleton.

Landed right now:

  • a TypeScript/Fastify service scaffold under src/
  • Ed25519 JWT signing plus /.well-known/jwks.json
  • file-backed signing-key loading/bootstrap so restart does not vaporize the service identity when you configure a real key path
  • signed OAuth start-state scaffolding for Discord, Patreon, GitHub, Twitch, YouTube, and Spotify
  • durable auth/control-plane storage with in-memory and Postgres backends
  • account, linked-identity, session, persistent OAuth attempt, grant, entitlement snapshot, and audit persistence
  • a real Discord OAuth callback path for the first Repixelizer access flow
  • direct backend callback handoff for same-host or Yggdrasil-reachable app backends
  • AES-256-GCM sealing for managed provider tokens at rest
  • a one-time browser completion exchange kept as fallback for opener postMessage handoff
  • app profile surfaces for Repixelizer, StreamPixels, and Spotiverse
  • signed claim issuance for app-local verification experiments
  • a local verifier helper in src/verifier.ts so app backends can validate Heimdall JWTs without phoning home on every guarded request
  • a read-only Odin/Eve provider advertisement export that names redacted CultCache witness document shapes and paths without touching live secrets
  • a daemon-owned CultCache boundary witness at GC_ACCESS_CULTCACHE_PATH containing the Heimdall provider advertisement, command boundary, transport profile, and Idunn daemon-health summary
  • optional Idunn daemon-health publication over cultnet.transport.rudp.v0 when GC_ACCESS_IDUNN_RUDP_HEALTH is configured
  • the gamecult.heimdall.access Eve plugin with executable describe, validate, and project operations plus a browser reference adapter
  • a loopback-only CultNet operation boundary on port 4101 for authenticated heimdall.auth.begin and heimdall.auth.complete; app payloads and completion claims are AES-256-GCM wrapped and HMAC-bound to expiry, nonce, operation, runtime, and idempotency identity
  • redacted provider, command-boundary, plugin, and transport records published through Odin under unique typed catalog keys; secret-bearing auth state never enters the catalog
  • the deployed Ghostlight Eve host consumes that discovered boundary and keeps routine app-session verification local

Remaining work:

  • the two-account and eight-account Ghostlight human canaries
  • refresh/revocation flows and admin surfaces
  • broader admin and inspection projections beyond the redacted access boundary

Canonical docs:

  • docs/architecture.md
  • docs/implementation-plan.md
  • docs/service-contract.md
  • docs/verse-service-contract.md
  • docs/app-profiles/repixelizer.md
  • docs/app-profiles/streampixels.md
  • docs/app-profiles/spotiverse.md
  • state/map.yaml
  • notes/fresh-workspace-handoff.md

Dev Commands

pnpm install
pnpm dev
pnpm test
pnpm build
pnpm export:provider-advertisement

Working Loop

  1. Rehydrate from canonical state.
  2. Keep identity authority central and app-domain data local.
  3. Prefer a Yggdrasil-hosted shared service over duplicated per-app provider stacks.
  4. Let app backends verify signed claims locally instead of begging Heimdall on every guarded route.
  5. Commit finished passes before the notes start breeding.