# RANGERBLOCK REGISTRATION & CONSENT BLOCKCHAIN SYSTEM
## Project Codename: "SENTINEL PROTOCOL"
### Version 1.0.0 - December 4, 2025

---

## CLASSIFICATION: PRIVATE
**DO NOT COMMIT TO PUBLIC GIT**

---

## 1. EXECUTIVE SUMMARY

### The Vision
When a user:
1. Creates identity (hardware-bound)
2. Accepts Terms of Use (18+, content policy, etc.)

A **REGISTRATION BLOCK** is created on the RangerBlock blockchain, providing:
- Immutable proof of acceptance
- Cryptographic signature
- Admin notification for approval
- Privilege assignment upon approval

### Components Needed

| Component | Purpose | Location |
|-----------|---------|----------|
| RegistrationBlock.sol | Solidity contract for EVM chains | Blockchain/contracts/ |
| registration-service.cjs | Node.js registration handler | rangerblock/lib/ |
| consent-service.cjs | Consent/terms handler | rangerblock/lib/ |
| Admin integration | View/approve registrations | ~/.claude/ranger/admin/ |

### Apps Covered
- ranger-chat-lite (Electron)
- just-chat (Terminal)
- server-only (Server deployment)
- RangerPlex (Full browser)

---

## 2. REGISTRATION BLOCK STRUCTURE

### 2.1 Solidity Contract (Remix Standard)

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/**
 * @title RangerRegistration
 * @dev User registration and consent tracking for RangerBlock
 * @author David Keane (IrishRanger) + Claude Code (Ranger)
 */
