@hypequery/protocol-conformance 0.10.4 → 0.11.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.
@@ -4,6 +4,7 @@ export declare function materializeIdentifier(spec: Spec): string;
4
4
  export declare function materializeExpression(spec: Spec): unknown;
5
5
  export declare function materializeSchema(spec: Spec): unknown;
6
6
  export declare function materializeImplementation(spec: Spec): unknown;
7
+ export declare function materializeSemanticInvocation(spec: Spec): unknown;
7
8
  export declare function materializeEvent(spec: Spec): unknown;
8
9
  export declare function materializeDiagnostics(spec: Spec): unknown;
9
10
  export declare function materializeDeployment(spec: Spec): unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/adapters/generators.ts"],"names":[],"mappings":"AAIA,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAkBpC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAuC1D;AAID,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAMxD;AAMD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAiCzD;AAID,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CA2BrD;AAgBD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAuB7D;AAkBD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAyBpD;AAeD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAoB1D;AA2BD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAwDzD;AAkBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAmBrD;AAaD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAgBtD"}
1
+ {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/adapters/generators.ts"],"names":[],"mappings":"AAIA,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAkBpC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAuC1D;AAID,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAMxD;AAMD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAoCzD;AAID,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CA2BrD;AAgBD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAuB7D;AA4CD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAsFjE;AAkBD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAyBpD;AAeD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAoB1D;AA2BD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAyFzD;AAkBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAmBrD;AAaD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAgBtD"}
@@ -83,10 +83,10 @@ export function materializeExpression(spec) {
83
83
  return {
84
84
  kind: 'logical',
85
85
  operator: 'and',
86
- operands: Array.from({ length: 10 }, () => ({
86
+ operands: Array.from({ length: 10 }, (_, groupIndex) => ({
87
87
  kind: 'logical',
88
88
  operator: 'and',
89
- operands: Array.from({ length: 100 }, () => ({ ...EXPR_LITERAL })),
89
+ operands: Array.from({ length: groupIndex === 9 ? spec.lastGroupItems : 100 }, () => ({ ...EXPR_LITERAL })),
90
90
  })),
91
91
  };
92
92
  case 'unsafe-accessor': {
@@ -162,6 +162,134 @@ export function materializeImplementation(spec) {
162
162
  throw new Error(`Unknown implementation generator: ${String(spec.type)}`);
163
163
  }
164
164
  }
165
+ // --- semantic-invocations-v1 ---
166
+ const INVOCATION_REVISION = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';
167
+ const INVOCATION_LIMITS = {
168
+ maxRows: 10_000,
169
+ maxColumnsPerRow: 256,
170
+ maxValueBytes: 65_536,
171
+ maxDeadlineMs: 3_600_000,
172
+ maxMessageBytes: 1_024,
173
+ };
174
+ function baseInvocation() {
175
+ return {
176
+ kind: 'hypequery-semantic-invocation',
177
+ version: 1,
178
+ target: { project: 'acme', environment: 'production' },
179
+ operation: { kind: 'dataset', dataset: 'orders', measures: ['revenue'] },
180
+ };
181
+ }
182
+ function baseInvocationResult() {
183
+ return {
184
+ kind: 'hypequery-semantic-invocation-result',
185
+ version: 1,
186
+ activationRevision: INVOCATION_REVISION,
187
+ data: [{ status: 'paid' }],
188
+ meta: { rowCount: 1 },
189
+ };
190
+ }
191
+ function baseInvocationFailure() {
192
+ return {
193
+ kind: 'hypequery-semantic-invocation-failure',
194
+ version: 1,
195
+ category: 'input-invalid',
196
+ code: 'HQ_SEMANTIC_UNKNOWN_DIMENSION',
197
+ message: 'The semantic query is invalid.',
198
+ retryable: false,
199
+ relist: false,
200
+ };
201
+ }
202
+ export function materializeSemanticInvocation(spec) {
203
+ switch (spec.type) {
204
+ case 'wrong-root-type': return [];
205
+ case 'unknown-root-field': return { ...baseInvocation(), extra: true };
206
+ case 'unsupported-version': return { ...baseInvocation(), version: 2 };
207
+ // A caller can never name a tenant; the field does not exist in the record.
208
+ case 'caller-supplied-tenant': return { ...baseInvocation(), tenant: 'acme' };
209
+ // Identifiers are normalized into `operation`; a second copy could disagree.
210
+ case 'redundant-operation-dataset': return { ...baseInvocation(), dataset: 'orders' };
211
+ case 'malformed-activation-revision':
212
+ return { ...baseInvocation(), activationRevision: 'not-a-digest' };
213
+ case 'empty-budget': return { ...baseInvocation(), budget: {} };
214
+ case 'zero-deadline': return { ...baseInvocation(), budget: { deadlineMs: 0 } };
215
+ case 'deadline-too-large':
216
+ return { ...baseInvocation(), budget: { deadlineMs: INVOCATION_LIMITS.maxDeadlineMs + 1 } };
217
+ case 'correlation-id-control-character':
218
+ return { ...baseInvocation(), correlationId: 'req\u0007id' };
219
+ case 'unsafe-accessor': {
220
+ const unsafe = baseInvocation();
221
+ Object.defineProperty(unsafe, 'kind', {
222
+ enumerable: true,
223
+ get: () => 'hypequery-semantic-invocation',
224
+ });
225
+ return unsafe;
226
+ }
227
+ case 'too-many-rows': {
228
+ const rows = INVOCATION_LIMITS.maxRows + 1;
229
+ return {
230
+ ...baseInvocationResult(),
231
+ data: Array.from({ length: rows }, () => ({ status: 'paid' })),
232
+ meta: { rowCount: rows },
233
+ };
234
+ }
235
+ case 'too-many-columns':
236
+ return {
237
+ ...baseInvocationResult(),
238
+ data: [Object.fromEntries(Array.from({ length: INVOCATION_LIMITS.maxColumnsPerRow + 1 }, (_, i) => [`c${i}`, i]))],
239
+ };
240
+ case 'non-finite-cell':
241
+ return { ...baseInvocationResult(), data: [{ revenue: Number.POSITIVE_INFINITY }] };
242
+ case 'nested-cell':
243
+ return { ...baseInvocationResult(), data: [{ breakdown: { paid: 1 } }] };
244
+ case 'cell-too-large':
245
+ return {
246
+ ...baseInvocationResult(),
247
+ data: [{ note: repeat('a', INVOCATION_LIMITS.maxValueBytes + 1) }],
248
+ };
249
+ case 'row-count-mismatch':
250
+ return { ...baseInvocationResult(), meta: { rowCount: 9 } };
251
+ case 'sparse-data-array': {
252
+ const data = [{ status: 'paid' }];
253
+ data.length = 3;
254
+ return { ...baseInvocationResult(), data, meta: { rowCount: 3 } };
255
+ }
256
+ case 'unknown-failure-category':
257
+ return { ...baseInvocationFailure(), category: 'exploded' };
258
+ case 'provider-shaped-failure-code':
259
+ return { ...baseInvocationFailure(), code: 'ClickHouseException: DB::Exception' };
260
+ case 'cell-control-character': {
261
+ return { ...baseInvocationResult(), data: [{ status: 'paid\u0007' }] };
262
+ }
263
+ case 'provider-shaped-failure-message': {
264
+ return { ...baseInvocationFailure(), message: 'SELECT * FROM private.orders WHERE tenant = acme' };
265
+ }
266
+ case 'custom-prototype-data-array': {
267
+ return { ...baseInvocationResult(), data: Object.setPrototypeOf([{ status: 'paid' }], {}) };
268
+ }
269
+ case 'accessor-data-array': {
270
+ const data = [{ status: 'paid' }];
271
+ Object.defineProperty(data, '0', { enumerable: true, get() { throw new Error('Getter must not execute'); } });
272
+ return { ...baseInvocationResult(), data };
273
+ }
274
+ case 'hidden-data-array-property': {
275
+ const data = [{ status: 'paid' }];
276
+ Object.defineProperty(data, 'hidden', { value: true });
277
+ return { ...baseInvocationResult(), data };
278
+ }
279
+ case 'symbol-data-array-property': {
280
+ const data = [{ status: 'paid' }];
281
+ Object.defineProperty(data, Symbol('hidden'), { value: true });
282
+ return { ...baseInvocationResult(), data };
283
+ }
284
+ case 'failure-message-too-large':
285
+ return {
286
+ ...baseInvocationFailure(),
287
+ message: repeat('a', INVOCATION_LIMITS.maxMessageBytes + 1),
288
+ };
289
+ default:
290
+ throw new Error(`Unknown semantic invocation generator: ${String(spec.type)}`);
291
+ }
292
+ }
165
293
  // --- query-events-v1 ---
166
294
  function baseEvent() {
167
295
  return {
@@ -307,8 +435,41 @@ export function materializeDeployment(spec) {
307
435
  });
308
436
  return { ...value, queries: [namedQuery('first'), namedQuery('second')] };
309
437
  }
438
+ case 'invalid-sensitivity':
439
+ return { ...value, datasets: [{ ...minimalDataset(), sensitivity: 'secret' }] };
440
+ case 'invalid-currency':
441
+ return { ...value, datasets: [{ ...minimalDataset(), currency: 'usd' }] };
442
+ case 'empty-defaults':
443
+ return { ...value, datasets: [{ ...minimalDataset(), defaults: {} }] };
444
+ case 'default-dimension-not-groupable':
445
+ return {
446
+ ...value,
447
+ datasets: [{
448
+ ...minimalDataset(),
449
+ dimensions: [{
450
+ name: 'status',
451
+ type: 'string',
452
+ source: { kind: 'column', column: 'status' },
453
+ filterable: true,
454
+ groupable: false,
455
+ }],
456
+ defaults: { dimensions: ['status'] },
457
+ }],
458
+ };
459
+ case 'default-grain-without-time-field':
460
+ // `timeGrain` has nothing to apply to unless the dataset declares
461
+ // `timeField`, so the reference reports it as a broken reference.
462
+ return { ...value, datasets: [{ ...minimalDataset(), defaults: { timeGrain: 'day' } }] };
310
463
  case 'too-many-datasets':
311
464
  return { ...value, datasets: Array.from({ length: 101 }, (_, i) => minimalDataset(`dataset_${i}`)) };
465
+ case 'too-many-synonyms':
466
+ return {
467
+ ...value,
468
+ datasets: [{
469
+ ...minimalDataset(),
470
+ synonyms: Array.from({ length: 101 }, (_, i) => `synonym_${i}`),
471
+ }],
472
+ };
312
473
  case 'source-too-large':
313
474
  return { ...value, datasets: [{ ...minimalDataset(), source: repeat('a', 1_025) }] };
314
475
  case 'unsafe-accessor': {
@@ -9,7 +9,7 @@ export declare const REFERENCE_HOSTILE_OBJECT_SUITE: {
9
9
  readonly count: 7;
10
10
  readonly mechanisms: readonly ["getter", "toJSON", "proxy", "custom-prototype", "symbol-key", "sparse-array", "cycle"];
11
11
  };
12
- export declare const REFERENCE_FAMILIES: readonly ["cache-keys-v1", "tagged-values-v1", "identifiers-v1", "expressions-v1", "query-schemas-v1", "query-implementations-v1", "query-events-v1", "query-diagnostics-v1", "deployments-v1", "deployment-bundles-v1", "deployment-releases-v1"];
12
+ export declare const REFERENCE_FAMILIES: readonly ["cache-keys-v1", "tagged-values-v1", "identifiers-v1", "expressions-v1", "query-schemas-v1", "query-implementations-v1", "query-events-v1", "query-diagnostics-v1", "deployments-v1", "deployment-bundles-v1", "deployment-releases-v1", "semantic-invocations-v1"];
13
13
  export declare function referenceHandle(family: string, role: FixtureRole, c: Case, section?: string): HandlerResult;
14
14
  export {};
15
15
  //# sourceMappingURL=reference.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../../src/adapters/reference.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAc9D,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA0BpC;;;;GAIG;AACH,eAAO,MAAM,8BAA8B;;;CAWjC,CAAC;AAEX,eAAO,MAAM,kBAAkB,oPAYrB,CAAC;AAEX,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,WAAW,EACjB,CAAC,EAAE,IAAI,EACP,OAAO,CAAC,EAAE,MAAM,GACf,aAAa,CAoCf"}
1
+ {"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../../src/adapters/reference.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAe9D,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA0BpC;;;;GAIG;AACH,eAAO,MAAM,8BAA8B;;;CAWjC,CAAC;AAEX,eAAO,MAAM,kBAAkB,+QAarB,CAAC;AAEX,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,WAAW,EACjB,CAAC,EAAE,IAAI,EACP,OAAO,CAAC,EAAE,MAAM,GACf,aAAa,CAsCf"}
@@ -2,8 +2,8 @@
2
2
  // root export of @hypequery/protocol and returns a wire result. Every operation
3
3
  // goes through the package's supported surface — this is exactly what a second
4
4
  // implementation must reproduce.
5
- import { decodeCanonicalValue, deriveProtocolCacheKey, deriveProtocolCacheNamespaceToken, encodeCanonicalValue, hashCanonicalValue, parseProtocolIdentifier, parseProtocolQualifiedIdentifier, prepareProtocolDeploymentBundleManifest, prepareProtocolDeploymentContract, prepareProtocolDeploymentReleaseEnvelope, splitProtocolQualifiedIdentifier, validateCanonicalValue, validateProtocolDeploymentBundleManifest, validateProtocolDeploymentContract, validateProtocolDeploymentReleaseEnvelope, validateProtocolExpression, validateProtocolQueryDiagnostics, validateProtocolQueryEvent, validateProtocolQueryImplementation, validateProtocolSchema, validateProtocolSemanticQuery, validateProtocolSqlExpression, } from '@hypequery/protocol';
6
- import { materializeBundle, materializeDeployment, materializeDiagnostics, materializeEvent, materializeExpression, materializeIdentifier, materializeImplementation, materializeRelease, materializeSchema, materializeTaggedValue, } from './generators.js';
5
+ import { decodeCanonicalValue, deriveProtocolCacheKey, deriveProtocolCacheNamespaceToken, encodeCanonicalValue, hashCanonicalValue, parseProtocolIdentifier, parseProtocolQualifiedIdentifier, prepareProtocolDeploymentBundleManifest, prepareProtocolDeploymentContract, prepareProtocolDeploymentReleaseEnvelope, splitProtocolQualifiedIdentifier, validateCanonicalValue, validateProtocolDeploymentBundleManifest, validateProtocolDeploymentContract, validateProtocolDeploymentReleaseEnvelope, validateProtocolExpression, validateProtocolQueryDiagnostics, validateProtocolQueryEvent, validateProtocolQueryImplementation, validateProtocolSchema, validateProtocolSemanticInvocation, validateProtocolSemanticInvocationFailure, validateProtocolSemanticInvocationResult, validateProtocolSemanticQuery, validateProtocolSqlExpression, } from '@hypequery/protocol';
6
+ import { materializeBundle, materializeDeployment, materializeDiagnostics, materializeEvent, materializeSemanticInvocation, materializeExpression, materializeIdentifier, materializeImplementation, materializeRelease, materializeSchema, materializeTaggedValue, } from './generators.js';
7
7
  const STABLE_CODE = /^HQ_[A-Z0-9_]+$/;
8
8
  /** Turns a thrown protocol error into a wire rejection; rethrows anything else. */
9
9
  function mapError(error) {
@@ -54,6 +54,7 @@ export const REFERENCE_FAMILIES = [
54
54
  'deployments-v1',
55
55
  'deployment-bundles-v1',
56
56
  'deployment-releases-v1',
57
+ 'semantic-invocations-v1',
57
58
  ];
58
59
  export function referenceHandle(family, role, c, section) {
59
60
  switch (family) {
@@ -86,12 +87,34 @@ export function referenceHandle(family, role, c, section) {
86
87
  return handleBundle(role, c);
87
88
  case 'deployment-releases-v1':
88
89
  return handleRelease(role, c);
90
+ case 'semantic-invocations-v1':
91
+ return handleSemanticInvocation(c);
89
92
  case 'cache-keys-v1':
90
93
  return handleCacheKey(role, c);
91
94
  default:
92
95
  throw new Error(`reference adapter does not support family ${family}`);
93
96
  }
94
97
  }
98
+ /**
99
+ * One family covers the invocation, result, and failure records, so each case
100
+ * names which one it validates against.
101
+ */
102
+ function handleSemanticInvocation(c) {
103
+ const validators = {
104
+ invocation: validateProtocolSemanticInvocation,
105
+ result: validateProtocolSemanticInvocationResult,
106
+ failure: validateProtocolSemanticInvocationFailure,
107
+ };
108
+ const record = c.record;
109
+ const validate = record === undefined ? undefined : validators[record];
110
+ if (!validate) {
111
+ throw new Error(`semantic invocation case is missing a known record: ${String(c.record)}`);
112
+ }
113
+ return attempt(() => {
114
+ validate(validationInput(c, materializeSemanticInvocation));
115
+ return ACCEPT;
116
+ });
117
+ }
95
118
  function hexToBytes(hex) {
96
119
  const out = new Uint8Array(hex.length / 2);
97
120
  for (let index = 0; index < out.length; index += 1) {
@@ -167,7 +190,7 @@ function handleExpression(role, c, section) {
167
190
  const validate = isQuery ? validateProtocolSemanticQuery : validateProtocolExpression;
168
191
  if (role === 'success') {
169
192
  return attempt(() => {
170
- validate(c.value);
193
+ validate(validationInput(c, materializeExpression));
171
194
  return ACCEPT;
172
195
  });
173
196
  }
@@ -7,3 +7,5 @@ These fixtures exercise RFC 0006 deployment envelopes containing datasets, named
7
7
  - `identity.json` pins canonical bytes and deployment identities.
8
8
 
9
9
  Coverage includes closed fields, versions, identifiers, relationship queryability, missing runtime artifacts, ambiguous routes, collection limits, source limits, and unsafe accessors.
10
+
11
+ Semantic metadata (`examples`, `synonyms`, `format`, `unit`, `currency`, `timezone`, `sensitivity`) plus dataset `description`, `owner`, `freshness`, and `defaults` are covered by the `dataset-with-semantic-metadata` success case and by rejections for an unsupported sensitivity, a non-ISO currency, empty defaults, a default dimension that is not groupable, a default grain without a time field, and a synonym list above the 100-item semantic-metadata ceiling.
@@ -3,5 +3,10 @@
3
3
  "id": "dataset-and-runtime-query",
4
4
  "canonical": "{\"artifacts\":[{\"artifactSha256\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"runtime\":\"node\"}],\"datasets\":[{\"dimensions\":[{\"filterable\":true,\"groupable\":true,\"name\":\"status\",\"source\":{\"column\":\"status\",\"kind\":\"column\"},\"type\":\"string\"}],\"endpoint\":{\"access\":{\"kind\":\"authenticated\",\"roles\":[],\"scopes\":[\"read:orders\"]},\"maxLimit\":1000,\"path\":\"/api/analytics/datasets/orders/query\",\"tenant\":{\"column\":\"tenant_id\",\"kind\":\"required\",\"mode\":\"auto-inject\"}},\"filters\":[{\"field\":\"status\",\"name\":\"status\",\"operators\":[\"eq\",\"neq\"]}],\"limits\":{\"maxResultSize\":1000},\"measures\":[{\"aggregation\":\"sum\",\"field\":\"amount\",\"filters\":[],\"name\":\"revenue\"}],\"metrics\":[],\"name\":\"orders\",\"relationships\":[],\"source\":\"analytics.orders\",\"tenant\":{\"field\":\"tenant_id\",\"kind\":\"required\"},\"timeField\":\"created_at\"}],\"kind\":\"hypequery-deployment\",\"queries\":[{\"endpoint\":{\"access\":{\"kind\":\"public\"},\"method\":\"GET\",\"path\":\"/api/analytics/queries/health\",\"tenant\":{\"kind\":\"not-required\"}},\"implementation\":{\"artifactSha256\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"entrypoint\":\"queries.health\",\"kind\":\"runtime-reference\",\"runtime\":\"node\"},\"input\":{\"kind\":\"any\"},\"name\":\"health\",\"output\":{\"kind\":\"object\",\"properties\":{\"ok\":{\"kind\":\"boolean\"}},\"required\":[\"ok\"],\"unknownProperties\":\"strip\"},\"tags\":[\"system\"]}],\"version\":1}",
5
5
  "sha256": "1ec521ddeb1bf29205a2c0e2876b24b0eab49c0002825bc569071fbf6ad23e2d"
6
+ },
7
+ {
8
+ "id": "dataset-with-semantic-metadata",
9
+ "canonical": "{\"artifacts\":[],\"datasets\":[{\"defaults\":{\"dimensions\":[\"status\"],\"timeGrain\":\"day\"},\"description\":\"Completed customer orders.\",\"dimensions\":[{\"examples\":[\"paid\",\"refunded\"],\"filterable\":true,\"groupable\":true,\"name\":\"status\",\"sensitivity\":\"public\",\"source\":{\"column\":\"status\",\"kind\":\"column\"},\"synonyms\":[\"state\"],\"type\":\"string\"}],\"filters\":[{\"examples\":[\"paid\"],\"field\":\"status\",\"name\":\"status\",\"operators\":[\"eq\",\"neq\"]}],\"freshness\":{\"maxAgeSeconds\":3600},\"measures\":[{\"aggregation\":\"sum\",\"currency\":\"USD\",\"field\":\"amount\",\"filters\":[],\"format\":\"0,0.00\",\"name\":\"revenue\",\"sensitivity\":\"confidential\",\"unit\":\"currency\"}],\"metrics\":[],\"name\":\"orders\",\"owner\":\"revenue-team\",\"relationships\":[],\"sensitivity\":\"internal\",\"source\":\"analytics.orders\",\"synonyms\":[\"purchases\",\"sales\"],\"tenant\":{\"field\":\"tenant_id\",\"kind\":\"required\"},\"timeField\":\"created_at\",\"timezone\":\"UTC\"}],\"kind\":\"hypequery-deployment\",\"queries\":[],\"version\":1}",
10
+ "sha256": "c5c349d90561634fa773753d0bccddfb8af60925f09bb0c9310af8fae3762ca9"
6
11
  }
7
12
  ]
@@ -6,7 +6,13 @@
6
6
  { "id": "invalid-relationship-queryability", "generator": { "type": "invalid-relationship-queryability" }, "error": "HQ_DEPLOYMENT_INVALID_VALUE" },
7
7
  { "id": "missing-runtime-artifact", "generator": { "type": "missing-runtime-artifact" }, "error": "HQ_DEPLOYMENT_INVALID_REFERENCE" },
8
8
  { "id": "ambiguous-query-route", "generator": { "type": "ambiguous-query-route" }, "error": "HQ_DEPLOYMENT_INVALID_VALUE" },
9
+ { "id": "invalid-sensitivity", "generator": { "type": "invalid-sensitivity" }, "error": "HQ_DEPLOYMENT_INVALID_VALUE" },
10
+ { "id": "invalid-currency", "generator": { "type": "invalid-currency" }, "error": "HQ_DEPLOYMENT_INVALID_VALUE" },
11
+ { "id": "empty-defaults", "generator": { "type": "empty-defaults" }, "error": "HQ_DEPLOYMENT_INVALID_VALUE" },
12
+ { "id": "default-dimension-not-groupable", "generator": { "type": "default-dimension-not-groupable" }, "error": "HQ_DEPLOYMENT_INVALID_REFERENCE" },
13
+ { "id": "default-grain-without-time-field", "generator": { "type": "default-grain-without-time-field" }, "error": "HQ_DEPLOYMENT_INVALID_REFERENCE" },
9
14
  { "id": "too-many-datasets", "generator": { "type": "too-many-datasets" }, "error": "HQ_DEPLOYMENT_TOO_MANY_ITEMS" },
15
+ { "id": "too-many-synonyms", "generator": { "type": "too-many-synonyms" }, "error": "HQ_DEPLOYMENT_TOO_MANY_ITEMS" },
10
16
  { "id": "source-too-large", "generator": { "type": "source-too-large" }, "error": "HQ_DEPLOYMENT_TOO_LARGE" },
11
17
  { "id": "unsafe-accessor", "generator": { "type": "unsafe-accessor" }, "error": "HQ_DEPLOYMENT_UNSAFE_OBJECT" }
12
18
  ]
@@ -77,5 +77,63 @@
77
77
  }
78
78
  ]
79
79
  }
80
+ },
81
+ {
82
+ "id": "dataset-with-semantic-metadata",
83
+ "value": {
84
+ "kind": "hypequery-deployment",
85
+ "version": 1,
86
+ "datasets": [
87
+ {
88
+ "name": "orders",
89
+ "description": "Completed customer orders.",
90
+ "source": "analytics.orders",
91
+ "owner": "revenue-team",
92
+ "freshness": { "maxAgeSeconds": 3600 },
93
+ "defaults": { "dimensions": ["status"], "timeGrain": "day" },
94
+ "synonyms": ["purchases", "sales"],
95
+ "timezone": "UTC",
96
+ "sensitivity": "internal",
97
+ "tenant": { "kind": "required", "field": "tenant_id" },
98
+ "timeField": "created_at",
99
+ "dimensions": [
100
+ {
101
+ "name": "status",
102
+ "type": "string",
103
+ "source": { "kind": "column", "column": "status" },
104
+ "filterable": true,
105
+ "groupable": true,
106
+ "examples": ["paid", "refunded"],
107
+ "synonyms": ["state"],
108
+ "sensitivity": "public"
109
+ }
110
+ ],
111
+ "measures": [
112
+ {
113
+ "name": "revenue",
114
+ "aggregation": "sum",
115
+ "field": "amount",
116
+ "filters": [],
117
+ "format": "0,0.00",
118
+ "unit": "currency",
119
+ "currency": "USD",
120
+ "sensitivity": "confidential"
121
+ }
122
+ ],
123
+ "filters": [
124
+ {
125
+ "name": "status",
126
+ "field": "status",
127
+ "operators": ["eq", "neq"],
128
+ "examples": ["paid"]
129
+ }
130
+ ],
131
+ "metrics": [],
132
+ "relationships": []
133
+ }
134
+ ],
135
+ "queries": [],
136
+ "artifacts": []
137
+ }
80
138
  }
81
139
  ]
@@ -1,7 +1,14 @@
1
1
  # Portable expression v1 fixtures
2
2
 
3
- This family accompanies RFC 0003 and covers the closed semantic expression registry plus metric and dataset query envelopes.
3
+ This family accompanies accepted RFC 0003 and covers the closed semantic expression registry plus metric and dataset query envelopes.
4
4
 
5
- `success.json` exercises accepted expressions and queries. `rejections.json` pins every stable failure code, including generated depth, width, node-count, and unsafe-accessor cases.
5
+ `success.json` exercises accepted expressions and queries. `rejections.json` pins every stable failure code, including generated depth, width, node-count, and unsafe-accessor cases. Together they pin the exact protocol boundaries: depth 16/17, 1,000/1,001 nodes, and 100/101 collection items.
6
6
 
7
- Each rejection selects the `expression` or `query` validation surface and contains exactly one literal value or deterministic generator.
7
+ Each case contains exactly one literal `value` or deterministic `generator`. Each rejection also selects the `expression` or `query` validation surface.
8
+
9
+ Generators have these language-neutral meanings:
10
+
11
+ - `nested-not` wraps the literal expression `{ "kind": "literal", "value": false }` in exactly `depth` logical `not` nodes.
12
+ - `logical-operands` creates one logical `and` node containing `count` distinct copies of that literal expression.
13
+ - `logical-tree` creates a logical `and` root with ten logical `and` groups. The first nine groups contain 100 distinct literal expressions and the tenth contains `lastGroupItems`. The resulting expression has exactly `911 + lastGroupItems` nodes.
14
+ - `unsafe-accessor` is host-model conditional under RFC 0012 and exposes a reference's `name` through an accessor rather than a data property.
@@ -9,9 +9,18 @@
9
9
  { "id": "comparison-empty-in-list", "mode": "expression", "value": { "kind": "comparison", "operator": "in", "left": { "kind": "reference", "name": "status" }, "right": { "kind": "literal", "value": { "$hypequery": { "type": "array", "version": 1, "values": [] } } } }, "error": "HQ_EXPRESSION_INVALID_ARITY" },
10
10
  { "id": "comparison-like-non-string", "mode": "expression", "value": { "kind": "comparison", "operator": "like", "left": { "kind": "reference", "name": "status" }, "right": { "kind": "literal", "value": 1.5 } }, "error": "HQ_EXPRESSION_INVALID_VALUE" },
11
11
  { "id": "expression-invalid-aggregation", "mode": "expression", "value": { "kind": "aggregate", "aggregation": "percentile", "field": "amount", "level": 2.0 }, "error": "HQ_EXPRESSION_INVALID_AGGREGATION" },
12
+ { "id": "aggregate-arg-with-filters", "mode": "expression", "value": { "kind": "aggregate", "aggregation": "argMax", "field": "status", "argField": "created_at", "filters": [] }, "error": "HQ_EXPRESSION_INVALID_AGGREGATION" },
13
+ { "id": "aggregate-non-arg-with-arg-field", "mode": "expression", "value": { "kind": "aggregate", "aggregation": "sum", "field": "amount", "argField": "created_at" }, "error": "HQ_EXPRESSION_INVALID_AGGREGATION" },
14
+ { "id": "aggregate-percentile-missing-level", "mode": "expression", "value": { "kind": "aggregate", "aggregation": "percentile", "field": "amount" }, "error": "HQ_EXPRESSION_INVALID_AGGREGATION" },
15
+ { "id": "aggregate-filter-not-predicate", "mode": "expression", "value": { "kind": "aggregate", "aggregation": "sum", "field": "amount", "filters": [{ "kind": "literal", "value": true }] }, "error": "HQ_EXPRESSION_INVALID_AGGREGATION" },
12
16
  { "id": "query-invalid-grain", "mode": "query", "value": { "kind": "dataset", "dataset": "orders", "by": "hour" }, "error": "HQ_EXPRESSION_INVALID_QUERY" },
13
- { "id": "expression-too-deep", "mode": "expression", "generator": { "type": "nested-not", "depth": 17 }, "error": "HQ_EXPRESSION_TOO_DEEP" },
14
- { "id": "expression-too-many-nodes", "mode": "expression", "generator": { "type": "logical-tree" }, "error": "HQ_EXPRESSION_TOO_MANY_NODES" },
17
+ { "id": "query-filter-not-predicate", "mode": "query", "value": { "kind": "dataset", "dataset": "orders", "filters": [{ "kind": "literal", "value": true }] }, "error": "HQ_EXPRESSION_INVALID_QUERY" },
18
+ { "id": "metric-query-measures-unknown", "mode": "query", "value": { "kind": "metric", "dataset": "orders", "metric": "revenue", "measures": [] }, "error": "HQ_EXPRESSION_UNKNOWN_FIELD" },
19
+ { "id": "query-limit-unsafe-integer", "mode": "query", "value": { "kind": "dataset", "dataset": "orders", "limit": 9007199254740992 }, "error": "HQ_EXPRESSION_INVALID_QUERY" },
20
+ { "id": "query-offset-negative", "mode": "query", "value": { "kind": "dataset", "dataset": "orders", "offset": -1 }, "error": "HQ_EXPRESSION_INVALID_QUERY" },
21
+ { "id": "query-order-direction-invalid", "mode": "query", "value": { "kind": "dataset", "dataset": "orders", "orderBy": [{ "field": "revenue", "direction": "ascending" }] }, "error": "HQ_EXPRESSION_INVALID_QUERY" },
22
+ { "id": "expression-too-deep", "mode": "expression", "generator": { "type": "nested-not", "depth": 16 }, "error": "HQ_EXPRESSION_TOO_DEEP" },
23
+ { "id": "expression-too-many-nodes", "mode": "expression", "generator": { "type": "logical-tree", "lastGroupItems": 90 }, "error": "HQ_EXPRESSION_TOO_MANY_NODES" },
15
24
  { "id": "expression-too-many-items", "mode": "expression", "generator": { "type": "logical-operands", "count": 101 }, "error": "HQ_EXPRESSION_TOO_MANY_ITEMS" },
16
25
  { "id": "expression-unsafe-accessor", "mode": "expression", "generator": { "type": "unsafe-accessor" }, "error": "HQ_EXPRESSION_UNSAFE_OBJECT" }
17
26
  ]
@@ -8,6 +8,7 @@
8
8
  { "id": "binary-divide", "value": { "kind": "binary", "operator": "divide", "left": { "kind": "reference", "name": "revenue" }, "right": { "kind": "literal", "value": 1.5 } } },
9
9
  { "id": "call-nullIfZero", "value": { "kind": "call", "function": "nullIfZero", "args": [{ "kind": "reference", "name": "orders" }] } },
10
10
  { "id": "call-coalesce", "value": { "kind": "call", "function": "coalesce", "args": [{ "kind": "reference", "name": "revenue" }, { "kind": "literal", "value": 0.5 }] } },
11
+ { "id": "call-round-one-argument", "value": { "kind": "call", "function": "round", "args": [{ "kind": "reference", "name": "revenue" }] } },
11
12
  { "id": "call-round", "value": { "kind": "call", "function": "round", "args": [{ "kind": "reference", "name": "revenue" }, { "kind": "literal", "value": 2.0 }] } },
12
13
  { "id": "call-floor", "value": { "kind": "call", "function": "floor", "args": [{ "kind": "reference", "name": "revenue" }] } },
13
14
  { "id": "call-ceil", "value": { "kind": "call", "function": "ceil", "args": [{ "kind": "reference", "name": "revenue" }] } },
@@ -25,6 +26,7 @@
25
26
  { "id": "logical-or", "value": { "kind": "logical", "operator": "or", "operands": [{ "kind": "literal", "value": true }, { "kind": "literal", "value": false }] } },
26
27
  { "id": "logical-not", "value": { "kind": "logical", "operator": "not", "operand": { "kind": "literal", "value": false } } },
27
28
  { "id": "aggregate-sum-filtered", "value": { "kind": "aggregate", "aggregation": "sum", "field": "amount", "filters": [{ "kind": "comparison", "operator": "eq", "left": { "kind": "reference", "name": "status" }, "right": { "kind": "literal", "value": "paid" } }] } },
29
+ { "id": "aggregate-sum-empty-filters", "value": { "kind": "aggregate", "aggregation": "sum", "field": "amount", "filters": [] } },
28
30
  { "id": "aggregate-count", "value": { "kind": "aggregate", "aggregation": "count", "field": "id" } },
29
31
  { "id": "aggregate-countDistinct", "value": { "kind": "aggregate", "aggregation": "countDistinct", "field": "customer_id" } },
30
32
  { "id": "aggregate-avg", "value": { "kind": "aggregate", "aggregation": "avg", "field": "amount" } },
@@ -35,11 +37,15 @@
35
37
  { "id": "aggregate-percentile", "value": { "kind": "aggregate", "aggregation": "percentile", "field": "amount", "level": 0.95 } },
36
38
  { "id": "aggregate-median-normalized", "value": { "kind": "aggregate", "aggregation": "percentile", "field": "amount", "level": 0.5 } },
37
39
  { "id": "aggregate-stddev", "value": { "kind": "aggregate", "aggregation": "stddev", "field": "amount" } },
38
- { "id": "aggregate-variance", "value": { "kind": "aggregate", "aggregation": "variance", "field": "amount" } }
40
+ { "id": "aggregate-variance", "value": { "kind": "aggregate", "aggregation": "variance", "field": "amount" } },
41
+ { "id": "limit-depth-16", "generator": { "type": "nested-not", "depth": 15 } },
42
+ { "id": "limit-nodes-1000", "generator": { "type": "logical-tree", "lastGroupItems": 89 } },
43
+ { "id": "limit-items-100", "generator": { "type": "logical-operands", "count": 100 } }
39
44
  ],
40
45
  "queries": [
41
46
  { "id": "dataset-all-query-features", "value": { "kind": "dataset", "dataset": "orders", "dimensions": ["status", "customer.country"], "measures": ["revenue", "orders"], "filters": [{ "kind": "comparison", "operator": "eq", "left": { "kind": "reference", "name": "status" }, "right": { "kind": "literal", "value": "paid" } }], "orderBy": [{ "field": "customer.country", "direction": "asc" }, { "field": "revenue", "direction": "desc" }], "limit": 100, "offset": 0, "by": "quarter", "includeMeta": true } },
42
47
  { "id": "metric-all-query-features", "value": { "kind": "metric", "dataset": "orders", "metric": "average_order_value", "dimensions": ["customer.country"], "filters": [], "orderBy": [{ "field": "period", "direction": "asc" }], "limit": 25, "offset": 50, "by": "week", "includeMeta": false } },
48
+ { "id": "query-safe-integer-maximum", "value": { "kind": "dataset", "dataset": "orders", "limit": 9007199254740991, "offset": 9007199254740991 } },
43
49
  { "id": "grain-day", "value": { "kind": "dataset", "dataset": "orders", "by": "day" } },
44
50
  { "id": "grain-month", "value": { "kind": "dataset", "dataset": "orders", "by": "month" } },
45
51
  { "id": "grain-year", "value": { "kind": "dataset", "dataset": "orders", "by": "year", "limit": 0 } }
@@ -221,6 +221,23 @@
221
221
  "role": "rejection"
222
222
  }
223
223
  ]
