Files
Atomizer/docs/plans/ATOMIZER_UX_SYSTEM.md
Anto01 a26914bbe8 feat: Add Studio UI, intake system, and extractor improvements
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>
2026-01-27 12:02:30 -05:00

58 KiB
Raw Permalink Blame History

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:

  1. Tier 1: PyMuPDF (Fast)

    • Extract plain text
    • Works for most spec documents
    • ~100ms processing time
  2. 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

  1. Executive Summary

    • Key metrics (improvement %, best values)
    • Optimization status (converged?)
    • Runtime statistics
  2. Problem Definition

    • Design variables table
    • Objectives and constraints
    • Model information
  3. Convergence Analysis

    • Best value over trials
    • Moving average
    • Convergence detection
  4. Results

    • Best design parameters
    • Pareto front (if multi-objective)
    • Top 10 designs table
  5. Parameter Analysis

    • Importance ranking
    • Sensitivity plots
    • Correlation matrix
  6. 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