Dashboard: - Add Studio page with drag-drop model upload and Claude chat - Add intake system for study creation workflow - Improve session manager and context builder - Add intake API routes and frontend components Optimization Engine: - Add CLI module for command-line operations - Add intake module for study preprocessing - Add validation module with gate checks - Improve Zernike extractor documentation - Update spec models with better validation - Enhance solve_simulation robustness Documentation: - Add ATOMIZER_STUDIO.md planning doc - Add ATOMIZER_UX_SYSTEM.md for UX patterns - Update extractor library docs - Add study-readme-generator skill Tools: - Add test scripts for extraction validation - Add Zernike recentering test Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
58 KiB
Atomizer UX System - Design Document
Version: 1.0
Author: Atomizer Team
Date: January 2026
Status: DESIGN PHASE
Executive Summary
The Atomizer UX System transforms the current ad-hoc study creation process into a streamlined, standardized workflow. Engineers drop files into an intake folder, Claude assembles context from all sources, conducts an intelligent interview (or the user builds visually in Canvas), validates with test trials, runs optimization with real-time monitoring, and produces a professional interactive report.
Key Benefits:
- Reduced friction: Drop files, answer questions, get results
- Standardized process: Consistent study setup across all projects
- Rich context: PDFs, images, and notes all contribute to study configuration
- Validation gate: Catch errors before wasting optimization time
- Professional deliverables: Interactive HTML reports + PDF export
1. System Architecture
1.1 High-Level Flow
┌─────────────────────────────────────────────────────────────────────────────────┐
│ ATOMIZER UX SYSTEM │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ENTRY POINTS │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ CLI │ │ Dashboard │ │ Claude Chat │ │
│ │ atomizer │ │ Browser │ │ Terminal │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ ▼ │
│ ┌───────────┐ │
│ │ INTAKE │ ← Drop files here │
│ └─────┬─────┘ │
│ ▼ │
│ ┌───────────┐ │
│ │ INTROSPECT│ ← Analyze model + run baseline │
│ └─────┬─────┘ │
│ ▼ │
│ ┌───────────┐ │
│ │ ASSEMBLE │ ← Combine all context sources │
│ │ CONTEXT │ │
│ └─────┬─────┘ │
│ │ │
│ ┌───────────┴───────────┐ │
│ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ │
│ │ INTERVIEW │ │ CANVAS │ │
│ │ MODE │ │ MODE │ │
│ └─────┬─────┘ └─────┬─────┘ │
│ │ │ │
│ └───────────┬───────────┘ │
│ ▼ │
│ ┌───────────┐ │
│ │ VALIDATE │ ← Test trials + user approval │
│ └─────┬─────┘ │
│ ▼ │
│ ┌───────────┐ │
│ │ RUN │ ← Dashboard monitoring + LAC recording │
│ └─────┬─────┘ │
│ ▼ │
│ ┌───────────┐ │
│ │ FINALIZE │ ← Interactive report + deliverables │
│ └───────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
1.2 Component Overview
| Component | Purpose | Location |
|---|---|---|
| IntakeProcessor | File organization, validation | optimization_engine/intake/processor.py |
| NXIntrospector | Model analysis, baseline solve | optimization_engine/nx/introspector.py |
| ContextAssembler | Combine all context sources | optimization_engine/intake/context.py |
| PDFExtractor | Extract text from PDFs | optimization_engine/intake/pdf_extractor.py |
| ImageAnalyzer | Analyze images with Claude Vision | optimization_engine/intake/image_analyzer.py |
| StudyInterviewEngine | Q&A study configuration | optimization_engine/interview/engine.py (existing) |
| ValidationGate | Test trials, approval | optimization_engine/validation/gate.py |
| ReportGenerator | HTML/PDF reports | optimization_engine/reporting/html_report.py |
2. Intake System
2.1 Folder Structure
The engineer creates a folder with their project files:
studies/_inbox/{project_name}/
│
├── models/ # REQUIRED - NX model files
│ ├── *.sim # Simulation file (required)
│ ├── *.fem # FEM file
│ ├── *.prt # Geometry part
│ └── *_i.prt # Idealized part (CRITICAL!)
│
├── context/ # OPTIONAL - rich context
│ ├── goals.md # Free-text goals description
│ ├── requirements.pdf # Client specifications
│ ├── constraints.txt # Known limits/constraints
│ ├── sketches/ # Images for Claude to analyze
│ │ └── *.png, *.jpg, *.svg
│ └── reference/ # Any supporting documentation
│ └── *.docx, *.xlsx, *.csv
│
├── data/ # OPTIONAL - baseline/reference data
│ ├── baseline_results.op2 # Existing FEA results
│ ├── material_data.csv # Custom material properties
│ └── previous_study.json # Results from related study
│
└── intake.yaml # OPTIONAL - pre-configuration
2.2 intake.yaml Schema
Pre-configuration file for power users who want to skip interview questions:
# Atomizer Intake Configuration
# All fields are optional - anything not specified goes to interview
study:
name: bracket_mass_opt # Auto-generated from folder if omitted
type: single_objective # single_objective | multi_objective
description: |
Optimize bracket for minimum mass while maintaining structural integrity.
Client requires safety factor of 1.5 on yield stress.
# Objectives - what to optimize
objectives:
primary:
goal: minimize # minimize | maximize
target: mass # mass | displacement | stress | frequency | custom
# For multi-objective only:
# secondary:
# - goal: maximize
# target: stiffness
# - goal: minimize
# target: max_stress
# Constraints - limits that must be respected
constraints:
- type: max_stress
threshold: 250
units: MPa
description: "Von Mises stress limit (SF=1.1 on 275 MPa yield)"
- type: max_displacement
threshold: 0.5
units: mm
description: "Maximum deflection at load point"
# Design variables - parameters to optimize
# If omitted, Claude suggests from introspection
design_variables:
- name: rib_thickness
bounds: [2, 10]
units: mm
description: "Main rib thickness"
- name: flange_width
bounds: [15, 40]
units: mm
description: "Flange width at mounting points"
- name: fillet_radius
bounds: [1, 5]
units: mm
# Optimization budget and strategy
budget:
max_trials: 100
timeout_per_trial: 300 # seconds
target_runtime: 2h # Alternative: specify target runtime
# Algorithm preferences
algorithm:
method: auto # auto | TPE | CMA-ES | NSGA-II
neural_acceleration: false # Enable surrogate model
priority: balanced # speed | accuracy | balanced
# Material information (if not in model)
material:
name: "Aluminum 6061-T6"
yield_stress: 275 # MPa
density: 2700 # kg/m³
# Free-form notes for Claude
notes: |
- Focus optimization on the bracket arms, base is fixed geometry
- Client prefers rib_thickness > 5mm for manufacturing reasons
- Previous study showed fillet_radius has minimal effect
2.3 Pydantic Schema
from pydantic import BaseModel, Field
from typing import Optional, List, Literal, Union
from pathlib import Path
class ObjectiveConfig(BaseModel):
goal: Literal["minimize", "maximize"]
target: str # mass, displacement, stress, frequency, or custom name
weight: float = 1.0
extractor: Optional[str] = None # Custom extractor function
class ConstraintConfig(BaseModel):
type: str # max_stress, max_displacement, min_frequency, etc.
threshold: float
units: str
description: Optional[str] = None
class DesignVariableConfig(BaseModel):
name: str # NX expression name
bounds: tuple[float, float]
units: Optional[str] = None
description: Optional[str] = None
step: Optional[float] = None # For discrete variables
class BudgetConfig(BaseModel):
max_trials: int = 100
timeout_per_trial: int = 300
target_runtime: Optional[str] = None
class AlgorithmConfig(BaseModel):
method: Literal["auto", "TPE", "CMA-ES", "NSGA-II", "random"] = "auto"
neural_acceleration: bool = False
priority: Literal["speed", "accuracy", "balanced"] = "balanced"
class MaterialConfig(BaseModel):
name: str
yield_stress: Optional[float] = None # MPa
density: Optional[float] = None # kg/m³
class StudyConfig(BaseModel):
name: Optional[str] = None
type: Literal["single_objective", "multi_objective"] = "single_objective"
description: Optional[str] = None
class IntakeConfig(BaseModel):
"""Complete intake.yaml schema."""
study: Optional[StudyConfig] = None
objectives: Optional[dict] = None
constraints: Optional[List[ConstraintConfig]] = None
design_variables: Optional[List[DesignVariableConfig]] = None
budget: Optional[BudgetConfig] = None
algorithm: Optional[AlgorithmConfig] = None
material: Optional[MaterialConfig] = None
notes: Optional[str] = None
2.4 Intake CLI Commands
# Process intake folder
atomizer intake bracket_project
# With options
atomizer intake bracket_project --skip-baseline # Don't run baseline solve
atomizer intake bracket_project --interview # Go directly to interview
atomizer intake bracket_project --auto # Full auto-configure
atomizer intake bracket_project --canvas # Open in dashboard canvas
# From within folder
cd studies/_inbox/bracket_project
atomizer intake .
# List pending intakes
atomizer intake --list
# Check intake status
atomizer intake bracket_project --status
3. Introspection System
3.1 Introspection Components
The introspection system analyzes the NX model to discover:
| Component | What it Discovers |
|---|---|
| Part Introspection | Expressions, bodies, mass properties |
| Simulation Introspection | Solutions, BCs, loads, materials, mesh info |
| OP2 Introspection | Available results, subcases |
| Baseline Solve | Actual values (mass, displacement, stress) |
3.2 IntrospectionResult Structure
@dataclass
class IntrospectionResult:
"""Complete model introspection results."""
success: bool
timestamp: datetime
# Part information
expressions: List[ExpressionInfo]
bodies: List[BodyInfo]
mass_properties: MassProperties
# Simulation information
solutions: List[SolutionInfo]
boundary_conditions: List[BCInfo]
loads: List[LoadInfo]
materials: List[MaterialInfo]
mesh_info: MeshInfo
# Results (from OP2 if available)
available_results: Dict[str, bool]
subcases: List[int]
# Baseline solve results
baseline: Optional[BaselineResult]
# Suggestions
suggested_design_variables: List[DVSuggestion]
suggested_objectives: List[ObjectiveSuggestion]
warnings: List[str]
@dataclass
class BaselineResult:
"""Results from baseline solve."""
mass_kg: float
max_displacement_mm: float
max_stress_mpa: float
solve_time_seconds: float
success: bool
3.3 Introspection Output
{
"success": true,
"timestamp": "2026-01-22T14:30:00",
"expressions": [
{
"name": "rib_thickness",
"value": 5.0,
"units": "mm",
"type": "Number",
"formula": null,
"is_design_candidate": true,
"confidence": "high"
},
{
"name": "flange_width",
"value": 25.0,
"units": "mm",
"type": "Number",
"formula": null,
"is_design_candidate": true,
"confidence": "high"
}
],
"baseline": {
"mass_kg": 2.34,
"max_displacement_mm": 0.42,
"max_stress_mpa": 185.3,
"solve_time_seconds": 45.2,
"success": true
},
"suggested_design_variables": [
{
"name": "rib_thickness",
"current_value": 5.0,
"suggested_bounds": [2.5, 10.0],
"units": "mm",
"confidence": "high",
"reason": "Numeric expression with typical design parameter name"
}
]
}
4. Context Assembly
4.1 StudyContext Structure
The ContextAssembler combines all sources into a unified context object:
@dataclass
class StudyContext:
"""Complete context for study creation."""
# === Identity ===
study_name: str
source_folder: Path
created_at: datetime
# === From Introspection ===
introspection: IntrospectionResult
# === From Context Files ===
goals_text: Optional[str] # From goals.md
requirements_text: Optional[str] # Extracted from requirements.pdf
constraints_text: Optional[str] # From constraints.txt
image_analyses: List[ImageAnalysis] # From Claude Vision on sketches/
additional_notes: Optional[str] # From any other text files
# === From intake.yaml ===
preconfig: Optional[IntakeConfig]
# === From LAC (Learning Atomizer Core) ===
similar_studies: List[StudyInsight]
recommended_method: Optional[MethodRecommendation]
known_issues: List[KnownIssue]
user_preferences: List[UserPreference]
# === Derived Suggestions ===
suggested_dvs: List[DesignVariableSuggestion]
suggested_objectives: List[ObjectiveSuggestion]
suggested_constraints: List[ConstraintSuggestion]
suggested_budget: BudgetSuggestion
# === Completion Status ===
ready_for_interview: bool
ready_for_canvas: bool
missing_required: List[str]
warnings: List[str]
4.2 Context Assembly Pipeline
┌─────────────────────────────────────────────────────────────────────────────┐
│ CONTEXT ASSEMBLY PIPELINE │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ INPUT SOURCES │
│ ───────────── │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Model │ │ PDFs │ │ Images │ │ YAML │ │ LAC │ │
│ │ Files │ │ │ │ │ │ │ │ Memory │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │ │ │
│ ▼ ▼ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ NX │ │ PyMuPDF│ │ Claude │ │ Pydantic│ │ Query │ │
│ │Introspect│ │ or │ │ Vision │ │ Parse │ │ Similar │ │
│ │ │ │ Vision │ │ API │ │ │ │ Studies │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │ │ │
│ └───────────┴───────────┴───────────┴───────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ CONTEXT ASSEMBLER │ │
│ │ │ │
│ │ • Merge all sources│ │
│ │ • Resolve conflicts│ │
│ │ • Generate suggest.│ │
│ │ • Check readiness │ │
│ └──────────┬──────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ StudyContext │ │
│ │ │ │
│ │ Ready for: │ │
│ │ • Interview Mode │ │
│ │ • Canvas Mode │ │
│ └─────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
4.3 PDF Processing Strategy
Two-tier approach:
-
Tier 1: PyMuPDF (Fast)
- Extract plain text
- Works for most spec documents
- ~100ms processing time
-
Tier 2: Claude Vision (Smart)
- For complex PDFs with diagrams, tables
- When Tier 1 extraction is poor quality
- When images need analysis
- ~2-5s processing time
def extract_pdf_content(pdf_path: Path) -> PDFContent:
"""Extract content from PDF using tiered approach."""
# Tier 1: Try PyMuPDF first
text = extract_with_pymupdf(pdf_path)
# Check quality
if is_quality_acceptable(text):
return PDFContent(text=text, method="pymupdf")
# Tier 2: Fall back to Vision
images = pdf_to_images(pdf_path)
analysis = analyze_with_vision(images)
return PDFContent(
text=analysis.text,
tables=analysis.tables,
diagrams=analysis.diagrams,
method="vision"
)
4.4 Image Analysis
For images in context/sketches/:
def analyze_image(image_path: Path) -> ImageAnalysis:
"""Analyze image using Claude Vision."""
prompt = """
Analyze this engineering image for an FEA optimization study.
Identify:
1. What type of component/structure is shown
2. Key dimensions or parameters visible
3. Load conditions or constraints indicated
4. Any annotations about design intent
5. Suggestions for optimization parameters
Format as JSON.
"""
response = claude_vision_api(image_path, prompt)
return ImageAnalysis.parse(response)
5. Interview Mode Enhancement
5.1 Enhanced Interview Flow
The interview now leverages StudyContext:
┌─────────────────────────────────────────────────────────────────────────────┐
│ ATOMIZER STUDY INTERVIEW │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░ 40% Complete │
│ │
│ ════════════════════════════════════════════════════════════════════════════│
│ │
│ LOADED CONTEXT: │
│ ┌──────────────────────────────────────────────────────────────────────────┐│
│ │ ✓ Model: bracket_assembly.sim (SOL 101 Static Linear) ││
│ │ ✓ Baseline: mass=2.34kg, disp=0.42mm, stress=185MPa ││
│ │ ✓ Found 12 expressions, 4 design candidates ││
│ │ ✓ goals.md: "minimize mass while maintaining stiffness" ││
│ │ ✓ requirements.pdf: max stress 250 MPa, SF=1.5 ││
│ │ ✓ intake.yaml: 2 constraints pre-configured ││
│ │ ℹ LAC: Similar to "bracket_v2" (converged in 67 trials with TPE) ││
│ └──────────────────────────────────────────────────────────────────────────┘│
│ │
│ ════════════════════════════════════════════════════════════════════════════│
│ │
│ SECTION 2/5: OBJECTIVES │
│ │
│ From your context, I understand: │
│ → Primary goal: Minimize mass (from goals.md) │
│ → Secondary mention: "maintaining stiffness" │
│ │
│ The baseline mass is **2.34 kg**. Does this seem correct for your model? │
│ │
│ [1] Yes, that's correct │
│ [2] No, it should be different (explain) │
│ │
│ ────────────────────────────────────────────────────────────────────────────│
│ │
│ Q: Is this a single-objective or multi-objective problem? │
│ │
│ [1] Single-objective: Minimize mass only │
│ → Stiffness becomes a constraint (max displacement) │
│ [2] Multi-objective: Minimize mass AND maximize stiffness │
│ → Get Pareto front of trade-offs │
│ [3] Let me explain differently... │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
5.2 Pre-filled Answers
If intake.yaml specifies a value, skip that question:
def get_next_question(self) -> Optional[InterviewQuestion]:
"""Get next unanswered question, respecting pre-config."""
for question in self.questions:
if question.answered:
continue
# Check if pre-configured
preconfig_value = self.context.preconfig.get_value(question.key)
if preconfig_value is not None:
# Auto-answer from preconfig
self.answer_question(question.id, preconfig_value, source="preconfig")
continue
return question
return None # Interview complete
5.3 Smart Suggestions
The interview shows intelligent suggestions based on context:
def get_dv_suggestions(self) -> List[DVSuggestion]:
"""Get design variable suggestions with reasoning."""
suggestions = []
# From introspection
for expr in self.context.introspection.suggested_design_variables:
suggestions.append(DVSuggestion(
name=expr.name,
current_value=expr.value,
suggested_bounds=self._calculate_bounds(expr),
confidence=expr.confidence,
reason=f"Numeric expression with value {expr.value} {expr.units}",
source="introspection"
))
# From intake.yaml
if self.context.preconfig and self.context.preconfig.design_variables:
for dv in self.context.preconfig.design_variables:
# Merge or add
existing = next((s for s in suggestions if s.name == dv.name), None)
if existing:
existing.bounds = dv.bounds # Override with user preference
existing.source = "preconfig"
else:
suggestions.append(DVSuggestion(
name=dv.name,
suggested_bounds=dv.bounds,
confidence="high",
reason="Specified in intake.yaml",
source="preconfig"
))
# From LAC (similar studies)
for study in self.context.similar_studies:
for dv in study.design_variables:
existing = next((s for s in suggestions if s.name == dv.name), None)
if existing:
existing.lac_insight = f"Used in {study.name} with success"
return suggestions
6. Validation Gate
6.1 Validation Checks
Before optimization starts:
| Check | Description | Severity |
|---|---|---|
| Schema Valid | atomizer_spec.json passes JSON Schema | ERROR |
| Expressions Exist | All DVs exist as NX expressions | ERROR |
| Bounds Reasonable | Not too wide (>100x) or narrow (<2x) | WARNING |
| Extractors Available | All objective/constraint extractors exist | ERROR |
| Files Complete | All required files present | ERROR |
| No Anti-Patterns | Mass min without constraints, etc. | WARNING |
6.2 Test Trials
Run 2-3 trials before approval:
def run_validation_trials(self, n_trials: int = 3) -> ValidationResult:
"""Run test trials to verify setup."""
results = []
for i in range(n_trials):
# Sample design variables randomly
params = self._sample_random_params()
# Run FEA
trial_result = self.nx_solver.run_simulation(
sim_file=self.spec.model.sim.path,
working_dir=self.working_dir,
expression_updates=params
)
results.append(trial_result)
# Check variance
mass_values = [r.objectives['mass'] for r in results]
mass_variance = np.var(mass_values)
if mass_variance < 1e-6:
return ValidationResult(
passed=False,
error="Results are identical - mesh may not be updating!"
)
return ValidationResult(
passed=True,
trials=results,
variance=mass_variance,
estimated_time=np.mean([r.solve_time for r in results]) * self.spec.optimization.budget.max_trials
)
6.3 Approval Interface
┌─────────────────────────────────────────────────────────────────────────────┐
│ VALIDATION COMPLETE - READY FOR APPROVAL │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ SPEC VALIDATION │
│ ────────────── │
│ ✓ Schema valid │
│ ✓ All 4 expressions exist in model │
│ ✓ All extractors available │
│ ⚠ Bounds for 'fillet_radius' may be narrow (1-5mm = 5x range) │
│ │
│ TEST TRIALS (3 runs) │
│ ──────────────────── │
│ ┌────────┬────────────┬────────────┬────────────┬──────────┐ │
│ │ Trial │ Mass (kg) │ Disp (mm) │ Stress(MPa)│ Time (s) │ │
│ ├────────┼────────────┼────────────┼────────────┼──────────┤ │
│ │ Test 1 │ 2.31 │ 0.44 │ 192 │ 43 │ │
│ │ Test 2 │ 2.28 │ 0.46 │ 178 │ 45 │ │
│ │ Test 3 │ 2.45 │ 0.39 │ 201 │ 44 │ │
│ └────────┴────────────┴────────────┴────────────┴──────────┘ │
│ │
│ VERIFICATION │
│ ──────────── │
│ ✓ Results vary (mass: 2.28-2.45 kg) - parameters updating correctly! │
│ ✓ All extractors working │
│ ✓ Constraints evaluated (all within limits) │
│ ✓ Avg solve time: 44s │
│ │
│ ESTIMATE │
│ ──────── │
│ 100 trials × 44s = ~1h 13m total runtime │
│ │
│ ═══════════════════════════════════════════════════════════════════════════ │
│ │
│ [✓ Approve & Start] [Edit Spec] [Run More Tests] [Cancel] │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
7. Report System
7.1 Report Components
The finalize system generates:
studies/{name}/4_report/
│
├── index.html # Main interactive report
├── report.md # Markdown version
├── report.pdf # PDF export
│
├── figures/
│ ├── convergence.html # Interactive Plotly
│ ├── convergence.png # Static for PDF
│ ├── pareto_front.html # Multi-objective only
│ ├── pareto_front.png
│ ├── parameter_importance.html
│ ├── parameter_importance.png
│ ├── parallel_coordinates.html
│ └── design_comparison.png
│
├── data/
│ ├── all_trials.csv # Complete data
│ ├── all_trials.json
│ ├── pareto_set.json # Multi-objective
│ ├── best_trials.json # Top 10
│ └── summary.json # Key metrics
│
└── deliverables/
├── best_design.prt # NX part with optimal params
├── best_results.op2 # FEA results
├── design_table.xlsx # Formatted for client
└── params_to_apply.json # For applying to new model
7.2 Interactive HTML Report
Features:
- Plotly charts - Zoom, pan, hover for details
- Responsive design - Works on any screen
- Dark/light mode - Toggle for preference
- Export buttons - Download figures, data
- Self-contained - Single HTML file, works offline
7.3 Report Sections
-
Executive Summary
- Key metrics (improvement %, best values)
- Optimization status (converged?)
- Runtime statistics
-
Problem Definition
- Design variables table
- Objectives and constraints
- Model information
-
Convergence Analysis
- Best value over trials
- Moving average
- Convergence detection
-
Results
- Best design parameters
- Pareto front (if multi-objective)
- Top 10 designs table
-
Parameter Analysis
- Importance ranking
- Sensitivity plots
- Correlation matrix
-
Recommendations
- Suggested next steps
- LAC-based insights
- Potential improvements
7.4 Finalize Commands
# Generate report for current study
atomizer finalize bracket_mass_opt
# With options
atomizer finalize bracket_mass_opt --format all # HTML + PDF + MD
atomizer finalize bracket_mass_opt --format html # HTML only
atomizer finalize bracket_mass_opt --include-models # Include .prt in deliverables
atomizer finalize bracket_mass_opt --open # Open in browser when done
# From within study directory
cd studies/bracket_mass_opt
atomizer finalize .
8. Dashboard Integration
8.1 New Study Wizard
Dashboard "New Study" flow:
┌─────────────────────────────────────────────────────────────────────────────┐
│ NEW STUDY WIZARD │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Step 1: Select Source [■■□□□] 20% │
│ ───────────────────── │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ 📁 Browse │ │ 📥 Inbox │ │ ✨ Scratch │ │ │
│ │ │ Folder │ │ Folder │ │ (Empty) │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ │ Select a folder Choose from Start with no │ │
│ │ with your model prepared intakes pre-loaded files │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ [Cancel] [Next →] │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
8.2 Intake Progress
┌─────────────────────────────────────────────────────────────────────────────┐
│ PROCESSING INTAKE │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Source: C:/Projects/bracket_project │
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ✓ Copying model files... [DONE] │ │
│ │ ✓ Parsing intake.yaml... [DONE] │ │
│ │ ✓ Extracting requirements.pdf... [DONE] │ │
│ │ ✓ Analyzing sketches/ (2 images)... [DONE] │ │
│ │ ● Running NX introspection... [IN PROGRESS] │ │
│ │ └─ Opening simulation file │ │
│ │ └─ Querying expressions │ │
│ │ └─ Extracting mesh info │ │
│ │ ○ Running baseline solve... [PENDING] │ │
│ │ ○ Assembling context... [PENDING] │ │
│ │ ○ Generating suggestions... [PENDING] │ │
│ │ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ Elapsed: 1m 23s │
│ │
│ [Cancel] │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
8.3 Report Viewer
Dashboard includes a report viewer component:
┌─────────────────────────────────────────────────────────────────────────────┐
│ 📊 Study Report: bracket_mass_opt [PDF] [Open HTML] │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─ Sidebar ─┐ ┌─────────────────────────────────────────────────────────┐ │
│ │ │ │ │ │
│ │ Summary │ │ EXECUTIVE SUMMARY │ │
│ │ ──────── │ │ │ │
│ │ Problem │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │
│ │ Results │ │ │ 100 │ │ -18%│ │1.92 │ │ 1h │ │ │
│ │ Analysis │ │ │trials│ │impr │ │ kg │ │ 15m │ │ │
│ │ Next Steps│ │ └─────┘ └─────┘ └─────┘ └─────┘ │ │
│ │ │ │ Trials Improve Best Runtime │ │
│ │ │ │ │ │
│ │ │ │ ────────────────────────────────────────────────── │ │
│ │ │ │ │ │
│ │ │ │ [Interactive Convergence Chart - Plotly] │ │
│ │ │ │ │ │
│ └───────────┘ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
8.4 Finalize Button
┌─────────────────────────────────────────────────────────────────────────────┐
│ bracket_mass_opt [⚙️] [📊 Finalize]│
├─────────────────────────────────────────────────────────────────────────────┤
When clicked, shows:
┌─────────────────────────────────────────────────────────────────────────────┐
│ FINALIZE STUDY │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Generate final report and deliverables for: bracket_mass_opt │
│ │
│ Report Options: │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ [✓] Interactive HTML Report │ │
│ │ [✓] PDF Export │ │
│ │ [✓] Markdown Version │ │
│ │ [ ] Include source model files │ │
│ │ [✓] Export best design .prt │ │
│ │ [✓] Generate Excel design table │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
│ Output Location: studies/bracket_mass_opt/4_report/ │
│ │
│ [Cancel] [Generate Report] │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
9. Implementation Phases
Phase 1: Foundation (2-3 days)
| Task | Description | Files |
|---|---|---|
| Create inbox structure | studies/_inbox/ with example |
Directory |
| IntakeConfig schema | Pydantic model for intake.yaml | intake/config.py |
| IntakeProcessor | File copying, validation | intake/processor.py |
| StudyContext | Complete context dataclass | intake/context.py |
| CLI skeleton | atomizer intake command |
cli/intake.py |
Phase 2: Rich Context (2-3 days)
| Task | Description | Files |
|---|---|---|
| PDFExtractor | PyMuPDF integration | intake/pdf_extractor.py |
| ImageAnalyzer | Claude Vision integration | intake/image_analyzer.py |
| ContextAssembler | Merge all sources | intake/assembler.py |
| LAC integration | Query similar studies | intake/lac_query.py |
Phase 3: Interview Enhancement (1-2 days)
| Task | Description | Files |
|---|---|---|
| Context integration | Use StudyContext in interview | interview/engine.py |
| Pre-fill logic | Skip answered questions | interview/prefill.py |
| Rich display | Show baseline, context | interview/presenter.py |
Phase 4: Validation Gate (1-2 days)
| Task | Description | Files |
|---|---|---|
| ValidationChecker | Schema + semantic checks | validation/checker.py |
| TestTrialRunner | Run 2-3 test trials | validation/test_runner.py |
| ValidationGate | Orchestrate + approve | validation/gate.py |
Phase 5: Report System (3-4 days)
| Task | Description | Files |
|---|---|---|
| ReportGenerator | Main generator class | reporting/generator.py |
| HTML template | Jinja2 + Plotly template | reporting/templates/report.html |
| PlotGenerator | Plotly chart generation | reporting/plots.py |
| PDF exporter | HTML to PDF conversion | reporting/pdf_export.py |
| Deliverables bundler | Package best design | reporting/bundler.py |
Phase 6: Dashboard Integration (2-3 days)
| Task | Description | Files |
|---|---|---|
| New Study wizard | Multi-step React component | frontend/src/components/NewStudyWizard.tsx |
| Intake progress | Real-time progress display | frontend/src/components/IntakeProgress.tsx |
| Report viewer | Embedded report display | frontend/src/components/ReportViewer.tsx |
| Finalize button | Trigger report generation | frontend/src/components/FinalizeButton.tsx |
| API endpoints | Backend routes | backend/api/routes/intake.py, report.py |
Phase 7: Polish (1-2 days)
| Task | Description | Files |
|---|---|---|
| User documentation | How-to guides | docs/guides/INTAKE.md |
| Protocol updates | OP_01, OP_08 updates | docs/protocols/operations/ |
| Error handling | Graceful failures | Throughout |
| Testing | Unit + integration tests | tests/ |
10. Success Metrics
User Experience
| Metric | Target | Current |
|---|---|---|
| Time from model to running study | < 15 min | ~45 min |
| Questions in interview | < 10 | ~15-20 |
| Study setup failures | < 5% | ~20% |
| User satisfaction (would use again) | > 90% | TBD |
System Performance
| Metric | Target | Current |
|---|---|---|
| Intake processing time | < 2 min | N/A |
| Introspection time | < 30s | ~20s |
| Report generation time | < 30s | N/A |
| PDF export time | < 10s | N/A |
Quality
| Metric | Target | Current |
|---|---|---|
| Suggested DVs accuracy | > 80% | ~60% |
| Auto-detected constraints | > 50% | ~20% |
| LAC recommendation accuracy | > 70% | TBD |
11. Risks and Mitigations
| Risk | Impact | Mitigation |
|---|---|---|
| PDF extraction fails | Medium | Fall back to manual entry, log for improvement |
| Vision API rate limits | Low | Cache results, batch requests |
| Large model introspection | Medium | Timeout handling, progress display |
| Report generation memory | Low | Stream processing, chunk large data |
| User rejects all suggestions | Low | Allow full manual mode |
12. Future Enhancements
Short-term (3-6 months)
- Voice input: Describe goals by speaking
- Template library: Pre-built configurations for common problems
- Collaborative editing: Multiple users on same study
- Mobile dashboard: View reports on phone
Long-term (6-12 months)
- Auto-iteration: Claude automatically refines study based on results
- Cross-study learning: LAC suggests based on ALL historical studies
- Client portal: Share reports with clients directly
- Integration: Connect to PLM systems (Teamcenter)
Appendix A: File Locations
optimization_engine/
├── intake/
│ ├── __init__.py
│ ├── config.py # IntakeConfig Pydantic model
│ ├── processor.py # IntakeProcessor class
│ ├── context.py # StudyContext dataclass
│ ├── assembler.py # ContextAssembler class
│ ├── pdf_extractor.py # PDF text extraction
│ ├── image_analyzer.py # Claude Vision integration
│ └── lac_query.py # LAC query helpers
│
├── validation/
│ ├── __init__.py
│ ├── checker.py # ValidationChecker
│ ├── test_runner.py # TestTrialRunner
│ └── gate.py # ValidationGate
│
├── reporting/
│ ├── __init__.py
│ ├── generator.py # ReportGenerator
│ ├── plots.py # PlotGenerator
│ ├── pdf_export.py # PDF exporter
│ ├── bundler.py # Deliverables bundler
│ └── templates/
│ ├── report.html # Main Jinja2 template
│ ├── components/ # Reusable HTML components
│ └── styles/ # CSS files
│
└── cli/
├── __init__.py
├── main.py # Main CLI entry point
└── intake.py # atomizer intake command
Appendix B: API Endpoints
POST /api/intake/process # Start intake processing
GET /api/intake/{id}/status # Get intake progress
POST /api/intake/{id}/complete # Mark intake complete
GET /api/studies/{id}/context # Get assembled context
POST /api/studies/{id}/validate # Run validation gate
POST /api/studies/{id}/approve # Approve and start
POST /api/studies/{id}/finalize # Generate report
GET /api/studies/{id}/report # Get report status
GET /api/studies/{id}/report/html # Download HTML
GET /api/studies/{id}/report/pdf # Download PDF
GET /api/studies/{id}/deliverables # Download deliverables ZIP
Document Version: 1.0
Last Updated: January 2026