# LICENSE OVERVIEW

## What You're Getting

**Trial Period:** 14 days from first install  
**Machine Binding:** Yes (locked to your hardware)  
**Internet Required:** No (all validation local)  
**Renewable:** Generate new license key each device

---

## How It Works

### Trial Mode (Default)

1. First run: System records install timestamp
2. Every call to physics functions checks license
3. After 14 days: Functions return error
4. No warnings, no tracking, no internet

### Licensed Mode

1. Receive `license.json` from vendor
2. Place in working directory or specify path:
   ```python
   from spigot_torch import LicenseManager
   LicenseManager.load_license('path/to/license.json')
   ```
3. License validated (HMAC check)
4. Machine ID verified (your hardware bound)
5. Unlimited access

---

## License File Format

```json
{
  "machine_id": "39af49a2165e15dc",
  "install_time": 1710951234.5,
  "version": "1.0",
  "_sig": "a1b2c3d4e5f6..."
}
```

**machine_id**: Hashed from your MAC address + OS + CPU (16 chars)  
**install_time**: Unix timestamp of license generation  
**_sig**: HMAC-SHA256 signature (cannot be edited)

---

## Security

### What Cannot Be Bypassed

✅ **License file is cryptographically signed**
- Changing any field invalidates signature
- Requires vendor's secret key to re-sign
- HMAC prevents tampering

✅ **Machine binding**
- License locked to your hardware
- Cannot transfer to another computer
- Machine ID unhashable (one-way)

✅ **Clock rollback detection**
- System detects if system time goes backward
- Prevents trial reset by changing clock
- Enforced in compiled C code

✅ **Trial is hard-coded**
- 14-day limit in binary (cannot be extended)
- Check runs on every function call (fast, inline)
- No configuration files to edit

### What Happens

❌ **Trying to edit license file**
→ Signature validation fails → License rejected

❌ **Trying to copy license to another machine**
→ Machine ID doesn't match → License rejected

❌ **Trying to reset clock to restart trial**
→ Anti-rollback detection triggers → License invalid

❌ **Trying to extend trial period**
→ Hard-coded 14 days → Fails after expiration

---

## Activation Flow

### Step 1: Get Your Machine ID

```python
from spigot_torch import LicenseManager
info = LicenseManager.info()
print(info['machine_id'])
# Output: 39af49a2165e15dc
```

### Step 2: Send to Vendor

Send your machine ID (publicly safe—it's hashed).

### Step 3: Receive License

Vendor returns `license.json` with:
- Your machine ID
- HMAC-SHA256 signature
- Install timestamp

### Step 4: Install License

Place `license.json` in your project directory:

```python
LicenseManager.load_license('license.json')
print(LicenseManager.info())
# Output: {'licensed': True, 'trial_remaining_days': -1, ...}
```

### Step 5: Start Using

All functions now have unlimited access:

```python
from spigot_torch import TCEDSolver
T_final, _ = TCEDSolver.solve(T_init, iterations=1000)  # No limit
```

---

## Trial Countdown

Check remaining trial days:

```python
info = LicenseManager.info()
print(f"Days remaining: {info['trial_remaining_days']}")
```

Output:
- **14**: Just installed
- **7**: Halfway through
- **0**: Last day
- **-1**: Expired (if not licensed)

---

## Multi-Device Setup

Each device needs its own license:

```
Device A: Machine ID = 39af49a2165e15dc → license_A.json
Device B: Machine ID = 5c1d8e7a9f2b3c4e → license_B.json
Device C: Machine ID = 7a2f9c1d5e3b8a6f → license_C.json
```

Each vendor-generated license is unique per hardware.

---

## License Expiration

If trial expires without license:

```python
from spigot_torch import MaterialProperties

# This will raise:
# RuntimeError: License expired or invalid

k = MaterialProperties.thermal_conductivity(400.0)
```

Solution: Load valid `license.json`

---

## Vendor Guarantees

**What The Vendor Provides:**
✅ Unique license per customer per device
✅ HMAC signature (cannot be forged)
✅ Fast, offline validation
✅ No tracking, no phone-home

**What You Get:**
✅ 14-day free trial (no strings)
✅ Unlimited access once licensed
✅ Works offline
✅ No subscription renewal hassles

---

## FAQ

**Q: Can I use my license on multiple machines?**  
A: No. Each machine needs its own license. Send your machine ID to vendor for each device.

**Q: What if I change my hardware?**  
A: Machine ID changes. You need a new license. This is intentional (prevents license sharing).

**Q: Does the license expire after a year?**  
A: No expiration date. It's perpetual (tied to your machine only).

**Q: Can I reset the 14-day trial?**  
A: No. Trial is enforced in compiled code and protected against clock tampering.

**Q: What if I lose my license.json?**  
A: Contact vendor. They have your machine ID and can regenerate it (no special key needed).

---

## Support

For license issues:

1. Check machine ID: `LicenseManager.info()['machine_id']`
2. Verify license file: `cat license.json` (should have `_sig` field)
3. Contact vendor with your machine ID

---

**License System:** HMAC-SHA256 protected  
**Trial:** 14 days, no internet required  
**Machine Binding:** Yes, unhashable  
**Offline:** Yes, all validation local
