@ai-matrx/content-ir 0.3.0 → 0.5.0

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.
package/dist/index.d.cts CHANGED
@@ -12,8 +12,20 @@ import { ComponentType } from 'react';
12
12
  */
13
13
  /** Path of a value inside a parsed region (object keys + array indices). */
14
14
  type IrPath = Array<string | number>;
15
- /** How a node's kind was (or wasn't) established. */
16
- type IrKindState = "resolved" | "speculative" | "pending_kind" | "pending_schema" | "raw";
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";
17
29
  /**
18
30
  * System-level zero-data-loss channel. Unknown keys are NEVER merged into a
19
31
  * node's `value` (they'd be indistinguishable from schema fields); they are
@@ -290,6 +302,16 @@ interface SchemaResolver {
290
302
  kindForJsonRootKey?(key: string): string | null;
291
303
  }
292
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";
293
315
  type KindStreamEvent = {
294
316
  type: "kind_identified";
295
317
  kind: string;
@@ -336,15 +358,23 @@ type KindStreamEvent = {
336
358
  value: unknown;
337
359
  reason: string;
338
360
  /**
339
- * The kind that WAS identified for this node before it degraded raw
340
- * present ONLY for schema-availability failures ("no schema registered"
341
- * for an identified/declared kind), never for structural failures
342
- * (missing __kind, duplicate keys, schema violations). Consumers use it
343
- * to preserve a known-but-unrenderable kind on the envelope so the
344
- * render seam can route to the generic viewer (or upgrade when the
345
- * schema arrives late) instead of dumping raw JSON.
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).
346
366
  */
347
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;
348
378
  at: number;
