Browse Source
- Add ORLY_POLICY_PATH environment variable to configure custom policy file path, overriding the default ~/.config/ORLY/policy.json location - Enforce ABSOLUTE paths only - relay panics on startup if relative path is provided, preventing common misconfiguration errors - Update PolicyManager to store and expose configPath for hot-reload saves - Add ConfigPath() method to P struct delegating to internal PolicyManager - Update NewWithManager() signature to accept optional custom path parameter - Add BUG_REPORTS_AND_FEATURE_REQUEST_PROTOCOL.md with issue submission guidelines requiring environment details, reproduction steps, and logs - Update README.md with system requirements (500MB minimum memory) and link to bug report protocol - Update CLAUDE.md and README.md documentation for new ORLY_POLICY_PATH Files modified: - app/config/config.go: Add PolicyPath config field - pkg/policy/policy.go: Add configPath storage and validation - app/handle-policy-config.go: Use policyManager.ConfigPath() - app/main.go: Pass cfg.PolicyPath to NewWithManager - pkg/policy/*_test.go: Update test calls with new parameter - BUG_REPORTS_AND_FEATURE_REQUEST_PROTOCOL.md: New file - README.md, CLAUDE.md: Documentation updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>main
17 changed files with 335 additions and 20 deletions
@ -0,0 +1,254 @@ |
|||||||
|
# Feature Request and Bug Report Protocol |
||||||
|
|
||||||
|
This document describes how to submit effective bug reports and feature requests for ORLY relay. Following these guidelines helps maintainers understand and resolve issues quickly. |
||||||
|
|
||||||
|
## Before Submitting |
||||||
|
|
||||||
|
1. **Search existing issues** - Your issue may already be reported or discussed |
||||||
|
2. **Check documentation** - Review `CLAUDE.md`, `docs/`, and `pkg/*/README.md` files |
||||||
|
3. **Verify with latest version** - Ensure the issue exists in the current release |
||||||
|
4. **Test with default configuration** - Rule out configuration-specific problems |
||||||
|
|
||||||
|
## Bug Reports |
||||||
|
|
||||||
|
### Required Information |
||||||
|
|
||||||
|
**Title**: Concise summary of the problem |
||||||
|
- Good: "Kind 3 events with 8000+ follows truncated on save" |
||||||
|
- Bad: "Events not saving" or "Bug in database" |
||||||
|
|
||||||
|
**Environment**: |
||||||
|
``` |
||||||
|
ORLY version: (output of ./orly version) |
||||||
|
OS: (e.g., Ubuntu 24.04, macOS 14.2) |
||||||
|
Go version: (output of go version) |
||||||
|
Database backend: (badger/neo4j/wasmdb) |
||||||
|
``` |
||||||
|
|
||||||
|
**Configuration** (relevant settings only): |
||||||
|
```bash |
||||||
|
ORLY_DB_TYPE=badger |
||||||
|
ORLY_POLICY_ENABLED=true |
||||||
|
# Include any non-default settings |
||||||
|
``` |
||||||
|
|
||||||
|
**Steps to Reproduce**: |
||||||
|
1. Start relay with configuration X |
||||||
|
2. Connect client and send event Y |
||||||
|
3. Query for event with filter Z |
||||||
|
4. Observe error/unexpected behavior |
||||||
|
|
||||||
|
**Expected Behavior**: What should happen |
||||||
|
|
||||||
|
**Actual Behavior**: What actually happens |
||||||
|
|
||||||
|
**Logs**: Include relevant log output with `ORLY_LOG_LEVEL=debug` or `trace` |
||||||
|
|
||||||
|
### Minimal Reproduction |
||||||
|
|
||||||
|
The most effective bug reports include a minimal reproduction case: |
||||||
|
|
||||||
|
```bash |
||||||
|
# Example: Script that demonstrates the issue |
||||||
|
export ORLY_LOG_LEVEL=debug |
||||||
|
./orly & |
||||||
|
sleep 2 |
||||||
|
|
||||||
|
# Send problematic event |
||||||
|
echo '["EVENT", {...}]' | websocat ws://localhost:3334 |
||||||
|
|
||||||
|
# Show the failure |
||||||
|
echo '["REQ", "test", {"kinds": [1]}]' | websocat ws://localhost:3334 |
||||||
|
``` |
||||||
|
|
||||||
|
Or provide a failing test case: |
||||||
|
|
||||||
|
```go |
||||||
|
func TestReproduceBug(t *testing.T) { |
||||||
|
// Setup |
||||||
|
db := setupTestDB(t) |
||||||
|
|
||||||
|
// This should work but fails |
||||||
|
event := createTestEvent(kind, content) |
||||||
|
err := db.SaveEvent(ctx, event) |
||||||
|
require.NoError(t, err) |
||||||
|
|
||||||
|
// Query returns unexpected result |
||||||
|
results, err := db.QueryEvents(ctx, filter) |
||||||
|
assert.Len(t, results, 1) // Fails: got 0 |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## Feature Requests |
||||||
|
|
||||||
|
### Required Information |
||||||
|
|
||||||
|
**Title**: Clear description of the feature |
||||||
|
- Good: "Add WebSocket compression support (permessage-deflate)" |
||||||
|
- Bad: "Make it faster" or "New feature idea" |
||||||
|
|
||||||
|
**Problem Statement**: What problem does this solve? |
||||||
|
``` |
||||||
|
Currently, clients with high-latency connections experience slow sync times |
||||||
|
because event data is transmitted uncompressed. A typical session transfers |
||||||
|
50MB of JSON that could be reduced to ~10MB with compression. |
||||||
|
``` |
||||||
|
|
||||||
|
**Proposed Solution**: How should it work? |
||||||
|
``` |
||||||
|
Add optional permessage-deflate WebSocket extension support: |
||||||
|
- New config: ORLY_WS_COMPRESSION=true |
||||||
|
- Negotiate compression during WebSocket handshake |
||||||
|
- Apply to messages over configurable threshold (default 1KB) |
||||||
|
``` |
||||||
|
|
||||||
|
**Use Case**: Who benefits and how? |
||||||
|
``` |
||||||
|
- Mobile clients on cellular connections |
||||||
|
- Users syncing large follow lists |
||||||
|
- Relays with bandwidth constraints |
||||||
|
``` |
||||||
|
|
||||||
|
**Alternatives Considered** (optional): |
||||||
|
``` |
||||||
|
- Application-level compression: Rejected because it requires client changes |
||||||
|
- HTTP/2: Not applicable for WebSocket connections |
||||||
|
``` |
||||||
|
|
||||||
|
### Implementation Notes (optional) |
||||||
|
|
||||||
|
If you have implementation ideas: |
||||||
|
|
||||||
|
``` |
||||||
|
Suggested approach: |
||||||
|
1. Add compression config to app/config/config.go |
||||||
|
2. Modify gorilla/websocket upgrader in app/handle-websocket.go |
||||||
|
3. Add compression threshold check before WriteMessage() |
||||||
|
|
||||||
|
Reference: gorilla/websocket has built-in permessage-deflate support |
||||||
|
``` |
||||||
|
|
||||||
|
## What Makes Reports Effective |
||||||
|
|
||||||
|
**Do**: |
||||||
|
- Be specific and factual |
||||||
|
- Include version numbers and exact error messages |
||||||
|
- Provide reproducible steps |
||||||
|
- Attach relevant logs (redact sensitive data) |
||||||
|
- Link to related issues or discussions |
||||||
|
- Respond to follow-up questions promptly |
||||||
|
|
||||||
|
**Avoid**: |
||||||
|
- Vague descriptions ("it doesn't work") |
||||||
|
- Multiple unrelated issues in one report |
||||||
|
- Assuming the cause without evidence |
||||||
|
- Demanding immediate fixes |
||||||
|
- Duplicating existing issues |
||||||
|
|
||||||
|
## Issue Labels |
||||||
|
|
||||||
|
When applicable, suggest appropriate labels: |
||||||
|
|
||||||
|
| Label | Use When | |
||||||
|
|-------|----------| |
||||||
|
| `bug` | Something isn't working as documented | |
||||||
|
| `enhancement` | New feature or improvement | |
||||||
|
| `performance` | Speed or resource usage issue | |
||||||
|
| `documentation` | Docs are missing or incorrect | |
||||||
|
| `question` | Clarification needed (not a bug) | |
||||||
|
| `good first issue` | Suitable for new contributors | |
||||||
|
|
||||||
|
## Response Expectations |
||||||
|
|
||||||
|
- **Acknowledgment**: Within a few days |
||||||
|
- **Triage**: Issue labeled and prioritized |
||||||
|
- **Resolution**: Depends on complexity and priority |
||||||
|
|
||||||
|
Complex features may require discussion before implementation. Bug fixes for critical issues are prioritized. |
||||||
|
|
||||||
|
## Following Up |
||||||
|
|
||||||
|
If your issue hasn't received attention: |
||||||
|
|
||||||
|
1. **Check issue status** - It may be labeled or assigned |
||||||
|
2. **Add new information** - If you've discovered more details |
||||||
|
3. **Politely bump** - A single follow-up comment after 2 weeks is appropriate |
||||||
|
4. **Consider contributing** - PRs that fix bugs or implement features are welcome |
||||||
|
|
||||||
|
## Contributing Fixes |
||||||
|
|
||||||
|
If you want to fix a bug or implement a feature yourself: |
||||||
|
|
||||||
|
1. Comment on the issue to avoid duplicate work |
||||||
|
2. Follow the coding patterns in `CLAUDE.md` |
||||||
|
3. Include tests for your changes |
||||||
|
4. Keep PRs focused on a single issue |
||||||
|
5. Reference the issue number in your PR |
||||||
|
|
||||||
|
## Security Issues |
||||||
|
|
||||||
|
**Do not report security vulnerabilities in public issues.** |
||||||
|
|
||||||
|
For security-sensitive bugs: |
||||||
|
- Contact maintainers directly |
||||||
|
- Provide detailed reproduction steps privately |
||||||
|
- Allow reasonable time for a fix before disclosure |
||||||
|
|
||||||
|
## Examples |
||||||
|
|
||||||
|
### Good Bug Report |
||||||
|
|
||||||
|
```markdown |
||||||
|
## WebSocket disconnects after 60 seconds of inactivity |
||||||
|
|
||||||
|
**Environment**: |
||||||
|
- ORLY v0.34.5 |
||||||
|
- Ubuntu 22.04 |
||||||
|
- Go 1.25.3 |
||||||
|
- Badger backend |
||||||
|
|
||||||
|
**Steps to Reproduce**: |
||||||
|
1. Connect to relay: `websocat ws://localhost:3334` |
||||||
|
2. Send subscription: `["REQ", "test", {"kinds": [1], "limit": 1}]` |
||||||
|
3. Wait 60 seconds without sending messages |
||||||
|
4. Observe connection closed |
||||||
|
|
||||||
|
**Expected**: Connection remains open (Nostr relays should maintain persistent connections) |
||||||
|
|
||||||
|
**Actual**: Connection closed with code 1000 after exactly 60 seconds |
||||||
|
|
||||||
|
**Logs** (ORLY_LOG_LEVEL=debug): |
||||||
|
``` |
||||||
|
1764783029014485🔎 client timeout, closing connection /app/handle-websocket.go:142 |
||||||
|
``` |
||||||
|
|
||||||
|
**Possible Cause**: May be related to read deadline not being extended on subscription activity |
||||||
|
``` |
||||||
|
|
||||||
|
### Good Feature Request |
||||||
|
|
||||||
|
```markdown |
||||||
|
## Add rate limiting per pubkey |
||||||
|
|
||||||
|
**Problem**: |
||||||
|
A single pubkey can flood the relay with events, consuming storage and |
||||||
|
bandwidth. Currently there's no way to limit per-author submission rate. |
||||||
|
|
||||||
|
**Proposed Solution**: |
||||||
|
Add configurable rate limiting: |
||||||
|
```bash |
||||||
|
ORLY_RATE_LIMIT_EVENTS_PER_MINUTE=60 |
||||||
|
ORLY_RATE_LIMIT_BURST=10 |
||||||
|
``` |
||||||
|
|
||||||
|
When exceeded, return OK false with "rate-limited" message per NIP-20. |
||||||
|
|
||||||
|
**Use Case**: |
||||||
|
- Public relays protecting against spam |
||||||
|
- Community relays with fair-use policies |
||||||
|
- Paid relays enforcing subscription tiers |
||||||
|
|
||||||
|
**Alternatives Considered**: |
||||||
|
- IP-based limiting: Ineffective because users share IPs and use VPNs |
||||||
|
- Global limiting: Punishes all users for one bad actor |
||||||
|
``` |
||||||
Loading…
Reference in new issue