@suss/ir-core 0.7.2 → 0.9.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/README.md +43 -0
- package/dist/{chunk-TEXSN75M.js → chunk-XUXN6DIX.js} +165 -77
- package/dist/index.cjs +230 -92
- package/dist/index.d.cts +85 -9
- package/dist/index.d.ts +85 -9
- package/dist/index.js +54 -3
- package/dist/{schemas-D6hKT-zV.d.cts → schemas-CGR6qjFf.d.cts} +31 -8
- package/dist/{schemas-D6hKT-zV.d.ts → schemas-CGR6qjFf.d.ts} +31 -8
- package/dist/schemas.cjs +153 -74
- package/dist/schemas.d.cts +1 -1
- package/dist/schemas.d.ts +1 -1
- package/dist/schemas.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,6 +31,49 @@ The boundary key uses only the subject, so both forms end up in the same bucket
|
|
|
31
31
|
|
|
32
32
|
Schemas are the single source of truth (`@suss/ir-core/schemas`); the types are derived from them. The recursive `TypeShape` is a hand-written named export so consuming packages reference it by name across the package boundary rather than inlining the recursion.
|
|
33
33
|
|
|
34
|
+
## Names with a hole in them
|
|
35
|
+
|
|
36
|
+
A deployed resource is often called something built at deploy time. A template writes `!Sub "${StageName}-orders-v1"` and the code writes `` `${stage}-orders-v1` ``, so neither side states a string, both agree about the fixed text, and each spells the parameter its own way. A name is written here as fixed text with `{}` holes, and `namesAgree` says whether two of them are the same name.
|
|
37
|
+
|
|
38
|
+
A hole stops at the separator between it and what comes next. No separator works for every project, so the rule does not name one, it takes the separator from the pattern: when the fixed text after a hole starts with a character that is not a letter or a digit, that character divides the deploy-time value from the rest of the name, and the value may not contain it. So `{env}-publications-v1` covers `prod-publications-v1`, and it does not cover `prod-creator-publications-v1`, which the hole could only reach by swallowing a `-`.
|
|
39
|
+
|
|
40
|
+
A greedy hole was the earlier rule, and a module declaring both of those tables had one storage access pair with each of them. The table the code never touches keys on something else, so the run reported a selector mismatch on a boundary that code never reaches.
|
|
41
|
+
|
|
42
|
+
A hole at the end of a name, and a hole whose next character is a letter or a digit, has no separator to stop at, and it still covers anything. That costs a pair when the value has the separator inside it: `{region}-orders` does not cover `us-east-1-orders`, though `orders-{region}` still covers `orders-us-east-1`. Missing a pair is the better failure of the two, since a wrong match reports findings about a store the code never touches.
|
|
43
|
+
|
|
44
|
+
One name can still be covered by two patterns. A hole at the end covers anything, so `orders-{suffix}` and `orders-blue-{suffix}` both cover `orders-blue-v1`. Choosing between them belongs to whichever pass picks a provider for an access, and `fixedTextLength` is what such a pass ranks by: the pattern that states more fixed text is the more specific one, and two patterns that state the same amount settle nothing between them.
|
|
45
|
+
|
|
46
|
+
## Words OpenTelemetry already has
|
|
47
|
+
|
|
48
|
+
A summary says what a unit can reach. A trace says what it did reach. Comparing the two is the point, and it only works if both sides spell a boundary the same way, so wherever OpenTelemetry's semantic conventions have a word for something in a binding, that is the word suss writes.
|
|
49
|
+
|
|
50
|
+
The values are theirs. A Postgres table is `postgresql`, not `postgres`; a DynamoDB table is `aws.dynamodb`; an SQS queue is `aws_sqs` and an SNS topic is `aws.sns`, spelled the two different ways the conventions spell them.
|
|
51
|
+
|
|
52
|
+
The field names are ours. Each protocol module says which attribute each of its fields goes under, and `semconvAttributes(binding)` reads a binding as the attributes a span would state:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
semconvAttributes(
|
|
56
|
+
storageBinding({
|
|
57
|
+
recognition: "prisma",
|
|
58
|
+
storageSystem: "postgresql",
|
|
59
|
+
scope: "orders",
|
|
60
|
+
container: "users",
|
|
61
|
+
}),
|
|
62
|
+
);
|
|
63
|
+
// { "db.system.name": "postgresql", "db.namespace": "orders",
|
|
64
|
+
// "db.collection.name": "users" }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
A field appears in that projection only when the value suss writes is the value a span gets, so the comparison is byte for byte with nothing in between. Three kinds of field stay out of it:
|
|
68
|
+
|
|
69
|
+
- **A field the conventions have no attribute for.** A secondary index (`accessPath`) is one, and a GraphQL resolver's type and field are another, since the conventions describe the operation a client sent and not the resolver the server ran for one field of it.
|
|
70
|
+
- **A value suss writes where the source stated none.** `scope: "default"` means no source said which database, and a REST method of `"*"` means the route responds to every method. A span says neither.
|
|
71
|
+
- **The same thing under a different string.** `service.name` and `cloud.resource_id` both point at the deployable a `runtime-config` boundary belongs to, but `instanceName` is the deployment template's logical id, which is neither of those strings.
|
|
72
|
+
|
|
73
|
+
Where the conventions have no word at all, suss keeps its own: a store they never covered (`s3`, `gcs`, `r2`, `d1`, `cloudflare-kv`), a bus they never covered (`eventbridge`, `bullmq`, `nats`, the Cloudflare triggers), a metric's system and type, and every boundary nobody crosses at run time, which is a function call across a package boundary, a contract a template declares, and an intent. Those are the boundaries suss exists for, and no observability convention has a word for them.
|
|
74
|
+
|
|
75
|
+
Adding a protocol means filling in `semconv` on its definition, empty included, so the question gets answered rather than skipped.
|
|
76
|
+
|
|
34
77
|
## Where it fits in suss
|
|
35
78
|
|
|
36
79
|
Both `@suss/behavioral-ir` (what code does) and `@suss/intent-ir` (what the team meant) build on this package, so neither IR depends on the other. They describe boundaries in the same vocabulary, and suss compares them rather than merging them. `@suss/behavioral-ir` re-exports these primitives, so existing consumers keep importing them from there unchanged.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// src/schemas.ts
|
|
2
|
-
import { z as
|
|
2
|
+
import { z as z11 } from "zod";
|
|
3
3
|
|
|
4
4
|
// src/semantics/registry.ts
|
|
5
|
-
import { z as
|
|
5
|
+
import { z as z10 } from "zod";
|
|
6
6
|
|
|
7
7
|
// src/semantics/functionCall.ts
|
|
8
8
|
import { z } from "zod";
|
|
@@ -17,6 +17,9 @@ function fnIdentityKey(packageName, exportPath) {
|
|
|
17
17
|
function busIdentityKey(messageBus, subject) {
|
|
18
18
|
return `bus:${messageBus} ${subject}`;
|
|
19
19
|
}
|
|
20
|
+
function metricIdentityKey(metricSystem, metricType) {
|
|
21
|
+
return `metric:${metricSystem} ${metricType}`;
|
|
22
|
+
}
|
|
20
23
|
|
|
21
24
|
// src/semantics/definition.ts
|
|
22
25
|
function defineBoundarySemantics(definition) {
|
|
@@ -58,6 +61,9 @@ var FunctionCallSemanticsSchema = z.object({
|
|
|
58
61
|
var functionCallSemantics = defineBoundarySemantics({
|
|
59
62
|
name: "function-call",
|
|
60
63
|
schema: FunctionCallSemanticsSchema,
|
|
64
|
+
// A call that never leaves the process does not produce a span, and
|
|
65
|
+
// the conventions do not name one. All of it is ours.
|
|
66
|
+
semconv: {},
|
|
61
67
|
behavior: {
|
|
62
68
|
/** A call returns a value, which is not a status and a body. */
|
|
63
69
|
exchangesHttpResponses: false,
|
|
@@ -93,6 +99,10 @@ var GraphqlOperationSemanticsSchema = z2.object({
|
|
|
93
99
|
var graphqlOperationSemantics = defineBoundarySemantics({
|
|
94
100
|
name: "graphql-operation",
|
|
95
101
|
schema: GraphqlOperationSemanticsSchema,
|
|
102
|
+
semconv: {
|
|
103
|
+
operationName: { name: "graphql.operation.name" },
|
|
104
|
+
operationType: { name: "graphql.operation.type" }
|
|
105
|
+
},
|
|
96
106
|
behavior: {
|
|
97
107
|
/**
|
|
98
108
|
* An operation gets a data-and-errors document back, which the
|
|
@@ -126,6 +136,9 @@ var GraphqlResolverSemanticsSchema = z3.object({
|
|
|
126
136
|
var graphqlResolverSemantics = defineBoundarySemantics({
|
|
127
137
|
name: "graphql-resolver",
|
|
128
138
|
schema: GraphqlResolverSemanticsSchema,
|
|
139
|
+
// The conventions name the operation a client sent, not the
|
|
140
|
+
// resolver the server ran for one field of it.
|
|
141
|
+
semconv: {},
|
|
129
142
|
behavior: {
|
|
130
143
|
/** A resolver returns a field value, not a status and a body. */
|
|
131
144
|
exchangesHttpResponses: false,
|
|
@@ -174,13 +187,19 @@ function channelsPair(a, b) {
|
|
|
174
187
|
var MessageBusSemanticsSchema = z4.object({
|
|
175
188
|
name: z4.literal("message-bus"),
|
|
176
189
|
messageBus: z4.enum([
|
|
177
|
-
|
|
178
|
-
|
|
190
|
+
// The conventions spell the two AWS buses this way, one with an
|
|
191
|
+
// underscore and one with a dot, so these are their strings and
|
|
192
|
+
// not a typo.
|
|
193
|
+
"aws_sqs",
|
|
194
|
+
"aws.sns",
|
|
179
195
|
"s3",
|
|
180
196
|
"eventbridge",
|
|
181
197
|
"bullmq",
|
|
182
198
|
"kafka",
|
|
183
|
-
"nats"
|
|
199
|
+
"nats",
|
|
200
|
+
"cloudflare-queues",
|
|
201
|
+
"cloudflare-cron",
|
|
202
|
+
"cloudflare-tail"
|
|
184
203
|
]),
|
|
185
204
|
/**
|
|
186
205
|
* Stable channel identifier: a CFN logical id, a queue or topic name,
|
|
@@ -193,6 +212,10 @@ var MessageBusSemanticsSchema = z4.object({
|
|
|
193
212
|
var messageBusSemantics = defineBoundarySemantics({
|
|
194
213
|
name: "message-bus",
|
|
195
214
|
schema: MessageBusSemanticsSchema,
|
|
215
|
+
semconv: {
|
|
216
|
+
messageBus: { name: "messaging.system" },
|
|
217
|
+
channel: { name: "messaging.destination.name" }
|
|
218
|
+
},
|
|
196
219
|
behavior: {
|
|
197
220
|
/** A message goes onto the channel and nothing comes back. */
|
|
198
221
|
exchangesHttpResponses: false,
|
|
@@ -251,25 +274,58 @@ var messageBusSemantics = defineBoundarySemantics({
|
|
|
251
274
|
}
|
|
252
275
|
});
|
|
253
276
|
|
|
254
|
-
// src/semantics/
|
|
277
|
+
// src/semantics/metric.ts
|
|
255
278
|
import { z as z5 } from "zod";
|
|
256
|
-
var
|
|
257
|
-
name: z5.literal("
|
|
279
|
+
var MetricSemanticsSchema = z5.object({
|
|
280
|
+
name: z5.literal("metric"),
|
|
281
|
+
/** Which system the series lives in: cloud-monitoring, cloudwatch. */
|
|
282
|
+
metricSystem: z5.string(),
|
|
283
|
+
/**
|
|
284
|
+
* The type string the system knows the metric by, spelled the way
|
|
285
|
+
* both sides spell it. Null when the source states one this reader
|
|
286
|
+
* could not settle, as with a query it could not read: a metric
|
|
287
|
+
* nobody could name pairs with nothing rather than with whatever
|
|
288
|
+
* happens to share its source text.
|
|
289
|
+
*/
|
|
290
|
+
metricType: z5.string().nullable()
|
|
291
|
+
});
|
|
292
|
+
var metricSemantics = defineBoundarySemantics({
|
|
293
|
+
name: "metric",
|
|
294
|
+
schema: MetricSemanticsSchema,
|
|
295
|
+
// OpenTelemetry knows a metric by its instrument name, and has no
|
|
296
|
+
// attribute for the system it lives in or the type string it goes by.
|
|
297
|
+
semconv: {},
|
|
298
|
+
behavior: {
|
|
299
|
+
exchangesHttpResponses: false,
|
|
300
|
+
reportsUnpairedItself: false,
|
|
301
|
+
identityKey(semantics) {
|
|
302
|
+
if (semantics.metricType === null) {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
return metricIdentityKey(semantics.metricSystem, semantics.metricType);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// src/semantics/rest.ts
|
|
311
|
+
import { z as z6 } from "zod";
|
|
312
|
+
var RestSemanticsSchema = z6.object({
|
|
313
|
+
name: z6.literal("rest"),
|
|
258
314
|
/**
|
|
259
315
|
* Uppercase HTTP method ("GET", "POST", …), `"*"` for a handler that
|
|
260
316
|
* responds to every method, or null when this source does not say
|
|
261
317
|
* which method.
|
|
262
318
|
*/
|
|
263
|
-
method:
|
|
319
|
+
method: z6.string().min(1).nullable(),
|
|
264
320
|
/** Normalized route path ("/users/{id}"), or null when this source does not give one. */
|
|
265
|
-
path:
|
|
321
|
+
path: z6.string().min(1).nullable(),
|
|
266
322
|
/**
|
|
267
323
|
* Status codes the producing source explicitly declared (OpenAPI
|
|
268
324
|
* responses, CFN MethodResponses, ts-rest router statuses). They are
|
|
269
325
|
* kept here so the pairing layer can see them without unwrapping any
|
|
270
326
|
* metadata. Absent, or empty, for a source that was inferred.
|
|
271
327
|
*/
|
|
272
|
-
declaredResponses:
|
|
328
|
+
declaredResponses: z6.array(z6.number()).optional()
|
|
273
329
|
});
|
|
274
330
|
function normalizePath(path) {
|
|
275
331
|
let normalized = path.replace(/:([a-zA-Z_]\w*)/g, "{$1}");
|
|
@@ -308,6 +364,14 @@ function routePathAdmits(declaredPath, requestPath) {
|
|
|
308
364
|
var restSemantics = defineBoundarySemantics({
|
|
309
365
|
name: "rest",
|
|
310
366
|
schema: RestSemanticsSchema,
|
|
367
|
+
semconv: {
|
|
368
|
+
// A span states the one method a request used, so a route that
|
|
369
|
+
// responds to every method has nothing to compare.
|
|
370
|
+
method: { name: "http.request.method", placeholderValues: ["*"] },
|
|
371
|
+
path: { name: "http.route" }
|
|
372
|
+
// declaredResponses is a list, and http.response.status_code is
|
|
373
|
+
// the one status a request got back.
|
|
374
|
+
},
|
|
311
375
|
behavior: {
|
|
312
376
|
/** A request goes out, a status and a body come back. */
|
|
313
377
|
exchangesHttpResponses: true,
|
|
@@ -380,20 +444,21 @@ var restSemantics = defineBoundarySemantics({
|
|
|
380
444
|
});
|
|
381
445
|
|
|
382
446
|
// src/semantics/runtimeConfig.ts
|
|
383
|
-
import { z as
|
|
447
|
+
import { z as z8 } from "zod";
|
|
384
448
|
|
|
385
449
|
// src/deployableUnit.ts
|
|
386
|
-
import { z as
|
|
387
|
-
var DeployableUnitSchema =
|
|
388
|
-
deploymentTarget:
|
|
450
|
+
import { z as z7 } from "zod";
|
|
451
|
+
var DeployableUnitSchema = z7.object({
|
|
452
|
+
deploymentTarget: z7.enum([
|
|
389
453
|
"lambda",
|
|
390
454
|
"ecs-task",
|
|
391
455
|
"container",
|
|
392
|
-
"k8s-deployment"
|
|
456
|
+
"k8s-deployment",
|
|
457
|
+
"worker"
|
|
393
458
|
]),
|
|
394
459
|
// An empty name would agree with every other empty name, so a unit
|
|
395
460
|
// with no name has to leave the field off instead.
|
|
396
|
-
instanceName:
|
|
461
|
+
instanceName: z7.string().min(1)
|
|
397
462
|
});
|
|
398
463
|
function ecsContainerInstanceName(taskDefinitionLogicalId, containerName) {
|
|
399
464
|
return `${taskDefinitionLogicalId}/${containerName}`;
|
|
@@ -401,11 +466,15 @@ function ecsContainerInstanceName(taskDefinitionLogicalId, containerName) {
|
|
|
401
466
|
|
|
402
467
|
// src/semantics/runtimeConfig.ts
|
|
403
468
|
var RuntimeConfigSemanticsSchema = DeployableUnitSchema.extend({
|
|
404
|
-
name:
|
|
469
|
+
name: z8.literal("runtime-config")
|
|
405
470
|
});
|
|
406
471
|
var runtimeConfigSemantics = defineBoundarySemantics({
|
|
407
472
|
name: "runtime-config",
|
|
408
473
|
schema: RuntimeConfigSemanticsSchema,
|
|
474
|
+
// service.name and cloud.resource_id name the same deployable, but
|
|
475
|
+
// instanceName is the deployment template's logical id, which is
|
|
476
|
+
// neither of those strings.
|
|
477
|
+
semconv: {},
|
|
409
478
|
behavior: {
|
|
410
479
|
/** A process reads its config at startup, and nothing replies. */
|
|
411
480
|
exchangesHttpResponses: false,
|
|
@@ -415,28 +484,28 @@ var runtimeConfigSemantics = defineBoundarySemantics({
|
|
|
415
484
|
});
|
|
416
485
|
|
|
417
486
|
// src/semantics/storage.ts
|
|
418
|
-
import { z as
|
|
419
|
-
var StorageSemanticsSchema =
|
|
420
|
-
name:
|
|
487
|
+
import { z as z9 } from "zod";
|
|
488
|
+
var StorageSemanticsSchema = z9.object({
|
|
489
|
+
name: z9.literal("storage"),
|
|
421
490
|
/**
|
|
422
|
-
* Which store this is:
|
|
423
|
-
*
|
|
424
|
-
*
|
|
491
|
+
* Which store this is: postgresql, mysql, aws.dynamodb, or our own
|
|
492
|
+
* word for one OpenTelemetry never named, such as s3. Two products'
|
|
493
|
+
* containers can share a name, so this keeps them apart.
|
|
425
494
|
*/
|
|
426
|
-
storageSystem:
|
|
495
|
+
storageSystem: z9.string(),
|
|
427
496
|
/**
|
|
428
497
|
* The ORM, schema, or deployment scope. A single-database setup uses
|
|
429
498
|
* `"default"`, and a monorepo with several schemas gives each one its
|
|
430
499
|
* own value.
|
|
431
500
|
*/
|
|
432
|
-
scope:
|
|
501
|
+
scope: z9.string(),
|
|
433
502
|
/**
|
|
434
503
|
* The table, bucket, collection, or index, as the source declares
|
|
435
504
|
* it, or null when the source states one this reader could not
|
|
436
505
|
* settle. A null container pairs with nothing, rather than with
|
|
437
506
|
* whatever its source text happens to spell.
|
|
438
507
|
*/
|
|
439
|
-
container:
|
|
508
|
+
container: z9.string().nullable(),
|
|
440
509
|
/**
|
|
441
510
|
* A secondary way into the container, a DynamoDB global secondary
|
|
442
511
|
* index or an Elasticsearch alias, each with its own key fields.
|
|
@@ -444,11 +513,19 @@ var StorageSemanticsSchema = z8.object({
|
|
|
444
513
|
* index and a query through the table are different accesses, so
|
|
445
514
|
* they pair separately.
|
|
446
515
|
*/
|
|
447
|
-
accessPath:
|
|
516
|
+
accessPath: z9.string().nullable()
|
|
448
517
|
});
|
|
449
518
|
var storageSemantics = defineBoundarySemantics({
|
|
450
519
|
name: "storage",
|
|
451
520
|
schema: StorageSemanticsSchema,
|
|
521
|
+
semconv: {
|
|
522
|
+
storageSystem: { name: "db.system.name" },
|
|
523
|
+
// "default" is our word for a source that named no database.
|
|
524
|
+
scope: { name: "db.namespace", placeholderValues: ["default"] },
|
|
525
|
+
container: { name: "db.collection.name" }
|
|
526
|
+
// A secondary index has no attribute of its own, so accessPath
|
|
527
|
+
// stays our word.
|
|
528
|
+
},
|
|
452
529
|
behavior: {
|
|
453
530
|
/** A query returns rows or items, not a status and a body. */
|
|
454
531
|
exchangesHttpResponses: false,
|
|
@@ -458,14 +535,15 @@ var storageSemantics = defineBoundarySemantics({
|
|
|
458
535
|
});
|
|
459
536
|
|
|
460
537
|
// src/semantics/registry.ts
|
|
461
|
-
var SemanticsSchema =
|
|
538
|
+
var SemanticsSchema = z10.discriminatedUnion("name", [
|
|
462
539
|
restSemantics.schema,
|
|
463
540
|
functionCallSemantics.schema,
|
|
464
541
|
graphqlResolverSemantics.schema,
|
|
465
542
|
graphqlOperationSemantics.schema,
|
|
466
543
|
runtimeConfigSemantics.schema,
|
|
467
544
|
storageSemantics.schema,
|
|
468
|
-
messageBusSemantics.schema
|
|
545
|
+
messageBusSemantics.schema,
|
|
546
|
+
metricSemantics.schema
|
|
469
547
|
]);
|
|
470
548
|
var DEFINITIONS = [
|
|
471
549
|
restSemantics,
|
|
@@ -474,48 +552,55 @@ var DEFINITIONS = [
|
|
|
474
552
|
graphqlOperationSemantics,
|
|
475
553
|
runtimeConfigSemantics,
|
|
476
554
|
storageSemantics,
|
|
477
|
-
messageBusSemantics
|
|
555
|
+
messageBusSemantics,
|
|
556
|
+
metricSemantics
|
|
478
557
|
];
|
|
479
558
|
var BY_NAME = new Map(
|
|
480
559
|
DEFINITIONS.map((d) => [d.name, d])
|
|
481
560
|
);
|
|
482
561
|
function behaviorOf(semantics) {
|
|
483
|
-
|
|
562
|
+
return definitionFor(semantics.name).behavior;
|
|
563
|
+
}
|
|
564
|
+
function definitionFor(name) {
|
|
565
|
+
const definition = BY_NAME.get(name);
|
|
484
566
|
if (definition === void 0) {
|
|
485
|
-
throw new Error(`no boundary
|
|
567
|
+
throw new Error(`no boundary definition for semantics "${name}"`);
|
|
486
568
|
}
|
|
487
|
-
return definition
|
|
569
|
+
return definition;
|
|
570
|
+
}
|
|
571
|
+
function semconvMappingOf(semantics) {
|
|
572
|
+
return definitionFor(semantics.name).semconv;
|
|
488
573
|
}
|
|
489
574
|
function allBehaviors() {
|
|
490
575
|
return DEFINITIONS.map((d) => d.behavior);
|
|
491
576
|
}
|
|
492
577
|
|
|
493
578
|
// src/schemas.ts
|
|
494
|
-
var ConfidenceSourceSchema =
|
|
579
|
+
var ConfidenceSourceSchema = z11.enum([
|
|
495
580
|
"inferred_static",
|
|
496
581
|
"inferred_ai",
|
|
497
582
|
"declared",
|
|
498
583
|
"derived"
|
|
499
584
|
]);
|
|
500
|
-
var ConfidenceLevelSchema =
|
|
501
|
-
var CorroborationSchema =
|
|
502
|
-
outcome:
|
|
585
|
+
var ConfidenceLevelSchema = z11.enum(["high", "medium", "low"]);
|
|
586
|
+
var CorroborationSchema = z11.object({
|
|
587
|
+
outcome: z11.enum(["observed", "refuted", "untested"]),
|
|
503
588
|
/** Executions that produced a verdict for this claim. */
|
|
504
|
-
runs:
|
|
589
|
+
runs: z11.number(),
|
|
505
590
|
/** Present when refuted: the input and observation that disagreed. */
|
|
506
|
-
counterexample:
|
|
591
|
+
counterexample: z11.unknown().optional(),
|
|
507
592
|
/** Present when untested: why no verdict was reachable. */
|
|
508
|
-
reason:
|
|
593
|
+
reason: z11.string().optional()
|
|
509
594
|
});
|
|
510
|
-
var ConfidenceInfoSchema =
|
|
595
|
+
var ConfidenceInfoSchema = z11.object({
|
|
511
596
|
source: ConfidenceSourceSchema,
|
|
512
597
|
level: ConfidenceLevelSchema,
|
|
513
598
|
corroboration: CorroborationSchema.optional()
|
|
514
599
|
});
|
|
515
|
-
var SourceLocationSchema =
|
|
516
|
-
file:
|
|
517
|
-
range:
|
|
518
|
-
exportName:
|
|
600
|
+
var SourceLocationSchema = z11.object({
|
|
601
|
+
file: z11.string(),
|
|
602
|
+
range: z11.object({ start: z11.number(), end: z11.number() }),
|
|
603
|
+
exportName: z11.string().nullable(),
|
|
519
604
|
/**
|
|
520
605
|
* The project the extract was pointed at, by the name that project
|
|
521
606
|
* calls itself.
|
|
@@ -525,47 +610,47 @@ var SourceLocationSchema = z10.object({
|
|
|
525
610
|
* summaries puts them on top of each other. This field is what tells
|
|
526
611
|
* them apart, and what a reader groups by.
|
|
527
612
|
*/
|
|
528
|
-
workspace:
|
|
613
|
+
workspace: z11.string().optional()
|
|
529
614
|
});
|
|
530
|
-
var BoundaryBindingSchema =
|
|
531
|
-
transport:
|
|
615
|
+
var BoundaryBindingSchema = z11.object({
|
|
616
|
+
transport: z11.string(),
|
|
532
617
|
semantics: SemanticsSchema,
|
|
533
|
-
recognition:
|
|
618
|
+
recognition: z11.string()
|
|
534
619
|
});
|
|
535
620
|
function typeDefinitionKey(ref) {
|
|
536
621
|
return ref.def ?? null;
|
|
537
622
|
}
|
|
538
|
-
var TypeShapeSchema =
|
|
539
|
-
() =>
|
|
540
|
-
|
|
541
|
-
type:
|
|
542
|
-
properties:
|
|
543
|
-
spreads:
|
|
623
|
+
var TypeShapeSchema = z11.lazy(
|
|
624
|
+
() => z11.discriminatedUnion("type", [
|
|
625
|
+
z11.object({
|
|
626
|
+
type: z11.literal("record"),
|
|
627
|
+
properties: z11.record(z11.string(), TypeShapeSchema),
|
|
628
|
+
spreads: z11.array(z11.object({ sourceText: z11.string() })).optional()
|
|
544
629
|
}),
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
type:
|
|
549
|
-
value:
|
|
550
|
-
raw:
|
|
630
|
+
z11.object({ type: z11.literal("dictionary"), values: TypeShapeSchema }),
|
|
631
|
+
z11.object({ type: z11.literal("array"), items: TypeShapeSchema }),
|
|
632
|
+
z11.object({
|
|
633
|
+
type: z11.literal("literal"),
|
|
634
|
+
value: z11.union([z11.string(), z11.number(), z11.boolean()]),
|
|
635
|
+
raw: z11.string().optional()
|
|
551
636
|
}),
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
type:
|
|
560
|
-
variants:
|
|
637
|
+
z11.object({ type: z11.literal("text") }),
|
|
638
|
+
z11.object({ type: z11.literal("integer") }),
|
|
639
|
+
z11.object({ type: z11.literal("number") }),
|
|
640
|
+
z11.object({ type: z11.literal("boolean") }),
|
|
641
|
+
z11.object({ type: z11.literal("null") }),
|
|
642
|
+
z11.object({ type: z11.literal("undefined") }),
|
|
643
|
+
z11.object({
|
|
644
|
+
type: z11.literal("union"),
|
|
645
|
+
variants: z11.array(TypeShapeSchema)
|
|
561
646
|
}),
|
|
562
|
-
|
|
563
|
-
type:
|
|
564
|
-
name:
|
|
565
|
-
from:
|
|
566
|
-
def:
|
|
647
|
+
z11.object({
|
|
648
|
+
type: z11.literal("ref"),
|
|
649
|
+
name: z11.string(),
|
|
650
|
+
from: z11.string().optional(),
|
|
651
|
+
def: z11.string().optional()
|
|
567
652
|
}),
|
|
568
|
-
|
|
653
|
+
z11.object({ type: z11.literal("unknown") })
|
|
569
654
|
])
|
|
570
655
|
);
|
|
571
656
|
var MAX_DEFINITION_DEPTH = 6;
|
|
@@ -614,6 +699,7 @@ export {
|
|
|
614
699
|
gqlIdentityKey,
|
|
615
700
|
fnIdentityKey,
|
|
616
701
|
busIdentityKey,
|
|
702
|
+
metricIdentityKey,
|
|
617
703
|
FunctionCallSemanticsSchema,
|
|
618
704
|
GraphqlResolverSemanticsSchema,
|
|
619
705
|
parseChannel,
|
|
@@ -621,6 +707,7 @@ export {
|
|
|
621
707
|
busesAgree,
|
|
622
708
|
channelsPair,
|
|
623
709
|
MessageBusSemanticsSchema,
|
|
710
|
+
MetricSemanticsSchema,
|
|
624
711
|
RestSemanticsSchema,
|
|
625
712
|
normalizePath,
|
|
626
713
|
methodsAgree,
|
|
@@ -631,6 +718,7 @@ export {
|
|
|
631
718
|
StorageSemanticsSchema,
|
|
632
719
|
SemanticsSchema,
|
|
633
720
|
behaviorOf,
|
|
721
|
+
semconvMappingOf,
|
|
634
722
|
allBehaviors,
|
|
635
723
|
ConfidenceSourceSchema,
|
|
636
724
|
ConfidenceLevelSchema,
|