contract RangerRegistration {

    // ========================================================================
    // STRUCTURES
    // ========================================================================

    struct Registration {
        bytes32 userIdHash;           // SHA256 of userId
        bytes32 publicKeyHash;        // SHA256 of RSA public key
        bytes32 hardwareIdHash;       // SHA256 of hardware fingerprint
        string username;              // Display name
        string appType;               // ranger-chat-lite, just-chat, etc.

        // Consent
        string termsVersion;          // "1.0.0"
        bytes32 termsHash;            // SHA256 of terms text
        bytes signature;              // RSA signature of consent

        // Timestamps
        uint256 registeredAt;         // Block timestamp
        uint256 consentedAt;          // When terms accepted

        // Status
        RegistrationStatus status;    // pending, approved, denied, revoked
        string statusReason;          // Reason for status change

        // Admin
        address approvedBy;           // Admin who approved
        uint256 approvedAt;           // Approval timestamp
    }

    enum RegistrationStatus {
        PENDING,
        APPROVED,
        DENIED,
        REVOKED
    }

    // ========================================================================
    // STATE
    // ========================================================================

    address public owner;
    address public supremeAdmin;

    mapping(bytes32 => Registration) public registrations;  // userIdHash => Registration
    mapping(bytes32 => bool) public hardwareUsed;           // hardwareIdHash => used
    bytes32[] public registrationList;                      // All registration IDs

    uint256 public totalRegistrations;
    uint256 public pendingCount;
    uint256 public approvedCount;
    uint256 public deniedCount;

    // ========================================================================
    // EVENTS
    // ========================================================================

    event RegistrationSubmitted(
        bytes32 indexed userIdHash,
        string username,
        string appType,
        uint256 timestamp
    );

    event RegistrationApproved(
        bytes32 indexed userIdHash,
        address approvedBy,
        uint256 timestamp
    );

    event RegistrationDenied(
        bytes32 indexed userIdHash,
        address deniedBy,
        string reason,
        uint256 timestamp
    );

    event RegistrationRevoked(
        bytes32 indexed userIdHash,
        address revokedBy,
        string reason,
        uint256 timestamp
    );

    event ConsentRecorded(
        bytes32 indexed userIdHash,
        string termsVersion,
        bytes32 termsHash,
        uint256 timestamp
    );

    // ========================================================================
    // MODIFIERS
    // ========================================================================

    modifier onlyOwner() {
        require(msg.sender == owner || msg.sender == supremeAdmin, "Not authorized");
        _;
    }

    modifier onlyAdmin() {
        require(msg.sender == owner || msg.sender == supremeAdmin, "Not admin");
        _;
    }

    // ========================================================================
    // CONSTRUCTOR
    // ========================================================================

    constructor(address _supremeAdmin) {
        owner = msg.sender;
        supremeAdmin = _supremeAdmin;
    }

    // ========================================================================
    // REGISTRATION FUNCTIONS
    // ========================================================================

    /**
     * @dev Submit a new registration with consent
     */
    function register(
        bytes32 userIdHash,
        bytes32 publicKeyHash,
        bytes32 hardwareIdHash,
        string memory username,
        string memory appType,
        string memory termsVersion,
        bytes32 termsHash,
        bytes memory signature
    ) public returns (bool) {
        // Check hardware not already used (prevents ban evasion)
        require(!hardwareUsed[hardwareIdHash], "Hardware already registered");

        // Check not already registered
        require(registrations[userIdHash].registeredAt == 0, "Already registered");

        // Create registration
        Registration storage reg = registrations[userIdHash];
        reg.userIdHash = userIdHash;
        reg.publicKeyHash = publicKeyHash;
        reg.hardwareIdHash = hardwareIdHash;
        reg.username = username;
        reg.appType = appType;
        reg.termsVersion = termsVersion;
        reg.termsHash = termsHash;
        reg.signature = signature;
        reg.registeredAt = block.timestamp;
        reg.consentedAt = block.timestamp;
        reg.status = RegistrationStatus.PENDING;

        // Mark hardware as used
        hardwareUsed[hardwareIdHash] = true;

        // Add to list
        registrationList.push(userIdHash);
        totalRegistrations++;
        pendingCount++;

        emit RegistrationSubmitted(userIdHash, username, appType, block.timestamp);
        emit ConsentRecorded(userIdHash, termsVersion, termsHash, block.timestamp);

        return true;
    }

    /**
     * @dev Approve a pending registration (admin only)
     */
    function approve(bytes32 userIdHash) public onlyAdmin {
        Registration storage reg = registrations[userIdHash];
        require(reg.registeredAt > 0, "Registration not found");
        require(reg.status == RegistrationStatus.PENDING, "Not pending");

        reg.status = RegistrationStatus.APPROVED;
        reg.approvedBy = msg.sender;
        reg.approvedAt = block.timestamp;

        pendingCount--;
        approvedCount++;

        emit RegistrationApproved(userIdHash, msg.sender, block.timestamp);
    }

    /**
     * @dev Deny a pending registration (admin only)
     */
    function deny(bytes32 userIdHash, string memory reason) public onlyAdmin {
        Registration storage reg = registrations[userIdHash];
        require(reg.registeredAt > 0, "Registration not found");
        require(reg.status == RegistrationStatus.PENDING, "Not pending");

        reg.status = RegistrationStatus.DENIED;
        reg.statusReason = reason;

        pendingCount--;
        deniedCount++;

        emit RegistrationDenied(userIdHash, msg.sender, reason, block.timestamp);
    }

    /**
     * @dev Revoke an approved registration (admin only)
     */
    function revoke(bytes32 userIdHash, string memory reason) public onlyAdmin {
        Registration storage reg = registrations[userIdHash];
        require(reg.registeredAt > 0, "Registration not found");
        require(reg.status == RegistrationStatus.APPROVED, "Not approved");

        reg.status = RegistrationStatus.REVOKED;
        reg.statusReason = reason;

        approvedCount--;

        emit RegistrationRevoked(userIdHash, msg.sender, reason, block.timestamp);
    }

    // ========================================================================
    // VIEW FUNCTIONS
    // ========================================================================

    function getRegistration(bytes32 userIdHash) public view returns (
        string memory username,
        string memory appType,
        string memory termsVersion,
        RegistrationStatus status,
        uint256 registeredAt,
        uint256 approvedAt
    ) {
        Registration storage reg = registrations[userIdHash];
        return (
            reg.username,
            reg.appType,
            reg.termsVersion,
            reg.status,
            reg.registeredAt,
            reg.approvedAt
        );
    }

    function isApproved(bytes32 userIdHash) public view returns (bool) {
        return registrations[userIdHash].status == RegistrationStatus.APPROVED;
    }

    function isPending(bytes32 userIdHash) public view returns (bool) {
        return registrations[userIdHash].status == RegistrationStatus.PENDING;
    }

    function getPendingCount() public view returns (uint256) {
        return pendingCount;
    }

    function getStats() public view returns (
        uint256 total,
        uint256 pending,
        uint256 approved,
        uint256 denied
    ) {
        return (totalRegistrations, pendingCount, approvedCount, deniedCount);
    }
}
```

---

## 3. NODE.JS INTEGRATION

### 3.1 Registration Block (JSON Format for RangerBlock P2P)

For our custom blockchain (non-EVM), registrations are blocks:

```javascript
// Registration block structure
const registrationBlock = {
    type: 'USER_REGISTRATION',
    version: '1.0.0',

    // Identity (hashed for privacy)
    identity: {
        userIdHash: 'sha256_of_rb_xxx',
        publicKeyHash: 'sha256_of_public_key',
        hardwareIdHash: 'sha256_of_hardware_fingerprint',
        username: 'SwiftRanger',
        appType: 'ranger-chat-lite'
    },

    // Consent record
    consent: {
        termsVersion: '1.0.0',
        termsHash: 'sha256_of_terms_text',
        acceptedAt: '2025-12-04T10:30:00.000Z',
        ageConfirmed: true,  // User confirmed 18+
        signature: 'RSA_signature_of_consent'
    },

    // Block metadata
    metadata: {
        timestamp: '2025-12-04T10:30:05.000Z',
        previousHash: 'abc123...',
        nonce: 12345,
        minedBy: 'relay_node_id'
    },

    // Status (updated by admin)
    status: {
        current: 'pending',  // pending, approved, denied, revoked
        updatedAt: null,
        updatedBy: null,
        reason: null
    }
};
```

### 3.2 Registration Service (registration-service.cjs)

```javascript
// Location: rangerblock/lib/registration-service.cjs

