0080: PromptGroup Arity Enforcement¶
- Status: Accepted
- Author: Chris Colinsky
- Created: 2026-06-23
- Accepted: 2026-06-23
- Targets: prompt-management/spec.md §10 PromptGroup (pin the enforcement point —
constructing a group with fewer than two members MUST raise, at construction) + §11 Errors
(add a
prompt_group_invalidcategory). Plus new conformance fixtures underspec/prompt-management/conformance/asserting the rejection. - Related: 0017 (prompt-management core — introduced the
PromptGroup§10 primitive and the two-or-more-members rule), 0033 (prompt-management surface refinements), 0057 (LlmCompletionEvent field set — its observability fixture066built the group-of-one that exposed this gap; corrected in spec v0.74.1), 0055 (conformance-adapter — the categorizedraises: {category}assertion shape these fixtures use) - Supersedes:
Summary¶
prompt-management §10 requires a PromptGroup to hold two or more members ("empty groups and
single-member groups are both spec-invalid; members MUST contain at least two elements"), but it
specifies neither the enforcement point (must the implementation actively reject an invalid
group, or is the behavior undefined?) nor an error category, and no conformance fixture pins
it. This proposal closes that loop: it pins rejection at construction time, adds a
prompt_group_invalid error category (§11), and adds rejection fixtures so the rule is enforced
uniformly across implementations.
Motivation¶
The gap is not hypothetical — it just bit. Observability conformance fixture 066
(LlmCompletionEvent.active_prompt_group) was authored with a single-member group, directly
contradicting §10's two-or-more-members rule. It went undetected through authoring and acceptance;
the only thing that surfaced it was a reference implementation wiring the fixture into its harness
and finding its own PromptGroup constructor (which enforces ≥2) rejected the fixture's group. The
fixture was corrected in spec v0.74.1.
That episode is the argument for this proposal. A normative MUST with no conformance fixture and
no defined error is a latent cross-implementation divergence:
- An implementation that doesn't enforce ≥2 would pass the entire suite, because nothing tests rejection — the §10 rule is real but toothless.
- Worse, a fixture can silently violate the rule (as
066did) without any guard catching it.
Closing the gap needs three things the spec lacks: (1) a pinned enforcement point, (2) an error the
conformance harness can assert against (prompt-management's error model is fully categorized — every
raises: assertion names a category), and (3) a fixture that exercises rejection.
Proposed change¶
§10 PromptGroup — add an enforcement sentence alongside the existing two-or-more rule:
Constructing a
PromptGroupwhosememberscontains fewer than two elements (an empty or single-member group) MUST raiseprompt_group_invalid(§11). Enforcement is at construction time — the earliest point at which the member set is known — so an invalid group never reaches rendering, an LLM call, or observability emission.
§11 Errors — add a fourth canonical category, modeled on the existing prompt_render_error shape
(one coarse category with a list of triggers):
prompt_group_invalid—PromptGroupconstruction violated a §10 group-validity rule. Raised atPromptGroupconstruction. Currently raised when:memberscontains fewer than two elements (an empty or single-member group), violating §10's two-or-more-members rule.Non-transient (a caller contract violation; constructing again with the same members will not succeed without changing them). Future group-validity rules (e.g. duplicate or null members) extend this trigger list under the same category rather than minting new ones.
Conformance — new fixtures under spec/prompt-management/conformance/ exercising
construct_prompt_group (the existing group-construction directive, per fixture 011) with an
invalid member count and asserting the raise.
Conformance test impact¶
New fixtures (numbers assigned at Accept; appended after 034), complementing 011
(which covers only the valid N>2 case):
- Single-member group rejected —
construct_prompt_groupwith one member assertsraises: {category: prompt_group_invalid}at construction. - Empty group rejected —
construct_prompt_groupwith zero members asserts the same.
No change to existing fixtures (011's valid-group assertions are unaffected; the corrected 066
already holds a valid two-member group).
Versioning¶
MINOR bump (pre-1.0), additive: a new public error category (prompt_group_invalid), the pinned
enforcement of an already-stated MUST, and new fixtures. The valid-group contract is unchanged — no
existing conforming construction starts failing.
Alternatives considered¶
- Leave construction rejection undefined (status quo). Reject — that is precisely the gap that
let
066slip; cross-impl uniformity requires the error pinned and a fixture testing it. - Reuse an existing §11 category. Reject —
prompt_not_found/prompt_render_error/prompt_store_unavailableare operational/runtime errors with no semantic fit for a construction precondition violation. - A category-agnostic "construction raises" assertion shape instead of a named category. Reject
— prompt-management's error model is fully categorized (every
raises:asserts acategory); a one-off uncategorized raise would be the lone exception and would give no stable cross-impl signal to assert on. - Enforce at render / first use rather than construction. Reject — construction is the earliest point the member set is known and gives the fastest, clearest feedback; deferring to use permits an invalid group to exist transiently and pushes the error further from its cause.
Open questions¶
None blocking — resolved during drafting:
- Category name & generality — RESOLVED.
prompt_group_invalid(not the narrowerprompt_group_arity_invalid), defined as a general group-construction-validity category with member-count (arity) as the currently-specified trigger — mirroring §11's existingprompt_render_error(one coarse category, a list of triggers). Future group-validity rules (duplicate / null members) add triggers under the same category rather than minting new ones. A dedicated category (vs. a category-agnostic construction-raises assertion shape) keeps the conformance harness asserting on a stablecategory, consistent with prompt-management's fully-categorized error model.
Out of scope¶
- The two-or-more-members rule itself — it stands per §10; this proposal enforces it, it does not change it.
- Construction-precondition validation for other spec objects (
RuntimeConfig, etc.) — scoped toPromptGrouphere. - Member-content validation beyond count (duplicate members, null members) — a future proposal if a need arises.