feat(application): integrate measured-load ingestion training and planner source

This commit is contained in:
ENELIX Agent
2026-10-02 21:00:05 +00:00
parent 44362e4bf5
commit fc024fcfba
96 changed files with 8933 additions and 0 deletions
@@ -0,0 +1,162 @@
"""Explicit, time-limited commissioning authority; NEVER enables shadow execution.
Only a reviewed internal operator call can arm a trial, and only for a separate
allowlist (empty by default). The manager and battery must additionally consent
locally. Existing shadow plans/acknowledgements keep their original meaning.
"""
from copy import deepcopy
from datetime import datetime, timedelta, timezone
from uuid import UUID
import json
MAX_SECONDS = 1800
MAX_POWER_W = 5000
AUTHORITY_TTL_SECONDS = 90
def schema(con):
con.execute('''CREATE TABLE IF NOT EXISTS planner_controlled_trials(
plant TEXT PRIMARY KEY, session_id TEXT NOT NULL UNIQUE,
value TEXT NOT NULL, revoked_at TEXT)''')
def timestamp(v):
if not isinstance(v, str):
raise ValueError('Explicit timestamp required')
t = datetime.fromisoformat(v.replace('Z', '+00:00'))
if t.tzinfo is None:
raise ValueError('Timezone required')
return t.astimezone(timezone.utc)
def uuid(v):
if not isinstance(v, str) or str(UUID(v)) != v:
raise ValueError('Canonical UUID required')
return v
def power(v):
if type(v) not in (int, float) or not 0 < v <= MAX_POWER_W:
raise ValueError('Pilot limit must be explicit and at most 5000 W')
return float(v)
def accounting(plan):
# A human checkbox alone must not relabel aggregate house consumption.
quality = plan.get('inputQuality', {})
if quality.get('loadBasis') != 'base_load':
raise ValueError('Verified base-load/SDL adapter required before a control trial')
evidence = quality.get('accountingEvidenceId')
if not isinstance(evidence, str) or not 8 <= len(evidence) <= 160:
raise ValueError('Plan lacks traceable base-load accounting evidence')
return evidence
def eligibility(view, plant):
if view.get('installationId') != plant or view.get('liveEnabled') is not False:
raise ValueError('Wrong plant or service mode')
p = view.get('plan')
if view.get('fresh') is not True or not isinstance(p, dict):
raise ValueError('Fresh independently validated planning input required')
if (p.get('installationId') != plant or p.get('runMode') != 'shadow'
or p.get('liveEnabled') is not False or p.get('executable') is not True):
raise ValueError('Wrong source plan identity or mode')
settings = view.get('settings', {})
if settings.get('family') == 'auto' or p.get('sourceFamily') != settings.get('family'):
raise ValueError('First controlled trial requires a fixed model family')
if p.get('configRevision') != settings.get('revision'):
raise ValueError('Configuration revision changed')
if len(p.get('controlContext', {}).get('batteries', {})) != 1:
raise ValueError('First controlled trial supports exactly one battery')
accounting(p)
return p
def arm(store, plant, request, view, now, allowed_plants):
"""Caller is authenticated internal operator; not exposed via device proxy."""
if plant not in allowed_plants:
raise ValueError('Controlled trial disabled by server allowlist')
fields = {'sessionId', 'expectedPlanId', 'expectedRevision', 'durationSeconds',
'maxChargeW', 'maxDischargeW', 'assetId', 'managerId', 'batteryInstanceId',
'acceptEstimatedPeak', 'actuatorWatchdogEvidenceId', 'confirmation'}
if set(request) != fields or request['confirmation'] != 'ARM_BOUNDED_CONTROL_TRIAL':
raise ValueError('Explicit reviewed commissioning request required')
session = uuid(request['sessionId']); p = eligibility(view, plant)
if type(request['expectedRevision']) is not int or request['expectedRevision'] < 0:
raise ValueError('Expected revision must be an integer')
if request['expectedPlanId'] != p['planId'] or request['expectedRevision'] != p['configRevision']:
raise ValueError('Source plan/revision changed; review again')
seconds = request['durationSeconds']
if type(seconds) is not int or not 30 <= seconds <= MAX_SECONDS:
raise ValueError('Trial duration must be 30..1800 seconds')
for k in ('managerId', 'batteryInstanceId'):
if type(request[k]) is not int or not 1 <= request[k] <= 99999:
raise ValueError('Explicit local instance binding required')
if request['managerId'] == request['batteryInstanceId']:
raise ValueError('Manager and battery instance must differ')
if request['assetId'] not in p['controlContext']['batteries']:
raise ValueError('Wrong trial battery')
if type(request['acceptEstimatedPeak']) is not bool:
raise ValueError('Explicit estimated-peak policy required')
if p.get('peakCostIsEstimate') and not request['acceptEstimatedPeak']:
raise ValueError('Estimated peak has not been accepted for this trial')
evidence = request['actuatorWatchdogEvidenceId']
if not isinstance(evidence, str) or not 8 <= len(evidence) <= 160:
raise ValueError('Device-side command-loss watchdog proof required')
value = {'kind': 'controlled_trial_grant', 'version': 1, 'sessionId': session,
'installationId': plant, 'issuedAt': now.isoformat(),
'expiresAt': (now + timedelta(seconds=seconds)).isoformat(),
'revision': p['configRevision'], 'family': p['sourceFamily'],
'assetId': request['assetId'], 'managerId': request['managerId'],
'batteryInstanceId': request['batteryInstanceId'],
'maxChargeW': power(request['maxChargeW']),
'maxDischargeW': power(request['maxDischargeW']),
'acceptEstimatedPeak': request['acceptEstimatedPeak'],
'accountingEvidenceId': accounting(p),
'actuatorWatchdogEvidenceId': evidence,
'controlContext': deepcopy(p['controlContext'])}
with store.con:
existing = store.con.execute('SELECT value,revoked_at FROM planner_controlled_trials WHERE plant=?', (plant,)).fetchone()
if existing and existing[1] is None and timestamp(json.loads(existing[0])['expiresAt']) > now:
raise ValueError('Existing trial must first end; implicit extension forbidden')
# Reusing an expired/revoked session ID must never resurrect it.
used = store.con.execute("SELECT 1 FROM planner_audit WHERE plant=? AND kind='trial_arm' AND detail=?", (plant, session)).fetchone()
if used:
raise ValueError('Session ID already used')
store.con.execute('INSERT INTO planner_controlled_trials VALUES(?,?,?,NULL) ON CONFLICT(plant) DO UPDATE SET session_id=excluded.session_id,value=excluded.value,revoked_at=NULL',
(plant, session, json.dumps(value, sort_keys=True, allow_nan=False)))
store.con.execute("INSERT INTO planner_audit(plant,at,kind,detail) VALUES(?,?,'trial_arm',?)", (plant, now.isoformat(), session))
return value
def revoke(store, plant, session, now):
uuid(session)
with store.con:
store.con.execute('UPDATE planner_controlled_trials SET revoked_at=? WHERE plant=? AND session_id=?', (now.isoformat(), plant, session))
return {'status': 'revoked', 'sessionId': session, 'remoteRevocationMaxSeconds': AUTHORITY_TTL_SECONDS}
def authority(store, plant, view, now, allowed_plants):
"""Separate authorization envelope, not a mutation of the shadow plan."""
if plant not in allowed_plants:
return None
row = store.con.execute('SELECT value,revoked_at FROM planner_controlled_trials WHERE plant=?', (plant,)).fetchone()
if not row or row[1] is not None:
return None
grant = json.loads(row[0])
try:
p = eligibility(view, plant)
if not timestamp(grant['issuedAt']) <= now < timestamp(grant['expiresAt']):
return None
if (p['configRevision'] != grant['revision'] or p['sourceFamily'] != grant['family']
or p['controlContext'] != grant['controlContext']
or accounting(p) != grant['accountingEvidenceId']
or p.get('peakCostIsEstimate') and not grant['acceptEstimatedPeak']):
return None
except (ValueError, KeyError, TypeError):
return None
until = min(timestamp(grant['expiresAt']), timestamp(p['validUntil']),
now + timedelta(seconds=AUTHORITY_TTL_SECONDS))
return {**grant, 'kind': 'controlled_trial_authority',
'sourceShadowPlanId': p['planId'], 'checkedAt': now.isoformat(),
'validUntil': until.isoformat(), 'sourcePlanRemainsShadow': True}