class RegistrationService {
    constructor(identityService, consentService) {
        this.identity = identityService;
        this.consent = consentService;
    }

    // Create registration block
    async createRegistrationBlock() { }

    // Submit to relay (goes to admin queue)
    async submitRegistration(block) { }

    // Check registration status
    async checkStatus(userId) { }

    // Handle approval notification
    onApproved(callback) { }

    // Handle denial notification
    onDenied(callback) { }
}
```

---

## 4. ADMIN INTEGRATION

### 4.1 Admin Dashboard Updates

**New "Registrations" Tab:**

```
┌─────────────────────────────────────────────────────────────────┐
│ PENDING REGISTRATIONS (3)                                       │
├───────┬──────────────┬─────────────────┬───────────┬───────────┤
│ #     │ Username     │ App             │ Date      │ Actions   │
├───────┼──────────────┼─────────────────┼───────────┼───────────┤
│ 1     │ SwiftRanger  │ ranger-chat-lite│ Dec 4     │ [A] [D]   │
│ 2     │ StormWolf    │ just-chat       │ Dec 4     │ [A] [D]   │
│ 3     │ NightHawk    │ just-chat       │ Dec 4     │ [A] [D]   │
└───────┴──────────────┴─────────────────┴───────────┴───────────┘

[A] = Approve   [D] = Deny   [V] = View Details

Registration Details (SwiftRanger):
─────────────────────────────────────
User ID:      rb_abc123...
Hardware:     M4Max-xxx (masked)
App:          ranger-chat-lite
Registered:   2025-12-04 10:30:05
Terms:        v1.0.0 (18+ accepted)
Signature:    ✓ Valid
Status:       PENDING

[A]pprove  [D]eny  [B]ack
```

### 4.2 Admin Registry Updates

Add to `admin-registry.cjs`:

```javascript
// Registration queue management
getPendingRegistrations() { }
approveRegistration(userIdHash, adminId) { }
denyRegistration(userIdHash, adminId, reason) { }
revokeRegistration(userIdHash, adminId, reason) { }

