7.8 KiB
AGENTS.md
This file provides guidance to agents when working with code in this repository.
Project Structure
Workspace with Two Rust Projects:
- Root:
ngit-grasp(main GRASP relay implementation) grasp-audit/: Separate subproject with ownCargo.tomlandflake.nix
Cannot build grasp-audit from root - must cd grasp-audit first.
Build & Test
Nix Flakes (Non-Standard)
CRITICAL: Use nix develop, NOT nix-shell (we use flake.nix, not shell.nix)
# ✅ Correct
cd grasp-audit
nix develop -c cargo build
nix develop -c cargo test
# ❌ Wrong
nix-shell
nix-shell --run "cargo build"
Running Tests
Integration tests require relay running:
# Start ngit-relay first (use any available port to avoid conflicts)
docker run --rm -p 18081:8081 ghcr.io/danconwaydev/ngit-relay:latest
# From grasp-audit directory, set RELAY_URL to match your port
# Run all ignored tests (includes GRASP-01 and other relay-dependent tests)
RELAY_URL="ws://localhost:18081" nix develop -c cargo test --lib -- --ignored --nocapture
# Or run a specific test
RELAY_URL="ws://localhost:18081" nix develop -c cargo test --lib test_grasp01_nostr_relay_against_relay -- --ignored --nocapture
Tests marked #[ignore] need relay - unit tests don't.
Note: Always use a random available port for the relay to avoid conflicts with existing services.
Standard Testing Process (Recommended)
Use test-ngit-relay.sh for automated relay management:
This script handles all relay lifecycle management automatically:
- Starts ngit-relay in isolated Docker container
- Uses random port to avoid conflicts
- Creates isolated temporary directories
- Ensures cleanup on exit (success or failure)
- Supports both audit and test modes
Basic Usage:
# Run cargo test suite (recommended for GRASP-01 development)
cd grasp-audit && nix develop -c bash test-ngit-relay.sh --mode test
# Run audit CLI tool (for quick validation)
cd grasp-audit && nix develop -c bash test-ngit-relay.sh
# Get help
cd grasp-audit && ./test-ngit-relay.sh --help
Benefits:
- No manual relay startup required
- Automatic cleanup prevents leftover containers
- Random port selection avoids conflicts
- Consistent environment across all runs
- Proper test isolation
Note: Manual relay setup is still available but test-ngit-relay.sh is recommended for development workflows.
Running Single Test
# From grasp-audit/
nix develop -c cargo test --lib specific_test_name -- --nocapture
Quick Test Verification
To verify GRASP-01 compliance tests are working correctly:
# Run all ignored library tests (includes GRASP-01)
cd grasp-audit && RELAY_URL="ws://localhost:18081" nix develop -c cargo test --lib -- --ignored --nocapture 2>&1 | tail -60
# Or run specific GRASP-01 test
cd grasp-audit && RELAY_URL="ws://localhost:18081" nix develop -c cargo test --lib test_grasp01_nostr_relay_against_relay -- --ignored --nocapture 2>&1 | tail -60
Expected Output:
- 2-3 tests passing
- 15+ tests showing "Not implemented yet"
Troubleshooting
Buffer Size Errors: If you see mpsc channel buffer size panics on first test run, this is usually transient. Simply run the tests again.
Verify Relay is Running: Check if relay is accessible before running tests:
nak req -l 1 ws://localhost:18081 # Replace port with your chosen port
Port Conflicts: Always use a random available port to avoid conflicts with existing services. If a port is busy, choose a different one for docker.
Code Patterns
nostr-sdk 0.43 Breaking Changes (vs 0.35)
Field access, not method calls:
// ❌ WRONG (0.35 API)
event.id()
event.tags()
for tag in &event.tags { }
// ✅ CORRECT (0.43 API)
event.id // Direct field access
event.tags // Direct field access
event.tags.iter() // Iterator method
Tag API changed:
// ❌ WRONG (0.35)
Tag::Generic(TagKind::Custom("clone".into()), vec![...])
// ✅ CORRECT (0.43)
Tag::custom(TagKind::custom("clone"), vec![...])
EventBuilder signature changed:
// ❌ WRONG (0.35)
EventBuilder::new(kind, content, &[tags])
// ✅ CORRECT (0.43)
EventBuilder::new(kind, content).tags(tags)
See docs/archive/2025-11-04-nostr-sdk-upgrade.md for full migration.
Audit Event Tagging (grasp-audit)
All audit events automatically include cleanup tags:
The grasp-audit system automatically adds three tags to every event for production cleanup and test isolation. These tags are added transparently via AuditEventBuilder::build() with 100% coverage through AuditClient::event_builder().
Automatic Tags (no manual intervention needed):
// These tags are automatically added to EVERY audit event:
["t", "grasp-audit-test-event"] // Identifies all audit test events
["t", "audit-{run_id}"] // Unique ID for this audit run (correlates events)
["t", "audit-cleanup-after-{unix_timestamp}"] // Unix timestamp for cleanup scheduling
Tag Format Details:
- Uses standard NIP-01
"t"(hashtag) tags for maximum compatibility - Unix timestamps (not ISO 8601) for easier database queries
- All tags added automatically when calling
client.event_builder().build() - No manual tag management required
Verifying Tags in Tests:
// Test that verifies automatic tag addition:
// See: grasp-audit/src/client.rs:273-302
#[test]
fn test_audit_tags_automatically_added() {
// Creates event and verifies all three tags are present
}
Testing Implications:
- All audit events are tagged for easy cleanup
- Use
run_idtag to correlate events from same audit run - Tags enable production relay cleanup scripts
- No special handling needed in test code - tags are automatic
Documentation
Diátaxis Framework Used:
docs/tutorials/- Learning-orienteddocs/how-to/- Task-orienteddocs/reference/- Information-orienteddocs/explanation/- Understanding-oriented
Session files go in work/ (gitignored except README.md)
- Archive valuable content to
docs/archive/YYYY-MM-DD-*.mdat session end - Delete temporary files
- Keep root clean (only README.md, AGENTS.md)
Critical Gotchas
- Workspace compilation: Can't
cargo buildfrom root for grasp-audit - Nix environment: Must use
nix develop, notnix-shell - nostr-sdk API: Fields not methods in 0.43
- Test isolation: Integration tests need relay, marked with
#[ignore] - Work directory: All session docs go in
work/, NOT root - Archive naming: Use
YYYY-MM-DD-description.mdformat - Use test-ngit-relay.sh: Always use the test script for GRASP-01 tests - it handles cleanup and port management automatically
File Restrictions by Mode
Code mode can only edit files matching specific patterns (enforced by system):
- Example: Architect mode restricted to
\.md$files only - Attempting to edit restricted files causes FileRestrictionError
- Check mode configuration if edit attempts fail unexpectedly
Quick Reference
# Recommended: Use test-ngit-relay.sh for all testing
cd grasp-audit && nix develop -c bash test-ngit-relay.sh --mode test
# Build grasp-audit
cd grasp-audit && nix develop -c cargo build
# Manual relay testing (if needed)
# 1. Start relay: docker run --rm -p 18081:8081 ghcr.io/danconwaydev/ngit-relay:latest
# 2. Run all ignored tests: RELAY_URL="ws://localhost:18081" nix develop -c cargo test --lib -- --ignored --nocapture
# 3. Or specific test: RELAY_URL="ws://localhost:18081" nix develop -c cargo test --lib test_grasp01_nostr_relay_against_relay -- --ignored --nocapture
# Run single test
cd grasp-audit && nix develop -c cargo test --lib test_name -- --nocapture
# Check session files
ls work/ # Should only have README.md when clean