Exosphere is a set of small, modular, self-hostable community tools built on the AT Protocol. app.exosphere.site
7
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: update lexicon names

Hugo d9d9a72a e18ddd62

+40 -40
+4 -4
ARCHITECTURE.md
··· 131 131 132 132 | Lexicon ID | Published by | Purpose | 133 133 | ------------------------------------------- | ------------ | ------------------------------------------------------------------------ | 134 - | `site.exosphere.sphere` | Sphere owner | Sphere declaration (name, slug, visibility, modules) — enables discovery | 134 + | `site.exosphere.sphere.profile` | Sphere owner | Sphere declaration (name, slug, visibility, modules) — enables discovery | 135 135 | `site.exosphere.sphere.member` | Member | "I am a member of this Sphere" — member-side of bilateral membership | 136 136 | `site.exosphere.sphere.memberApproval` | Owner/admin | "This user is an approved member" — admin-side of bilateral membership | 137 137 | `site.exosphere.sphere.permissions` | Sphere owner | Permission overrides for core Sphere actions | 138 - | `site.exosphere.featureRequest` | Author | Feature request content | 138 + | `site.exosphere.featureRequest.entry` | Author | Feature request content | 139 139 | `site.exosphere.featureRequest.vote` | Voter | Upvote on a feature request | 140 140 | `site.exosphere.featureRequest.comment` | Commenter | Comment on a feature request | 141 141 | `site.exosphere.featureRequest.commentVote` | Voter | Upvote on a comment | ··· 173 173 174 174 ### Sphere declaration on PDS 175 175 176 - When a Sphere is created, the owner publishes a `site.exosphere.sphere` record on their PDS. This makes the Sphere discoverable by anyone crawling the AT Protocol network and serves as the canonical reference that other records (membership, content) point to via AT URI. 176 + When a Sphere is created, the owner publishes a `site.exosphere.sphere.profile` record on their PDS. This makes the Sphere discoverable by anyone crawling the AT Protocol network and serves as the canonical reference that other records (membership, content) point to via AT URI. 177 177 178 178 ### Private Spheres 179 179 ··· 308 308 309 309 ### Private Spheres and membership privacy 310 310 311 - For **private Spheres**, the Sphere record itself (`site.exosphere.sphere`) has `visibility: "private"`. The bilateral membership records are still published on PDS (since AT Protocol repos are public), but the Sphere's content remains off-protocol. A third party could see that a user is a member of a private Sphere, but cannot access the Sphere's content. This is an acceptable trade-off — membership is public, content is private — similar to how a private GitHub repository's collaborator list can be partially visible. 311 + For **private Spheres**, the Sphere record itself (`site.exosphere.sphere.profile`) has `visibility: "private"`. The bilateral membership records are still published on PDS (since AT Protocol repos are public), but the Sphere's content remains off-protocol. A third party could see that a user is a member of a private Sphere, but cannot access the Sphere's content. This is an acceptable trade-off — membership is public, content is private — similar to how a private GitHub repository's collaborator list can be partially visible. 312 312 313 313 If full membership privacy is required, operators can skip PDS writes for membership and rely solely on the local SQLite table. This sacrifices interoperability for privacy. 314 314
+1 -1
TODO.md
··· 60 60 ## Lexicons 61 61 62 62 - [x] Define formal Lexicon schemas for all AT Protocol record types (exact record shapes are still being defined) 63 - - [x] `site.exosphere.featureRequest` 63 + - [x] `site.exosphere.featureRequest.entry` 64 64 - [ ] Feed/post record types 65 65 - [ ] Set up Lexicon codegen for type-safe record handling 66 66
+27 -27
packages/core/src/generated/lexicon-records.ts
··· 1 1 // AUTO-GENERATED from landing/lexicons/site/exosphere/*.json 2 2 // Do not edit manually. Run: bun run generate:lexicons 3 3 4 - export interface FeatureRequestRecord { 5 - title: string; 6 - description?: string; 7 - category?: string; 8 - /** did — DID of the Sphere owner (the identity hosting the site.exosphere.sphere record). */ 9 - subject: string; 10 - /** datetime */ 11 - updatedAt?: string; 12 - } 13 - 14 4 export interface FeatureRequestCommentRecord { 15 5 /** at-uri — AT URI of the feature request being commented on. */ 16 6 subject: string; ··· 22 12 export interface FeatureRequestCommentVoteRecord { 23 13 /** at-uri — AT URI of the comment being voted on. */ 24 14 subject: string; 15 + } 16 + 17 + export interface FeatureRequestEntryRecord { 18 + title: string; 19 + description?: string; 20 + category?: string; 21 + /** did — DID of the Sphere owner (the identity hosting the site.exosphere.sphere.profile record). */ 22 + subject: string; 23 + /** datetime */ 24 + updatedAt?: string; 25 25 } 26 26 27 27 export interface FeatureRequestPermissionsRecord { ··· 58 58 action: string; 59 59 } 60 60 61 - export interface SphereRecord { 62 - /** Human-readable display name. */ 63 - name: string; 64 - /** Short description of the Sphere's purpose. */ 65 - description?: string; 66 - /** Whether the Sphere's content is publicly readable. */ 67 - visibility: string; 68 - /** Module names enabled for this Sphere. */ 69 - modules?: string[]; 70 - /** datetime */ 71 - createdAt: string; 72 - } 73 - 74 61 export interface SphereMemberRecord { 75 - /** at-uri — AT URI of the Sphere record (site.exosphere.sphere) on the owner's PDS. */ 62 + /** at-uri — AT URI of the Sphere record (site.exosphere.sphere.profile) on the owner's PDS. */ 76 63 sphere: string; 77 64 } 78 65 79 66 export interface SphereMemberApprovalRecord { 80 - /** at-uri — AT URI of the Sphere record (site.exosphere.sphere). */ 67 + /** at-uri — AT URI of the Sphere record (site.exosphere.sphere.profile). */ 81 68 sphere: string; 82 69 /** did — DID of the member being approved. */ 83 70 subject: string; ··· 100 87 updatePermissions?: string; 101 88 } 102 89 90 + export interface SphereProfileRecord { 91 + /** Human-readable display name. */ 92 + name: string; 93 + /** Short description of the Sphere's purpose. */ 94 + description?: string; 95 + /** Whether the Sphere's content is publicly readable. */ 96 + visibility: string; 97 + /** Module names enabled for this Sphere. */ 98 + modules?: string[]; 99 + /** datetime */ 100 + createdAt: string; 101 + } 102 + 103 103 export interface PdsRecordMap { 104 - "site.exosphere.featureRequest": FeatureRequestRecord; 105 104 "site.exosphere.featureRequest.comment": FeatureRequestCommentRecord; 106 105 "site.exosphere.featureRequest.commentVote": FeatureRequestCommentVoteRecord; 106 + "site.exosphere.featureRequest.entry": FeatureRequestEntryRecord; 107 107 "site.exosphere.featureRequest.permissions": FeatureRequestPermissionsRecord; 108 108 "site.exosphere.featureRequest.status": FeatureRequestStatusRecord; 109 109 "site.exosphere.featureRequest.vote": FeatureRequestVoteRecord; 110 110 "site.exosphere.moderation": ModerationRecord; 111 - "site.exosphere.sphere": SphereRecord; 112 111 "site.exosphere.sphere.member": SphereMemberRecord; 113 112 "site.exosphere.sphere.memberApproval": SphereMemberApprovalRecord; 114 113 "site.exosphere.sphere.permissions": SpherePermissionsRecord; 114 + "site.exosphere.sphere.profile": SphereProfileRecord; 115 115 }
+1 -1
packages/core/src/sphere/api/members.ts
··· 12 12 import { findSphere } from "./helpers.ts"; 13 13 import { resolveDidHandles } from "../../identity/index.ts"; 14 14 15 - const SPHERE_COLLECTION = "site.exosphere.sphere"; 15 + const SPHERE_COLLECTION = "site.exosphere.sphere.profile"; 16 16 const MEMBER_COLLECTION = "site.exosphere.sphere.member"; 17 17 const APPROVAL_COLLECTION = "site.exosphere.sphere.memberApproval"; 18 18
+1 -1
packages/core/src/sphere/api/modules.ts
··· 9 9 import { enableModuleSchema } from "../schemas.ts"; 10 10 import { findSphere, getEnabledModules, formatModules } from "./helpers.ts"; 11 11 12 - const SPHERE_COLLECTION = "site.exosphere.sphere" as const; 12 + const SPHERE_COLLECTION = "site.exosphere.sphere.profile" as const; 13 13 14 14 type Sphere = typeof spheres.$inferSelect; 15 15
+1 -1
packages/core/src/sphere/api/spheres.ts
··· 10 10 import { computeUserPermissions } from "../../permissions/check.ts"; 11 11 import { findSphere, getEnabledModules, formatModules } from "./helpers.ts"; 12 12 13 - const SPHERE_COLLECTION = "site.exosphere.sphere"; 13 + const SPHERE_COLLECTION = "site.exosphere.sphere.profile"; 14 14 15 15 /** Return spheres the given DID is an active member of, including their role. */ 16 16 export function getMemberSpheres(did: string) {
+1 -1
packages/core/src/sphere/indexer.ts
··· 12 12 } from "./operations.ts"; 13 13 import { getAllPermissionsCollections } from "../permissions/index.ts"; 14 14 15 - const SPHERE_COLLECTION = "site.exosphere.sphere"; 15 + const SPHERE_COLLECTION = "site.exosphere.sphere.profile"; 16 16 const MEMBER_COLLECTION = "site.exosphere.sphere.member"; 17 17 const APPROVAL_COLLECTION = "site.exosphere.sphere.memberApproval"; 18 18 const MODERATION_COLLECTION = "site.exosphere.moderation";
+1 -1
packages/feature-requests/src/api/comments.ts
··· 288 288 289 289 // Admin moderation — publish moderation record on admin's PDS, hide locally 290 290 if (comment.pdsUri) { 291 - const sphereUri = spherePdsUri ?? `at://${sphereOwnerDid}/site.exosphere.sphere/self`; 291 + const sphereUri = spherePdsUri ?? `at://${sphereOwnerDid}/site.exosphere.sphere.profile/self`; 292 292 const session = c.var.session; 293 293 const pdsUri = await putPdsRecord(session, MODERATION_COLLECTION, id, { 294 294 sphere: sphereUri,
+2 -2
packages/feature-requests/src/api/requests.ts
··· 17 17 unhideFeatureRequest, 18 18 } from "../db/operations.ts"; 19 19 20 - const COLLECTION = "site.exosphere.featureRequest"; 20 + const COLLECTION = "site.exosphere.featureRequest.entry"; 21 21 const MODERATION_COLLECTION = "site.exosphere.moderation"; 22 22 23 23 const app = new Hono<AuthEnv & SphereEnv>(); ··· 263 263 264 264 // Publish moderation record on admin's PDS 265 265 if (existing.pdsUri) { 266 - const sphereUri = spherePdsUri ?? `at://${sphereOwnerDid}/site.exosphere.sphere/self`; 266 + const sphereUri = spherePdsUri ?? `at://${sphereOwnerDid}/site.exosphere.sphere.profile/self`; 267 267 const session = c.var.session; 268 268 const pdsUri = await putPdsRecord(session, MODERATION_COLLECTION, id, { 269 269 sphere: sphereUri,
+1 -1
packages/feature-requests/src/indexer.ts
··· 25 25 registerModerationHandler(handleFeatureRequestModeration); 26 26 27 27 const MODULE_NAME = "feature-requests"; 28 - const COLLECTION = "site.exosphere.featureRequest"; 28 + const COLLECTION = "site.exosphere.featureRequest.entry"; 29 29 const VOTE_COLLECTION = "site.exosphere.featureRequest.vote"; 30 30 const COMMENT_COLLECTION = "site.exosphere.featureRequest.comment"; 31 31 const COMMENT_VOTE_COLLECTION = "site.exosphere.featureRequest.commentVote";