mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-05 15:08:24 +00:00
Migrate to standard NIP-01 't' tags for audit events
- Changed from custom single-letter tags (g, r, c) to standard 't' tags
- Tag values now use descriptive prefixes:
- 'grasp-audit-test-event' (marker tag)
- 'audit-{run-id}' (run identification)
- 'audit-cleanup-after-{timestamp}' (cleanup time)
- Updated audit_tags() in src/audit.rs
- Updated query filtering in src/client.rs
- Updated all tests to verify 't' tag usage
- All tests passing: 12/12 unit tests, 1/1 integration test
- CLI verified working with new tag scheme
This follows standard Nostr conventions and avoids potential
conflicts with other uses of single-letter tags. The 't' tag
is specifically designed for categorization/topics per NIP-01.
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
# ✅ Tag Migration Complete
|
||||
|
||||
**Date:** November 4, 2025
|
||||
**Task:** Migrate audit tags to standard NIP-01 "t" tags
|
||||
**Status:** ✅ **COMPLETE**
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Successfully migrated the audit system from custom single-letter tags (`g`, `r`, `c`) to standard NIP-01 "t" tags (hashtags) to avoid conflicts and follow Nostr conventions.
|
||||
|
||||
---
|
||||
|
||||
## What Changed
|
||||
|
||||
### Tag Structure
|
||||
|
||||
**Before (Custom Tags):**
|
||||
```rust
|
||||
// "g" tag for marker
|
||||
Tag::custom(TagKind::SingleLetter(g_tag), vec!["grasp-audit"])
|
||||
|
||||
// "r" tag for run ID
|
||||
Tag::custom(TagKind::SingleLetter(r_tag), vec![run_id])
|
||||
|
||||
// "c" tag for cleanup
|
||||
Tag::custom(TagKind::SingleLetter(c_tag), vec![timestamp])
|
||||
```
|
||||
|
||||
**After (Standard "t" Tags):**
|
||||
```rust
|
||||
// "t" tag with descriptive value
|
||||
Tag::custom(TagKind::SingleLetter(t_tag), vec!["grasp-audit-test-event"])
|
||||
|
||||
// "t" tag with prefixed run ID
|
||||
Tag::custom(TagKind::SingleLetter(t_tag), vec![format!("audit-{}", run_id)])
|
||||
|
||||
// "t" tag with prefixed cleanup time
|
||||
Tag::custom(TagKind::SingleLetter(t_tag), vec![format!("audit-cleanup-after-{}", timestamp)])
|
||||
```
|
||||
|
||||
### Tag Value Mapping
|
||||
|
||||
| Purpose | Old Tag | Old Value | New Tag | New Value |
|
||||
|---------|---------|-----------|---------|-----------|
|
||||
| Marker | `g` | `grasp-audit` | `t` | `grasp-audit-test-event` |
|
||||
| Run ID | `r` | `{run-id}` | `t` | `audit-{run-id}` |
|
||||
| Cleanup | `c` | `{timestamp}` | `t` | `audit-cleanup-after-{timestamp}` |
|
||||
|
||||
### Example Event
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": 1,
|
||||
"content": "test event",
|
||||
"tags": [
|
||||
["t", "grasp-audit-test-event"],
|
||||
["t", "audit-ci-a1b2c3d4-e5f6-7890-abcd-ef1234567890"],
|
||||
["t", "audit-cleanup-after-1730707200"]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Why This Change?
|
||||
|
||||
### 1. Standards Compliance
|
||||
- "t" tag is the standard NIP-01 mechanism for topics/categories
|
||||
- Follows established Nostr conventions
|
||||
- Better interoperability with other tools
|
||||
|
||||
### 2. Conflict Avoidance
|
||||
- Custom single-letter tags (`g`, `r`, `c`) could conflict with other uses
|
||||
- "t" tag is specifically designed for categorization
|
||||
- Multiple "t" tags are expected and supported
|
||||
|
||||
### 3. Self-Documenting
|
||||
- Tag values now clearly indicate their purpose
|
||||
- `grasp-audit-test-event` vs `grasp-audit`
|
||||
- `audit-ci-{uuid}` vs just `{uuid}`
|
||||
- `audit-cleanup-after-{timestamp}` vs just `{timestamp}`
|
||||
|
||||
### 4. Better Namespacing
|
||||
- All values prefixed with `audit-` or `grasp-audit-`
|
||||
- Reduces chance of collision with other systems
|
||||
- Makes it clear these are audit-related tags
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
### `grasp-audit/src/audit.rs`
|
||||
- ✅ Updated `audit_tags()` to use "t" tags
|
||||
- ✅ Updated tests to verify "t" tag kind
|
||||
- ✅ All tag values now have descriptive prefixes
|
||||
|
||||
### `grasp-audit/src/client.rs`
|
||||
- ✅ Updated `query()` to filter by "t" tags
|
||||
- ✅ Changed from multiple single-letter tags to "t" tag with multiple values
|
||||
|
||||
### `grasp-audit/TAG_MIGRATION.md`
|
||||
- ✅ Comprehensive documentation of the migration
|
||||
- ✅ Rationale, examples, and verification steps
|
||||
|
||||
---
|
||||
|
||||
## Testing Results
|
||||
|
||||
### Unit Tests: 12/12 ✅
|
||||
```
|
||||
✓ audit::tests::test_ci_config
|
||||
✓ audit::tests::test_production_config
|
||||
✓ audit::tests::test_audit_tags
|
||||
✓ audit::tests::test_audit_event_builder
|
||||
✓ client::tests::test_client_creation
|
||||
✓ client::tests::test_event_builder
|
||||
✓ isolation::tests::test_generate_ci_run_id
|
||||
✓ isolation::tests::test_generate_prod_run_id
|
||||
✓ isolation::tests::test_generate_test_id
|
||||
✓ result::tests::test_audit_result
|
||||
✓ result::tests::test_result_pass
|
||||
✓ result::tests::test_result_fail
|
||||
```
|
||||
|
||||
### Integration Tests: 1/1 ✅
|
||||
```
|
||||
✓ specs::nip01_smoke::tests::test_smoke_tests_against_relay
|
||||
```
|
||||
|
||||
### CLI Verification: ✅
|
||||
```bash
|
||||
$ nix develop -c cargo run -- audit \
|
||||
--relay ws://localhost:7000 \
|
||||
--mode ci \
|
||||
--spec nip01-smoke
|
||||
|
||||
Results: 6/6 passed (100.0%)
|
||||
✅ All tests passed!
|
||||
```
|
||||
|
||||
All smoke tests pass:
|
||||
- ✅ websocket_connection
|
||||
- ✅ send_receive_event
|
||||
- ✅ create_subscription
|
||||
- ✅ close_subscription
|
||||
- ✅ reject_invalid_signature
|
||||
- ✅ reject_invalid_event_id
|
||||
|
||||
---
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
⚠️ **Note:** This is a breaking change for event queries.
|
||||
|
||||
Events created with the old tag scheme will not be found by new queries. This is acceptable because:
|
||||
|
||||
1. **Alpha Status**: System is in development
|
||||
2. **Test Data Only**: Old events are just test data
|
||||
3. **Auto Cleanup**: Events expire via cleanup timestamps
|
||||
4. **No Production Use**: No production deployments exist
|
||||
|
||||
---
|
||||
|
||||
## Benefits Achieved
|
||||
|
||||
✅ **Standards Compliance**: Uses NIP-01 standard hashtag mechanism
|
||||
✅ **No Conflicts**: "t" tag is designed for categorization
|
||||
✅ **Better Namespacing**: Values prefixed to avoid collisions
|
||||
✅ **Queryable**: Standard filtering works as expected
|
||||
✅ **Self-Documenting**: Tag values clearly indicate purpose
|
||||
✅ **Maintainable**: Follows established patterns
|
||||
|
||||
---
|
||||
|
||||
## Commit
|
||||
|
||||
```
|
||||
commit 820fa67
|
||||
Author: [automated]
|
||||
Date: November 4, 2025
|
||||
|
||||
Migrate to standard NIP-01 't' tags for audit events
|
||||
|
||||
- Changed from custom single-letter tags (g, r, c) to standard 't' tags
|
||||
- Tag values now use descriptive prefixes
|
||||
- Updated audit_tags() in src/audit.rs
|
||||
- Updated query filtering in src/client.rs
|
||||
- Updated all tests to verify 't' tag usage
|
||||
- All tests passing: 12/12 unit tests, 1/1 integration test
|
||||
- CLI verified working with new tag scheme
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verification Commands
|
||||
|
||||
```bash
|
||||
# Build
|
||||
cd grasp-audit
|
||||
nix develop -c cargo build
|
||||
|
||||
# Unit tests
|
||||
nix develop -c cargo test --lib
|
||||
|
||||
# Integration tests (requires relay)
|
||||
docker run --rm -p 7000:7000 scsibug/nostr-rs-relay
|
||||
nix develop -c cargo test -- --ignored
|
||||
|
||||
# CLI test
|
||||
nix develop -c cargo run -- audit \
|
||||
--relay ws://localhost:7000 \
|
||||
--mode ci \
|
||||
--spec nip01-smoke
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
The audit system is now ready for:
|
||||
|
||||
### Path 2: GRASP-01 Test Suite
|
||||
- [ ] Create `src/specs/grasp_01_relay.rs`
|
||||
- [ ] Implement repository announcement tests
|
||||
- [ ] Implement state event tests
|
||||
- [ ] Implement maintainer validation tests
|
||||
- [ ] Test against mock relay
|
||||
|
||||
### Future Enhancements
|
||||
- [ ] Add tag validation helpers
|
||||
- [ ] Document tag format in API docs
|
||||
- [ ] Add examples showing tag usage
|
||||
- [ ] Consider tag versioning for future changes
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- **NIP-01**: https://github.com/nostr-protocol/nips/blob/master/01.md
|
||||
- **SESSION_CONTINUATION_COMPLETE.md**: Previous session work
|
||||
- **TAG_MIGRATION.md**: Detailed migration documentation
|
||||
- **Commit 8190a3a**: Previous tag implementation (g/r/c tags)
|
||||
- **Commit 820fa67**: Current implementation (t tags)
|
||||
|
||||
---
|
||||
|
||||
**Status:** ✅ **COMPLETE**
|
||||
**All Tests:** 🟢 **PASSING** (13/13)
|
||||
**CLI:** 🟢 **WORKING**
|
||||
**Ready for:** Path 2 (GRASP-01 Test Suite)
|
||||
|
||||
---
|
||||
|
||||
*Migration completed: November 4, 2025*
|
||||
@@ -0,0 +1,54 @@
|
||||
# 🏷️ Tag Migration Summary
|
||||
|
||||
## Before → After
|
||||
|
||||
```diff
|
||||
- ["g", "grasp-audit"]
|
||||
- ["r", "ci-a1b2c3d4-..."]
|
||||
- ["c", "1730707200"]
|
||||
|
||||
+ ["t", "grasp-audit-test-event"]
|
||||
+ ["t", "audit-ci-a1b2c3d4-..."]
|
||||
+ ["t", "audit-cleanup-after-1730707200"]
|
||||
```
|
||||
|
||||
## Why?
|
||||
|
||||
✅ Standard NIP-01 hashtag mechanism
|
||||
✅ Avoids conflicts with other single-letter tags
|
||||
✅ Self-documenting tag values
|
||||
✅ Better namespacing with prefixes
|
||||
|
||||
## Status
|
||||
|
||||
| Component | Status | Tests |
|
||||
|-----------|--------|-------|
|
||||
| Tag Generation | ✅ Working | 12/12 pass |
|
||||
| Tag Filtering | ✅ Working | 1/1 pass |
|
||||
| CLI | ✅ Working | 6/6 smoke tests |
|
||||
| Documentation | ✅ Complete | TAG_MIGRATION.md |
|
||||
|
||||
## Test Results
|
||||
|
||||
```
|
||||
Unit Tests: 12/12 ✅
|
||||
Integration: 1/1 ✅
|
||||
CLI Smoke: 6/6 ✅
|
||||
Total: 19/19 ✅
|
||||
```
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `src/audit.rs` - Tag generation
|
||||
- `src/client.rs` - Query filtering
|
||||
- `TAG_MIGRATION.md` - Documentation
|
||||
|
||||
## Commit
|
||||
|
||||
```
|
||||
820fa67 - Migrate to standard NIP-01 't' tags for audit events
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Ready for:** GRASP-01 Test Suite Development
|
||||
@@ -0,0 +1,151 @@
|
||||
# Tag Migration to Standard NIP-01 "t" Tags
|
||||
|
||||
**Date:** November 4, 2025
|
||||
**Status:** ✅ Complete
|
||||
|
||||
## Overview
|
||||
|
||||
Migrated audit system tags from custom single-letter tags (`g`, `r`, `c`) to standard NIP-01 "t" tags (hashtags) to avoid conflicts and follow Nostr conventions.
|
||||
|
||||
## Motivation
|
||||
|
||||
The previous tag scheme used:
|
||||
- `g` tag for `grasp-audit` marker
|
||||
- `r` tag for `audit-run-id`
|
||||
- `c` tag for `audit-cleanup` timestamp
|
||||
|
||||
However, this could conflict with other uses of these single-letter tags. The "t" tag is the standard NIP-01 tag type for categorization/topics, making it the appropriate choice for audit event tagging.
|
||||
|
||||
## Changes Made
|
||||
|
||||
### Tag Structure
|
||||
|
||||
**Before:**
|
||||
```rust
|
||||
vec![
|
||||
Tag::custom(TagKind::SingleLetter(g_tag), vec!["grasp-audit"]),
|
||||
Tag::custom(TagKind::SingleLetter(r_tag), vec![run_id]),
|
||||
Tag::custom(TagKind::SingleLetter(c_tag), vec![cleanup_timestamp]),
|
||||
]
|
||||
```
|
||||
|
||||
**After:**
|
||||
```rust
|
||||
vec![
|
||||
Tag::custom(TagKind::SingleLetter(t_tag), vec!["grasp-audit-test-event"]),
|
||||
Tag::custom(TagKind::SingleLetter(t_tag), vec![format!("audit-{}", run_id)]),
|
||||
Tag::custom(TagKind::SingleLetter(t_tag), vec![format!("audit-cleanup-after-{}", timestamp)]),
|
||||
]
|
||||
```
|
||||
|
||||
### Tag Values
|
||||
|
||||
| Purpose | Old Tag | Old Value | New Tag | New Value |
|
||||
|---------|---------|-----------|---------|-----------|
|
||||
| Marker | `g` | `grasp-audit` | `t` | `grasp-audit-test-event` |
|
||||
| Run ID | `r` | `ci-{uuid}` | `t` | `audit-ci-{uuid}` |
|
||||
| Cleanup | `c` | `{timestamp}` | `t` | `audit-cleanup-after-{timestamp}` |
|
||||
|
||||
### Example Event Tags
|
||||
|
||||
```json
|
||||
[
|
||||
["t", "grasp-audit-test-event"],
|
||||
["t", "audit-ci-a1b2c3d4-e5f6-7890-abcd-ef1234567890"],
|
||||
["t", "audit-cleanup-after-1730707200"]
|
||||
]
|
||||
```
|
||||
|
||||
## Files Modified
|
||||
|
||||
### `src/audit.rs`
|
||||
- Updated `audit_tags()` to use "t" tags
|
||||
- Updated tests to check for "t" tag kind
|
||||
- All values now prefixed for clarity
|
||||
|
||||
### `src/client.rs`
|
||||
- Updated `query()` to filter by "t" tags
|
||||
- Changed from `.custom_tag(g_tag, ...)` to `.custom_tag(t_tag, ...)`
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Standards Compliance**: Uses standard NIP-01 hashtag mechanism
|
||||
2. **No Conflicts**: "t" tag is designed for categorization
|
||||
3. **Better Namespacing**: Values prefixed with `audit-` to avoid collisions
|
||||
4. **Queryable**: Standard tag filtering works as expected
|
||||
5. **Self-Documenting**: Tag values clearly indicate their purpose
|
||||
|
||||
## Testing
|
||||
|
||||
All tests pass with the new tag scheme:
|
||||
|
||||
```bash
|
||||
# Unit tests
|
||||
✓ 12/12 tests passing
|
||||
|
||||
# Integration tests
|
||||
✓ 1/1 test passing (NIP-01 smoke tests)
|
||||
|
||||
# CLI verification
|
||||
✓ All 6 smoke tests pass
|
||||
```
|
||||
|
||||
## Backwards Compatibility
|
||||
|
||||
⚠️ **Breaking Change**: Events created with old tags will not be found by new queries.
|
||||
|
||||
This is acceptable because:
|
||||
- System is in alpha/development
|
||||
- Old events are test data only
|
||||
- Cleanup happens automatically via timestamps
|
||||
- No production deployments exist yet
|
||||
|
||||
## Migration Path
|
||||
|
||||
For future tag changes:
|
||||
1. Consider versioning in tag values (e.g., `grasp-audit-v2-test-event`)
|
||||
2. Support querying both old and new tags during transition
|
||||
3. Document breaking changes clearly
|
||||
4. Provide migration tools if needed
|
||||
|
||||
## References
|
||||
|
||||
- **NIP-01**: https://github.com/nostr-protocol/nips/blob/master/01.md
|
||||
- **Tag Standardization**: "t" tags for topics/categories
|
||||
- **Previous Implementation**: Commit `8190a3a` (custom g/r/c tags)
|
||||
- **Current Implementation**: Uses standard "t" tags
|
||||
|
||||
## Verification
|
||||
|
||||
To verify the new tag structure:
|
||||
|
||||
```bash
|
||||
# Run tests
|
||||
nix develop -c cargo test --lib
|
||||
nix develop -c cargo test -- --ignored
|
||||
|
||||
# Run CLI
|
||||
nix develop -c cargo run -- audit \
|
||||
--relay ws://localhost:7000 \
|
||||
--mode ci \
|
||||
--spec nip01-smoke
|
||||
|
||||
# Check event structure (example)
|
||||
# Events will have tags like:
|
||||
# ["t", "grasp-audit-test-event"]
|
||||
# ["t", "audit-ci-{uuid}"]
|
||||
# ["t", "audit-cleanup-after-{timestamp}"]
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [ ] Update documentation to reflect new tag scheme
|
||||
- [ ] Consider adding tag validation helpers
|
||||
- [ ] Document tag format in API/spec documentation
|
||||
- [ ] Add examples showing tag usage
|
||||
|
||||
---
|
||||
|
||||
**Status:** ✅ Migration complete and verified
|
||||
**All tests passing:** 13/13 (12 unit + 1 integration)
|
||||
**CLI verified:** ✅ Working correctly
|
||||
+24
-30
@@ -65,22 +65,21 @@ impl AuditConfig {
|
||||
pub fn audit_tags(&self) -> Vec<Tag> {
|
||||
use nostr_sdk::prelude::{Alphabet, SingleLetterTag};
|
||||
|
||||
// Use "t" tags for categorization (standard NIP-01 hashtag type)
|
||||
let t_tag = SingleLetterTag::lowercase(Alphabet::T);
|
||||
|
||||
vec![
|
||||
// Use single-letter tags for filtering support
|
||||
// "g" = grasp-audit marker
|
||||
Tag::custom(
|
||||
TagKind::SingleLetter(SingleLetterTag::lowercase(Alphabet::G)),
|
||||
vec!["grasp-audit"]
|
||||
TagKind::SingleLetter(t_tag),
|
||||
vec!["grasp-audit-test-event"]
|
||||
),
|
||||
// "r" = audit run ID
|
||||
Tag::custom(
|
||||
TagKind::SingleLetter(SingleLetterTag::lowercase(Alphabet::R)),
|
||||
vec![self.run_id.clone()]
|
||||
TagKind::SingleLetter(t_tag),
|
||||
vec![format!("audit-{}", self.run_id)]
|
||||
),
|
||||
// "c" = cleanup timestamp
|
||||
Tag::custom(
|
||||
TagKind::SingleLetter(SingleLetterTag::lowercase(Alphabet::C)),
|
||||
vec![self.cleanup_after.to_string()]
|
||||
TagKind::SingleLetter(t_tag),
|
||||
vec![format!("audit-cleanup-after-{}", self.cleanup_after.as_u64())]
|
||||
),
|
||||
]
|
||||
}
|
||||
@@ -159,35 +158,30 @@ mod tests {
|
||||
|
||||
assert_eq!(tags.len(), 3);
|
||||
|
||||
let g_tag = SingleLetterTag::lowercase(Alphabet::G);
|
||||
let r_tag = SingleLetterTag::lowercase(Alphabet::R);
|
||||
let c_tag = SingleLetterTag::lowercase(Alphabet::C);
|
||||
let t_tag = SingleLetterTag::lowercase(Alphabet::T);
|
||||
|
||||
// Check "g" tag (grasp-audit marker)
|
||||
assert!(tags.iter().any(|t| {
|
||||
if let TagKind::SingleLetter(letter) = t.kind() {
|
||||
letter == g_tag
|
||||
// All tags should be "t" tags (hashtags)
|
||||
for tag in &tags {
|
||||
if let TagKind::SingleLetter(letter) = tag.kind() {
|
||||
assert_eq!(letter, t_tag);
|
||||
} else {
|
||||
false
|
||||
panic!("Expected SingleLetter tag");
|
||||
}
|
||||
}
|
||||
|
||||
// Check for "t" tag with "grasp-audit-test-event"
|
||||
assert!(tags.iter().any(|t| {
|
||||
t.content() == Some("grasp-audit-test-event")
|
||||
}));
|
||||
|
||||
// Check "r" tag (audit run ID)
|
||||
// Check for "t" tag with "audit-{run_id}"
|
||||
assert!(tags.iter().any(|t| {
|
||||
if let TagKind::SingleLetter(letter) = t.kind() {
|
||||
letter == r_tag
|
||||
} else {
|
||||
false
|
||||
}
|
||||
t.content().map(|c| c.starts_with("audit-ci-")).unwrap_or(false)
|
||||
}));
|
||||
|
||||
// Check "c" tag (cleanup timestamp)
|
||||
// Check for "t" tag with "audit-cleanup-after-{timestamp}"
|
||||
assert!(tags.iter().any(|t| {
|
||||
if let TagKind::SingleLetter(letter) = t.kind() {
|
||||
letter == c_tag
|
||||
} else {
|
||||
false
|
||||
}
|
||||
t.content().map(|c| c.starts_with("audit-cleanup-after-")).unwrap_or(false)
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -95,16 +95,11 @@ impl AuditClient {
|
||||
|
||||
if self.config.mode == AuditMode::CI {
|
||||
// In CI mode, only see our own audit events
|
||||
// Filter by "g" tag (grasp-audit marker) and "r" tag (run ID)
|
||||
// Filter by "t" tags (hashtags)
|
||||
let t_tag = SingleLetterTag::lowercase(Alphabet::T);
|
||||
filter = filter
|
||||
.custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::G),
|
||||
"grasp-audit"
|
||||
)
|
||||
.custom_tag(
|
||||
SingleLetterTag::lowercase(Alphabet::R),
|
||||
&self.config.run_id
|
||||
);
|
||||
.custom_tag(t_tag, "grasp-audit-test-event")
|
||||
.custom_tag(t_tag, format!("audit-{}", self.config.run_id));
|
||||
}
|
||||
// In Production mode, see all events (no filter modification)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user