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.
Added infrastructure/technical TODOs:
- OAuth authentication for community actions (P1)
- Jetstream consumer race condition (P2)
- Structured logging migration (P3)
- PDS URL resolution from DID (P3)
- PLC directory registration for prod (P3)
Feature-specific TODOs (avatars, moderator checks, update/delete handlers)
are tracked in their respective PRDs (PRD_COMMUNITIES, PRD_GOVERNANCE).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem:
- Default INSTANCE_DID was did:web:coves.local
- instanceDomain extracted as "coves.local"
- Community handles generated as "{name}.communities.coves.local"
- .local TLD is disallowed per atProto spec (RFC 6762)
- Result: Community creation failed immediately with InvalidHandleError
Solution:
- Changed default to did:web:coves.social (.social is valid TLD)
- Added TODO comment documenting did:web domain verification security issue
- Created docs/PRD_BACKLOG.md to track follow-up work
Security Note:
Self-hosters can currently set INSTANCE_DID to any domain without
verification. This enables domain impersonation attacks. Added to
backlog (P0) to implement did:web verification per atProto spec.
Testing:
- All integration tests pass (TestCommunity_E2E)
- Community handles now: gaming.communities.coves.social ✓
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add logging for internal server errors in community XRPC handlers to
aid debugging during development. Internal errors are now logged before
returning generic error responses to clients.
Changes:
- Add log import to errors.go
- Log actual error details when returning InternalServerError
- Add TODO comment to migrate to proper structured logger
Rationale:
During E2E testing, internal errors were being silently swallowed making
debugging difficult. This change logs the actual error while still
returning safe generic error messages to clients.
Security note:
- Internal error details are NOT exposed to clients
- Logging is for server-side debugging only
- Generic "InternalServerError" message still returned to clients
TODO: Replace log.Printf with structured logger (e.g., zerolog/zap)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update development PostgreSQL port from 5433 to 5435 to avoid conflicts
with existing local PostgreSQL installations or other services.
Changes:
- .env.dev: Update POSTGRES_PORT to 5435
- docker-compose.dev.yml: Update health checks to use wget instead of curl
- cmd/server/main.go: Update default DATABASE_URL to use port 5435
Additional improvements:
- Replace curl with wget in Docker healthchecks (more reliable in Alpine)
- Update comments to reflect new port configuration
Ports summary:
- Dev PostgreSQL: 5435 (was 5433)
- Test PostgreSQL: 5434 (unchanged)
- PDS: 3001
- AppView: 8081
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive technical decisions to PRDs documenting architecture
choices for community handles and moderator record storage.
PRD_COMMUNITIES.md:
- Add technical decision: Single handle field (2025-10-11)
- Update lexicon summary to reflect DNS-valid handle approach
- Add DNS infrastructure checklist items (wildcard setup, well-known endpoint)
- Document that !name@instance format is client-side display only
PRD_GOVERNANCE.md:
- Add technical decision: Moderator records storage location (2025-10-11)
- Document security analysis comparing user repo vs community repo
- Explain attack vector for malicious self-hosted instances
- Rationale: Community repo provides better security and federation
Key decisions documented:
1. Single handle field matches Bluesky pattern (app.bsky.actor.profile)
2. Separation of concerns: protocol (DNS handle) vs presentation (!prefix)
3. Moderator records in community repo prevents forgery attacks
4. DNS wildcard required for *.communities.coves.social resolution
Infrastructure requirements added:
- [ ] DNS Wildcard Setup: Configure *.communities.coves.social
- [ ] Well-Known Endpoint: Implement .well-known/atproto-did handler
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Update all community tests to use DNS-valid atProto handles instead of
scoped handle format. All tests passing including E2E, integration, and
unit test suites.
Changes:
- Update test fixtures to use DNS-valid handles
- Remove atprotoHandle references from test data
- Rename TestCommunityConsumer_AtprotoHandleField to TestCommunityConsumer_HandleField
- Update test assertions to expect DNS format handles
- Fix unused variable warnings in unit tests
Test coverage:
✅ E2E tests (5.57s) - Full PDS → Jetstream → AppView flow
✅ Integration tests (4.36s) - 13 suites covering CRUD, credentials, V2 validation
✅ Unit tests (0.37s) - Service layer, timeout handling, credentials
✅ Lexicon validation (0.40s) - All 60 schemas validated
Example test data changes:
- Before: handle="!gaming@coves.social"
- After: handle="gaming.communities.coves.social"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>