code
Clone this repository
https://tangled.org/bretton.dev/coves
git@knot.bretton.dev:bretton.dev/coves
For self-hosted knots, clone URLs may differ based on your setup.
Server was using local PLC directory (localhost:3002) for resolving real
Bluesky handles like "bretton.dev", which failed with 404 errors. Now uses
a dedicated production PLC resolver (https://plc.directory) that is READ-ONLY
for looking up existing Bluesky identities.
- Add productionPLCResolver in main.go for Bluesky handle resolution
- Update tests to use production PLC helper function
- Clean up debug logging in post service
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Address PR review feedback:
- Add debug logging when URI is not a string type
- Differentiate timeout errors from other parse errors
- Include unavailable post message in log output
- Add test case for wrong URI type (int instead of string)
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a user pastes a Bluesky URL (bsky.app) as an external embed,
convert it to a social.coves.embed.post with proper strongRef
containing both URI and CID. This enables rich embedded quote posts
instead of plain external links.
Key changes:
- Implement tryConvertBlueskyURLToPostEmbed in service.go
- Detect Bluesky URLs and resolve them via blueskyService
- Parse URL to AT-URI (resolves handle to DID if needed)
- Fetch CID from Bluesky API for strongRef
- Fall back to external embed on errors (graceful degradation)
- Differentiated logging for circuit breaker vs other errors
- Keep unavailable posts as external embeds (no fake CIDs)
Test coverage:
- Unit tests for all error cases and success path
- Integration test for URL to strongRef conversion
Closes: Coves-p44
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Hot ranking formula now uses (score + 1) instead of score to prevent
new posts with 0 votes from sinking to the bottom. Previously,
0 / time_decay = 0 caused all unvoted posts to have rank 0.
Affects discover, timeline, and community feed repos.
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update community handles to use c-{name}.{instance} pattern and
enable additional feeds (US News, Science).
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extend auth middleware to accept both OAuth sealed tokens (users) and
PDS service JWTs (aggregators). Uses Indigo's ServiceAuthValidator for
JWT signature verification against DID document public keys.
Security model:
- Detect token format upfront (detect-and-route, not fallback)
- JWT auth restricted to DIDs in aggregators table
- Aggregators self-register via social.coves.aggregator.service record
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1 is text-only, so skip converting Bluesky URLs to post embeds.
The social.coves.embed.post lexicon requires a valid CID in strongRef,
which we don't have without calling ResolvePost. This caused P1 bug
where empty CID violated lexicon validation.
Changes:
- Disable tryConvertBlueskyURLToPostEmbed (return false, remove dead code)
- Add TestBlueskyPostCrossPosting_E2E_LivePDS integration test that
writes posts with Bluesky URLs directly to dev PDS to catch lexicon
validation errors
- Create beads for Phase 2 embed conversion (Coves-p44) and functional
options refactoring (Coves-8k1, Coves-jdf, etc.)
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix quoted post mapping for recordWithMedia#view embeds
- Handle nested viewRecord structure where content is in embed.record.record
- Add mapViewRecordToResult and mapNestedViewRecordToResult functions
- Properly extract text and author from value field (not record field)
- Implement age-based cache TTL decay for scalability
- Fresh posts (< 24h): 15 min TTL (engagement changing rapidly)
- Recent posts (1-7 days): 1 hour TTL
- Old posts (7+ days): 24 hour TTL
- Unavailable posts: 15 min TTL (allow re-checking)
- Add comprehensive unit tests for TTL calculation
- Add integration tests for live Bluesky API interaction
- Update integration tests for new blueskyService parameter
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>