/** * A property assertion: what a caller may claim about a value other than its exact bytes. * * The contract half only. `satisfiesProperty` — the function that DECIDES whether a reading has a * property — stays in the engine, with the baseline plumbing and the `show`/`numberIn` helpers it * reasons with. This file is what a flow file on disk can legally contain. * * Split out of the engine with the rest of the predicate contract, and for the same reason: a saved * flow carries one of these now, so core has to be able to parse what it reads. */ import { z } from 'zod'; import { MeasureOp } from 'open-verification'; export type PropertyAssertion = /** Produced something at all — the honest floor for any generated output. */ { readonly property: 'nonEmpty'; } /** A classification landed inside the allowed set. Exact membership, no coercion. */ | { readonly property: 'oneOf'; readonly values: readonly unknown[]; } /** A number near enough to an expected one — inclusive on the bound. */ | { readonly property: 'withinTolerance'; readonly of: number; readonly tolerance: number; } /** The shape of the output, as a regular expression over its string form. */ | { readonly property: 'matchesPattern'; readonly pattern: string; } /** The right KIND of thing: `array` and `object` are distinguished, which `typeof` cannot do. */ | { readonly property: 'type'; readonly is: 'string' | 'number' | 'boolean' | 'array' | 'object'; } | { readonly property: 'changed'; } | { readonly property: 'unchanged'; } | { readonly property: 'increased'; readonly by?: Delta; } | { readonly property: 'decreased'; readonly by?: Delta; }; /** How far a reading moved, in the protocol's comparison vocabulary. Tolerance defaults to exact. */ export interface Delta { readonly op: MeasureOp; readonly value: number; readonly tolerance?: number; } /** * The reading taken BEFORE the action, when one was taken. * * A wrapper rather than a bare value because `undefined` is a legitimate reading — a store path * that held nothing — and "the path was empty" and "nobody looked" must not collapse into the same * answer. The first is a comparison; the second is a refusal to pretend one happened. */ export interface Baseline { readonly taken: true; readonly value: unknown; } export declare const propertyAssertionSchema: z.ZodDiscriminatedUnion<"property", [z.ZodObject<{ property: z.ZodLiteral<"nonEmpty">; }, "strict", z.ZodTypeAny, { property: "nonEmpty"; }, { property: "nonEmpty"; }>, z.ZodObject<{ property: z.ZodLiteral<"oneOf">; values: z.ZodArray; }, "strict", z.ZodTypeAny, { values: unknown[]; property: "oneOf"; }, { values: unknown[]; property: "oneOf"; }>, z.ZodObject<{ property: z.ZodLiteral<"withinTolerance">; of: z.ZodNumber; tolerance: z.ZodNumber; }, "strict", z.ZodTypeAny, { tolerance: number; property: "withinTolerance"; of: number; }, { tolerance: number; property: "withinTolerance"; of: number; }>, z.ZodObject<{ property: z.ZodLiteral<"matchesPattern">; pattern: z.ZodString; }, "strict", z.ZodTypeAny, { property: "matchesPattern"; pattern: string; }, { property: "matchesPattern"; pattern: string; }>, z.ZodObject<{ property: z.ZodLiteral<"type">; is: z.ZodEnum<["string", "number", "boolean", "array", "object"]>; }, "strict", z.ZodTypeAny, { property: "type"; is: "string" | "number" | "boolean" | "object" | "array"; }, { property: "type"; is: "string" | "number" | "boolean" | "object" | "array"; }>, z.ZodObject<{ property: z.ZodLiteral<"changed">; }, "strict", z.ZodTypeAny, { property: "changed"; }, { property: "changed"; }>, z.ZodObject<{ property: z.ZodLiteral<"unchanged">; }, "strict", z.ZodTypeAny, { property: "unchanged"; }, { property: "unchanged"; }>, z.ZodObject<{ property: z.ZodLiteral<"increased">; by: z.ZodOptional; value: z.ZodNumber; /** Never negative — a negative tolerance NARROWS the band, which is a different claim by accident. */ tolerance: z.ZodOptional; }, "strict", z.ZodTypeAny, { value: number; op: "equals" | "at-least" | "at-most"; tolerance?: number | undefined; }, { value: number; op: "equals" | "at-least" | "at-most"; tolerance?: number | undefined; }>>; }, "strict", z.ZodTypeAny, { property: "increased"; by?: { value: number; op: "equals" | "at-least" | "at-most"; tolerance?: number | undefined; } | undefined; }, { property: "increased"; by?: { value: number; op: "equals" | "at-least" | "at-most"; tolerance?: number | undefined; } | undefined; }>, z.ZodObject<{ property: z.ZodLiteral<"decreased">; by: z.ZodOptional; value: z.ZodNumber; /** Never negative — a negative tolerance NARROWS the band, which is a different claim by accident. */ tolerance: z.ZodOptional; }, "strict", z.ZodTypeAny, { value: number; op: "equals" | "at-least" | "at-most"; tolerance?: number | undefined; }, { value: number; op: "equals" | "at-least" | "at-most"; tolerance?: number | undefined; }>>; }, "strict", z.ZodTypeAny, { property: "decreased"; by?: { value: number; op: "equals" | "at-least" | "at-most"; tolerance?: number | undefined; } | undefined; }, { property: "decreased"; by?: { value: number; op: "equals" | "at-least" | "at-most"; tolerance?: number | undefined; } | undefined; }>]>;