Add domain CRUD, energy density constraint, LLM status, reset results, score display fixes
Domain management: - Add domain list/detail/form templates and full CRUD routes (domains.py) - Add metric bound add/edit/delete via HTMX partials (_metrics_table.html) Energy density constraint (Rule 6 in ConstraintResolver): - Hard-block combos where power source provides <25% of platform's required Wh/kg - Warn (conditional) when under-density but within 4x - Solar Sail exempt (no stored energy); Airplane requires 400 Wh/kg, Spaceship 2000 Wh/kg - Add energy_density_wh_kg provides to all 8 stored-energy power sources in seed data - 3 new constraint resolver tests LLM-complete status: - Pipeline Pass 4 now sets combo status to llm_reviewed after successful LLM review - update_combination_status guards against downgrading: scored won't overwrite llm_reviewed or reviewed; llm_reviewed won't overwrite reviewed - Add badge-llm_reviewed CSS style (light blue) Reset results: - Repository.reset_domain_results() deletes combination_results, combination_scores, and pipeline_runs for a domain; pipeline re-evaluates on next run - POST /results/<domain>/reset route with flash confirmation - "Reset results" danger button with JS confirm dialog in results list Fix composite score 0 displaying as --- (Jinja2 falsy 0.0 bug): - Change `if r.composite_score` to `if r.composite_score is not none` Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -42,6 +42,7 @@ class ConstraintResolver:
|
||||
self._check_mutual_exclusion(all_deps, result)
|
||||
self._check_range_incompatibility(all_deps, result)
|
||||
self._check_force_scale(combination, result)
|
||||
self._check_energy_density(combination, result)
|
||||
self._check_unmet_requirements(all_deps, result)
|
||||
|
||||
if result.violations:
|
||||
@@ -155,6 +156,40 @@ class ConstraintResolver:
|
||||
f"(under-powered)"
|
||||
)
|
||||
|
||||
def _check_energy_density(
|
||||
self, combination: Combination, result: ConstraintResult
|
||||
) -> None:
|
||||
"""Rule 6: If power source energy density << platform minimum → warn/block.
|
||||
|
||||
Uses a 25% threshold: below 25% of required → hard block (> 4x deficit).
|
||||
"""
|
||||
density_provided: list[tuple[str, float]] = []
|
||||
density_required: list[tuple[str, float]] = []
|
||||
|
||||
for entity in combination.entities:
|
||||
for dep in entity.dependencies:
|
||||
if dep.key == "energy_density_wh_kg" and dep.constraint_type == "provides":
|
||||
density_provided.append((entity.name, float(dep.value)))
|
||||
elif dep.key == "energy_density_wh_kg" and dep.constraint_type == "range_min":
|
||||
density_required.append((entity.name, float(dep.value)))
|
||||
|
||||
for req_name, req_density in density_required:
|
||||
if not density_provided:
|
||||
continue # No stored energy source in this combo — skip check
|
||||
for prov_name, prov_density in density_provided:
|
||||
if prov_density < req_density * 0.25:
|
||||
result.violations.append(
|
||||
f"{prov_name} provides {prov_density:.0f} Wh/kg but "
|
||||
f"{req_name} requires {req_density:.0f} Wh/kg "
|
||||
f"(energy density deficit > 4x)"
|
||||
)
|
||||
elif prov_density < req_density:
|
||||
result.warnings.append(
|
||||
f"{prov_name} provides {prov_density:.0f} Wh/kg but "
|
||||
f"{req_name} requires {req_density:.0f} Wh/kg "
|
||||
f"(under-density)"
|
||||
)
|
||||
|
||||
def _check_unmet_requirements(
|
||||
self, all_deps: list[tuple[str, Dependency]], result: ConstraintResult
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user