// Consent verification
verifyConsent(userIdHash) { }
getConsentRecord(userIdHash) { }
```

---

## 5. APP INTEGRATION FLOW

### 5.1 ranger-chat-lite Flow

```
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  App Start  │────>│   Check     │────>│   Show      │
│             │     │  Identity   │     │ Terms Modal │
└─────────────┘     └─────────────┘     └──────┬──────┘
                                               │
                    ┌──────────────────────────┘
                    │ User Accepts
                    v
              ┌─────────────┐     ┌─────────────┐
              │  Sign       │────>│  Submit to  │
              │  Consent    │     │  Relay      │
              └─────────────┘     └──────┬──────┘
                                         │
                    ┌────────────────────┘
                    v
              ┌─────────────┐
              │ PENDING     │ <── Limited features
              │ status      │     (view only)
              └──────┬──────┘
                     │
        ┌────────────┴────────────┐
        v                         v
  ┌───────────┐           ┌───────────────┐
  │ APPROVED  │           │    DENIED     │
  │ Full      │           │ Show reason,  │
  │ access    │           │ exit app      │
  └───────────┘           └───────────────┘
```

### 5.2 just-chat Flow

Same flow but terminal-based:
1. First run → Show terms in terminal
2. User types 'y' to accept
3. Consent signed and submitted
4. Status: PENDING (can view chat, can't send)
5. When approved → Full access
6. When denied → Exit with message

### 5.3 server-only Flow

Server operators get different terms:
1. Setup script shows server terms
2. Operator accepts
3. Server registration submitted
4. Admin approves server node
5. Server can join network

---

## 6. PRIVILEGE SYSTEM

### 6.1 Status-Based Privileges

| Status | Chat | Voice | Files | DM | Channels |
|--------|------|-------|-------|----|----------|
| PENDING | View | No | No | No | View |
| APPROVED | Full | Full | Full | Full | Full |
| DENIED | No | No | No | No | No |
| REVOKED | No | No | No | No | No |

### 6.2 Implementation

```javascript
// In each app's message handler
if (registrationStatus !== 'APPROVED') {
    if (registrationStatus === 'PENDING') {
        showNotification('Registration pending admin approval. View-only mode.');
        return false;  // Can't send
    } else {
        showError('Access denied. Contact admin.');
        exitApp();
    }
}
```

---

## 7. FILES TO CREATE

| File | Location | Purpose |
|------|----------|---------|
| RangerRegistration.sol | Blockchain/contracts/ | Solidity contract |
| registration-service.cjs | rangerblock/lib/ | Node.js registration |
| consent-service.cjs | rangerblock/lib/ | Consent management |
| Admin dashboard updates | ~/.claude/ranger/admin/ | Registration queue UI |

---

## 8. IMPLEMENTATION PHASES

### Phase 1: Core Infrastructure (This Week)
- [ ] Create RangerRegistration.sol
- [ ] Create registration-service.cjs
- [ ] Create consent-service.cjs
- [ ] Test locally

### Phase 2: Admin Integration (Next Week)
- [ ] Add registration queue to admin-registry.cjs
- [ ] Add Registrations tab to admin-dashboard.cjs
- [ ] Test approve/deny flow

### Phase 3: App Integration (Week 3)
- [ ] Integrate into ranger-chat-lite
- [ ] Integrate into just-chat
- [ ] Integrate into server-only setup
- [ ] Test end-to-end

### Phase 4: Testing (Week 4)
- [ ] Test on MSI Vector
- [ ] Test on AWS
- [ ] Security review
- [ ] Deploy to production

---

## 9. SECURITY NOTES

### What Admin Can See:
- Username
- App type
- Registration date
- Terms version accepted
- Signature validity
- Hardware ID (hashed, for ban enforcement)

### What Admin CANNOT See:
- Full userId (only hash)
- Full hardware fingerprint
- Private key
- Message content

### Hardware Ban Enforcement:
- Hardware ID hashed but tracked
- If banned user creates new identity, same hardware = blocked
- Admin can see "hardware previously used by banned user"

---

**Document Status**: READY FOR IMPLEMENTATION
**Created**: December 4, 2025
**Author**: Claude Code (Ranger) for David Keane (IrishRanger)

*Rangers lead the way!*
