[Issue #736] ADR: Nullable Optional Fields#855
Conversation
|
🚀 Website Preview Deployed! Preview your changes at: https://cg-pr-855.billy-daly.workers.dev This preview will be automatically deleted when the PR is closed. |
|
👍 — approved. Heads up that this ADR has handler-level implications the SDK PoCs didn't anticipate. The TypeScript transforms PoC (#825) had three coercing handlers ( I've pushed alignment commits to #825 that:
ADR-0024's "SDKs already reflect this model and require no changes" framing is accurate for the validation surface ( No changes needed in ADR-0024 itself. |
|
🗑️ Preview Cleaned Up The preview for this PR has been automatically deleted. |
The "Null handling" cross-SDK note claimed the Python ADR-0024 parity follow-up was "tracked there" and linked #810. Reading #810 directly (body + diff) confirms it is the base Python Transform PoC (closes #799, merged 2026-05-13), scoped "to the transform layer only" with no null/three-state content — its coercing handlers collapse absent and null into `None` (`str(val) if val is not None else None`; `if val is None: return None`). ADR-0024 (PR #855) was created and merged 2026-05-26, 13 days after #810, so #810 neither did the parity work nor tracks it. No dedicated Python-parity issue exists. Reword: drop the false "tracked there" claim, link ADR-0024 directly as the contract Python must meet, state plainly that Python predates the ADR and that handler parity is a pending follow-up. No tracker is asserted. Docs-only; prettier clean.
Summary
Changes proposed
Adds ADR-0024 documenting the decision on optional field nullability in the CommonGrants protocol spec and SDKs.
Context for reviewers
This ADR resolves the question of whether optional fields in the base protocol (TypeSpec-generated) should be nullable. The current situation: both the Python SDK
(
Optional[X]) and TypeScript SDK (.nullish()) render optional fields as nullable, but the base protocol declares them as optional-but-non-nullable. Once theresolveAnyOf()bug incg check specis fixed (#735), both SDKs will fail validation.Decision: Make optional fields nullable in the base protocol (Option 1).
The key insight driving this decision is that publishers need to express three distinct field states — "not provided" (field absent), "doesn't apply" (explicit
null), and "has a value" — and this three-state model is only achievable with a nullable spec, especially for scalar types like dates where no natural sentinelvalue exists.
No code changes are included in this PR; the ADR documents the rationale so the corresponding TypeSpec and implementation changes can follow in a subsequent PR.
Additional information
The three options evaluated in the ADR:
.nullish()/Optional[X]nulland absent as equivalent