From d43be1def4d896b9d4fca67e7125e8618311bda9 Mon Sep 17 00:00:00 2001 From: Alex Groleau Date: Mon, 3 Aug 2026 19:35:07 -0400 Subject: [PATCH] doc update --- GEMINI.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/GEMINI.md b/GEMINI.md index f5dc233..a0de213 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -184,23 +184,27 @@ It evaluates as an **Independent Declarative Rules Engine**. Every `Case` block * **`array`**: Homogeneous collection of items matching the `items` schema. Validation is homogeneous, so strictness checking does not apply. `"extensible"` is not applicable at the `array` level (tuple-like `prefixItems` are removed). * **Inheritance Boundaries**: Strictness resets when crossing non-primitive `type` boundaries. A schema extending a strict parent remains strict unless it explicitly overrides with `"extensible": true`. -### Immutable Properties (`"immutable": true`) -To distinguish read-only hydrated endpoint references, computed properties, system-managed timestamps (`created_at`, `modified_at`), or audit fields from writable properties, JSPG introduces the universal `"immutable": true` schema keyword. +### Immutable Properties (`"immutable": "always" | "external"`) +To distinguish read-only hydrated endpoint references, computed properties, system-managed timestamps (`created_at`, `modified_at`), or audit fields from writable properties, JSPG supports the `"immutable"` property schema attribute, which takes string enum values (`"always"`, `"external"`, or omitted). -* **Developer Perspective**: Annotate properties in database schemas or trait definitions with `"immutable": true` when the property should be visible on reads (`jspg_query` / `.response`), but rejected or ignored on writes (`jspg_merge` / `.request`). +* **Enum Values**: + * `"always"`: Property is permanently read-only across all boundaries (e.g. system-managed audit timestamps like `created_at`, `modified_at`, or computed fields). + * `"external"`: Property is read-only from external client API requests (`.request` payloads), but can be populated or mutated by internal system operations. + * Omitted: Property is fully writable. +* **Developer Perspective**: Annotate properties in database schemas or trait definitions with `"immutable": "always"` or `"immutable": "external"` when the property should be visible on reads (`jspg_query` / `.response`), but rejected or ignored on writes (`jspg_merge` / `.request`). ```json "properties": { "source": { "family": "lite.organization", - "immutable": true, + "immutable": "always", "description": "Read-only hydrated member entity summary on a membership edge." } } ``` * **Behavior Across Pillars**: - * **Queryer (`jspg_query`)**: Hydrates and includes `immutable` properties in output read responses without restriction. - * **Validator (`jspg_validate`)**: Context-aware. Returns `IMMUTABLE_PROPERTY_VIOLATION` if an `immutable` property is supplied in a write/request payload (schema IDs not ending in `.response`). Response schemas (`.response`) permit `immutable` fields. - * **Merger (`jspg_merge`)**: Automatically skips `immutable` properties during object graph merging so client payloads can never mutate database columns or relationship edges. + * **Queryer (`jspg_query`)**: Hydrates and includes `"immutable"` properties in output read responses without restriction. + * **Validator (`jspg_validate`)**: Context-aware. Rejects specified `"immutable"` properties supplied in write/request payloads. Response schemas (`.response`) permit `"immutable"` fields. + * **Merger (`jspg_merge`)**: Automatically skips `"immutable"` properties during object graph merging so client payloads can never mutate database columns or relationship edges. ### Format Leniency for Empty Strings To simplify frontend form validation, format validators specifically for `uuid`, `date-time`, and `email` explicitly allow empty strings (`""`), treating them as "present but unset".