begin embedded pds with xrpc endpoints and well-known
This commit is contained in:
@@ -510,40 +510,58 @@ With embedded PDS:
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: Basic PDS with Carstore (Current)
|
||||
### Phase 1: Basic PDS with Carstore ✅ COMPLETED
|
||||
|
||||
**Decision: Use indigo's carstore with SQLite backend**
|
||||
**Implementation: Using indigo's carstore with SQLite + DeltaSession**
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/bluesky-social/indigo/carstore"
|
||||
"github.com/bluesky-social/indigo/models"
|
||||
"github.com/bluesky-social/indigo/repo"
|
||||
)
|
||||
|
||||
type HoldPDS struct {
|
||||
did string
|
||||
carstore carstore.CarStore
|
||||
repo *repo.Repo
|
||||
did string
|
||||
carstore carstore.CarStore
|
||||
session *carstore.DeltaSession // Provides blockstore interface
|
||||
repo *repo.Repo
|
||||
dbPath string
|
||||
uid models.Uid // User ID for carstore (fixed: 1)
|
||||
}
|
||||
|
||||
func NewHoldPDS(did, dbPath string) (*HoldPDS, error) {
|
||||
func NewHoldPDS(ctx context.Context, did, dbPath string) (*HoldPDS, error) {
|
||||
// Create SQLite-backed carstore
|
||||
sqlStore, err := carstore.NewSqliteStore(dbPath)
|
||||
sqlStore.Open(dbPath)
|
||||
cs := sqlStore.CarStore()
|
||||
|
||||
// Get or create repo
|
||||
head, err := cs.GetUserRepoHead(ctx, did)
|
||||
var r *repo.Repo
|
||||
if err == carstore.ErrRepoNotFound {
|
||||
r, err = repo.NewRepo(ctx, did, cs.Blockstore())
|
||||
} else {
|
||||
r, err = repo.OpenRepo(ctx, cs.Blockstore(), head)
|
||||
}
|
||||
// For single-hold use, fixed UID
|
||||
uid := models.Uid(1)
|
||||
|
||||
return &HoldPDS{did: did, carstore: cs, repo: r}, nil
|
||||
// Create DeltaSession (provides blockstore interface)
|
||||
session, err := cs.NewDeltaSession(ctx, uid, nil)
|
||||
|
||||
// Create repo with session as blockstore
|
||||
r := repo.NewRepo(ctx, did, session)
|
||||
|
||||
return &HoldPDS{
|
||||
did: did,
|
||||
carstore: cs,
|
||||
session: session,
|
||||
repo: r,
|
||||
dbPath: dbPath,
|
||||
uid: uid,
|
||||
}, nil
|
||||
}
|
||||
```
|
||||
|
||||
**Key learnings:**
|
||||
- ✅ Carstore provides blockstore via `DeltaSession` (not direct access)
|
||||
- ✅ `models.Uid` is the user ID type (we use fixed UID(1))
|
||||
- ✅ DeltaSession needs to be a pointer (`*carstore.DeltaSession`)
|
||||
- ✅ `repo.NewRepo()` accepts the session directly as blockstore
|
||||
|
||||
**Storage:**
|
||||
- Single file: `/var/lib/atcr-hold/hold.db` (SQLite)
|
||||
- Contains MST nodes, records, commits in carstore tables
|
||||
@@ -552,10 +570,10 @@ func NewHoldPDS(did, dbPath string) (*HoldPDS, error) {
|
||||
**Why SQLite carstore:**
|
||||
- ✅ Single file persistence (like appview's SQLite)
|
||||
- ✅ Official indigo storage backend
|
||||
- ✅ No custom blockstore implementation needed
|
||||
- ✅ Handles compaction/cleanup automatically
|
||||
- ✅ Migration path to Postgres/Scylla if needed
|
||||
- ✅ Easy to replicate (Litestream, LiteFS, rsync)
|
||||
- ✅ CAR import/export support built-in
|
||||
|
||||
**Scale considerations:**
|
||||
- SQLite carstore marked "experimental" but suitable for single-hold use
|
||||
@@ -564,6 +582,27 @@ func NewHoldPDS(did, dbPath string) (*HoldPDS, error) {
|
||||
- Bluesky PDSs use carstore for millions of records
|
||||
- If needed: migrate to Postgres-backed carstore (same API)
|
||||
|
||||
### Hold as Proper ATProto User
|
||||
|
||||
**Decision:** Make holds full ATProto actors for discoverability and ecosystem integration.
|
||||
|
||||
**What this enables:**
|
||||
- Hold becomes discoverable via ATProto directory
|
||||
- Can have profile (`app.bsky.actor.profile`)
|
||||
- Can post status updates (`app.bsky.feed.post`)
|
||||
- Users can follow holds
|
||||
- Social proof/reputation via ATProto social graph
|
||||
|
||||
**MVP Scope:**
|
||||
We're building the minimal PDS needed for discoverability, not a full social client:
|
||||
- ✅ Signing keys (ES256K via `atproto/atcrypto`)
|
||||
- ✅ DID document (did:web at `/.well-known/did.json`)
|
||||
- ✅ Standard XRPC endpoints (`describeRepo`, `getRecord`, `listRecords`)
|
||||
- ✅ Profile record (`app.bsky.actor.profile`)
|
||||
- ⏸️ Posting functionality (later - other services can read our records)
|
||||
|
||||
**Key insight:** Other ATProto services will "just work" as long as they can retrieve records from the hold's PDS. We don't need to implement full social features for the hold to participate in the ecosystem.
|
||||
|
||||
### Crew Management: Individual Records
|
||||
|
||||
**Decision: Individual crew record per user (remove wildcard logic)**
|
||||
|
||||
Reference in New Issue
Block a user