> For the complete documentation index, see [llms.txt](https://docs.openbrim.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.openbrim.org/developers/llm-guides/ai-paramml-readme.md).

# ParamML README

## Overview

You are working with **OpenBrIM's Parametric Engine (ParamML)**, a powerful XML-based parametric modeling system for bridge engineering and infrastructure projects. This system enables the creation of intelligent, data-driven bridge components through parametric expressions, inheritance, and lazy evaluation.

## What is ParamML?

ParamML (Parametric Markup Language) is an XML-based language that defines:

* **Parametric Objects**: Hierarchical objects with parameters and expressions
* **Library Components**: Reusable templates for bridge elements (girders, columns, decks, etc.)
* **3D Geometry**: Points, Lines, Surfaces, and Volumes
* **FEA Models**: Finite Element Analysis meshes and boundary conditions
* **Code Checks**: Design verification and compliance calculations
* **Reports**: Automated documentation and analysis results

## File Structure

When you download a branch, you'll receive:

### 1. Branch XML Files (Main Objects)

* `ObjectName.xml` - The library objects you're working on
* These are the objects that were modified or developed in this branch

### 2. Dependency XML Files (Referenced Objects)

* `__dep__ObjectName.xml` - Library objects that are referenced by your main objects
* Prefixed with `__dep__` to distinguish them from your working files
* These are automatically downloaded based on the `subobjtypes` (object type references) in your main objects
* **Example**: If your girder object uses a `StandardSection` object, `__dep__StandardSection.xml` will be downloaded

### 3. AI Documentation Files (.md)

These are guides to help you understand and work with the ParamML system:

**Core Guides (Read These First):**

* `AI-Parametric-Engine-Guide.md` - **ESSENTIAL - Read FIRST**
  * Explains Objects, Parameters, Expressions, Lazy Evaluation
  * Covers Repeat loops, Guards, Library Objects, Export objects
  * Distance-based parameter resolution
  * Performance optimization patterns
* `AI-ParamML-Functions-Reference.md` - **Function library reference**
  * Mathematical, geometric, and alignment functions
  * Array operations (map, filter, reduce)
  * String manipulation and utility functions

**Task-Specific Guides (Read When Needed):**

* `AI-FEA-Guide.md` - Finite Element Analysis
  * FENode, FELine, FESurf element types
  * Boundary conditions, loads, analysis cases
  * Mesh generation and node merging
* `AI-3D-Visualization-Guide.md` - 3D Geometry
  * Point, Line, Surface, Volume primitives
  * Texture mapping and materials
  * Parametric shapes and extrusions
* `AI-Bridge-Alignment-Guide.md` - Bridge Alignments
  * Horizontal and vertical alignment functions
  * Superelevation and cross-slope
  * Station-based positioning

## Key Concepts (Quick Reference)

### 1. XML Object Structure

```xml
<O N="ObjectName" T="ObjectType">
  <P N="ParameterName" V="Expression" Role="Input" UT="Length"/>
  <!-- Child objects -->
</O>
```

### 2. Parameter Roles

* `Role="Input"` - User-editable, automatically exported (accessible to other objects)
* `Role="Private"` - Internal calculations, not exported
* No role - Private by default

### 3. Export Objects

To export computed parameters, place them inside `<O T="Export">` containers. Parameters inside Export objects are automatically accessible to other objects.

**Important Dependency Rule:** If an exported parameter depends on other parameters, those dependencies must also be exported OR have `Role="Input"`.

**Naming Export Objects:** Export objects can have names (e.g., `<O N="MyExport" T="Export">`). This is useful when extending objects, as named Export groups can be overridden with `Override="1"`.

```xml
<!-- ❌ WRONG - param3 depends on non-exported parameters -->
<O T="Group">
  <P N="param1" V="12"/>
  <P N="param2" V="13"/>
</O>
<O T="Export">
  <P N="param3" V="param1+param2"/>  <!-- ERROR: param1, param2 not accessible -->
</O>

<!-- ✅ CORRECT - Option 1: Put dependencies in Export (with name for override) -->
<O N="Calculations" T="Export">
  <P N="param1" V="12"/>
  <P N="param2" V="13"/>
  <P N="param3" V="param1+param2"/>
</O>

<!-- ✅ CORRECT - Option 2: Use Role="Input" for dependencies -->
<O T="Group">
  <P N="param1" V="12" Role="Input"/>
  <P N="param2" V="13" Role="Input"/>
</O>
<O T="Export">
  <P N="param3" V="param1+param2"/>
</O>

<!-- Override Export in extended object -->
<O N="DerivedObject" T="Project" Extends="BaseObject">
  <O N="Calculations" T="Export" Override="1">
    <P N="param1" V="100"/>  <!-- Override values -->
    <P N="param3" V="param1*param2"/>  <!-- Override formula -->
  </O>
</O>
```

**For more details:** See `AI-Export.md`

### 4. Library Objects (Templates)

```xml
<O N="MyLibraryObject" T="Project" Tags="@library" ObjLabel="Display Name">
  <!-- Input parameters - automatically exported -->
  <P N="Width" V="24" Role="Input"/>
  <P N="Height" V="12" Role="Input"/>

  <!-- Export computed results -->
  <O N="Results" T="Export">
    <P N="Area" V="Width*Height"/>  <!-- Can access Input parameters -->
  </O>
</O>

<!-- Use the template -->
<O N="Instance1" T="MyLibraryObject">
  <P N="Width" V="30"/>  <!-- Override -->
</O>
```

### 5. Extending Objects

Use `Extends` attribute to inherit from other objects. For multiple inheritance, use array syntax.

```xml
<!-- Single inheritance -->
<O N="DerivedObject" T="Project" Extends="BaseObject">
  <P N="Width" V="50"/>  <!-- Override parent parameter -->
</O>

<!-- Multiple inheritance -->
<O N="CombinedObject" T="Project" Extends="[BaseObject1,BaseObject2]">
  <!-- Inherits from both objects -->
</O>
```

### 6. Object References

* `@ObjectName|ObjectType` - Reference by name and type
* `ObjectName.ParameterName` - Access object parameters
* `RepeatName[i].ParameterName` - Array access in Repeat loops
* `RepeatName[i-1].ParameterName` - Access previous iteration

### 7. Coordinate Format

**ALWAYS use inline X-Y-Z attributes (no spaces in expressions):**

```xml
<!-- ✅ CORRECT -->
<O T="Point" N="Pt" X="i*10" Y="0" Z="0" />
<O T="FENode" N="NODE" X="j*120" Y="i*120" Z="0">
  <P N="Tz" V="1"/>
</O>

<!-- ❌ WRONG (nested P elements, spaces in math) -->
<O T="Point" N="Pt">
  <P N="X" V="i * 10"/>
  <P N="Y" V="0"/>
  <P N="Z" V="0"/>
</O>
```

### 8. Repeat Loops

```xml
<O T="Repeat" N="Points" S="0" E="10" I="1" CTRL="i" i="0">
  <O T="Point" N="Pt" X="i*12" Y="0" Z="0" />
</O>

<!-- Access previous element -->
<O T="Repeat" N="Segments" S="0" E="5" I="1" CTRL="i" i="0">
  <O T="Segment" N="Seg">
    <P N="StartX" V="i > 0 ? Segments[i-1].EndX : 0"/>
  </O>
</O>
```

### 9. Performance Rules

* **Use Repeat ONLY for creating objects** (Points, Lines, FENodes, etc.)
* **Use map() for data transformations** - 100x faster than Repeat
* **Use filter() for selecting subsets**
* **Use reduce() for aggregations**

```xml
<!-- ✅ CORRECT -->
<P N="Results" V="map(InputList, x => x * 2)"/>

<!-- ❌ WRONG (creates unnecessary objects) -->
<O T="Repeat" N="Loop" S="0" E="99">
  <P N="Result" V="InputList[i] * 2"/>
</O>
```

## Working with This Code

### Step 1: Read Documentation Guides

**Before starting any task**, read the relevant AI guides:

1. **Always read first**: `AI-Parametric-Engine-Guide.md` (core foundation)
2. If working with FEA: `AI-FEA-Guide.md`
3. If using functions: `AI-ParamML-Functions-Reference.md`
4. If working with 3D geometry: `AI-3D-Visualization-Guide.md`
5. If working with alignments: `AI-Bridge-Alignment-Guide.md`

### Step 2: Understand the Object Type

* **Library Objects**: `T="Project"` with Tags - reusable templates
* **Geometry**: Point, Line, Surface, Volume
* **FEA**: FENode, FELine, FESurf, FEGroup
* **Structural**: Girder, Column, Deck, Bearing
* **Analysis**: AnalysisCase, LoadCase, LoadCombination

### Step 3: Follow XML Formatting Standards

* Use inline X-Y-Z attributes for coordinates
* No spaces around operators in expressions (e.g., `i*12` not `i * 12`)
* Self-closing tags when no children: `<O T="Point" .../>`
* Comments for clarity: `<!-- Description -->`

### Step 4: Parameter Best Practices

* Use `Role="Input"` for user-editable values (automatically exported)
* Place computed results inside `<O T="Export">` containers
* Include `UT` (UnitType) for engineering values
* Add `D` (Description) for documentation
* Ensure exported parameters only depend on other exported params or `Role="Input"` params

### Step 5: Test Expressions

* All expressions use JavaScript syntax
* Lazy evaluation - computed only when needed
* Ternary operators: `condition ? trueValue : falseValue`
* Math functions: `sin()`, `cos()`, `sqrt()`, `abs()`, etc.
* Array functions: `map()`, `filter()`, `reduce()`, `sum()`, `max()`, `min()`

## Common Patterns

### Creating Library Components

```xml
<O N="StandardGirder" T="Project"
   Tags="@library,structural,girder"
   ObjLabel="Standard Steel Girder"
   Category="Structural Components:Girders">

  <!-- Inputs - automatically exported -->
  <P N="Span" V="120" Role="Input" UT="Length"/>
  <P N="Depth" V="72" Role="Input" UT="Length"/>

  <!-- Internal calculations (private, not exported) -->
  <P N="SectionModulus" V="Depth^3/6"/>

  <!-- Export results - can access Role="Input" parameters -->
  <O T="Export">
    <P N="Weight" V="Span*Depth*0.49" UT="Force"/>

    <!-- Export geometry -->
    <O T="Line" N="Geometry">
      <O T="Point" X="0" Y="0" Z="0"/>
      <O T="Point" X="Span" Y="0" Z="0"/>
    </O>
  </O>
</O>
```

### FEA Mesh Generation

```xml
<!-- Node grid -->
<O T="Repeat" N="NodeRows" S="0" E="3" I="1" CTRL="i" i="0">
  <O T="Repeat" N="NodeCols" S="0" E="3" I="1" CTRL="j" j="0">
    <O T="FENode" N="NODE" X="j*120" Y="i*120" Z="0">
      <P N="Tz" V="(i==0 || i==3) ? 1 : 0"/>  <!-- Pin edges -->
    </O>
  </O>
</O>

<!-- Elements -->
<O T="Repeat" N="ElemRows" S="0" E="2" I="1" CTRL="i" i="0">
  <O T="Repeat" N="ElemCols" S="0" E="2" I="1" CTRL="j" j="0">
    <O T="FESurfMITC4" N="SHELL">
      <P N="Node1" V="@NODE_{i}_{j}|FENode"/>
      <P N="Node2" V="@NODE_{i}_{j+1}|FENode"/>
      <P N="Node3" V="@NODE_{i+1}_{j+1}|FENode"/>
      <P N="Node4" V="@NODE_{i+1}_{j}|FENode"/>
    </O>
  </O>
</O>
```

### Alignment-Based Positioning

```xml
<O T="Point" N="BridgePoint"
   X="alignHX(Centerline, Station, Offset)"
   Y="alignHY(Centerline, Station, Offset)"
   Z="alignV(Centerline, Station)+alignT(Centerline, Station, Offset)">
  <P N="Station" V="100" Role="Input"/>
  <P N="Offset" V="10" Role="Input"/>
</O>
```

### Referencing Objects Pattern (Bidirectional References)

Use this pattern to create automatic two-way references between parent and child objects.

**Use Cases:**

* Girder → Cross Frames (bracings)
* Pier Column → Foundation
* Deck → Barrier

```xml
<!-- PARENT: Girder -->
<O N="OBPBase_Girder" T="Project">
    <O N="Referencing Objects" T="Group">
        <P N="bracings" V="[]" D="Cross Frames" Role="Input" Category="Referencing Objects" />
        <O T="ParamInfo" Param="bracings" Required="0" ReadOnly="1" />
    </O>
</O>

<!-- CHILD: CrossFrame -->
<O N="OBPBase_CrossFrame" T="Project">
    <O N="General" T="Group">
        <P N="Girders" V="[]" T="OBPBase_Girder" D="Girders" Role="Input" />
        <O T="ParamInfo" Param="Girders" Min="2" Max="2" Required="1" RefParam="@bracings"/>
    </O>
</O>
```

**Key Points:**

* Parent has `ReadOnly="1"` list in "Referencing Objects" group
* Child uses `RefParam="@bracings"` to register itself with parent
* System automatically adds/removes child from parent's list
* Other objects can navigate through references (e.g., Deck takes girder list, then accesses `girder.bracings` to reach cross frame data)

## File Types

* `.md` - Markdown documentation (AI guides)
* `.xml` - XML data files (library objects, type definitions)
* `.ts` - TypeScript source code (ParamML engine implementation)

## Common Tasks

### Adding New Library Objects

1. Read: `AI-Parametric-Engine-Guide.md` (Library Objects section)
2. Define `T="Project"` with proper Tags and Category
3. Add `Role="Input"` parameters for user configuration (automatically exported)
4. Add internal calculations (no role - private by default)
5. Create `<O T="Export">` for computed results that need to be accessible externally
6. Ensure exported params only depend on other exported params or `Role="Input"` params

### Creating FEA Models

1. Read: `AI-FEA-Guide.md`
2. Create nodes with `T="FENode"` (use X, Y, Z attributes)
3. Create elements (FELine, FESurf, FEVolume)
4. Define boundary conditions (Tx, Ty, Tz, Rx, Ry, Rz)
5. Create analysis cases and load combinations
6. Reference nodes using `@NodeName|FENode`

### Working with 3D Geometry

1. Read: `AI-3D-Visualization-Guide.md`
2. Use Point, Line, Surface, Volume types
3. Define coordinates with inline X, Y, Z attributes
4. Use Repeat for parametric arrays
5. Apply materials and textures as needed

## Code Review Checklist

When reviewing ParamML code, systematically check for these common issues:

### 1. Parameter Name Validation

**Check:** All parameter overrides use correct names from parent object

```xml
<!-- ❌ BAD: Typo in parameter name -->
<O N="MyGirder" Extends="StandardGirder">
  <P N="Lenght" V="120"/>  <!-- Typo: should be "Length" -->
</O>

<!-- ✅ GOOD: Correct parameter names -->
<O N="MyGirder" Extends="StandardGirder">
  <P N="Length" V="120"/>
</O>
```

**How to Check:**

1. Open `__dep__ParentObjectName.xml` file
2. List all `Role="Input"` parameters
3. Verify each override matches an actual parameter name
4. Flag typos or non-existent parameter names

### 2. Complete Parameter Overrides (Extends)

**Check:** All parameters affecting referenced child objects are overridden

```xml
<!-- ❌ BAD: Using StiffenerGroup but not setting NumStiffeners -->
<O N="MyGirder" Extends="StandardGirder">
  <P N="Length" V="120"/>
  <!-- Missing: NumStiffeners -->
</O>
<P N="Count" V="MyGirder.StiffenerGroup.Count"/>  <!-- BUG! -->

<!-- ✅ GOOD: Set all parameters affecting groups you use -->
<O N="MyGirder" Extends="StandardGirder">
  <P N="Length" V="120"/>
  <P N="NumStiffeners" V="5"/>
</O>
<P N="Count" V="MyGirder.StiffenerGroup.Count"/>
```

**How to Check:**

1. Find all references to child objects: `ObjectName.ChildGroup.Property`
2. Open `__dep__` file, trace which input parameters affect those child objects
3. Verify ALL those parameters are either:
   * Overridden with appropriate values
   * Left as default AND defaults make sense for this use case

### 3. Coordinate Format Standards

**Check:** All coordinates use inline X-Y-Z attributes, no spaces in math

```xml
<!-- ❌ BAD -->
<O T="Point" N="Pt">
  <P N="X" V="i * 10"/>
</O>

<!-- ✅ GOOD -->
<O T="Point" N="Pt" X="i*10" Y="0" Z="0" />
```

### 4. Performance: Repeat vs map() and StaticParams

**Check:** Using Repeat only for objects, map() for data transformations

```xml
<!-- ❌ BAD: Using Repeat for calculations -->
<O T="Repeat" N="Loop" S="0" E="99">
  <P N="Result" V="InputList[i] * 2"/>
</O>

<!-- ✅ GOOD: Using map() -->
<P N="Results" V="map(InputList, x => x * 2)"/>
```

**Check:** Using StaticParams for constant parameters in Repeat loops

**IMPORTANT:** StaticParams value must be enclosed in square brackets `[]`.

```xml
<!-- ❌ INEFFICIENT: Re-evaluates Spacing every iteration -->
<O T="Repeat" N="Points" S="0" E="10" CTRL="i">
  <P N="Spacing" V="12"/>
  <O T="Point" X="i*Spacing" Y="0" Z="0"/>
</O>

<!-- ❌ WRONG: Missing square brackets -->
<O T="Repeat" N="Points" S="0" E="10" CTRL="i" StaticParams="Spacing">
  ...
</O>

<!-- ✅ CORRECT: StaticParams with square brackets -->
<O T="Repeat" N="Points" S="0" E="10" CTRL="i" StaticParams="[Spacing]">
  <P N="Spacing" V="12"/>
  <O T="Point" X="i*Spacing" Y="0" Z="0"/>
</O>

<!-- ✅ CORRECT: Multiple static params -->
<O T="Repeat" N="Points" S="0" E="10" CTRL="i" StaticParams="[Spacing,Offset,Material]">
  <P N="Spacing" V="12"/>
  <P N="Offset" V="5"/>
  <O T="Point" X="i*Spacing+Offset" Y="0" Z="0"/>
</O>
```

**How to Check:**

1. Find all Repeat loops
2. Identify parameters that don't depend on loop variable (i, j, etc.)
3. Add those parameter names to StaticParams attribute
4. Format: `StaticParams="[Param1,Param2,Param3]"` (with square brackets!)

### 5. FEA Content Separation

**Check:** FEA-specific code should reference AI-FEA-Guide.md

* FENode, FELine, FESurf, FEGroup → FEA-specific
* Point, Line, Surface, Volume → General geometry

### 6. Input Parameter Renaming - Breaking Changes

**Check:** Renaming `Role="Input"` parameters in **workflow objects** requires backwards compatibility

**Critical Rule:** If a library object appears in a **Workflow** (check `*Workflow*.xml` files), renaming its `Role="Input"` parameters is a **breaking change** for end users.

**Why This Matters:**

* End users have saved projects with parameter values using old names
* Renaming parameters loses user's saved values (silent failure)
* Users must manually re-enter all values - **unacceptable UX**

**Problem Example:**

```xml
<!-- User's project (created 6 months ago): -->
<O N="MyObject" T="SomeWorkflowObject">
  <O N="InputGroup" T="Group">
    <P N="WidthOld" V="25"/>     <!-- User entered 25 -->
    <P N="HeightOld" V="30"/>    <!-- User entered 30 -->
  </O>
</O>

<!-- Developer renames parameters: -->
<!-- OLD: WidthOld, HeightOld -->
<!-- NEW: WidthNew, HeightNew -->

<!-- ❌ RESULT: User updates software version -->
<!-- WidthOld = 25 → LOST (falls back to default) -->
<!-- HeightOld = 30 → LOST (falls back to default) -->
<!-- User's values are silently ignored! -->
```

**Solution:**

If renaming `Role="Input"` parameters in workflow objects, **implement backwards compatibility** to preserve old parameter values. This ensures users don't lose their saved data when updating software versions.

**Best Practice:**

* **Check workflow files** before renaming to see if object is user-facing
* If object is in workflow → Backwards compatibility may be needed to preserve user data
* If object is NOT in workflow → Update dependent objects in same branch
* Document parameter renames in release notes

### 7. DesignRun Object Completeness Check (DR Objects)

**Check:** For DesignRun (DR) objects, verify all Base object's `Role="Input"` parameters are mapped in `T="DesignRun"` group

**What are DR Objects?**

* DR (DesignRun) objects are wrapper objects that execute Base library objects with user-provided inputs
* They map user inputs from the DR object's interface to the Base object's parameters
* Pattern: `*OBPDR_*.xml` files contain DR objects, they reference `*OBPBase_*.xml` files
* File naming: Base object `OBPBase_MyObject.xml` → DR object `OBPDR_MyObject.xml`

**Structure:**

```xml
<!-- DR Object Structure -->
<O N="MyDRObject" T="Project">
    <!-- User input parameters (DR interface) -->
    <O N="General" T="Group">
        <P N="userInput1" V="..." Role="Input" Category="General"/>
        <P N="userInput2" V="..." Role="Input" Category="General"/>
    </O>

    <!-- DesignRun group - maps to Base object -->
    <O N="STGLR" T="DesignRun">
        <P N="LibObjTypeName" V="OBPBase_MyObject" T="Text"/>
        <P N="LibObjVersion" V="1"/>

        <!-- Map ALL Base Role="Input" parameters here -->
        <P N="baseInputParam1" V="userInput1"/>
        <P N="baseInputParam2" V="userInput2"/>

        <!-- WARNING: Can also override non-Input parameters -->
        <P N="baseCalculatedParam" V="customValue"/>
    </O>
</O>
```

**Why This Matters:**

* **Missing Input parameters** → Base uses default values instead of user inputs → **Silent failures**
* **Users lose control** over critical design parameters
* **Results may be incorrect** without any warning
* Incomplete mapping is the **#1 cause** of DR object bugs

**⚠️ WARNING: DesignRun Non-Input Parameter Override**

DesignRun has a **dangerous capability** that must be carefully controlled:

**The Problem:**

* DesignRun can override **ANY parameter** in the Base object, not just `Role="Input"` parameters
* When you override a non-Input parameter, **ALL occurrences** of that parameter in the Base object scope are overridden
* This is **NOT recommended** and should be avoided in most cases

**Example - Unintended Override:**

```xml
<!-- Base Object -->
<O N="OBPBase_MyCodeCheck" T="Project">
    <P N="width" V="10" Role="Input"/>
    <P N="height" V="20" Role="Input"/>

    <!-- Internal calculation parameter - NOT an Input -->
    <P N="safety_factor" V="1.5"/>

    <P N="area" V="width * height"/>
    <P N="capacity" V="area * safety_factor"/>
    <P N="check1" V="capacity * safety_factor"/>
    <P N="check2" V="width * safety_factor"/>
</O>

<!-- DR Object - PROBLEMATIC -->
<O N="OBPDR_MyCodeCheck" T="Project">
    <P N="userWidth" V="15" Role="Input"/>
    <P N="userHeight" V="25" Role="Input"/>
    <P N="userFactor" V="2.0" Role="Input"/>

    <O N="Run" T="DesignRun">
        <P N="LibObjTypeName" V="OBPBase_MyCodeCheck" T="Text"/>

        <!-- OK: Map Input parameters -->
        <P N="width" V="userWidth"/>
        <P N="height" V="userHeight"/>

        <!-- ⚠️ PROBLEM: Overriding non-Input parameter -->
        <P N="safety_factor" V="userFactor"/>
        <!-- This overrides safety_factor EVERYWHERE in Base:
             - capacity calculation
             - check1 calculation
             - check2 calculation
             ALL will now use 2.0 instead of 1.5 -->
    </O>
</O>
```

**When This Happens:**

* ❌ **Breaks Base object's internal logic** - calculated parameters no longer use intended values
* ❌ **Creates maintenance nightmare** - changes to Base don't behave as expected
* ❌ **Violates separation of concerns** - DR should only provide input data, not override calculations
* ❌ **Hard to debug** - override affects multiple locations silently

**What To Do Instead:**

**If user needs to control a parameter that's not `Role="Input"`:**

1. **Add `Role="Input"` to that parameter in the Base object**

   ```xml
   <!-- Fix in Base object -->
   <P N="safety_factor" V="1.5" Role="Input"/>
   ```

   * Makes it officially part of the Base object's API
   * Clear to all developers that this parameter is meant to be configurable
   * Proper design pattern
2. **If parameter should remain internal:**
   * Do NOT override it from DR
   * Modify Base object logic if behavior needs to change
   * Keep data override (DR) separate from logic (Base)

**How to Check:**

**Step 1:** Identify the Base object reference

```xml
<O N="STGLR" T="DesignRun">
    <P N="LibObjTypeName" V="OBPBase_MyObject" T="Text"/>
</O>
```

**Step 2:** Extract all `Role="Input"` parameters from Base object

* Open the corresponding Base file (e.g., `OBPBase_MyObject.xml`)
* Find ALL parameters with `Role="Input"` attribute
* Create a list of these parameter names (these MUST be mapped)

**Step 3:** Verify each Base input exists in DesignRun group

* Check the `<O N="..." T="DesignRun">` group in the DR file
* Verify EVERY Base `Role="Input"` parameter has a corresponding `<P N="paramName" .../>` entry
* Parameter names must match EXACTLY (no spaces, correct spelling)

**Step 4:** Check for non-Input parameter overrides

* Identify any parameters in DesignRun that are NOT `Role="Input"` in Base
* These are **problematic overrides** that should be flagged
* Review why these exist and if Base object should be modified instead

**Step 5:** Check for naming errors

* Watch for trailing/leading spaces: `N="param "` vs `N="param"`
* Watch for typos or case sensitivity issues
* Parameter names must match Base object exactly (character-by-character)

**Automated Check (PowerShell):**

```powershell
# Extract Base Role="Input" parameters
$baseLines = Get-Content 'OBPBase_MyObject.xml'
$baseInputs = @()
foreach ($line in $baseLines) {
    if ($line -match 'Role="Input"' -and $line -match '<P\s+N="([^"]+)"') {
        $baseInputs += $matches[1]
    }
}

Write-Host "Base object has $($baseInputs.Count) Role='Input' parameters"

# Extract DR DesignRun parameters
$drLines = Get-Content 'OBPDR_MyObject.xml'
$designRunStart = -1
$designRunEnd = -1

# Find DesignRun group boundaries
for ($i = 0; $i -lt $drLines.Count; $i++) {
    if ($drLines[$i] -match '<O\s+[^>]*T="DesignRun"') {
        $designRunStart = $i
    }
    if ($designRunStart -gt -1 -and $designRunEnd -eq -1 -and $drLines[$i] -match '^\s*</O>\s*$') {
        $designRunEnd = $i
        break
    }
}

# Extract DesignRun parameters
$drParams = @()
for ($i = $designRunStart; $i -le $designRunEnd; $i++) {
    if ($drLines[$i] -match '<P\s+N="([^"]+)"') {
        $drParams += $matches[1]
    }
}

Write-Host "DesignRun group has $($drParams.Count) parameters mapped"

# Find missing Input parameters
$missing = @()
foreach ($param in $baseInputs) {
    if ($drParams -notcontains $param) {
        $missing += $param
    }
}

# Report missing inputs
if ($missing.Count -eq 0) {
    Write-Host "`n✅ All Base Role='Input' parameters are mapped in DesignRun"
} else {
    Write-Host "`n❌ ERROR: Missing $($missing.Count) Role='Input' parameters in DesignRun:"
    foreach ($param in $missing) {
        for ($i = 0; $i -lt $baseLines.Count; $i++) {
            if ($baseLines[$i] -match "N=`"$param`"" -and $baseLines[$i] -match 'Role="Input"') {
                Write-Host "  - $param (Base line $($i + 1))"
                break
            }
        }
    }
}

# Check for non-Input parameter overrides
$drNonInputOverrides = @()
foreach ($param in $drParams) {
    if ($baseInputs -notcontains $param -and $param -ne 'LibObjTypeName' -and $param -ne 'LibObjVersion') {
        $drNonInputOverrides += $param
    }
}

if ($drNonInputOverrides.Count -gt 0) {
    Write-Host "`n⚠️  WARNING: $($drNonInputOverrides.Count) non-Input parameter(s) overridden:"
    $drNonInputOverrides | ForEach-Object { Write-Host "  - $_" }
    Write-Host "`nThese overrides are PROBLEMATIC because:"
    Write-Host "  1. They override internal Base object calculations"
    Write-Host "  2. They affect ALL occurrences of these parameters in Base"
    Write-Host "  3. They violate separation of data (DR) and logic (Base)"
    Write-Host "`nRECOMMENDATION:"
    Write-Host "  - If users need to control these parameters: Add Role='Input' to Base object"
    Write-Host "  - If parameters should remain internal: Remove these overrides from DR"
}
```

**Common Issues:**

1. **Forgotten Input Parameters:** New `Role="Input"` added to Base but not mapped in DR
2. **Spacing Errors:** `N="param "` (with space) vs `N="param"` (correct)
3. **Typos:** Parameter name misspellings
4. **Version Mismatch:** DR references old Base version, missing new parameters
5. **Unintended Non-Input Overrides:** DR overrides calculated parameters (MUST FIX)

**Best Practice:**

* **Always map ALL `Role="Input"` parameters** from Base to DR (mandatory)
* **NEVER override non-Input parameters** in DesignRun
* When adding new `Role="Input"` to Base → immediately add to corresponding DR
* Use automated scripts during code review to verify completeness
* If non-Input override is found → add `Role="Input"` to Base or remove override from DR

***

**Review Process:**

When user says "review the code":

1. ✅ **Validate parameter names** against `__dep__` files
2. ✅ **Check complete overrides** for all referenced child objects
3. ✅ **Verify coordinate format** (inline X-Y-Z, no spaces)
4. ✅ **Check Repeat optimization** (use map() for data, StaticParams for constants)
5. ✅ **Check formatting** (no spaces in math: `i*12` not `i * 12`)
6. ✅ **Check input parameter renames** (if workflow files exist and parameters renamed, warn user about backwards compatibility)
7. ✅ **Check DesignRun completeness** (for DR objects with `T="DesignRun"`: find the Base object via `LibObjTypeName` parameter, verify all Base `Role="Input"` parameters are mapped in DesignRun group, flag any non-Input parameter overrides)

## Important Notes

⚠️ **Always read the AI documentation guides before starting work** (start with AI-Parametric-Engine-Guide.md)

⚠️ **Understand file types:**

* **Main objects** (`ObjectName.xml`) - Your working files
* **Dependencies** (`__dep__ObjectName.xml`) - Referenced library objects
* **Guides** (`.md` files) - Documentation to help you understand the system

⚠️ **FEA-specific content belongs in AI-FEA-Guide.md, not AI-Parametric-Engine-Guide.md**

⚠️ **Use inline X-Y-Z attributes for all coordinate definitions**

⚠️ **No spaces in mathematical expressions** (e.g., `i*12` not `i * 12`)

⚠️ **Use map() for data transformations, Repeat only for objects**

⚠️ **Type name is `Surface` not `Surface3D` in XML** (Surface3D is TypeScript class name)

⚠️ **Parameter Scope and Shared Parameters:**

* Parameters in sibling Groups under the same parent CAN access each other
* When parameters are used by multiple sibling Groups, consider organizing them:
  * **Option 1:** Keep shared parameters in one Group if primary usage is there (sibling access works)
  * **Option 2:** Move to parent level for clearer organization and better documentation
  * Both approaches work technically, but Option 2 is preferred for maintainability

**Example:** Shared parameters between CADD drawings and Section geometry:

```xml
<!-- WORKS: Sibling groups can access each other's parameters -->
<O N="CADDrawing" T="Group">
    <P N="SharedParam" V="10" />
    <O N="Drawing1" T="CADD">
        <!-- Can use SharedParam -->
    </O>
</O>
<O N="SectionGeometries" T="Group">
    <O N="Section1" T="Section">
        <P N="Value" V="SharedParam" />  <!-- ✅ WORKS (sibling group access) -->
    </O>
</O>

<!-- BETTER: Move shared parameters to parent level -->
<O N="SharedParameters" T="Group">
    <P N="SharedParam" V="10" />
</O>
<O N="CADDrawing" T="Group">
    <O N="Drawing1" T="CADD">
        <!-- Can use SharedParam -->
    </O>
</O>
<O N="SectionGeometries" T="Group">
    <O N="Section1" T="Section">
        <P N="Value" V="SharedParam" />  <!-- ✅ CLEARER (parent parameter) -->
    </O>
</O>
```

## Getting Help

When you need clarification:

1. Check the relevant AI guide first (AI-Parametric-Engine-Guide.md, AI-FEA-Guide.md, etc.)
2. Search for similar examples in the guides
3. Check `__dep__` files to understand referenced object structures

## Summary

This is a sophisticated parametric modeling system for bridge engineering. The XML files define intelligent, data-driven components that:

* Automatically calculate results from input parameters
* Generate 3D geometry and FEA meshes
* Perform design checks and code compliance
* Update dynamically when parameters change
* Export computed results for use by other objects
* Reference other library objects (downloaded as `__dep__` files)

**Quick Start:**

1. Read `AI-Parametric-Engine-Guide.md` first
2. Examine your main XML files (`ObjectName.xml`)
3. Check `__dep__` files to understand dependencies
4. Follow formatting standards and best practices
5. Create robust, reusable parametric components

***

**Generated for AI Agents working with OpenBrIM ParamML Code**


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.openbrim.org/developers/llm-guides/ai-paramml-readme.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
