Phase 1: PeerTube plugin and recon_domains module

Single source of truth for the 18 RECON knowledge domains mapped to
PeerTube category IDs 100-117. Replaces duplicate VALID_DOMAINS sets
in enricher.py and embedder.py with imports from lib/recon_domains.py.

Includes PeerTube plugin (peertube-plugin-recon-domains) that registers
custom categories via videoCategoryManager.addConstant(), and a parity
test to verify constants match between RECON and the PeerTube API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Matt 2026-04-28 00:04:13 +00:00
commit 71e3dc12ed
7 changed files with 207 additions and 14 deletions

View file

@ -27,13 +27,7 @@ from .utils import resolve_text_dir
logger = setup_logging('recon.embedder')
# ── Classification allowlists ───────────────────────────────────────────────
VALID_DOMAINS = {
'Agriculture & Livestock', 'Civil Organization', 'Communications',
'Food Systems', 'Foundational Skills', 'Logistics', 'Medical',
'Navigation', 'Operations', 'Power Systems', 'Preservation & Storage',
'Security', 'Shelter & Construction', 'Technology', 'Tools & Equipment',
'Vehicles', 'Water Systems', 'Wilderness Skills',
}
from .recon_domains import VALID_DOMAINS
VALID_KNOWLEDGE_TYPES = {'foundational', 'procedural', 'operational'}
VALID_COMPLEXITIES = {'basic', 'intermediate', 'advanced'}

View file

@ -42,13 +42,7 @@ logger = setup_logging('recon.enricher')
STALE_ENRICHING_HOURS = 2
# ── Classification allowlists ───────────────────────────────────────────────
VALID_DOMAINS = {
'Agriculture & Livestock', 'Civil Organization', 'Communications',
'Food Systems', 'Foundational Skills', 'Logistics', 'Medical',
'Navigation', 'Operations', 'Power Systems', 'Preservation & Storage',
'Security', 'Shelter & Construction', 'Technology', 'Tools & Equipment',
'Vehicles', 'Water Systems', 'Wilderness Skills',
}
from .recon_domains import VALID_DOMAINS
VALID_KNOWLEDGE_TYPES = {'foundational', 'procedural', 'operational'}
VALID_COMPLEXITIES = {'basic', 'intermediate', 'advanced'}

34
lib/recon_domains.py Normal file
View file

@ -0,0 +1,34 @@
"""
RECON Domain Taxonomy
Single source of truth for the 18 knowledge domains and their PeerTube
category ID mappings. IDs 100-117 are registered via the
peertube-plugin-recon-domains plugin.
Import VALID_DOMAINS from here instead of defining local sets.
"""
DOMAIN_CATEGORY_MAP = {
'Agriculture & Livestock': 100,
'Civil Organization': 101,
'Communications': 102,
'Food Systems': 103,
'Foundational Skills': 104,
'Logistics': 105,
'Medical': 106,
'Navigation': 107,
'Operations': 108,
'Power Systems': 109,
'Preservation & Storage': 110,
'Security': 111,
'Shelter & Construction': 112,
'Technology': 113,
'Tools & Equipment': 114,
'Vehicles': 115,
'Water Systems': 116,
'Wilderness Skills': 117,
}
VALID_DOMAINS = set(DOMAIN_CATEGORY_MAP.keys())
CATEGORY_DOMAIN_MAP = {v: k for k, v in DOMAIN_CATEGORY_MAP.items()}

View file

@ -0,0 +1,52 @@
# peertube-plugin-recon-domains
Registers 18 RECON knowledge domains as PeerTube video categories using IDs 100-117. These categories are assigned automatically by RECON's domain assignment pipeline based on concept extraction analysis.
## Category Mapping
| ID | Domain |
|-----|---------------------------|
| 100 | Agriculture & Livestock |
| 101 | Civil Organization |
| 102 | Communications |
| 103 | Food Systems |
| 104 | Foundational Skills |
| 105 | Logistics |
| 106 | Medical |
| 107 | Navigation |
| 108 | Operations |
| 109 | Power Systems |
| 110 | Preservation & Storage |
| 111 | Security |
| 112 | Shelter & Construction |
| 113 | Technology |
| 114 | Tools & Equipment |
| 115 | Vehicles |
| 116 | Water Systems |
| 117 | Wilderness Skills |
Built-in PeerTube categories (IDs 1-18) are not modified.
## Install
```bash
# Copy plugin to PeerTube storage
cp -r peertube-plugin-recon-domains /var/www/peertube/storage/plugins/node_modules/
# Register plugin via API or admin UI
# Admin > Plugins > Install > peertube-plugin-recon-domains
# Restart PeerTube
sudo systemctl restart peertube
```
## Uninstall
Remove the plugin via PeerTube admin UI or:
```bash
rm -rf /var/www/peertube/storage/plugins/node_modules/peertube-plugin-recon-domains
sudo systemctl restart peertube
```
Videos with RECON categories will revert to showing the raw category ID until the plugin is reinstalled.

