2026-06-02 16:25:38 +01:00
|
|
|
# Spotiverse App Profile
|
|
|
|
|
|
Retire the Spotiverse profile; keep the spotify provider intact for restore
Spotiverse was lost with the E: drive and has no repository in the swarm,
but /v1/oauth/spotify/start stayed publicly reachable and
GC_ACCESS_PROVIDER_SPOTIFY_CLIENT_ID/_SECRET stayed configured on
yggdrasil. That path would have run a real OAuth handshake against a real
secret and taken custody of a user's Spotify refresh token for a consumer
that could not use it.
The seam is supportsProvider(profile, provider): a provider with no app
behind it is unreachable. So the registry entry is what had to go, not the
provider.
Removed: spotiverseProfile and its registry entry, the spotiverse slug
from appSlugs, the hardcoded callback arm in app.ts, and three
spotiverse-specific tests. Removed from the host: the two spotify env
vars, backed up to /root/heimdall-service.env.bak-20260906-spotify. Nine
other provider vars and the file's 0600 heimdall:heimdall ownership are
untouched.
Kept deliberately: the entire spotify provider -- the providers.ts catalog
entry, spotifyRuntime and its token/profile exchange in oauth.ts, and
"spotify" in the providers union. It is intact and unreferenced, which is
what makes restoring a registry change rather than protocol work. The
capability is wanted back; a Persona managing the queue during a stream is
the motivating case.
docs/app-profiles/spotiverse.md is now the restore spec rather than an
archive: what was removed, what was kept, the base commit 5a15f71 to
recover the profile verbatim, and the daemon's callback URL
(http://127.0.0.1:8796/auth/heimdall/callback), which existed only in a
hardcoded allowlist arm and would otherwise have been lost with it.
Before deleting the three tests I checked their routes keep coverage:
managed-credential resolve is exercised twice via streampixels, and
backend_callback handoff at three other sites. The generic
untrusted_backend_callback negative test was retargeted to bifrost rather
than deleted. 35 pass, 9 files; tsc clean.
Verified the deployed build still boots without the vars --
readProviderConfig returns an empty config rather than throwing, so the
running release fails that route at request time instead of at startup.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 01:47:10 +02:00
|
|
|
> **RETIRED from the live registry 2026-09-06. This document is the restore
|
|
|
|
|
> spec — it is deliberately kept current, not archived.**
|
|
|
|
|
>
|
|
|
|
|
> Spotiverse was a small daemon exposing the Spotify API to agents. It was lost
|
|
|
|
|
> with the `E:` drive and has no repository in the swarm. The capability is
|
|
|
|
|
> wanted back — letting a Persona manage the queue during a stream is the
|
|
|
|
|
> motivating case — so this profile was removed in a way that is cheap to undo.
|
|
|
|
|
>
|
|
|
|
|
> **What was removed:** the `spotiverseProfile` object and its registry entry in
|
|
|
|
|
> `src/app-profiles.ts`, the `spotiverse` slug from `appSlugs` in
|
|
|
|
|
> `src/contracts.ts`, the hardcoded callback arm in `src/app.ts`, and three
|
|
|
|
|
> spotiverse-specific tests in `tests/app.test.ts`.
|
|
|
|
|
>
|
|
|
|
|
> **What was deliberately kept:** the whole `spotify` OAuth provider — the
|
|
|
|
|
> catalog entry in `src/providers.ts`, `spotifyRuntime` and its token/profile
|
|
|
|
|
> exchange in `src/oauth.ts`, and `"spotify"` in the `providers` union in
|
|
|
|
|
> `src/contracts.ts`. The provider is intact and unreferenced. Runtime health
|
|
|
|
|
> still reports `providers=2/6`, which counts it.
|
|
|
|
|
>
|
|
|
|
|
> **Why it was removed anyway:** `/v1/oauth/spotify/start` is gated by
|
2026-10-19 12:31:59 +02:00
|
|
|
> `admitsProviderForMode(profile, provider, mode)`, so a provider with no app behind it is
|
Retire the Spotiverse profile; keep the spotify provider intact for restore
Spotiverse was lost with the E: drive and has no repository in the swarm,
but /v1/oauth/spotify/start stayed publicly reachable and
GC_ACCESS_PROVIDER_SPOTIFY_CLIENT_ID/_SECRET stayed configured on
yggdrasil. That path would have run a real OAuth handshake against a real
secret and taken custody of a user's Spotify refresh token for a consumer
that could not use it.
The seam is supportsProvider(profile, provider): a provider with no app
behind it is unreachable. So the registry entry is what had to go, not the
provider.
Removed: spotiverseProfile and its registry entry, the spotiverse slug
from appSlugs, the hardcoded callback arm in app.ts, and three
spotiverse-specific tests. Removed from the host: the two spotify env
vars, backed up to /root/heimdall-service.env.bak-20260906-spotify. Nine
other provider vars and the file's 0600 heimdall:heimdall ownership are
untouched.
Kept deliberately: the entire spotify provider -- the providers.ts catalog
entry, spotifyRuntime and its token/profile exchange in oauth.ts, and
"spotify" in the providers union. It is intact and unreferenced, which is
what makes restoring a registry change rather than protocol work. The
capability is wanted back; a Persona managing the queue during a stream is
the motivating case.
docs/app-profiles/spotiverse.md is now the restore spec rather than an
archive: what was removed, what was kept, the base commit 5a15f71 to
recover the profile verbatim, and the daemon's callback URL
(http://127.0.0.1:8796/auth/heimdall/callback), which existed only in a
hardcoded allowlist arm and would otherwise have been lost with it.
Before deleting the three tests I checked their routes keep coverage:
managed-credential resolve is exercised twice via streampixels, and
backend_callback handoff at three other sites. The generic
untrusted_backend_callback negative test was retargeted to bifrost rather
than deleted. 35 pass, 9 files; tsc clean.
Verified the deployed build still boots without the vars --
readProviderConfig returns an empty config rather than throwing, so the
running release fails that route at request time instead of at startup.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 01:47:10 +02:00
|
|
|
> unreachable. While the profile existed, that path was publicly reachable and
|
|
|
|
|
> would have run a real OAuth handshake against a real client secret, taking
|
|
|
|
|
> custody of a user's Spotify refresh token on behalf of a consumer that could
|
|
|
|
|
> not use it. Removing the profile closes the path; keeping the provider keeps
|
|
|
|
|
> the capability.
|
|
|
|
|
|
|
|
|
|
## Restoring
|
|
|
|
|
|
|
|
|
|
Everything below this line is still accurate. To bring Spotiverse back:
|
|
|
|
|
|
|
|
|
|
1. Re-add `spotiverseProfile` and its registry entry to `src/app-profiles.ts`,
|
|
|
|
|
and `"spotiverse"` to `appSlugs` in `src/contracts.ts`. Both are recoverable
|
|
|
|
|
verbatim from commit `5a15f71`, the last commit before removal.
|
|
|
|
|
2. Re-add the backend callback arm in `src/app.ts`. The daemon ran on
|
|
|
|
|
**`http://127.0.0.1:8796/auth/heimdall/callback`**; that exact URL was the
|
|
|
|
|
allowlisted value.
|
|
|
|
|
3. Configure `GC_ACCESS_PROVIDER_SPOTIFY_CLIENT_ID` and
|
2026-09-30 13:52:11 +02:00
|
|
|
`GC_ACCESS_PROVIDER_SPOTIFY_CLIENT_SECRET_FILE` pointing at a credential file.
|
Retire the Spotiverse profile; keep the spotify provider intact for restore
Spotiverse was lost with the E: drive and has no repository in the swarm,
but /v1/oauth/spotify/start stayed publicly reachable and
GC_ACCESS_PROVIDER_SPOTIFY_CLIENT_ID/_SECRET stayed configured on
yggdrasil. That path would have run a real OAuth handshake against a real
secret and taken custody of a user's Spotify refresh token for a consumer
that could not use it.
The seam is supportsProvider(profile, provider): a provider with no app
behind it is unreachable. So the registry entry is what had to go, not the
provider.
Removed: spotiverseProfile and its registry entry, the spotiverse slug
from appSlugs, the hardcoded callback arm in app.ts, and three
spotiverse-specific tests. Removed from the host: the two spotify env
vars, backed up to /root/heimdall-service.env.bak-20260906-spotify. Nine
other provider vars and the file's 0600 heimdall:heimdall ownership are
untouched.
Kept deliberately: the entire spotify provider -- the providers.ts catalog
entry, spotifyRuntime and its token/profile exchange in oauth.ts, and
"spotify" in the providers union. It is intact and unreferenced, which is
what makes restoring a registry change rather than protocol work. The
capability is wanted back; a Persona managing the queue during a stream is
the motivating case.
docs/app-profiles/spotiverse.md is now the restore spec rather than an
archive: what was removed, what was kept, the base commit 5a15f71 to
recover the profile verbatim, and the daemon's callback URL
(http://127.0.0.1:8796/auth/heimdall/callback), which existed only in a
hardcoded allowlist arm and would otherwise have been lost with it.
Before deleting the three tests I checked their routes keep coverage:
managed-credential resolve is exercised twice via streampixels, and
backend_callback handoff at three other sites. The generic
untrusted_backend_callback negative test was retargeted to bifrost rather
than deleted. 35 pass, 9 files; tsc clean.
Verified the deployed build still boots without the vars --
readProviderConfig returns an empty config rather than throwing, so the
running release fails that route at request time instead of at startup.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 01:47:10 +02:00
|
|
|
They were removed from `/srv/heimdall/env/service.env` on retirement, so a
|
|
|
|
|
fresh Spotify application registration may be needed.
|
|
|
|
|
4. Restore the three tests from `5a15f71` if the capabilities they covered
|
|
|
|
|
(managed-credential resolve for spotify, portal backend callbacks) are not
|
|
|
|
|
otherwise exercised. At retirement both were covered independently by the
|
|
|
|
|
`streampixels` managed-credential tests and the generic
|
|
|
|
|
`untrusted_backend_callback` test, so no coverage was lost by removing them.
|
|
|
|
|
|
|
|
|
|
No provider or protocol work is required. The retirement was a registry change.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-06-02 16:25:38 +01:00
|
|
|
Spotiverse consumes Heimdall as a managed Spotify credential authority.
|
|
|
|
|
|
|
|
|
|
## Boundary
|
|
|
|
|
|
|
|
|
|
- Heimdall owns Spotify OAuth, linked identity custody, refresh-token custody,
|
|
|
|
|
and managed access-token projection.
|
|
|
|
|
- Spotiverse owns Spotify playback polling, queue command execution, command
|
|
|
|
|
receipts, and its CultMesh/Eve provider surface.
|
|
|
|
|
- Odin, Eve, VoidBot Faces, and renderers consume the surface and command
|
|
|
|
|
boundary; they do not receive Spotify tokens.
|
|
|
|
|
|
|
|
|
|
## Providers
|
|
|
|
|
|
|
|
|
|
- identity providers: `spotify`
|
|
|
|
|
- entitlement sources: none
|
|
|
|
|
- managed connection providers: `spotify`
|
|
|
|
|
|
|
|
|
|
## Capabilities
|
|
|
|
|
|
|
|
|
|
- `spotify_player_read`: shared capability after a linked Spotify identity.
|
|
|
|
|
- `spotify_queue_add`: shared capability after a linked Spotify identity;
|
|
|
|
|
Spotiverse still owns URI validation and command receipts.
|
|
|
|
|
|
|
|
|
|
## Local Configuration
|
|
|
|
|
|
|
|
|
|
Heimdall needs:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
GC_ACCESS_PROVIDER_SPOTIFY_CLIENT_ID=...
|
2026-09-30 13:52:11 +02:00
|
|
|
GC_ACCESS_PROVIDER_SPOTIFY_CLIENT_SECRET_FILE=/absolute/path/to/spotify-client-secret
|
2026-06-02 19:25:14 +01:00
|
|
|
GC_ACCESS_APP_SPOTIVERSE_BACKEND_CALLBACK_URLS=https://your-spotiverse-portal.example/auth/heimdall/callback
|
2026-06-02 16:25:38 +01:00
|
|
|
```
|
|
|
|
|
|
2026-09-30 14:40:21 +02:00
|
|
|
Spotiverse needs only the Heimdall base URL and local portal callback/return
|
|
|
|
|
URLs. The callback URL Spotiverse sends in
|
2026-06-02 19:25:14 +01:00
|
|
|
`HEIMDALL_CALLBACK_URL` must exactly match one URL in Heimdall's
|
|
|
|
|
`GC_ACCESS_APP_SPOTIVERSE_BACKEND_CALLBACK_URLS` allowlist unless both services
|
|
|
|
|
are running on the same local host.
|