@happyvertical/smrt-core 0.42.4 → 0.42.5

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/AGENTS.md CHANGED
@@ -18,6 +18,7 @@ subsystem you are editing. This file keeps what holds across all of them.
18
18
  | `src/change-signals.ts` + the generated `_events` SSE route | the push companion to the change feed — the signal bus, cross-replica fan-out, the SSE route, and its documented gaps | [agents/change-signals.md](agents/change-signals.md) |
19
19
  | `src/generators/` + `src/vite-plugin/web-collections.ts` | REST/CLI/MCP/web-collection generation, the `manifestHash` emission sites, and generated conditional-GET / ETag v2 semantics | [agents/generators.md](agents/generators.md) |
20
20
  | `src/schema/` | the four `SchemaGenerator` entry points, which two reach production, why schema drift stayed invisible, and the #2382 index/tenancy rules | [agents/schema-paths.md](agents/schema-paths.md) |
21
+ | `src/data-query.ts` | canonical bounded data-query normalizer: allowlisted fields, deterministic fingerprints, output validation, and transport-neutral envelope (#2444) | — |
21
22
 
22
23
  ## SmrtObject Lifecycle
23
24
 
@@ -90,6 +91,25 @@ The executor deliberately does not compose SQL, cache the plan, or change pool
90
91
  defaults. On failure it stops starting queued entries, drains operations already
91
92
  in flight, and rethrows the first error.
92
93
 
94
+ ## Canonical Bounded Data Queries (#2444)
95
+
96
+ `normalizeDataQueryRequest()` and `normalizeDataQueryResult()` are the trust
97
+ boundary for the transport-neutral table/report/content query envelope. An
98
+ authenticated adapter supplies a trusted `DataQuerySchema`; the caller only
99
+ gets its declared projectable/sortable/filterable/facetable fields. The helpers
100
+ never execute a query or decide tenant/principal access.
101
+
102
+ Use `createDataQueryFingerprint()` for cache and result correlation. It omits
103
+ the request id and page position, canonicalizes equivalent filter/projection/
104
+ facet forms, and adds the identity sort tie-break. Keep data-query values
105
+ scalar, requests/pages/facets positive and bounded, results within the schema
106
+ byte cap with declared field types preserved. Datetimes must be valid RFC 3339
107
+ instants, identity fields must be string/number/datetime-compatible, and JSON
108
+ result fields are depth/container/string/byte bounded before cloning. Return
109
+ only normalized `DataQueryResult` envelopes to REST, MCP,
110
+ WebMCP, and browser consumers. Adapter-specific report/content context wraps
111
+ the base envelope; it does not add unsafe fields or SQL-like controls to it.
112
+
93
113
  ## Object Memory & Semantic Search
94
114
 
95
115
  Two persistence primitives every `SmrtObject`/`SmrtCollection` inherits — load-bearing for learning agents, usable by any object. Full guide: `docs/content/core.md` → "Context Memory System".
@@ -0,0 +1,45 @@
1
+ import { DataQueryRequest, DataQueryResult, DataQuerySchema } from '@happyvertical/smrt-types';
2
+ import { ValidationError } from './errors';
3
+ /** Default and hard ceilings for normalized data-query input and output. */
4
+ export declare const DEFAULT_DATA_QUERY_PAGE_LIMIT = 50;
5
+ export declare const MAX_DATA_QUERY_PAGE_LIMIT = 1000;
6
+ export declare const DEFAULT_DATA_QUERY_RESULT_BYTES = 1000000;
7
+ export declare const MAX_DATA_QUERY_RESULT_BYTES = 10000000;
8
+ export declare const MAX_DATA_QUERY_REQUEST_BYTES = 100000;
9
+ export declare const MAX_DATA_QUERY_OFFSET = 1000000;
10
+ export declare const MAX_DATA_QUERY_FILTER_DEPTH = 8;
11
+ export declare const MAX_DATA_QUERY_FILTERS = 50;
12
+ export declare const MAX_DATA_QUERY_IN_VALUES = 100;
13
+ export declare const MAX_DATA_QUERY_FACETS = 20;
14
+ export declare const MAX_DATA_QUERY_WARNINGS = 100;
15
+ export declare const MAX_DATA_QUERY_CURSOR_LENGTH = 2048;
16
+ export declare const MAX_DATA_QUERY_JSON_DEPTH = 16;
17
+ export declare const MAX_DATA_QUERY_JSON_CONTAINER_ITEMS = 1000;
18
+ export declare const MAX_DATA_QUERY_JSON_STRING_LENGTH = 65536;
19
+ /** A typed 400-class failure for malformed or policy-disallowed data queries. */
20
+ export declare class DataQueryValidationError extends ValidationError {
21
+ readonly status = 400;
22
+ readonly publicMessage: string;
23
+ constructor(message: string, code?: string, details?: Record<string, unknown>);
24
+ }
25
+ /** Validate and canonicalize trusted adapter query policy before use. */
26
+ export declare function normalizeDataQuerySchema(value: unknown): DataQuerySchema;
27
+ /**
28
+ * Normalize an untrusted request against its trusted adapter schema. Equivalent
29
+ * projection/filter/facet orderings produce byte-identical output; sort order
30
+ * remains intact because it is semantically meaningful. The identity field is
31
+ * always projected even when a caller omits it.
32
+ */
33
+ export declare function normalizeDataQueryRequest(value: unknown, inputSchema: unknown): DataQueryRequest;
34
+ /** Canonical match/query form used for stable fingerprints (no request id/page). */
35
+ export declare function canonicalizeDataQuery(value: unknown, schema: unknown): string;
36
+ /** Collision-resistant canonical fingerprint for result correlation and selection scope. */
37
+ export declare function createDataQueryFingerprint(value: unknown, schema: unknown): string;
38
+ /**
39
+ * Validate an adapter result against the normalized request and its schema.
40
+ * This is the final projection boundary: undeclared fields, malformed totals,
41
+ * forged fingerprints, oversized rows, and authority-shaped prototype payloads
42
+ * cannot cross into REST, MCP, WebMCP, or browser consumers unnoticed.
43
+ */
44
+ export declare function normalizeDataQueryResult(value: unknown, inputRequest: unknown, inputSchema: unknown): DataQueryResult;
45
+ //# sourceMappingURL=data-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-query.d.ts","sourceRoot":"","sources":["../src/data-query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAUV,gBAAgB,EAChB,eAAe,EAGf,eAAe,EAGhB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,4EAA4E;AAC5E,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAC/C,eAAO,MAAM,+BAA+B,UAAY,CAAC;AACzD,eAAO,MAAM,2BAA2B,WAAa,CAAC;AACtD,eAAO,MAAM,4BAA4B,SAAU,CAAC;AACpD,eAAO,MAAM,qBAAqB,UAAY,CAAC;AAC/C,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAC7C,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,4BAA4B,OAAQ,CAAC;AAClD,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAC5C,eAAO,MAAM,mCAAmC,OAAQ,CAAC;AACzD,eAAO,MAAM,iCAAiC,QAAS,CAAC;AAexD,iFAAiF;AACjF,qBAAa,wBAAyB,SAAQ,eAAe;IAC3D,QAAQ,CAAC,MAAM,OAAO;IACtB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBAG7B,OAAO,EAAE,MAAM,EACf,IAAI,SAAuB,EAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAMpC;AAgWD,yEAAyE;AACzE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAiIxE;AA2UD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,EACd,WAAW,EAAE,OAAO,GACnB,gBAAgB,CAuGlB;AAED,oFAAoF;AACpF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAI7E;AAED,4FAA4F;AAC5F,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,OAAO,GACd,MAAM,CAER;AAuLD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,OAAO,EACrB,WAAW,EAAE,OAAO,GACnB,eAAe,CAuLjB"}