diff --git a/README.md b/README.md
index 0b26d3a..0488af7 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,110 @@
-# mxlint rules
+
-TBD
+
+
+
+ [![Contributors][contributors-shield]][contributors-url]
+ [![Forks][forks-shield]][forks-url]
+ [![Issues][issues-shield]][issues-url]
+ [![Unlicense License][license-shield]][license-url]
+
+
+
+
+
+
+
+
+
+ Table of Contents
+
+ - Getting Started
+ - Roadmap
+ - Contributing
+ - License
+ - Contact
+
+
+
+
+## Getting started
+Add new rules to your Mendix project by downloading the applicable `.rego` file and storing it in the project's `.mendix-cache/rules` folder. This folder contains subfolders for each rule category.
+
+Each rule comes with its own `_test` file, which contains test data and one or more test cases.
+
+For more information, see the installation instructions on the [MxLint website](https://mxlint.com/mendix-studio-pro-extension/installation/).
+
+
+
+## Roadmap
+
+- [x] Add README
+- [ ] Add changelog
+- [ ] Convert all [Mendix Best Practices for Development](https://docs.mendix.com/refguide/dev-best-practices/) to rules
+
+
+
+## Contributing
+MxLint and its rules is a fully open source project, driven entirely by the Mendix community! That is why we welcome any and all contributions!
+
+If you want to contribute, this is the way:
+
+1. Fork the Project
+2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
+3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
+4. Push to the Branch (`git push origin feature/AmazingFeature`)
+5. Open a Pull Request
+
+You pull request will be reviewed and, if accepted, merged into the mainline of MxLint.
+
+
+
+## License
+MxLint—the CLI tools, the Mendix Studio Pro extension and its rules—is distributed under the [AGPL license](https://github.com/mxlint/mxlint-rules/blob/main/LICENSE)
+
+
+
+## Contact
+Xiwen Cheng - [LinkedIn](https://linkedin.com/in/xiwen) - [Email](mailto:x@cinaq.com)
+
+Bart Zantingh - [LinkedIn](https://linkedin.com/in/bartzantingh) - [Email](mailto:bart.zantingh@nl.abnamro.com)
+
+MxLint project home: [https://github.com/mxlint](https://github.com/mxlint)
+
+## Useful links
+- [MxLint home](https://mxlint.com/)
+- [Open Policy Agent home](https://www.openpolicyagent.org/)
+- [Open Policy Agent docs](https://www.openpolicyagent.org/docs/latest/)
+- [Rego language reference](https://www.openpolicyagent.org/docs/latest/policy-reference/)
+
+(back to top)
+
+
+
+[contributors-shield]: https://img.shields.io/badge/Contributors-3-339933?style=for-the-badge&logo=data:image/svg+xml;base64,PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KDTwhLS0gVXBsb2FkZWQgdG86IFNWRyBSZXBvLCB3d3cuc3ZncmVwby5jb20sIFRyYW5zZm9ybWVkIGJ5OiBTVkcgUmVwbyBNaXhlciBUb29scyAtLT4KPHN2ZyB3aWR0aD0iODAwcHgiIGhlaWdodD0iODAwcHgiIHZpZXdCb3g9IjAgMCAxNiAxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsPSJub25lIj4KDTxnIGlkPSJTVkdSZXBvX2JnQ2FycmllciIgc3Ryb2tlLXdpZHRoPSIwIi8+Cg08ZyBpZD0iU1ZHUmVwb190cmFjZXJDYXJyaWVyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KDTxnIGlkPSJTVkdSZXBvX2ljb25DYXJyaWVyIj4gPGcgZmlsbD0iI2ZmZiI+IDxwYXRoIGQ9Ik0zLjQ2MiA3Ljk0MmE1LjYzOCA1LjYzOCAwIDAxMS4yMTYtMi4yOTljLS4xODctLjE0Ny0uOTI4LS43NTUtLjk2My0xLjIzMkMzLjY2MSAzLjYyOSA0LjQwMyAxIDQuNDAzIDFzLTIuMjQgMi44NzYtMi4zOTUgNC4wMzlDMS44ODQgNS45NSAzLjMgNy43NiAzLjQ0OSA3Ljk0NXYtLjAwM2guMDEzem05LjExNC0uMDQ3VjcuOWMwIC4wMDQuMDAzLjAwNy4wMDMuMDEuMjQ4LS4zMTQgMS41My0yIDEuNDEzLTIuODcyQzEzLjgzOCAzLjg3NiAxMS41OTggMSAxMS41OTggMXMuNzQyIDIuNjI5LjY4OCAzLjQxYy0uMDMyLjQ1OC0uNzA3IDEuMDMtLjkzMiAxLjIxYTUuNTcgNS41NyAwIDAxMS4yMjMgMi4yNzV6Ii8+IDxwYXRoIGQ9Ik0xMi41NzYgNy44OTh2LS4wMDZhNS42MTUgNS42MTUgMCAwMC0xLjIyMy0yLjI3NWMtLjg3LS45Ny0yLjA1Ni0xLjU1LTMuMzMzLTEuNTV2My4xMDZoLjAwNGMuMzEzLjAwNC41NjcuMjc0LjU2Ny42MDUgMCAuMDQtLjAwMy4wNzctLjAxLjExNGEuNTgzLjU4MyAwIDAxLS41NTcuNDloLS4wMXYxLjE1M2wtLjAwNiA1LjQ1OGguMTFzMS4yMDUtMS44MzcgMS44NTQtMi4zNjFjLjc2LS42MTUgMi42MDQtMS4zNzcgMi42MDQtMS4zNzd2LTMuMzJsLjAxLS4wMDNjLS4wMDQtLjAwNy0uMDA0LS4wMTctLjAwNy0uMDI0IDAtLjAwMyAwLS4wMDYtLjAwMy0uMDF6Ii8+IDxwYXRoIGQ9Ik04LjAxNCA5LjUzOFY4LjM4NmEuNTguNTggMCAwMS0uNTQ4LS40NDQuNjUuNjUgMCAwMS0uMDIyLS4xNmMwLS4zMzUuMjU3LS42MDUuNTczLS42MDVoLjAwNFY0LjA4Yy0xLjI4NCAwLTIuNDcyLjU4NS0zLjM0MyAxLjU2M2E1LjYxNiA1LjYxNiAwIDAwLTEuMjE2IDIuMjk5aC0uMDF2My4zNjRzMS44NDQuNzYxIDIuNjA0IDEuMzc2Yy42My41MSAxLjg0NyAyLjMxOCAxLjg0NyAyLjMxOGguMTE0di0uMDAzaC0uMDA2bC4wMDMtNS40NTl6Ii8+IDwvZz4gPC9nPgoNPC9zdmc+
+[contributors-url]: https://github.com/mxlint/mxlint-rules/graphs/contributors
+[forks-shield]: https://img.shields.io/badge/Forks-3-007EC6?style=for-the-badge&logo=git&logoColor=white
+[forks-url]: https://github.com/mxlint/mxlint-rules/network
+[issues-shield]: https://img.shields.io/badge/Issues-2-DFB317?style=for-the-badge
+[issues-url]: https://github.com/mxlint/mxlint-rules/issues
+[license-shield]: https://img.shields.io/badge/License-AGPL-663066?style=for-the-badge&logo=gnu
+[license-url]: https://github.com/mxlint/mxlint-rules/blob/main/LICENSE
diff --git a/rules/005_microflows/005_0003_number_of_elements_in_microflow.rego b/rules/005_microflows/005_0003_number_of_elements_in_microflow.rego
new file mode 100644
index 0000000..8d691c3
--- /dev/null
+++ b/rules/005_microflows/005_0003_number_of_elements_in_microflow.rego
@@ -0,0 +1,40 @@
+# METADATA
+# scope: package
+# title: No more than 25 elements in a microflow
+# description: The bigger a microflow, the harder it will be to maintain.
+# authors:
+# - Bart Zantingh
+# custom:
+# category: Maintainability
+# rulename: NumberOfElementsInMicroflow
+# severity: MEDIUM
+# rulenumber: 005_0003
+# remediation: Split microflow into logical, functional elements.
+# input: "**/*$Microflow.yaml"
+package app.mendix.microflows.number_of_elements_in_microflow
+
+import rego.v1
+
+annotation := rego.metadata.chain()[1].annotations
+
+default allow := false
+
+allow if count(errors) == 0
+
+errors contains error if {
+ name := input.Name
+
+ count_elements := count(input.ObjectCollection.Objects) - 2
+ count_elements > 25
+
+ error := sprintf(
+ "[%v, %v, %v] Microflow %v has %v actions which is more than 25",
+ [
+ annotation.custom.severity,
+ annotation.custom.category,
+ annotation.custom.rulenumber,
+ name,
+ count_elements,
+ ],
+ )
+}
diff --git a/rules/005_microflows/005_0003_number_of_elements_in_microflow_test.rego b/rules/005_microflows/005_0003_number_of_elements_in_microflow_test.rego
new file mode 100644
index 0000000..a3a62a3
--- /dev/null
+++ b/rules/005_microflows/005_0003_number_of_elements_in_microflow_test.rego
@@ -0,0 +1,65 @@
+package app.mendix.microflows.number_of_elements_in_microflow_test
+
+import data.app.mendix.microflows.number_of_elements_in_microflow
+import rego.v1
+
+# Test data
+microflow_with_less_than_25_activities := {
+ "$Type": "Microflows$Microflow",
+ "Name": "Microflow_with_less_than_25_activities",
+ "ObjectCollection": {
+ "$Type": "Microflows$MicroflowObjectCollection",
+ "Objects": [
+ {"$Type": "Microflows$StartEvent"},
+ {"$Type": "Microflows$EndEvent"},
+ {"$Type": "Microflows$ActionActivity"},
+ ],
+ },
+}
+
+microflow_with_more_than_25_activities := {
+ "$Type": "Microflows$Microflow",
+ "Name": "Microflow_with_more_than_25_activities",
+ "ObjectCollection": {
+ "$Type": "Microflows$MicroflowObjectCollection",
+ "Objects": [
+ {"$Type": "Microflows$StartEvent"},
+ {"$Type": "Microflows$EndEvent"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ ],
+ },
+}
+
+# Test cases
+test_should_allow_when_microflow_has_less_than_25_activities if {
+ number_of_elements_in_microflow.allow with input as microflow_with_less_than_25_activities
+}
+
+test_should_deny_when_microflow_has_more_than_25_activities if {
+ not number_of_elements_in_microflow.allow with input as microflow_with_more_than_25_activities
+}
diff --git a/rules/005_microflows/005_0004_complex_microflows_without_annotations.rego b/rules/005_microflows/005_0004_complex_microflows_without_annotations.rego
new file mode 100644
index 0000000..ebed94d
--- /dev/null
+++ b/rules/005_microflows/005_0004_complex_microflows_without_annotations.rego
@@ -0,0 +1,68 @@
+# METADATA
+# scope: package
+# title: Complex microflows without annotations
+# description: Microflows with more than 10 actions and/or 2 decisions can be hard to understand.
+# authors:
+# - Bart Zantingh
+# custom:
+# category: Maintainability
+# rulename: ComplexMicroflowsWithoutAnnotations
+# severity: MEDIUM
+# rulenumber: 005_0004
+# remediation: Add one or more annotations to explain the microflow.
+# input: "**/*$Microflow.yaml"
+package app.mendix.microflows.complex_microflows_without_annotations
+
+import rego.v1
+
+annotation := rego.metadata.chain()[1].annotations
+
+default allow := false
+
+allow if count(errors) == 0
+
+errors contains error if {
+ is_complex
+
+ # if MF Is complex, collect all objects of type Microflows$Annotations from input file
+ annotation_collection := [annotation |
+ some annotation in input.ObjectCollection.Objects
+ annotation["$Type"] == "Microflows$Annotation"
+ ]
+
+ count(annotation_collection) == 0
+
+ error := sprintf(
+ "[%v, %v, %v] Microflow %v has more than 10 activities and/or more than 2 exclusive splits, but no annotations",
+ [
+ annotation.custom.severity,
+ annotation.custom.category,
+ annotation.custom.rulenumber,
+ input.Name,
+ ],
+ )
+}
+
+# A microflow is considered complex if one or more of these conditions are met:
+# - it has more than 10 actions
+# - it has more than 2 exclusive splits
+# based on Mendix Best Practices for Development paragraph 4.3.2
+# see https://docs.mendix.com/refguide/dev-best-practices/#documentation-and-annotations
+
+is_complex if {
+ ex_splits_collection := [ex_split |
+ some ex_split in input.ObjectCollection.Objects
+ ex_split["$Type"] == "Microflows$ExclusiveSplit"
+ ]
+
+ count(ex_splits_collection) > 2
+}
+
+is_complex if {
+ activity_collection := [activity |
+ some activity in input.ObjectCollection.Objects
+ activity["$Type"] == "Microflows$ActionActivity"
+ ]
+
+ count(activity_collection) > 10
+}
diff --git a/rules/005_microflows/005_0004_complex_microflows_without_annotations_test.rego b/rules/005_microflows/005_0004_complex_microflows_without_annotations_test.rego
new file mode 100644
index 0000000..b4128ae
--- /dev/null
+++ b/rules/005_microflows/005_0004_complex_microflows_without_annotations_test.rego
@@ -0,0 +1,115 @@
+package app.mendix.microflows.complex_microflows_without_annotations_test
+
+import data.app.mendix.microflows.complex_microflows_without_annotations
+import rego.v1
+
+# Test data
+microflow_with_1_exclusive_split := {
+ "$Type": "Microflows$Microflow",
+ "Name": "Microflow",
+ "ObjectCollection": {
+ "$Type": "Microflows$MicroflowObjectCollection",
+ "Objects": [
+ {"$Type": "Microflows$ExclusiveSplit"}
+ ],
+ },
+}
+
+microflow_with_2_actions_and_2_exclusive_splits := {
+ "$Type": "Microflows$Microflow",
+ "Name": "Microflow",
+ "ObjectCollection": {
+ "$Type": "Microflows$MicroflowObjectCollection",
+ "Objects": [
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ExclusiveSplit"},
+ {"$Type": "Microflows$ExclusiveSplit"}
+ ],
+ },
+}
+
+microflow_with_11_actions_no_annotations := {
+ "$Type": "Microflows$Microflow",
+ "Name": "Microflow",
+ "ObjectCollection": {
+ "$Type": "Microflows$MicroflowObjectCollection",
+ "Objects": [
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"}
+ ],
+ },
+}
+
+microflow_with_11_actions_with_annotations := {
+ "$Type": "Microflows$Microflow",
+ "Name": "Microflow",
+ "ObjectCollection": {
+ "$Type": "Microflows$MicroflowObjectCollection",
+ "Objects": [
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$ActionActivity"},
+ {"$Type": "Microflows$Annotation"}
+ ],
+ },
+}
+
+microflow_with_3_exclusive_splits_no_annotations := {
+ "$Type": "Microflows$Microflow",
+ "Name": "Microflow",
+ "ObjectCollection": {
+ "$Type": "Microflows$MicroflowObjectCollection",
+ "Objects": [
+ {"$Type": "Microflows$ExclusiveSplit"},
+ {"$Type": "Microflows$ExclusiveSplit"},
+ {"$Type": "Microflows$ExclusiveSplit"}
+ ],
+ },
+}
+
+microflow_with_3_exclusive_splits_with_annotations := {
+ "$Type": "Microflows$Microflow",
+ "Name": "Microflow",
+ "ObjectCollection": {
+ "$Type": "Microflows$MicroflowObjectCollection",
+ "Objects": [
+ {"$Type": "Microflows$ExclusiveSplit"},
+ {"$Type": "Microflows$ExclusiveSplit"},
+ {"$Type": "Microflows$ExclusiveSplit"},
+ {"$Type": "Microflows$Annotation"}
+ ],
+ },
+}
+
+test_should_allow_when_microflow_is_not_complex if {
+ complex_microflows_without_annotations.allow with input as microflow_with_2_actions_and_2_exclusive_splits
+ complex_microflows_without_annotations.allow with input as microflow_with_1_exclusive_split
+}
+
+test_should_allow_when_microflow_is_complex_and_has_annotations if {
+ complex_microflows_without_annotations.allow with input as microflow_with_11_actions_with_annotations
+ complex_microflows_without_annotations.allow with input as microflow_with_3_exclusive_splits_with_annotations
+}
+
+test_should_deny_when_microflow_is_complex_and_has_no_annotations if {
+ not complex_microflows_without_annotations.allow with input as microflow_with_11_actions_no_annotations
+ not complex_microflows_without_annotations.allow with input as microflow_with_3_exclusive_splits_no_annotations
+}