Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .changeset/prompt-template-experimental-marking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
"@objectstack/spec": patch
---

docs(spec): mark `PromptTemplate.system` / `.user` `[EXPERIMENTAL — not enforced]` (#15954, #16321)

Prose only. `Clause-②: no` — no accept-set change, no new/narrowed authorable
key, no matrix declaration. Every value that parsed before parses now, and
every value refused before is refused identically.

Under the #15954 ruling (decision batch #56, option B) the template-typed pair
is **marked, not retired**. Both `.describe()` strings on
`ai/PromptTemplateSchema` now carry the repo's existing
`[EXPERIMENTAL — not enforced]` prefix and state that no runtime renders or
executes the template today:

```ts
system: TemplateExpressionInputSchema.optional().describe('[EXPERIMENTAL — not enforced] System prompt — supports {{var}} interpolation. No runtime renders or executes the template today.'),
user: TemplateExpressionInputSchema.describe('[EXPERIMENTAL — not enforced] User prompt template — supports {{var}} interpolation. No runtime renders or executes the template today.'),
```

**Why an author sees this.** `PromptTemplateSchema` has no consumer outside
`packages/spec`, so the `{{var}}` holes are never interpolated and the declared
`variables` are never checked against them. The ADR-0058 D7 conformance ledger
already recorded that verdict (`template-prompt`, `state: 'experimental'`,
`PARSE ONLY — NO EVALUATOR FOUND`); until now nothing said it at the
declaration, so the generated reference page advertised a capability the
runtime does not deliver.

**What does NOT change.** `.user` remains **required** and `.system` remains
optional — the schema shape is untouched. Optionalising or retiring a required
key is a parse-breaking change and is deliberately left to its own card. No
tombstone and no ADR-0087 entry is owed: nothing is renamed, retired or
re-typed.
8 changes: 4 additions & 4 deletions content/docs/references/ai/model-registry.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ const result = ModelCapabilitySchema.parse(data);
| **id** | `string` | ✅ | Unique template identifier |
| **name** | `string` | ✅ | Template name (snake_case) |
| **label** | `string` | ✅ | Display name |
| **system** | `string \| { dialect: 'template'; source?: string; ast?: any; meta?: object }` | optional | System prompt — supports `{{var}}` interpolation |
| **user** | `string \| { dialect: 'template'; source?: string; ast?: any; meta?: object }` | ✅ | User prompt template — supports `{{var}}` interpolation |
| **system** | `string \| { dialect: 'template'; source?: string; ast?: any; meta?: object }` | optional | [EXPERIMENTAL — not enforced] System prompt — supports `{{var}}` interpolation. No runtime renders or executes the template today. |
| **user** | `string \| { dialect: 'template'; source?: string; ast?: any; meta?: object }` | ✅ | [EXPERIMENTAL — not enforced] User prompt template — supports `{{var}}` interpolation. No runtime renders or executes the template today. |
| **assistant** | `string` | optional | Assistant message prefix |
| **variables** | `{ name: string; type?: Enum<'string' \| 'number' \| 'boolean' \| 'object' \| 'array'>; required?: boolean; defaultValue?: any; … }[]` | optional | Template variables |
| **modelId** | `string` | optional | Recommended model ID |
Expand Down Expand Up @@ -260,8 +260,8 @@ const result = ModelCapabilitySchema.parse(data);
| **id** | `string` | ✅ | Unique template identifier |
| **name** | `string` | ✅ | Template name (snake_case) |
| **label** | `string` | ✅ | Display name |
| **system** | `string \| { dialect: 'template'; source?: string; ast?: any; meta?: object }` | optional | System prompt — supports `{{var}}` interpolation |
| **user** | `string \| { dialect: 'template'; source?: string; ast?: any; meta?: object }` | ✅ | User prompt template — supports `{{var}}` interpolation |
| **system** | `string \| { dialect: 'template'; source?: string; ast?: any; meta?: object }` | optional | [EXPERIMENTAL — not enforced] System prompt — supports `{{var}}` interpolation. No runtime renders or executes the template today. |
| **user** | `string \| { dialect: 'template'; source?: string; ast?: any; meta?: object }` | ✅ | [EXPERIMENTAL — not enforced] User prompt template — supports `{{var}}` interpolation. No runtime renders or executes the template today. |
| **assistant** | `string` | optional | Assistant message prefix |
| **variables** | `{ name: string; type?: Enum<'string' \| 'number' \| 'boolean' \| 'object' \| 'array'>; required?: boolean; defaultValue?: any; … }[]` | optional | Template variables |
| **modelId** | `string` | optional | Recommended model ID |
Expand Down
4 changes: 3 additions & 1 deletion packages/qa/dogfood/test/expression-conformance.ledger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,9 @@ export const EXPRESSION_SURFACE: ExprSurface[] = [
'ai/model-registry.zod.ts:PromptTemplateSchema.system',
'ai/model-registry.zod.ts:PromptTemplateSchema.user',
],
note: 'EXPERIMENTAL — declared prompt templates with no runtime evaluator (ADR-0049). Ownership was checked before classifying rather than assumed: the card that appeared to own these keys is closed as completed, and its delivered diff (`d355c361157`) touched exactly one file, `skills/objectstack-ai/SKILL.md` — it corrected a prose clause that called these keys CEL, and never owned a ledger row. No open card owns them.',
// Ruling: #15954 (decision batch #56, option B for the template family). The tracker ids live
// here, not in the string: `note` is runtime prose (check:doc-authoring, cross-package prose-id leg).
note: 'EXPERIMENTAL — declared prompt templates with no runtime evaluator (ADR-0049), and MARKED as such at the declaration under the marking ruling (option B: this pair is marked, NOT retired). Both positions this row covers — `PromptTemplateSchema.system` and `PromptTemplateSchema.user` — now carry the `[EXPERIMENTAL — not enforced]` prefix in their own `.describe()`, stating that no runtime renders or executes the template today, so an author reading the generated reference page gets the same verdict this row records instead of having to find this ledger. The marking is PROSE ONLY: `.user` remains REQUIRED (no `.optional()`) and `.system` keeps the `.optional()` it already had — optionalising or retiring a required key is parse-breaking and is its own card. Ownership was checked before classifying rather than assumed: the card that appeared to own these keys is closed as completed, and its delivered diff (`d355c361157`) touched exactly one file, `skills/objectstack-ai/SKILL.md` — it corrected a prose clause that called these keys CEL, and never owned a ledger row. No open card owns them.',
},
{
id: 'template-title-format',
Expand Down
4 changes: 2 additions & 2 deletions packages/spec/src/ai/model-registry.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ export const PromptTemplateSchema = lazySchema(() => z.object({
label: z.string().describe('Display name'),

/** Template Content */
system: TemplateExpressionInputSchema.optional().describe('System prompt — supports {{var}} interpolation'),
user: TemplateExpressionInputSchema.describe('User prompt template — supports {{var}} interpolation'),
system: TemplateExpressionInputSchema.optional().describe('[EXPERIMENTAL — not enforced] System prompt — supports {{var}} interpolation. No runtime renders or executes the template today.'),
user: TemplateExpressionInputSchema.describe('[EXPERIMENTAL — not enforced] User prompt template — supports {{var}} interpolation. No runtime renders or executes the template today.'),
assistant: z.string().optional().describe('Assistant message prefix'),

/** Variables */
Expand Down
Loading