349
379
  } | {
350
380
  type: "optional_field_missing";
@@ -508,6 +538,14 @@ declare class KindStreamParser {
508
538
  private completeRoot;
509
539
  /** Mark a node raw (node-scoped failure) without killing the stream. */
510
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
+ */
511
549
  private emitRawObject;
512
550
  private clearKindWait;
513
551
  private emitFieldIfReady;
@@ -596,11 +634,20 @@ declare class IrTree {
596
634
  */
597
635
  private readonly earlyFields;
598
636
  /**
599
- * pathKey → identified kind preserved through a SCHEMA-AVAILABILITY raw
600
- * fallback (parser stamped `kind` on the raw_object event). Structural raws
601
- * (missing __kind, duplicate key, validation failure) never land here.
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.
602
641
  */
603
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;
604
651
  private regionStatus;
605
652
  private errorReason;
606
653
  private rootRawValue;
@@ -1932,4 +1979,4 @@ declare function emitPayloadJson(kind: string, value: unknown): string;
1932
1979
  */
1933
1980
  declare function emitPayloadFence(kind: string, value: unknown): string;
1934
1981
 
1935
- 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, 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 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, 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 };
1982
+ 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, 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, 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 };
package/dist/index.d.ts CHANGED
@@ -12,8 +12,20 @@ import { ComponentType } from 'react';
12
12
  */
13
13
  /** Path of a value inside a parsed region (object keys + array indices). */
14
14
  type IrPath = Array<string | number>;
15
- /** How a node's kind was (or wasn't) established. */
16
- type IrKindState = "resolved" | "speculative" | "pending_kind" | "pending_schema" | "raw";
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";
17
29
  /**
18
30
  * System-level zero-data-loss channel. Unknown keys are NEVER merged into a
19
31
  * node's `value` (they'd be indistinguishable from schema fields); they are
@@ -290,6 +302,16 @@ interface SchemaResolver {
290
302
  kindForJsonRootKey?(key: string): string | null;
291
303
  }
292
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";
293
315
  type KindStreamEvent = {
294
316
  type: "kind_identified";
295
317
  kind: string;
@@ -336,15 +358,23 @@ type KindStreamEvent = {
336
358
  value: unknown;
337
359
  reason: string;
338
360
  /**
339
- * The kind that WAS identified for this node before it degraded raw
340
- * present ONLY for schema-availability failures ("no schema registered"
341
- * for an identified/declared kind), never for structural failures
342
- * (missing __kind, duplicate keys, schema violations). Consumers use it
343
- * to preserve a known-but-unrenderable kind on the envelope so the
344
- * render seam can route to the generic viewer (or upgrade when the
345
- * schema arrives late) instead of dumping raw JSON.
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).
346
366
  */
347
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;
348
378
  at: number;
349
379
  } | {
350
380
  type: "optional_field_missing";
@@ -508,6 +538,14 @@ declare class KindStreamParser {
508
538
  private completeRoot;
509
539
  /** Mark a node raw (node-scoped failure) without killing the stream. */
510
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
+ */
511
549
  private emitRawObject;
512
550
  private clearKindWait;
513
551
  private emitFieldIfReady;
@@ -596,11 +634,20 @@ declare class IrTree {
596
634
  */
597
635
  private readonly earlyFields;
598
636
  /**
599
- * pathKey → identified kind preserved through a SCHEMA-AVAILABILITY raw
600
- * fallback (parser stamped `kind` on the raw_object event). Structural raws
601
- * (missing __kind, duplicate key, validation failure) never land here.
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.
602
641
  */
603
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;
604
651
  private regionStatus;
605
652
  private errorReason;
606
653
  private rootRawValue;
@@ -1932,4 +1979,4 @@ declare function emitPayloadJson(kind: string, value: unknown): string;
1932
1979
  */
1933
1980
  declare function emitPayloadFence(kind: string, value: unknown): string;
1934
1981
 
1935
- 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, 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 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, 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 };
1982
+ 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, 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, 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 };
package/dist/index.js CHANGED
@@ -105,11 +105,20 @@ var IrTree = class {
105
105
  */
106
106
  earlyFields = /* @__PURE__ */ new Map();
107
107
  /**
108
- * pathKey → identified kind preserved through a SCHEMA-AVAILABILITY raw
109
- * fallback (parser stamped `kind` on the raw_object event). Structural raws
110
- * (missing __kind, duplicate key, validation failure) never land here.
108
+ * pathKey → identified kind preserved through a raw fallback (parser stamped
109
+ * `kind` on the raw_object event) schema-availability degrades and, since
110
+ * 2026-08-29, structural ones too. Only a node nothing ever identified (no
111
+ * `__kind` at all) is absent here.
111
112
  */
112
113
  rawKinds = /* @__PURE__ */ new Map();
114
+ /**
115
+ * pathKey → WHY the node degraded. `"unverified"` means no schema was
116
+ * available and nothing was ever checked; `"invalid"` means a check ran and
117
+ * failed. THE RENDER ROUTE BRANCHES ON THIS — see `IrKindState`. Absent =
118
+ * `"invalid"`, so a parser that predates the `cause` field (or any consumer
119
+ * hand-building events) keeps the strict, safe reading.
120
+ */
121
+ rawCauses = /* @__PURE__ */ new Map();
113
122
  regionStatus = "streaming";
114
123
  errorReason = null;
115
124
  rootRawValue = null;
@@ -162,6 +171,7 @@ var IrTree = class {
162
171
  this.pendingSchemaPaths.delete(pathKey);
163
172
  this.earlyFields.delete(pathKey);
164
173
  if (event.kind) this.rawKinds.set(pathKey, event.kind);
174
+ this.rawCauses.set(pathKey, event.cause ?? "invalid");
165
175
  this.markRaw(event.path, event.reason, event.value);
166
176
  return;
167
177
  }
@@ -360,10 +370,11 @@ var IrTree = class {
360
370
  const isRaw = rootRawReason !== null;
361
371
  const identifiedKind = this.identifiedKinds.get("") ?? "";
362
372
  const rootKind = isRaw ? this.rawKinds.get("") ?? "" : rootNode?.kind ?? (this.completedKind || identifiedKind);
373
+ const rootRawState = this.rawCauses.get("") === "unverified" ? "unverified" : "raw";
363
374
  const root = {
364
375
  role: "structured",
365
376
  kind: rootKind,
366
- kindState: isRaw ? "raw" : rootNode ? rootNode.kindState : this.pendingSchemaPaths.has("") ? "pending_schema" : this.regionStatus === "streaming" ? identifiedKind ? "pending_schema" : "pending_kind" : "raw",
377
+ kindState: isRaw ? rootRawState : rootNode ? rootNode.kindState : this.pendingSchemaPaths.has("") ? "pending_schema" : this.regionStatus === "streaming" ? identifiedKind ? "pending_schema" : "pending_kind" : "raw",
367
378
  discriminator: JSON_DISCRIMINATOR,
368
379
  path: [],
369
380
  status: this.regionStatus,
@@ -386,7 +397,7 @@ var IrTree = class {
386
397
  if (pathKey === "") continue;
387
398
  nodeIndex[pathKey] = {
388
399
  kind: this.rawKinds.get(pathKey) ?? "",
389
- kindState: "raw",
400
+ kindState: this.rawCauses.get(pathKey) === "unverified" ? "unverified" : "raw",
390
401
  status: "complete"
391
402
  };
392
403
  }
@@ -726,7 +737,8 @@ var KindStreamParser = class {
726
737
  safeCopy(value),
727
738
  `No block schema registered for "${kind}".`,
728
739
  at,
729
- kind
740
+ kind,
741
+ "unverified"
730
742
  );
731
743
  }
732
744
  }
@@ -760,7 +772,8 @@ var KindStreamParser = class {
760
772
  safeCopy(value ?? {}),
761
773
  `No block schema registered for "${kind}".`,
762
774
  at,
763
- kind
775
+ kind,
776
+ "unverified"
764
777
  );
765
778
  this.closedPendingPaths.delete(pathKey);
766
779
  continue;
@@ -1306,7 +1319,8 @@ var KindStreamParser = class {
1306
1319
  objectValue,
1307
1320
  `No block schema registered for "${kind}".`,
1308
1321
  at,
1309
- kind
1322
+ kind,
1323
+ "unverified"
1310
1324
  );
1311
1325
  return;
1312
1326
  }
@@ -1340,7 +1354,8 @@ var KindStreamParser = class {
1340
1354
  objectValue,
1341
1355
  `No block schema registered for "${kind}".`,
1342
1356
  at,
1343
- kind
1357
+ kind,
1358
+ "unverified"
1344
1359
  );
1345
1360
  return;
1346
1361
  }
