Replies: 1 comment 1 reply
|
Numbers from the Stolperfalle install, since you asked for real corpus data. Corpus: 194 units, 2026-04-20 → 2026-07-29, one install. 150 Lengths in characters:
Counts over thresholds: 60/194 summaries exceed 200 chars (0 exceed 300); 9 details exceed 2000, 1 exceeds 3000, 0 exceed 4000; 0 actions exceed 1000.
The reason is structural, and it's the thing I'd most want folded into the RFC: Rule of thumb I'd suggest for the numbers generally: ceiling ≥ 2× the observed max on any field carrying substance. The related fields — all fine against our data, no objection to any of them:
One note on On the split — agreed, and for the reason you give. Hard enforcement where content crosses the wire into bounded storage, soft Two additions to the implementer guidance, both cheap:
And one on rollout: publishing the bounds as machine-readable constants in the SDKs (not just in the JSON Schema) is what actually stops implementations from re-inventing private ceilings. We read the schema, but a Go or Python implementer who wants a pre-flight check before the wire will hardcode a number unless the SDK hands them one. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Problem
schema/knowledge_unit.jsondeclares the three insight fields as unbounded strings:There is no
maxLengthanywhere on them, and neither SDK (sdk/python,sdk/go) constrains them either. That has two consequences for anyone building a conforming implementation:varchar(n), a key-length-limited index, a size-capped document field) can accept a schema-valid unit at its API boundary and then fail, or be forced to truncate, at the storage layer. Truncation silently corrupts the insight (the caveat or theactioncan be in the dropped tail); failing turns a should-be-clean rejection into a low-level driver error.Today the only guidance is soft prose in the prompts (
plugins/cq/skills/cq/SKILL.md: "summary — One-line description…";sdk/*/prompts/reflect.md: "detail — two to four sentences…"). That prose shapes authoring, but it is not part of the contract and nothing enforces it: a producer that ignores it (or an LLM author that runs long) emits a unit that passes validation and breaks downstream.Proposal
Add a hard
maxLengthto each insight field. Straw values, open to input:maxLengthsummarydetailactionRationale:
summaryis a headline, so a few hundred characters is generous. The fidelity of an insight lives indetail(andaction), so those stay large; a tightsummarycap does not cost fidelity because the substance was never meant to live there.detailcarries the largest multiple deliberately. Its ceiling is sized against the machine author, not the soft target: real corpora already graze 4000 on a small first pass, anddetailis the one field whose fat tail the "two to four sentences" guidance cannot bind. Fields with a bounded shape (summaryis a headline,actionis an instruction) stay near ~2× their observed maxima;detailis set well above that so an ordinary unit is never rejected as corpora grow.The principle: hard where it must be enforced, soft where content is opaque
The fix should be consistent with how the schema already bounds things, which splits cleanly:
maxLength(schema-enforced) for fields that are core content, cross the wire, and land in bounded storage:summary/detail/action. ASHOULDcannot prevent a storage-layer failure, so these need enforcement.SHOULDcap (documented, not enforced) for opaque, implementation-specific content that naturally lands in unbounded storage: theextensionsslot. This matches the size-guidance direction already being scoped in Scoping the `extensions` slot (follow-up to #286) #411.extensionstoday is already the best-bounded part of the schema (maxProperties: 20, anamespace:keyformat constraint, producerSHOULDguidance); its values are intentionally opaque, so a soft cap is the right tool there. The insight fields are the conspicuous gap.Related free-text fields (same class; bound together)
For completeness, these are also unbounded strings today and share the same "valid at the boundary, unstorable downstream" property. Proposing modest caps so we don't fix one field and leave the class latent; happy to split these into their own thread if they're contentious:
maxLengthdomains[]itemscreated_bycontext.patterncontext.languages[]/context.frameworks[]itemsflags[].detailAlso bound array cardinality (
maxItems)The same "valid at the boundary, expensive downstream" property applies to the number of items in the producer-supplied arrays, not just each item's length. An unbounded
domains/languages/frameworksarray is schema-valid but can overrun bounded storage (a join table, an index, a size-capped document) the same way an unbounded string does.extensionsis already cardinality-bounded (maxProperties: 20); these producer arrays are the remaining gap.Adding a hard
maxItemsto the producer-supplied arrays (ceilings, not targets — nothing real approaches them):maxItemsdomains[]context.languages[]context.frameworks[]flags[]is intentionally left unbounded: it is server-managed and append-only over a unit's lifetime (not producer-supplied) and internal (never returned to querying agents), so a cap would block recording legitimate flags on a contentious unit rather than protect a producer.Like the length bounds, these apply consistently wherever the arrays are redeclared at the wire boundary (
propose.json,query.json), and are part of the same breaking tightening.Compatibility and rollout
Field(max_length=…)) and the Go types, with fixtures/round-trip tests.detail: 8420 exceeds maxLength 8000lets it re-emit a shorter unit on its own; an opaque validation failure just loses the insight.maxLengthcounts Unicode code points, not bytes. Sizing avarchar(n)or byte-capped column needs up to 4× the number in bytes for UTF-8; mixed-script corpora make this a real source of storage-layer failure, not a hypothetical one.Call for input
StolpersteinStolperfalle runs againstschema/knowledge_unit.jsonand strips non-conforming fields at the wire, and you raised the extensions size-cap question in Scoping the `extensions` slot (follow-up to #286) #411, so your read here would be especially useful: do the straw ceilings fit what your deployments already store, and does the "hard for core insight fields / soft forextensions" split match how you'd want size bounded?Builds on the
extensions-slot scoping in #411 and the original schema-extensions thread in #286.All reactions