View file

@ -0,0 +1,28 @@
async function register ({ videoCategoryManager }) {
const reconDomains = {
100: 'Agriculture & Livestock',
101: 'Civil Organization',
102: 'Communications',
103: 'Food Systems',
104: 'Foundational Skills',
105: 'Logistics',
106: 'Medical',
107: 'Navigation',
108: 'Operations',
109: 'Power Systems',
110: 'Preservation & Storage',
111: 'Security',
112: 'Shelter & Construction',
113: 'Technology',
114: 'Tools & Equipment',
115: 'Vehicles',
116: 'Water Systems',
117: 'Wilderness Skills'
}
for (const [id, label] of Object.entries(reconDomains)) {
videoCategoryManager.addConstant(parseInt(id), label)
}
}
module.exports = { register }

View file

@ -0,0 +1,20 @@
{
"name": "peertube-plugin-recon-domains",
"version": "1.0.0",
"description": "Registers 18 RECON knowledge domains as PeerTube video categories (IDs 100-117)",
"engine": {
"peertube": ">=6.0.0"
},
"keywords": [
"peertube",
"plugin"
],
"homepage": "https://forge.echo6.co/matt/recon",
"author": "Echo6",
"license": "MIT",
"library": "./main.js",
"staticDirs": {},
"css": [],
"clientScripts": [],
"translations": {}
}

View file

@ -0,0 +1,71 @@
#!/usr/bin/env python3
"""
Parity test: verify RECON domain taxonomy matches PeerTube categories.
Tests:
1. DOMAIN_CATEGORY_MAP keys match VALID_DOMAINS exactly
2. PeerTube API returns all 18 RECON categories (IDs 100-117) with correct labels
Usage:
cd /opt/recon && source venv/bin/activate
python3 tests/test_constants_parity.py
"""
import json
import sys
import requests
# Add parent dir to path for imports
sys.path.insert(0, '/opt/recon')
from lib.recon_domains import DOMAIN_CATEGORY_MAP, VALID_DOMAINS, CATEGORY_DOMAIN_MAP
def test_local_parity():
"""Verify DOMAIN_CATEGORY_MAP keys match VALID_DOMAINS."""
map_keys = set(DOMAIN_CATEGORY_MAP.keys())
assert map_keys == VALID_DOMAINS, (
f"Mismatch: in map but not VALID_DOMAINS: {map_keys - VALID_DOMAINS}, "
f"in VALID_DOMAINS but not map: {VALID_DOMAINS - map_keys}"
)
assert len(CATEGORY_DOMAIN_MAP) == len(DOMAIN_CATEGORY_MAP), "Reverse map size mismatch"
print(f"[OK] Local parity: {len(VALID_DOMAINS)} domains, map keys match VALID_DOMAINS")
def test_peertube_categories():
"""Verify PeerTube API returns all 18 RECON categories."""
url = "http://192.168.1.170:9000/api/v1/videos/categories"
headers = {"Host": "stream.echo6.co"}
try:
resp = requests.get(url, headers=headers, timeout=10)
resp.raise_for_status()
except Exception as e:
print(f"[SKIP] PeerTube API unreachable: {e}")
return
categories = resp.json() # dict of {id_str: label}
missing = []
wrong_label = []
for domain, cat_id in DOMAIN_CATEGORY_MAP.items():
cat_str = str(cat_id)
if cat_str not in categories:
missing.append((cat_id, domain))
elif categories[cat_str] != domain:
wrong_label.append((cat_id, domain, categories[cat_str]))
if missing:
print(f"[FAIL] Missing categories in PeerTube: {missing}")
print(" Deploy peertube-plugin-recon-domains to CT 110 first")
sys.exit(1)
if wrong_label:
print(f"[FAIL] Wrong labels in PeerTube: {wrong_label}")
sys.exit(1)
print(f"[OK] PeerTube parity: all {len(DOMAIN_CATEGORY_MAP)} categories present with correct labels")
if __name__ == '__main__':
test_local_parity()
test_peertube_categories()
print("\nAll parity tests passed.")