- Added CRITICAL warning section to AGENTS.md about treating architecture docs as living documents - Mark 'Keep Architecture Docs Updated' item as fixed in grasp-01 learnings - Mark 'Document actual architecture' technical debt item as fixed This addresses a key learning from GRASP-01 where docs described plans rather than implementation, causing confusion.
6.9 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"
Testing ngit-grasp (Main Project)
ngit-grasp integration tests use the TestRelay fixture:
The TestRelay fixture automatically starts an instance of ngit-grasp itself and manages its lifecycle:
# Run all ngit-grasp tests (from project root)
cargo test
# Run integration tests only
cargo test --test '*'
# Run specific test file
cargo test --test nip01_compliance
How TestRelay works:
- Spawns
ngit-graspbinary on a random available port - Creates temporary directories for git and relay data
- Provides
url()anddomain()methods for test clients - Automatically cleans up on drop
Example test pattern:
use common::TestRelay;
#[tokio::test]
async fn test_something() {
let relay = TestRelay::start().await;
// relay.url() returns "ws://127.0.0.1:{port}"
// ... run test against ngit-grasp ...
relay.stop().await;
}
Summary: Which Test Command for What
| What you're testing | Command |
|---|---|
| ngit-grasp (this project) | cargo test from project root |
| ngit-relay (reference impl) | cd grasp-audit && nix develop -c bash test-ngit-relay.sh --mode test |
| grasp-audit unit tests | cd grasp-audit && nix develop -c cargo test --lib |
Running Single Test
# ngit-grasp test (from project root)
cargo test --test nip01_compliance test_websocket_connection -- --nocapture
# grasp-audit test (from grasp-audit/)
nix develop -c cargo test --lib specific_test_name -- --nocapture
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.
Port Conflicts:
Both TestRelay and test-ngit-relay.sh use random ports to avoid conflicts. If you see port errors, ensure no stale processes are running.
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)
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
⚠️ CRITICAL: Keep Architecture Docs Updated
Architecture and design documents are LIVING DOCUMENTS. When implementation diverges from the documented plan:
- Update the doc IMMEDIATELY - Don't wait until "later"
- Document what was actually built, not what was originally planned
- Note why decisions changed - Future readers need this context
- Files to watch:
docs/explanation/architecture.md,docs/explanation/decisions.md
This was a key learning from GRASP-01: docs described plans, not implementation, causing confusion.
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 use
TestRelay(ngit-grasp) ortest-ngit-relay.sh(ngit-relay) - Work directory: All session docs go in
work/, NOT root - Archive naming: Use
YYYY-MM-DD-description.mdformat - test-ngit-relay.sh tests ngit-relay: This script tests the reference implementation, NOT ngit-grasp
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
# Test ngit-grasp (main project)
cargo test
# Build grasp-audit
cd grasp-audit && nix develop -c cargo build
# Run grasp-audit unit tests
cd grasp-audit && nix develop -c cargo test --lib
# Check session files
ls work/ # Should only have README.md when clean