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>
This commit is contained in:
2026-01-27 12:02:30 -05:00
parent 3193831340
commit a26914bbe8
56 changed files with 14173 additions and 646 deletions

View File

@@ -0,0 +1,144 @@
# Atomizer Studio - Technical Implementation Plan
**Version**: 1.0
**Date**: January 24, 2026
**Status**: In Progress
**Author**: Atomizer Team
---
## 1. Executive Summary
**Atomizer Studio** is a unified, drag-and-drop study creation environment that consolidates file management, visual configuration (Canvas), and AI assistance into a single real-time workspace. It replaces the legacy wizard-based approach with a modern "Studio" experience.
### Core Principles
| Principle | Implementation |
|-----------|----------------|
| **Drag & Drop First** | No wizards, no forms. Drop files, see results. |
| **AI-Native** | Claude sees everything: files, parameters, goals. It proposes, you approve. |
| **Zero Commitment** | Work in "Draft Mode" until ready. Nothing is permanent until "Build". |
---
## 2. Architecture
### 2.1 The Draft Workflow
```
User Opens /studio
POST /intake/draft ──► Creates studies/_inbox/draft_{id}/
User Drops Files ──► Auto-Introspection ──► Parameters Discovered
AI Reads Context ──► Proposes Configuration ──► Canvas Updates
User Clicks BUILD ──► Finalize ──► studies/{topic}/{name}/
```
### 2.2 Interface Layout
```
┌───────────────────┬───────────────────────────────────────────────┬───────────────────┐
│ RESOURCES (Left) │ CANVAS (Center) │ ASSISTANT (Right) │
├───────────────────┼───────────────────────────────────────────────┼───────────────────┤
│ ▼ DROP ZONE │ │ │
│ [Drag files] │ ┌───────┐ ┌────────┐ ┌─────────┐ │ "I see you want │
│ │ │ Model ├─────►│ Solver ├─────►│ Extract │ │ to minimize │
│ ▼ MODEL FILES │ └───────┘ └────────┘ └────┬────┘ │ mass. Adding │
│ • bracket.sim │ │ │ objective..." │
│ • bracket.prt │ ┌────▼────┐ │ │
│ │ │ Objectiv│ │ [Apply Changes] │
│ ▼ PARAMETERS │ └─────────┘ │ │
│ • thickness │ │ │
│ • rib_count │ AtomizerSpec v2.0 │ │
│ │ (Draft Mode) │ │
│ ▼ CONTEXT │ │ │
│ • goals.pdf │ │ [ Chat Input... ] │
├───────────────────┼───────────────────────────────────────────────┼───────────────────┤
│ [ Reset Draft ] │ [ Validate ] [ BUILD STUDY ] │ │
└───────────────────┴───────────────────────────────────────────────┴───────────────────┘
```
---
## 3. Implementation Phases
### Phase 1: Backend API Enhancements
- `POST /intake/draft` - Create anonymous draft
- `GET /intake/{id}/context/content` - Extract text from uploaded files
- Enhanced `POST /intake/{id}/finalize` with rename support
### Phase 2: Frontend Studio Shell
- `/studio` route with 3-column layout
- DropZone component with file categorization
- Integrated Canvas in draft mode
- Parameter discovery panel
### Phase 3: AI Integration
- Context-aware chat system
- Spec modification via Claude
- Real-time canvas updates
### Phase 4: Polish & Testing
- Full DevLoop testing
- Edge case handling
- UX polish and animations
---
## 4. File Structure
```
atomizer-dashboard/
├── frontend/src/
│ ├── pages/
│ │ └── Studio.tsx
│ ├── components/
│ │ └── studio/
│ │ ├── StudioLayout.tsx
│ │ ├── ResourcePanel.tsx
│ │ ├── StudioCanvas.tsx
│ │ ├── StudioChat.tsx
│ │ ├── DropZone.tsx
│ │ ├── ParameterList.tsx
│ │ ├── ContextFileList.tsx
│ │ └── BuildDialog.tsx
│ └── hooks/
│ └── useDraft.ts
├── backend/api/
│ └── routes/
│ └── intake.py (enhanced)
```
---
## 5. API Endpoints
### New Endpoints
| Endpoint | Method | Description |
|----------|--------|-------------|
| `/intake/draft` | POST | Create anonymous draft study |
| `/intake/{id}/context/content` | GET | Extract text from context files |
### Enhanced Endpoints
| Endpoint | Change |
|----------|--------|
| `/intake/{id}/finalize` | Added `new_name` parameter for rename |
---
## 6. Status
- [x] Plan documented
- [ ] Phase 1: Backend
- [ ] Phase 2: Frontend Shell
- [ ] Phase 3: AI Integration
- [ ] Phase 4: Testing & Polish

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,637 @@
# Dashboard Intake & AtomizerSpec Integration Plan
**Version**: 1.0
**Author**: Atomizer Team
**Date**: January 22, 2026
**Status**: APPROVED FOR IMPLEMENTATION
**Dependencies**: ATOMIZER_UX_SYSTEM.md, UNIFIED_CONFIGURATION_ARCHITECTURE.md
---
## Executive Summary
This plan implements visual study creation in the Atomizer Dashboard, with `atomizer_spec.json` as the **single source of truth** for all study configuration. Engineers can:
1. **Drop files** into the dashboard to create a new study
2. **See introspection results** inline (expressions, mass, solver type)
3. **Open Canvas** for detailed configuration (one-click from create card)
4. **Generate README with Claude** (intelligent, not template-based)
5. **Run baseline solve** with real-time progress via WebSocket
6. **Finalize** to move study from inbox to studies folder
**Key Principle**: Every operation reads from or writes to `atomizer_spec.json`. Nothing bypasses the spec.
---
## 1. Architecture Overview
### 1.1 AtomizerSpec as Central Data Hub
```
┌─────────────────────────────────────────────────────────────────────────────────┐
│ ATOMIZER_SPEC.JSON - CENTRAL DATA HUB │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ INPUTS (write to spec) SPEC OUTPUTS (read spec) │
│ ┌──────────────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ File Upload │ │ │ │ Canvas Builder │ │
│ │ Introspection │ ────────→ │ atomizer │ ────────→ │ Dashboard Views │ │
│ │ Claude Interview │ │ _spec │ │ Optimization Run │ │
│ │ Canvas Edits │ │ .json │ │ README Generator │ │
│ │ Manual Edit │ │ │ │ Report Generator │ │
│ └──────────────────┘ └──────────┘ └──────────────────┘ │
│ │ │
│ │ validates against │
│ ↓ │
│ ┌──────────────────┐ │
│ │ atomizer_spec │ │
│ │ _v2.json │ │
│ │ (JSON Schema) │ │
│ └──────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
```
### 1.2 Study Creation Flow
```
┌─────────────────────────────────────────────────────────────────────────────────┐
│ STUDY CREATION FLOW │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. DROP FILES 2. INTROSPECT 3. CLAUDE README 4. FINALIZE │
│ ┌────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ .sim .prt │ → │ Expressions │ → │ Analyzes │ → │ Baseline │ │
│ │ .fem _i.prt│ │ Mass props │ │ context+model│ │ solve │ │
│ │ goals.md │ │ Solver type │ │ Writes full │ │ Update │ │
│ └────────────┘ └──────────────┘ │ README.md │ │ README │ │
│ │ │ └──────────────┘ │ Archive │ │
│ ↓ ↓ │ │ inbox │ │
│ Creates initial Updates spec Claude skill └──────────┘ │
│ atomizer_spec.json with introspection for study docs │ │
│ status="draft" status="introspected" ↓ │
│ studies/ │
│ {topic}/ │
│ {name}/ │
└─────────────────────────────────────────────────────────────────────────────────┘
```
### 1.3 Spec Status State Machine
```
draft → introspected → configured → validated → ready → running → completed
│ │ │ │ │ │ │
│ │ │ │ │ │ └─ optimization done
│ │ │ │ │ └─ optimization started
│ │ │ │ └─ can start optimization
│ │ │ └─ baseline solve done
│ │ └─ DVs, objectives, constraints set (Claude or Canvas)
│ └─ introspection done
└─ files uploaded, minimal spec created
```
---
## 2. AtomizerSpec Schema Extensions
### 2.1 New Fields in SpecMeta
Add to `optimization_engine/config/spec_models.py`:
```python
class SpecStatus(str, Enum):
"""Study lifecycle status."""
DRAFT = "draft"
INTROSPECTED = "introspected"
CONFIGURED = "configured"
VALIDATED = "validated"
READY = "ready"
RUNNING = "running"
COMPLETED = "completed"
FAILED = "failed"
class SpecCreatedBy(str, Enum):
"""Who/what created the spec."""
CANVAS = "canvas"
CLAUDE = "claude"
API = "api"
MIGRATION = "migration"
MANUAL = "manual"
DASHBOARD_INTAKE = "dashboard_intake" # NEW
class SpecMeta(BaseModel):
"""Metadata about the spec."""
version: str = Field(..., pattern=r"^2\.\d+$")
study_name: str
created: Optional[datetime] = None
modified: Optional[datetime] = None
created_by: Optional[SpecCreatedBy] = None
modified_by: Optional[str] = None
status: SpecStatus = SpecStatus.DRAFT # NEW
topic: Optional[str] = None # NEW - folder grouping
```
### 2.2 IntrospectionData Model
New model for storing introspection results in the spec:
```python
class ExpressionInfo(BaseModel):
"""Information about an NX expression."""
name: str
value: Optional[float] = None
units: Optional[str] = None
formula: Optional[str] = None
is_candidate: bool = False
confidence: float = 0.0 # 0.0 to 1.0
class BaselineData(BaseModel):
"""Results from baseline FEA solve."""
timestamp: datetime
solve_time_seconds: float
mass_kg: Optional[float] = None
max_displacement_mm: Optional[float] = None
max_stress_mpa: Optional[float] = None
success: bool = True
error: Optional[str] = None
class IntrospectionData(BaseModel):
"""Model introspection results."""
timestamp: datetime
solver_type: Optional[str] = None
mass_kg: Optional[float] = None
volume_mm3: Optional[float] = None
expressions: List[ExpressionInfo] = []
baseline: Optional[BaselineData] = None
warnings: List[str] = []
```
### 2.3 Extended ModelConfig
```python
class ModelConfig(BaseModel):
"""Model file configuration."""
sim: Optional[SimFile] = None
fem: Optional[str] = None
prt: Optional[str] = None
idealized_prt: Optional[str] = None # NEW - critical for mesh updating
introspection: Optional[IntrospectionData] = None # NEW
```
### 2.4 JSON Schema Updates
Add to `optimization_engine/schemas/atomizer_spec_v2.json`:
```json
{
"definitions": {
"SpecMeta": {
"properties": {
"status": {
"type": "string",
"enum": ["draft", "introspected", "configured", "validated", "ready", "running", "completed", "failed"],
"default": "draft"
},
"topic": {
"type": "string",
"pattern": "^[A-Za-z0-9_]+$",
"description": "Topic folder for grouping related studies"
}
}
},
"IntrospectionData": {
"type": "object",
"properties": {
"timestamp": { "type": "string", "format": "date-time" },
"solver_type": { "type": "string" },
"mass_kg": { "type": "number" },
"volume_mm3": { "type": "number" },
"expressions": {
"type": "array",
"items": { "$ref": "#/definitions/ExpressionInfo" }
},
"baseline": { "$ref": "#/definitions/BaselineData" },
"warnings": { "type": "array", "items": { "type": "string" } }
}
},
"ExpressionInfo": {
"type": "object",
"properties": {
"name": { "type": "string" },
"value": { "type": "number" },
"units": { "type": "string" },
"formula": { "type": "string" },
"is_candidate": { "type": "boolean", "default": false },
"confidence": { "type": "number", "minimum": 0, "maximum": 1 }
},
"required": ["name"]
},
"BaselineData": {
"type": "object",
"properties": {
"timestamp": { "type": "string", "format": "date-time" },
"solve_time_seconds": { "type": "number" },
"mass_kg": { "type": "number" },
"max_displacement_mm": { "type": "number" },
"max_stress_mpa": { "type": "number" },
"success": { "type": "boolean", "default": true },
"error": { "type": "string" }
}
}
}
}
```
---
## 3. Backend Implementation
### 3.1 New File: `backend/api/routes/intake.py`
Core intake API endpoints:
| Endpoint | Method | Purpose | Status After |
|----------|--------|---------|--------------|
| `/api/intake/create` | POST | Create inbox folder with initial spec | draft |
| `/api/intake/introspect` | POST | Run NX introspection, update spec | introspected |
| `/api/intake/readme/generate` | POST | Claude generates README + config suggestions | configured |
| `/api/intake/finalize` | POST | Baseline solve, move to studies folder | validated/ready |
| `/api/intake/list` | GET | List inbox folders with status | - |
| `/api/intake/topics` | GET | List existing topic folders | - |
**Key Implementation Details:**
1. **Create** - Creates folder structure + minimal `atomizer_spec.json`
2. **Introspect** - Runs NX introspection, updates spec with expressions, mass, solver type
3. **Generate README** - Calls Claude with spec + goals.md, returns README + suggested config
4. **Finalize** - Full workflow: copy files, baseline solve (optional), move to studies, archive inbox
### 3.2 New File: `backend/api/services/spec_manager.py`
Centralized spec operations:
```python
class SpecManager:
"""Single source of truth for spec operations."""
def load(self) -> dict
def save(self, spec: dict) -> None
def update_status(self, status: str, modified_by: str) -> dict
def add_introspection(self, data: dict) -> dict
def get_status(self) -> str
def exists(self) -> bool
```
### 3.3 New File: `backend/api/services/claude_readme.py`
Claude-powered README generation:
- Loads skill from `.claude/skills/modules/study-readme-generator.md`
- Builds prompt with spec + goals
- Returns README content + suggested DVs/objectives/constraints
- Uses Claude API (claude-sonnet-4-20250514)
### 3.4 WebSocket for Finalization Progress
The `/api/intake/finalize` endpoint will support WebSocket for real-time progress:
```typescript
// Progress steps
const steps = [
'Creating study folder',
'Copying model files',
'Running introspection',
'Running baseline solve',
'Extracting baseline results',
'Generating README with Claude',
'Moving to studies folder',
'Archiving inbox'
];
```
---
## 4. Frontend Implementation
### 4.1 Component Structure
```
frontend/src/components/home/
├── CreateStudyCard.tsx # Main study creation UI
├── IntrospectionResults.tsx # Display introspection data
├── TopicSelector.tsx # Topic dropdown + new topic input
├── StudyFilesPanel.tsx # File display in preview
└── index.ts # Exports
frontend/src/components/common/
└── ProgressModal.tsx # Finalization progress display
```
### 4.2 CreateStudyCard States
```typescript
type CardState =
| 'empty' // No files, just showing dropzone
| 'staged' // Files selected, ready to upload
| 'uploading' // Uploading files to inbox
| 'introspecting' // Running introspection
| 'ready' // Introspection done, can finalize or open canvas
| 'finalizing' // Running finalization
| 'complete'; // Study created, showing success
```
### 4.3 CreateStudyCard UI
```
╔═══════════════════════════════════════════════════════════════╗
║ + Create New Study [Open Canvas] ║
╠═══════════════════════════════════════════════════════════════╣
║ ║
║ Study Name ║
║ ┌─────────────────────────────────────────────────────────┐ ║
║ │ bracket_optimization_v1 │ ║
║ └─────────────────────────────────────────────────────────┘ ║
║ ║
║ Topic ║
║ ┌─────────────────────────────────────────────────────────┐ ║
║ │ M1_Mirror ▼ │ ║
║ └─────────────────────────────────────────────────────────┘ ║
║ ○ Brackets ○ M1_Mirror ○ Support_Arms ● + New Topic ║
║ ║
║ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ ║
║ │ 📁 Drop model files here │ ║
║ │ .sim .prt .fem _i.prt │ ║
║ │ or click to browse │ ║
║ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ ║
║ ║
║ Files [Clear] ║
║ ┌─────────────────────────────────────────────────────────┐ ║
║ │ ✓ bracket_sim1.sim 1.2 MB │ ║
║ │ ✓ bracket.prt 3.4 MB │ ║
║ │ ✓ bracket_fem1.fem 2.1 MB │ ║
║ │ ✓ bracket_fem1_i.prt 0.8 MB ← Idealized! │ ║
║ └─────────────────────────────────────────────────────────┘ ║
║ ║
║ ▼ Model Information ✓ Ready ║
║ ┌─────────────────────────────────────────────────────────┐ ║
║ │ Solver: NX Nastran │ ║
║ │ Estimated Mass: 2.34 kg │ ║
║ │ │ ║
║ │ Design Variable Candidates (5 found): │ ║
║ │ ★ rib_thickness = 5.0 mm [2.5 - 10.0] │ ║
║ │ ★ web_height = 20.0 mm [10.0 - 40.0] │ ║
║ │ ★ flange_width = 15.0 mm [7.5 - 30.0] │ ║
║ └─────────────────────────────────────────────────────────┘ ║
║ ║
║ ┌─────────────────────────────────────────────────────────┐ ║
║ │ ☑ Run baseline solve (recommended for accurate values) │ ║
║ │ ☑ Generate README with Claude │ ║
║ └─────────────────────────────────────────────────────────┘ ║
║ ║
║ [ Finalize Study ] [ Open Canvas → ] ║
║ ║
╚═══════════════════════════════════════════════════════════════╝
```
### 4.4 ProgressModal UI
```
╔════════════════════════════════════════════════════════════════╗
║ Creating Study [X] ║
╠════════════════════════════════════════════════════════════════╣
║ ║
║ bracket_optimization_v1 ║
║ Topic: M1_Mirror ║
║ ║
║ ┌──────────────────────────────────────────────────────────┐ ║
║ │ │ ║
║ │ ✓ Creating study folder 0.5s │ ║
║ │ ✓ Copying model files 1.2s │ ║
║ │ ✓ Running introspection 3.4s │ ║
║ │ ● Running baseline solve... │ ║
║ │ ├─ Updating parameters │ ║
║ │ ├─ Meshing... │ ║
║ │ └─ Solving (iteration 2/5) │ ║
║ │ ○ Extracting baseline results │ ║
║ │ ○ Generating README with Claude │ ║
║ │ ○ Moving to studies folder │ ║
║ │ ○ Archiving inbox │ ║
║ │ │ ║
║ └──────────────────────────────────────────────────────────┘ ║
║ ║
║ [━━━━━━━━━━━━━━━━░░░░░░░░░░░░░░░░░░░] 42% ║
║ ║
║ Estimated time remaining: ~45 seconds ║
║ ║
╚════════════════════════════════════════════════════════════════╝
```
### 4.5 StudyFilesPanel (in Preview)
```
┌────────────────────────────────────────────────────────────────┐
│ 📁 Model Files (4) [+ Add] [↗] │
├────────────────────────────────────────────────────────────────┤
│ 📦 bracket_sim1.sim 1.2 MB Simulation │
│ 📐 bracket.prt 3.4 MB Geometry │
│ 🔷 bracket_fem1.fem 2.1 MB FEM │
│ 🔶 bracket_fem1_i.prt 0.8 MB Idealized Part │
└────────────────────────────────────────────────────────────────┘
```
---
## 5. Claude Skill for README Generation
### 5.1 Skill Location
`.claude/skills/modules/study-readme-generator.md`
### 5.2 Skill Purpose
Claude analyzes the AtomizerSpec and generates:
1. **Comprehensive README.md** - Not a template, but intelligent documentation
2. **Suggested design variables** - Based on introspection candidates
3. **Suggested objectives** - Based on goals.md or reasonable defaults
4. **Suggested extractors** - Mapped to objectives
5. **Suggested constraints** - If mentioned in goals
### 5.3 README Structure
1. **Title & Overview** - Study name, description, quick stats
2. **Optimization Goals** - Primary objective, constraints summary
3. **Model Information** - Solver, baseline mass, warnings
4. **Design Variables** - Table with baseline, bounds, units
5. **Extractors & Objectives** - Physics extraction mapping
6. **Constraints** - Limits and thresholds
7. **Recommended Approach** - Algorithm, trial budget
8. **Files** - Model file listing
---
## 6. Home Page Integration
### 6.1 Layout
```
┌──────────────────────────────────────────────────────────────────┐
│ [Logo] [Canvas Builder] [Refresh] │
├──────────────────────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Studies │ │ Running │ │ Trials │ │ Best │ │
│ │ 15 │ │ 2 │ │ 1,234 │ │ 2.34e-3 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
├─────────────────────────────┬────────────────────────────────────┤
│ ┌─────────────────────────┐ │ Study Preview │
│ │ + Create New Study │ │ ┌────────────────────────────────┐ │
│ │ │ │ │ 📁 Model Files (4) [+] │ │
│ │ [CreateStudyCard] │ │ │ (StudyFilesPanel) │ │
│ │ │ │ └────────────────────────────────┘ │
│ └─────────────────────────┘ │ │
│ │ README.md │
│ Studies (15) │ (MarkdownRenderer) │
│ ▶ M1_Mirror (5) │ │
│ ▶ Brackets (3) │ │
│ ▼ Other (2) │ │
│ └─ test_study ● Running │ │
└─────────────────────────────┴────────────────────────────────────┘
```
---
## 7. File Changes Summary
| File | Action | Est. Lines |
|------|--------|------------|
| **Backend** | | |
| `backend/api/routes/intake.py` | CREATE | ~350 |
| `backend/api/services/spec_manager.py` | CREATE | ~80 |
| `backend/api/services/claude_readme.py` | CREATE | ~150 |
| `backend/api/main.py` | MODIFY | +5 |
| **Schema/Models** | | |
| `optimization_engine/config/spec_models.py` | MODIFY | +60 |
| `optimization_engine/schemas/atomizer_spec_v2.json` | MODIFY | +50 |
| **Frontend** | | |
| `frontend/src/components/home/CreateStudyCard.tsx` | CREATE | ~400 |
| `frontend/src/components/home/IntrospectionResults.tsx` | CREATE | ~120 |
| `frontend/src/components/home/TopicSelector.tsx` | CREATE | ~80 |
| `frontend/src/components/home/StudyFilesPanel.tsx` | CREATE | ~100 |
| `frontend/src/components/common/ProgressModal.tsx` | CREATE | ~150 |
| `frontend/src/pages/Home.tsx` | MODIFY | +80 |
| `frontend/src/api/client.ts` | MODIFY | +100 |
| `frontend/src/types/atomizer-spec.ts` | MODIFY | +40 |
| **Skills** | | |
| `.claude/skills/modules/study-readme-generator.md` | CREATE | ~120 |
**Total: ~1,885 lines**
---
## 8. Implementation Order
### Phase 1: Backend Foundation (Day 1)
1. Update `spec_models.py` with new fields (status, IntrospectionData)
2. Update JSON schema
3. Create `spec_manager.py` service
4. Create `intake.py` routes (create, introspect, list, topics)
5. Register in `main.py`
6. Test with curl/Postman
### Phase 2: Claude Integration (Day 1-2)
1. Create `study-readme-generator.md` skill
2. Create `claude_readme.py` service
3. Add `/readme/generate` endpoint
4. Test README generation
### Phase 3: Frontend Components (Day 2-3)
1. Add TypeScript types
2. Add API client methods
3. Create `TopicSelector` component
4. Create `IntrospectionResults` component
5. Create `ProgressModal` component
6. Create `CreateStudyCard` component
7. Create `StudyFilesPanel` component
### Phase 4: Home Page Integration (Day 3)
1. Modify `Home.tsx` layout
2. Integrate `CreateStudyCard` above study list
3. Add `StudyFilesPanel` to study preview
4. Test full flow
### Phase 5: Finalization & WebSocket (Day 4)
1. Implement `/finalize` endpoint with baseline solve
2. Add WebSocket progress updates
3. Implement inbox archiving
4. End-to-end testing
5. Documentation updates
---
## 9. Validation Gate Integration
The Validation Gate runs 2-3 test trials before full optimization to catch:
- Mesh not updating (identical results)
- Extractor failures
- Constraint evaluation errors
**Integration point**: After study is finalized, before optimization starts, a "Validate" button appears in the study preview that runs the gate.
---
## 10. Success Criteria
- [ ] User can create study by dropping files in dashboard
- [ ] Introspection runs automatically after upload
- [ ] Introspection results show inline with design candidates highlighted
- [ ] "Open Canvas" button works, loading spec into canvas
- [ ] Claude generates comprehensive README from spec + goals
- [ ] Baseline solve runs with WebSocket progress display
- [ ] Study moves to correct topic folder
- [ ] Inbox folder is archived after success
- [ ] `atomizer_spec.json` is the ONLY configuration file used
- [ ] Spec status updates correctly through workflow
- [ ] Canvas can load and edit spec from inbox (pre-finalization)
---
## 11. Error Handling
### Baseline Solve Failure
If baseline solve fails:
- Still create the study
- Set `spec.meta.status = "configured"` (not "validated")
- Store error in `spec.model.introspection.baseline.error`
- README notes baseline was attempted but failed
- User can retry baseline later or proceed without it
### Missing Idealized Part
If `*_i.prt` is not found:
- Add CRITICAL warning to introspection
- Highlight in UI with warning icon
- Still allow study creation (user may add later)
- README includes warning about mesh not updating
### Introspection Failure
If NX introspection fails:
- Store error in spec
- Allow manual configuration via Canvas
- User can retry introspection after fixing issues
---
## 12. Future Enhancements (Out of Scope)
- PDF extraction with Claude Vision
- Image analysis for sketches in context/
- Batch study creation (multiple studies at once)
- Study templates from existing studies
- Auto-retry failed baseline with different parameters
---
*Document created: January 22, 2026*
*Approved for implementation*

