diff --git a/.github/workflows/ids-lint.yml b/.github/workflows/ids-lint.yml
new file mode 100644
index 0000000..2efe753
--- /dev/null
+++ b/.github/workflows/ids-lint.yml
@@ -0,0 +1,88 @@
+name: IDS Compliance Check
+
+on:
+ push:
+ pull_request:
+ workflow_dispatch:
+
+jobs:
+ ids-lint:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.10'
+
+ - name: Install ifctester and idssplit
+ run: |
+ pip install ifctester
+ pip install --no-deps https://github.com/brunopostle/idssplit/releases/download/0.1.0/idssplit-0.1.0-py3-none-any.whl
+
+ - name: Run IDS validations
+ run: |
+ set -e
+ shopt -s globstar nullglob
+
+ if [ ! -d IDS ]; then
+ echo "No IDS/ folder found"
+ exit 0
+ fi
+
+ ids_sources=(IDS/**/*.ids)
+
+ if [ ${#ids_sources[@]} -eq 0 ]; then
+ echo "No IDS files found in IDS/ folder"
+ exit 0
+ fi
+
+ ifc_files=(**/*.ifc)
+
+ if [ ${#ifc_files[@]} -eq 0 ]; then
+ echo "No IFC files found"
+ exit 0
+ fi
+
+ mkdir -p split_ids
+
+ echo "Splitting IDS files..."
+ for ids in "${ids_sources[@]}"; do
+ idssplit "$ids" split_ids/
+ done
+
+ split_ids_files=(split_ids/*.ids)
+ if [ ${#split_ids_files[@]} -eq 0 ]; then
+ echo "No rules found after splitting IDS files"
+ exit 1
+ fi
+
+ echo "Running ifctester validations..."
+ failed=0
+
+ for rule_ids in "${split_ids_files[@]}"; do
+ for ifc in "${ifc_files[@]}"; do
+ echo "::group::Test: $rule_ids with $ifc"
+ echo "Testing: $rule_ids with $ifc"
+ output=$(python3 -m ifctester --no-color "$rule_ids" "$ifc" || true)
+ echo "$output"
+ echo "::endgroup::"
+
+ if echo "$output" | grep -q '\[FAIL\]'; then
+ echo "FAIL: $rule_ids with $ifc"
+ failed=1
+ else
+ echo "PASS: $rule_ids with $ifc"
+ fi
+ done
+ done
+
+ if [ "$failed" -ne 0 ]; then
+ echo "One or more validations failed"
+ exit 1
+ else
+ echo "All validations passed"
+ fi
diff --git a/.github/workflows/ifc-lint.yml b/.github/workflows/ifc-lint.yml
new file mode 100644
index 0000000..d6acac8
--- /dev/null
+++ b/.github/workflows/ifc-lint.yml
@@ -0,0 +1,32 @@
+name: IFC Validation
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ lint-ifc:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Set up Python
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
+
+ - name: Install ifcopenshell
+ run: |
+ pip install pytest
+ pip install ifcopenshell
+
+ - name: Run IFC lint checks
+ run: |
+ set -e
+ shopt -s globstar nullglob
+ for file in **/*.ifc; do
+ echo "Validating $file..."
+ python3 -m ifcopenshell.validate --rules "$file"
+ done
diff --git a/IDS/EN_Basic IDM Check.ids b/IDS/EN_Basic IDM Check.ids
new file mode 100644
index 0000000..98c8e62
--- /dev/null
+++ b/IDS/EN_Basic IDM Check.ids
@@ -0,0 +1,114 @@
+
+
+
+ EN_Basic IDM Check
+ Example IDS for model validation according to the BIM Basic Information Delivery Manual (IDM)
+ sgolchinfar@bimcollab.com
+ 2024-10-29
+ Specify a set of agreements that IFC models must meet according to the basic IDM.
+
+
+
+
+
+
+ IFCBUILDINGELEMENTPROXY
+
+
+
+
+
+
+ GlobalId
+
+
+ ?
+
+
+
+
+
+
+
+
+ Pset_WallCommon
+
+
+ IsExternal
+
+
+ False
+
+
+
+
+ Pset_WallCommon
+
+
+ LoadBearing
+
+
+ True
+
+
+
+
+
+
+ Pset_WallCommon
+
+
+ FireRating
+
+
+ 30
+
+
+
+
+
+
+
+
+ Pset_WallCommon
+
+
+ IsExternal
+
+
+ True
+
+
+
+
+
+
+ Pset_WallCommon
+
+
+ Thermal Transmitance
+
+
+
+
+
+
+
+
+ IFCFLOWSEGMENT
+
+
+
+
+
+
+ AC_Pset_RenovationAndPhasing
+
+
+ Renovation Status
+
+
+
+
+
+
diff --git a/IDS/IDS_random_example.ids b/IDS/IDS_random_example.ids
new file mode 100644
index 0000000..24fd04a
--- /dev/null
+++ b/IDS/IDS_random_example.ids
@@ -0,0 +1,81 @@
+
+
+
+ random example to show technical capabilities and usage
+ buildingSMART International Ltd
+ 2021-09-17
+
+
+
+
+
+
+ IFCWINDOW
+
+
+
+
+
+
+ The value should be a number; a dot; another number. For example '1.1', '2.4', etc.
+
+
+
+
+
+ NL-Sfb
+
+
+
+
+
+
+ attribute
+
+
+ OverallWidth
+
+
+
+
+
+
+
+
+
+
+ AedesUVIP
+
+
+ FireRating
+
+
+
+
+
+
+ Thirty minutes
+
+
+
+
+
+
+ Sixty minutes
+
+
+
+
+
+
+ Ninety minutes
+
+
+
+
+
+
+
+
+
+
diff --git a/model.ifc b/model.ifc
index 89e1ae6..9875833 100644
--- a/model.ifc
+++ b/model.ifc
@@ -1,7 +1,7 @@
ISO-10303-21;
HEADER;
FILE_DESCRIPTION(('ViewDefinition[DesignTransferView]'),'2;1');
-FILE_NAME('model.ifc','2025-02-06T22:16:33+00:00',('',''),('',''),'IfcOpenShell 0.0.0','Bonsai 0.0.0','Nobody');
+FILE_NAME('model.ifc','2025-10-17T10:31:20+01:00',('',''),('',''),'IfcOpenShell 0.0.0','Bonsai 0.0.0','Nobody');
FILE_SCHEMA(('IFC4'));
ENDSEC;
DATA;
@@ -8517,7 +8517,7 @@ DATA;
#35959=IFCPOLYGONALFACESET(#35945,$,(#35946,#35947,#35948,#35949,#35950,#35951,#35952,#35953,#35954,#35955,#35956,#35957,#35958),$);
#35960=IFCGROUP('3NpCHi67PBu9TmvZGd4Pbn',$,'BBIM_Linked_Aggregate',$,$);
#35961=IFCRELASSIGNSTOGROUP('2YO79r$sH2qu3t6d1iy2r4',$,$,$,(#39529,#35843,#38874),$,#35960);
-#35962=IFCPROPERTYSET('1pXbg_yYr7KPmJi1htT7g2',$,'BBIM_Linked_Aggregate',$,(#35964));
+#35962=IFCPROPERTYSET('1pXbg_yYr7KPmJi1htT7g2',$,'BBIM_Linked_Aggregate',$,(#35964,#41306,#41307));
#35963=IFCRELDEFINESBYPROPERTIES('1x8EvK_VvDFxpvkkdgg$w_',$,$,$,(#35843),#35962);
#35964=IFCPROPERTYSINGLEVALUE('Index',$,IFCINTEGER(0),$);
#35965=IFCPROPERTYSET('1YPtSHUJ9B_B9lz7ppy7yK',$,'BBIM_Linked_Aggregate',$,(#35967));
@@ -8956,7 +8956,7 @@ DATA;
#39166=IFCPROPERTYSET('16fgijRGH0wQ4w9kJF$$Vr',$,'BBIM_Linked_Aggregate',$,(#39168));
#39167=IFCRELDEFINESBYPROPERTIES('2PlGVQ7pjEvw7E$79txECs',$,$,$,(#38849),#39166);
#39168=IFCPROPERTYSINGLEVALUE('Index',$,IFCINTEGER(2),$);
-#39169=IFCPROPERTYSET('12Npe0f6D0_BsrIZtUisSy',$,'BBIM_Linked_Aggregate',$,(#39171));
+#39169=IFCPROPERTYSET('12Npe0f6D0_BsrIZtUisSy',$,'BBIM_Linked_Aggregate',$,(#39171,#41308,#41309));
#39170=IFCRELDEFINESBYPROPERTIES('3GCIzzBb9ERx0AKtY_QKod',$,$,$,(#38874),#39169);
#39171=IFCPROPERTYSINGLEVALUE('Index',$,IFCINTEGER(0),$);
#39172=IFCPROPERTYSET('1O3gul9Gf0UfQIHuaY$zu$',$,'BBIM_Linked_Aggregate',$,(#39174));
@@ -9356,7 +9356,7 @@ DATA;
#39821=IFCPROPERTYSET('3Bi4nPYrP86AQT5N7Cp5sX',$,'BBIM_Linked_Aggregate',$,(#39823));
#39822=IFCRELDEFINESBYPROPERTIES('1tOefteVD2UxoFC3U7Jb9l',$,$,$,(#39504),#39821);
#39823=IFCPROPERTYSINGLEVALUE('Index',$,IFCINTEGER(2),$);
-#39824=IFCPROPERTYSET('3lpBAgbw58qfyNULP3a8nO',$,'BBIM_Linked_Aggregate',$,(#39826));
+#39824=IFCPROPERTYSET('3lpBAgbw58qfyNULP3a8nO',$,'BBIM_Linked_Aggregate',$,(#39826,#41304,#41305));
#39825=IFCRELDEFINESBYPROPERTIES('2PMH7w56X5BQIVTIy0$XwZ',$,$,$,(#39529),#39824);
#39826=IFCPROPERTYSINGLEVALUE('Index',$,IFCINTEGER(0),$);
#39827=IFCPROPERTYSET('0uxOlwfAv0gfNQ_2gapcZC',$,'BBIM_Linked_Aggregate',$,(#39829));
@@ -9993,5 +9993,11 @@ DATA;
#41301=IFCCSGSOLID(#41300);
#41302=IFCSHAPEREPRESENTATION(#15,'Body','CSG',(#41301));
#41303=IFCDOCUMENTREFERENCE('sheets/A00 - GENERAL ARRANGEMENT.svg','X',$,'SHEET',#41290);
+#41304=IFCPROPERTYSINGLEVALUE('Aggregate_Index',$,IFCINTEGER(1),$);
+#41305=IFCPROPERTYSINGLEVALUE('Name',$,IFCLABEL('Truss'),$);
+#41306=IFCPROPERTYSINGLEVALUE('Aggregate_Index',$,IFCINTEGER(0),$);
+#41307=IFCPROPERTYSINGLEVALUE('Name',$,IFCLABEL('Truss'),$);
+#41308=IFCPROPERTYSINGLEVALUE('Aggregate_Index',$,IFCINTEGER(2),$);
+#41309=IFCPROPERTYSINGLEVALUE('Name',$,IFCLABEL('Truss'),$);
ENDSEC;
END-ISO-10303-21;