Topic Constraints¶
Prisma AIRS enforces hard limits on custom topic definitions. Daystrom handles these automatically so you don't have to worry about truncation or rejection.
Limits¶
| Field | Max Length |
|---|---|
| Name | 100 characters |
| Description | 250 characters |
| Each example | 250 characters |
| Examples count | 2--5 |
| Combined (description + all examples) | 1000 characters |
UTF-8 Byte Length
All length checks use UTF-8 byte length, not character count. Multi-byte characters (emoji, non-ASCII) consume more than one unit toward the limit.
Automatic Clamping¶
The LLM frequently exceeds the 250-character description limit — natural language tends to be verbose. The clampTopic() function enforces limits automatically after every LLM call:
graph TD
A[LLM Output] --> B{Name > 100?}
B -->|Yes| C[Truncate name]
B -->|No| D{Examples > 250 each?}
C --> D
D -->|Yes| E[Truncate each example]
D -->|No| F{Combined > 1000?}
E --> F
F -->|Yes| G[Drop trailing examples]
G --> H{Still > 1000?}
H -->|Yes| I[Truncate description]
H -->|No| J[Done]
F -->|No| J
I --> J
The strategy is ordered by impact: drop trailing examples first, truncate the description only as a last resort. This preserves as much semantic content as possible.
Why post-LLM, not Zod
Clamping happens after the LLM generates output, not via Zod schema validation. The LLM needs freedom to produce natural descriptions, and the priority-based truncation logic is more nuanced than schema constraints can express.
Validation vs. Clamping¶
src/core/constraints.ts exports two approaches:
| Function | What it does |
|---|---|
| Validation | Checks all limits, returns error strings. Non-destructive — useful for diagnostics and tests. |
| Clamping | Silently enforces all limits by truncating and dropping as needed. Used in the production pipeline. |
Topic Name Locking¶
Info
After iteration 1, the topic name is locked — only the description and examples change in subsequent iterations. This prevents AIRS sync issues from name changes mid-run.