View File

@@ -110,31 +110,48 @@ frequency = result['frequency'] # Hz
```python
from optimization_engine.extractors.extract_von_mises_stress import extract_solid_stress
# For shell elements (CQUAD4, CTRIA3)
result = extract_solid_stress(op2_file, subcase=1, element_type='cquad4')
# RECOMMENDED: Check ALL solid element types (returns max across all)
result = extract_solid_stress(op2_file, subcase=1)
# For solid elements (CTETRA, CHEXA)
result = extract_solid_stress(op2_file, subcase=1, element_type='ctetra')
# Or specify single element type
result = extract_solid_stress(op2_file, subcase=1, element_type='chexa')
# Returns: {
# 'max_von_mises': float, # MPa
# 'max_stress_element': int
# 'max_von_mises': float, # MPa (auto-converted from kPa)
# 'max_stress_element': int,
# 'element_type': str, # e.g., 'CHEXA', 'CTETRA'
# 'units': 'MPa'
# }
max_stress = result['max_von_mises'] # MPa
```
**IMPORTANT (Updated 2026-01-22):**
- By default, checks ALL solid types: CTETRA, CHEXA, CPENTA, CPYRAM
- CHEXA elements often have highest stress (not CTETRA!)
- Auto-converts from kPa to MPa (NX kg-mm-s unit system outputs kPa)
- Returns Elemental Nodal stress (peak), not Elemental Centroid (averaged)
### E4: BDF Mass Extraction
**Module**: `optimization_engine.extractors.bdf_mass_extractor`
**Module**: `optimization_engine.extractors.extract_mass_from_bdf`
```python
from optimization_engine.extractors.bdf_mass_extractor import extract_mass_from_bdf
from optimization_engine.extractors import extract_mass_from_bdf
mass_kg = extract_mass_from_bdf(str(bdf_file)) # kg
result = extract_mass_from_bdf(bdf_file)
# Returns: {
# 'total_mass': float, # kg (primary key)
# 'mass_kg': float, # kg
# 'mass_g': float, # grams
# 'cg': [x, y, z], # center of gravity
# 'num_elements': int
# }
mass_kg = result['mass_kg'] # kg
```
**Note**: Reads mass directly from BDF/DAT file material and element definitions.
**Note**: Uses `BDFMassExtractor` internally. Reads mass from element geometry and material density in BDF/DAT file. NX kg-mm-s unit system - mass is directly in kg.
### E5: CAD Expression Mass