diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index cc75377..79c1477 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -8,5 +8,6 @@
# Plugins
/plugins/data-designer-github/ @NVIDIA-NeMo/data_designer_reviewers @eric-tramel
+/plugins/data-designer-group-consistent/ @andreatnvidia
/plugins/data-designer-retrieval-sdg/ @NVIDIA-NeMo/data_designer_reviewers @shan-nvidia @oliverholworthy
/plugins/data-designer-template/ @NVIDIA-NeMo/data_designer_reviewers
diff --git a/docs/plugins/data-designer-group-consistent/index.md b/docs/plugins/data-designer-group-consistent/index.md
new file mode 100644
index 0000000..67ad068
--- /dev/null
+++ b/docs/plugins/data-designer-group-consistent/index.md
@@ -0,0 +1,57 @@
+# Group-consistent generation
+
+Use `group-consistent` to select one correlated candidate record for each
+logical group. The selection is deterministic for a given combination of group
+values, role, seed, and candidate pool.
+
+## Installation
+
+```bash
+uv add data-designer data-designer-group-consistent
+```
+
+## Column type
+
+```python
+from data_designer_group_consistent.config import GroupConsistentColumnConfig
+
+builder.add_column(
+ GroupConsistentColumnConfig(
+ name="synthetic_first_name",
+ group_by=["patient_id"],
+ role="patient",
+ seed=7,
+ records=[
+ {"first_name": "Amina", "last_name": "Diallo", "email": "amina@example.test"},
+ {"first_name": "Carlos", "last_name": "Silva", "email": "carlos@example.test"},
+ ],
+ field_mapping={
+ "synthetic_first_name": "first_name",
+ "synthetic_last_name": "last_name",
+ "synthetic_email": "email",
+ },
+ ),
+)
+```
+
+All mapped fields come from the same candidate record. Rows with the same
+`patient_id` therefore receive a coherent first name, last name, and email even
+when those rows are generated in different batches.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `name` | Yes | Primary output column. It must be a key in `field_mapping`. |
+| `group_by` | Yes | Ordered list of upstream columns defining a logical group. |
+| `records` | Yes | Non-empty candidate record pool. |
+| `field_mapping` | Yes | Mapping from output column names to candidate record fields. |
+| `role` | No | Namespace for independent entities in one group. Defaults to `default`. |
+| `seed` | No | Deterministic selection seed. Defaults to `0`. |
+
+## Implementation notes
+
+The plugin uses SHA-256 rather than Python's process-dependent `hash()` function.
+It does not persist a mapping table or call an LLM. Candidate order and pool size
+are part of the effective configuration: changing them may change prior choices.
+
+For the full plugin authoring guide, see the
+[main repository docs](https://nvidia-nemo.github.io/DataDesignerPlugins/authoring/).
diff --git a/docs/plugins/index.md b/docs/plugins/index.md
index 5fc1a9c..ee82842 100644
--- a/docs/plugins/index.md
+++ b/docs/plugins/index.md
@@ -16,6 +16,17 @@ Browse available Data Designer plugins by what they add to your data generation
github
+
+
+ Deterministic group-scoped record generation for Data Designer
+
+ Entry points
+ group-consistent
+
+