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')
|
logger = setup_logging('recon.embedder')
|
||||||
|
|
||||||
# ── Classification allowlists ───────────────────────────────────────────────
|
# ── Classification allowlists ───────────────────────────────────────────────
|
||||||
VALID_DOMAINS = {
|
from .recon_domains import 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',
|
|
||||||
}
|
|
||||||
VALID_KNOWLEDGE_TYPES = {'foundational', 'procedural', 'operational'}
|
VALID_KNOWLEDGE_TYPES = {'foundational', 'procedural', 'operational'}
|
||||||
VALID_COMPLEXITIES = {'basic', 'intermediate', 'advanced'}
|
VALID_COMPLEXITIES = {'basic', 'intermediate', 'advanced'}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,13 +42,7 @@ logger = setup_logging('recon.enricher')
|
||||||
STALE_ENRICHING_HOURS = 2
|
STALE_ENRICHING_HOURS = 2
|
||||||
|
|
||||||
# ── Classification allowlists ───────────────────────────────────────────────
|
# ── Classification allowlists ───────────────────────────────────────────────
|
||||||
VALID_DOMAINS = {
|
from .recon_domains import 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',
|
|
||||||
}
|
|
||||||
VALID_KNOWLEDGE_TYPES = {'foundational', 'procedural', 'operational'}
|
VALID_KNOWLEDGE_TYPES = {'foundational', 'procedural', 'operational'}
|
||||||
VALID_COMPLEXITIES = {'basic', 'intermediate', 'advanced'}
|
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