102 lines
3.7 KiB
Markdown
102 lines
3.7 KiB
Markdown
User approved Claude's plan:
|
|
⎿ Implement Sailor Profile & Hold Discovery System
|
|
|
|
Summary
|
|
|
|
Add io.atcr.sailor.profile record type to manage user's default hold preference, and update manifest to store historical hold endpoint reference. This enables transparent hold
|
|
routing while preserving image ownership semantics.
|
|
|
|
Changes Required
|
|
|
|
1. Create Sailor Profile Lexicon
|
|
|
|
File: lexicons/io/atcr/sailor/profile.json
|
|
- New record type: io.atcr.sailor.profile
|
|
- Fields: defaultHold (string, nullable), createdAt, updatedAt
|
|
|
|
2. Update Manifest Lexicon
|
|
|
|
File: lexicons/io/atcr/manifest.json
|
|
- Add holdEndpoint field (string, required)
|
|
- This is historical reference (immutable per manifest)
|
|
|
|
3. Update Go Types
|
|
|
|
File: pkg/atproto/lexicon.go
|
|
- Add SailorProfileCollection = "io.atcr.sailor.profile"
|
|
- Add SailorProfileRecord struct
|
|
- Add NewSailorProfileRecord() constructor
|
|
- Update ManifestRecord struct to include HoldEndpoint field
|
|
|
|
4. Create Profile Management
|
|
|
|
File: pkg/atproto/profile.go (new file)
|
|
- EnsureProfile(ctx, client, defaultHoldEndpoint) function
|
|
- Logic: check if profile exists, create with default if not
|
|
|
|
5. Update Auth Handlers
|
|
|
|
Files: pkg/auth/exchange/handler.go and pkg/auth/token/service.go
|
|
- Call EnsureProfile() after token validation
|
|
- Use authenticated client (has write access to user's PDS)
|
|
- Pass AppView's default_hold_endpoint config
|
|
|
|
6. Update Hold Resolution
|
|
|
|
File: pkg/middleware/registry.go
|
|
- Update findStorageEndpoint() priority:
|
|
a. Check io.atcr.sailor.profile.defaultHold
|
|
b. If null (opted out): check user's io.atcr.hold, then AppView default
|
|
c. If no profile: check user's io.atcr.hold, then AppView default
|
|
|
|
7. Store Hold in Manifest
|
|
|
|
File: pkg/atproto/manifest_store.go
|
|
- When creating manifest, include resolved holdEndpoint
|
|
- Pass hold endpoint through context or parameter
|
|
|
|
8. Update Pull to Use Manifest Hold
|
|
|
|
File: pkg/atproto/manifest_store.go and pkg/storage/routing_repository.go
|
|
- On pull, extract holdEndpoint from manifest
|
|
- Route blob requests to that hold (not via discovery)
|
|
|
|
9. Update Documentation
|
|
|
|
Files: CLAUDE.md, docs/BYOS.md, .env.example
|
|
- Document sailor profile concept
|
|
- Explain hold resolution priority
|
|
- Update examples for shared holds
|
|
- Document how crew members configure profile
|
|
|
|
Benefits
|
|
|
|
- ✅ URL structure remains atcr.io/<owner>/<image> (ownership clear)
|
|
- ✅ Hold is transparent infrastructure (like S3 region)
|
|
- ✅ Supports personal, shared, and public holds
|
|
- ✅ Historical reference in manifest (pull works even if defaults change)
|
|
- ✅ User can opt-out (set defaultHold to null)
|
|
- ✅ Future: UI for self-service profile management
|
|
|
|
|
|
Progress Summary
|
|
|
|
✅ Completed:
|
|
1. Created io.atcr.sailor.profile lexicon
|
|
2. Updated io.atcr.manifest lexicon with holdEndpoint field
|
|
3. Updated Go types in pkg/atproto/lexicon.go
|
|
4. Created profile management in pkg/atproto/profile.go
|
|
5. Updated /auth/exchange handler to manage profile
|
|
|
|
⏳ In Progress:
|
|
- Need to update /auth/token handler similarly (add defaultHoldEndpoint parameter and profile management)
|
|
- Fix compilation error in extractDefaultHoldEndpoint() - should use configuration.Middleware type not any
|
|
|
|
🔜 Remaining:
|
|
- Update findStorageEndpoint() for new priority logic (check profile → own hold → default)
|
|
- Update manifest_store.go to include holdEndpoint when creating manifests
|
|
- Update pull flow to use manifest holdEndpoint
|
|
- Update documentation
|
|
|
|
The architecture is solid - just need to finish the token handler update and fix the type issue in the config extraction. Would you like me to continue?
|