{"id":"b636c1ac1968f717b4fb03b59fe511a7d344b9a8a387c9e32979801a3deed31b","pubkey":"a8d1560d6a647d501699167246f237b36fb123f89168fda11dc743533fec7a08","created_at":1766288087,"kind":30817,"tags":[["d","collaborative-documentation-extension"],["title","Collaborative Documentation Extension"],["k","39562"],["k","39563"],["client","nostrhub.io"]],"content":"# NIP-XX: Collaborative Documentation Spaces\n\n`draft` `optional`\n\nThis NIP extends the Documentation Spaces specification to support multi-author collaboration, allowing anyone to contribute to documentation while maintaining quality control through various permission models.\n\n## Overview\n\nThis extension adds collaboration features to Documentation Spaces by introducing:\n- **Contributor Lists** for managing who can edit documentation\n- **Edit Proposals** for suggesting changes without direct write access\n- **Merge Events** for accepting proposed changes\n- **Permission Models** (open, moderated, restricted) for different collaboration styles\n- **Full backwards compatibility** with non-collaborative documentation spaces\n\n## New Event Kinds\n\n### Edit Proposal (`kind:39562`)\n\nProposes changes to an existing documentation page without directly modifying it.\n\n```json\n{\n  \"kind\": 39562,\n  \"content\": \"# Welcome\\n\\nThis is the UPDATED introduction page with improvements.\",\n  \"tags\": [\n    [\"d\", \"proposal-uuid-12345\"],\n    [\"a\", \"39561:<author-pubkey>:introduction\", \"<relay>\"],\n    [\"space\", \"my-project-docs\"],\n    [\"page\", \"introduction\"],\n    [\"title\", \"Introduction\"],\n    [\"format\", \"markdown\"],\n    [\"summary\", \"Fixed typos and added more details\"],\n    [\"parent\", \"getting-started\"]\n  ]\n}\n```\n\n**Required tags:**\n- `d`: Unique identifier for this proposal\n- `a`: Address tag pointing to the target page being modified (`39561:<pubkey>:<page-d-tag>`)\n- `space`: The space identifier where the target page exists\n- `page`: The `d` tag of the target page\n- `title`: Proposed title for the page\n- `format`: Markup format of the proposed content\n\n**Optional tags:**\n- `summary`: Description of changes being proposed\n- `parent`: Proposed parent page (if changing hierarchy)\n- `order`: Proposed order value\n- `t`: Proposed category tags\n- All other tags from the original page specification\n\n**Content field:**\nThe complete proposed content for the page (not a diff/patch).\n\n### Merge Event (`kind:39563`)\n\nAccepts an edit proposal and signals that changes should be incorporated.\n\n```json\n{\n  \"kind\": 39563,\n  \"content\": \"Looks good, merging this proposal.\",\n  \"tags\": [\n    [\"d\", \"merge-uuid-67890\"],\n    [\"e\", \"<proposal-event-id>\", \"<relay>\", \"proposal\"],\n    [\"a\", \"39562:<proposer-pubkey>:proposal-uuid-12345\", \"<relay>\"],\n    [\"p\", \"<proposer-pubkey>\"],\n    [\"merged_at\", \"1234567890\"]\n  ]\n}\n```\n\n**Required tags:**\n- `d`: Unique identifier for this merge event\n- `e`: Event ID of the accepted proposal\n- `a`: Address of the accepted proposal\n- `p`: Pubkey of the proposal author\n\n**Optional tags:**\n- `merged_at`: Unix timestamp when merge was accepted\n- `review_comment`: Additional notes about the merge\n\n**Content field:**\nOptional message about the merge decision.\n\nAfter publishing a merge event, the page owner should publish an updated `kind:39561` event incorporating the proposed changes.\n\n## Extended Space Permissions\n\nDocumentation Spaces (`kind:33527`) gain new optional tags for collaboration:\n\n```json\n{\n  \"kind\": 33527,\n  \"content\": \"# Welcome to Our Wiki\",\n  \"tags\": [\n    [\"d\", \"community-wiki\"],\n    [\"title\", \"Community Wiki\"],\n    [\"permission_model\", \"open\"],\n    [\"p\", \"<contributor1-pubkey>\", \"\", \"editor\"],\n    [\"p\", \"<contributor2-pubkey>\", \"\", \"editor\"],\n    [\"p\", \"<moderator-pubkey>\", \"\", \"moderator\"]\n  ]\n}\n```\n\n**New optional tags:**\n- `permission_model`: Collaboration mode (`open`, `moderated`, `restricted`, or omitted for single-author)\n  - `open`: Anyone can directly publish pages in this space\n  - `moderated`: Anyone can propose edits, but only editors can merge them\n  - `restricted`: Only listed contributors can propose or publish\n- `p`: Contributor/role assignments with role marker in the 3rd position\n  - `editor`: Can publish pages and merge proposals\n  - `moderator`: Can merge proposals but not directly publish\n  - `contributor`: Can propose edits (explicit listing for restricted spaces)\n\n**Backwards Compatibility:**\n- Spaces without `permission_model` tag default to single-author (only space creator can edit)\n- Spaces without any `p` tags with roles function as before\n- Existing clients ignore unknown tags\n\n## Permission Models\n\n### Single-Author (Default - Backwards Compatible)\n```json\n{\n  \"kind\": 33527,\n  \"tags\": [\n    [\"d\", \"my-docs\"],\n    [\"title\", \"My Documentation\"]\n  ]\n}\n```\n- No `permission_model` tag\n- Only the space creator (event author) can create/edit pages\n- Fully backwards compatible with existing implementation\n\n### Open Collaboration\n```json\n{\n  \"kind\": 33527,\n  \"tags\": [\n    [\"d\", \"open-wiki\"],\n    [\"title\", \"Open Wiki\"],\n    [\"permission_model\", \"open\"]\n  ]\n}\n```\n- Anyone can publish pages directly\n- Anyone can edit any page by publishing newer versions\n- Like Wikipedia's model: assume good faith, rollback vandalism\n- Best for: Community knowledge bases, public documentation\n\n### Moderated Collaboration\n```json\n{\n  \"kind\": 33527,\n  \"tags\": [\n    [\"d\", \"moderated-docs\"],\n    [\"title\", \"Moderated Documentation\"],\n    [\"permission_model\", \"moderated\"],\n    [\"p\", \"<editor1-pubkey>\", \"\", \"editor\"],\n    [\"p\", \"<editor2-pubkey>\", \"\", \"editor\"]\n  ]\n}\n```\n- Anyone can submit edit proposals (`kind:39562`)\n- Only listed editors can publish pages and merge proposals\n- Best for: Official documentation, curated wikis\n\n### Restricted Collaboration\n```json\n{\n  \"kind\": 33527,\n  \"tags\": [\n    [\"d\", \"private-wiki\"],\n    [\"title\", \"Team Wiki\"],\n    [\"permission_model\", \"restricted\"],\n    [\"p\", \"<member1-pubkey>\", \"\", \"contributor\"],\n    [\"p\", \"<member2-pubkey>\", \"\", \"editor\"]\n  ]\n}\n```\n- Only listed contributors can submit proposals\n- Only listed editors can publish pages and merge proposals\n- Best for: Private team documentation, sensitive content\n\n## Page Collaboration\n\n### Direct Editing (Open Spaces)\nIn open spaces, anyone can publish an updated version of a page:\n\n```json\n{\n  \"kind\": 39561,\n  \"content\": \"# Updated Content\",\n  \"tags\": [\n    [\"d\", \"introduction\"],\n    [\"space\", \"open-wiki\"],\n    [\"title\", \"Introduction (Updated)\"],\n    [\"format\", \"markdown\"],\n    [\"e\", \"<previous-version-event-id>\", \"\", \"previous\"]\n  ]\n}\n```\n\nThe `e` tag with marker \"previous\" creates a version chain.\n\n### Edit Proposals (Moderated/Restricted Spaces)\nIn moderated or restricted spaces, non-editors submit proposals:\n\n```json\n{\n  \"kind\": 39562,\n  \"content\": \"# Improved Introduction\\n\\nI fixed the grammar and added examples.\",\n  \"tags\": [\n    [\"d\", \"proposal-intro-fix\"],\n    [\"a\", \"39561:<original-author>:introduction\"],\n    [\"space\", \"moderated-docs\"],\n    [\"page\", \"introduction\"],\n    [\"title\", \"Introduction\"],\n    [\"format\", \"markdown\"],\n    [\"summary\", \"Grammar fixes and added examples\"]\n  ]\n}\n```\n\nEditors review and can merge:\n\n```json\n{\n  \"kind\": 39563,\n  \"content\": \"Great improvements, thanks!\",\n  \"tags\": [\n    [\"d\", \"merge-intro-fix\"],\n    [\"e\", \"<proposal-event-id>\", \"\", \"proposal\"],\n    [\"a\", \"39562:<proposer-pubkey>:proposal-intro-fix\"],\n    [\"p\", \"<proposer-pubkey>\"]\n  ]\n}\n```\n\nThen publish the updated page:\n\n```json\n{\n  \"kind\": 39561,\n  \"content\": \"# Improved Introduction\\n\\nI fixed the grammar and added examples.\",\n  \"tags\": [\n    [\"d\", \"introduction\"],\n    [\"space\", \"moderated-docs\"],\n    [\"title\", \"Introduction\"],\n    [\"format\", \"markdown\"],\n    [\"e\", \"<previous-version-event-id>\", \"\", \"previous\"],\n    [\"e\", \"<proposal-event-id>\", \"\", \"merged\"],\n    [\"p\", \"<proposer-pubkey>\", \"\", \"contributor\"]\n  ]\n}\n```\n\nThe `p` tag with \"contributor\" marker gives credit to the proposal author.\n\n## Querying Collaborative Content\n\n### Find Edit Proposals for a Page\n```json\n{\n  \"kinds\": [39562],\n  \"#space\": [\"my-docs\"],\n  \"#page\": [\"introduction\"]\n}\n```\n\n### Find Pending Proposals (Unmerged)\n```json\n{\n  \"kinds\": [39562],\n  \"#space\": [\"my-docs\"],\n  \"since\": <timestamp>\n}\n```\n\nThen filter out proposals that have corresponding merge events.\n\n### Find Merge History\n```json\n{\n  \"kinds\": [39563],\n  \"#a\": [\"39561:<author>:introduction\"]\n}\n```\n\n### Find Contributors to a Space\nQuery all pages in a space and collect unique `p` tags with \"contributor\" marker.\n\n## Version History and Attribution\n\n### Version Chain\nPages should maintain version history through `e` tags:\n\n```json\n{\n  \"kind\": 39561,\n  \"tags\": [\n    [\"e\", \"<version1-event-id>\", \"\", \"previous\"],\n    [\"e\", \"<version2-event-id>\", \"\", \"previous\"],\n    [\"e\", \"<proposal-event-id>\", \"\", \"merged\"]\n  ]\n}\n```\n\n### Attribution\nPages should credit all contributors:\n\n```json\n{\n  \"kind\": 39561,\n  \"tags\": [\n    [\"p\", \"<author1>\", \"\", \"author\"],\n    [\"p\", \"<contributor1>\", \"\", \"contributor\"],\n    [\"p\", \"<contributor2>\", \"\", \"contributor\"]\n  ]\n}\n```\n\n## Conflict Resolution\n\n### Concurrent Edits\nWhen multiple versions of the same page exist with the same `created_at`:\n1. Clients should show both versions and let editors merge manually\n2. The version from the space owner takes precedence (for moderated/restricted)\n3. The newest version takes precedence (for open)\n\n### Edit Conflicts\nWhen a proposal becomes stale (target page has been updated):\n1. Proposer should submit a new proposal based on current version\n2. Clients should show diff between proposal base and current version\n3. Editors can choose to merge anyway or request rebase\n\n## Client Implementation\n\n### Displaying Collaborative Spaces\nClients should:\n- Show permission model prominently\n- Display contributor lists\n- Indicate when pages have pending proposals\n- Show edit history and attribution\n\n### Proposing Edits\nFor non-editors in moderated/restricted spaces:\n1. Fetch current page version\n2. Present editor interface with current content\n3. On save, publish `kind:39562` proposal\n4. Notify editors (through notifications or UI)\n\n### Reviewing Proposals\nFor editors:\n1. Show pending proposals with diffs\n2. Provide approve/reject interface\n3. On approve, publish merge event (`kind:39563`)\n4. Publish updated page with attribution\n\n### Version History\nClients should:\n- Track version chains through `e` tags\n- Show who contributed what (from `p` tags)\n- Provide rollback capabilities\n- Display merge history\n\n## Security Considerations\n\n### Permission Validation\nClients must validate:\n- User has appropriate role for action\n- Pubkey is listed in space's `p` tags (for restricted/moderated)\n- Merge events come from authorized editors\n\n### Spam Prevention\nFor open wikis:\n- Implement rate limiting\n- Track reputation/trust scores\n- Provide easy rollback mechanisms\n- Consider WoT (Web of Trust) filters\n\n### Vandalism Protection\n- Maintain complete version history\n- Make rollbacks easy\n- Ban malicious contributors (client-side filtering)\n- Consider requiring proof-of-work for edits\n\n## Migration from Single-Author\n\nExisting single-author spaces can become collaborative by publishing an updated space event:\n\n**Before:**\n```json\n{\n  \"kind\": 33527,\n  \"tags\": [\n    [\"d\", \"my-docs\"],\n    [\"title\", \"My Documentation\"]\n  ]\n}\n```\n\n**After:**\n```json\n{\n  \"kind\": 33527,\n  \"tags\": [\n    [\"d\", \"my-docs\"],\n    [\"title\", \"My Documentation\"],\n    [\"permission_model\", \"moderated\"],\n    [\"p\", \"<trusted-editor>\", \"\", \"editor\"]\n  ]\n}\n```\n\nAll existing pages remain valid. The space owner maintains full control.\n\n## Examples\n\n### Community Wiki (Open)\n\n**Space:**\n```json\n{\n  \"kind\": 33527,\n  \"content\": \"# Nostr Community Wiki\\n\\nEveryone can contribute!\",\n  \"tags\": [\n    [\"d\", \"nostr-wiki\"],\n    [\"title\", \"Nostr Community Wiki\"],\n    [\"permission_model\", \"open\"],\n    [\"default_format\", \"markdown\"],\n    [\"visibility\", \"public\"]\n  ]\n}\n```\n\n**Anyone can publish/edit pages directly:**\n```json\n{\n  \"kind\": 39561,\n  \"content\": \"# What is Nostr?\\n\\nNostr is a protocol...\",\n  \"tags\": [\n    [\"d\", \"what-is-nostr\"],\n    [\"space\", \"nostr-wiki\"],\n    [\"title\", \"What is Nostr?\"],\n    [\"format\", \"markdown\"]\n  ]\n}\n```\n\n### Official Documentation (Moderated)\n\n**Space:**\n```json\n{\n  \"kind\": 33527,\n  \"tags\": [\n    [\"d\", \"bitcoin-docs\"],\n    [\"title\", \"Bitcoin Protocol Documentation\"],\n    [\"permission_model\", \"moderated\"],\n    [\"p\", \"npub1maintainer...\", \"\", \"editor\"],\n    [\"p\", \"npub2reviewer...\", \"\", \"editor\"]\n  ]\n}\n```\n\n**User submits proposal:**\n```json\n{\n  \"kind\": 39562,\n  \"content\": \"# Lightning Network\\n\\nImproved explanation with examples...\",\n  \"tags\": [\n    [\"d\", \"lightning-improvement\"],\n    [\"a\", \"39561:npub1maintainer...:lightning-network\"],\n    [\"space\", \"bitcoin-docs\"],\n    [\"page\", \"lightning-network\"],\n    [\"title\", \"Lightning Network\"],\n    [\"format\", \"markdown\"],\n    [\"summary\", \"Added examples and improved clarity\"]\n  ]\n}\n```\n\n**Editor merges:**\n```json\n{\n  \"kind\": 39563,\n  \"content\": \"Excellent contribution!\",\n  \"tags\": [\n    [\"d\", \"merge-lightning\"],\n    [\"e\", \"<proposal-id>\", \"\", \"proposal\"],\n    [\"p\", \"<contributor-pubkey>\"]\n  ]\n}\n```\n\n**Editor publishes updated page:**\n```json\n{\n  \"kind\": 39561,\n  \"content\": \"# Lightning Network\\n\\nImproved explanation with examples...\",\n  \"tags\": [\n    [\"d\", \"lightning-network\"],\n    [\"space\", \"bitcoin-docs\"],\n    [\"title\", \"Lightning Network\"],\n    [\"format\", \"markdown\"],\n    [\"e\", \"<previous-version-id>\", \"\", \"previous\"],\n    [\"e\", \"<proposal-id>\", \"\", \"merged\"],\n    [\"p\", \"<contributor-pubkey>\", \"\", \"contributor\"]\n  ]\n}\n```\n\n### Team Wiki (Restricted)\n\n**Space:**\n```json\n{\n  \"kind\": 33527,\n  \"tags\": [\n    [\"d\", \"team-internal\"],\n    [\"title\", \"Team Internal Wiki\"],\n    [\"permission_model\", \"restricted\"],\n    [\"visibility\", \"private\"],\n    [\"p\", \"npub1alice...\", \"\", \"editor\"],\n    [\"p\", \"npub1bob...\", \"\", \"editor\"],\n    [\"p\", \"npub1carol...\", \"\", \"contributor\"]\n  ]\n}\n```\n\nOnly listed people can propose or publish.\n\n## Rationale\n\n### Why Proposals Instead of Patches?\n- **Simpler implementation**: Full content is easier to validate than diffs\n- **Format independence**: Works with all markup formats\n- **Better review**: Editors see complete result, not just changes\n- **Nostr-native**: Each proposal is a standalone event\n\n### Why Multiple Permission Models?\n- **Flexibility**: Different communities have different needs\n- **Gradual adoption**: Start single-author, expand to collaborative\n- **Backwards compatibility**: Default to single-author if no model specified\n\n### Why Not Just Use Multiple Authors?\nThe `p` tag system with roles provides:\n- **Clear permissions**: Know who can do what\n- **Attribution**: Track all contributors\n- **Trust management**: Space owners control access\n\n## Compatibility\n\n### With Original NIP\n- All original event kinds remain unchanged\n- Spaces without `permission_model` work exactly as before\n- No breaking changes to existing functionality\n\n### Client Support Levels\n1. **Basic**: Ignore collaboration features, single-author only\n2. **Read-only**: Display collaborative content, show contributors\n3. **Proposal**: Can submit edit proposals\n4. **Full**: Can manage permissions, merge proposals, full collaboration\n\n## Future Extensions\n\n### Possible Additions\n- Discussion threads on proposals (using kind:1 with `e` tag)\n- Approval voting (multiple editors approve before merge)\n- Automated merges for trusted contributors\n- Review workflows with required reviewer counts\n- Conflict resolution mechanisms\n- Change request comments (inline notes on proposals)","sig":"2ee226619077c049f3b084a8cf2cfcc365e42b444b816e970a24b4c047642bb35c9c02a408eed43f1eae83dd889612d50b25d46aa1f4f0c4fef41ff84b4424ae"}