mirror of
https://github.com/zvx-echo6/recon.git
synced 2026-05-20 06:34:40 +02:00
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:
parent
991826b4f1
commit
71e3dc12ed
7 changed files with 207 additions and 14 deletions
|
|
@ -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'}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
34
lib/recon_domains.py
Normal 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()}
|
||||
52
peertube-plugin/peertube-plugin-recon-domains/README.md
Normal file
52
peertube-plugin/peertube-plugin-recon-domains/README.md
Normal 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.
|
||||
28
peertube-plugin/peertube-plugin-recon-domains/main.js
Normal file
28
peertube-plugin/peertube-plugin-recon-domains/main.js
Normal 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 }
|
||||
20
peertube-plugin/peertube-plugin-recon-domains/package.json
Normal file
20
peertube-plugin/peertube-plugin-recon-domains/package.json
Normal 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": {}
|
||||
}
|
||||
71
tests/test_constants_parity.py
Normal file
71
tests/test_constants_parity.py
Normal 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.")
|
||||
Loading…
Add table
Add a link
Reference in a new issue