TAD User Guide
Version: v1.0 Complete (v1.0) Date: November 28, 2025
Table of Contents
- Introduction
- Quick Start
- Installation
- Basic Usage
- Command Reference
- Channels & Tribes
- Private Channels & Security
- Message History & Export
- Keyboard Shortcuts
- Troubleshooting
- Advanced Topics
Introduction
TAD (Tactical Autonomous Zone Communications) is a peer-to-peer, decentralized chat system designed for offline-first communication. It works on local networks without internet access and provides end-to-end encrypted private channels.
Key Features
- ✅ Zero Configuration - Auto-discovery via mDNS
- ✅ Multi-Channel - Organize conversations into Tribes
- ✅ End-to-End Encryption - Private channels with AES-256-GCM
- ✅ Message Persistence - SQLite database storage
- ✅ Advanced TUI - Professional terminal interface
- ✅ Export/Import - Backup and restore conversations
Quick Start
# 1. Install dependencies
pip install -r requirements.txt
# 2. Start TAD
python -m tad.main
# 3. Nodes on the same network will auto-discover each other!That's it! No configuration, no servers, no accounts.
Installation
Requirements
- Python: 3.8 or higher
- OS: Linux, macOS, Windows (with WSL recommended)
- Network: Wi-Fi or Ethernet (same local network)
Step-by-Step
# Clone repository (or download ZIP)
git clone https://github.com/yourusername/tad.git
cd tad
# Create virtual environment (recommended)
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Test installation
python -m pytest tests/ -v
# Run TAD
python -m tad.mainDependencies
textual>=0.40.0 # TUI framework
pynacl>=1.5.0 # Cryptography (libsodium)
zeroconf>=0.100.0 # mDNS peer discovery
cryptography>=41.0.0 # AES-GCM encryptionBasic Usage
Starting TAD
python -m tad.mainOn first run, TAD will:
- Generate a cryptographic identity (Ed25519 + X25519 keys)
- Create
profile.jsonwith your identity - Create
tad_node.dbSQLite database - Start peer discovery service
- Open the TUI interface
The Interface
┌─────────────────────────────────────────────────┐
│ TAD v1.0 │
├──────────┬────────────────────────┬─────────────┤
│ │ │ │
│ Channels │ Message History │ Peers │
│ │ │ │
│ #general │ [10:23] Alice: Hello! │ 👤 Alice │
│🔒#secret │ [10:24] You: Hi there! │ 👤 Bob │
│ #dev │ [10:25] Bob joined │ │
│ │ │ │
├──────────┴────────────────────────┴─────────────┤
│ > Type message or /help │
├─────────────────────────────────────────────────┤
│ Tab: Next | Shift+Tab: Prev | ?: Help | q: Quit│
└─────────────────────────────────────────────────┘Sending Messages
Just type your message and press Enter. It will be sent to the active channel.
> Hello, world!Using Commands
Commands start with /:
> /help # Show help
> /channels # List channels
> /join #dev # Join a channel
> /switch #dev # Switch to #devCommand Reference
Channel Management
/join <#channel>
Subscribe to a channel to receive its messages.
/join #dev
/join #offtopicExample:
> /join #dev
[SYSTEM] Joined #dev/leave <#channel>
Unsubscribe from a channel.
/leave #devNote: You cannot leave #general (the default channel).
/switch <#channel> or /s <#channel>
Switch to a different channel. The switched channel becomes active.
/switch #dev
/s #generalKeyboard Shortcut: Tab (next) / Shift+Tab (previous)
/channels
List all channels you're subscribed to.
/channelsOutput:
Subscribed channels:
▶ #general
#dev
#offtopicPrivate Channels
/create <#channel> [public|private]
Create a new channel. Default is public.
/create #myChannel # Public
/create #secret private # Private (encrypted)Private channels:
- Use AES-256-GCM encryption
- Only invited members can read messages
- Show 🔒 icon in channel list
/invite <node_id> <#channel>
Invite a peer to a private channel. Only the channel owner can invite.
/invite alice_abc123 #secretHow to get node_id: Use /peers to see connected peers and their IDs.
Information
/peers
Show number of connected peers.
/peersOutput:
Connected peers: 3/help
Show command reference and keyboard shortcuts.
/helpImport/Export
/export [#channel] [filename]
Export messages to JSON file for backup.
/export # All channels → tad_export_all_TIMESTAMP.json
/export #general # Only #general → tad_export_general_TIMESTAMP.json
/export #general messages.json # Custom filename
/export messages.json # All channels → messages.jsonOutput file structure:
{
"export_date": "2025-11-28T14:30:00",
"channel": "#general",
"message_count": 42,
"messages": [
{
"msg_id": "abc123...",
"channel_id": "#general",
"sender_id": "alice_xyz",
"content": "Hello!",
"timestamp": "2025-11-28T14:25:00",
"signature": "...",
"is_encrypted": false,
"nonce": null
}
]
}/import <filename>
Import messages from JSON file.
/import messages.json
/import backup_20251128.jsonFeatures:
- Auto-creates missing channels
- Skips duplicate messages (by msg_id)
- Refreshes active channel view
Channels & Tribes
What are Channels?
Channels (also called Tribes) organize conversations by topic. Each channel is independent:
- Messages sent to
#generalonly appear in#general - You can subscribe to multiple channels
- Switch between channels with
/switchor Tab
Default Channels
Every node starts subscribed to:
#general- Main discussion channel (cannot leave)
Creating Channels
Anyone can create a public channel:
/create #dev
/create #randomJoining Channels
There are two ways to join a channel:
Create it:
bash/create #newChannelJoin existing:
bash/join #dev
Note: For public channels, you can join even if you haven't seen it yet. For private channels, you need an invitation.
Private Channels & Security
Why Private Channels?
Private channels provide end-to-end encryption for sensitive conversations:
- ✅ Only invited members can read messages
- ✅ Non-members see garbled ciphertext
- ✅ AES-256-GCM authenticated encryption
- ✅ Forward secrecy (future: key rotation)
Creating a Private Channel
/create #secret privateYou become the owner with these permissions:
- Invite new members (
/invite) - Full read/write access
Inviting Members
Get the peer's node ID:
bash/peersInvite them:
bash/invite alice_abc123 #secretThey auto-join when they receive the invite
Security Model
What's Protected:
- Message content (encrypted with AES-256-GCM)
- Channel key (exchanged via X25519 SealedBox)
- Message authenticity (Ed25519 signatures)
What's Visible:
- Channel ID (e.g., "#secret")
- Sender ID
- Message size and timing
Key Management
- Channel Key: 256-bit symmetric key (one per private channel)
- Signing Keys: Ed25519 (for message signatures)
- Encryption Keys: X25519 (for key exchange)
Keys are stored:
- On Disk:
profile.json(signing/encryption keys) - In Memory: Channel keys (during runtime)
- In Messages: Encrypted channel keys (for invites)
Message History & Export
Message Storage
All messages are saved in tad_node.db (SQLite):
- Organized by channel
- Includes sender, timestamp, signature
- Encrypted messages stored as ciphertext
- Survives node restarts
Loading History
When you switch to a channel, TAD automatically loads the last 50 messages:
/switch #devOutput:
[SYSTEM] Loading history for #dev...
[10:20] Alice: Previous message 1
[10:21] Bob: Previous message 2
...
[SYSTEM] Switched to #devExport Messages
Use Case: Backup before system upgrade
/export # Backup all channelsResult:
✓ Exported 156 messages to /Users/you/tad_export_all_20251128_143000.jsonImport Messages
Use Case: Restore after reinstall
/import tad_export_all_20251128_143000.jsonResult:
✓ Imported 156/156 messages from tad_export_all_20251128_143000.jsonExport Format
Exports are standard JSON, safe to:
- ✅ Archive for long-term storage
- ✅ Import on another device
- ✅ Parse with external tools
- ✅ Version control (if not private)
Warning: Exported private channel messages contain encrypted content. You need the channel key to decrypt them.
Keyboard Shortcuts
Navigation
| Key | Action |
|---|---|
Tab | Next channel |
Shift+Tab | Previous channel |
↑ / ↓ | Scroll message history |
Page Up / Page Down | Fast scroll |
Actions
| Key | Action |
|---|---|
Enter | Send message / Execute command |
Ctrl+C | Quit application |
? | Show help |
q | Quit (alternative) |
TUI Interactions
- Mouse Click: Select channel (if terminal supports it)
- Scroll Wheel: Scroll message history
- Resize Window: Auto-adjusts layout
Troubleshooting
Nodes Not Discovering Each Other
Problem: Started TAD but no peers appear.
Solutions:
Check Network:
- Ensure both devices on same Wi-Fi/LAN
- Try
ping <other-ip>to verify connectivity
Check Firewall:
- Allow Python/TAD through firewall
- Open UDP port 5353 (mDNS)
- Open TCP ports 50000-60000 (dynamic ports)
Check mDNS Service:
bash# macOS/Linux dns-sd -B _tad._tcp # Should show TAD nodesRestart Nodes:
- Exit TAD (Ctrl+C)
- Wait 5 seconds
- Restart:
python -m tad.main
Messages Not Sending
Problem: Type message but nothing happens.
Solutions:
Check Active Channel:
- Verify correct channel selected
- Use
/channelsto list subscribed channels
Check Peers:
- Use
/peersto see if peers connected - At least 1 peer needed to receive messages
- Use
Check Logs:
bash# Run with debug logging python -m tad.main --log-level DEBUG
Cannot Decrypt Private Channel
Problem: Receive encrypted messages but see garbled text.
Causes:
- ❌ Not invited to channel
- ❌ Lost channel key (database corruption)
- ❌ Wrong decryption key
Solutions:
Request Re-Invite:
- Ask channel owner to
/inviteyou again
- Ask channel owner to
Check Database:
bashsqlite3 tad_node.db "SELECT * FROM channel_members WHERE node_id='YOUR_ID';"Verify Identity:
- Ensure
profile.jsonintact - Backup and regenerate if corrupted
- Ensure
Import Fails
Problem: /import command shows error.
Solutions:
Check File Format:
- Must be valid JSON
- Use
/exportto see correct format
Check File Path:
bash/import /full/path/to/messages.jsonCheck Permissions:
- Ensure read access to file
- Ensure write access to database
Advanced Topics
Identity Files
profile.json - Your cryptographic identity
{
"version": "1.0",
"username": "Alice",
"signing_key": "hex_encoded_ed25519_private_key",
"verify_key": "hex_encoded_ed25519_public_key",
"encryption_private_key": "hex_encoded_x25519_private_key",
"encryption_public_key": "hex_encoded_x25519_public_key"
}⚠️ CRITICAL: Backup this file! Losing it means:
- ❌ New identity required
- ❌ Cannot decrypt old private channels
- ❌ Others see you as a new user
Database Schema
tad_node.db - SQLite database with 3 tables:
channels - Channel metadata
sqlchannel_id | name | type | owner_node_id | created_at | subscribedchannel_members - Membership & permissions
sqlchannel_id | node_id | role | joined_atmessages - Message history
sqlmsg_id | channel_id | sender_id | content | timestamp | signature | is_encrypted | nonce
Backup:
cp tad_node.db tad_node.db.backupCustom Port Configuration
By default, TAD uses random available ports. To specify:
# In tad/node.py, modify __init__
self.tcp_port = 5000 # Fixed portUse Case: Firewall rules, port forwarding
Running as Service
systemd (Linux):
# /etc/systemd/system/tad.service
[Unit]
Description=TAD P2P Chat
After=network.target
[Service]
Type=simple
User=youruser
WorkingDirectory=/home/youruser/tad
ExecStart=/usr/bin/python3 -m tad.main
Restart=on-failure
[Install]
WantedBy=multi-user.targetsudo systemctl enable tad
sudo systemctl start tadNetwork Diagnostics
Check Discovery:
dns-sd -B _tad._tcpCheck Connections:
netstat -an | grep ESTABLISHEDMonitor Traffic:
tcpdump -i en0 port 5353 # mDNSFAQ
Q: Do I need internet access? A: No! TAD works on local networks without internet.
Q: Can I use this over the internet? A: Not directly. You'd need VPN or port forwarding (not recommended without additional security).
Q: How many peers can I have? A: Tested with 10-20 peers. Theoretically hundreds, limited by network bandwidth.
Q: Are messages encrypted? A: Private channels: Yes (AES-256-GCM). Public channels: No (plaintext).
Q: Can I change my username? A: Edit profile.json and restart. But others track you by public key, not username.
Q: What if I lose profile.json? A: Generate new identity. Old private channels inaccessible.
Q: Can I run multiple nodes on same computer? A: Yes! Use different directories:
cd ~/tad1 && python -m tad.main &
cd ~/tad2 && python -m tad.main &Getting Help
- GitHub Issues: https://github.com/yourusername/tad/issues
- Documentation: See
README.md,architecture documentation - Logs: Check terminal output, enable DEBUG level
- Community: (Future: Discord/Matrix)
License
MIT License - See LICENSE file
Happy Chatting! 🎉
For developers: See architecture documentation for technical architecture