@@ -1413,7 +1428,15 @@ var KindStreamParser = class {
1413
1428
  this.speculativeKinds.delete(pathKey);
1414
1429
  this.emitRawObject(path, safeCopy(liveValue), reason, at, identifiedKind);
1415
1430
  }
1416
- emitRawObject(path, value, reason, at, identifiedKind) {
1431
+ /**
1432
+ * Degrade ONE node off the resolved path.
1433
+ *
1434
+ * `cause` defaults to `"invalid"` deliberately: every call site that omits
1435
+ * it is a real failure (validation, duplicate key, placement, contradicted
1436
+ * speculation). ONLY the "no schema registered" sites pass `"unverified"`,
1437
+ * and they are the reason the parameter exists — see `IrKindState`.
1438
+ */
1439
+ emitRawObject(path, value, reason, at, identifiedKind, cause = "invalid") {
1417
1440
  const pathKey = this.pathKey(path);
1418
1441
  if (this.rawObjectPaths.has(pathKey)) return;
1419
1442
  this.rawObjectPaths.add(pathKey);
@@ -1424,6 +1447,7 @@ var KindStreamParser = class {
1424
1447
  value,
1425
1448
  reason,
1426
1449
  ...identifiedKind !== void 0 && { kind: identifiedKind },
1450
+ cause,
1427
1451
  at
1428
1452
  });
1429
1453
  }
