@ai-matrx/content-ir 0.9.0 โ†’ 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +24 -5
  3. package/dist/convert.cjs +1680 -0
  4. package/dist/convert.cjs.map +1 -0
  5. package/dist/convert.d.cts +230 -0
  6. package/dist/convert.d.ts +230 -0
  7. package/dist/convert.js +1666 -0
  8. package/dist/convert.js.map +1 -0
  9. package/dist/core.cjs +2493 -0
  10. package/dist/core.cjs.map +1 -0
  11. package/dist/core.d.cts +370 -0
  12. package/dist/core.d.ts +370 -0
  13. package/dist/core.js +2452 -0
  14. package/dist/core.js.map +1 -0
  15. package/dist/index.cjs +3 -1
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +9 -2030
  18. package/dist/index.d.ts +9 -2030
  19. package/dist/index.js +3 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/ir-tree-DbLVxbf1.d.cts +441 -0
  22. package/dist/ir-tree-Dsc_66ek.d.ts +441 -0
  23. package/dist/ir-types-95bA2cXH.d.cts +119 -0
  24. package/dist/ir-types-95bA2cXH.d.ts +119 -0
  25. package/dist/kind-schema.types-CwncWj9U.d.cts +139 -0
  26. package/dist/kind-schema.types-CwncWj9U.d.ts +139 -0
  27. package/dist/registry.cjs +468 -0
  28. package/dist/registry.cjs.map +1 -0
  29. package/dist/registry.d.cts +357 -0
  30. package/dist/registry.d.ts +357 -0
  31. package/dist/registry.js +456 -0
  32. package/dist/registry.js.map +1 -0
  33. package/dist/session.cjs +2052 -0
  34. package/dist/session.cjs.map +1 -0
  35. package/dist/session.d.cts +75 -0
  36. package/dist/session.d.ts +75 -0
  37. package/dist/session.js +2047 -0
  38. package/dist/session.js.map +1 -0
  39. package/dist/wire.cjs +310 -0
  40. package/dist/wire.cjs.map +1 -0
  41. package/dist/wire.d.cts +326 -0
  42. package/dist/wire.d.ts +326 -0
  43. package/dist/wire.js +291 -0
  44. package/dist/wire.js.map +1 -0
  45. package/package.json +73 -1
