Install
$ agentstack add skill-impertio-studio-blender-bonsai-ifcopenshell-sverchok-claude-skill-package-ifcos-agents-code-validator ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
IfcOpenShell Code Validator Agent
Quick Reference
When to Activate This Validator
Activate this validation checklist when:
- Reviewing IfcOpenShell Python code for correctness
- Auditing IFC file manipulation scripts before production use
- Checking code that creates, modifies, or reads IFC files
- Validating code that processes IFC geometry
- Reviewing code that handles multiple IFC schema versions
- Assessing performance of scripts processing large IFC files (100MB+)
Severity Levels
| Severity | Meaning | Action | |----------|---------|--------| | BLOCKER | Code will crash, corrupt data, or produce invalid IFC files | MUST fix before code is accepted | | WARNING | Code has potential bugs, performance issues, or fragile patterns | SHOULD fix; document reason if deferred | | INFO | Code works but does not follow best practices | MAY fix; note for future improvement |
Validation Checklist
Execute these checks in order. Each check references the dependency skill that defines the rule.
Step 1: Schema Awareness (BLOCKER)
Source: ifcos-errors-schema
Code uses IFC entities?
├── Does code check model.schema before using schema-specific entities?
│ ├── NO → BLOCKER: Add schema check
│ └── YES → Pass
│
├── Does code use any *StandardCase entity (IfcWallStandardCase, etc.)?
│ ├── YES + no IFC4X3 guard → BLOCKER: StandardCase removed in IFC4X3
│ └── NO or guarded → Pass
│
├── Does code use IfcBuiltElement or IfcBuildingElement?
│ ├── YES + no schema branch → BLOCKER: Name differs by schema
│ └── Handled → Pass
│
├── Does code use IfcDoorStyle/IfcWindowStyle?
│ ├── YES + targets IFC4+ → BLOCKER: Use IfcDoorType/IfcWindowType
│ └── Handled → Pass
│
├── Does code use IFC4X3-only entities (IfcRoad, IfcBridge, IfcAlignment)?
│ ├── YES + schema != "IFC4X3" → BLOCKER: Entity does not exist
│ └── Correct schema → Pass
│
└── Does code access PredefinedType on IFC2X3 entities?
├── YES + no hasattr guard → BLOCKER: Most IFC2X3 entities lack PredefinedType
└── Guarded → Pass
Step 2: API Usage Correctness (BLOCKER)
Source: ifcos-syntax-api, ifcos-errors-patterns
Code creates or modifies IFC entities?
├── Uses model.create_entity() for production code?
│ └── BLOCKER: Use ifcopenshell.api.run("root.create_entity", ...) instead
│
├── Uses ifcopenshell.api.run() or direct module calls?
│ ├── Invents non-existent API modules/functions?
│ │ └── BLOCKER: Verify against the 35 API modules table
│ ├── Uses positional arguments after model?
│ │ └── BLOCKER: ALWAYS use keyword arguments
│ └── Passes single element where list is required (v0.8+)?
│ └── BLOCKER: products=, related_objects= require lists
│
├── Modifies entity attributes directly (wall.Name = "X")?
│ ├── For Name/Description → WARNING: Use api.run("attribute.edit_attributes", ...)
│ └── For relationships (ContainedInStructure, IsTypedBy) → BLOCKER: Use API
│
├── Creates relationships manually (model.create_entity("IfcRelContained..."))?
│ └── BLOCKER: Use spatial.assign_container, aggregate.assign_object, etc.
│
└── Creates IFC file with ifcopenshell.file() for production use?
└── WARNING: Use ifcopenshell.api.run("project.create_file", ...) instead
Step 3: File I/O Correctness (BLOCKER/WARNING)
Source: ifcos-syntax-fileio
Code opens or creates IFC files?
├── Uses ifcopenshell.file() without explicit schema= parameter?
│ └── WARNING: ALWAYS specify schema explicitly
│
├── Uses project.create_file() with schema= instead of version=?
│ └── BLOCKER: Parameter name is version=, not schema=
│
├── Creates file without IfcProject + units + context + spatial hierarchy?
│ └── WARNING: Incomplete IFC files cause downstream failures
│
├── Calls model.remove() directly on products?
│ └── BLOCKER: Use api.run("root.remove_product", ...) for safe removal
│
├── Uses transactions?
│ ├── Missing end_transaction() or discard_transaction()?
│ │ └── BLOCKER: Open transactions cause undefined behavior
│ └── Calls undo()/redo() inside active transaction?
│ └── BLOCKER: NEVER call undo/redo during active transaction
│
└── Writes to disk?
└── Pass (model.write() is safe)
Step 4: Entity Reference Safety (BLOCKER)
Source: ifcos-errors-patterns
Code removes entities or uses undo?
├── Accesses entity attributes after model.remove()?
│ └── BLOCKER: Entity wrapper is invalid after removal
│
├── Iterates and removes simultaneously?
│ └── BLOCKER: Collect to list first, then remove
│
├── Caches entity references across file modifications?
│ └── BLOCKER: References invalidate after remove/undo
│
└── Extracts data before removal?
└── Pass
Step 5: None Return Value Handling (BLOCKER)
Source: ifcos-errors-patterns
Code calls utility functions that return None?
├── Uses get_container(element).Name without None check?
│ └── BLOCKER: get_container returns None if no containment
│
├── Uses get_type(element).Name without None check?
│ └── BLOCKER: get_type returns None if no type assigned
│
├── Uses get_material(element) without None check?
│ └── BLOCKER: get_material returns None if no material
│
├── Uses geom.create_shape() without try/except RuntimeError?
│ └── BLOCKER: Geometry processing fails for many elements
│
└── Uses model.by_guid() without None check?
└── WARNING: Returns None if GUID not found
Step 6: GUID Handling (BLOCKER)
Source: ifcos-errors-patterns
Code creates entities with GlobalId?
├── Uses uuid.uuid4() or str(uuid) for GlobalId?
│ └── BLOCKER: IFC requires 22-char base64 GUID; use ifcopenshell.guid.new()
│
├── Reuses same GUID for multiple entities?
│ └── BLOCKER: Every entity MUST have a unique GlobalId
│
└── Uses ifcopenshell.api.run("root.create_entity") (auto-generates)?
└── Pass
Step 7: Unit Handling (WARNING)
Source: ifcos-errors-patterns
Code reads coordinates or dimensions from IFC files?
├── Assumes coordinates are in meters?
│ └── WARNING: ALWAYS call ifcopenshell.util.unit.calculate_unit_scale(model)
│
├── Applies unit_scale to all extracted coordinates?
│ └── Pass
│
└── Creates geometry with hardcoded values?
└── INFO: Document assumed unit system in comments
Step 8: Property Set Handling (WARNING)
Source: ifcos-errors-patterns
Code creates property sets?
├── Creates pset without checking for existing one?
│ └── WARNING: Produces duplicate property sets; check get_psets() first
│
├── Creates pset manually without IfcRelDefinesByProperties?
│ └── BLOCKER: Orphaned pset; use api.run("pset.add_pset", ...)
│
└── Uses api.run("pset.add_pset") + api.run("pset.edit_pset")?
└── Pass
Step 9: Performance Patterns (WARNING)
Source: ifcos-errors-performance
Code processes geometry for multiple elements?
├── Calls create_shape() in a loop for 10+ elements?
│ └── WARNING: Use ifcopenshell.geom.iterator instead (5-10x faster)
│
├── Uses geom.iterator without multiprocessing.cpu_count()?
│ └── WARNING: Pass cpu_count() for optimal parallelism
│
├── Stores all geometry shapes in memory simultaneously?
│ └── WARNING: Process each shape and discard immediately
│
├── Uses get_info(recursive=True) on large files?
│ └── WARNING: Materializes entire entity graph; extract specific attributes
│
├── Opens same large file multiple times?
│ └── WARNING: Open once, pass model reference
│
├── Iterates all entities with `for e in model` instead of by_type()?
│ └── WARNING: by_type() is O(1), full iteration is O(n)
│
├── Calls spatial.assign_container per-element instead of batching?
│ └── WARNING: Pass all products in one call
│
└── Processes 200MB+ file without gc.collect() between batches?
└── INFO: Add gc.collect() between processing phases
Step 10: IFC2X3 Compatibility (BLOCKER)
Source: ifcos-errors-schema
Code targets or handles IFC2X3 files?
├── Creates entities without OwnerHistory?
│ └── BLOCKER in IFC2X3: OwnerHistory is REQUIRED on all IfcRoot subclasses
│
├── Uses ifcopenshell.api.run() for entity creation?
│ └── Pass (API handles OwnerHistory automatically)
│
├── Queries IfcContext (does not exist in IFC2X3)?
│ └── BLOCKER: Use IfcProject directly
│
└── Uses IfcDoorType/IfcWindowType on IFC2X3?
└── BLOCKER: Use IfcDoorStyle/IfcWindowStyle for IFC2X3
Decision Trees
Decision Tree: Severity Classification
Is the issue...
├── A crash, data corruption, or invalid IFC output?
│ └── BLOCKER
│ Examples:
│ - Schema mismatch (entity not found)
│ - Invalid entity reference after removal
│ - Missing OwnerHistory in IFC2X3
│ - Dangling references from model.remove()
│ - Wrong GUID format
│ - Open transaction never closed
│
├── A potential bug, performance problem, or fragile pattern?
│ └── WARNING
│ Examples:
│ - Missing None check on get_container()
│ - create_shape() loop instead of iterator
│ - No unit scale applied
│ - Duplicate property sets
│ - Per-element API calls instead of batch
│
└── A best-practice deviation with no functional impact?
└── INFO
Examples:
- Implicit schema parameter
- Missing gc.collect() call
- Hardcoded unit assumptions (documented)
Decision Tree: Auto-Fix Applicability
Can this issue be auto-fixed?
├── Schema entity name substitution?
│ └── YES: Replace with version-aware branching
│
├── model.remove() → api.run("root.remove_product")?
│ └── YES: Direct substitution
│
├── model.create_entity() → api.run("root.create_entity")?
│ └── YES: Add ifc_class= and name= parameters
│
├── Missing None check on utility return value?
│ └── YES: Wrap in `if result is not None:` guard
│
├── create_shape() loop → iterator?
│ └── PARTIAL: Requires restructuring; provide template
│
├── Single element → list parameter?
│ └── YES: Wrap in list brackets [element]
│
└── Missing schema check?
└── PARTIAL: Insert model.schema check; pattern depends on context
Auto-Fix Patterns
Fix 1: Single Element to List Parameter (v0.8+)
# BEFORE (BLOCKER):
ifcopenshell.api.run("spatial.assign_container", model,
product=wall, relating_structure=storey)
# AFTER:
ifcopenshell.api.run("spatial.assign_container", model,
products=[wall], relating_structure=storey)
Fix 2: Direct Removal to Safe API Removal
# BEFORE (BLOCKER):
model.remove(wall)
# AFTER:
ifcopenshell.api.run("root.remove_product", model, product=wall)
Fix 3: Low-Level Entity Creation to API
# BEFORE (BLOCKER):
wall = model.create_entity("IfcWall",
GlobalId=ifcopenshell.guid.new(), Name="Wall 001")
# AFTER:
wall = ifcopenshell.api.run("root.create_entity", model,
ifc_class="IfcWall", name="Wall 001")
Fix 4: Missing None Guard
# BEFORE (BLOCKER):
container = ifcopenshell.util.element.get_container(wall)
print(container.Name)
# AFTER:
container = ifcopenshell.util.element.get_container(wall)
if container is not None:
print(container.Name)
Fix 5: UUID to IFC GUID
# BEFORE (BLOCKER):
import uuid
wall = model.create_entity("IfcWall", GlobalId=str(uuid.uuid4()))
# AFTER:
wall = ifcopenshell.api.run("root.create_entity", model,
ifc_class="IfcWall", name="Wall")
# Or if manual creation is required:
wall = model.create_entity("IfcWall",
GlobalId=ifcopenshell.guid.new(), Name="Wall")
Fix 6: Iterate-and-Remove to Collect-Then-Remove
# BEFORE (BLOCKER):
for wall in model.by_type("IfcWall"):
model.remove(wall)
# AFTER:
walls_to_remove = list(model.by_type("IfcWall"))
for wall in walls_to_remove:
ifcopenshell.api.run("root.remove_product", model, product=wall)
Fix 7: create_shape Loop to Iterator
# BEFORE (WARNING):
# IfcOpenShell: all schema versions
for wall in model.by_type("IfcWall"):
shape = ifcopenshell.geom.create_shape(settings, wall)
process(shape)
# AFTER:
# IfcOpenShell: all schema versions
import multiprocessing
walls = model.by_type("IfcWall")
iterator = ifcopenshell.geom.iterator(
settings, model, multiprocessing.cpu_count(), include=walls)
if iterator.initialize():
while True:
shape = iterator.get()
process(shape)
if not iterator.next():
break
Fix 8: Schema-Aware Entity Selection
# BEFORE (BLOCKER):
# IfcOpenShell: assumes single schema
elements = model.by_type("IfcBuildingElement")
# AFTER:
# IfcOpenShell: all schema versions
schema = model.schema
if schema == "IFC4X3":
elements = model.by_type("IfcBuiltElement")
else:
elements = model.by_type("IfcBuildingElement")
Validation Report Format
After running all checks, produce a report in this format:
## IfcOpenShell Code Validation Report
### Summary
- BLOCKERS: [count]
- WARNINGS: [count]
- INFO: [count]
### BLOCKER Issues
1. [Line X]: [Description] — [Fix reference]
### WARNING Issues
1. [Line X]: [Description] — [Fix reference]
### INFO Issues
1. [Line X]: [Description] — [Fix reference]
### Verdict
[PASS / FAIL (if any BLOCKERS exist)]
Reference Links
- [Validation Rules and Detection Patterns](references/methods.md)
- [Before/After Validation Fix Examples](references/examples.md)
- [Anti-Patterns Catalog](references/anti-patterns.md)
Dependency Skills (define the rules this validator checks)
- ifcos-syntax-fileio — File I/O patterns and transaction management
- ifcos-syntax-api — API module system, invocation patterns, parameter conventions
- ifcos-errors-patterns — Error categories, debugging strategies, None handling
- ifcos-errors-schema — Schema version differences, entity availability, migration
- ifcos-errors-performance — Geometry iterator, caching, memory management
External References
- IfcOpenShell Documentation: https://docs.ifcopenshell.org/
- IFC Schema Specifications: https://technical.buildingsmart.org/standards/ifc/ifc-schema-specifications/
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Impertio-Studio
- Source: Impertio-Studio/Blender-Bonsai-ifcOpenshell-Sverchok-Claude-Skill-Package
- License: MIT
- Homepage: https://github.com/OpenAEC-Foundation
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.