@@ -2993,21 +3017,26 @@ function fieldSchemaSummary(field) {
2993
3017
  function resolvePrimaryType(node) {
2994
3018
  const raw = node.type;
2995
3019
  if (typeof raw === "string") {
2996
- return { type: raw === "integer" ? "number" : raw, nullable: false };
3020
+ const t = raw === "integer" ? "number" : raw;
3021
+ return { type: t, nullable: false, members: [t] };
2997
3022
  }
2998
3023
  if (Array.isArray(raw)) {
2999
3024
  const types = raw.filter((t) => typeof t === "string");
3000
3025
  const nullable = types.includes("null");
3001
- const primary = types.find((t) => t !== "null") ?? (nullable && types.length === 1 ? "null" : null);
3002
- if (primary === "integer") {
3003
- return { type: "number", nullable };
3004
- }
3005
- return { type: primary ?? null, nullable };
3006
- }
3007
- if (node.enum) return { type: "string", nullable: false };
3008
- if (node.properties) return { type: "object", nullable: false };
3009
- if (node.items) return { type: "array", nullable: false };
3010
- return { type: null, nullable: false };
3026
+ const members = [
3027
+ ...new Set(
3028
+ types.filter((t) => t !== "null").map((t) => t === "integer" ? "number" : t)
3029
+ )
3030
+ ];
3031
+ const primary = members[0] ?? (nullable && types.length === 1 ? "null" : null);
3032
+ return { type: primary ?? null, nullable, members };
3033
+ }
3034
+ if (node.enum) return { type: "string", nullable: false, members: ["string"] };
3035
+ if (node.properties)
3036
+ return { type: "object", nullable: false, members: ["object"] };
3037
+ if (node.items)
3038
+ return { type: "array", nullable: false, members: ["array"] };
3039
+ return { type: null, nullable: false, members: [] };
3011
3040
  }
3012
3041
  function carriedMetadataKeys(field) {
3013
3042
  if (field === null) return /* @__PURE__ */ new Set();
@@ -3325,7 +3354,34 @@ function convertPropertyCore(fieldName, node, required, path, ctx) {
3325
3354
  });
3326
3355
  return { ...requiredNullableFlags(required), type: "json" };
3327
3356
  }
3328
- const { type, nullable } = resolvePrimaryType(node);
3357
+ const { type, nullable, members } = resolvePrimaryType(node);
3358
+ if (members.length > 1) {
3359
+ const objectish = members.some((m) => m === "object" || m === "array");
3360
+ if (objectish) {
3361
+ ctx.problems.push({
3362
+ severity: "info",
3363
+ path,
3364
+ message: `Union of [${members.join(", ")}] at "${path || "(root)"}" spans objects/arrays \u2014 carried as any JSON value (json).`
3365
+ });
3366
+ return { ...requiredNullableFlags(required), type: "json" };
3367
+ }
3368
+ const scalars = members.filter(
3369
+ (m) => m === "string" || m === "number" || m === "boolean"
3370
+ );
3371
+ if (scalars.length === members.length && scalars.length > 1) {
3372
+ return {
3373
+ ...requiredNullableFlags(required, nullable),
3374
+ type: "union",
3375
+ scalars
3376
+ };
3377
+ }
3378
+ ctx.problems.push({
3379
+ severity: "warning",
3380
+ path,
3381
+ message: `Union of [${members.join(", ")}] at "${path || "(root)"}" has no exact field type \u2014 carried as any JSON value (json) rather than narrowed to "${type}".`
3382
+ });
3383
+ return { ...requiredNullableFlags(required), type: "json" };
3384
+ }
3329
3385
  if (type === "string") {
3330
3386
  if (Array.isArray(node.enum)) {
3331
3387
  const values = node.enum.filter(