package/dist/index.d.cts CHANGED
@@ -1,2030 +1,9 @@
1
- import { ComponentType } from 'react';
2
-
3
- /**
4
- * The canonical IR contract for structured content.
5
- *
6
- * Every source (live agent stream, DB reload, Python-preprocessed results,
7
- * notes, any future surface) is normalized into these shapes exactly once.
8
- * Anything already carrying this IR passes through downstream layers by
9
- * reference โ€” see `core/normalize.ts` for the idempotence law.
10
- *
11
- * This file is pure types + path helpers. No React, no Redux, no IO.
12
- */
13
- /** Path of a value inside a parsed region (object keys + array indices). */
14
- type IrPath = Array<string | number>;
15
- /**
16
- * How a node's kind was (or wasn't) established.
17
- *
18
- * ๐Ÿšจ `unverified` IS NOT `raw`, AND THE DIFFERENCE IS LOAD-BEARING (Arman's
19
- * ruling, 2026-08-29). "We checked it and it is wrong" and "we had nothing to
20
- * check it with" are opposite facts about a payload, and collapsing them cost
21
- * ~221 live kinds their component overnight: a kind whose schema never loaded
22
- * degraded to `raw`, the render route read `raw` as "broken instance", and
23
- * perfectly valid payloads were dumped as key/value lists instead of reaching
24
- * the component the user built. A consumer that treats `unverified` as a
25
- * failure is reintroducing that outage โ€” the data is intact and MAY be
26
- * entirely valid; all that is missing is the schema that would prove it.
27
- */
28
- type IrKindState = "resolved" | "speculative" | "pending_kind" | "pending_schema" | "unverified" | "raw";
29
- /**
30
- * System-level zero-data-loss channel. Unknown keys are NEVER merged into a
31
- * node's `value` (they'd be indistinguishable from schema fields); they are
32
- * carried here verbatim โ€” Protobuf unknown-fields discipline. Distinct from
33
- * any domain-level `additionalDetails` field, which is an ordinary schema
34
- * field inside `value`.
35
- */
36
- interface IrResidue {
37
- /** Keys present in the source object but absent from the kind schema. */
38
- extra: Record<string, unknown> | null;
39
- /** Optional schema fields the source never provided. */
40
- optionalMissing: string[] | null;
41
- /** Structured warnings attached during parsing (speculation backtracks, truncation, โ€ฆ). */
42
- notices: Array<{
43
- code: string;
44
- message: string;
45
- at?: number;
46
- }> | null;
47
- }
48
- /** Which wire syntax carried the kind discriminator for a node. */
49
- type IrDiscriminator = {
50
- format: "json";
51
- key: "__kind";
52
- } | {
53
- format: "xml";
54
- tag: string;
55
- } | {
56
- format: "fence";
57
- language: string;
58
- };
59
- /** A schema-shaped structured node. Children live inside `value` (and carry their own metadata via `nodeIndex`). */
60
- interface IrStructuredNode {
61
- role: "structured";
62
- /** Canonical kind slug. Empty string while pending. */
63
- kind: string;
64
- kindState: IrKindState;
65
- discriminator: IrDiscriminator;
66
- /** Region-relative path ([] = region root). */
67
- path: IrPath;
68
- status: "streaming" | "complete" | "error";
69
- /** Compliant snapshot: schema fields + __kind ONLY. Unknown keys โ†’ residue. */
70
- value: Record<string, unknown>;
71
- residue: IrResidue | null;
72
- }
73
- /** Envelope version. Bump = migration point for persisted envelopes. */
74
- declare const IR_VERSION: 1;
75
- /** Reserved key carrying the envelope inside RenderBlockPayload.data. */
76
- declare const IR_ENVELOPE_KEY: "__ir";
77
- /**
78
- * One parsed region's canonical form. Serializable (plain JSON), carried on
79
- * render blocks (`data.__ir`), persisted on artifacts and message metadata,
80
- * and โ€” with `engine: "py-block-detector"` โ€” accepted pre-built from Python.
81
- */
82
- interface CanonicalBlockIR {
83
- v: typeof IR_VERSION;
84
- /** Provenance: which implementation produced this envelope. */
85
- engine: "fe-kind-parser" | "py-block-detector";
86
- /** Stable hash of the region source text โ€” the idempotence / cache key. */
87
- fingerprint: string;
88
- root: IrStructuredNode;
89
- /**
90
- * pathKey โ†’ node metadata for per-path readers (child kinds under root).
91
- * Carries each child node's residue โ€” child snapshot values inside
92
- * `root.value` hold schema fields only, so WITHOUT this the envelope would
93
- * silently drop nested unknown keys (zero-data-loss violation).
94
- */
95
- nodeIndex?: Record<string, Pick<IrStructuredNode, "kind" | "kindState" | "status"> & {
96
- residue?: IrResidue | null;
97
- }>;
98
- }
99
- /** Normalizer output segment: prose stays raw text; structured regions carry IR. */
100
- type CanonicalSegment = {
101
- role: "text";
102
- content: string;
103
- } | {
104
- role: "block";
105
- blockType: string;
106
- content: string;
107
- ir: CanonicalBlockIR | null;
108
- };
109
- interface CanonicalContent {
110
- v: typeof IR_VERSION;
111
- segments: CanonicalSegment[];
112
- }
113
- declare function irPathKey(path: IrPath): string;
114
- declare function irPathsEqual(left: IrPath, right: IrPath): boolean;
115
- declare function irPathIsUnderOrEqual(path: IrPath, prefix: IrPath): boolean;
116
- /** Human label for a path ("root", "cards[2].front"). */
117
- declare function irPathLabel(path: IrPath): string;
118
- /** True when every residue channel is empty โ€” normalize to null instead. */
119
- declare function isEmptyResidue(residue: IrResidue): boolean;
120
-
121
- /**
122
- * KindSchema โ€” the data-defined field model for a registered kind.
123
- *
124
- * `__kind` (KIND_KEY) is the carried discriminator: it is NOT part of a
125
- * kind's field map; the parser enforces it via `KindSchema.kind` and stamps
126
- * it onto every compliant snapshot.
127
- *
128
- * Moved from app/(dev)/demos/json-block-detector/kind-schemas.ts.
129
- *
130
- * 2026-07-15 expressivity extension (A2) โ€” four constructs the Python-owned
131
- * pydantic schemas need that the v1 vocabulary could not express:
132
- * - `{type:"json"}` / `{type:"json[]"}` โ€” any JSON value / array of any
133
- * JSON values (pydantic bare `Any` fields, `items: {}` arrays, `{}`
134
- * schemas). A `json` value is implicitly nullable โ€” `null` IS a JSON
135
- * value โ€” so `nullable` is meaningless (and ignored) on it.
136
- * - `record` values widened to `"json"` (pydantic `dict[str, Any]` /
137
- * `additionalProperties: true`).
138
- * - `union` may now carry `kinds` (object unions โ€” anyOf over kind refs,
139
- * optionally mixed with scalars). Refs externalize to `kind_edge` rows
140
- * exactly like `array.itemKinds`.
141
- * - `KindSchema.root` โ€” a NON-OBJECT root form: the kind's VALUE is the
142
- * root field itself (scalar / array / json / open object), not a `__kind`
143
- * object with fields. Root-form kinds are data-only: the streaming
144
- * `__kind` parser cannot type them (a scalar cannot carry a
145
- * discriminator) and refuses them loudly; validation goes through the
146
- * emitted JSON Schema (ajv / Pydantic). `root` and a non-empty `fields`
147
- * are mutually exclusive.
148
- * - `inline_object.open` โ€” `additionalProperties: true`; fixes the
149
- * open-empty-object defect where an open `inline_object{fields:{}}`
150
- * materialized as CLOSED (schema_proposal / item_presentation class).
151
- *
152
- * 2026-07-15 input-semantics extension (W3-A, agent-input bridge) โ€” the
153
- * constructs the Wave-1 sufficiency survey of all 1,529 live agent variables
154
- * showed FieldSchema could not carry, added so `AgentVariable` โ‡„ kind
155
- * conversion is faithful:
156
- * - `FieldBase.description` โ€” human guidance; round-trips JSON Schema
157
- * `description` and VariableDefinition `helpText`.
158
- * - `FieldBase.default` โ€” the field's default VALUE (JSON Schema `default`,
159
- * VariableDefinition `defaultValue`). Annotation-level: validators never
160
- * apply it; emitters carry it verbatim.
161
- * - `enum.open` โ€” "one of these options OR any string" (the FE's
162
- * `allowOther`). Emits as `anyOf: [{type:"string", enum}, {type:"string"}]`
163
- * so the option set survives instead of widening to bare `string`.
164
- * - `number` bounds `min`/`max`/`step` โ€” JSON Schema
165
- * `minimum`/`maximum`/`multipleOf` (number/slider components).
166
- * - `string[].values` (+ `open`) โ€” an items-enum: array of strings drawn
167
- * from an option set (checkbox components), `open` meaning the set is
168
- * advisory (`allowOther` on a multi-select).
169
- * Picklist bindings, scope bindings, and media component identity are
170
- * PROVENANCE, not structure โ€” they never enter FieldSchema; the bridge
171
- * carries them out-of-band (see convert/kind-variable-bridge.ts sidecar).
172
- */
173
- /** System discriminator โ€” hardcoded, not part of per-kind field schemas. */
174
- declare const KIND_KEY = "__kind";
175
- type ScalarFieldType = "string" | "number" | "boolean";
176
- type ArrayItemScalarType = "string" | "number" | "boolean";
177
- /** Value domain of a `record` field โ€” typed scalars, or any JSON value. */
178
- type RecordValueType = ArrayItemScalarType | "json";
179
- type FieldBase = {
180
- required?: boolean;
181
- nullable?: boolean;
182
- /** Human guidance โ€” JSON Schema `description` / variable `helpText`. */
183
- description?: string;
184
- /**
185
- * Default VALUE (JSON Schema `default` / variable `defaultValue`).
186
- * Annotation-level: validators never apply it; emitters carry it verbatim.
187
- */
188
- default?: unknown;
189
- };
190
- type FieldSchema = (FieldBase & {
191
- type: "string" | "boolean";
192
- }) | (FieldBase & {
193
- type: "number";
194
- /** Inclusive lower bound โ€” JSON Schema `minimum`. */
195
- min?: number;
196
- /** Inclusive upper bound โ€” JSON Schema `maximum`. */
197
- max?: number;
198
- /** Increment โ€” JSON Schema `multipleOf`. Annotation-level in the parser. */
199
- step?: number;
200
- }) | (FieldBase & {
201
- type: "string[]";
202
- /** Items-enum: each item must be one of these values (checkbox option sets). */
203
- values?: string[];
204
- /** With `values`: the set is advisory โ€” any string item is also legal (`allowOther`). */
205
- open?: boolean;
206
- }) | (FieldBase & {
207
- type: "number[]" | "boolean[]";
208
- }) | (FieldBase & {
209
- type: "json";
210
- }) | (FieldBase & {
211
- type: "json[]";
212
- }) | (FieldBase & {
213
- type: "array";
214
- itemKinds: string[];
215
- }) | (FieldBase & {
216
- type: "object";
217
- kind: string;
218
- }) | (FieldBase & {
219
- type: "inline_object";
220
- fields: Record<string, FieldSchema>;
221
- /** additionalProperties: true โ€” unknown keys are legal, not residue-only. */
222
- open?: boolean;
223
- }) | (FieldBase & {
224
- type: "record";
225
- values: RecordValueType;
226
- }) | (FieldBase & {
227
- type: "enum";
228
- values: string[];
229
- /** "One of these OR any string" โ€” the option set is advisory (`allowOther`). */
230
- open?: boolean;
231
- }) | (FieldBase & {
232
- type: "union";
233
- scalars: Array<"string" | "number" | "boolean">;
234
- /** Object union members โ€” kind refs (anyOf of $refs), may mix with scalars. */
235
- kinds?: string[];
236
- });
237
- /**
238
- * Domain fields only โ€” __kind is enforced by the parser via KindSchema.kind
239
- * (block slug). A kind with `root` set has NO field map (fields stays `{}`):
240
- * its value is the root field's type at the top level. See the module header.
241
- */
242
- type KindSchema = {
243
- kind: string;
244
- fields: Record<string, FieldSchema>;
245
- /** Non-object root form โ€” mutually exclusive with a non-empty `fields`. */
246
- root?: FieldSchema;
247
- };
248
- declare function readObjectKind(value: Record<string, unknown>): string | null;
249
- declare function isScalarArrayType(type: FieldSchema["type"]): type is "string[]" | "number[]" | "boolean[]";
250
- declare function scalarArrayItemType(type: "string[]" | "number[]" | "boolean[]"): ArrayItemScalarType;
251
- /**
252
- * Does this field's value domain accept ANY JSON shape (object/array/scalar/
253
- * null alike)? True for `json` and `json[]` ITEMS โ€” the parser treats the
254
- * subtree under such a field as opaque (no kind identification, no raw_object
255
- * degradation: unknown structure is the declared contract, not a failure).
256
- */
257
- declare function isJsonAnyField(field: FieldSchema): boolean;
258
-
259
- /**
260
- * KindStreamParser โ€” the streaming, schema-validating, __kind-discriminated
261
- * JSON parser at the heart of content-ir.
262
- *
263
- * Frame-stack pushdown parser over JsonStreamTokenizer tokens. Every value is
264
- * path-addressed; every object resolves a kind against the schema registry;
265
- * schema-shaped `block_snapshot` events fire on field arrival so renderers
266
- * get live partials; unknown/invalid structures degrade to `raw_object`
267
- * instead of failing the stream.
268
- *
269
- * The pushdown discipline (commit โ†’ descend โ†’ never re-ask โ†’ backtrack):
270
- * - SPECULATIVE DESCENT: when a parent field schema predicts a child's kind
271
- * ({type:"object", kind} or {type:"array", itemKinds:[K]} with one member),
272
- * the child commits to that kind THE INSTANT `{` opens and renders a
273
- * placeholder snapshot. `__kind` arrival confirms (no-op), re-tags (allowed
274
- * sibling kind), or backtracks to raw (contradiction). An object under a
275
- * predicting parent doesn't even need `__kind` โ€” prediction alone types it.
276
- * - PENDING SCHEMA: an identified kind whose schema isn't loaded holds the
277
- * node open (`pending_schema` event, fields keep accumulating), fires the
278
- * resolver's cold fetch, and upgrades in place via `notifySchemaArrived` โ€”
279
- * even after the node (or the whole region) has closed.
280
- * - POP-UP-ONE-LEVEL: node-scoped problems (duplicate key, schema violation,
281
- * disallowed itemKind) mark THAT node raw and keep parsing the parent.
282
- * Only grammar/tokenizer errors are region-fatal โ€” and the host degrades
283
- * the region to a plain code block, never the stream.
284
- */
285
-
286
- /** Kept as the historical name for the parser's event paths. */
287
- type JsonPath = IrPath;
288
- /**
289
- * Schema source abstraction. A plain Record works for static sets; the
290
- * registry supplies a resolver whose `request` fires a cold fetch and later
291
- * calls `parser.notifySchemaArrived`.
292
- */
293
- interface SchemaResolver {
294
- get(kind: string): KindSchema | undefined;
295
- /** Fire-and-forget cold fetch. Absent = static source, unknown kinds go raw. */
296
- request?(kind: string): void;
297
- /**
298
- * Optional per-resolver override for legacy root-key recognition. Most hosts
299
- * leave this unset and register the lookup once via
300
- * `setJsonRootKeyLookup` โ€” see that function for why.
301
- */
302
- kindForJsonRootKey?(key: string): string | null;
303
- }
304
- declare function setJsonRootKeyLookup(lookup: ((key: string) => string | null) | null): void;
305
- /**
306
- * Why a node degraded off the `resolved` path.
307
- *
308
- * `"unverified"` is reserved for ONE situation: no schema was registered for
309
- * an identified kind, so no check ever ran. Every other degrade โ€” a schema
310
- * violation, an array-item kind mismatch, a duplicate key, a bad field
311
- * placement, a contradicted speculation โ€” is `"invalid"`: something checked
312
- * the node and it failed.
313
- */
314
- type RawObjectCause = "unverified" | "invalid";
315
- type KindStreamEvent = {
316
- type: "kind_identified";
317
- kind: string;
318
- path: JsonPath;
319
- /** True when committed from the parent schema before __kind arrived. */
320
- speculative?: boolean;
321
- at: number;
322
- } | {
323
- type: "pending_kind";
324
- path: JsonPath;
325
- at: number;
326
- } | {
327
- type: "kind_wait_end";
328
- path: JsonPath;
329
- outcome: "identified" | "raw_fallback";
330
- kind?: string;
331
- reason?: string;
332
- at: number;
333
- } | {
334
- type: "pending_schema";
335
- kind: string;
336
- path: JsonPath;
337
- at: number;
338
- } | {
339
- type: "field";
340
- kind: string;
341
- path: JsonPath;
342
- key: string;
343
- value: unknown;
344
- at: number;
345
- } | {
346
- type: "object_start";
347
- path: JsonPath;
348
- at: number;
349
- } | {
350
- type: "object_complete";
351
- kind: string;
352
- path: JsonPath;
353
- value: Record<string, unknown>;
354
- at: number;
355
- } | {
356
- type: "raw_object";
357
- path: JsonPath;
358
- value: unknown;
359
- reason: string;
360
- /**
361
- * The kind that WAS identified for this node before it degraded โ€” set
362
- * for schema-availability degrades AND (since 2026-08-29) structural
363
- * ones, so a payload that said what it is stays acknowledged as an
364
- * instance of that kind. Absent only when nothing ever identified it
365
- * (an object with no `__kind` at all).
366
- */
367
- kind?: string;
368
- /**
369
- * WHY this node is not `resolved` โ€” the discriminator the render route
370
- * reads. See `IrKindState` for why collapsing these two is an outage.
371
- *
372
- * - `"unverified"`: no schema was available, so nothing was checked.
373
- * The value is intact and may be perfectly valid.
374
- * - `"invalid"` (default): a check RAN and the node failed it, or the
375
- * node is structurally broken (duplicate key, bad placement).
376
- */
377
- cause?: RawObjectCause;
378
- at: number;
379
- } | {
380
- type: "optional_field_missing";
381
- kind: string;
382
- path: JsonPath;
383
- field: string;
384
- at: number;
385
- } | {
386
- type: "extra_field";
387
- kind: string;
388
- path: JsonPath;
389
- field: string;
390
- at: number;
391
- } | {
392
- type: "block_snapshot";
393
- kind: string;
394
- path: JsonPath;
395
- value: Record<string, unknown>;
396
- residue: IrResidue | null;
397
- complete: boolean;
398
- at: number;
399
- } | {
400
- type: "array_start";
401
- path: JsonPath;
402
- field: string;
403
- at: number;
404
- } | {
405
- type: "complete";
406
- kind: string;
407
- value: unknown;
408
- at: number;
409
- } | {
410
- type: "error";
411
- reason: string;
412
- at: number;
413
- };
414
- type KindStreamParserOptions = {
415
- onEvent: (event: KindStreamEvent) => void;
416
- schemas: Record<string, KindSchema> | SchemaResolver;
417
- /**
418
- * Known-context root prediction (e.g. "this agent's output schema is
419
- * flashcard_set"). The root commits speculatively at `{` open โ€” the Option-1
420
- * provenance path for agents whose schemas don't carry __kind yet.
421
- */
422
- expectedRootKind?: string;
423
- };
424
- declare class KindStreamParser {
425
- private readonly resolver;
426
- private readonly stack;
427
- private readonly objectKinds;
428
- private readonly inlineSchemas;
429
- private readonly recordSchemas;
430
- private readonly rawObjectPaths;
431
- /**
432
- * Subtrees whose value domain is "any JSON" by schema (`json` / `json[]`
433
- * fields, `record` with `values:"json"` members). OPAQUE by contract: no
434
- * kind identification, no pending_kind, no raw_object degradation โ€” unknown
435
- * structure here is the declared shape, not a failure. Propagates to every
436
- * descendant compound.
437
- */
438
- private readonly opaquePaths;
439
- private readonly deferredFields;
440
- private readonly awaitingKindPaths;
441
- /** Paths whose kind came from parent-schema prediction, unconfirmed so far. */
442
- private readonly speculativeKinds;
443
- /**
444
- * Kind named by the root object's FIRST key through the `json_root_key`
445
- * surface registry โ€” a candidate, adopted only at root finalize.
446
- */
447
- private rootSurfaceKind;
448
- /** kind โ†’ paths (by key) waiting for the resolver's cold fetch. */
449
- private readonly pendingSchemaPaths;
450
- /** Pending-schema paths whose object already closed. */
451
- private readonly closedPendingPaths;
452
- /** Schemas delivered via notifySchemaArrived (overlay over the resolver). */
453
- private readonly arrivedSchemas;
454
- private tokenizer;
455
- private root;
456
- private rootKind;
457
- private rootDone;
458
- private failed;
459
- private readonly options;
460
- constructor(options: KindStreamParserOptions);
461
- push(chunk: string): void;
462
- end(): void;
463
- private resolvePendingSchemasAsRaw;
464
- /** True once the root value has closed โ€” the region is fully consumed. */
465
- get isComplete(): boolean;
466
- get hasFailed(): boolean;
467
- /**
468
- * Upgrade-in-place: the registry's cold fetch answered. Pending nodes for
469
- * this kind validate and complete (closed nodes retroactively); a null
470
- * schema (fetch miss) drops them to raw. Safe to call after end().
471
- */
472
- notifySchemaArrived(kind: string, schema: KindSchema | null): void;
473
- private handleToken;
474
- private handleString;
475
- private handlePunctuation;
476
- private beginCompound;
477
- /**
478
- * THE JSON-ROOT-KEY SURFACE โ€” `content_ir.kind_surface` rows of type
479
- * `json_root_key`, live at last (they were inert phantom rows until
480
- * 2026-08-20).
481
- *
482
- * A legacy payload such as `{"quiz_title": ...}` carries no `__kind`, but
483
- * the ONE surface registry knows exactly which kind that root key names โ€”
484
- * the same lookup the SERVER performs before adapting the payload
485
- * (`aidream .../processing/blocks/envelope.py`). Consulting it HERE, in the
486
- * shared parser core, is what makes one place decide it: both hosts โ€” the
487
- * one-shot `normalizeJsonRegion` (DB reload / reconcile) and the live
488
- * `openParseSession` (streaming) โ€” build their parser through
489
- * `createKindStreamParser`, so neither passes an option and neither can
490
- * drift from the other.
491
- *
492
- * Recorded at the first root key; ADOPTED only when the root object closes
493
- * (`completeTypedObject`). That is the surface registry's complete-only
494
- * convergence law, and every json_root_key row is `streaming:false` โ€” these
495
- * legacy shapes are recognized by their whole payload, so speculating
496
- * mid-stream would flash a kind component over an object that may never
497
- * satisfy the schema. An explicit `expectedRootKind` (an agent's declared
498
- * output schema) is stronger context and always wins; an actual `__kind`
499
- * still wins over both.
500
- */
501
- private noteRootSurfaceKind;
502
- /**
503
- * Prediction from the parent schema: object field โ†’ declared kind; array
504
- * item โ†’ sole itemKind; root โ†’ expectedRootKind. Only when the schema is
505
- * actually resolvable (a prediction we can't validate against is not a
506
- * commitment worth making).
507
- */
508
- private resolveSpeculativeKind;
509
- /**
510
- * A schema usable for OBJECT speculation/snapshots โ€” root-form kinds
511
- * (non-object data-only shapes) are never a valid object commitment.
512
- */
513
- private lookupObjectSchema;
514
- private beginScalar;
515
- private placeValue;
516
- private acceptObjectKey;
517
- private acceptColon;
518
- private acceptComma;
519
- private closeCompound;
520
- /**
521
- * True when a value placed at `path` sits directly under a json-any
522
- * placement: a `json`/`json[]` FIELD, or a member of a `record` whose
523
- * values are `"json"`. (Deeper descendants inherit via `opaquePaths`.)
524
- */
525
- private isJsonAnyPlacement;
526
- private onValueFinalized;
527
- /** __kind arrived for an object โ€” confirm speculation, identify, or backtrack. */
528
- private onKindDiscriminatorArrived;
529
- /** A contradicted speculation may re-tag only where the new kind is legal. */
530
- private speculativeRetagAllowed;
531
- private addPendingSchemaPath;
532
- private completeTypedObject;
533
- /** Validate + complete an object whose value carries __kind. */
534
- private finalizeTypedObject;
535
- /** Validate + complete an object typed purely by parent prediction. */
536
- private finalizeSpeculatedObject;
537
- private validateArrayItemKind;
538
- private completeRoot;
539
- /** Mark a node raw (node-scoped failure) without killing the stream. */
540
- private markNodeRaw;
541
- /**
542
- * Degrade ONE node off the resolved path.
543
- *
544
- * `cause` defaults to `"invalid"` deliberately: every call site that omits
545
- * it is a real failure (validation, duplicate key, placement, contradicted
546
- * speculation). ONLY the "no schema registered" sites pass `"unverified"`,
547
- * and they are the reason the parameter exists โ€” see `IrKindState`.
548
- */
549
- private emitRawObject;
550
- private clearKindWait;
551
- private emitFieldIfReady;
552
- private flushDeferredFields;
553
- private getLiveObjectValue;
554
- private emitBlockSnapshotForObject;
555
- /**
556
- * On `complete` snapshots (and post-close schema upgrades) the frame has
557
- * already been popped โ€” the finalized value lives in the root tree.
558
- */
559
- private getFinalizedObjectValue;
560
- private validateFieldPlacement;
561
- private emitSchemaNotices;
562
- private validateObjectAgainstSchema;
563
- private validateFinalFieldValue;
564
- private validateValueAgainstField;
565
- private validateScalarField;
566
- private validateRecordScalar;
567
- private validateRecordObject;
568
- private validateObjectAgainstFields;
569
- private registerObjectContext;
570
- private resolveParentFieldSchema;
571
- private getObjectKindForPath;
572
- private getDirectObjectKind;
573
- private isAllowedSchemaField;
574
- private parentFieldName;
575
- private fieldKeyFromPath;
576
- private isKindFieldPath;
577
- private pathKey;
578
- private lookupSchema;
579
- private fail;
580
- private emit;
581
- private currentFrame;
582
- }
583
- declare function createKindStreamParser(options: KindStreamParserOptions): KindStreamParser;
584
-
585
- /**
586
- * IrTree โ€” the immutable, structurally-shared view of a parsed region.
587
- *
588
- * Consumes KindStreamEvents and maintains one node per kind-resolved path.
589
- * Node values are STABILIZED: compound children that are themselves kind
590
- * nodes are substituted by their current tree value, so an update to
591
- * cards[7] produces new identities for root โ†’ cards โ†’ cards[7] ONLY;
592
- * cards[0..6] keep referential identity and memoized components bail out.
593
- *
594
- * Parser frame values are NEVER exposed โ€” everything handed out is rebuilt
595
- * copy-on-write, so it is safe to freeze (Redux dev-mode immutability) and
596
- * safe to hold across renders.
597
- *
598
- * Both the live ParseSession and the one-shot normalizer build their
599
- * CanonicalBlockIR from this tree โ€” one assembly path, structurally
600
- * identical output for stream and static input.
601
- */
602
-
603
- interface IrTreeNode {
604
- kind: string;
605
- kindState: IrKindState;
606
- path: IrPath;
607
- pathKey: string;
608
- /** Stabilized immutable snapshot value (schema fields + __kind only). */
609
- value: Record<string, unknown>;
610
- residue: IrResidue | null;
611
- complete: boolean;
612
- /** Bumps on every update to this node (incl. child propagation). */
613
- version: number;
614
- }
615
- declare class IrTree {
616
- private readonly nodes;
617
- private readonly rawPaths;
618
- private readonly dirty;
619
- /**
620
- * KIND PRESERVATION (streaming db/cloud kinds): pathKey โ†’ identified kind
621
- * for nodes whose kind is KNOWN (kind_identified / pending_schema) but that
622
- * have no snapshot node yet because the schema is still cold-fetching.
623
- * Without this, the envelope reports `kind: ""` for the whole pending
624
- * window and the render seam can only show raw JSON.
625
- */
626
- private readonly identifiedKinds;
627
- /** pathKeys currently waiting on a schema cold fetch. */
628
- private readonly pendingSchemaPaths;
629
- /**
630
- * Early top-level scalar fields (title, loading_message, โ€ฆ) captured for
631
- * identified-but-schema-pending nodes โ€” the loading-component fuel. Scalars
632
- * only (no live parser references can escape through here). Superseded the
633
- * moment a real snapshot node exists.
634
- */
635
- private readonly earlyFields;
636
- /**
637
- * pathKey โ†’ identified kind preserved through a raw fallback (parser stamped
638
- * `kind` on the raw_object event) โ€” schema-availability degrades and, since
639
- * 2026-08-29, structural ones too. Only a node nothing ever identified (no
640
- * `__kind` at all) is absent here.
641
- */
642
- private readonly rawKinds;
643
- /**
644
- * pathKey โ†’ WHY the node degraded. `"unverified"` means no schema was
645
- * available and nothing was ever checked; `"invalid"` means a check ran and
646
- * failed. THE RENDER ROUTE BRANCHES ON THIS โ€” see `IrKindState`. Absent =
647
- * `"invalid"`, so a parser that predates the `cause` field (or any consumer
648
- * hand-building events) keeps the strict, safe reading.
649
- */
650
- private readonly rawCauses;
651
- private regionStatus;
652
- private errorReason;
653
- private rootRawValue;
654
- /** Notices for degrades that tried to erase already-published data. */
655
- private readonly rescueNotices;
656
- private completedKind;
657
- get status(): "streaming" | "complete" | "error";
658
- applyEvent(event: KindStreamEvent): void;
659
- getNode(pathKey: string): IrTreeNode | null;
660
- listNodes(): IrTreeNode[];
661
- isRawPath(pathKey: string): boolean;
662
- /** Dirty pathKeys since the last drain โ€” the flush/notify unit. */
663
- drainDirty(): string[];
664
- hasDirty(): boolean;
665
- private upsertNode;
666
- /**
667
- * Substitute kind-node children with their current tree values so sibling
668
- * identities are stable; deep-copy everything else so no live parser
669
- * reference ever escapes.
670
- */
671
- private stabilizeValue;
672
- /**
673
- * COW spine rebuild: replace the child's slot in each ancestor kind-node's
674
- * value, shallow-copying only the containers along the way. Siblings keep
675
- * identity; every ancestor gets a new value identity + version bump.
676
- */
677
- private propagateToAncestors;
678
- private findNearestAncestorNode;
679
- private cloneAlong;
680
- private markRaw;
681
- /**
682
- * A rescue means a degrade tried to erase data a user could already see โ€”
683
- * an upstream defect. It rides the envelope as a notice so it surfaces in the
684
- * Error Inspector instead of being silently absorbed (`core/` is a pure
685
- * kernel: no console, no capture โ€” the notice IS the alarm).
686
- */
687
- private recordRescue;
688
- /**
689
- * Assemble the canonical envelope. ONE code path for stream + one-shot.
690
- * Callers supply the fingerprint (one-shot hashes the source; live sessions
691
- * keep an incremental hasher so no per-flush re-hash happens).
692
- */
693
- buildEnvelope(fingerprint: string): CanonicalBlockIR;
694
- }
695
-
696
- /**
697
- * Character-level incremental JSON tokenizer. Survives chunk boundaries
698
- * mid-token (strings, escapes, unicode sequences, primitives). Pure โ€” no
699
- * React, no Redux, no IO.
700
- *
701
- * Moved from app/(dev)/demos/json-block-detector/reusable-logic.ts (the demo
702
- * is now a consumer of this library).
703
- */
704
- type Punct = "{" | "}" | "[" | "]" | ":" | ",";
705
- type JsonToken = {
706
- type: "punct";
707
- value: Punct;
708
- at: number;
709
- } | {
710
- type: "string";
711
- value: string;
712
- at: number;
713
- } | {
714
- type: "number";
715
- value: number;
716
- at: number;
717
- } | {
718
- type: "boolean";
719
- value: boolean;
720
- at: number;
721
- } | {
722
- type: "null";
723
- value: null;
724
- at: number;
725
- };
726
- declare class JsonStreamTokenizer {
727
- private mode;
728
- private pos;
729
- private stringBuffer;
730
- private primitiveBuffer;
731
- private unicodeBuffer;
732
- private tokenStart;
733
- private readonly onToken;
734
- constructor(onToken: (token: JsonToken) => void);
735
- get position(): number;
736
- push(chunk: string): void;
737
- end(): void;
738
- private handleNormalChar;
739
- private emitPrimitive;
740
- private isDelimiter;
741
- }
742
-
743
- /**
744
- * Compliant snapshot builder โ€” the guarantee that a renderer always receives
745
- * a well-formed, schema-shaped object even mid-stream.
746
- *
747
- * ZERO DATA LOSS: unknown keys are NOT merged into the snapshot value (they
748
- * would be indistinguishable from schema fields). They are returned on the
749
- * residue channel and re-merged only at wire-serialization time via
750
- * `mergeResidueIntoValue`.
751
- */
752
-
753
- /** Placeholder for a required field not yet received during streaming. */
754
- declare function emptyValueForFieldSchema(field: FieldSchema): unknown;
755
- interface CompliantKindSnapshot {
756
- /** Schema fields + __kind only. Required-but-missing fields hold typed placeholders. */
757
- value: Record<string, unknown>;
758
- /** Unknown keys + missing optionals. Null when both channels are empty. */
759
- residue: IrResidue | null;
760
- }
761
- declare function buildCompliantKindSnapshot(schema: KindSchema, partial: Record<string, unknown>): CompliantKindSnapshot;
762
- /**
763
- * Wire/round-trip form: schema fields + unknown keys back together, exactly
764
- * as the source carried them. `residue.extra` wins nothing โ€” snapshot value
765
- * and extras are disjoint by construction.
766
- */
767
- declare function mergeResidueIntoValue(value: Record<string, unknown>, residue: IrResidue | null): Record<string, unknown>;
768
-
769
- /**
770
- * Idempotent normalizer โ€” the "recognizes its own work" property.
771
- *
772
- * THE LAW: anything already carrying a current CanonicalBlockIR envelope is
773
- * returned BY REFERENCE โ€” zero reprocessing, reference equality holds, React
774
- * bails out. Only raw text (a detected region's source) is ever parsed, and
775
- * it is parsed exactly once per fingerprint.
776
- *
777
- * `normalizeJsonRegion` is the one-shot mode: the same KindStreamParser that
778
- * powers live streams, run over a complete region string (DB reloads,
779
- * reconcile passes), assembled through the same IrTree the live session uses
780
- * โ€” stream and static output are structurally identical by construction.
781
- */
782
-
783
- declare function isCanonicalBlockIR(value: unknown): value is CanonicalBlockIR;
784
- /**
785
- * The idempotence fast path: return the existing envelope by reference when
786
- * it still describes this source text; null means "parse needed".
787
- */
788
- declare function reuseEnvelopeIfCurrent(source: string, candidate: unknown): CanonicalBlockIR | null;
789
- interface NormalizeJsonRegionOptions {
790
- schemas: Record<string, KindSchema> | SchemaResolver;
791
- /** Known-context root prediction (agent output schema, fence hint). */
792
- expectedRootKind?: string;
793
- /**
794
- * Pass a previously persisted envelope (message metadata, artifact row);
795
- * when its fingerprint matches, it is returned as-is and nothing parses.
796
- */
797
- existing?: unknown;
798
- }
799
- interface CompleteValueEnvelopeOptions {
800
- /**
801
- * Wire discriminator recorded on the root node โ€” which syntax established
802
- * the kind. Defaults to the JSON `__kind` key; XML surfaces converging at
803
- * region finalize pass `xmlDiscriminator(tag)` so round-trip serializers
804
- * know the original arrival format.
805
- */
806
- discriminator?: IrDiscriminator;
807
- }
808
- /**
809
- * Build a resolved, complete envelope directly from an already-structured
810
- * value (a persisted artifact's `content.data` object, or a completed XML
811
- * region's strategy output). This is the zero-reprocessing rehydration path:
812
- * the value IS the reconstructed region value (schema fields + residue extras
813
- * merged at persist time), so no tokenizer/parser run is needed โ€” the
814
- * envelope wraps it verbatim. The fingerprint hashes the canonical value
815
- * serialization, so any two paths producing the same value produce the SAME
816
- * envelope (stream โ‰ก static by construction).
817
- */
818
- declare function envelopeFromCompleteValue(value: Record<string, unknown>, kind: string, options?: CompleteValueEnvelopeOptions): CanonicalBlockIR;
819
- /** One-shot: complete region text in โ†’ canonical envelope out. */
820
- declare function normalizeJsonRegion(source: string, options: NormalizeJsonRegionOptions): CanonicalBlockIR;
821
-
822
- /**
823
- * Stable, fast content fingerprint for IR envelopes.
824
- *
825
- * Used as the idempotence / cache key: a persisted CanonicalBlockIR is only
826
- * reused when its fingerprint matches the region source text it claims to
827
- * represent. Not cryptographic โ€” collision resistance at the "same message,
828
- * same block" scale is all that's required, and it must be synchronous and
829
- * dependency-free (runs per region on the hot streaming path).
830
- *
831
- * FNV-1a 32-bit, applied twice with different seeds and concatenated, so a
832
- * single 32-bit collision doesn't alias two regions.
833
- *
834
- * `createFingerprinter` is the incremental form for live streams: feeding
835
- * chunks one at a time yields EXACTLY the same fingerprint as
836
- * `fingerprintText` over the concatenation โ€” sessions never re-hash the
837
- * whole source per flush.
838
- */
839
- interface Fingerprinter {
840
- push(chunk: string): void;
841
- /** Fingerprint of everything pushed so far. */
842
- current(): string;
843
- }
844
- declare function createFingerprinter(): Fingerprinter;
845
- declare function fingerprintText(source: string): string;
846
-
847
- /**
848
- * Discriminator abstraction โ€” how a node's kind is established from the wire.
849
- *
850
- * The parser never hardcodes "kind comes from a JSON key". JSON resolves via
851
- * the `__kind` field (implemented today); XML resolves via tag โ†’ registry
852
- * alias (Phase 6 โ€” contract only). `IrStructuredNode.discriminator` records
853
- * which resolver produced each node so renderers and round-trip serializers
854
- * can reconstruct the original wire format per node.
855
- */
856
-
857
- declare const JSON_DISCRIMINATOR: IrDiscriminator;
858
- declare function xmlDiscriminator(tag: string): IrDiscriminator;
859
- declare function fenceDiscriminator(language: string): IrDiscriminator;
860
- /** What a resolver can say about an opening compound value. */
861
- type KindResolution = {
862
- outcome: "kind";
863
- kind: string;
864
- } | {
865
- outcome: "pending";
866
- } | {
867
- outcome: "raw";
868
- reason: string;
869
- };
870
-
871
- /**
872
- * IrEnvelopeCache โ€” the persisted envelope cache carried on MESSAGE PARTS.
873
- *
874
- * Phase 5 (reload without re-parse): at stream end, `assembleMessageParts`
875
- * stamps every completed JSON region's CanonicalBlockIR onto the committed
876
- * `CxTextContent.metadata.__ir` as this cache โ€” keyed by fingerprint, because
877
- * one text part can embed several regions. On reload the splitter's envelope
878
- * memo consults the seeded cache (`registry/region-envelope-memo.ts`) and
879
- * reuses the persisted envelope BY REFERENCE via `reuseEnvelopeIfCurrent`
880
- * (exact fingerprint match of the detected region source) โ€” zero re-parse.
881
- *
882
- * Shape discipline: the SAME `__ir` metadata key carries two shapes at two
883
- * levels, disambiguated by validators that reject each other โ€”
884
- * - render block metadata โ†’ a single CanonicalBlockIR (`isCanonicalBlockIR`)
885
- * - message part metadata โ†’ this cache (`isIrEnvelopeCache`)
886
- *
887
- * Pure kernel module: types + validators only. No React/Redux/Supabase.
888
- */
889
-
890
- /** Cache version. Bump = migration point for persisted part caches. */
891
- declare const IR_ENVELOPE_CACHE_VERSION: 1;
892
- /**
893
- * The envelope cache persisted on a message part's `metadata.__ir`.
894
- * `blocks` maps each region-source fingerprint to its complete envelope.
895
- */
896
- interface IrEnvelopeCache {
897
- v: typeof IR_ENVELOPE_CACHE_VERSION;
898
- blocks: Record<string, CanonicalBlockIR>;
899
- }
900
- /**
901
- * Strict whole-cache validation: every entry must be a complete
902
- * CanonicalBlockIR keyed by its OWN fingerprint. A cache failing this guard
903
- * came from a buggy or foreign writer โ€” callers surface that loudly and seed
904
- * nothing (a half-trusted cache is how poisoned envelopes reach renderers).
905
- */
906
- declare function isIrEnvelopeCache(value: unknown): value is IrEnvelopeCache;
907
- /**
908
- * Build the persistable cache from a run's collected envelopes. Only
909
- * complete envelopes are cacheable (a streaming/error envelope can never be
910
- * reused โ€” its fingerprint doesn't describe a finished region). Duplicate
911
- * regions (same fingerprint) collapse to one entry. Engine-agnostic by
912
- * design: an aidream-built `engine: "py-block-detector"` envelope is cached
913
- * identically to an FE-parsed one. Returns null when nothing qualifies so
914
- * callers skip the metadata stamp entirely.
915
- */
916
- declare function envelopeCacheFromEnvelopes(envelopes: readonly CanonicalBlockIR[]): IrEnvelopeCache | null;
917
-
918
- /**
919
- * PURE envelope ingestion โ€” reading `metadata.__ir` off a block's metadata
920
- * and gating SERVER-BUILT envelopes at the wire boundary. Twin-safe: no
921
- * React / Redux / Supabase / host diagnostics โ€” side effects (seeding the
922
- * region-envelope memo, screaming to the Error Inspector) are injected by
923
- * the host through `InboundEnvelopeHooks`.
924
- *
925
- * The frontend host shell is `redux/render-block-envelope.ts` (binds the
926
- * hooks to `seedEnvelope` + `captureError`); aidream's Workflow Studio binds
927
- * its own. Contract: /Users/armanisadeghi/code/common-docs/systems/content-ir-system/PYTHON_ENVELOPE_CONTRACT.md.
928
- */
929
-
930
- /** Read a CanonicalBlockIR envelope off a block's metadata (or anything). */
931
- declare function readEnvelope(metadata: Record<string, unknown> | null | undefined): CanonicalBlockIR | null;
932
- /** Pure classification of inbound metadata carrying (or not) an envelope. */
933
- type InboundEnvelopeVerdict = {
934
- /** No `__ir` key โ€” zero-touch pass, same reference back. */
935
- outcome: "absent";
936
- metadata: Record<string, unknown> | undefined;
937
- } | {
938
- /** Valid CanonicalBlockIR โ€” same reference back (idempotence law). */
939
- outcome: "valid";
940
- metadata: Record<string, unknown>;
941
- envelope: CanonicalBlockIR;
942
- } | {
943
- /** Malformed/foreign `__ir` โ€” a COPY with `__ir` stripped. */
944
- outcome: "malformed";
945
- metadata: Record<string, unknown>;
946
- engine: string;
947
- raw: unknown;
948
- };
949
- declare function classifyInboundEnvelopeMetadata(metadata: Record<string, unknown> | null | undefined): InboundEnvelopeVerdict;
950
- /** Host-injected side effects for the inbound gate. */
951
- interface InboundEnvelopeHooks {
952
- /** Called with every VALID envelope so later re-splits reuse it by reference. */
953
- seedEnvelope?: (envelope: CanonicalBlockIR) => void;
954
- /** Called LOUDLY for every malformed envelope โ€” a bad envelope is a defect. */
955
- reportMalformed?: (info: {
956
- blockId: string;
957
- engine: string;
958
- raw: unknown;
959
- }) => void;
960
- }
961
- /**
962
- * Ingest guard for SERVER-BUILT envelopes riding `metadata.__ir` on a
963
- * `render_block` event.
964
- *
965
- * - No `__ir` key โ†’ the SAME metadata reference back (zero-touch pass).
966
- * - Valid CanonicalBlockIR โ†’ the SAME metadata reference back (reuse-by-
967
- * reference โ€” the idempotence law) AND `hooks.seedEnvelope` fires so any
968
- * later re-split of the same region source reuses it instead of parsing.
969
- * - Malformed/foreign `__ir` โ†’ a COPY with `__ir` stripped, plus a loud
970
- * `hooks.reportMalformed`. A bad envelope must never poison kind routing
971
- * or the persistence cache; dropping it degrades that block to the
972
- * ordinary content-driven path, nothing more.
973
- */
974
- declare function sanitizeInboundEnvelopeMetadata(metadata: Record<string, unknown> | null | undefined, context: {
975
- blockId: string;
976
- }, hooks?: InboundEnvelopeHooks): Record<string, unknown> | undefined;
977
-
978
- /**
979
- * Pure envelopeโ†’value functions (the zero-data-loss wire round-trip).
980
- *
981
- * These live in core/ (the pure kernel) because every layer needs them โ€”
982
- * including kinds/legacy-bridge-utils, whose bridges are built at MODULE
983
- * SCOPE inside kinds/<slug>.ts files that system-kinds.ts imports. When these
984
- * functions lived in redux/render-block-envelope.ts, that file's memo/capture
985
- * imports closed a module cycle (kinds โ†’ bridge-utils โ†’ render-block-envelope
986
- * โ†’ region-envelope-memo โ†’ kind-registry โ†’ system-kinds โ†’ kinds), which made
987
- * SYSTEM_KIND_DEFINITIONS entry-point-fragile (undefined defs when a kinds
988
- * module was the import entry). Keeping them here makes every kinds module
989
- * cycle-free BY CONSTRUCTION. redux/render-block-envelope re-exports them for
990
- * its existing consumers.
991
- */
992
-
993
- /**
994
- * Rebuild the region's full data: walk the root value and merge each node's
995
- * residue extras back in (root residue + nodeIndex residues). This is the
996
- * zero-data-loss read: nothing the model emitted is missing, whether or not
997
- * a schema knew about it.
998
- */
999
- declare function reconstructRegionValue(envelope: CanonicalBlockIR): Record<string, unknown>;
1000
- /**
1001
- * Deep-remove the `__kind` discriminator.
1002
- *
1003
- * ๐Ÿšจ NOT A TRANSFORM FOR PLATFORM DATA. `__kind` is part of the data
1004
- * (KINDS_EVERYWHERE_PLAN ยง4.2) and stripping it from anything stored, passed or
1005
- * rendered was annihilated on 2026-08-23. This helper survives for exactly two
1006
- * shapes of caller, both of which are guarded:
1007
- * - a SYMMETRIC COMPARISON that reduces both sides and returns a boolean;
1008
- * - legacy validation TOLERANCE against a pre-2026-08-23 schema version.
1009
- * Guards: aidream `scripts/check_kind_marker_law.py`,
1010
- * matrx-frontend `pnpm check:kind-marker-law`.
1011
- */
1012
- declare function stripKindDeep(value: unknown): unknown;
1013
-
1014
- /**
1015
- * ContentRegion โ€” the handshake between a host detector and this library.
1016
- *
1017
- * Boundary rule (the answer to the single-root problem): the HOST detector
1018
- * (StreamBlockAccumulator on streams, content-splitter-v2 on DB loads) finds
1019
- * where a structured region begins and ends inside prose; the kind parser
1020
- * owns everything INSIDE the region. A fresh parser is created per region, so
1021
- * "one root object" is true within a region by construction, and multiple
1022
- * blocks per message are just multiple regions.
1023
- *
1024
- * Through Phase 6 the host's fence-close / brace-count logic remains the
1025
- * region-end oracle (bit-level parity with today). In Phase 7 the parser's
1026
- * own frame stack becomes the oracle and the mirrored counters are deleted.
1027
- */
1028
- type RegionFormat = "json";
1029
- type RegionSourceKind = "fence" | "bare";
1030
- interface ContentRegionInit {
1031
- regionId: string;
1032
- format: RegionFormat;
1033
- sourceKind: RegionSourceKind;
1034
- }
1035
- /** How a region ended. Truncation is a normal outcome, never stream-fatal. */
1036
- type RegionEndReason = "closed" | "truncated" | "aborted";
1037
-
1038
- /**
1039
- * Schema-shape helpers โ€” structural depth and layout hints derived from a
1040
- * KindSchema. Drives the generic renderer's flat / grid / nested layout and
1041
- * human labels for slugs.
1042
- *
1043
- * Moved from app/(dev)/demos/json-block-detector/schema-structure.ts.
1044
- */
1045
-
1046
- /** Human label from a slug or field key (snake_case โ†’ Title Case + acronym fixes). */
1047
- declare function formatBlockLabel(key: string): string;
1048
- /**
1049
- * Structural nesting depth of a kind schema โ€” drives generic renderer layout.
1050
- * 0 = flat card (scalars only)
1051
- * 1 = grid (one array/object nesting level)
1052
- * 2+ = expandable grid (parent โ†’ child โ†’ grandchild)
1053
- */
1054
- declare function schemaStructureDepth(schema: KindSchema, allSchemas: Record<string, KindSchema>, visiting?: Set<string>): number;
1055
- type SchemaLayoutMode = "flat" | "grid" | "nested";
1056
- declare function schemaLayoutMode(schema: KindSchema, allSchemas: Record<string, KindSchema>): SchemaLayoutMode;
1057
-
1058
- /**
1059
- * ParseSession โ€” one live region parse per stream identity.
1060
- *
1061
- * Owns the parser + IrTree OUTSIDE React and Redux. Writers push chunks;
1062
- * N readers subscribe per path (useIrNode / selectors) and are notified on
1063
- * the host's flush cadence โ€” never per token.
1064
- *
1065
- * Notification contract: `write()`/`end()` never notify. The host (demo rAF
1066
- * loop, process-stream's dispatchBatch tick) calls `flushNotify()` to publish
1067
- * dirty paths. Late schema arrivals (registry cold fetch) notify themselves โ€”
1068
- * they happen outside any streaming tick.
1069
- */
1070
-
1071
- interface ParseSessionOptions {
1072
- identity: string;
1073
- schemas: Record<string, KindSchema> | SchemaResolver;
1074
- expectedRootKind?: string;
1075
- /**
1076
- * Registry hook: subscribe to cold-fetch answers, return an unsubscribe.
1077
- * The session forwards arrivals into the parser (upgrade-in-place) and
1078
- * notifies affected readers immediately.
1079
- */
1080
- onSchemaArrived?: (deliver: (kind: string, schema: KindSchema | null) => void) => () => void;
1081
- /** Observe every parser event (demo inspector, telemetry). */
1082
- onEvent?: (event: KindStreamEvent) => void;
1083
- }
1084
- type Listener = () => void;
1085
- declare class ParseSession {
1086
- readonly identity: string;
1087
- private readonly parser;
1088
- private readonly tree;
1089
- private readonly listeners;
1090
- private readonly anyListeners;
1091
- private readonly unsubscribeSchemaArrivals;
1092
- private readonly fingerprinter;
1093
- private ended;
1094
- constructor(options: ParseSessionOptions);
1095
- /** The single writer's input. Does NOT notify โ€” host flushes on its cadence. */
1096
- write(chunk: string): void;
1097
- end(): void;
1098
- get isEnded(): boolean;
1099
- get status(): "streaming" | "complete" | "error";
1100
- getNode(pathKey: string): IrTreeNode | null;
1101
- listNodes(): IrTreeNode[];
1102
- isRawPath(pathKey: string): boolean;
1103
- subscribe(pathKey: string, listener: Listener): () => void;
1104
- /** Structural subscription: fires when ANY node changes (mount lists). */
1105
- subscribeAny(listener: Listener): () => void;
1106
- /** Publish dirty paths to their readers. Host-cadence, coalesced. */
1107
- flushNotify(): void;
1108
- buildEnvelope(): CanonicalBlockIR;
1109
- dispose(): void;
1110
- }
1111
-
1112
- /**
1113
- * Session manager โ€” one writer per stream identity, N readers, mechanically
1114
- * enforced: a second `openParseSession` for a live identity THROWS. Readers
1115
- * resolve sessions by identity and never gain write access.
1116
- *
1117
- * Identities: `"{requestId}:{blockId}"` for agent-stream regions; any unique
1118
- * string for other hosts (demo runs, notes, one-shot upgrades).
1119
- *
1120
- * Ended sessions stay resolvable for late readers (reload happens via the
1121
- * persisted envelope, but in-session remounts read here) until disposed.
1122
- */
1123
-
1124
- declare function openParseSession(options: ParseSessionOptions): ParseSession;
1125
- declare function getParseSession(identity: string): ParseSession | null;
1126
- declare function disposeParseSession(identity: string): void;
1127
-
1128
- /**
1129
- * KindDefinition โ€” one kind, many facets. THE canonical registry entry.
1130
- *
1131
- * This does NOT merge BlockComponentRegistry or artifact-type-registry; the
1132
- * `legacyBlockType` and `artifact` facets are FACADES pointing into them, so
1133
- * migration is incremental and each registry keeps its own job.
1134
- */
1135
-
1136
- /**
1137
- * The uniform props contract for kind-driven block components. This is what
1138
- * de-special-cases flashcards: no component receives bespoke glue โ€” every
1139
- * kind component gets exactly this shape.
1140
- */
1141
- interface KindBlockProps {
1142
- kind: string;
1143
- schema: KindSchema;
1144
- /** Compliant snapshot value (schema fields + __kind). */
1145
- data: Record<string, unknown>;
1146
- status: "streaming" | "complete" | "error";
1147
- residue: IrResidue | null;
1148
- path: IrPath;
1149
- /** ParseSession identity for live child subscriptions; null after reload. */
1150
- identity: string | null;
1151
- /** Child-kind schema lookup (replaces passing allSchemas around). */
1152
- resolve: (kind: string) => KindSchema | undefined;
1153
- }
1154
- type KindTier = "eager" | "warm" | "cold";
1155
- interface KindDefinition {
1156
- /** Canonical slug โ€” THE key. */
1157
- kind: string;
1158
- /** null until the warm/cold fetch delivers it. */
1159
- schema: KindSchema | null;
1160
- schemaSource: "system" | "flexible_data" | "content_ir";
1161
- tier: KindTier;
1162
- /** Component facet โ€” lazy-loaded renderer for this kind. */
1163
- component?: {
1164
- load: () => Promise<{
1165
- default: ComponentType<KindBlockProps>;
1166
- }>;
1167
- };
1168
- /** Facade โ†’ BlockComponentRegistry type string (e.g. "flashcards"). */
1169
- legacyBlockType?: string;
1170
- /**
1171
- * Legacy-bridge facet: derive the existing component's `serverData` from a
1172
- * canonical envelope. This is what lets a kind light up the REAL component
1173
- * (FlashcardsBlock, โ€ฆ) with zero component changes during migration.
1174
- */
1175
- toLegacyServerData?: (envelope: CanonicalBlockIR) => Record<string, unknown> | undefined;
1176
- /** Facade โ†’ artifact-type-registry canvasType. */
1177
- artifact?: {
1178
- canvasType: string;
1179
- };
1180
- /**
1181
- * Markdown export facet โ€” the FORWARD leg of artifact โ‡„ markdown. Receives
1182
- * the ZERO-LOSS reconstructed value object (the CALLER reconstructs โ€” for
1183
- * persisted structured artifacts `content.data` already IS that object;
1184
- * this facet only renders it; `__kind` discriminators may still be
1185
- * present and must be ignored). MUST produce human-readable markdown
1186
- * (headings / lists / bold), never a JSON dump โ€” a fenced json body under
1187
- * a heading is acceptable only for inherently-code payloads (e.g. a
1188
- * schema_proposal's JSON Schema). Unknown extra keys the renderer doesn't
1189
- * understand MUST be appended under a small "Additional details"
1190
- * (key: value) section so nothing silently vanishes. Kinds without this
1191
- * facet fall back to `genericKindMarkdown` (kinds/kind-markdown-utils.ts).
1192
- */
1193
- toMarkdown?: (value: Record<string, unknown>) => string;
1194
- persistence?: {
1195
- persistStructured: boolean;
1196
- };
1197
- /** Future XML tags / kind aliases resolving to this kind. */
1198
- discriminatorAliases?: string[];
1199
- /**
1200
- * PARTIAL-READY opt-in โ€” the streaming partial-kinds posture.
1201
- *
1202
- * While a structured region streams, the server may announce a PROVISIONAL
1203
- * instance of this kind on `metadata.__ir_partial` (valid, closed JSON that
1204
- * may be missing required fields). The default posture is WITHHOLD: a
1205
- * provisional value is never routed to a component, and the block keeps its
1206
- * loading skeleton until the region completes โ€” because a component that
1207
- * throws on an absent field must not be handed one.
1208
- *
1209
- * Setting this to `true` declares "this kind's component renders a partial
1210
- * value without throwing", and the provisional value is routed to the SAME
1211
- * component that renders the final one, filling in as tokens arrive. A kind
1212
- * with a `toLegacyServerData` bridge must ALSO pass `{ provisional: true }`
1213
- * to `makeCompleteEnvelopeBridge` (pinned by a test). A component that
1214
- * throws anyway is caught, screams, and permanently drops this kind back to
1215
- * withhold for the session.
1216
- *
1217
- * Contract: common-docs/systems/content-ir-system/STREAMING_PARTIAL_KINDS.md
1218
- */
1219
- partialReady?: boolean;
1220
- /**
1221
- * Loading-library slug (`kind_definition.metadata.loading_component`) โ€”
1222
- * which of the ~20 hardcoded loading components renders while this kind's
1223
- * instance streams in / its schema+component fetch is in flight. Null or
1224
- * unknown slugs fall back to the generic structured skeleton.
1225
- */
1226
- loadingComponent?: string | null;
1227
- }
1228
-
1229
- /**
1230
- * Kind โ†” content_ir storage shape โ€” the pure, DB-free reshaping between the
1231
- * consumed `KindSchema` and the `content_ir.kind_definition.data` array +
1232
- * `content_ir.kind_edge` rows.
1233
- *
1234
- * Two exact inverses:
1235
- * - `kindSchemaToStorage` โ€” the MIGRATION / write direction: a parsed
1236
- * `KindSchema` (fields Record, targets inline) โ†’ an ORDERED `data` array
1237
- * (targets stripped) + externalized `kind_edge` specs (targets, keyed by
1238
- * field PATH). This is what pours `flexible_data` (and future authored
1239
- * kinds) into the canonical tables.
1240
- * - `storageToKindSchema` โ€” the ADAPTER / read direction: `data` array +
1241
- * edges โ†’ the same `KindSchema` the parser/emitter consume, re-attaching
1242
- * `object.kind` / `array.itemKinds` from the edges by path.
1243
- *
1244
- * Design invariants (from the 2026-07-05 kind-registry storage design, since deleted):
1245
- * - The `data` element is `FieldSchema` + `name`, MINUS ref targets. Order is
1246
- * intrinsic to the array (fixes the jsonb key-reorder bug).
1247
- * - `kind_edge` is the SINGLE source of truth for kindโ†’kind refs: `object`
1248
- * โ†’ one edge (position null); `array` โ†’ N edges (union) ordered by
1249
- * `position`. `field_name` is a dot-PATH so a ref nested inside an
1250
- * `inline_object` still gets a distinct, collision-free edge.
1251
- * - `inline_object` is structural: its `fields` is an ordered array, it never
1252
- * becomes a registry row and never carries `__kind`. Its nested refs DO get
1253
- * edges (path-prefixed) so cascade/pinning see every dependency. Its
1254
- * `open` flag persists on the element (losing it is the open-empty-object
1255
- * defect).
1256
- * - `union.kinds` refs externalize to edges exactly like `array.itemKinds`;
1257
- * the stored element keeps `hasKinds: true` so lost edges scream on read.
1258
- * - A NON-OBJECT ROOT (`KindSchema.root`) stores as ONE reserved element
1259
- * named `ROOT_STORAGE_NAME` ("__root") โ€” the only element allowed in that
1260
- * kind's `data`. Real fields may never use the reserved name.
1261
- *
1262
- * NO imports of supabase / the DB โ€” this is pure and unit-tested by round-trip
1263
- * (`__tests__/kind-storage-transform.test.ts`).
1264
- */
1265
-
1266
- /**
1267
- * Reserved `data[]` element name for a NON-OBJECT ROOT form (`KindSchema.root`).
1268
- * A root-form kind stores exactly one element under this name; the read
1269
- * direction reconstructs `{ root }` instead of a field map. The write
1270
- * direction rejects any REAL field with this name โ€” the name is the marker.
1271
- */
1272
- declare const ROOT_STORAGE_NAME = "__root";
1273
- type StoredFieldBase = {
1274
- name: string;
1275
- required?: boolean;
1276
- nullable?: boolean;
1277
- /** Human guidance โ€” mirrors FieldBase.description. */
1278
- description?: string;
1279
- /** Default VALUE (annotation-level) โ€” mirrors FieldBase.default. */
1280
- default?: unknown;
1281
- };
1282
- /** One element of `kind_definition.data` โ€” FieldSchema + name, ref targets removed. */
1283
- type StoredFieldElement = (StoredFieldBase & {
1284
- type: "string" | "boolean";
1285
- }) | (StoredFieldBase & {
1286
- type: "number";
1287
- min?: number;
1288
- max?: number;
1289
- step?: number;
1290
- }) | (StoredFieldBase & {
1291
- type: "string[]";
1292
- values?: string[];
1293
- open?: boolean;
1294
- }) | (StoredFieldBase & {
1295
- type: "number[]" | "boolean[]";
1296
- }) | (StoredFieldBase & {
1297
- type: "json";
1298
- }) | (StoredFieldBase & {
1299
- type: "json[]";
1300
- }) | (StoredFieldBase & {
1301
- type: "array";
1302
- }) | (StoredFieldBase & {
1303
- type: "object";
1304
- }) | (StoredFieldBase & {
1305
- type: "inline_object";
1306
- fields: StoredFieldElement[];
1307
- open?: boolean;
1308
- }) | (StoredFieldBase & {
1309
- type: "record";
1310
- values: RecordValueType;
1311
- }) | (StoredFieldBase & {
1312
- type: "enum";
1313
- values: string[];
1314
- open?: boolean;
1315
- }) | (StoredFieldBase & {
1316
- type: "union";
1317
- scalars: Array<"string" | "number" | "boolean">;
1318
- /** Marker that this union's kind refs live in edges (positions ordered). */
1319
- hasKinds?: boolean;
1320
- });
1321
- /** One `content_ir.kind_edge` row (child resolved to an id at insert time). */
1322
- type KindEdgeSpec = {
1323
- /** Field PATH in the parent's `data` (dot-notation into inline_objects). */
1324
- fieldPath: string;
1325
- /** Child kind slug โ€” insert resolves this to `child_definition_id`. */
1326
- childKind: string;
1327
- /** Union (anyOf) ordering for array refs; null for a single object ref. */
1328
- position: number | null;
1329
- };
1330
- /** The full write payload for one kind: the ordered data array + its edges. */
1331
- type KindStorageShape = {
1332
- data: StoredFieldElement[];
1333
- edges: KindEdgeSpec[];
1334
- };
1335
- declare class KindStorageError extends Error {
1336
- constructor(message: string);
1337
- }
1338
- /**
1339
- * MIGRATION / write direction. Order of `data` follows `Object.entries(fields)`
1340
- * โ€” the caller supplies the KindSchema whose field order is authoritative
1341
- * (prefer the compiled `system-kinds.ts` order for system kinds during the
1342
- * one-time flexible_data migration; jsonb order is the fallback for user kinds).
1343
- */
1344
- declare function kindSchemaToStorage(schema: KindSchema): KindStorageShape;
1345
- /** ADAPTER / read direction โ€” the exact inverse of `kindSchemaToStorage`. */
1346
- declare function storageToKindSchema(kind: string, shape: KindStorageShape): KindSchema;
1347
-
1348
- /**
1349
- * The dual gate โ€” Arman's law as executable code: a kind is only `is_active`
1350
- * when its canonical `sample_data` passes BOTH systems.
1351
- *
1352
- * 1. Structural (Pydantic): the sample validates against the kind's
1353
- * `emitted_json_schema`. Python's Pydantic is the AUTHORITATIVE owner of
1354
- * this leg, but it reads the SAME materialized `emitted_json_schema` โ€” so
1355
- * this TS ajv check and the Python check validate the same sample against
1356
- * the same schema and agree by construction. A disagreement IS the
1357
- * screamer (a schema Pydantic can't express, or an ajv/Pydantic gap).
1358
- * 2. Render (UI): the sample lights up the kind's real component. TS is the
1359
- * AUTHORITATIVE owner of this leg. It is a PROXY for a DOM render, not a
1360
- * DOM render. Exactly what it checks, and nothing more:
1361
- * ยท the kind has something to render with (`legacyBlockType` or
1362
- * `component`);
1363
- * ยท for BRIDGED kinds, `toLegacyServerData(sample)` returns a plain
1364
- * object that is SEMANTICALLY non-empty โ€” see
1365
- * `describeUnrenderableBridgeOutput` for the exact predicate;
1366
- * ยท BRIDGELESS kinds pass with a recorded caveat โ€” nothing is verified.
1367
- *
1368
- * This catches the 2026-07-04 "No flashcards available yet" class: a
1369
- * bridge that returns `undefined`, `{}`, `{language:"json"}` (the raw
1370
- * code-region annotation), or an object whose every value is empty.
1371
- *
1372
- * What it does NOT do โ€” stated plainly, because a gate that overclaims is
1373
- * worse than no gate: it does not mount the component, and it cannot know
1374
- * WHICH key carries the payload. `{title:"Cell Biology", cards:[]}` passes
1375
- * this leg on `title` alone. Proving the payload key is populated needs
1376
- * per-kind knowledge the gate deliberately does not have; a DOM-level
1377
- * render check is the deeper leg, deferred to an RTL harness.
1378
- *
1379
- * Both legs necessary, neither sufficient. Fail either โ†’ `isActive: false` and
1380
- * the caller reports it loudly (Error Inspector, `content-ir`) and holds the
1381
- * row out of production. This module is PURE (deps injected) so it runs in the
1382
- * harness, in CI, and in a browser author-save alike.
1383
- *
1384
- * Ownership split (the 2026-07-05 kind-registry storage design, since deleted; the live contract is the code below): the caller writes the outcome
1385
- * to the LIVE `content_ir.kind_definition` row's `is_active`; the canonical
1386
- * `_version_capture` trigger snapshots that state into `history.row_versions`
1387
- * (never a post-hoc history mutation).
1388
- */
1389
-
1390
- /** The facets the render leg needs โ€” a structural subset of KindDefinition. */
1391
- interface DualGateDefinition {
1392
- legacyBlockType?: string;
1393
- toLegacyServerData?: (envelope: CanonicalBlockIR) => Record<string, unknown> | undefined;
1394
- component?: {
1395
- load: () => Promise<unknown>;
1396
- };
1397
- }
1398
- /**
1399
- * The render leg's second satisfier: an ACTIVE `role='output'` component
1400
- * resolved from `content_ir.kind_component`. Feed this from
1401
- * `resolveComponent(kind, "web", "output")`.
1402
- *
1403
- * Why this exists: the render leg originally consulted only the compiled TS
1404
- * registry, so an agent-authored kind whose renderer is a `source='db'` row was
1405
- * structurally unable to pass โ€” `definition` came back null and the gate said
1406
- * "no component" about a kind that had a live, working one. Six authored kinds
1407
- * (wine_tasting, employee_card, employee_roster, employee_of_the_week,
1408
- * flashcard_deck, arman_video_prompt) sat permanently inactive because of it.
1409
- *
1410
- * NOT a mirror of `content_ir.evaluate_kind_activation`. The SQL render leg is
1411
- * presence-only โ€” it checks that an active `role='output'` row exists, because
1412
- * SQL cannot execute a TypeScript bridge. THIS leg is strictly stronger: for a
1413
- * compiled kind it also runs `toLegacyServerData` and rejects semantically
1414
- * empty output (the "No <kind> available" class).
1415
- *
1416
- * The asymmetry is deliberate and bounded: SQL is the FLOOR (necessary, and
1417
- * sufficient for DB-authored components, which own no bridge), while this leg
1418
- * is the CEILING for compiled kinds. Consequence to know: activating a COMPILED
1419
- * kind whose bridge is broken would pass the RPC and fail here. Compiled kinds
1420
- * are activated by developers through `scripts/shape/activate-kinds.ts`, which
1421
- * runs this leg โ€” the studio control only ever reaches owner-authored kinds.
1422
- * If that ever stops being true, the browser control must run this gate before
1423
- * enabling its button.
1424
- */
1425
- interface DualGateResolvedComponent {
1426
- componentKey: string;
1427
- /** The row's own render-trust verdict (R6). Inactive rows do not satisfy. */
1428
- isActive: boolean;
1429
- /** "bundled" | "db" โ€” reported in the leg detail, never gates the verdict. */
1430
- source: string;
1431
- }
1432
- interface DualGateInput {
1433
- kind: string;
1434
- /** The canonical instance (kind_definition.sample_data). */
1435
- sample: Record<string, unknown>;
1436
- /** The materialized kind_definition.emitted_json_schema (plain, no __kind). */
1437
- emittedJsonSchema: unknown;
1438
- /** The registry definition for the kind (or null when unregistered). */
1439
- definition: DualGateDefinition | null;
1440
- /**
1441
- * The resolver's `(kind, web, output)` answer, when the caller has one.
1442
- * Omit (or pass null) to check the compiled registry alone.
1443
- */
1444
- resolvedComponent?: DualGateResolvedComponent | null;
1445
- /**
1446
- * True when the kind is a generated data-only contract
1447
- * (`metadata.family` โˆˆ workflow_io | tool_io | action_io | agent_io).
1448
- * Those are passed between nodes and never rendered, so the render leg is
1449
- * structurally inapplicable โ€” the same `n/a` doctrine the shape doctor uses.
1450
- * Failing them would be noise, and noise erodes the gate.
1451
- */
1452
- dataOnly?: boolean;
1453
- }
1454
- interface LegResult {
1455
- ok: boolean;
1456
- detail?: string;
1457
- }
1458
- interface DualGateResult {
1459
- /** True only when BOTH legs pass โ€” the value the caller writes to is_active. */
1460
- isActive: boolean;
1461
- structural: LegResult;
1462
- render: LegResult;
1463
- }
1464
- /**
1465
- * The structural leg, exported on its own so the shape doctor
1466
- * (`shape-doctor.ts`) RECOMPUTES gate validation with the exact same ajv
1467
- * config + marker semantics as activation (verbatim first, marker-free retry
1468
- * second) โ€” never a parallel validator. `sample` is `unknown` (not `Record`) because kind examples may
1469
- * legitimately be scalars/arrays (workflow I/O kinds like `text`/`number`).
1470
- */
1471
- declare function validateStructuralLeg(sample: unknown, emittedJsonSchema: unknown): LegResult;
1472
- declare function runKindDualGate(input: DualGateInput): DualGateResult;
1473
- /**
1474
- * One-line, Error-Inspector-ready reason for a failed gate (empty string when
1475
- * it passed). The caller feeds this to `captureError({ source: "content-ir" })`
1476
- * and sets `is_active=false`.
1477
- */
1478
- declare function describeDualGateFailure(kind: string, result: DualGateResult): string;
1479
-
1480
- /**
1481
- * OpenAI/provider JSON Schema โ†’ KindSchema converter + __kind injection.
1482
- *
1483
- * The strategic keystone: `buildAgentSchemaWithRenderBlockSupport` turns "a
1484
- * user/agent defined an output schema" into "the platform has a render
1485
- * contract for it" by injecting the `__kind` discriminator into the agent's
1486
- * output schema (root + array items), so the model emits self-identifying
1487
- * objects from then on.
1488
- *
1489
- * Moved from app/(dev)/demos/json-block-detector/schema-converter.ts.
1490
- */
1491
-
1492
- type JsonSchemaNode = Record<string, unknown>;
1493
- type ConversionProblem = {
1494
- severity: "error" | "warning" | "info";
1495
- path: string;
1496
- message: string;
1497
- };
1498
- type DroppedMetadata = {
1499
- path: string;
1500
- dropped: Record<string, unknown>;
1501
- };
1502
- type FieldComparison = {
1503
- field: string;
1504
- aiPresent: boolean;
1505
- blockPresent: boolean;
1506
- aiSummary: string | null;
1507
- blockSummary: string | null;
1508
- status: "match" | "ai_only" | "block_only" | "type_mismatch" | "ai_richer" | "block_richer";
1509
- detail?: string;
1510
- };
1511
- /** One standalone flexible_data block schema row. */
1512
- type BlockSchemaDraft = {
1513
- slug: string;
1514
- label: string;
1515
- fields: Record<string, FieldSchema>;
1516
- /**
1517
- * NON-OBJECT ROOT form (KindSchema.root): the kind's value is this field's
1518
- * shape at the top level (scalar / array / json / OPEN object). When set,
1519
- * `fields` is empty โ€” mirror of `KindSchema.root`.
1520
- */
1521
- root?: FieldSchema;
1522
- };
1523
- type ArrayItemKindBinding = {
1524
- arrayField: string;
1525
- itemKindSlug: string;
1526
- };
1527
- type SchemaConversionResult = {
1528
- schemaName: string | null;
1529
- strict: boolean | null;
1530
- /** Every block schema row required for the converted shape (1..n). */
1531
- blockSchemas: BlockSchemaDraft[];
1532
- /** OPTION 2 โ€” same input shape with __kind injected for agent output. */
1533
- agentSchemaWithKinds: unknown | null;
1534
- problems: ConversionProblem[];
1535
- droppedMetadata: DroppedMetadata[];
1536
- comparisons: FieldComparison[];
1537
- };
1538
- type SavePlanEntry = {
1539
- draft: BlockSchemaDraft;
1540
- existsInDb: boolean;
1541
- willSave: boolean;
1542
- };
1543
- type ItemKindRefCheck = {
1544
- parentSlug: string;
1545
- field: string;
1546
- itemKind: string;
1547
- satisfied: boolean;
1548
- source: "batch" | "database" | "missing";
1549
- };
1550
- type SavePlanValidation = {
1551
- entries: SavePlanEntry[];
1552
- itemKindRefs: ItemKindRefCheck[];
1553
- newCount: number;
1554
- canSave: boolean;
1555
- errors: string[];
1556
- };
1557
- /**
1558
- * Inject the `__kind` discriminator into one object schema (const when
1559
- * strict, enum otherwise; `__kind` prepended to required; strict also pins
1560
- * additionalProperties:false). Shared with the REVERSE converter
1561
- * (kind-to-json-schema.ts) so both directions stamp identical discriminators.
1562
- */
1563
- declare function injectKindIntoObjectSchema(objectSchema: JsonSchemaNode, kindSlug: string, strict: boolean): JsonSchemaNode;
1564
- declare function buildAgentSchemaWithRenderBlockSupport(input: unknown, rootKindSlug: string, arrayBindings: ArrayItemKindBinding[], strict: boolean): unknown | null;
1565
- declare function normalizeAiSchemaInput(input: unknown): {
1566
- name: string | null;
1567
- strict: boolean | null;
1568
- rootSchema: JsonSchemaNode | null;
1569
- parseErrors: string[];
1570
- };
1571
- type ConversionCore = {
1572
- schemaName: string | null;
1573
- strict: boolean | null;
1574
- blockSchemas: BlockSchemaDraft[];
1575
- problems: ConversionProblem[];
1576
- droppedMetadata: DroppedMetadata[];
1577
- };
1578
- declare function convertAiSchemaToBlockFields(schemaName: string, rootSchema: JsonSchemaNode, strict: boolean): ConversionCore;
1579
- declare function compareWithExistingKindSchema(convertedFields: Record<string, FieldSchema>, existing: KindSchema | null): FieldComparison[];
1580
- declare function runSchemaConversion(input: unknown, existingSchemas: Record<string, KindSchema>): SchemaConversionResult & {
1581
- parseErrors: string[];
1582
- };
1583
- declare function validateBlockSchemaSavePlan(blockSchemas: BlockSchemaDraft[], existingSlugs: string[], hasConversionErrors: boolean): SavePlanValidation;
1584
- declare function fieldsToDbPayload(fields: Record<string, FieldSchema>): Record<string, unknown>;
1585
- declare function isDuplicateBlockSlug(slug: string, entries: Array<{
1586
- slug: string;
1587
- }>): boolean;
1588
-
1589
- /**
1590
- * KindSchema โ†’ provider-ready JSON Schema โ€” the REVERSE of the OpenAI
1591
- * converter in openai-schema-converter.ts.
1592
- *
1593
- * The requested root kind renders INLINE as the top-level object; every
1594
- * OTHER kind it transitively references (via `{type:"object", kind}` and
1595
- * `{type:"array", itemKinds}` fields, including inside inline_objects)
1596
- * becomes a `$defs` entry referenced with `$ref: "#/$defs/<slug>"`.
1597
- * References back to the ROOT kind use `"#"` โ€” the standard JSON Schema
1598
- * recursive-root reference (OpenAI structured outputs support both forms).
1599
- * Collection is cycle-safe: each kind enters the closure exactly once.
1600
- *
1601
- * Round-trip contract โ€” output fed through `runSchemaConversion`
1602
- * (openai-schema-converter.ts) reproduces the source KindSchemas for the
1603
- * root and every array-item child (enforced by
1604
- * __tests__/kind-to-json-schema.test.ts). The 2026-07-15 expressivity
1605
- * extension closed the three historical asymmetries: `record` now has a
1606
- * forward target (properties-less objects โ†’ record scalar/json), multi-
1607
- * itemKind arrays read back through items-anyOf when each variant declares
1608
- * its `__kind`, and nullable anyOf preserves the member list + nullable flag
1609
- * instead of flattening to `string`. Remaining accepted narrowings:
1610
- * - multi-kind array items emitted as $refs (not inline __kind objects)
1611
- * still cannot be read back โ€” the forward converter rejects $ref.
1612
- * - a nullable object-REF (`anyOf: [$ref, {type:"null"}]`) degrades for the
1613
- * same $ref reason.
1614
- * - JSON Schema `integer` narrows to `number` (the map_result precedent).
1615
- */
1616
-
1617
- type KindJsonSchemaOptions = {
1618
- /**
1619
- * Provider strict mode: additionalProperties:false on every kind object
1620
- * and inline object, and `const` (vs `enum`) __kind discriminators โ€”
1621
- * mirrors makeKindJsonSchemaProperty / injectKindIntoObjectSchema.
1622
- */
1623
- strict?: boolean;
1624
- /**
1625
- * Inject the `__kind` discriminator (+ required) into the root and every
1626
- * $defs kind object. Default true โ€” this is what makes the emitted
1627
- * objects self-identifying for the render pipeline.
1628
- */
1629
- injectKind?: boolean;
1630
- };
1631
- type KindJsonSchemaExport = {
1632
- /** The root kind slug โ€” doubles as the provider schema name. */
1633
- name: string;
1634
- schema: JsonSchemaNode;
1635
- strict: boolean;
1636
- /**
1637
- * Referenced kinds the resolver could not supply. Each still gets a
1638
- * permissive `$defs` object stub (never additionalProperties:false, even
1639
- * in strict mode โ€” a __kind-only strict object would reject every real
1640
- * payload) so the export stays structurally valid. Surface these loudly.
1641
- */
1642
- unresolved: string[];
1643
- };
1644
- /**
1645
- * Every kind referenced by a field map โ€” `{type:"object", kind}` refs and
1646
- * `{type:"array", itemKinds}` members, recursing through inline_objects.
1647
- * First-sighting order, deduplicated. Shared read helper (the registry
1648
- * catalog builds its uses / used-by graph from this).
1649
- */
1650
- declare function collectReferencedKinds(fields: Record<string, FieldSchema>): string[];
1651
- /**
1652
- * Schema-level referenced kinds โ€” field-map refs PLUS the refs a non-object
1653
- * root form carries. Use this (not `collectReferencedKinds(schema.fields)`)
1654
- * whenever the schema in hand may be root-form.
1655
- */
1656
- declare function collectSchemaReferencedKinds(schema: KindSchema): string[];
1657
- declare function kindSchemaToJsonSchema(kind: string, resolve: (kind: string) => KindSchema | undefined, options?: KindJsonSchemaOptions): KindJsonSchemaExport | null;
1658
-
1659
- /**
1660
- * JSON Schema โ†’ KindSchema โ€” THE registry-facing direction.
1661
- *
1662
- * ๐Ÿšจ WHY THIS FILE IS THE POINT OF THE WHOLE CONVERT LAYER (Arman's ruling,
1663
- * 2026-08-29): a kind's fields must be DERIVED from its schema, never stored a
1664
- * second time. `content_ir.kind_definition` used to carry both โ€” a JSON Schema
1665
- * AND a flattened field list written beside it โ€” and the two had already
1666
- * diverged on 13 of the 62 live kinds that carried both: stored lists holding
1667
- * `__kind` as if it were a data field, enums flattened to bare strings,
1668
- * min/max bounds and required flags the schema states and the copy never
1669
- * learned. A cache that can disagree with its source is not a cache.
1670
- *
1671
- * The heavy lifting lives in `openai-schema-converter.ts` (it also serves the
1672
- * agent-authoring flow, which needs the problems/dropped-metadata detail).
1673
- * This module is the narrow, honest door the registry calls: one schema in,
1674
- * one `KindSchema` out, plus whatever child kinds the schema declared inline
1675
- * or through `$defs`.
1676
- *
1677
- * Accepts both storage shapes seen in the wild: a bare JSON Schema, and the
1678
- * provider `{name, schema, strict}` response-format envelope that 5 live rows
1679
- * carry.
1680
- */
1681
-
1682
- type KindSchemaFromJsonResult = {
1683
- /**
1684
- * The requested kind's schema, or null when the input could not be read as
1685
- * an object contract at all. NEVER a partial guess: a field the vocabulary
1686
- * cannot express degrades to `json` (widening, always safe), and only a
1687
- * structurally unusable root yields null.
1688
- */
1689
- schema: KindSchema | null;
1690
- /**
1691
- * Child kinds the schema declared inline or via `$defs`, keyed by slug.
1692
- * A registry that ingests these gets the whole tree from ONE row's schema โ€”
1693
- * which is how a nested kind renders before its children's rows load.
1694
- */
1695
- children: Record<string, KindSchema>;
1696
- /** Conversion notes. `severity: "error"` entries are worth screaming about. */
1697
- problems: ConversionProblem[];
1698
- };
1699
- /**
1700
- * Derive `kind`'s field schema from its JSON Schema.
1701
- *
1702
- * Pure and synchronous โ€” no registry, no IO โ€” so a host can call it from a
1703
- * warm load, a cold fetch, a reducer, or a test.
1704
- */
1705
- declare function kindSchemaFromJsonSchema(kind: string, jsonSchema: unknown): KindSchemaFromJsonResult;
1706
-
1707
- /**
1708
- * Streaming partial kinds โ€” the TS twin of the Python producer's contract.
1709
- *
1710
- * Cross-repo system-of-record (read it before changing anything here):
1711
- * `common-docs/systems/content-ir-system/STREAMING_PARTIAL_KINDS.md`.
1712
- * Python twin: `aidream/packages/matrx-graph/matrx_graph/content_ir/partial.py`.
1713
- *
1714
- * WHAT THIS IS
1715
- * ------------
1716
- * While a structured region streams, the server announces what it thinks the
1717
- * region IS and what has arrived so far, so the UI fills in progressively
1718
- * instead of showing a spinner until the closing brace. Three events, a CLOSED
1719
- * union on `state`, all riding `metadata.__ir_partial` on the `render_block`
1720
- * events this app already receives:
1721
- *
1722
- * partial โ€” repeatable. A provisional instance whose `root.value` is
1723
- * VALID, CLOSED JSON (the server truncates and closes it, so
1724
- * this side never repairs or guesses). `kindState` is
1725
- * "speculative": it MAY still turn out to be something else.
1726
- * superseded โ€” TERMINAL. The region completed as the announced kind; drop
1727
- * the provisional render, the block's own content/`__ir` is the
1728
- * truth.
1729
- * retracted โ€” TERMINAL escape hatch. Detection was wrong; `becameKind` /
1730
- * `becameBlockType` name what it actually is. Never a silent
1731
- * swap.
1732
- *
1733
- * WHY IT IS NOT ON `__ir`
1734
- * -----------------------
1735
- * `__ir` means "validated against the registered schema", and a valid `__ir`
1736
- * is SEEDED into the fingerprint-keyed envelope memo. A provisional value
1737
- * there would poison every later read of that region. The two channels never
1738
- * touch: `classifyInboundEnvelopeMetadata` sees `absent` for a partial and
1739
- * passes the metadata through by reference.
1740
- *
1741
- * Pure kernel module: types + validators only. No React, no Redux, no IO.
1742
- * Lives in @ai-matrx/content-ir `wire/` so EVERY UI (Matrix, Workflow Studio,
1743
- * the dashboard, the Chrome extension, the desktop app) reads the channel
1744
- * through the same reader.
1745
- */
1746
-
1747
- /** The reserved metadata key carrying every event of this contract. */
1748
- declare const IR_PARTIAL_KEY: "__ir_partial";
1749
- type PartialKindState = "partial" | "superseded" | "retracted";
1750
- /** The provisional node. Deliberately `IrStructuredNode`-shaped so existing IR readers work. */
1751
- interface PartialKindNode {
1752
- role: "structured";
1753
- /** The server's DETECTION GUESS for this region. */
1754
- kind: string;
1755
- /** Always "speculative" on a partial โ€” pre-recognition, not a resolved kind. */
1756
- kindState: "speculative";
1757
- discriminator: IrDiscriminator;
1758
- path: IrPath;
1759
- status: "streaming";
1760
- /**
1761
- * Valid, closed JSON carrying its own `__kind`. MAY be missing required
1762
- * schema fields โ€” that is what `partial_unvalidated` in `residue.notices`
1763
- * says. A renderer that throws on an absent field is not partial-ready and
1764
- * must not be routed a provisional value.
1765
- */
1766
- value: Record<string, unknown>;
1767
- residue: IrResidue | null;
1768
- }
1769
- interface PartialKindEvent {
1770
- v: typeof IR_VERSION;
1771
- engine: string;
1772
- state: "partial";
1773
- /** Monotonic PER BLOCK โ€” the ordering / staleness key. Keep the highest. */
1774
- seq: number;
1775
- fingerprint: string;
1776
- root: PartialKindNode;
1777
- }
1778
- interface SupersededKindEvent {
1779
- v: typeof IR_VERSION;
1780
- engine: string;
1781
- state: "superseded";
1782
- seq: number;
1783
- kind: string;
1784
- }
1785
- interface RetractedKindEvent {
1786
- v: typeof IR_VERSION;
1787
- engine: string;
1788
- state: "retracted";
1789
- seq: number;
1790
- /** The kind that was WRONGLY announced. */
1791
- kind: string;
1792
- reason: string;
1793
- /** What it actually is โ€” null when it resolved to no registered kind. */
1794
- becameKind: string | null;
1795
- /** The detector's final block type, so a consumer re-routes without guessing. */
1796
- becameBlockType: string | null;
1797
- }
1798
- type AnyPartialKindEvent = PartialKindEvent | SupersededKindEvent | RetractedKindEvent;
1799
- /**
1800
- * Read + validate a partial-channel event off a block's metadata.
1801
- *
1802
- * Returns null for anything malformed, foreign, or of an unknown `state`. A
1803
- * malformed partial degrades to "no live rendering" โ€” never to a wrong render,
1804
- * and never to a thrown error inside a stream handler.
1805
- */
1806
- declare function readPartialKindEvent(metadata: Record<string, unknown> | null | undefined): AnyPartialKindEvent | null;
1807
- /**
1808
- * Ingest guard for the partial channel on a `render_block` event โ€” the twin of
1809
- * `sanitizeInboundEnvelopeMetadata` for `__ir`, and it exists for the same
1810
- * reason: a malformed server event must be stripped at the wire boundary, not
1811
- * carried into Redux where every later reader has to re-decide whether to
1812
- * trust it.
1813
- *
1814
- * - no `__ir_partial` key โ†’ the SAME metadata reference back (zero-touch).
1815
- * - valid event โ†’ the SAME metadata reference back (idempotence law).
1816
- * - malformed โ†’ a COPY with the key stripped, plus a loud `reportMalformed`.
1817
- * Dropping it degrades that block to "no live rendering" and nothing more.
1818
- *
1819
- * Pure: the host injects the reporter, exactly like the envelope gate, so
1820
- * aidream's Workflow Studio can bind its own.
1821
- */
1822
- declare function sanitizeInboundPartialKindMetadata(metadata: Record<string, unknown> | null | undefined, context: {
1823
- blockId: string;
1824
- }, hooks?: {
1825
- reportMalformed?: (info: {
1826
- blockId: string;
1827
- raw: unknown;
1828
- }) => void;
1829
- }): Record<string, unknown> | undefined;
1830
- /** Narrowing helper: is this the repeatable provisional event? */
1831
- declare function isProvisionalKind(event: AnyPartialKindEvent | null): event is PartialKindEvent;
1832
- /**
1833
- * Narrowing helper: is this a TERMINAL event? Every partial ends in exactly
1834
- * one of these โ€” that law is what makes a stuck skeleton impossible, so a
1835
- * consumer clears its provisional render here and nowhere else.
1836
- */
1837
- declare function isTerminalKindEvent(event: AnyPartialKindEvent | null): event is SupersededKindEvent | RetractedKindEvent;
1838
- /**
1839
- * Per-block staleness gate. Events can be re-dispatched, replayed on reconnect,
1840
- * or arrive out of order; only a strictly higher `seq` advances a block.
1841
- * Returns null when the event should be ignored.
1842
- *
1843
- * Pure: the caller owns the `seen` map, so this composes into a reducer
1844
- * without hiding module state.
1845
- */
1846
- declare function advancePartialKind(seen: Record<string, number>, blockId: string, event: AnyPartialKindEvent | null): AnyPartialKindEvent | null;
1847
- /**
1848
- * The per-block staleness GATE, as a stateful closure over `advancePartialKind`
1849
- * โ€” one per stream.
1850
- *
1851
- * `upsertRenderBlock` REPLACES the stored block, so an event landing on a block
1852
- * would regress what the user is looking at (a filled-in quiz snapping back to
1853
- * two questions, or a terminal being undone by a late `partial`). The highest
1854
- * accepted event is CARRIED FORWARD rather than dropped, so it is a no-op on
1855
- * screen instead of a flicker back to the skeleton.
1856
- *
1857
- * ๐Ÿšจ TWO arrivals must be carried, and the second one is the common case:
1858
- *
1859
- * 1. A STALE key โ€” a replay or an out-of-order event (`seq <= last`).
1860
- * 2. **NO key at all.** The producer clears `__ir_partial` at the top of every
1861
- * stamp and re-adds it only when the value genuinely advanced
1862
- * (`stream_processor.py::_stamp_partial` โ†’ `_partials.advanced(...)`), so
1863
- * it is CORRECT for it to omit the key โ€” re-shipping an identical payload
1864
- * every token is pure wire cost. But the block still ships whole, and
1865
- * replacing the stored block with one that has no partial metadata is what
1866
- * made the provisional render vanish between advances: every non-advancing
1867
- * token dropped the user back to the pending skeleton.
1868
- *
1869
- * Carrying stops at the TERMINAL, and only there. After `superseded` /
1870
- * `retracted` the region's truth is its own content or `__ir`, so resurrecting
1871
- * a provisional value would be a lie that outlives its own contract.
1872
- *
1873
- * Returns the metadata to store: the same reference when nothing changed, a
1874
- * copy with the carried-forward event otherwise.
1875
- */
1876
- declare function makePartialKindStalenessGate(): (blockId: string, metadata: Record<string, unknown> | undefined) => Record<string, unknown> | undefined;
1877
-
1878
- /**
1879
- * Runtime wrapper kinds โ€” the reader, and THE elision gate.
1880
- *
1881
- * Cross-repo contract (system of record):
1882
- * `common-docs/systems/content-ir-system/RUNTIME_WRAPPER_WIRE.md`.
1883
- *
1884
- * A runtime wrapper is the CLOSED set of envelopes that carry instance
1885
- * context with a data kind NESTED inside: `node_outcome` (one settled node
1886
- * invocation) and `run_result` (one terminated run, nesting one
1887
- * `node_outcome` per terminal node). `tool_result` is registered server-side
1888
- * but nothing emits it yet, so nothing here reads it.
1889
- *
1890
- * ## THE ELISION RULE โ€” do it ONCE, here
1891
- *
1892
- * The payload is NEVER sent twice. On the wire `output` is `null` and
1893
- * `output_ref` names the FRAME field that already holds the value:
1894
- *
1895
- * - `"output"` โ†’ the frame's own `output` (`node_completed.output`,
1896
- * the run row's `output`).
1897
- * - `"output.<node_id>"` โ†’ that key of the frame's terminal output map.
1898
- *
1899
- * PRESENCE OF `output_ref` IS THE MARKER. A bare `output: null` with NO ref is
1900
- * a legitimately empty payload โ€” never an elision, never something to go
1901
- * looking for. This is the same rule the `__ir` envelope follows with
1902
- * `value_ref`, for the same reason: otherwise every payload is serialized
1903
- * twice per streamed event, twice per durable row and twice per run read.
1904
- *
1905
- * Rehydration happens at the single INGEST GATE (each host's one ingest point โ€”
1906
- * Matrix's workflow-runs reducer, the Studio's inbound-envelope gate),
1907
- * before anything reads the wrapper. No renderer, selector or component ever
1908
- * sees an un-rehydrated wrapper, so none of them may re-implement this.
1909
- *
1910
- * ## Never load-bearing
1911
- *
1912
- * Assembly is a pure read. A malformed wrapper yields `null` and the frame's
1913
- * own fields carry the surface exactly as they did before the wrapper
1914
- * existed โ€” additive on the wire, additive here.
1915
- */
1916
- /** The registered slugs โ€” named once, never spelled by hand elsewhere. */
1917
- declare const NODE_OUTCOME_KIND = "node_outcome";
1918
- declare const RUN_RESULT_KIND = "run_result";
1919
- /** One settled node invocation, with its data kind nested in `output`. */
1920
- interface NodeOutcomeWrapper {
1921
- __kind: typeof NODE_OUTCOME_KIND;
1922
- run_id: string;
1923
- node_id: string;
1924
- workflow_id: string | null;
1925
- step: number | null;
1926
- attempt: number;
1927
- status: string;
1928
- started_at: string | null;
1929
- ended_at: string | null;
1930
- /** `0` is a REAL duration, not "unknown"; `null` is unknown. */
1931
- duration_ms: number | null;
1932
- /** null = the node declared no kind (a loud defect, never a pass). */
1933
- output_kind: string | null;
1934
- /** null = never checked / degraded โ€” NEVER renderable as a pass. */
1935
- output_kind_ok: boolean | null;
1936
- output_kind_errors: string[] | null;
1937
- /** Rehydrated by {@link rehydrateNodeOutcome}; null = genuinely empty. */
1938
- output: unknown;
1939
- }
1940
- /** One terminated run. `outputs` is one wrapper per TERMINAL node. */
1941
- interface RunResultWrapper {
1942
- __kind: typeof RUN_RESULT_KIND;
1943
- run_id: string;
1944
- workflow_id: string | null;
1945
- status: string;
1946
- started_at: string | null;
1947
- ended_at: string | null;
1948
- duration_ms: number | null;
1949
- output_kind: string | null;
1950
- output: unknown;
1951
- outputs: NodeOutcomeWrapper[];
1952
- }
1953
- /**
1954
- * Resolve a dotted `output_ref` against the frame that carries the payload.
1955
- * Returns `undefined` when the path does not resolve โ€” the caller keeps
1956
- * `output: null` rather than inventing a value.
1957
- */
1958
- declare function readOutputRef(frame: unknown, ref: string): unknown;
1959
- /**
1960
- * Read a `node_outcome` off a frame and rehydrate its elided payload.
1961
- *
1962
- * `frame` is the object the wrapper travelled ON โ€” the `node_completed` event,
1963
- * or the run read response for a `run_result`'s children. Returns null for
1964
- * anything that is not a node_outcome (including a missing wrapper: the
1965
- * producer fails OPEN, so an absent wrapper is a normal, non-fatal state).
1966
- */
1967
- declare function rehydrateNodeOutcome(raw: unknown, frame: unknown): NodeOutcomeWrapper | null;
1968
- /**
1969
- * Read an ALREADY-REHYDRATED node_outcome value into its typed form.
1970
- *
1971
- * Deliberately does NOT require `__kind`: the render bridge strips the root
1972
- * discriminator before the component sees the value, and it does NOT touch
1973
- * `output_ref` โ€” by the time anything renders, the ingest gate has already
1974
- * resolved the elision, and a second resolution attempt against a frame that
1975
- * is no longer there is how a payload goes missing.
1976
- */
1977
- declare function readNodeOutcomeValue(raw: unknown): NodeOutcomeWrapper | null;
1978
- /**
1979
- * Read a `run_result` off the run read response and rehydrate every elided
1980
- * payload โ€” its own, and each terminal node's. Both resolve against the SAME
1981
- * frame (the run read response), which is what `"output.<node_id>"` addresses.
1982
- */
1983
- declare function rehydrateRunResult(raw: unknown, frame: unknown): RunResultWrapper | null;
1984
- /**
1985
- * Read an ALREADY-REHYDRATED run_result value into its typed form. Same
1986
- * contract as {@link readNodeOutcomeValue}: no `__kind` requirement, no
1987
- * second elision pass.
1988
- */
1989
- declare function readRunResultValue(raw: unknown): RunResultWrapper | null;
1990
- /**
1991
- * The kind verdict, as three states the UI must keep distinct.
1992
- *
1993
- * `unchecked` is NEVER a pass: the engine either did not check (no declared
1994
- * kind) or checked and could not conclude. Collapsing it into "ok" is how a
1995
- * confidently-rendered document gets shown for a shape nobody verified.
1996
- */
1997
- type KindVerdict = "passed" | "failed" | "unchecked";
1998
- declare function kindVerdictOf(wrapper: {
1999
- output_kind: string | null;
2000
- output_kind_ok: boolean | null;
2001
- }): KindVerdict;
2002
-
2003
- /**
2004
- * The forward composer: given a kind's stored example, produce the EMIT/RENDER
2005
- * payload โ€” `{ "__kind": <slug>, ...data }`.
2006
- *
2007
- * Pure kernel module (@ai-matrx/content-ir `wire/`): no React, no Redux, no IO.
2008
- *
2009
- * Since 2026-08-23 stored examples and instances ALREADY carry their marker
2010
- * (`__kind` is part of the data โ€” KINDS_EVERYWHERE_PLAN ยง4.2), so for a
2011
- * well-formed row this is an IDENTITY with a guarantee attached: the marker is
2012
- * the FIRST key and it names the right slug. It stays because it is also the
2013
- * repair for the legacy rows and hand-typed values that do not, and because a
2014
- * caller wanting a copy-ready render payload should not have to know which it
2015
- * has.
2016
- *
2017
- * Scalars/arrays are returned unchanged โ€” for those kinds the identity travels
2018
- * out of band (`root.kind`); there is no key to add.
2019
- */
2020
- declare function withRootKind(kind: string, value: unknown): unknown;
2021
- /** The copy-ready render payload: pretty JSON of `{ __kind, ...data }`. */
2022
- declare function emitPayloadJson(kind: string, value: unknown): string;
2023
- /**
2024
- * The copy-ready render BLOCK โ€” the render payload inside a ```json fence, the
2025
- * exact form an agent emits and a user pastes into a prompt or a message to see
2026
- * it render live.
2027
- */
2028
- declare function emitPayloadFence(kind: string, value: unknown): string;
2029
-
2030
- export { type AnyPartialKindEvent, type ArrayItemKindBinding, type ArrayItemScalarType, type BlockSchemaDraft, type CanonicalBlockIR, type CanonicalContent, type CanonicalSegment, type CompleteValueEnvelopeOptions, type CompliantKindSnapshot, type ContentRegionInit, type ConversionProblem, type DroppedMetadata, type DualGateDefinition, type DualGateInput, type DualGateResolvedComponent, type DualGateResult, type FieldComparison, type FieldSchema, type Fingerprinter, IR_ENVELOPE_CACHE_VERSION, IR_ENVELOPE_KEY, IR_PARTIAL_KEY, IR_VERSION, type InboundEnvelopeHooks, type InboundEnvelopeVerdict, type IrDiscriminator, type IrEnvelopeCache, type IrKindState, type IrPath, type IrResidue, type IrStructuredNode, IrTree, type IrTreeNode, type ItemKindRefCheck, JSON_DISCRIMINATOR, type JsonPath, type JsonSchemaNode, JsonStreamTokenizer, type JsonToken, KIND_KEY, type KindBlockProps, type KindDefinition, type KindEdgeSpec, type KindJsonSchemaExport, type KindJsonSchemaOptions, type KindResolution, type KindSchema, type KindSchemaFromJsonResult, KindStorageError, type KindStorageShape, type KindStreamEvent, KindStreamParser, type KindStreamParserOptions, type KindTier, type KindVerdict, type LegResult, NODE_OUTCOME_KIND, type NodeOutcomeWrapper, type NormalizeJsonRegionOptions, ParseSession, type ParseSessionOptions, type PartialKindEvent, type PartialKindNode, type PartialKindState, type Punct, ROOT_STORAGE_NAME, RUN_RESULT_KIND, type RawObjectCause, type RecordValueType, type RegionEndReason, type RegionFormat, type RegionSourceKind, type RetractedKindEvent, type RunResultWrapper, type SavePlanEntry, type SavePlanValidation, type ScalarFieldType, type SchemaConversionResult, type SchemaLayoutMode, type SchemaResolver, type StoredFieldElement, type SupersededKindEvent, advancePartialKind, buildAgentSchemaWithRenderBlockSupport, buildCompliantKindSnapshot, classifyInboundEnvelopeMetadata, collectReferencedKinds, collectSchemaReferencedKinds, compareWithExistingKindSchema, convertAiSchemaToBlockFields, createFingerprinter, createKindStreamParser, describeDualGateFailure, disposeParseSession, emitPayloadFence, emitPayloadJson, emptyValueForFieldSchema, envelopeCacheFromEnvelopes, envelopeFromCompleteValue, fenceDiscriminator, fieldsToDbPayload, fingerprintText, formatBlockLabel, getParseSession, injectKindIntoObjectSchema, irPathIsUnderOrEqual, irPathKey, irPathLabel, irPathsEqual, isCanonicalBlockIR, isDuplicateBlockSlug, isEmptyResidue, isIrEnvelopeCache, isJsonAnyField, isProvisionalKind, isScalarArrayType, isTerminalKindEvent, kindSchemaFromJsonSchema, kindSchemaToJsonSchema, kindSchemaToStorage, kindVerdictOf, makePartialKindStalenessGate, mergeResidueIntoValue, normalizeAiSchemaInput, normalizeJsonRegion, openParseSession, readEnvelope, readNodeOutcomeValue, readObjectKind, readOutputRef, readPartialKindEvent, readRunResultValue, reconstructRegionValue, rehydrateNodeOutcome, rehydrateRunResult, reuseEnvelopeIfCurrent, runKindDualGate, runSchemaConversion, sanitizeInboundEnvelopeMetadata, sanitizeInboundPartialKindMetadata, scalarArrayItemType, schemaLayoutMode, schemaStructureDepth, setJsonRootKeyLookup, storageToKindSchema, stripKindDeep, validateBlockSchemaSavePlan, validateStructuralLeg, withRootKind, xmlDiscriminator };
1
+ export { C as CanonicalBlockIR, a as CanonicalContent, b as CanonicalSegment, I as IR_ENVELOPE_KEY, c as IR_VERSION, d as IrDiscriminator, e as IrKindState, f as IrPath, g as IrResidue, h as IrStructuredNode, i as irPathIsUnderOrEqual, j as irPathKey, k as irPathLabel, l as irPathsEqual, m as isEmptyResidue } from './ir-types-95bA2cXH.cjs';
2
+ export { I as IrTree, a as IrTreeNode, J as JsonPath, K as KindStreamEvent, b as KindStreamParser, c as KindStreamParserOptions, R as RawObjectCause, S as SchemaResolver, d as createKindStreamParser, s as setJsonRootKeyLookup } from './ir-tree-DbLVxbf1.cjs';
3
+ export { CompleteValueEnvelopeOptions, CompliantKindSnapshot, ContentRegionInit, Fingerprinter, IR_ENVELOPE_CACHE_VERSION, InboundEnvelopeHooks, InboundEnvelopeVerdict, IrEnvelopeCache, JSON_DISCRIMINATOR, JsonStreamTokenizer, JsonToken, KindResolution, NormalizeJsonRegionOptions, Punct, RegionEndReason, RegionFormat, RegionSourceKind, SchemaLayoutMode, buildCompliantKindSnapshot, classifyInboundEnvelopeMetadata, createFingerprinter, emptyValueForFieldSchema, envelopeCacheFromEnvelopes, envelopeFromCompleteValue, fenceDiscriminator, fingerprintText, formatBlockLabel, isCanonicalBlockIR, isIrEnvelopeCache, mergeResidueIntoValue, normalizeJsonRegion, readEnvelope, reconstructRegionValue, reuseEnvelopeIfCurrent, sanitizeInboundEnvelopeMetadata, schemaLayoutMode, schemaStructureDepth, stripKindDeep, xmlDiscriminator } from './core.cjs';
4
+ export { A as ArrayItemScalarType, F as FieldSchema, K as KIND_KEY, a as KindSchema, R as RecordValueType, S as ScalarFieldType, i as isJsonAnyField, b as isScalarArrayType, r as readObjectKind, s as scalarArrayItemType } from './kind-schema.types-CwncWj9U.cjs';
5
+ export { ParseSession, ParseSessionOptions, disposeParseSession, getParseSession, openParseSession } from './session.cjs';
6
+ export { DualGateDefinition, DualGateInput, DualGateResolvedComponent, DualGateResult, KindBlockProps, KindDefinition, KindEdgeSpec, KindStorageError, KindStorageShape, KindTier, LegResult, ROOT_STORAGE_NAME, StoredFieldElement, describeDualGateFailure, kindSchemaToStorage, runKindDualGate, storageToKindSchema, validateStructuralLeg } from './registry.cjs';
7
+ export { ArrayItemKindBinding, BlockSchemaDraft, ConversionProblem, DroppedMetadata, FieldComparison, ItemKindRefCheck, JsonSchemaNode, KindJsonSchemaExport, KindJsonSchemaOptions, KindSchemaFromJsonResult, SavePlanEntry, SavePlanValidation, SchemaConversionResult, buildAgentSchemaWithRenderBlockSupport, collectReferencedKinds, collectSchemaReferencedKinds, compareWithExistingKindSchema, convertAiSchemaToBlockFields, fieldsToDbPayload, injectKindIntoObjectSchema, isDuplicateBlockSlug, kindSchemaFromJsonSchema, kindSchemaToJsonSchema, normalizeAiSchemaInput, runSchemaConversion, validateBlockSchemaSavePlan } from './convert.cjs';
8
+ export { AnyPartialKindEvent, IR_PARTIAL_KEY, KindVerdict, NODE_OUTCOME_KIND, NodeOutcomeWrapper, PartialKindEvent, PartialKindNode, PartialKindState, RUN_RESULT_KIND, RetractedKindEvent, RunResultWrapper, SupersededKindEvent, advancePartialKind, emitPayloadFence, emitPayloadJson, isProvisionalKind, isTerminalKindEvent, kindVerdictOf, makePartialKindStalenessGate, readNodeOutcomeValue, readOutputRef, readPartialKindEvent, readRunResultValue, rehydrateNodeOutcome, rehydrateRunResult, sanitizeInboundPartialKindMetadata, withRootKind } from './wire.cjs';
9
+ import 'react';