upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AGENTS.md560
-rw-r--r--CLEANUP_SUMMARY.md448
-rw-r--r--CURRENT_STATUS.md464
-rw-r--r--docs/archive/2025-11-03-architecture-investigation.md (renamed from INVESTIGATION_COMPLETE.md)0
-rw-r--r--docs/archive/2025-11-03-compliance-test-proposal.md (renamed from COMPLIANCE_TEST_PROPOSAL.md)0
-rw-r--r--docs/archive/2025-11-03-compliance-testing-report.md (renamed from REPORT_COMPLIANCE_TESTING.md)0
-rw-r--r--docs/archive/2025-11-03-documentation-index.md (renamed from DOCUMENTATION_INDEX.md)0
-rw-r--r--docs/archive/2025-11-03-files-created.md (renamed from FILES_CREATED.md)0
-rw-r--r--docs/archive/2025-11-03-final-audit-report.md (renamed from FINAL_AUDIT_REPORT.md)0
-rw-r--r--docs/archive/2025-11-03-final-summary.md (renamed from FINAL_SUMMARY.md)0
-rw-r--r--docs/archive/2025-11-03-grasp-audit-implementation.md (renamed from GRASP_AUDIT_IMPLEMENTATION_SUMMARY.md)0
-rw-r--r--docs/archive/2025-11-03-grasp-audit-plan.md (renamed from GRASP_AUDIT_PLAN.md)0
-rw-r--r--docs/archive/2025-11-03-implementation-complete.md (renamed from IMPLEMENTATION_COMPLETE.md)0
-rw-r--r--docs/archive/2025-11-03-quick-reference.md (renamed from QUICK_REFERENCE.md)0
-rw-r--r--docs/archive/2025-11-03-review-summary.md (renamed from REVIEW_SUMMARY.md)0
-rw-r--r--docs/archive/2025-11-03-smoke-test-report.md (renamed from SMOKE_TEST_REPORT.md)0
-rw-r--r--docs/archive/2025-11-03-start-here.md (renamed from START_HERE.md)0
-rw-r--r--docs/archive/2025-11-03-test-breakdown.md (renamed from TEST_BREAKDOWN.md)0
-rw-r--r--docs/archive/2025-11-03-verification-complete.md (renamed from VERIFICATION_COMPLETE.md)0
-rw-r--r--docs/archive/2025-11-04-audit-status-report.md (renamed from AUDIT_SYSTEM_STATUS_REPORT.md)0
-rw-r--r--docs/archive/2025-11-04-audit-system-fixed.md (renamed from AUDIT_SYSTEM_FIXED.md)0
-rw-r--r--docs/archive/2025-11-04-compilation-fixes.md (renamed from COMPILATION_FIXES.md)0
-rw-r--r--docs/archive/2025-11-04-flake-migration.md (renamed from FLAKE_MIGRATION_COMPLETE.md)0
-rw-r--r--docs/archive/2025-11-04-next-prompt.md (renamed from next_prompt.md)0
-rw-r--r--docs/archive/2025-11-04-next-session-quickstart.md (renamed from NEXT_SESSION_QUICKSTART.md)0
-rw-r--r--docs/archive/2025-11-04-nostr-sdk-upgrade.md (renamed from NOSTR_SDK_0.43_UPGRADE.md)0
-rw-r--r--docs/archive/2025-11-04-ready-for-next-phase.md (renamed from READY_FOR_NEXT_PHASE.md)0
-rw-r--r--docs/archive/2025-11-04-session-complete-1.md (renamed from SESSION_COMPLETE.md)0
-rw-r--r--docs/archive/2025-11-04-session-complete-2.md (renamed from SESSION_COMPLETE_2025_11_04.md)0
-rw-r--r--docs/archive/2025-11-04-session-continuation.md (renamed from SESSION_CONTINUATION_COMPLETE.md)0
-rw-r--r--docs/archive/2025-11-04-session-summary.md (renamed from SESSION_2025_11_04_SUMMARY.md)0
-rw-r--r--docs/archive/2025-11-04-tag-migration-summary.md (renamed from TAG_MIGRATION_SUMMARY.md)0
-rw-r--r--docs/archive/2025-11-04-tag-migration.md (renamed from TAG_MIGRATION_COMPLETE.md)0
-rw-r--r--docs/archive/2025-11-04-upgrade-complete.md (renamed from UPGRADE_COMPLETE.md)0
-rw-r--r--docs/archive/README.md158
-rw-r--r--docs/learnings/grasp-audit.md498
-rw-r--r--docs/learnings/nix-flakes.md423
-rw-r--r--docs/learnings/nostr-sdk.md577
38 files changed, 3128 insertions, 0 deletions
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..c063f68
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,560 @@
1# AI Agent Guidelines for ngit-grasp
2
3**Purpose:** Ensure AI agents (and humans) maintain consistent documentation practices and avoid common pitfalls.
4
5**Last Updated:** November 4, 2025
6
7---
8
9## 📁 Documentation Structure
10
11### Overview
12
13We maintain a **clean, hierarchical documentation structure** to avoid documentation sprawl. All working documents have a defined lifecycle and location.
14
15```
16ngit-grasp/
17├── README.md # Project overview (keep updated)
18├── AGENTS.md # This file - agent guidelines
19├── CHANGELOG.md # User-facing changes (semver)
20
21├── docs/ # Permanent technical documentation
22│ ├── README.md # Docs navigation guide
23│ ├── ARCHITECTURE.md # System architecture
24│ ├── TEST_STRATEGY.md # Testing approach
25│ ├── GIT_PROTOCOL.md # Git protocol reference
26│ ├── COMPARISON.md # vs other implementations
27│ ├── GETTING_STARTED.md # Setup guide
28│ └── DECISION_SUMMARY.md # Key architectural decisions
29
30├── docs/archive/ # Completed session/phase docs
31│ ├── 2025-11-04-tag-migration.md
32│ ├── 2025-11-04-flake-migration.md
33│ └── 2025-11-03-architecture-investigation.md
34
35├── docs/learnings/ # Extracted knowledge (permanent)
36│ ├── nix-flakes.md # Flake gotchas and patterns
37│ ├── nostr-sdk.md # nostr-sdk patterns and upgrades
38│ └── git-http-backend.md # Git protocol learnings
39
40├── grasp-audit/ # Audit tool subproject
41│ ├── README.md # Main audit docs
42│ ├── QUICK_START.md # Getting started
43│ └── docs/
44│ └── archive/ # Audit-specific archives
45
46└── .ai/ # AI assistant context (ignored in git)
47 └── history/ # Conversation history
48```
49
50---
51
52## 📋 Document Lifecycle
53
54### 1. Working Documents (Root Level)
55
56**Purpose:** Active development, session notes, status reports
57**Location:** Project root
58**Lifecycle:** Created → Updated → Archived
59**Retention:** Archive after completion, delete if obsolete
60
61**Examples:**
62- `TAG_MIGRATION_COMPLETE.md` → Archive when next phase starts
63- `SESSION_2025_11_04_SUMMARY.md` → Archive at session end
64- `NEXT_STEPS.md` → Update continuously, archive when complete
65
66**Rules:**
67- ✅ Use descriptive names with dates: `YYYY-MM-DD-description.md`
68- ✅ Mark status clearly: `[WIP]`, `[COMPLETE]`, `[ARCHIVED]`
69- ✅ Include date and context at top
70- ❌ Don't let root accumulate more than 5-10 working docs
71- ❌ Don't create duplicates (merge or link instead)
72
73### 2. Permanent Documentation (docs/)
74
75**Purpose:** Long-term reference, architecture, guides
76**Location:** `docs/`
77**Lifecycle:** Created → Maintained → Updated
78**Retention:** Permanent (version controlled)
79
80**Examples:**
81- `docs/ARCHITECTURE.md` - System design
82- `docs/TEST_STRATEGY.md` - Testing approach
83- `docs/learnings/nix-flakes.md` - Extracted knowledge
84
85**Rules:**
86- ✅ Keep updated as project evolves
87- ✅ Use clear structure and headings
88- ✅ Link between related docs
89- ❌ Don't duplicate information (use links)
90- ❌ Don't include session-specific details
91
92### 3. Archive (docs/archive/)
93
94**Purpose:** Historical record, completed phases
95**Location:** `docs/archive/`
96**Lifecycle:** Moved from root → Archived
97**Retention:** Permanent (for reference)
98
99**Examples:**
100- `docs/archive/2025-11-04-tag-migration.md`
101- `docs/archive/2025-11-03-architecture-investigation.md`
102
103**Rules:**
104- ✅ Rename with date prefix when archiving
105- ✅ Add "ARCHIVED" marker at top
106- ✅ Extract learnings to docs/learnings/ first
107- ❌ Don't modify after archiving
108- ❌ Don't reference in active documentation
109
110### 4. Learnings (docs/learnings/)
111
112**Purpose:** Reusable knowledge, gotchas, patterns
113**Location:** `docs/learnings/`
114**Lifecycle:** Extracted → Maintained → Updated
115**Retention:** Permanent (living documents)
116
117**Examples:**
118- `docs/learnings/nix-flakes.md` - Flake patterns and gotchas
119- `docs/learnings/nostr-sdk.md` - SDK upgrade notes
120- `docs/learnings/git-http-backend.md` - Git protocol tips
121
122**Rules:**
123- ✅ Extract from session docs before archiving
124- ✅ Organize by topic, not by session
125- ✅ Include code examples
126- ✅ Update as we learn more
127- ❌ Don't duplicate official docs (link instead)
128
129---
130
131## 🔄 Cleanup Process
132
133### When to Clean Up
134
135**Trigger:** Root directory has >10 markdown files
136**Frequency:** End of each major phase or weekly
137**Responsibility:** AI agents should proactively suggest cleanup
138
139### Cleanup Steps
140
1411. **Identify Completed Documents**
142 ```bash
143 # Find old working docs
144 ls -lt *.md | head -20
145 ```
146
1472. **Extract Learnings**
148 - Review each completed doc
149 - Extract gotchas, patterns, solutions
150 - Add to appropriate `docs/learnings/*.md`
151
1523. **Archive Completed Work**
153 ```bash
154 # Move to archive with date prefix
155 mv TAG_MIGRATION_COMPLETE.md docs/archive/2025-11-04-tag-migration.md
156 ```
157
1584. **Delete Obsolete Documents**
159 - Duplicates (keep most recent/complete)
160 - Superseded documents
161 - Pure status reports (no learnings)
162
1635. **Update References**
164 - Update links in active docs
165 - Update README.md if needed
166 - Commit changes
167
168### Example Cleanup
169
170```bash
171# Before cleanup (36 files in root!)
172ls *.md | wc -l
173# 36
174
175# After cleanup (5-8 files in root)
176ls *.md
177# README.md
178# AGENTS.md
179# CHANGELOG.md
180# CURRENT_STATUS.md
181# NEXT_STEPS.md
182
183# Archived
184ls docs/archive/
185# 2025-11-04-tag-migration.md
186# 2025-11-04-flake-migration.md
187# 2025-11-03-architecture-investigation.md
188# ...
189
190# Learnings extracted
191ls docs/learnings/
192# nix-flakes.md
193# nostr-sdk.md
194# git-http-backend.md
195```
196
197---
198
199## 🚨 Common Gotchas
200
201### Nix Flakes
202
203**Always use `nix develop`, not `nix-shell`**
204
205```bash
206# ✅ Correct
207cd grasp-audit
208nix develop
209nix develop -c cargo build
210
211# ❌ Wrong
212nix-shell
213nix-shell --run "cargo build"
214```
215
216**Why:** We use `flake.nix`, not `shell.nix`. See `docs/learnings/nix-flakes.md`.
217
218**Flake Commands:**
219```bash
220# Show flake outputs
221nix flake show
222
223# Update flake inputs
224nix flake update
225
226# Build package
227nix build
228
229# Run package
230nix run
231```
232
233### Git Subprojects
234
235**grasp-audit is a subproject with its own flake**
236
237```bash
238# ✅ Correct - enter grasp-audit environment
239cd grasp-audit
240nix develop
241cargo build
242
243# ❌ Wrong - can't build from root
244cd ngit-grasp
245cargo build # This won't find grasp-audit
246```
247
248**Why:** `grasp-audit/` has its own `Cargo.toml` and `flake.nix`.
249
250### nostr-sdk Versions
251
252**We use nostr-sdk 0.43.x (latest stable)**
253
254```toml
255# ✅ Correct
256[dependencies]
257nostr-sdk = "0.43"
258
259# ❌ Wrong
260nostr-sdk = "0.35" # Old version, breaking changes
261```
262
263**Why:** We upgraded from 0.35 to 0.43. See `docs/learnings/nostr-sdk.md` for migration notes.
264
265**Common Breaking Changes:**
266- `EventBuilder::new()` signature changed
267- Tag API changed to `Tag::custom()`
268- Filter API changed
269- See archived upgrade docs for details
270
271### Testing Patterns
272
273**Integration tests require relay**
274
275```bash
276# ✅ Correct - start relay first
277docker run --rm -p 7000:7000 scsibug/nostr-rs-relay
278
279# Then run tests
280cd grasp-audit
281nix develop -c cargo test --ignored
282
283# ❌ Wrong - integration tests will fail
284cargo test --ignored # No relay running
285```
286
287**Test Organization:**
288```rust
289// Unit tests (no relay needed)
290#[cfg(test)]
291mod tests {
292 #[test]
293 fn test_something() { }
294}
295
296// Integration tests (relay required)
297#[cfg(test)]
298mod tests {
299 #[test]
300 #[ignore] // Requires relay
301 fn test_against_relay() { }
302}
303```
304
305### Documentation Updates
306
307**Keep README.md synchronized**
308
309When you:
310- Complete a major feature → Update README.md status
311- Change architecture → Update docs/ARCHITECTURE.md
312- Add dependencies → Update README.md tech stack
313- Change workflow → Update docs/GETTING_STARTED.md
314
315**Don't:**
316- Create duplicate documentation
317- Leave stale status markers
318- Forget to update CHANGELOG.md for user-facing changes
319
320---
321
322## 📝 Writing Guidelines
323
324### Markdown Style
325
326```markdown
327# Title (H1 - only one per file)
328
329**Date:** YYYY-MM-DD
330**Status:** [WIP|COMPLETE|ARCHIVED]
331
332## Section (H2)
333
334### Subsection (H3)
335
336**Bold** for emphasis, `code` for commands/code.
337
338- Bullet lists for items
339- Keep consistent style
340
3411. Numbered lists for sequences
3422. Use when order matters
343
344✅ Use emoji for status (sparingly)
345❌ Don't overuse emoji
346
347\`\`\`bash
348# Code blocks with language
349cargo build
350\`\`\`
351```
352
353### Status Markers
354
355- `[WIP]` - Work in progress
356- `[COMPLETE]` - Finished, may be archived
357- `[ARCHIVED]` - Moved to archive, historical only
358- `✅` - Success/complete
359- `❌` - Failure/incorrect
360- `⏳` - In progress
361- `🔜` - Planned/next
362
363### Document Headers
364
365```markdown
366# Document Title
367
368**Purpose:** One-line purpose
369**Date:** YYYY-MM-DD
370**Status:** [WIP|COMPLETE|ARCHIVED]
371**Related:** Links to related docs
372
373---
374
375## Content starts here
376```
377
378---
379
380## 🤖 AI Agent Responsibilities
381
382### Before Creating New Documents
383
3841. **Check if document already exists**
385 ```bash
386 find . -name "*keyword*.md"
387 ```
388
3892. **Check if information can be added to existing doc**
390 - Prefer updating over creating
391 - Use sections/subsections
392
3933. **Determine correct location**
394 - Working doc → Root
395 - Permanent → docs/
396 - Learning → docs/learnings/
397 - Historical → docs/archive/
398
3994. **Use descriptive names with dates**
400 - `YYYY-MM-DD-description.md` for working docs
401 - `topic-name.md` for permanent docs
402
403### During Development
404
4051. **Update status markers**
406 - Mark WIP → COMPLETE when done
407 - Update README.md status section
408
4092. **Extract learnings as you go**
410 - Add gotchas to docs/learnings/
411 - Don't wait until cleanup
412
4133. **Keep documentation DRY**
414 - Link to existing docs
415 - Don't duplicate information
416
417### End of Session
418
4191. **Suggest cleanup if needed**
420 - Count root .md files
421 - Suggest archiving completed docs
422
4232. **Create session summary**
424 - What was accomplished
425 - What's next
426 - Any blockers
427
4283. **Update permanent docs**
429 - Sync README.md with reality
430 - Update relevant docs/ files
431
432### Cleanup Time
433
4341. **Review all root .md files**
4352. **Extract learnings to docs/learnings/**
4363. **Archive completed work to docs/archive/**
4374. **Delete obsolete duplicates**
4385. **Update links in active docs**
4396. **Commit with clear message**
440
441---
442
443## 🎯 Quality Checklist
444
445### For Every Document
446
447- [ ] Clear purpose stated at top
448- [ ] Date included
449- [ ] Status marker present
450- [ ] Proper heading hierarchy (H1 → H2 → H3)
451- [ ] Code blocks have language specified
452- [ ] Links are valid and relative
453- [ ] No duplicate information
454- [ ] Spell-checked and readable
455
456### For Working Documents
457
458- [ ] Descriptive filename with date
459- [ ] Will be archived or deleted when done
460- [ ] Not duplicating permanent docs
461- [ ] Learnings extracted to docs/learnings/
462
463### For Permanent Documents
464
465- [ ] In correct docs/ subdirectory
466- [ ] Linked from docs/README.md
467- [ ] Updated as project evolves
468- [ ] No session-specific details
469- [ ] Serves long-term purpose
470
471### For Archived Documents
472
473- [ ] Moved to docs/archive/
474- [ ] Renamed with date prefix
475- [ ] ARCHIVED marker at top
476- [ ] Learnings extracted first
477- [ ] Not referenced in active docs
478
479---
480
481## 📚 Reference Documents
482
483### Must Read
484- **This file (AGENTS.md)** - Guidelines for documentation
485- **README.md** - Project overview
486- **docs/README.md** - Documentation navigation
487
488### Key Technical Docs
489- **docs/ARCHITECTURE.md** - System design
490- **docs/TEST_STRATEGY.md** - Testing approach
491- **docs/GETTING_STARTED.md** - Setup guide
492
493### Learnings (Gotchas)
494- **docs/learnings/nix-flakes.md** - Nix flake patterns
495- **docs/learnings/nostr-sdk.md** - nostr-sdk notes
496- **docs/learnings/git-http-backend.md** - Git protocol tips
497
498---
499
500## 🔗 Quick Links
501
502- [Project README](README.md)
503- [Documentation Index](docs/README.md)
504- [Architecture](docs/ARCHITECTURE.md)
505- [Learnings](docs/learnings/)
506- [Archive](docs/archive/)
507
508---
509
510## 💡 Tips for Success
511
5121. **Less is more** - Prefer updating over creating
5132. **Archive often** - Keep root clean
5143. **Extract learnings** - Make knowledge reusable
5154. **Link, don't duplicate** - DRY applies to docs too
5165. **Date everything** - Context is important
5176. **Use descriptive names** - Future you will thank you
5187. **Check before creating** - Document might already exist
5198. **Update as you go** - Don't wait for cleanup time
520
521---
522
523## 🚀 Next Steps
524
525After reading this:
526
5271. **Review current documentation structure**
528 ```bash
529 ls -la *.md
530 ls -la docs/
531 ```
532
5332. **Identify cleanup candidates**
534 - Completed working docs
535 - Obsolete duplicates
536 - Session summaries
537
5383. **Extract learnings**
539 - Review completed docs
540 - Add to docs/learnings/
541
5424. **Archive and clean**
543 - Move to docs/archive/
544 - Delete obsolete files
545 - Update links
546
5475. **Commit changes**
548 ```bash
549 git add .
550 git commit -m "docs: cleanup and reorganization"
551 ```
552
553---
554
555**Remember:** Good documentation structure is like good code structure - it makes everything easier.
556
557---
558
559*Last updated: November 4, 2025*
560*Status: ✅ Active guidelines*
diff --git a/CLEANUP_SUMMARY.md b/CLEANUP_SUMMARY.md
new file mode 100644
index 0000000..8ffce92
--- /dev/null
+++ b/CLEANUP_SUMMARY.md
@@ -0,0 +1,448 @@
1# Documentation Cleanup - November 4, 2025
2
3**Purpose:** Summary of documentation reorganization
4**Status:** ✅ Complete
5
6---
7
8## Summary
9
10Cleaned up **32 markdown files** from project root, organizing them into a clear, maintainable structure.
11
12**Before:** 32 files in root (documentation sprawl)
13**After:** 3 files in root (clean structure)
14
15---
16
17## What Changed
18
19### Root Directory
20
21**Before:**
22```
2332 markdown files including:
24- Session summaries
25- Status reports
26- Migration docs
27- Implementation reports
28- Quick references
29- Planning documents
30```
31
32**After:**
33```
343 essential files:
35- README.md # Project overview
36- AGENTS.md # AI agent guidelines
37- CURRENT_STATUS.md # Current project state
38```
39
40---
41
42### New Structure
43
44```
45docs/
46├── README.md # Docs navigation
47├── ARCHITECTURE.md # System design
48├── TEST_STRATEGY.md # Testing approach
49├── GETTING_STARTED.md # Setup guide
50├── GIT_PROTOCOL.md # Git protocol reference
51├── COMPARISON.md # vs other implementations
52├── DECISION_SUMMARY.md # Key decisions
53
54├── learnings/ # Reusable knowledge
55│ ├── nix-flakes.md # Nix patterns & gotchas ✨ NEW
56│ ├── nostr-sdk.md # nostr-sdk 0.43 notes ✨ NEW
57│ └── grasp-audit.md # Audit tool patterns ✨ NEW
58
59└── archive/ # Historical documents
60 ├── README.md # Archive index ✨ NEW
61 ├── 2025-11-03-*.md # Nov 3 session docs (16 files)
62 └── 2025-11-04-*.md # Nov 4 session docs (14 files)
63```
64
65---
66
67## Documents Archived
68
69### November 3, 2025 (16 files)
70
71**Investigation & Planning:**
72- architecture-investigation.md
73- review-summary.md
74- documentation-index.md
75- grasp-audit-plan.md
76
77**Implementation:**
78- grasp-audit-implementation.md
79- implementation-complete.md
80- verification-complete.md
81
82**Testing:**
83- compliance-test-proposal.md
84- compliance-testing-report.md
85- test-breakdown.md
86- smoke-test-report.md
87- final-audit-report.md
88- final-summary.md
89
90**Reference:**
91- files-created.md
92- quick-reference.md
93- start-here.md
94
95---
96
97### November 4, 2025 (14 files)
98
99**Migrations:**
100- tag-migration.md
101- tag-migration-summary.md
102- flake-migration.md
103
104**Upgrades:**
105- nostr-sdk-upgrade.md
106- upgrade-complete.md
107
108**Fixes:**
109- compilation-fixes.md
110- audit-system-fixed.md
111- audit-status-report.md
112
113**Sessions:**
114- session-summary.md
115- session-complete-1.md
116- session-complete-2.md
117- session-continuation.md
118
119**Planning:**
120- next-session-quickstart.md
121- next-prompt.md
122- ready-for-next-phase.md
123
124---
125
126## Learnings Extracted
127
128Created 3 new learning documents with reusable knowledge:
129
130### 1. docs/learnings/nix-flakes.md
131
132**Content:**
133- Critical gotcha: Use `nix develop`, not `nix-shell`
134- Flake structure and patterns
135- Common commands
136- Subproject flakes
137- Migration from shell.nix
138- Benefits and best practices
139- Common issues and solutions
140
141**Extracted from:**
142- FLAKE_MIGRATION_COMPLETE.md
143- Various session documents
144- Real experience during development
145
146---
147
148### 2. docs/learnings/nostr-sdk.md
149
150**Content:**
151- Current version: 0.43.x
152- Breaking changes from 0.35 → 0.43
153- Common patterns (events, tags, queries)
154- Testing patterns (unit vs integration)
155- Common gotchas and solutions
156- Performance tips
157- Migration checklist
158
159**Extracted from:**
160- NOSTR_SDK_0.43_UPGRADE.md
161- Implementation experience
162- Test code examples
163
164---
165
166### 3. docs/learnings/grasp-audit.md
167
168**Content:**
169- Architecture decisions
170- Audit event tagging strategy
171- Code patterns
172- Test isolation
173- Cleanup strategy
174- Testing organization
175- Lessons learned
176- Common issues
177
178**Extracted from:**
179- TAG_MIGRATION_COMPLETE.md
180- GRASP_AUDIT_PLAN.md
181- Implementation summaries
182- Testing experience
183
184---
185
186## New Documents Created
187
188### CURRENT_STATUS.md
189
190**Purpose:** Single source of truth for project state
191
192**Content:**
193- Quick summary
194- Project structure
195- What works
196- What's next
197- Development workflow
198- Key technologies
199- Important gotchas
200- Recent milestones
201- Success metrics
202- Resources
203
204**Replaces:** Multiple status reports and session summaries
205
206---
207
208### AGENTS.md (Updated)
209
210**Purpose:** AI agent documentation guidelines
211
212**Already existed but now enforced:**
213- Documentation structure
214- Document lifecycle
215- Cleanup process
216- Common gotchas
217- Writing guidelines
218- AI agent responsibilities
219- Quality checklist
220
221---
222
223### docs/archive/README.md
224
225**Purpose:** Archive organization and usage guide
226
227**Content:**
228- Archive organization
229- Document index by date/topic
230- When to reference archives
231- Extracting learnings
232- Archive principles
233- Quick find by topic/date
234
235---
236
237## Benefits Achieved
238
239### 1. Clarity
240
241✅ **Easy to find current information**
242- `CURRENT_STATUS.md` - where we are
243- `README.md` - what the project is
244- `AGENTS.md` - how to document
245
246✅ **Easy to find historical information**
247- `docs/archive/` - organized by date
248- `docs/archive/README.md` - searchable index
249
250---
251
252### 2. Maintainability
253
254✅ **Clear document lifecycle**
255- Working docs in root
256- Permanent docs in docs/
257- Learnings extracted
258- Completed work archived
259
260✅ **No more sprawl**
261- Root directory stays clean
262- Archive grows but stays organized
263- Learnings get updated, not duplicated
264
265---
266
267### 3. Reusability
268
269✅ **Learnings are accessible**
270- Organized by topic, not session
271- Include code examples
272- Link to historical context
273- Living documents that evolve
274
275✅ **Patterns are documented**
276- Nix flake patterns
277- nostr-sdk patterns
278- grasp-audit patterns
279- Testing patterns
280
281---
282
283### 4. Onboarding
284
285✅ **New developers (human or AI) can:**
2861. Read `README.md` - understand project
2872. Read `CURRENT_STATUS.md` - know where we are
2883. Read `AGENTS.md` - learn documentation practices
2894. Read `docs/learnings/` - avoid known pitfalls
2905. Reference `docs/archive/` - understand history
291
292---
293
294## Cleanup Statistics
295
296### Before
297
298```
299Root directory:
300- 32 markdown files
301- Mix of status, reports, plans, summaries
302- Hard to find current information
303- Duplicate information
304- No clear organization
305
306docs/ directory:
307- 7 permanent docs
308- 0 learnings
309- 0 archived docs
310```
311
312### After
313
314```
315Root directory:
316- 3 markdown files (README, AGENTS, CURRENT_STATUS)
317- Clean and focused
318- Clear purpose for each file
319
320docs/ directory:
321- 7 permanent docs (unchanged)
322- 3 learnings (NEW)
323- 30 archived docs (NEW)
324- 1 archive index (NEW)
325```
326
327---
328
329## Document Count
330
331| Location | Count | Purpose |
332|----------|-------|---------|
333| Root | 3 | Essential project files |
334| docs/ | 7 | Permanent documentation |
335| docs/learnings/ | 3 | Reusable knowledge |
336| docs/archive/ | 30 | Historical records |
337| **Total** | **43** | **Well-organized docs** |
338
339---
340
341## Maintenance Going Forward
342
343### Daily Development
344
345**Create working docs in root:**
346- Session notes
347- Status updates
348- Temporary planning
349
350**Keep root clean:**
351- Max 5-10 working docs
352- Archive when complete
353- Extract learnings first
354
355---
356
357### Weekly Cleanup
358
359**Trigger:** Root has >10 markdown files
360
361**Process:**
3621. Review completed working docs
3632. Extract learnings to `docs/learnings/`
3643. Archive to `docs/archive/YYYY-MM-DD-topic.md`
3654. Delete obsolete duplicates
3665. Update `CURRENT_STATUS.md`
3676. Commit changes
368
369---
370
371### Guidelines
372
373**Follow `AGENTS.md` for:**
374- When to create new documents
375- Where to put documents
376- How to name documents
377- When to archive
378- How to extract learnings
379
380---
381
382## Commit Message
383
384```
385docs: major cleanup and reorganization
386
387- Archive 30 completed session documents to docs/archive/
388- Extract learnings to docs/learnings/ (nix-flakes, nostr-sdk, grasp-audit)
389- Create CURRENT_STATUS.md as single source of truth
390- Create docs/archive/README.md for archive organization
391- Clean root directory: 32 files → 3 files
392- Enforce AGENTS.md documentation guidelines
393
394Root directory now contains only:
395- README.md (project overview)
396- AGENTS.md (documentation guidelines)
397- CURRENT_STATUS.md (current state)
398
399All historical documents preserved in docs/archive/ with proper dating.
400All reusable knowledge extracted to docs/learnings/.
401
402Benefits:
403- Easy to find current information
404- Clear document lifecycle
405- No more documentation sprawl
406- Learnings are accessible and reusable
407- Better onboarding for new developers/agents
408```
409
410---
411
412## Verification
413
414```bash
415# Verify structure
416ls -la *.md
417# Should show: README.md, AGENTS.md, CURRENT_STATUS.md
418
419ls -la docs/learnings/
420# Should show: nix-flakes.md, nostr-sdk.md, grasp-audit.md
421
422ls -la docs/archive/ | wc -l
423# Should show: 31 (30 files + README.md)
424
425# Verify no broken links (manual check)
426grep -r "\.md" docs/ | grep -v ".git"
427```
428
429---
430
431## Next Steps
432
4331. ✅ Cleanup complete
4342. ✅ Learnings extracted
4353. ✅ Archive organized
4364. 🔜 Commit changes
4375. 🔜 Start NIP-01 relay implementation
438
439---
440
441**Cleanup completed:** November 4, 2025
442**Files organized:** 43 total
443**Root cleaned:** 32 → 3 files
444**Status:** ✅ Ready for next phase
445
446---
447
448*This document will be archived after commit*
diff --git a/CURRENT_STATUS.md b/CURRENT_STATUS.md
new file mode 100644
index 0000000..417691a
--- /dev/null
+++ b/CURRENT_STATUS.md
@@ -0,0 +1,464 @@
1# ngit-grasp - Current Status
2
3**Date:** November 4, 2025
4**Phase:** Audit Tool Complete - Ready for NIP-01 Implementation
5**Status:** 🟢 All Systems Green
6
7---
8
9## Quick Summary
10
11✅ **grasp-audit tool complete** - NIP-01 smoke tests passing
12✅ **Tag migration complete** - Using standard NIP-01 "t" tags
13✅ **nostr-sdk upgraded** - Version 0.43.x (latest stable)
14✅ **Nix flakes migrated** - Modern reproducible builds
15✅ **Documentation cleaned** - Clear structure established
16
17**Next:** Build NIP-01 relay implementation, test with grasp-audit
18
19---
20
21## Project Structure
22
23```
24ngit-grasp/
25├── README.md # Project overview
26├── AGENTS.md # AI agent guidelines
27├── CURRENT_STATUS.md # This file
28
29├── docs/ # Permanent documentation
30│ ├── ARCHITECTURE.md # System design
31│ ├── TEST_STRATEGY.md # Testing approach
32│ ├── GETTING_STARTED.md # Setup guide
33│ ├── GIT_PROTOCOL.md # Git protocol reference
34│ ├── COMPARISON.md # vs ngit-relay
35│ ├── DECISION_SUMMARY.md # Key decisions
36│ │
37│ ├── learnings/ # Reusable knowledge
38│ │ ├── nix-flakes.md # Nix flake patterns
39│ │ ├── nostr-sdk.md # nostr-sdk 0.43 notes
40│ │ └── grasp-audit.md # Audit tool patterns
41│ │
42│ └── archive/ # Historical documents
43│ ├── 2025-11-04-tag-migration.md
44│ ├── 2025-11-04-flake-migration.md
45│ ├── 2025-11-04-nostr-sdk-upgrade.md
46│ └── ...
47
48└── grasp-audit/ # Audit tool (separate crate)
49 ├── README.md # Audit tool docs
50 ├── QUICK_START.md # Getting started
51 ├── flake.nix # Nix dev environment
52 ├── Cargo.toml # Rust dependencies
53 └── src/
54 ├── specs/ # Test specifications
55 │ └── nip01_smoke.rs # NIP-01 basic tests ✅
56 ├── audit.rs # Audit config & event builder
57 ├── client.rs # Audit client wrapper
58 └── ...
59```
60
61---
62
63## What Works
64
65### grasp-audit Tool ✅
66
67**Status:** Fully functional, all tests passing
68
69```bash
70cd grasp-audit
71nix develop
72cargo test --lib # 12/12 unit tests ✅
73cargo test -- --ignored # 1/1 integration test ✅
74cargo run -- audit --relay ws://localhost:7000 --spec nip01-smoke
75# Results: 6/6 passed (100.0%) ✅
76```
77
78**Features:**
79- ✅ NIP-01 smoke tests (websocket, events, subscriptions)
80- ✅ CI and production modes
81- ✅ Test isolation via unique run IDs
82- ✅ Standard "t" tag usage
83- ✅ Audit event cleanup strategy
84- ✅ CLI interface
85
86**Test Coverage:**
87- websocket_connection
88- send_receive_event
89- create_subscription
90- close_subscription
91- reject_invalid_signature
92- reject_invalid_event_id
93
94---
95
96### Development Environment ✅
97
98**Nix Flakes:**
99- ✅ `grasp-audit/flake.nix` - Reproducible builds
100- ✅ Rust toolchain via rust-overlay
101- ✅ All dependencies managed
102- ✅ Cross-platform support
103
104**Usage:**
105```bash
106cd grasp-audit
107nix develop # Enter dev shell
108nix develop -c cargo build # One-off command
109nix build # Build package
110```
111
112---
113
114### Documentation ✅
115
116**Permanent Docs:**
117- ✅ `docs/ARCHITECTURE.md` - Detailed system design
118- ✅ `docs/TEST_STRATEGY.md` - Testing approach
119- ✅ `docs/GETTING_STARTED.md` - Setup guide
120- ✅ `docs/README.md` - Documentation index
121
122**Learnings:**
123- ✅ `docs/learnings/nix-flakes.md` - Nix patterns and gotchas
124- ✅ `docs/learnings/nostr-sdk.md` - nostr-sdk 0.43 migration
125- ✅ `docs/learnings/grasp-audit.md` - Audit tool patterns
126
127**Guidelines:**
128- ✅ `AGENTS.md` - AI agent documentation practices
129
130---
131
132## What's Next
133
134### Immediate: NIP-01 Relay Implementation
135
136**Goal:** Build basic Nostr relay that passes grasp-audit tests
137
138**Approach:**
1391. Create `src/` directory structure
1402. Implement basic NIP-01 relay using nostr-relay-builder
1413. Run grasp-audit tests against it
1424. Iterate until all tests pass
143
144**Files to Create:**
145```
146src/
147├── main.rs # Entry point
148├── config.rs # Configuration
149├── nostr/
150│ ├── mod.rs
151│ ├── relay.rs # NIP-01 relay setup
152│ └── events.rs # Event handling
153└── storage/
154 ├── mod.rs
155 └── repository.rs # Event storage
156```
157
158**Success Criteria:**
159```bash
160# Start ngit-grasp relay
161cargo run
162
163# In another terminal
164cd grasp-audit
165cargo run -- audit --relay ws://localhost:8080 --spec nip01-smoke
166# Results: 6/6 passed (100.0%) ✅
167```
168
169---
170
171### Phase 2: GRASP-01 Compliance
172
173**After NIP-01 works:**
174
1751. **Extend grasp-audit**
176 - Create `src/specs/grasp_01_relay.rs`
177 - Test repository announcements (NIP-34)
178 - Test state events
179 - Test maintainer validation
180
1812. **Implement in ngit-grasp**
182 - NIP-34 event validation
183 - Repository state management
184 - Maintainer authorization
185
1863. **Iterate**
187 - Run GRASP-01 audit tests
188 - Fix failures
189 - Repeat until passing
190
191---
192
193### Phase 3: Git Integration
194
195**After GRASP-01 compliance:**
196
1971. **Git HTTP Backend**
198 - Implement git-smart-http handlers
199 - Integrate with authorization
200
2012. **Push Validation**
202 - Query Nostr state events
203 - Validate push permissions
204 - Inline authorization (no hooks)
205
2063. **Full GRASP-01**
207 - Complete service requirements
208 - End-to-end testing
209
210---
211
212## Development Workflow
213
214### Daily Development
215
216```bash
217# For ngit-grasp (when we create it)
218cd ngit-grasp
219nix develop
220cargo build
221cargo test
222cargo run
223
224# For grasp-audit
225cd grasp-audit
226nix develop
227cargo build
228cargo test --lib
229cargo test -- --ignored # Requires relay
230cargo run -- audit --relay ws://localhost:8080
231```
232
233---
234
235### Running Tests
236
237**Unit Tests (Fast):**
238```bash
239# grasp-audit
240cd grasp-audit
241cargo test --lib
242
243# ngit-grasp (when created)
244cargo test --lib
245```
246
247**Integration Tests (Requires Relay):**
248```bash
249# Start test relay
250docker run --rm -p 7000:7000 scsibug/nostr-rs-relay
251
252# Run integration tests
253cd grasp-audit
254cargo test -- --ignored
255```
256
257**Audit Tests:**
258```bash
259# Start your relay
260cd ngit-grasp
261cargo run
262
263# Run audit in another terminal
264cd grasp-audit
265cargo run -- audit --relay ws://localhost:8080
266```
267
268---
269
270## Key Technologies
271
272### Current Stack
273
274- **Rust**: Core language
275- **nostr-sdk 0.43**: Nostr event handling
276- **Nix Flakes**: Reproducible dev environment
277- **Cargo**: Build system
278- **Docker**: Test relay (nostr-rs-relay)
279
280### Planned Stack (ngit-grasp)
281
282- **actix-web**: HTTP server
283- **nostr-relay-builder**: Relay infrastructure
284- **git-http-backend**: Git protocol handling
285- **tokio**: Async runtime
286
287---
288
289## Important Gotchas
290
291### 1. Use Nix Flakes, Not nix-shell
292
293```bash
294# ✅ Correct
295nix develop
296
297# ❌ Wrong
298nix-shell
299```
300
301**Why:** We use `flake.nix`, not `shell.nix`
302
303---
304
305### 2. grasp-audit is Separate
306
307```bash
308# ✅ Correct
309cd grasp-audit
310nix develop
311cargo build
312
313# ❌ Wrong
314cd ngit-grasp
315cargo build # Won't find grasp-audit
316```
317
318**Why:** Separate crate with own flake and Cargo.toml
319
320---
321
322### 3. Integration Tests Need Relay
323
324```bash
325# ✅ Correct
326docker run --rm -p 7000:7000 scsibug/nostr-rs-relay
327cargo test -- --ignored
328
329# ❌ Wrong
330cargo test -- --ignored # Will fail without relay
331```
332
333---
334
335### 4. nostr-sdk 0.43 API Changes
336
337**Event Building:**
338```rust
339// ✅ Correct (0.43)
340EventBuilder::new(kind, content)
341 .tags(tags)
342 .sign_with_keys(&keys)?
343
344// ❌ Wrong (0.35)
345EventBuilder::new(kind, content, tags)
346 .to_event(&keys)?
347```
348
349**See:** `docs/learnings/nostr-sdk.md` for full migration guide
350
351---
352
353## Documentation Practices
354
355### When to Create Documents
356
357**Working Docs (Root):**
358- Session summaries
359- Status reports
360- Next steps
361- Temporary notes
362
363**Permanent Docs (docs/):**
364- Architecture
365- Design decisions
366- API documentation
367- User guides
368
369**Learnings (docs/learnings/):**
370- Gotchas and patterns
371- Migration notes
372- Best practices
373- Reusable knowledge
374
375**Archive (docs/archive/):**
376- Completed session docs
377- Historical records
378- Superseded documents
379
380**See:** `AGENTS.md` for full guidelines
381
382---
383
384## Recent Milestones
385
386- ✅ **Nov 4, 2025** - Tag migration to standard "t" tags
387- ✅ **Nov 4, 2025** - Flake migration (shell.nix → flake.nix)
388- ✅ **Nov 4, 2025** - nostr-sdk upgrade (0.35 → 0.43)
389- ✅ **Nov 4, 2025** - Documentation cleanup
390- ✅ **Nov 3, 2025** - Architecture investigation complete
391- ✅ **Nov 3, 2025** - grasp-audit tool implemented
392- ✅ **Nov 3, 2025** - NIP-01 smoke tests passing
393
394---
395
396## Success Metrics
397
398### Current Status
399
400| Metric | Status | Details |
401|--------|--------|---------|
402| grasp-audit builds | ✅ | Clean build, no warnings |
403| Unit tests | ✅ | 12/12 passing |
404| Integration tests | ✅ | 1/1 passing |
405| CLI works | ✅ | All commands functional |
406| Smoke tests | ✅ | 6/6 passing |
407| Documentation | ✅ | Complete and organized |
408| Nix flakes | ✅ | Reproducible builds |
409
410### Next Milestone: NIP-01 Relay
411
412| Metric | Status | Target |
413|--------|--------|--------|
414| ngit-grasp builds | 🔜 | Clean build |
415| NIP-01 relay running | 🔜 | Accepts connections |
416| Smoke tests pass | 🔜 | 6/6 against ngit-grasp |
417| Basic event storage | 🔜 | Events persist |
418| Subscriptions work | 🔜 | Real-time updates |
419
420---
421
422## Resources
423
424### Documentation
425- [Project README](README.md)
426- [Architecture](docs/ARCHITECTURE.md)
427- [Test Strategy](docs/TEST_STRATEGY.md)
428- [Getting Started](docs/GETTING_STARTED.md)
429- [Agent Guidelines](AGENTS.md)
430
431### Learnings
432- [Nix Flakes](docs/learnings/nix-flakes.md)
433- [nostr-sdk](docs/learnings/nostr-sdk.md)
434- [grasp-audit](docs/learnings/grasp-audit.md)
435
436### External
437- [GRASP Protocol](https://gitworkshop.dev/danconwaydev.com/grasp)
438- [NIP-01](https://github.com/nostr-protocol/nips/blob/master/01.md)
439- [NIP-34](https://github.com/nostr-protocol/nips/blob/master/34.md)
440- [nostr-sdk docs](https://docs.rs/nostr-sdk/0.43.0)
441
442---
443
444## Contact & Contribution
445
446**Status:** Alpha - Active Development
447**License:** MIT
448**Repository:** ngit-grasp (local development)
449
450**Contributing:**
4511. Read `AGENTS.md` for documentation practices
4522. Review `docs/ARCHITECTURE.md` for design
4533. Check `CURRENT_STATUS.md` (this file) for current state
4544. Follow Rust conventions (`cargo fmt`, `cargo clippy`)
4555. Add tests for new functionality
456
457---
458
459**Last Updated:** November 4, 2025
460**Next Review:** When NIP-01 relay is implemented
461
462---
463
464*Status: 🟢 Ready to build NIP-01 relay implementation*
diff --git a/INVESTIGATION_COMPLETE.md b/docs/archive/2025-11-03-architecture-investigation.md
index 190a010..190a010 100644
--- a/INVESTIGATION_COMPLETE.md
+++ b/docs/archive/2025-11-03-architecture-investigation.md
diff --git a/COMPLIANCE_TEST_PROPOSAL.md b/docs/archive/2025-11-03-compliance-test-proposal.md
index 792f375..792f375 100644
--- a/COMPLIANCE_TEST_PROPOSAL.md
+++ b/docs/archive/2025-11-03-compliance-test-proposal.md
diff --git a/REPORT_COMPLIANCE_TESTING.md b/docs/archive/2025-11-03-compliance-testing-report.md
index d850f73..d850f73 100644
--- a/REPORT_COMPLIANCE_TESTING.md
+++ b/docs/archive/2025-11-03-compliance-testing-report.md
diff --git a/DOCUMENTATION_INDEX.md b/docs/archive/2025-11-03-documentation-index.md
index 17ba744..17ba744 100644
--- a/DOCUMENTATION_INDEX.md
+++ b/docs/archive/2025-11-03-documentation-index.md
diff --git a/FILES_CREATED.md b/docs/archive/2025-11-03-files-created.md
index 2bdb0f4..2bdb0f4 100644
--- a/FILES_CREATED.md
+++ b/docs/archive/2025-11-03-files-created.md
diff --git a/FINAL_AUDIT_REPORT.md b/docs/archive/2025-11-03-final-audit-report.md
index 83419d9..83419d9 100644
--- a/FINAL_AUDIT_REPORT.md
+++ b/docs/archive/2025-11-03-final-audit-report.md
diff --git a/FINAL_SUMMARY.md b/docs/archive/2025-11-03-final-summary.md
index 19e7a06..19e7a06 100644
--- a/FINAL_SUMMARY.md
+++ b/docs/archive/2025-11-03-final-summary.md
diff --git a/GRASP_AUDIT_IMPLEMENTATION_SUMMARY.md b/docs/archive/2025-11-03-grasp-audit-implementation.md
index 827db24..827db24 100644
--- a/GRASP_AUDIT_IMPLEMENTATION_SUMMARY.md
+++ b/docs/archive/2025-11-03-grasp-audit-implementation.md
diff --git a/GRASP_AUDIT_PLAN.md b/docs/archive/2025-11-03-grasp-audit-plan.md
index 96097a3..96097a3 100644
--- a/GRASP_AUDIT_PLAN.md
+++ b/docs/archive/2025-11-03-grasp-audit-plan.md
diff --git a/IMPLEMENTATION_COMPLETE.md b/docs/archive/2025-11-03-implementation-complete.md
index 1938595..1938595 100644
--- a/IMPLEMENTATION_COMPLETE.md
+++ b/docs/archive/2025-11-03-implementation-complete.md
diff --git a/QUICK_REFERENCE.md b/docs/archive/2025-11-03-quick-reference.md
index b9b9943..b9b9943 100644
--- a/QUICK_REFERENCE.md
+++ b/docs/archive/2025-11-03-quick-reference.md
diff --git a/REVIEW_SUMMARY.md b/docs/archive/2025-11-03-review-summary.md
index f66a371..f66a371 100644
--- a/REVIEW_SUMMARY.md
+++ b/docs/archive/2025-11-03-review-summary.md
diff --git a/SMOKE_TEST_REPORT.md b/docs/archive/2025-11-03-smoke-test-report.md
index ccb3916..ccb3916 100644
--- a/SMOKE_TEST_REPORT.md
+++ b/docs/archive/2025-11-03-smoke-test-report.md
diff --git a/START_HERE.md b/docs/archive/2025-11-03-start-here.md
index eaa125c..eaa125c 100644
--- a/START_HERE.md
+++ b/docs/archive/2025-11-03-start-here.md
diff --git a/TEST_BREAKDOWN.md b/docs/archive/2025-11-03-test-breakdown.md
index c054cd3..c054cd3 100644
--- a/TEST_BREAKDOWN.md
+++ b/docs/archive/2025-11-03-test-breakdown.md
diff --git a/VERIFICATION_COMPLETE.md b/docs/archive/2025-11-03-verification-complete.md
index e1efa65..e1efa65 100644
--- a/VERIFICATION_COMPLETE.md
+++ b/docs/archive/2025-11-03-verification-complete.md
diff --git a/AUDIT_SYSTEM_STATUS_REPORT.md b/docs/archive/2025-11-04-audit-status-report.md
index 3e1c3e7..3e1c3e7 100644
--- a/AUDIT_SYSTEM_STATUS_REPORT.md
+++ b/docs/archive/2025-11-04-audit-status-report.md
diff --git a/AUDIT_SYSTEM_FIXED.md b/docs/archive/2025-11-04-audit-system-fixed.md
index e47ac44..e47ac44 100644
--- a/AUDIT_SYSTEM_FIXED.md
+++ b/docs/archive/2025-11-04-audit-system-fixed.md
diff --git a/COMPILATION_FIXES.md b/docs/archive/2025-11-04-compilation-fixes.md
index 18584eb..18584eb 100644
--- a/COMPILATION_FIXES.md
+++ b/docs/archive/2025-11-04-compilation-fixes.md
diff --git a/FLAKE_MIGRATION_COMPLETE.md b/docs/archive/2025-11-04-flake-migration.md
index 2d2514d..2d2514d 100644
--- a/FLAKE_MIGRATION_COMPLETE.md
+++ b/docs/archive/2025-11-04-flake-migration.md
diff --git a/next_prompt.md b/docs/archive/2025-11-04-next-prompt.md
index 7cfdd32..7cfdd32 100644
--- a/next_prompt.md
+++ b/docs/archive/2025-11-04-next-prompt.md
diff --git a/NEXT_SESSION_QUICKSTART.md b/docs/archive/2025-11-04-next-session-quickstart.md
index a198bf9..a198bf9 100644
--- a/NEXT_SESSION_QUICKSTART.md
+++ b/docs/archive/2025-11-04-next-session-quickstart.md
diff --git a/NOSTR_SDK_0.43_UPGRADE.md b/docs/archive/2025-11-04-nostr-sdk-upgrade.md
index 052b851..052b851 100644
--- a/NOSTR_SDK_0.43_UPGRADE.md
+++ b/docs/archive/2025-11-04-nostr-sdk-upgrade.md
diff --git a/READY_FOR_NEXT_PHASE.md b/docs/archive/2025-11-04-ready-for-next-phase.md
index 10ad84a..10ad84a 100644
--- a/READY_FOR_NEXT_PHASE.md
+++ b/docs/archive/2025-11-04-ready-for-next-phase.md
diff --git a/SESSION_COMPLETE.md b/docs/archive/2025-11-04-session-complete-1.md
index 3f07161..3f07161 100644
--- a/SESSION_COMPLETE.md
+++ b/docs/archive/2025-11-04-session-complete-1.md
diff --git a/SESSION_COMPLETE_2025_11_04.md b/docs/archive/2025-11-04-session-complete-2.md
index 5de92f6..5de92f6 100644
--- a/SESSION_COMPLETE_2025_11_04.md
+++ b/docs/archive/2025-11-04-session-complete-2.md
diff --git a/SESSION_CONTINUATION_COMPLETE.md b/docs/archive/2025-11-04-session-continuation.md
index 6838115..6838115 100644
--- a/SESSION_CONTINUATION_COMPLETE.md
+++ b/docs/archive/2025-11-04-session-continuation.md
diff --git a/SESSION_2025_11_04_SUMMARY.md b/docs/archive/2025-11-04-session-summary.md
index 4cc53b0..4cc53b0 100644
--- a/SESSION_2025_11_04_SUMMARY.md
+++ b/docs/archive/2025-11-04-session-summary.md
diff --git a/TAG_MIGRATION_SUMMARY.md b/docs/archive/2025-11-04-tag-migration-summary.md
index 34d4ff0..34d4ff0 100644
--- a/TAG_MIGRATION_SUMMARY.md
+++ b/docs/archive/2025-11-04-tag-migration-summary.md
diff --git a/TAG_MIGRATION_COMPLETE.md b/docs/archive/2025-11-04-tag-migration.md
index c2fdbfc..c2fdbfc 100644
--- a/TAG_MIGRATION_COMPLETE.md
+++ b/docs/archive/2025-11-04-tag-migration.md
diff --git a/UPGRADE_COMPLETE.md b/docs/archive/2025-11-04-upgrade-complete.md
index 8fe3ebc..8fe3ebc 100644
--- a/UPGRADE_COMPLETE.md
+++ b/docs/archive/2025-11-04-upgrade-complete.md
diff --git a/docs/archive/README.md b/docs/archive/README.md
new file mode 100644
index 0000000..9ff9e3e
--- /dev/null
+++ b/docs/archive/README.md
@@ -0,0 +1,158 @@
1# Archive - Historical Documentation
2
3**Purpose:** Completed session documents, phase reports, and historical records
4**Status:** Read-only - documents are not modified after archiving
5
6---
7
8## Archive Organization
9
10Documents are organized by date (YYYY-MM-DD) and topic.
11
12### November 3, 2025 - Architecture Investigation & Initial Implementation
13
14**Architecture Investigation:**
15- `2025-11-03-architecture-investigation.md` - GRASP protocol investigation complete
16- `2025-11-03-review-summary.md` - Executive summary of investigation
17- `2025-11-03-documentation-index.md` - Initial docs structure
18
19**grasp-audit Implementation:**
20- `2025-11-03-grasp-audit-plan.md` - Audit tool design decisions
21- `2025-11-03-grasp-audit-implementation.md` - Implementation summary
22- `2025-11-03-implementation-complete.md` - Initial implementation complete
23- `2025-11-03-verification-complete.md` - Verification results
24
25**Testing:**
26- `2025-11-03-compliance-test-proposal.md` - Test strategy proposal
27- `2025-11-03-compliance-testing-report.md` - Compliance testing report
28- `2025-11-03-test-breakdown.md` - Detailed test breakdown
29- `2025-11-03-smoke-test-report.md` - Smoke test results
30- `2025-11-03-final-audit-report.md` - Final audit report
31- `2025-11-03-final-summary.md` - Final summary
32
33**Reference:**
34- `2025-11-03-files-created.md` - Files created during investigation
35- `2025-11-03-quick-reference.md` - Quick reference guide
36- `2025-11-03-start-here.md` - Getting started guide
37
38---
39
40### November 4, 2025 - Upgrades & Migrations
41
42**Tag Migration:**
43- `2025-11-04-tag-migration.md` - Migration to standard "t" tags (detailed)
44- `2025-11-04-tag-migration-summary.md` - Migration summary
45
46**Flake Migration:**
47- `2025-11-04-flake-migration.md` - shell.nix → flake.nix migration
48
49**nostr-sdk Upgrade:**
50- `2025-11-04-nostr-sdk-upgrade.md` - 0.35 → 0.43 upgrade guide
51- `2025-11-04-upgrade-complete.md` - Upgrade completion report
52
53**Fixes & Improvements:**
54- `2025-11-04-compilation-fixes.md` - Compilation fixes
55- `2025-11-04-audit-system-fixed.md` - Audit system fixes
56- `2025-11-04-audit-status-report.md` - Audit status report
57
58**Session Summaries:**
59- `2025-11-04-session-summary.md` - Main session summary
60- `2025-11-04-session-complete-1.md` - Session completion 1
61- `2025-11-04-session-complete-2.md` - Session completion 2
62- `2025-11-04-session-continuation.md` - Session continuation
63
64**Planning:**
65- `2025-11-04-next-session-quickstart.md` - Next session quickstart
66- `2025-11-04-next-prompt.md` - Next prompt planning
67- `2025-11-04-ready-for-next-phase.md` - Phase readiness report
68
69---
70
71## Using Archived Documents
72
73### When to Reference
74
75✅ **Good reasons to reference:**
76- Understanding historical context
77- Learning from past decisions
78- Reviewing what was tried before
79- Tracking project evolution
80
81❌ **Don't reference for:**
82- Current implementation details (use `docs/` instead)
83- Active development (use `CURRENT_STATUS.md`)
84- Reusable patterns (use `docs/learnings/`)
85
86### Extracting Learnings
87
88If you find useful patterns or gotchas in archived documents:
89
901. Extract to appropriate `docs/learnings/*.md` file
912. Update with current context
923. Link to archive for historical context
93
94**Example:**
95```markdown
96<!-- In docs/learnings/nostr-sdk.md -->
97
98## Tag Migration Pattern
99
100When changing tag structure...
101
102**Reference:** See `docs/archive/2025-11-04-tag-migration.md` for detailed migration story.
103```
104
105---
106
107## Archive Principles
108
1091. **Immutable**: Documents are not modified after archiving
1102. **Dated**: All filenames include YYYY-MM-DD prefix
1113. **Organized**: Grouped by date and topic
1124. **Referenced**: Can be linked from active docs for context
1135. **Searchable**: Full-text search helps find historical info
114
115---
116
117## Document Lifecycle
118
119```
120Working Doc (root)
121
122Extract Learnings → docs/learnings/
123
124Archive → docs/archive/
125
126Reference (read-only)
127```
128
129---
130
131## Quick Find
132
133### By Topic
134
135- **Architecture**: `2025-11-03-architecture-investigation.md`
136- **Testing**: `2025-11-03-*-test-*.md`
137- **Migrations**: `2025-11-04-*-migration.md`
138- **Upgrades**: `2025-11-04-*-upgrade.md`
139- **Sessions**: `2025-11-04-session-*.md`
140
141### By Date
142
143- **Nov 3**: Initial investigation and implementation
144- **Nov 4**: Upgrades, migrations, and refinements
145
146---
147
148## Related Documentation
149
150- **Active Status**: `../CURRENT_STATUS.md`
151- **Learnings**: `../learnings/`
152- **Architecture**: `../ARCHITECTURE.md`
153- **Guidelines**: `../../AGENTS.md`
154
155---
156
157*Archive established: November 4, 2025*
158*Total documents: 30*
diff --git a/docs/learnings/grasp-audit.md b/docs/learnings/grasp-audit.md
new file mode 100644
index 0000000..531ebda
--- /dev/null
+++ b/docs/learnings/grasp-audit.md
@@ -0,0 +1,498 @@
1# GRASP Audit Tool - Patterns and Learnings
2
3**Purpose:** Document grasp-audit architecture, patterns, and lessons learned
4**Last Updated:** November 4, 2025
5
6---
7
8## Overview
9
10`grasp-audit` is a compliance testing tool for GRASP (Git Relays Authorized via Signed-Nostr Proofs) protocol implementations. It tests both Nostr relay compliance (NIP-01) and GRASP-specific functionality.
11
12---
13
14## Architecture Decisions
15
16### Separate Crate Strategy
17
18**Decision:** Build `grasp-audit` as a separate crate from `ngit-grasp`
19
20**Why:**
211. **Parallel Development**: Can build tests before implementation
222. **Isolated Testing**: Tests run in isolation (CI/CD safe)
233. **Production Auditing**: Can audit live production services
244. **Reusability**: Other GRASP implementations can use it
25
26**Location:** `grasp-audit/` subdirectory with own `Cargo.toml` and `flake.nix`
27
28---
29
30### Audit Event Tagging Strategy
31
32**Problem:** Test events pollute the relay and need cleanup without deletion events.
33
34**Solution:** Use special tags to mark audit events:
35
36```rust
37// Every audit event includes these tags
38[
39 ["t", "grasp-audit-test-event"], // Marker
40 ["t", "audit-{run-id}"], // Run isolation
41 ["t", "audit-cleanup-after-{timestamp}"] // Cleanup time
42]
43```
44
45**Benefits:**
46- ✅ **Queryable**: Can find all audit events via tag filter
47- ✅ **Isolated**: Each test run has unique run ID
48- ✅ **Self-cleaning**: Cleanup timestamp indicates when to delete
49- ✅ **No deletion events**: Direct database cleanup, no KIND 5 events
50- ✅ **Production safe**: Won't interfere with real events
51
52**Reference:** See `docs/archive/2025-11-04-tag-migration.md`
53
54---
55
56### Standard "t" Tags vs Custom Tags
57
58**Evolution:**
591. **Original**: Custom single-letter tags (`g`, `r`, `c`)
602. **Current**: Standard NIP-01 "t" tags with prefixed values
61
62**Why we changed:**
63- ❌ Custom tags could conflict with other systems
64- ✅ "t" tag is standard for categorization/topics
65- ✅ Multiple "t" tags are expected and supported
66- ✅ Self-documenting values (`audit-{run-id}` vs just `{run-id}`)
67- ✅ Better namespacing with prefixes
68
69**Migration:** Completed November 4, 2025
70
71---
72
73## Code Patterns
74
75### Audit Configuration
76
77```rust
78use grasp_audit::audit::AuditConfig;
79
80// CI mode - isolated test runs
81let config = AuditConfig::ci();
82// Generates UUID run ID: "ci-{uuid}"
83// Cleanup after 1 hour
84
85// Production mode - persistent run ID
86let config = AuditConfig::production("prod-server-1");
87// Uses provided run ID
88// Cleanup after 24 hours
89```
90
91**When to use:**
92- **CI mode**: Automated testing, parallel runs, temporary
93- **Production mode**: Manual audits, monitoring, persistent
94
95---
96
97### Creating Audit Events
98
99```rust
100use grasp_audit::audit::{AuditConfig, AuditEventBuilder};
101use nostr_sdk::prelude::*;
102
103let config = AuditConfig::ci();
104let keys = Keys::generate();
105
106// Create audit event
107let event = AuditEventBuilder::new(&config, Kind::TextNote, "test content")
108 .build(&keys)?;
109
110// Event automatically includes:
111// - Audit marker tag
112// - Run ID tag
113// - Cleanup timestamp tag
114```
115
116---
117
118### Querying Audit Events
119
120```rust
121use grasp_audit::client::AuditClient;
122use grasp_audit::audit::AuditConfig;
123
124let config = AuditConfig::ci();
125let client = AuditClient::new(config, keys);
126
127// Connect to relay
128client.add_relay("ws://localhost:7000").await?;
129client.connect().await;
130
131// Query audit events for this run
132let events = client.query().await?;
133
134// Events are filtered by:
135// - "grasp-audit-test-event" marker
136// - Current run ID
137```
138
139---
140
141### Test Isolation
142
143**Each test run is isolated by unique run ID:**
144
145```rust
146// CI mode generates unique UUID per run
147let config1 = AuditConfig::ci();
148let config2 = AuditConfig::ci();
149
150// config1.run_id != config2.run_id
151// Tests won't interfere with each other
152```
153
154**Benefits:**
155- ✅ Parallel CI/CD runs don't conflict
156- ✅ Can run multiple test suites simultaneously
157- ✅ Easy to identify which run created which events
158- ✅ Cleanup can target specific runs
159
160---
161
162### Cleanup Strategy
163
164**Two-phase cleanup:**
165
1661. **Automatic expiry** via cleanup timestamp tag
1672. **Manual cleanup** by querying and deleting
168
169```rust
170// Events include cleanup timestamp
171["t", "audit-cleanup-after-1730707200"]
172
173// Cleanup process:
174// 1. Query events with expired cleanup timestamp
175// 2. Delete from database directly (no KIND 5)
176// 3. Avoid deletion event pollution
177```
178
179**Implementation:** To be built in relay (not in audit tool)
180
181---
182
183## Testing Strategy
184
185### Test Organization
186
187```
188grasp-audit/src/specs/
189├── nip01_smoke.rs # NIP-01 basic functionality
190├── grasp_01_relay.rs # GRASP-01 relay requirements (planned)
191└── mod.rs # Test suite registry
192```
193
194### Unit vs Integration Tests
195
196**Unit Tests** (no relay required):
197```rust
198#[cfg(test)]
199mod tests {
200 #[test]
201 fn test_audit_config() {
202 let config = AuditConfig::ci();
203 assert!(config.run_id.starts_with("ci-"));
204 }
205}
206```
207
208**Integration Tests** (relay required):
209```rust
210#[cfg(test)]
211mod tests {
212 #[tokio::test]
213 #[ignore] // Requires relay
214 async fn test_smoke_tests_against_relay() {
215 // Test against real relay
216 }
217}
218```
219
220**Running tests:**
221```bash
222# Unit tests (fast, no dependencies)
223cargo test --lib
224
225# Integration tests (requires relay)
226docker run --rm -p 7000:7000 scsibug/nostr-rs-relay
227cargo test -- --ignored
228```
229
230---
231
232### Test Result Reporting
233
234```rust
235use grasp_audit::result::AuditResult;
236
237// Run tests
238let results = vec![
239 AuditResult::pass("websocket_connection", "Connected successfully"),
240 AuditResult::fail("invalid_event", "Expected rejection, got acceptance"),
241];
242
243// Report
244for result in &results {
245 println!("{}", result);
246}
247
248// Summary
249let passed = results.iter().filter(|r| r.is_pass()).count();
250let total = results.len();
251println!("Results: {}/{} passed ({:.1}%)",
252 passed, total, (passed as f64 / total as f64) * 100.0);
253```
254
255---
256
257## CLI Design
258
259### Command Structure
260
261```bash
262grasp-audit audit [OPTIONS]
263
264Options:
265 --relay <URL> Relay to test (required)
266 --mode <MODE> ci or production (default: ci)
267 --run-id <ID> Custom run ID (production mode only)
268 --spec <SPEC> Test spec to run (default: all)
269 --verbose Detailed output
270```
271
272### Usage Examples
273
274```bash
275# CI mode - quick smoke test
276grasp-audit audit \
277 --relay ws://localhost:7000 \
278 --mode ci \
279 --spec nip01-smoke
280
281# Production mode - full compliance audit
282grasp-audit audit \
283 --relay wss://relay.example.com \
284 --mode production \
285 --run-id "audit-2025-11-04" \
286 --verbose
287
288# Test all specs
289grasp-audit audit --relay ws://localhost:7000
290```
291
292---
293
294## Lessons Learned
295
296### 1. Tag Migration is Breaking
297
298**Lesson:** Changing tag structure breaks event queries.
299
300**Impact:** Events created with old tags won't be found by new queries.
301
302**Mitigation:**
303- ✅ Accept breaking changes in alpha stage
304- ✅ Document migration clearly
305- ✅ Old events auto-expire via cleanup
306- ✅ No production deployments affected
307
308**Reference:** `docs/archive/2025-11-04-tag-migration.md`
309
310---
311
312### 2. Test Data Lifecycle Matters
313
314**Lesson:** Test events accumulate and pollute relay.
315
316**Solution:** Built-in cleanup strategy from day one.
317
318**Implementation:**
319- Every event has cleanup timestamp
320- Relay can cleanup expired events
321- No deletion event pollution (direct DB cleanup)
322
323---
324
325### 3. Isolation Enables Parallel Testing
326
327**Lesson:** Unique run IDs enable parallel test execution.
328
329**Benefit:** CI/CD can run multiple test suites simultaneously.
330
331**Pattern:**
332```rust
333// Each CI run gets unique ID
334let config = AuditConfig::ci();
335// run_id = "ci-{uuid}"
336
337// Tests isolated by run ID
338let events = client.query().await?;
339// Only returns events for this run
340```
341
342---
343
344### 4. Standards Compliance Reduces Friction
345
346**Lesson:** Using standard NIP-01 "t" tags instead of custom tags.
347
348**Benefits:**
349- ✅ No conflicts with other systems
350- ✅ Standard relay filtering works
351- ✅ Better interoperability
352- ✅ Self-documenting
353
354---
355
356## Future Enhancements
357
358### Planned Features
359
360- [ ] **GRASP-01 Test Suite**: Repository announcement and state event tests
361- [ ] **Test Report Generation**: JSON/HTML output for CI/CD
362- [ ] **Performance Benchmarks**: Measure relay performance
363- [ ] **Relay Comparison**: Side-by-side compliance comparison
364- [ ] **Continuous Monitoring**: Periodic production audits
365
366---
367
368### Possible Improvements
369
370- [ ] **Parallel Test Execution**: Run specs in parallel
371- [ ] **Retry Logic**: Handle transient failures
372- [ ] **Custom Assertions**: Domain-specific test helpers
373- [ ] **Event Diff Tool**: Compare expected vs actual events
374- [ ] **Cleanup Automation**: Auto-cleanup after tests
375
376---
377
378## Common Issues
379
380### Issue: Integration Tests Fail
381
382**Symptoms:** Tests timeout or fail to connect
383
384**Causes:**
3851. No relay running
3862. Wrong relay URL
3873. Firewall blocking connection
388
389**Solution:**
390```bash
391# Start relay
392docker run --rm -p 7000:7000 scsibug/nostr-rs-relay
393
394# Verify relay is running
395curl http://localhost:7000
396
397# Run tests
398cargo test -- --ignored
399```
400
401---
402
403### Issue: Events Not Found in Query
404
405**Symptoms:** Query returns empty even though events were sent
406
407**Causes:**
4081. Wrong run ID (querying different run)
4092. Connection timing (query before event propagated)
4103. Tag mismatch (uppercase vs lowercase)
411
412**Solution:**
413```rust
414// Use same config for send and query
415let config = AuditConfig::ci();
416
417// Wait for event to propagate
418tokio::time::sleep(Duration::from_millis(500)).await;
419
420// Verify tags match exactly
421let t_tag = SingleLetterTag::lowercase(Alphabet::T); // Lowercase!
422```
423
424---
425
426### Issue: Build Fails in CI
427
428**Symptoms:** `cargo build` fails with dependency errors
429
430**Cause:** Not in Nix dev environment
431
432**Solution:**
433```bash
434# Enter Nix environment first
435cd grasp-audit
436nix develop
437
438# Then build
439cargo build
440```
441
442---
443
444## Quick Reference
445
446### Configuration
447
448```rust
449// CI mode
450let config = AuditConfig::ci();
451
452// Production mode
453let config = AuditConfig::production("run-id");
454```
455
456### Event Creation
457
458```rust
459let event = AuditEventBuilder::new(&config, kind, content)
460 .build(&keys)?;
461```
462
463### Client Usage
464
465```rust
466let client = AuditClient::new(config, keys);
467client.add_relay("ws://localhost:7000").await?;
468client.connect().await;
469let events = client.query().await?;
470```
471
472### Running Tests
473
474```bash
475# Unit tests
476cargo test --lib
477
478# Integration tests
479cargo test -- --ignored
480
481# CLI
482cargo run -- audit --relay ws://localhost:7000
483```
484
485---
486
487## References
488
489- **GRASP Protocol**: https://gitworkshop.dev/danconwaydev.com/grasp
490- **NIP-01**: https://github.com/nostr-protocol/nips/blob/master/01.md
491- **NIP-34**: https://github.com/nostr-protocol/nips/blob/master/34.md
492- **grasp-audit README**: `grasp-audit/README.md`
493- **Tag Migration**: `docs/archive/2025-11-04-tag-migration.md`
494
495---
496
497*Last updated: November 4, 2025*
498*Status: Living document - update as grasp-audit evolves*
diff --git a/docs/learnings/nix-flakes.md b/docs/learnings/nix-flakes.md
new file mode 100644
index 0000000..6876647
--- /dev/null
+++ b/docs/learnings/nix-flakes.md
@@ -0,0 +1,423 @@
1# Nix Flakes - Learnings and Gotchas
2
3**Purpose:** Document Nix flake patterns, gotchas, and best practices learned during ngit-grasp development
4**Last Updated:** November 4, 2025
5
6---
7
8## Critical Gotchas
9
10### Always Use `nix develop`, Not `nix-shell`
11
12**Problem:** We use `flake.nix`, not `shell.nix`. Using `nix-shell` will fail or use the wrong environment.
13
14```bash
15# ✅ Correct - for flake.nix
16cd grasp-audit
17nix develop
18nix develop -c cargo build
19
20# ❌ Wrong - for shell.nix (we don't use this)
21nix-shell
22nix-shell --run "cargo build"
23```
24
25**Why:**
26- `nix-shell` looks for `shell.nix` or `default.nix`
27- `nix develop` looks for `flake.nix`
28- We migrated from `shell.nix` to `flake.nix` on November 4, 2025
29
30**Related:** See `docs/archive/2025-11-04-flake-migration.md`
31
32---
33
34## Flake Structure
35
36### Our Standard Flake Pattern
37
38```nix
39{
40 inputs = {
41 nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
42 rust-overlay.url = "github:oxalica/rust-overlay";
43 flake-utils.url = "github:numtide/flake-utils";
44 };
45
46 outputs = { nixpkgs, rust-overlay, flake-utils, ... }:
47 flake-utils.lib.eachDefaultSystem (system:
48 let
49 overlays = [ (import rust-overlay) ];
50 pkgs = import nixpkgs { inherit system overlays; };
51 manifest = pkgs.lib.importTOML ./Cargo.toml;
52 in with pkgs; {
53 # Development shell
54 devShells.default = mkShell {
55 nativeBuildInputs = [
56 rust-bin.stable.latest.default
57 pkg-config
58 gitlint
59 ];
60 buildInputs = [
61 openssl
62 ];
63 shellHook = ''
64 echo "🦀 Development environment loaded"
65 export RUST_SRC_PATH=${pkgs.rustPlatform.rustLibSrc}
66 '';
67 };
68
69 # Package output
70 packages.default = pkgs.rustPlatform.buildRustPackage {
71 pname = manifest.package.name;
72 version = manifest.package.version;
73 src = ./.;
74 cargoLock = { lockFile = ./Cargo.lock; };
75 buildInputs = [ openssl ];
76 nativeBuildInputs = [ pkg-config ];
77 doCheck = false; # Run tests separately
78 };
79 });
80}
81```
82
83### Key Components
84
851. **rust-overlay**: Provides latest stable Rust toolchain
862. **flake-utils**: Cross-platform support helper
873. **manifest**: Auto-read version from Cargo.toml
884. **devShells.default**: Development environment
895. **packages.default**: Buildable package
90
91---
92
93## Common Flake Commands
94
95### Essential Commands
96
97```bash
98# Enter development shell
99nix develop
100
101# Run command in dev shell (one-off)
102nix develop -c cargo build
103
104# Show flake outputs
105nix flake show
106
107# Check flake validity
108nix flake check
109
110# Update flake inputs (like updating dependencies)
111nix flake update
112
113# Build the package directly
114nix build
115
116# Run without installing
117nix run
118
119# Show flake metadata
120nix flake metadata
121```
122
123### Debugging Commands
124
125```bash
126# Show detailed evaluation trace
127nix develop --show-trace
128
129# Print flake evaluation
130nix eval .#devShells.x86_64-linux.default
131
132# Check what's in the store
133nix path-info .#packages.x86_64-linux.default
134```
135
136---
137
138## Subproject Flakes
139
140### grasp-audit Has Its Own Flake
141
142**Important:** `grasp-audit/` is a subproject with its own `flake.nix` and `Cargo.toml`.
143
144```bash
145# ✅ Correct - enter grasp-audit environment
146cd grasp-audit
147nix develop
148cargo build
149
150# ❌ Wrong - can't build from root
151cd ngit-grasp
152cargo build # This won't find grasp-audit dependencies
153```
154
155**Why:**
156- Each Rust workspace needs its own Nix environment
157- Dependencies are project-specific
158- Flake inputs are locked per-project
159
160---
161
162## Migration from shell.nix to flake.nix
163
164### What Changed
165
166**Before (shell.nix):**
167```nix
168{ pkgs ? import <nixpkgs> {} }:
169
170pkgs.mkShell {
171 buildInputs = with pkgs; [
172 rustc
173 cargo
174 openssl
175 pkg-config
176 ];
177}
178```
179
180**After (flake.nix):**
181- Locked inputs (reproducible)
182- Multi-output (dev shell + package)
183- Cross-platform by default
184- Better tooling integration
185
186### Migration Steps
187
1881. Create `flake.nix` with standard structure
1892. Run `nix flake check` to validate
1903. Update all documentation: `nix-shell` → `nix develop`
1914. Test that build works: `nix develop -c cargo build`
1925. Remove `shell.nix`
1936. Commit changes
194
195**Reference:** See `docs/archive/2025-11-04-flake-migration.md`
196
197---
198
199## Benefits of Flakes
200
201### Reproducibility
202
203**Locked inputs** ensure everyone gets the same environment:
204
205```bash
206# flake.lock contains exact commits
207$ cat flake.lock
208{
209 "nodes": {
210 "nixpkgs": {
211 "locked": {
212 "lastModified": 1698611440,
213 "narHash": "sha256-jPjHjrerhYDy3q9+s5EAsuhyhuknNfowY6yt6pjn9pc=",
214 "rev": "23e89e0c8c5e2d9cf5b5e7c3e8e8e8e8e8e8e8e8"
215 }
216 }
217 }
218}
219```
220
221Everyone running `nix develop` gets **exactly** this version of nixpkgs.
222
223### Multi-Output
224
225Single flake provides:
226- **devShells.default**: Development environment
227- **packages.default**: Buildable package
228- **apps.default**: Runnable application (optional)
229
230### Composability
231
232Flakes can use other flakes as inputs:
233
234```nix
235{
236 inputs = {
237 grasp-audit.url = "path:./grasp-audit";
238 };
239}
240```
241
242---
243
244## Common Issues
245
246### Issue: "error: getting status of '/nix/store/...': No such file or directory"
247
248**Cause:** Flake inputs need to be updated or fetched
249
250**Solution:**
251```bash
252nix flake update
253nix develop
254```
255
256### Issue: "error: experimental feature 'nix-command' is not enabled"
257
258**Cause:** Nix flakes are experimental and need to be enabled
259
260**Solution:**
261Add to `~/.config/nix/nix.conf`:
262```
263experimental-features = nix-command flakes
264```
265
266### Issue: Changes to flake.nix not taking effect
267
268**Cause:** Flake evaluation is cached
269
270**Solution:**
271```bash
272# Clear evaluation cache
273nix flake update
274# Or force re-evaluation
275nix develop --refresh
276```
277
278### Issue: "error: cannot find flake 'flake:self' in the flake registries"
279
280**Cause:** Not in a git repository or flake.nix not committed
281
282**Solution:**
283```bash
284git add flake.nix flake.lock
285git commit -m "Add flake"
286```
287
288**Note:** Flakes require git. Uncommitted files are ignored by default.
289
290---
291
292## Best Practices
293
294### 1. Always Commit flake.lock
295
296```bash
297git add flake.lock
298git commit -m "Update flake inputs"
299```
300
301**Why:** Ensures reproducibility across machines and CI/CD
302
303### 2. Use Specific Rust Versions When Needed
304
305```nix
306# Latest stable (default)
307rust-bin.stable.latest.default
308
309# Specific version
310rust-bin.stable."1.75.0".default
311
312# Nightly
313rust-bin.nightly."2024-01-01".default
314```
315
316### 3. Include Helpful Shell Hooks
317
318```nix
319shellHook = ''
320 echo "🦀 GRASP Audit development environment"
321 echo ""
322 echo "Common commands:"
323 echo " cargo build - Build project"
324 echo " cargo test - Run tests"
325 echo " cargo run - Run binary"
326 echo ""
327 export RUST_SRC_PATH=${pkgs.rustPlatform.rustLibSrc}
328'';
329```
330
331### 4. Separate Build and Runtime Dependencies
332
333```nix
334# Build-time only
335nativeBuildInputs = [
336 pkg-config
337 rustc
338 cargo
339];
340
341# Runtime needed
342buildInputs = [
343 openssl
344];
345```
346
347### 5. Disable Tests in Package Build
348
349```nix
350packages.default = pkgs.rustPlatform.buildRustPackage {
351 # ...
352 doCheck = false; # Run tests separately with cargo test
353};
354```
355
356**Why:** Faster builds, tests run via `cargo test` in dev shell
357
358---
359
360## Workflow Examples
361
362### Daily Development
363
364```bash
365# Start work
366cd grasp-audit
367nix develop
368
369# Inside nix shell
370cargo build
371cargo test
372cargo run -- --help
373
374# Exit shell
375exit
376```
377
378### CI/CD
379
380```bash
381# One-off commands (no interactive shell)
382nix develop -c cargo build
383nix develop -c cargo test --lib
384nix develop -c cargo test -- --ignored
385```
386
387### Building Release
388
389```bash
390# Build package directly
391nix build
392
393# Result is in ./result/bin/
394./result/bin/grasp-audit --version
395```
396
397---
398
399## References
400
401- **Nix Flakes Manual**: https://nixos.org/manual/nix/stable/command-ref/new-cli/nix3-flake.html
402- **rust-overlay**: https://github.com/oxalica/rust-overlay
403- **flake-utils**: https://github.com/numtide/flake-utils
404- **Our Migration**: `docs/archive/2025-11-04-flake-migration.md`
405
406---
407
408## Quick Reference
409
410| Task | Command |
411|------|---------|
412| Enter dev shell | `nix develop` |
413| Run one command | `nix develop -c <command>` |
414| Show outputs | `nix flake show` |
415| Validate flake | `nix flake check` |
416| Update inputs | `nix flake update` |
417| Build package | `nix build` |
418| Run package | `nix run` |
419
420---
421
422*Last updated: November 4, 2025*
423*Status: Living document - update as we learn more*
diff --git a/docs/learnings/nostr-sdk.md b/docs/learnings/nostr-sdk.md
new file mode 100644
index 0000000..57f451a
--- /dev/null
+++ b/docs/learnings/nostr-sdk.md
@@ -0,0 +1,577 @@
1# nostr-sdk - Learnings and Patterns
2
3**Purpose:** Document nostr-sdk usage patterns, upgrade notes, and gotchas
4**Last Updated:** November 4, 2025
5
6---
7
8## Current Version
9
10**We use nostr-sdk 0.43.x (latest stable)**
11
12```toml
13[dependencies]
14nostr-sdk = "0.43"
15```
16
17**Upgraded from:** 0.35.0 on November 4, 2025
18
19---
20
21## Critical Breaking Changes (0.35 → 0.43)
22
23### 1. EventBuilder API Changed
24
25**Before (0.35):**
26```rust
27let event = EventBuilder::new(kind, content, tags)
28 .to_event(keys)?;
29```
30
31**After (0.43):**
32```rust
33let event = EventBuilder::new(kind, content)
34 .tags(tags)
35 .sign_with_keys(keys)?;
36```
37
38**Changes:**
39- ❌ Removed `tags` parameter from constructor
40- ✅ Use `.tags()` builder method instead
41- ❌ Removed `.to_event()` method
42- ✅ Use `.sign_with_keys()` instead (more descriptive)
43
44---
45
46### 2. Client Ownership of Keys
47
48**Before (0.35):**
49```rust
50let keys = Keys::generate();
51let client = Client::new(&keys); // Reference
52// keys still available
53```
54
55**After (0.43):**
56```rust
57let keys = Keys::generate();
58let client = Client::new(keys.clone()); // Ownership
59// Need to clone if we want to keep keys
60```
61
62**Why:** Allows Client to own the signer, enabling more flexible signer types.
63
64---
65
66### 3. Relay Status Check No Longer Async
67
68**Before (0.35):**
69```rust
70if relay.is_connected().await {
71 // ...
72}
73```
74
75**After (0.43):**
76```rust
77if relay.is_connected() { // No await!
78 // ...
79}
80```
81
82**Why:** Status check doesn't require async operation.
83
84---
85
86### 4. Query API Redesigned
87
88**Before (0.35):**
89```rust
90let events = client
91 .get_events_of(vec![filter], EventSource::relays(Some(timeout)))
92 .await?;
93// Returns Vec<Event>
94```
95
96**After (0.43):**
97```rust
98let events = client
99 .fetch_events(filter, timeout)
100 .await?;
101// Returns Events (iterable collection)
102
103// Convert to Vec if needed
104let vec: Vec<Event> = events.into_iter().collect();
105```
106
107**Changes:**
108- ❌ Removed `get_events_of()` method
109- ✅ Use `fetch_events()` instead
110- ❌ Removed `EventSource` parameter (confusing)
111- ✅ Direct timeout parameter
112- ❌ Single filter instead of `Vec<Filter>`
113- ✅ Returns `Events` type instead of `Vec<Event>`
114
115---
116
117### 5. Filter Custom Tags Simplified
118
119**Before (0.35):**
120```rust
121filter.custom_tag(tag, ["value"])
122filter.custom_tag(tag, [&string_ref])
123```
124
125**After (0.43):**
126```rust
127filter.custom_tag(tag, "value")
128filter.custom_tag(tag, &string_ref)
129```
130
131**Why:** Simplified API for the common case of single tag value.
132
133---
134
135### 6. Send Event Takes Reference
136
137**Before (0.35):**
138```rust
139let event_id = client.send_event(event).await?;
140```
141
142**After (0.43):**
143```rust
144let output = client.send_event(&event).await?;
145let event_id = *output.id();
146```
147
148**Changes:**
149- Takes `&Event` instead of `Event` (can reuse events)
150- Returns `SendEventOutput` instead of `EventId`
151- Need to call `.id()` to get the event ID
152
153---
154
155## Common Patterns
156
157### Creating and Signing Events
158
159```rust
160use nostr_sdk::prelude::*;
161
162// Generate keys
163let keys = Keys::generate();
164
165// Create event
166let event = EventBuilder::new(Kind::TextNote, "Hello Nostr!")
167 .tags(vec![
168 Tag::custom(TagKind::SingleLetter(SingleLetterTag::lowercase(Alphabet::T)),
169 vec!["nostr"]),
170 ])
171 .sign_with_keys(&keys)?;
172
173// Send event
174let output = client.send_event(&event).await?;
175println!("Event ID: {}", output.id());
176```
177
178---
179
180### Creating Custom Tags
181
182```rust
183use nostr_sdk::prelude::*;
184
185// Single letter tag (like "t" for topics)
186let t_tag = SingleLetterTag::lowercase(Alphabet::T);
187let tag = Tag::custom(
188 TagKind::SingleLetter(t_tag),
189 vec!["my-topic"]
190);
191
192// Custom multi-letter tag
193let tag = Tag::custom(
194 TagKind::Custom("custom-tag".to_string()),
195 vec!["value1", "value2"]
196);
197
198// Hashtag (convenience method)
199let tag = Tag::hashtag("nostr"); // Creates ["t", "nostr"]
200```
201
202---
203
204### Querying Events
205
206```rust
207use nostr_sdk::prelude::*;
208
209// Build filter
210let filter = Filter::new()
211 .kind(Kind::TextNote)
212 .custom_tag(
213 SingleLetterTag::lowercase(Alphabet::T),
214 "my-topic"
215 )
216 .since(Timestamp::now() - Duration::from_secs(3600)); // Last hour
217
218// Query events
219let timeout = Duration::from_secs(10);
220let events = client.fetch_events(filter, timeout).await?;
221
222// Process events
223for event in events.into_iter() {
224 println!("Event: {}", event.id());
225}
226```
227
228---
229
230### Multiple Filters
231
232Since `fetch_events()` takes a single filter, combine multiple queries:
233
234```rust
235// Option 1: Fetch separately and combine
236let mut all_events = Vec::new();
237for filter in filters {
238 let events = client.fetch_events(filter, timeout).await?;
239 all_events.extend(events.into_iter());
240}
241
242// Option 2: Use subscription (more efficient)
243let subscription_id = SubscriptionId::new("my-sub");
244client.subscribe(filters, None).await?;
245
246// Handle events via notification handler
247let mut notifications = client.notifications();
248while let Ok(notification) = notifications.recv().await {
249 if let RelayPoolNotification::Event { event, .. } = notification {
250 println!("Event: {}", event.id());
251 }
252}
253```
254
255---
256
257### Client Setup with Relay
258
259```rust
260use nostr_sdk::prelude::*;
261
262// Create keys
263let keys = Keys::generate();
264
265// Create client
266let client = Client::new(keys.clone());
267
268// Add relay
269client.add_relay("wss://relay.example.com").await?;
270
271// Connect
272client.connect().await;
273
274// Wait for connection
275tokio::time::sleep(Duration::from_secs(2)).await;
276
277// Check connection
278if client.relay("wss://relay.example.com")
279 .await?
280 .is_connected()
281{
282 println!("Connected!");
283}
284```
285
286---
287
288## Testing Patterns
289
290### Unit Tests (No Relay Required)
291
292```rust
293#[cfg(test)]
294mod tests {
295 use super::*;
296 use nostr_sdk::prelude::*;
297
298 #[test]
299 fn test_event_creation() {
300 let keys = Keys::generate();
301 let event = EventBuilder::new(Kind::TextNote, "test")
302 .sign_with_keys(&keys)
303 .unwrap();
304
305 assert_eq!(event.kind(), Kind::TextNote);
306 assert_eq!(event.content(), "test");
307 }
308
309 #[test]
310 fn test_tag_creation() {
311 let t_tag = SingleLetterTag::lowercase(Alphabet::T);
312 let tag = Tag::custom(
313 TagKind::SingleLetter(t_tag),
314 vec!["test-topic"]
315 );
316
317 // Verify tag structure
318 assert_eq!(tag.as_vec()[0], "t");
319 assert_eq!(tag.as_vec()[1], "test-topic");
320 }
321}
322```
323
324---
325
326### Integration Tests (Relay Required)
327
328```rust
329#[cfg(test)]
330mod tests {
331 use super::*;
332 use nostr_sdk::prelude::*;
333
334 #[tokio::test]
335 #[ignore] // Requires running relay
336 async fn test_send_and_receive() -> Result<()> {
337 // Setup
338 let keys = Keys::generate();
339 let client = Client::new(keys.clone());
340 client.add_relay("ws://localhost:7000").await?;
341 client.connect().await;
342 tokio::time::sleep(Duration::from_secs(2)).await;
343
344 // Send event
345 let event = EventBuilder::new(Kind::TextNote, "test")
346 .sign_with_keys(&keys)?;
347 let output = client.send_event(&event).await?;
348
349 // Query it back
350 let filter = Filter::new()
351 .id(*output.id());
352 let events = client.fetch_events(filter, Duration::from_secs(5)).await?;
353
354 assert_eq!(events.len(), 1);
355 Ok(())
356 }
357}
358```
359
360**Running integration tests:**
361```bash
362# Start relay first
363docker run --rm -p 7000:7000 scsibug/nostr-rs-relay
364
365# Run tests
366cargo test -- --ignored
367```
368
369---
370
371## Common Gotchas
372
373### 1. Event Validation Failures
374
375**Problem:** Events fail validation with cryptic errors
376
377**Common Causes:**
378- Invalid signature (wrong keys used)
379- Invalid event ID (content/tags changed after signing)
380- Invalid timestamp (too far in future/past)
381
382**Solution:**
383```rust
384// Always sign AFTER setting all fields
385let event = EventBuilder::new(kind, content)
386 .tags(tags) // Set tags first
387 .sign_with_keys(&keys)?; // Sign last
388
389// Don't modify event after signing!
390```
391
392---
393
394### 2. Filter Not Matching Events
395
396**Problem:** Query returns no events even though they exist
397
398**Common Causes:**
399- Tag kind mismatch (uppercase vs lowercase)
400- Wrong filter field (using `.author()` when you need `.authors()`)
401- Timeout too short
402
403**Solution:**
404```rust
405// Be explicit about tag kinds
406let t_tag = SingleLetterTag::lowercase(Alphabet::T); // Lowercase!
407
408// Use correct filter methods
409let filter = Filter::new()
410 .authors(vec![keys.public_key()]) // Note: plural
411 .kinds(vec![Kind::TextNote]); // Note: plural
412
413// Increase timeout for slow relays
414let timeout = Duration::from_secs(10);
415```
416
417---
418
419### 3. Connection Timing Issues
420
421**Problem:** Events fail to send or queries return empty
422
423**Cause:** Client not fully connected to relay
424
425**Solution:**
426```rust
427// Connect
428client.connect().await;
429
430// Wait for connection to establish
431tokio::time::sleep(Duration::from_secs(2)).await;
432
433// Verify connection
434let relay = client.relay("wss://relay.example.com").await?;
435if !relay.is_connected() {
436 return Err("Not connected".into());
437}
438
439// Now safe to send/query
440```
441
442---
443
444### 4. Clone Keys When Creating Client
445
446**Problem:** Can't use keys after creating client
447
448**Cause:** Client takes ownership in 0.43+
449
450**Solution:**
451```rust
452// Clone keys if you need them later
453let keys = Keys::generate();
454let client = Client::new(keys.clone()); // Clone!
455
456// Now can still use keys
457let pubkey = keys.public_key();
458```
459
460---
461
462## Performance Tips
463
464### 1. Reuse Clients
465
466```rust
467// ✅ Good - single client
468let client = Client::new(keys);
469client.add_relay("wss://relay1.com").await?;
470client.add_relay("wss://relay2.com").await?;
471client.connect().await;
472
473// ❌ Bad - multiple clients
474for relay in relays {
475 let client = Client::new(keys.clone()); // Wasteful!
476 client.add_relay(relay).await?;
477}
478```
479
480---
481
482### 2. Use Subscriptions for Live Updates
483
484```rust
485// ✅ Good for live updates - subscription
486let filters = vec![Filter::new().kind(Kind::TextNote)];
487client.subscribe(filters, None).await?;
488
489let mut notifications = client.notifications();
490while let Ok(notification) = notifications.recv().await {
491 // Handle events as they arrive
492}
493
494// ❌ Bad for live updates - polling
495loop {
496 let events = client.fetch_events(filter, timeout).await?;
497 tokio::time::sleep(Duration::from_secs(1)).await;
498}
499```
500
501---
502
503### 3. Batch Event Creation
504
505```rust
506// ✅ Good - reuse keys
507let keys = Keys::generate();
508let events: Vec<Event> = (0..100)
509 .map(|i| {
510 EventBuilder::new(Kind::TextNote, format!("Message {}", i))
511 .sign_with_keys(&keys)
512 .unwrap()
513 })
514 .collect();
515
516// ❌ Bad - regenerate keys
517let events: Vec<Event> = (0..100)
518 .map(|i| {
519 let keys = Keys::generate(); // Wasteful!
520 EventBuilder::new(Kind::TextNote, format!("Message {}", i))
521 .sign_with_keys(&keys)
522 .unwrap()
523 })
524 .collect();
525```
526
527---
528
529## Migration Checklist (0.35 → 0.43)
530
531When upgrading from 0.35 to 0.43:
532
533- [ ] Update `Cargo.toml`: `nostr-sdk = "0.43"`
534- [ ] Fix `EventBuilder::new()` - remove tags parameter
535- [ ] Fix `EventBuilder::to_event()` → `sign_with_keys()`
536- [ ] Fix `Client::new()` - clone keys instead of reference
537- [ ] Fix `Relay::is_connected()` - remove `.await`
538- [ ] Fix `Client::get_events_of()` → `fetch_events()`
539- [ ] Remove `EventSource::relays()` usage
540- [ ] Fix `Filter::custom_tag()` - single value instead of array
541- [ ] Fix `Client::send_event()` - pass reference, handle `SendEventOutput`
542- [ ] Update tests
543- [ ] Verify all builds pass
544- [ ] Run integration tests
545
546**Reference:** See `docs/archive/2025-11-04-nostr-sdk-upgrade.md`
547
548---
549
550## Useful Resources
551
552- **nostr-sdk docs**: https://docs.rs/nostr-sdk/0.43.0
553- **rust-nostr GitHub**: https://github.com/rust-nostr/nostr
554- **NIPs**: https://github.com/nostr-protocol/nips
555- **NIP-01 (Events)**: https://github.com/nostr-protocol/nips/blob/master/01.md
556- **NIP-34 (Git)**: https://github.com/nostr-protocol/nips/blob/master/34.md
557
558---
559
560## Quick Reference
561
562| Task | Code |
563|------|------|
564| Create event | `EventBuilder::new(kind, content).sign_with_keys(&keys)?` |
565| Add tags | `.tags(vec![tag1, tag2])` |
566| Custom tag | `Tag::custom(TagKind::SingleLetter(t), vec!["value"])` |
567| Create client | `Client::new(keys.clone())` |
568| Add relay | `client.add_relay("wss://...").await?` |
569| Connect | `client.connect().await` |
570| Send event | `client.send_event(&event).await?` |
571| Query events | `client.fetch_events(filter, timeout).await?` |
572| Subscribe | `client.subscribe(filters, None).await?` |
573
574---
575
576*Last updated: November 4, 2025*
577*Status: Living document - update as nostr-sdk evolves*