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>
31 KiB
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:
- Drop files into the dashboard to create a new study
- See introspection results inline (expressions, mass, solver type)
- Open Canvas for detailed configuration (one-click from create card)
- Generate README with Claude (intelligent, not template-based)
- Run baseline solve with real-time progress via WebSocket
- 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:
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:
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
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:
{
"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:
- Create - Creates folder structure + minimal
atomizer_spec.json - Introspect - Runs NX introspection, updates spec with expressions, mass, solver type
- Generate README - Calls Claude with spec + goals.md, returns README + suggested config
- 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:
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:
// 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
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:
- Comprehensive README.md - Not a template, but intelligent documentation
- Suggested design variables - Based on introspection candidates
- Suggested objectives - Based on goals.md or reasonable defaults
- Suggested extractors - Mapped to objectives
- Suggested constraints - If mentioned in goals
5.3 README Structure
- Title & Overview - Study name, description, quick stats
- Optimization Goals - Primary objective, constraints summary
- Model Information - Solver, baseline mass, warnings
- Design Variables - Table with baseline, bounds, units
- Extractors & Objectives - Physics extraction mapping
- Constraints - Limits and thresholds
- Recommended Approach - Algorithm, trial budget
- 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)
- Update
spec_models.pywith new fields (status, IntrospectionData) - Update JSON schema
- Create
spec_manager.pyservice - Create
intake.pyroutes (create, introspect, list, topics) - Register in
main.py - Test with curl/Postman
Phase 2: Claude Integration (Day 1-2)
- Create
study-readme-generator.mdskill - Create
claude_readme.pyservice - Add
/readme/generateendpoint - Test README generation
Phase 3: Frontend Components (Day 2-3)
- Add TypeScript types
- Add API client methods
- Create
TopicSelectorcomponent - Create
IntrospectionResultscomponent - Create
ProgressModalcomponent - Create
CreateStudyCardcomponent - Create
StudyFilesPanelcomponent
Phase 4: Home Page Integration (Day 3)
- Modify
Home.tsxlayout - Integrate
CreateStudyCardabove study list - Add
StudyFilesPanelto study preview - Test full flow
Phase 5: Finalization & WebSocket (Day 4)
- Implement
/finalizeendpoint with baseline solve - Add WebSocket progress updates
- Implement inbox archiving
- End-to-end testing
- 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.jsonis 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