224
+ },
225
+ {
226
+ "name": "semantic-invocations-v1",
227
+ "rfc": "0014",
228
+ "codePrefixes": [
229
+ "HQ_INVOCATION_"
230
+ ],
231
+ "files": [
232
+ {
233
+ "path": "semantic-invocations-v1/success.json",
234
+ "role": "success"
235
+ },
236
+ {
237
+ "path": "semantic-invocations-v1/rejections.json",
238
+ "role": "rejection"
239
+ }
240
+ ]
224
241
  }
225
242
  ],
226
243
  "fuzz": [
@@ -0,0 +1,10 @@
1
+ # Semantic invocation v1 fixtures
2
+
3
+ These fixtures exercise RFC 0014 semantic invocation records: the dataset/metric invocation request, the successful result, and the closed failure record.
4
+
5
+ - `success.json` contains accepted language-neutral records, each tagged with the `record` it validates against.
6
+ - `rejections.json` pins generated invalid inputs and stable error codes.
7
+
8
+ Coverage includes closed fields, versions, the normalized single identifier location, activation-revision format, budget floors and ceilings, an empty budget, row and column limits, non-finite and non-scalar cells, a `rowCount` that disagrees with `data`, failure categories, provider-shaped failure codes, control characters, and unsafe accessors.
9
+
10
+ Every record carries a `record` discriminator (`invocation`, `result`, or `failure`) so one family covers all three without three near-identical fixture sets.
@@ -0,0 +1,29 @@
1
+ [
2
+ {"id": "wrong-root-type", "record": "invocation", "generator": {"type": "wrong-root-type"}, "error": "HQ_INVOCATION_TYPE"},
3
+ {"id": "unknown-root-field", "record": "invocation", "generator": {"type": "unknown-root-field"}, "error": "HQ_INVOCATION_UNKNOWN_FIELD"},
4
+ {"id": "unsupported-version", "record": "invocation", "generator": {"type": "unsupported-version"}, "error": "HQ_INVOCATION_INVALID_VERSION"},
5
+ {"id": "caller-supplied-tenant", "record": "invocation", "generator": {"type": "caller-supplied-tenant"}, "error": "HQ_INVOCATION_UNKNOWN_FIELD"},
6
+ {"id": "redundant-operation-dataset", "record": "invocation", "generator": {"type": "redundant-operation-dataset"}, "error": "HQ_INVOCATION_UNKNOWN_FIELD"},
7
+ {"id": "malformed-activation-revision", "record": "invocation", "generator": {"type": "malformed-activation-revision"}, "error": "HQ_INVOCATION_INVALID_VALUE"},
8
+ {"id": "empty-budget", "record": "invocation", "generator": {"type": "empty-budget"}, "error": "HQ_INVOCATION_INVALID_VALUE"},
9
+ {"id": "zero-deadline", "record": "invocation", "generator": {"type": "zero-deadline"}, "error": "HQ_INVOCATION_INVALID_VALUE"},
10
+ {"id": "deadline-too-large", "record": "invocation", "generator": {"type": "deadline-too-large"}, "error": "HQ_INVOCATION_TOO_LARGE"},
11
+ {"id": "correlation-id-control-character", "record": "invocation", "generator": {"type": "correlation-id-control-character"}, "error": "HQ_INVOCATION_INVALID_VALUE"},
12
+ {"id": "unsafe-accessor", "record": "invocation", "generator": {"type": "unsafe-accessor"}, "error": "HQ_INVOCATION_UNSAFE_OBJECT"},
13
+ {"id": "too-many-rows", "record": "result", "generator": {"type": "too-many-rows"}, "error": "HQ_INVOCATION_TOO_MANY_ITEMS"},
14
+ {"id": "too-many-columns", "record": "result", "generator": {"type": "too-many-columns"}, "error": "HQ_INVOCATION_TOO_MANY_ITEMS"},
15
+ {"id": "non-finite-cell", "record": "result", "generator": {"type": "non-finite-cell"}, "error": "HQ_INVOCATION_INVALID_VALUE"},
16
+ {"id": "nested-cell", "record": "result", "generator": {"type": "nested-cell"}, "error": "HQ_INVOCATION_TYPE"},
17
+ {"id": "cell-too-large", "record": "result", "generator": {"type": "cell-too-large"}, "error": "HQ_INVOCATION_TOO_LARGE"},
18
+ {"id": "row-count-mismatch", "record": "result", "generator": {"type": "row-count-mismatch"}, "error": "HQ_INVOCATION_INVALID_VALUE"},
19
+ {"id": "sparse-data-array", "record": "result", "generator": {"type": "sparse-data-array"}, "error": "HQ_INVOCATION_UNSAFE_OBJECT"},
20
+ {"id": "unknown-failure-category", "record": "failure", "generator": {"type": "unknown-failure-category"}, "error": "HQ_INVOCATION_INVALID_VALUE"},
21
+ {"id": "provider-shaped-failure-code", "record": "failure", "generator": {"type": "provider-shaped-failure-code"}, "error": "HQ_INVOCATION_INVALID_VALUE"},
22
+ {"id": "failure-message-too-large", "record": "failure", "generator": {"type": "failure-message-too-large"}, "error": "HQ_INVOCATION_TOO_LARGE"},
23
+ {"id": "cell-control-character", "record": "result", "generator": {"type": "cell-control-character"}, "error": "HQ_INVOCATION_INVALID_VALUE"},
24
+ {"id": "provider-shaped-failure-message", "record": "failure", "generator": {"type": "provider-shaped-failure-message"}, "error": "HQ_INVOCATION_INVALID_VALUE"},
25
+ {"id": "custom-prototype-data-array", "record": "result", "generator": {"type": "custom-prototype-data-array"}, "error": "HQ_INVOCATION_UNSAFE_OBJECT"},
26
+ {"id": "accessor-data-array", "record": "result", "generator": {"type": "accessor-data-array"}, "error": "HQ_INVOCATION_UNSAFE_OBJECT"},
27
+ {"id": "hidden-data-array-property", "record": "result", "generator": {"type": "hidden-data-array-property"}, "error": "HQ_INVOCATION_UNSAFE_OBJECT"},
28
+ {"id": "symbol-data-array-property", "record": "result", "generator": {"type": "symbol-data-array-property"}, "error": "HQ_INVOCATION_UNSAFE_OBJECT"}
29
+ ]
@@ -0,0 +1,102 @@
1
+ [
2
+ {
3
+ "id": "minimal-dataset-invocation",
4
+ "record": "invocation",
5
+ "value": {
6
+ "kind": "hypequery-semantic-invocation",
7
+ "version": 1,
8
+ "target": { "project": "acme", "environment": "production" },
9
+ "operation": { "kind": "dataset", "dataset": "orders", "measures": ["revenue"] }
10
+ }
11
+ },
12
+ {
13
+ "id": "pinned-metric-invocation-with-budget",
14
+ "record": "invocation",
15
+ "value": {
16
+ "kind": "hypequery-semantic-invocation",
17
+ "version": 1,
18
+ "target": { "project": "acme", "environment": "production" },
19
+ "activationRevision": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
20
+ "operation": {
21
+ "kind": "metric",
22
+ "dataset": "orders",
23
+ "metric": "total_revenue",
24
+ "dimensions": ["status"],
25
+ "by": "day",
26
+ "limit": 100,
27
+ "offset": 0
28
+ },
29
+ "budget": { "deadlineMs": 30000, "maxRows": 1000, "maxResponseBytes": 1048576 },
30
+ "correlationId": "req-7f3a"
31
+ }
32
+ },
33
+ {
34
+ "id": "empty-result",
35
+ "record": "result",
36
+ "value": {
37
+ "kind": "hypequery-semantic-invocation-result",
38
+ "version": 1,
39
+ "activationRevision": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
40
+ "data": [],
41
+ "meta": { "rowCount": 0 }
42
+ }
43
+ },
44
+ {
45
+ "id": "paginated-result",
46
+ "record": "result",
47
+ "value": {
48
+ "kind": "hypequery-semantic-invocation-result",
49
+ "version": 1,
50
+ "activationRevision": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
51
+ "data": [
52
+ { "status": "paid", "revenue": 1234.5, "refunded": false, "note": null },
53
+ { "status": "pending", "revenue": 0, "refunded": true, "note": "partial" }
54
+ ],
55
+ "meta": {
56
+ "rowCount": 2,
57
+ "pagination": { "limit": 2, "offset": 0, "hasMore": true }
58
+ }
59
+ }
60
+ },
61
+ {
62
+ "id": "correctable-failure",
63
+ "record": "failure",
64
+ "value": {
65
+ "kind": "hypequery-semantic-invocation-failure",
66
+ "version": 1,
67
+ "category": "input-invalid",
68
+ "code": "HQ_SEMANTIC_UNKNOWN_DIMENSION",
69
+ "message": "The semantic query is invalid.",
70
+ "path": "$.operation.dimensions[0]",
71
+ "retryable": false,
72
+ "relist": false
73
+ }
74
+ },
75
+ {
76
+ "id": "stale-activation-failure",
77
+ "record": "failure",
78
+ "value": {
79
+ "kind": "hypequery-semantic-invocation-failure",
80
+ "version": 1,
81
+ "category": "stale-activation",
82
+ "code": "HQ_SEMANTIC_STALE_ACTIVATION",
83
+ "message": "The pinned activation is no longer active.",
84
+ "retryable": true,
85
+ "relist": true,
86
+ "activationRevision": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
87
+ }
88
+ },
89
+ {
90
+ "id": "unsupported-capability-failure",
91
+ "record": "failure",
92
+ "value": {
93
+ "kind": "hypequery-semantic-invocation-failure",
94
+ "version": 1,
95
+ "category": "unsupported-capability",
96
+ "code": "HQ_SEMANTIC_DERIVED_METRIC_UNSUPPORTED",
97
+ "message": "Portable execution cannot reproduce this target.",
98
+ "retryable": false,
99
+ "relist": false
100
+ }
101
+ }
102
+ ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hypequery/protocol-conformance",
3
- "version": "0.10.4",
3
+ "version": "0.11.0",
4
4
  "description": "Cross-language conformance runner for the Hypequery analytics security protocol",
5
5
  "keywords": [
6
6
  "hypequery",
@@ -31,7 +31,7 @@
31
31
  "README.md"
32
32
  ],
33
33
  "dependencies": {
34
- "@hypequery/protocol": "^0.11.0"
34
+ "@hypequery/protocol": "^0.12.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/node": "^22.5.0",