@suss/ir-core 0.0.2 → 0.1.1

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 CHANGED
@@ -6,7 +6,7 @@ Primitives shared across suss's intermediate representations: the shapes every I
6
6
 
7
7
  The types that any suss IR is built from:
8
8
 
9
- - `TypeShape` — the structural shape of a value, for body / payload / field comparison.
9
+ - `TypeShape`: the structural shape of a value, for body / payload / field comparison.
10
10
  - `BoundaryBinding` + the `Semantics` variants (rest, function-call, graphql-resolver, graphql-operation, runtime-config, storage-relational, message-bus), plus the eight blessed binding constructors (`restBinding`, `functionCallBinding`, …).
11
11
  - `SourceLocation` and `Confidence` (`source` + `level`).
12
12
 
@@ -25,7 +25,7 @@ Schemas are the single source of truth (`@suss/ir-core/schemas`); the types are
25
25
 
26
26
  ## Where it sits in suss
27
27
 
28
- The base both `@suss/behavioral-ir` (what code does) and `@suss/intent-ir` (what the team meant) build on, so neither IR depends on the other — they describe boundaries in the same vocabulary and are compared, not merged. `@suss/behavioral-ir` re-exports these primitives, so existing consumers keep importing them from there unchanged.
28
+ The base both `@suss/behavioral-ir` (what code does) and `@suss/intent-ir` (what the team meant) build on, so neither IR depends on the other. They describe boundaries in the same vocabulary and are compared rather than merged. `@suss/behavioral-ir` re-exports these primitives, so existing consumers keep importing them from there unchanged.
29
29
 
30
30
  ## Status
31
31
 
@@ -7,9 +7,19 @@ var ConfidenceSourceSchema = z.enum([
7
7
  "derived"
8
8
  ]);
9
9
  var ConfidenceLevelSchema = z.enum(["high", "medium", "low"]);
10
+ var CorroborationSchema = z.object({
11
+ outcome: z.enum(["observed", "refuted", "untested"]),
12
+ /** Executions that produced a verdict for this claim. */
13
+ runs: z.number(),
14
+ /** Present when refuted: the input and observation that disagreed. */
15
+ counterexample: z.unknown().optional(),
16
+ /** Present when untested: why no verdict was reachable. */
17
+ reason: z.string().optional()
18
+ });
10
19
  var ConfidenceInfoSchema = z.object({
11
20
  source: ConfidenceSourceSchema,
12
- level: ConfidenceLevelSchema
21
+ level: ConfidenceLevelSchema,
22
+ corroboration: CorroborationSchema.optional()
13
23
  });
14
24
  var SourceLocationSchema = z.object({
15
25
  file: z.string(),
@@ -74,19 +84,19 @@ var GraphqlOperationSemanticsSchema = z.object({
74
84
  operationName: z.string().optional(),
75
85
  operationType: z.enum(["query", "mutation", "subscription"])
76
86
  });
77
- var RuntimeConfigSemanticsSchema = z.object({
78
- name: z.literal("runtime-config"),
87
+ var DeployableUnitSchema = z.object({
79
88
  deploymentTarget: z.enum([
80
89
  "lambda",
81
90
  "ecs-task",
82
91
  "container",
83
92
  "k8s-deployment"
84
93
  ]),
85
- /**
86
- * Stable identifier for the runtime instance — CFN logical resource
87
- * ID for Lambda / ECS, k8s deployment name, container name.
88
- */
89
- instanceName: z.string()
94
+ // An empty name would agree with every other empty name, so a unit
95
+ // that names nothing has to leave the field off instead.
96
+ instanceName: z.string().min(1)
97
+ });
98
+ var RuntimeConfigSemanticsSchema = DeployableUnitSchema.extend({
99
+ name: z.literal("runtime-config")
90
100
  });
91
101
  var StorageRelationalSemanticsSchema = z.object({
92
102
  name: z.literal("storage-relational"),
@@ -143,7 +153,11 @@ var TypeShapeSchema = z.lazy(
143
153
  type: z.literal("union"),
144
154
  variants: z.array(TypeShapeSchema)
145
155
  }),
146
- z.object({ type: z.literal("ref"), name: z.string() }),
156
+ z.object({
157
+ type: z.literal("ref"),
158
+ name: z.string(),
159
+ from: z.string().optional()
160
+ }),
147
161
  z.object({ type: z.literal("unknown") })
148
162
  ])
149
163
  );
@@ -151,12 +165,14 @@ var TypeShapeSchema = z.lazy(
151
165
  export {
152
166
  ConfidenceSourceSchema,
153
167
  ConfidenceLevelSchema,
168
+ CorroborationSchema,
154
169
  ConfidenceInfoSchema,
155
170
  SourceLocationSchema,
156
171
  RestSemanticsSchema,
157
172
  FunctionCallSemanticsSchema,
158
173
  GraphqlResolverSemanticsSchema,
159
174
  GraphqlOperationSemanticsSchema,
175
+ DeployableUnitSchema,
160
176
  RuntimeConfigSemanticsSchema,
161
177
  StorageRelationalSemanticsSchema,
162
178
  MessageBusSemanticsSchema,
package/dist/index.cjs CHANGED
@@ -24,6 +24,8 @@ __export(index_exports, {
24
24
  ConfidenceInfoSchema: () => ConfidenceInfoSchema,
25
25
  ConfidenceLevelSchema: () => ConfidenceLevelSchema,
26
26
  ConfidenceSourceSchema: () => ConfidenceSourceSchema,
27
+ CorroborationSchema: () => CorroborationSchema,
28
+ DeployableUnitSchema: () => DeployableUnitSchema,
27
29
  FunctionCallSemanticsSchema: () => FunctionCallSemanticsSchema,
28
30
  GraphqlOperationSemanticsSchema: () => GraphqlOperationSemanticsSchema,
29
31
  GraphqlResolverSemanticsSchema: () => GraphqlResolverSemanticsSchema,
@@ -39,7 +41,12 @@ __export(index_exports, {
39
41
  applySuppressionsToFindings: () => applySuppressionsToFindings,
40
42
  bodyShapesMatch: () => bodyShapesMatch,
41
43
  boundaryKey: () => boundaryKey,
44
+ busesAgree: () => busesAgree,
45
+ channelsPair: () => channelsPair,
46
+ codeScopePath: () => codeScopePath,
42
47
  countsForThreshold: () => countsForThreshold,
48
+ dispatchByType: () => dispatchByType,
49
+ fileInCodeScope: () => fileInCodeScope,
43
50
  functionCallBinding: () => functionCallBinding,
44
51
  graphqlOperationBinding: () => graphqlOperationBinding,
45
52
  graphqlResolverBinding: () => graphqlResolverBinding,
@@ -47,6 +54,7 @@ __export(index_exports, {
47
54
  normalizePath: () => normalizePath,
48
55
  normalizeRuleBoundary: () => normalizeRuleBoundary,
49
56
  packageExportBinding: () => packageExportBinding,
57
+ parseChannel: () => parseChannel,
50
58
  restBinding: () => restBinding,
51
59
  ruleBoundaryMatchesKey: () => ruleBoundaryMatchesKey,
52
60
  runtimeConfigBinding: () => runtimeConfigBinding,
@@ -64,9 +72,19 @@ var ConfidenceSourceSchema = import_zod.z.enum([
64
72
  "derived"
65
73
  ]);
66
74
  var ConfidenceLevelSchema = import_zod.z.enum(["high", "medium", "low"]);
75
+ var CorroborationSchema = import_zod.z.object({
76
+ outcome: import_zod.z.enum(["observed", "refuted", "untested"]),
77
+ /** Executions that produced a verdict for this claim. */
78
+ runs: import_zod.z.number(),
79
+ /** Present when refuted: the input and observation that disagreed. */
80
+ counterexample: import_zod.z.unknown().optional(),
81
+ /** Present when untested: why no verdict was reachable. */
82
+ reason: import_zod.z.string().optional()
83
+ });
67
84
  var ConfidenceInfoSchema = import_zod.z.object({
68
85
  source: ConfidenceSourceSchema,
69
- level: ConfidenceLevelSchema
86
+ level: ConfidenceLevelSchema,
87
+ corroboration: CorroborationSchema.optional()
70
88
  });
71
89
  var SourceLocationSchema = import_zod.z.object({
72
90
  file: import_zod.z.string(),
@@ -131,19 +149,19 @@ var GraphqlOperationSemanticsSchema = import_zod.z.object({
131
149
  operationName: import_zod.z.string().optional(),
132
150
  operationType: import_zod.z.enum(["query", "mutation", "subscription"])
133
151
  });
134
- var RuntimeConfigSemanticsSchema = import_zod.z.object({
135
- name: import_zod.z.literal("runtime-config"),
152
+ var DeployableUnitSchema = import_zod.z.object({
136
153
  deploymentTarget: import_zod.z.enum([
137
154
  "lambda",
138
155
  "ecs-task",
139
156
  "container",
140
157
  "k8s-deployment"
141
158
  ]),
142
- /**
143
- * Stable identifier for the runtime instance — CFN logical resource
144
- * ID for Lambda / ECS, k8s deployment name, container name.
145
- */
146
- instanceName: import_zod.z.string()
159
+ // An empty name would agree with every other empty name, so a unit
160
+ // that names nothing has to leave the field off instead.
161
+ instanceName: import_zod.z.string().min(1)
162
+ });
163
+ var RuntimeConfigSemanticsSchema = DeployableUnitSchema.extend({
164
+ name: import_zod.z.literal("runtime-config")
147
165
  });
148
166
  var StorageRelationalSemanticsSchema = import_zod.z.object({
149
167
  name: import_zod.z.literal("storage-relational"),
@@ -200,11 +218,32 @@ var TypeShapeSchema = import_zod.z.lazy(
200
218
  type: import_zod.z.literal("union"),
201
219
  variants: import_zod.z.array(TypeShapeSchema)
202
220
  }),
203
- import_zod.z.object({ type: import_zod.z.literal("ref"), name: import_zod.z.string() }),
221
+ import_zod.z.object({
222
+ type: import_zod.z.literal("ref"),
223
+ name: import_zod.z.string(),
224
+ from: import_zod.z.string().optional()
225
+ }),
204
226
  import_zod.z.object({ type: import_zod.z.literal("unknown") })
205
227
  ])
206
228
  );
207
229
 
230
+ // src/channel.ts
231
+ function parseChannel(channel) {
232
+ const hash = channel.indexOf("#");
233
+ if (hash === -1) {
234
+ return { bus: null, subject: channel };
235
+ }
236
+ return { bus: channel.slice(0, hash), subject: channel.slice(hash + 1) };
237
+ }
238
+ function busesAgree(a, b) {
239
+ return a === null || b === null || a === b;
240
+ }
241
+ function channelsPair(a, b) {
242
+ const left = parseChannel(a);
243
+ const right = parseChannel(b);
244
+ return left.subject === right.subject && busesAgree(left.bus, right.bus);
245
+ }
246
+
208
247
  // src/boundaryKey.ts
209
248
  function normalizePath(path) {
210
249
  let normalized = path.replace(/:([a-zA-Z_]\w*)/g, "{$1}");
@@ -228,8 +267,18 @@ function boundaryKey(binding) {
228
267
  return `${method} ${path}`;
229
268
  }
230
269
  if (semantics.name === "graphql-resolver") {
270
+ if (semantics.typeName === "" || semantics.fieldName === "") {
271
+ return null;
272
+ }
231
273
  return `gql:${semantics.typeName}.${semantics.fieldName}`;
232
274
  }
275
+ if (semantics.name === "message-bus") {
276
+ const { subject } = parseChannel(semantics.channel);
277
+ if (subject === "") {
278
+ return null;
279
+ }
280
+ return `bus:${semantics.messageBus} ${subject}`;
281
+ }
233
282
  if (semantics.name === "function-call") {
234
283
  if (semantics.package !== void 0 && semantics.exportPath !== void 0 && semantics.exportPath.length > 0) {
235
284
  return `fn:${semantics.package}::${semantics.exportPath.join(".")}`;
@@ -239,8 +288,31 @@ function boundaryKey(binding) {
239
288
  return null;
240
289
  }
241
290
 
291
+ // src/codeScope.ts
292
+ function codeScopePath(raw) {
293
+ return raw.trim().replace(/^\.\//, "").replace(/\/+$/, "");
294
+ }
295
+ function fileInCodeScope(file, scope) {
296
+ const prefix = codeScopePath(scope);
297
+ if (prefix === "" || prefix === ".") {
298
+ return true;
299
+ }
300
+ const path = codeScopePath(file);
301
+ return path === prefix || path.startsWith(`${prefix}/`);
302
+ }
303
+
304
+ // src/dispatch.ts
305
+ function dispatchByType(table, value) {
306
+ const handler = table[value.type];
307
+ return handler(value);
308
+ }
309
+
242
310
  // src/suppressions.ts
243
311
  var import_zod2 = require("zod");
312
+ var SuppressionSideSchema = import_zod2.z.object({
313
+ summary: import_zod2.z.string().optional(),
314
+ transitionId: import_zod2.z.string().optional()
315
+ }).optional();
244
316
  var SuppressionRuleSchema = import_zod2.z.object({
245
317
  /**
246
318
  * Finding kind to match — any behavioural or intent finding kind.
@@ -261,15 +333,21 @@ var SuppressionRuleSchema = import_zod2.z.object({
261
333
  * `consumer` never matches an intent finding, which has no
262
334
  * consumer side.
263
335
  */
264
- consumer: import_zod2.z.object({
265
- summary: import_zod2.z.string().optional(),
266
- transitionId: import_zod2.z.string().optional()
267
- }).optional(),
336
+ consumer: SuppressionSideSchema,
337
+ /**
338
+ * Provider-side discriminators, the mirror of `consumer`. A finding
339
+ * about a status the provider produces carries its transition id on
340
+ * this side, and that id is the only handle narrow enough to name
341
+ * that one finding. Like `consumer`, a rule that specifies
342
+ * `provider` never matches an intent finding.
343
+ */
344
+ provider: SuppressionSideSchema,
268
345
  /**
269
- * "narrow" (default): requires at least (kind + boundary) OR
270
- * (kind + consumer.transitionId) — enough to target a specific
271
- * finding class. "broad" opts in to kind-only or boundary-only
272
- * matches, which silence future regressions in that category too.
346
+ * "narrow" (default): requires kind plus one of boundary,
347
+ * consumer.transitionId, or provider.transitionId — enough to
348
+ * target a specific finding class. "broad" opts in to kind-only or
349
+ * boundary-only matches, which silence future regressions in that
350
+ * category too.
273
351
  */
274
352
  scope: import_zod2.z.enum(["narrow", "broad"]).default("narrow"),
275
353
  /** Required human-written justification. */
@@ -283,18 +361,18 @@ var SuppressionFileSchema = import_zod2.z.object({
283
361
  }).strict();
284
362
  function validateRule(rule) {
285
363
  if (rule.scope === "broad") {
286
- if (rule.kind === void 0 && rule.boundary === void 0 && rule.consumer === void 0) {
287
- return "broad-scope rule must constrain at least one field (kind, boundary, or consumer)";
364
+ if (rule.kind === void 0 && rule.boundary === void 0 && rule.consumer === void 0 && rule.provider === void 0) {
365
+ return "broad-scope rule must constrain at least one field (kind, boundary, consumer, or provider)";
288
366
  }
289
367
  return null;
290
368
  }
291
369
  const hasKind = rule.kind !== void 0;
292
370
  const hasBoundary = rule.boundary !== void 0;
293
- const hasConsumerTxn = rule.consumer?.transitionId !== void 0;
294
- if (hasKind && (hasBoundary || hasConsumerTxn)) {
371
+ const hasTransition = rule.consumer?.transitionId !== void 0 || rule.provider?.transitionId !== void 0;
372
+ if (hasKind && (hasBoundary || hasTransition)) {
295
373
  return null;
296
374
  }
297
- return "narrow-scope rule must specify kind AND (boundary OR consumer.transitionId); set scope: 'broad' to silence wider categories";
375
+ return "narrow-scope rule must specify kind AND (boundary OR consumer.transitionId OR provider.transitionId); set scope: 'broad' to silence wider categories";
298
376
  }
299
377
  function normalizeRuleBoundary(raw) {
300
378
  const trimmed = raw.trim();
@@ -361,10 +439,11 @@ function bodyShapesMatch(actual, declared) {
361
439
  if (actual.type === "unknown" || declared.type === "unknown") {
362
440
  return "unknown";
363
441
  }
442
+ if (actual.type === "ref" && declared.type === "ref") {
443
+ const sameDeclaration = actual.from !== void 0 && actual.from === declared.from && actual.name === declared.name;
444
+ return sameDeclaration ? "match" : "unknown";
445
+ }
364
446
  if (actual.type === "ref" || declared.type === "ref") {
365
- if (actual.type === "ref" && declared.type === "ref" && actual.name === declared.name) {
366
- return "match";
367
- }
368
447
  return "unknown";
369
448
  }
370
449
  if (actual.type === "union") {
@@ -595,6 +674,8 @@ function messageBusBinding(opts) {
595
674
  ConfidenceInfoSchema,
596
675
  ConfidenceLevelSchema,
597
676
  ConfidenceSourceSchema,
677
+ CorroborationSchema,
678
+ DeployableUnitSchema,
598
679
  FunctionCallSemanticsSchema,
599
680
  GraphqlOperationSemanticsSchema,
600
681
  GraphqlResolverSemanticsSchema,
@@ -610,7 +691,12 @@ function messageBusBinding(opts) {
610
691
  applySuppressionsToFindings,
611
692
  bodyShapesMatch,
612
693
  boundaryKey,
694
+ busesAgree,
695
+ channelsPair,
696
+ codeScopePath,
613
697
  countsForThreshold,
698
+ dispatchByType,
699
+ fileInCodeScope,
614
700
  functionCallBinding,
615
701
  graphqlOperationBinding,
616
702
  graphqlResolverBinding,
@@ -618,6 +704,7 @@ function messageBusBinding(opts) {
618
704
  normalizePath,
619
705
  normalizeRuleBoundary,
620
706
  packageExportBinding,
707
+ parseChannel,
621
708
  restBinding,
622
709
  ruleBoundaryMatchesKey,
623
710
  runtimeConfigBinding,
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { TypeShape, BoundaryBindingSchema, ConfidenceInfoSchema, ConfidenceLevelSchema, ConfidenceSourceSchema, SemanticsSchema, SourceLocationSchema } from './schemas.cjs';
2
+ import { TypeShape, BoundaryBindingSchema, ConfidenceInfoSchema, ConfidenceLevelSchema, ConfidenceSourceSchema, CorroborationSchema, DeployableUnitSchema, SemanticsSchema, SourceLocationSchema } from './schemas.cjs';
3
3
  export { FunctionCallSemanticsSchema, GraphqlOperationSemanticsSchema, GraphqlResolverSemanticsSchema, MessageBusSemanticsSchema, RestSemanticsSchema, RuntimeConfigSemanticsSchema, StorageRelationalSemanticsSchema, TypeShapeSchema } from './schemas.cjs';
4
4
 
5
5
  /**
@@ -14,7 +14,11 @@ declare function normalizePath(path: string): string;
14
14
  * Compute a stable string key from a boundary binding for grouping.
15
15
  * Dispatches on `semantics.name`:
16
16
  * - `rest` → `"METHOD /normalized/path"` (null if method or path empty)
17
- * - `graphql-resolver` → `"gql:<TypeName>.<fieldName>"`
17
+ * - `graphql-resolver` → `"gql:<TypeName>.<fieldName>"` (null when
18
+ * either is empty, which is how a resolver says the source never
19
+ * named the field it answers)
20
+ * - `message-bus` → `"bus:<messageBus> <subject>"` (null if the
21
+ * subject is empty)
18
22
  * - `function-call` → `"fn:<package>::<exportPath>"` when both
19
23
  * `package` and `exportPath` are set; other in-process function-call
20
24
  * units (intra-repo components, bare handlers) return null.
@@ -22,6 +26,55 @@ declare function normalizePath(path: string): string;
22
26
  */
23
27
  declare function boundaryKey(binding: BoundaryBinding): string | null;
24
28
 
29
+ /**
30
+ * A channel split into the bus that carries it and the subject on that
31
+ * bus. `default#order.placed` is the subject `order.placed` on the bus
32
+ * `default`. `OrdersQueue` is a subject with no bus, which is what a
33
+ * queue's logical id and an env-var-named channel look like.
34
+ */
35
+ interface ParsedChannel {
36
+ bus: string | null;
37
+ subject: string;
38
+ }
39
+ /**
40
+ * Split a channel on its first `#`. Later `#`s stay in the subject, so
41
+ * a subject that contains one is compared whole rather than being cut
42
+ * into pieces that pair with the wrong things.
43
+ */
44
+ declare function parseChannel(channel: string): ParsedChannel;
45
+ /** Two buses agree when they are the same, or when either is unknown. */
46
+ declare function busesAgree(a: string | null, b: string | null): boolean;
47
+ /** Whether two channels name the same subject on agreeing buses. */
48
+ declare function channelsPair(a: string, b: string): boolean;
49
+
50
+ /**
51
+ * The canonical form of a code-scope directory: no leading `./`, no
52
+ * trailing slash, no surrounding whitespace. An empty result means the
53
+ * scope names the project root.
54
+ */
55
+ declare function codeScopePath(raw: string): string;
56
+ /**
57
+ * Whether a project-relative file sits inside a code scope. Matching
58
+ * stops at a segment boundary, so `src/foo` covers `src/foo/a.ts` and
59
+ * never `src/foobar/a.ts`. A scope naming the project root covers
60
+ * every file.
61
+ *
62
+ * Both arguments pass through `codeScopePath`, so a scope stored under
63
+ * either of the older trailing-slash conventions still reads correctly.
64
+ */
65
+ declare function fileInCodeScope(file: string, scope: string): boolean;
66
+
67
+ type DispatchTable<T extends {
68
+ type: string;
69
+ }, R> = {
70
+ [K in T["type"]]: (variant: Extract<T, {
71
+ type: K;
72
+ }>) => R;
73
+ };
74
+ declare function dispatchByType<T extends {
75
+ type: string;
76
+ }, R>(table: DispatchTable<T, R>, value: T): R;
77
+
25
78
  declare const SuppressionRuleSchema: z.ZodObject<{
26
79
  kind: z.ZodOptional<z.ZodString>;
27
80
  boundary: z.ZodOptional<z.ZodString>;
@@ -29,6 +82,10 @@ declare const SuppressionRuleSchema: z.ZodObject<{
29
82
  summary: z.ZodOptional<z.ZodString>;
30
83
  transitionId: z.ZodOptional<z.ZodString>;
31
84
  }, z.core.$strip>>;
85
+ provider: z.ZodOptional<z.ZodObject<{
86
+ summary: z.ZodOptional<z.ZodString>;
87
+ transitionId: z.ZodOptional<z.ZodString>;
88
+ }, z.core.$strip>>;
32
89
  scope: z.ZodDefault<z.ZodEnum<{
33
90
  narrow: "narrow";
34
91
  broad: "broad";
@@ -50,6 +107,10 @@ declare const SuppressionFileSchema: z.ZodObject<{
50
107
  summary: z.ZodOptional<z.ZodString>;
51
108
  transitionId: z.ZodOptional<z.ZodString>;
52
109
  }, z.core.$strip>>;
110
+ provider: z.ZodOptional<z.ZodObject<{
111
+ summary: z.ZodOptional<z.ZodString>;
112
+ transitionId: z.ZodOptional<z.ZodString>;
113
+ }, z.core.$strip>>;
53
114
  scope: z.ZodDefault<z.ZodEnum<{
54
115
  narrow: "narrow";
55
116
  broad: "broad";
@@ -148,6 +209,7 @@ declare function bodyShapesMatch(actual: TypeShape, declared: TypeShape): MatchR
148
209
  type ConfidenceSource = z.infer<typeof ConfidenceSourceSchema>;
149
210
  type ConfidenceLevel = z.infer<typeof ConfidenceLevelSchema>;
150
211
  type ConfidenceInfo = z.infer<typeof ConfidenceInfoSchema>;
212
+ type Corroboration = z.infer<typeof CorroborationSchema>;
151
213
  type SourceLocation = z.infer<typeof SourceLocationSchema>;
152
214
  type BoundaryBinding = z.infer<typeof BoundaryBindingSchema>;
153
215
  type Semantics = z.infer<typeof SemanticsSchema>;
@@ -172,6 +234,7 @@ type StorageRelationalSemantics = Extract<Semantics, {
172
234
  type MessageBusSemantics = Extract<Semantics, {
173
235
  name: "message-bus";
174
236
  }>;
237
+ type DeployableUnit = z.infer<typeof DeployableUnitSchema>;
175
238
 
176
239
  /**
177
240
  * Build a REST-semantics binding. `method` and `path` can be empty
@@ -261,4 +324,4 @@ declare function messageBusBinding(opts: {
261
324
  channel: string;
262
325
  }): BoundaryBinding;
263
326
 
264
- export { type BoundaryBinding, BoundaryBindingSchema, type ConfidenceInfo, ConfidenceInfoSchema, type ConfidenceLevel, ConfidenceLevelSchema, type ConfidenceSource, ConfidenceSourceSchema, type FindingSuppression, type FunctionCallSemantics, type GraphqlOperationSemantics, type GraphqlResolverSemantics, type MatchResult, type MessageBusSemantics, type RestSemantics, type RuntimeConfigSemantics, type Semantics, SemanticsSchema, type SourceLocation, SourceLocationSchema, type StorageRelationalSemantics, type SuppressableSeverity, type SuppressibleFinding, type SuppressionFile, SuppressionFileSchema, type SuppressionRule, SuppressionRuleSchema, TypeShape, applySuppressionsToFindings, bodyShapesMatch, boundaryKey, countsForThreshold, functionCallBinding, graphqlOperationBinding, graphqlResolverBinding, messageBusBinding, normalizePath, normalizeRuleBoundary, packageExportBinding, restBinding, ruleBoundaryMatchesKey, runtimeConfigBinding, storageRelationalBinding, validateRule };
327
+ export { type BoundaryBinding, BoundaryBindingSchema, type ConfidenceInfo, ConfidenceInfoSchema, type ConfidenceLevel, ConfidenceLevelSchema, type ConfidenceSource, ConfidenceSourceSchema, type Corroboration, CorroborationSchema, type DeployableUnit, DeployableUnitSchema, type DispatchTable, type FindingSuppression, type FunctionCallSemantics, type GraphqlOperationSemantics, type GraphqlResolverSemantics, type MatchResult, type MessageBusSemantics, type ParsedChannel, type RestSemantics, type RuntimeConfigSemantics, type Semantics, SemanticsSchema, type SourceLocation, SourceLocationSchema, type StorageRelationalSemantics, type SuppressableSeverity, type SuppressibleFinding, type SuppressionFile, SuppressionFileSchema, type SuppressionRule, SuppressionRuleSchema, TypeShape, applySuppressionsToFindings, bodyShapesMatch, boundaryKey, busesAgree, channelsPair, codeScopePath, countsForThreshold, dispatchByType, fileInCodeScope, functionCallBinding, graphqlOperationBinding, graphqlResolverBinding, messageBusBinding, normalizePath, normalizeRuleBoundary, packageExportBinding, parseChannel, restBinding, ruleBoundaryMatchesKey, runtimeConfigBinding, storageRelationalBinding, validateRule };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { TypeShape, BoundaryBindingSchema, ConfidenceInfoSchema, ConfidenceLevelSchema, ConfidenceSourceSchema, SemanticsSchema, SourceLocationSchema } from './schemas.js';
2
+ import { TypeShape, BoundaryBindingSchema, ConfidenceInfoSchema, ConfidenceLevelSchema, ConfidenceSourceSchema, CorroborationSchema, DeployableUnitSchema, SemanticsSchema, SourceLocationSchema } from './schemas.js';
3
3
  export { FunctionCallSemanticsSchema, GraphqlOperationSemanticsSchema, GraphqlResolverSemanticsSchema, MessageBusSemanticsSchema, RestSemanticsSchema, RuntimeConfigSemanticsSchema, StorageRelationalSemanticsSchema, TypeShapeSchema } from './schemas.js';
4
4
 
5
5
  /**
@@ -14,7 +14,11 @@ declare function normalizePath(path: string): string;
14
14
  * Compute a stable string key from a boundary binding for grouping.
15
15
  * Dispatches on `semantics.name`:
16
16
  * - `rest` → `"METHOD /normalized/path"` (null if method or path empty)
17
- * - `graphql-resolver` → `"gql:<TypeName>.<fieldName>"`
17
+ * - `graphql-resolver` → `"gql:<TypeName>.<fieldName>"` (null when
18
+ * either is empty, which is how a resolver says the source never
19
+ * named the field it answers)
20
+ * - `message-bus` → `"bus:<messageBus> <subject>"` (null if the
21
+ * subject is empty)
18
22
  * - `function-call` → `"fn:<package>::<exportPath>"` when both
19
23
  * `package` and `exportPath` are set; other in-process function-call
20
24
  * units (intra-repo components, bare handlers) return null.
@@ -22,6 +26,55 @@ declare function normalizePath(path: string): string;
22
26
  */
23
27
  declare function boundaryKey(binding: BoundaryBinding): string | null;
24
28
 
29
+ /**
30
+ * A channel split into the bus that carries it and the subject on that
31
+ * bus. `default#order.placed` is the subject `order.placed` on the bus
32
+ * `default`. `OrdersQueue` is a subject with no bus, which is what a
33
+ * queue's logical id and an env-var-named channel look like.
34
+ */
35
+ interface ParsedChannel {
36
+ bus: string | null;
37
+ subject: string;
38
+ }
39
+ /**
40
+ * Split a channel on its first `#`. Later `#`s stay in the subject, so
41
+ * a subject that contains one is compared whole rather than being cut
42
+ * into pieces that pair with the wrong things.
43
+ */
44
+ declare function parseChannel(channel: string): ParsedChannel;
45
+ /** Two buses agree when they are the same, or when either is unknown. */
46
+ declare function busesAgree(a: string | null, b: string | null): boolean;
47
+ /** Whether two channels name the same subject on agreeing buses. */
48
+ declare function channelsPair(a: string, b: string): boolean;
49
+
50
+ /**
51
+ * The canonical form of a code-scope directory: no leading `./`, no
52
+ * trailing slash, no surrounding whitespace. An empty result means the
53
+ * scope names the project root.
54
+ */
55
+ declare function codeScopePath(raw: string): string;
56
+ /**
57
+ * Whether a project-relative file sits inside a code scope. Matching
58
+ * stops at a segment boundary, so `src/foo` covers `src/foo/a.ts` and
59
+ * never `src/foobar/a.ts`. A scope naming the project root covers
60
+ * every file.
61
+ *
62
+ * Both arguments pass through `codeScopePath`, so a scope stored under
63
+ * either of the older trailing-slash conventions still reads correctly.
64
+ */
65
+ declare function fileInCodeScope(file: string, scope: string): boolean;
66
+
67
+ type DispatchTable<T extends {
68
+ type: string;
69
+ }, R> = {
70
+ [K in T["type"]]: (variant: Extract<T, {
71
+ type: K;
72
+ }>) => R;
73
+ };
74
+ declare function dispatchByType<T extends {
75
+ type: string;
76
+ }, R>(table: DispatchTable<T, R>, value: T): R;
77
+
25
78
  declare const SuppressionRuleSchema: z.ZodObject<{
26
79
  kind: z.ZodOptional<z.ZodString>;
27
80
  boundary: z.ZodOptional<z.ZodString>;
@@ -29,6 +82,10 @@ declare const SuppressionRuleSchema: z.ZodObject<{
29
82
  summary: z.ZodOptional<z.ZodString>;
30
83
  transitionId: z.ZodOptional<z.ZodString>;
31
84
  }, z.core.$strip>>;
85
+ provider: z.ZodOptional<z.ZodObject<{
86
+ summary: z.ZodOptional<z.ZodString>;
87
+ transitionId: z.ZodOptional<z.ZodString>;
88
+ }, z.core.$strip>>;
32
89
  scope: z.ZodDefault<z.ZodEnum<{
33
90
  narrow: "narrow";
34
91
  broad: "broad";
@@ -50,6 +107,10 @@ declare const SuppressionFileSchema: z.ZodObject<{
50
107
  summary: z.ZodOptional<z.ZodString>;
51
108
  transitionId: z.ZodOptional<z.ZodString>;
52
109
  }, z.core.$strip>>;
110
+ provider: z.ZodOptional<z.ZodObject<{
111
+ summary: z.ZodOptional<z.ZodString>;
112
+ transitionId: z.ZodOptional<z.ZodString>;
113
+ }, z.core.$strip>>;
53
114
  scope: z.ZodDefault<z.ZodEnum<{
54
115
  narrow: "narrow";
55
116
  broad: "broad";
@@ -148,6 +209,7 @@ declare function bodyShapesMatch(actual: TypeShape, declared: TypeShape): MatchR
148
209
  type ConfidenceSource = z.infer<typeof ConfidenceSourceSchema>;
149
210
  type ConfidenceLevel = z.infer<typeof ConfidenceLevelSchema>;
150
211
  type ConfidenceInfo = z.infer<typeof ConfidenceInfoSchema>;
212
+ type Corroboration = z.infer<typeof CorroborationSchema>;
151
213
  type SourceLocation = z.infer<typeof SourceLocationSchema>;
152
214
  type BoundaryBinding = z.infer<typeof BoundaryBindingSchema>;
153
215
  type Semantics = z.infer<typeof SemanticsSchema>;
@@ -172,6 +234,7 @@ type StorageRelationalSemantics = Extract<Semantics, {
172
234
  type MessageBusSemantics = Extract<Semantics, {
173
235
  name: "message-bus";
174
236
  }>;
237
+ type DeployableUnit = z.infer<typeof DeployableUnitSchema>;
175
238
 
176
239
  /**
177
240
  * Build a REST-semantics binding. `method` and `path` can be empty
@@ -261,4 +324,4 @@ declare function messageBusBinding(opts: {
261
324
  channel: string;
262
325
  }): BoundaryBinding;
263
326
 
264
- export { type BoundaryBinding, BoundaryBindingSchema, type ConfidenceInfo, ConfidenceInfoSchema, type ConfidenceLevel, ConfidenceLevelSchema, type ConfidenceSource, ConfidenceSourceSchema, type FindingSuppression, type FunctionCallSemantics, type GraphqlOperationSemantics, type GraphqlResolverSemantics, type MatchResult, type MessageBusSemantics, type RestSemantics, type RuntimeConfigSemantics, type Semantics, SemanticsSchema, type SourceLocation, SourceLocationSchema, type StorageRelationalSemantics, type SuppressableSeverity, type SuppressibleFinding, type SuppressionFile, SuppressionFileSchema, type SuppressionRule, SuppressionRuleSchema, TypeShape, applySuppressionsToFindings, bodyShapesMatch, boundaryKey, countsForThreshold, functionCallBinding, graphqlOperationBinding, graphqlResolverBinding, messageBusBinding, normalizePath, normalizeRuleBoundary, packageExportBinding, restBinding, ruleBoundaryMatchesKey, runtimeConfigBinding, storageRelationalBinding, validateRule };
327
+ export { type BoundaryBinding, BoundaryBindingSchema, type ConfidenceInfo, ConfidenceInfoSchema, type ConfidenceLevel, ConfidenceLevelSchema, type ConfidenceSource, ConfidenceSourceSchema, type Corroboration, CorroborationSchema, type DeployableUnit, DeployableUnitSchema, type DispatchTable, type FindingSuppression, type FunctionCallSemantics, type GraphqlOperationSemantics, type GraphqlResolverSemantics, type MatchResult, type MessageBusSemantics, type ParsedChannel, type RestSemantics, type RuntimeConfigSemantics, type Semantics, SemanticsSchema, type SourceLocation, SourceLocationSchema, type StorageRelationalSemantics, type SuppressableSeverity, type SuppressibleFinding, type SuppressionFile, SuppressionFileSchema, type SuppressionRule, SuppressionRuleSchema, TypeShape, applySuppressionsToFindings, bodyShapesMatch, boundaryKey, busesAgree, channelsPair, codeScopePath, countsForThreshold, dispatchByType, fileInCodeScope, functionCallBinding, graphqlOperationBinding, graphqlResolverBinding, messageBusBinding, normalizePath, normalizeRuleBoundary, packageExportBinding, parseChannel, restBinding, ruleBoundaryMatchesKey, runtimeConfigBinding, storageRelationalBinding, validateRule };
package/dist/index.js CHANGED
@@ -3,6 +3,8 @@ import {
3
3
  ConfidenceInfoSchema,
4
4
  ConfidenceLevelSchema,
5
5
  ConfidenceSourceSchema,
6
+ CorroborationSchema,
7
+ DeployableUnitSchema,
6
8
  FunctionCallSemanticsSchema,
7
9
  GraphqlOperationSemanticsSchema,
8
10
  GraphqlResolverSemanticsSchema,
@@ -13,7 +15,24 @@ import {
13
15
  SourceLocationSchema,
14
16
  StorageRelationalSemanticsSchema,
15
17
  TypeShapeSchema
16
- } from "./chunk-BWK3IPL7.js";
18
+ } from "./chunk-QQLJDL3C.js";
19
+
20
+ // src/channel.ts
21
+ function parseChannel(channel) {
22
+ const hash = channel.indexOf("#");
23
+ if (hash === -1) {
24
+ return { bus: null, subject: channel };
25
+ }
26
+ return { bus: channel.slice(0, hash), subject: channel.slice(hash + 1) };
27
+ }
28
+ function busesAgree(a, b) {
29
+ return a === null || b === null || a === b;
30
+ }
31
+ function channelsPair(a, b) {
32
+ const left = parseChannel(a);
33
+ const right = parseChannel(b);
34
+ return left.subject === right.subject && busesAgree(left.bus, right.bus);
35
+ }
17
36
 
18
37
  // src/boundaryKey.ts
19
38
  function normalizePath(path) {
@@ -38,8 +57,18 @@ function boundaryKey(binding) {
38
57
  return `${method} ${path}`;
39
58
  }
40
59
  if (semantics.name === "graphql-resolver") {
60
+ if (semantics.typeName === "" || semantics.fieldName === "") {
61
+ return null;
62
+ }
41
63
  return `gql:${semantics.typeName}.${semantics.fieldName}`;
42
64
  }
65
+ if (semantics.name === "message-bus") {
66
+ const { subject } = parseChannel(semantics.channel);
67
+ if (subject === "") {
68
+ return null;
69
+ }
70
+ return `bus:${semantics.messageBus} ${subject}`;
71
+ }
43
72
  if (semantics.name === "function-call") {
44
73
  if (semantics.package !== void 0 && semantics.exportPath !== void 0 && semantics.exportPath.length > 0) {
45
74
  return `fn:${semantics.package}::${semantics.exportPath.join(".")}`;
@@ -49,8 +78,31 @@ function boundaryKey(binding) {
49
78
  return null;
50
79
  }
51
80
 
81
+ // src/codeScope.ts
82
+ function codeScopePath(raw) {
83
+ return raw.trim().replace(/^\.\//, "").replace(/\/+$/, "");
84
+ }
85
+ function fileInCodeScope(file, scope) {
86
+ const prefix = codeScopePath(scope);
87
+ if (prefix === "" || prefix === ".") {
88
+ return true;
89
+ }
90
+ const path = codeScopePath(file);
91
+ return path === prefix || path.startsWith(`${prefix}/`);
92
+ }
93
+
94
+ // src/dispatch.ts
95
+ function dispatchByType(table, value) {
96
+ const handler = table[value.type];
97
+ return handler(value);
98
+ }
99
+
52
100
  // src/suppressions.ts
53
101
  import { z } from "zod";
102
+ var SuppressionSideSchema = z.object({
103
+ summary: z.string().optional(),
104
+ transitionId: z.string().optional()
105
+ }).optional();
54
106
  var SuppressionRuleSchema = z.object({
55
107
  /**
56
108
  * Finding kind to match — any behavioural or intent finding kind.
@@ -71,15 +123,21 @@ var SuppressionRuleSchema = z.object({
71
123
  * `consumer` never matches an intent finding, which has no
72
124
  * consumer side.
73
125
  */
74
- consumer: z.object({
75
- summary: z.string().optional(),
76
- transitionId: z.string().optional()
77
- }).optional(),
126
+ consumer: SuppressionSideSchema,
78
127
  /**
79
- * "narrow" (default): requires at least (kind + boundary) OR
80
- * (kind + consumer.transitionId) — enough to target a specific
81
- * finding class. "broad" opts in to kind-only or boundary-only
82
- * matches, which silence future regressions in that category too.
128
+ * Provider-side discriminators, the mirror of `consumer`. A finding
129
+ * about a status the provider produces carries its transition id on
130
+ * this side, and that id is the only handle narrow enough to name
131
+ * that one finding. Like `consumer`, a rule that specifies
132
+ * `provider` never matches an intent finding.
133
+ */
134
+ provider: SuppressionSideSchema,
135
+ /**
136
+ * "narrow" (default): requires kind plus one of boundary,
137
+ * consumer.transitionId, or provider.transitionId — enough to
138
+ * target a specific finding class. "broad" opts in to kind-only or
139
+ * boundary-only matches, which silence future regressions in that
140
+ * category too.
83
141
  */
84
142
  scope: z.enum(["narrow", "broad"]).default("narrow"),
85
143
  /** Required human-written justification. */
@@ -93,18 +151,18 @@ var SuppressionFileSchema = z.object({
93
151
  }).strict();
94
152
  function validateRule(rule) {
95
153
  if (rule.scope === "broad") {
96
- if (rule.kind === void 0 && rule.boundary === void 0 && rule.consumer === void 0) {
97
- return "broad-scope rule must constrain at least one field (kind, boundary, or consumer)";
154
+ if (rule.kind === void 0 && rule.boundary === void 0 && rule.consumer === void 0 && rule.provider === void 0) {
155
+ return "broad-scope rule must constrain at least one field (kind, boundary, consumer, or provider)";
98
156
  }
99
157
  return null;
100
158
  }
101
159
  const hasKind = rule.kind !== void 0;
102
160
  const hasBoundary = rule.boundary !== void 0;
103
- const hasConsumerTxn = rule.consumer?.transitionId !== void 0;
104
- if (hasKind && (hasBoundary || hasConsumerTxn)) {
161
+ const hasTransition = rule.consumer?.transitionId !== void 0 || rule.provider?.transitionId !== void 0;
162
+ if (hasKind && (hasBoundary || hasTransition)) {
105
163
  return null;
106
164
  }
107
- return "narrow-scope rule must specify kind AND (boundary OR consumer.transitionId); set scope: 'broad' to silence wider categories";
165
+ return "narrow-scope rule must specify kind AND (boundary OR consumer.transitionId OR provider.transitionId); set scope: 'broad' to silence wider categories";
108
166
  }
109
167
  function normalizeRuleBoundary(raw) {
110
168
  const trimmed = raw.trim();
@@ -171,10 +229,11 @@ function bodyShapesMatch(actual, declared) {
171
229
  if (actual.type === "unknown" || declared.type === "unknown") {
172
230
  return "unknown";
173
231
  }
232
+ if (actual.type === "ref" && declared.type === "ref") {
233
+ const sameDeclaration = actual.from !== void 0 && actual.from === declared.from && actual.name === declared.name;
234
+ return sameDeclaration ? "match" : "unknown";
235
+ }
174
236
  if (actual.type === "ref" || declared.type === "ref") {
175
- if (actual.type === "ref" && declared.type === "ref" && actual.name === declared.name) {
176
- return "match";
177
- }
178
237
  return "unknown";
179
238
  }
180
239
  if (actual.type === "union") {
@@ -404,6 +463,8 @@ export {
404
463
  ConfidenceInfoSchema,
405
464
  ConfidenceLevelSchema,
406
465
  ConfidenceSourceSchema,
466
+ CorroborationSchema,
467
+ DeployableUnitSchema,
407
468
  FunctionCallSemanticsSchema,
408
469
  GraphqlOperationSemanticsSchema,
409
470
  GraphqlResolverSemanticsSchema,
@@ -419,7 +480,12 @@ export {
419
480
  applySuppressionsToFindings,
420
481
  bodyShapesMatch,
421
482
  boundaryKey,
483
+ busesAgree,
484
+ channelsPair,
485
+ codeScopePath,
422
486
  countsForThreshold,
487
+ dispatchByType,
488
+ fileInCodeScope,
423
489
  functionCallBinding,
424
490
  graphqlOperationBinding,
425
491
  graphqlResolverBinding,
@@ -427,6 +493,7 @@ export {
427
493
  normalizePath,
428
494
  normalizeRuleBoundary,
429
495
  packageExportBinding,
496
+ parseChannel,
430
497
  restBinding,
431
498
  ruleBoundaryMatchesKey,
432
499
  runtimeConfigBinding,
package/dist/schemas.cjs CHANGED
@@ -24,6 +24,8 @@ __export(schemas_exports, {
24
24
  ConfidenceInfoSchema: () => ConfidenceInfoSchema,
25
25
  ConfidenceLevelSchema: () => ConfidenceLevelSchema,
26
26
  ConfidenceSourceSchema: () => ConfidenceSourceSchema,
27
+ CorroborationSchema: () => CorroborationSchema,
28
+ DeployableUnitSchema: () => DeployableUnitSchema,
27
29
  FunctionCallSemanticsSchema: () => FunctionCallSemanticsSchema,
28
30
  GraphqlOperationSemanticsSchema: () => GraphqlOperationSemanticsSchema,
29
31
  GraphqlResolverSemanticsSchema: () => GraphqlResolverSemanticsSchema,
@@ -44,9 +46,19 @@ var ConfidenceSourceSchema = import_zod.z.enum([
44
46
  "derived"
45
47
  ]);
46
48
  var ConfidenceLevelSchema = import_zod.z.enum(["high", "medium", "low"]);
49
+ var CorroborationSchema = import_zod.z.object({
50
+ outcome: import_zod.z.enum(["observed", "refuted", "untested"]),
51
+ /** Executions that produced a verdict for this claim. */
52
+ runs: import_zod.z.number(),
53
+ /** Present when refuted: the input and observation that disagreed. */
54
+ counterexample: import_zod.z.unknown().optional(),
55
+ /** Present when untested: why no verdict was reachable. */
56
+ reason: import_zod.z.string().optional()
57
+ });
47
58
  var ConfidenceInfoSchema = import_zod.z.object({
48
59
  source: ConfidenceSourceSchema,
49
- level: ConfidenceLevelSchema
60
+ level: ConfidenceLevelSchema,
61
+ corroboration: CorroborationSchema.optional()
50
62
  });
51
63
  var SourceLocationSchema = import_zod.z.object({
52
64
  file: import_zod.z.string(),
@@ -111,19 +123,19 @@ var GraphqlOperationSemanticsSchema = import_zod.z.object({
111
123
  operationName: import_zod.z.string().optional(),
112
124
  operationType: import_zod.z.enum(["query", "mutation", "subscription"])
113
125
  });
114
- var RuntimeConfigSemanticsSchema = import_zod.z.object({
115
- name: import_zod.z.literal("runtime-config"),
126
+ var DeployableUnitSchema = import_zod.z.object({
116
127
  deploymentTarget: import_zod.z.enum([
117
128
  "lambda",
118
129
  "ecs-task",
119
130
  "container",
120
131
  "k8s-deployment"
121
132
  ]),
122
- /**
123
- * Stable identifier for the runtime instance — CFN logical resource
124
- * ID for Lambda / ECS, k8s deployment name, container name.
125
- */
126
- instanceName: import_zod.z.string()
133
+ // An empty name would agree with every other empty name, so a unit
134
+ // that names nothing has to leave the field off instead.
135
+ instanceName: import_zod.z.string().min(1)
136
+ });
137
+ var RuntimeConfigSemanticsSchema = DeployableUnitSchema.extend({
138
+ name: import_zod.z.literal("runtime-config")
127
139
  });
128
140
  var StorageRelationalSemanticsSchema = import_zod.z.object({
129
141
  name: import_zod.z.literal("storage-relational"),
@@ -180,7 +192,11 @@ var TypeShapeSchema = import_zod.z.lazy(
180
192
  type: import_zod.z.literal("union"),
181
193
  variants: import_zod.z.array(TypeShapeSchema)
182
194
  }),
183
- import_zod.z.object({ type: import_zod.z.literal("ref"), name: import_zod.z.string() }),
195
+ import_zod.z.object({
196
+ type: import_zod.z.literal("ref"),
197
+ name: import_zod.z.string(),
198
+ from: import_zod.z.string().optional()
199
+ }),
184
200
  import_zod.z.object({ type: import_zod.z.literal("unknown") })
185
201
  ])
186
202
  );
@@ -190,6 +206,8 @@ var TypeShapeSchema = import_zod.z.lazy(
190
206
  ConfidenceInfoSchema,
191
207
  ConfidenceLevelSchema,
192
208
  ConfidenceSourceSchema,
209
+ CorroborationSchema,
210
+ DeployableUnitSchema,
193
211
  FunctionCallSemanticsSchema,
194
212
  GraphqlOperationSemanticsSchema,
195
213
  GraphqlResolverSemanticsSchema,
@@ -11,6 +11,29 @@ declare const ConfidenceLevelSchema: z.ZodEnum<{
11
11
  medium: "medium";
12
12
  low: "low";
13
13
  }>;
14
+ /**
15
+ * The result of corroborating a claim against real execution
16
+ * (`suss corroborate`): generated inputs satisfying the claim's own
17
+ * conditions were run through the actual function and the observation
18
+ * either agreed every time (`observed`), disagreed at least once
19
+ * (`refuted` — an extractor bug or a genuine surprise; the
20
+ * counterexample says which input), or never produced a verdict
21
+ * (`untested` — no satisfying input was found, or every satisfying
22
+ * run hit a dependency the harness cannot supply).
23
+ *
24
+ * Corroboration upgrades a *derivation* with *observations*; it is
25
+ * additive evidence, never a rewrite of the derived claim.
26
+ */
27
+ declare const CorroborationSchema: z.ZodObject<{
28
+ outcome: z.ZodEnum<{
29
+ observed: "observed";
30
+ refuted: "refuted";
31
+ untested: "untested";
32
+ }>;
33
+ runs: z.ZodNumber;
34
+ counterexample: z.ZodOptional<z.ZodUnknown>;
35
+ reason: z.ZodOptional<z.ZodString>;
36
+ }, z.core.$strip>;
14
37
  declare const ConfidenceInfoSchema: z.ZodObject<{
15
38
  source: z.ZodEnum<{
16
39
  inferred_static: "inferred_static";
@@ -23,6 +46,16 @@ declare const ConfidenceInfoSchema: z.ZodObject<{
23
46
  medium: "medium";
24
47
  low: "low";
25
48
  }>;
49
+ corroboration: z.ZodOptional<z.ZodObject<{
50
+ outcome: z.ZodEnum<{
51
+ observed: "observed";
52
+ refuted: "refuted";
53
+ untested: "untested";
54
+ }>;
55
+ runs: z.ZodNumber;
56
+ counterexample: z.ZodOptional<z.ZodUnknown>;
57
+ reason: z.ZodOptional<z.ZodString>;
58
+ }, z.core.$strip>>;
26
59
  }, z.core.$strip>;
27
60
  declare const SourceLocationSchema: z.ZodObject<{
28
61
  file: z.ZodString;
@@ -68,13 +101,32 @@ declare const GraphqlOperationSemanticsSchema: z.ZodObject<{
68
101
  }>;
69
102
  }, z.core.$strip>;
70
103
  /**
71
- * Provider-side runtime configuration channel — env vars + their
104
+ * One thing that gets deployed and runs on its own: a Lambda
105
+ * function, an ECS task's container, a plain container, a k8s
106
+ * deployment.
107
+ *
108
+ * `instanceName` is the stable identifier the deployment medium uses:
109
+ * the CFN logical resource id for Lambda and ECS, the deployment name
110
+ * for k8s, the container name for a plain container.
111
+ */
112
+ declare const DeployableUnitSchema: z.ZodObject<{
113
+ deploymentTarget: z.ZodEnum<{
114
+ lambda: "lambda";
115
+ "ecs-task": "ecs-task";
116
+ container: "container";
117
+ "k8s-deployment": "k8s-deployment";
118
+ }>;
119
+ instanceName: z.ZodString;
120
+ }, z.core.$strip>;
121
+ /**
122
+ * Provider-side runtime configuration channel: env vars and their
72
123
  * declared values on a deployable unit. The channel is the boundary;
73
124
  * env var names are FIELDS on its contract. Pairing key:
74
- * `(deploymentTarget, instanceName)`.
125
+ * `(deploymentTarget, instanceName)`, which is exactly a deployable
126
+ * unit, so the two fields come from `DeployableUnitSchema` rather
127
+ * than being spelled a second time.
75
128
  */
76
129
  declare const RuntimeConfigSemanticsSchema: z.ZodObject<{
77
- name: z.ZodLiteral<"runtime-config">;
78
130
  deploymentTarget: z.ZodEnum<{
79
131
  lambda: "lambda";
80
132
  "ecs-task": "ecs-task";
@@ -82,6 +134,7 @@ declare const RuntimeConfigSemanticsSchema: z.ZodObject<{
82
134
  "k8s-deployment": "k8s-deployment";
83
135
  }>;
84
136
  instanceName: z.ZodString;
137
+ name: z.ZodLiteral<"runtime-config">;
85
138
  }, z.core.$strip>;
86
139
  /**
87
140
  * Provider-side relational storage table. Columns are FIELDS on the
@@ -146,7 +199,6 @@ declare const SemanticsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
146
199
  subscription: "subscription";
147
200
  }>;
148
201
  }, z.core.$strip>, z.ZodObject<{
149
- name: z.ZodLiteral<"runtime-config">;
150
202
  deploymentTarget: z.ZodEnum<{
151
203
  lambda: "lambda";
152
204
  "ecs-task": "ecs-task";
@@ -154,6 +206,7 @@ declare const SemanticsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
154
206
  "k8s-deployment": "k8s-deployment";
155
207
  }>;
156
208
  instanceName: z.ZodString;
209
+ name: z.ZodLiteral<"runtime-config">;
157
210
  }, z.core.$strip>, z.ZodObject<{
158
211
  name: z.ZodLiteral<"storage-relational">;
159
212
  storageSystem: z.ZodEnum<{
@@ -200,7 +253,6 @@ declare const BoundaryBindingSchema: z.ZodObject<{
200
253
  subscription: "subscription";
201
254
  }>;
202
255
  }, z.core.$strip>, z.ZodObject<{
203
- name: z.ZodLiteral<"runtime-config">;
204
256
  deploymentTarget: z.ZodEnum<{
205
257
  lambda: "lambda";
206
258
  "ecs-task": "ecs-task";
@@ -208,6 +260,7 @@ declare const BoundaryBindingSchema: z.ZodObject<{
208
260
  "k8s-deployment": "k8s-deployment";
209
261
  }>;
210
262
  instanceName: z.ZodString;
263
+ name: z.ZodLiteral<"runtime-config">;
211
264
  }, z.core.$strip>, z.ZodObject<{
212
265
  name: z.ZodLiteral<"storage-relational">;
213
266
  storageSystem: z.ZodEnum<{
@@ -264,9 +317,19 @@ type TypeShape = {
264
317
  } | {
265
318
  type: "ref";
266
319
  name: string;
320
+ /**
321
+ * The file that declares this type, when the project declares it.
322
+ * Absent for a name the language or a dependency owns, which means
323
+ * the same thing everywhere.
324
+ *
325
+ * A name on its own does not identify a type. Two modules each
326
+ * declaring a `User` produce the same ref, and a checker comparing
327
+ * them has nothing to go on. This is what tells them apart.
328
+ */
329
+ from?: string | undefined;
267
330
  } | {
268
331
  type: "unknown";
269
332
  };
270
333
  declare const TypeShapeSchema: z.ZodType<TypeShape>;
271
334
 
272
- export { BoundaryBindingSchema, ConfidenceInfoSchema, ConfidenceLevelSchema, ConfidenceSourceSchema, FunctionCallSemanticsSchema, GraphqlOperationSemanticsSchema, GraphqlResolverSemanticsSchema, MessageBusSemanticsSchema, RestSemanticsSchema, RuntimeConfigSemanticsSchema, SemanticsSchema, SourceLocationSchema, StorageRelationalSemanticsSchema, type TypeShape, TypeShapeSchema };
335
+ export { BoundaryBindingSchema, ConfidenceInfoSchema, ConfidenceLevelSchema, ConfidenceSourceSchema, CorroborationSchema, DeployableUnitSchema, FunctionCallSemanticsSchema, GraphqlOperationSemanticsSchema, GraphqlResolverSemanticsSchema, MessageBusSemanticsSchema, RestSemanticsSchema, RuntimeConfigSemanticsSchema, SemanticsSchema, SourceLocationSchema, StorageRelationalSemanticsSchema, type TypeShape, TypeShapeSchema };
package/dist/schemas.d.ts CHANGED
@@ -11,6 +11,29 @@ declare const ConfidenceLevelSchema: z.ZodEnum<{
11
11
  medium: "medium";
12
12
  low: "low";
13
13
  }>;
14
+ /**
15
+ * The result of corroborating a claim against real execution
16
+ * (`suss corroborate`): generated inputs satisfying the claim's own
17
+ * conditions were run through the actual function and the observation
18
+ * either agreed every time (`observed`), disagreed at least once
19
+ * (`refuted` — an extractor bug or a genuine surprise; the
20
+ * counterexample says which input), or never produced a verdict
21
+ * (`untested` — no satisfying input was found, or every satisfying
22
+ * run hit a dependency the harness cannot supply).
23
+ *
24
+ * Corroboration upgrades a *derivation* with *observations*; it is
25
+ * additive evidence, never a rewrite of the derived claim.
26
+ */
27
+ declare const CorroborationSchema: z.ZodObject<{
28
+ outcome: z.ZodEnum<{
29
+ observed: "observed";
30
+ refuted: "refuted";
31
+ untested: "untested";
32
+ }>;
33
+ runs: z.ZodNumber;
34
+ counterexample: z.ZodOptional<z.ZodUnknown>;
35
+ reason: z.ZodOptional<z.ZodString>;
36
+ }, z.core.$strip>;
14
37
  declare const ConfidenceInfoSchema: z.ZodObject<{
15
38
  source: z.ZodEnum<{
16
39
  inferred_static: "inferred_static";
@@ -23,6 +46,16 @@ declare const ConfidenceInfoSchema: z.ZodObject<{
23
46
  medium: "medium";
24
47
  low: "low";
25
48
  }>;
49
+ corroboration: z.ZodOptional<z.ZodObject<{
50
+ outcome: z.ZodEnum<{
51
+ observed: "observed";
52
+ refuted: "refuted";
53
+ untested: "untested";
54
+ }>;
55
+ runs: z.ZodNumber;
56
+ counterexample: z.ZodOptional<z.ZodUnknown>;
57
+ reason: z.ZodOptional<z.ZodString>;
58
+ }, z.core.$strip>>;
26
59
  }, z.core.$strip>;
27
60
  declare const SourceLocationSchema: z.ZodObject<{
28
61
  file: z.ZodString;
@@ -68,13 +101,32 @@ declare const GraphqlOperationSemanticsSchema: z.ZodObject<{
68
101
  }>;
69
102
  }, z.core.$strip>;
70
103
  /**
71
- * Provider-side runtime configuration channel — env vars + their
104
+ * One thing that gets deployed and runs on its own: a Lambda
105
+ * function, an ECS task's container, a plain container, a k8s
106
+ * deployment.
107
+ *
108
+ * `instanceName` is the stable identifier the deployment medium uses:
109
+ * the CFN logical resource id for Lambda and ECS, the deployment name
110
+ * for k8s, the container name for a plain container.
111
+ */
112
+ declare const DeployableUnitSchema: z.ZodObject<{
113
+ deploymentTarget: z.ZodEnum<{
114
+ lambda: "lambda";
115
+ "ecs-task": "ecs-task";
116
+ container: "container";
117
+ "k8s-deployment": "k8s-deployment";
118
+ }>;
119
+ instanceName: z.ZodString;
120
+ }, z.core.$strip>;
121
+ /**
122
+ * Provider-side runtime configuration channel: env vars and their
72
123
  * declared values on a deployable unit. The channel is the boundary;
73
124
  * env var names are FIELDS on its contract. Pairing key:
74
- * `(deploymentTarget, instanceName)`.
125
+ * `(deploymentTarget, instanceName)`, which is exactly a deployable
126
+ * unit, so the two fields come from `DeployableUnitSchema` rather
127
+ * than being spelled a second time.
75
128
  */
76
129
  declare const RuntimeConfigSemanticsSchema: z.ZodObject<{
77
- name: z.ZodLiteral<"runtime-config">;
78
130
  deploymentTarget: z.ZodEnum<{
79
131
  lambda: "lambda";
80
132
  "ecs-task": "ecs-task";
@@ -82,6 +134,7 @@ declare const RuntimeConfigSemanticsSchema: z.ZodObject<{
82
134
  "k8s-deployment": "k8s-deployment";
83
135
  }>;
84
136
  instanceName: z.ZodString;
137
+ name: z.ZodLiteral<"runtime-config">;
85
138
  }, z.core.$strip>;
86
139
  /**
87
140
  * Provider-side relational storage table. Columns are FIELDS on the
@@ -146,7 +199,6 @@ declare const SemanticsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
146
199
  subscription: "subscription";
147
200
  }>;
148
201
  }, z.core.$strip>, z.ZodObject<{
149
- name: z.ZodLiteral<"runtime-config">;
150
202
  deploymentTarget: z.ZodEnum<{
151
203
  lambda: "lambda";
152
204
  "ecs-task": "ecs-task";
@@ -154,6 +206,7 @@ declare const SemanticsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
154
206
  "k8s-deployment": "k8s-deployment";
155
207
  }>;
156
208
  instanceName: z.ZodString;
209
+ name: z.ZodLiteral<"runtime-config">;
157
210
  }, z.core.$strip>, z.ZodObject<{
158
211
  name: z.ZodLiteral<"storage-relational">;
159
212
  storageSystem: z.ZodEnum<{
@@ -200,7 +253,6 @@ declare const BoundaryBindingSchema: z.ZodObject<{
200
253
  subscription: "subscription";
201
254
  }>;
202
255
  }, z.core.$strip>, z.ZodObject<{
203
- name: z.ZodLiteral<"runtime-config">;
204
256
  deploymentTarget: z.ZodEnum<{
205
257
  lambda: "lambda";
206
258
  "ecs-task": "ecs-task";
@@ -208,6 +260,7 @@ declare const BoundaryBindingSchema: z.ZodObject<{
208
260
  "k8s-deployment": "k8s-deployment";
209
261
  }>;
210
262
  instanceName: z.ZodString;
263
+ name: z.ZodLiteral<"runtime-config">;
211
264
  }, z.core.$strip>, z.ZodObject<{
212
265
  name: z.ZodLiteral<"storage-relational">;
213
266
  storageSystem: z.ZodEnum<{
@@ -264,9 +317,19 @@ type TypeShape = {
264
317
  } | {
265
318
  type: "ref";
266
319
  name: string;
320
+ /**
321
+ * The file that declares this type, when the project declares it.
322
+ * Absent for a name the language or a dependency owns, which means
323
+ * the same thing everywhere.
324
+ *
325
+ * A name on its own does not identify a type. Two modules each
326
+ * declaring a `User` produce the same ref, and a checker comparing
327
+ * them has nothing to go on. This is what tells them apart.
328
+ */
329
+ from?: string | undefined;
267
330
  } | {
268
331
  type: "unknown";
269
332
  };
270
333
  declare const TypeShapeSchema: z.ZodType<TypeShape>;
271
334
 
272
- export { BoundaryBindingSchema, ConfidenceInfoSchema, ConfidenceLevelSchema, ConfidenceSourceSchema, FunctionCallSemanticsSchema, GraphqlOperationSemanticsSchema, GraphqlResolverSemanticsSchema, MessageBusSemanticsSchema, RestSemanticsSchema, RuntimeConfigSemanticsSchema, SemanticsSchema, SourceLocationSchema, StorageRelationalSemanticsSchema, type TypeShape, TypeShapeSchema };
335
+ export { BoundaryBindingSchema, ConfidenceInfoSchema, ConfidenceLevelSchema, ConfidenceSourceSchema, CorroborationSchema, DeployableUnitSchema, FunctionCallSemanticsSchema, GraphqlOperationSemanticsSchema, GraphqlResolverSemanticsSchema, MessageBusSemanticsSchema, RestSemanticsSchema, RuntimeConfigSemanticsSchema, SemanticsSchema, SourceLocationSchema, StorageRelationalSemanticsSchema, type TypeShape, TypeShapeSchema };
package/dist/schemas.js CHANGED
@@ -3,6 +3,8 @@ import {
3
3
  ConfidenceInfoSchema,
4
4
  ConfidenceLevelSchema,
5
5
  ConfidenceSourceSchema,
6
+ CorroborationSchema,
7
+ DeployableUnitSchema,
6
8
  FunctionCallSemanticsSchema,
7
9
  GraphqlOperationSemanticsSchema,
8
10
  GraphqlResolverSemanticsSchema,
@@ -13,12 +15,14 @@ import {
13
15
  SourceLocationSchema,
14
16
  StorageRelationalSemanticsSchema,
15
17
  TypeShapeSchema
16
- } from "./chunk-BWK3IPL7.js";
18
+ } from "./chunk-QQLJDL3C.js";
17
19
  export {
18
20
  BoundaryBindingSchema,
19
21
  ConfidenceInfoSchema,
20
22
  ConfidenceLevelSchema,
21
23
  ConfidenceSourceSchema,
24
+ CorroborationSchema,
25
+ DeployableUnitSchema,
22
26
  FunctionCallSemanticsSchema,
23
27
  GraphqlOperationSemanticsSchema,
24
28
  GraphqlResolverSemanticsSchema,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suss/ir-core",
3
- "version": "0.0.2",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "description": "Shared IR primitives for suss — type shapes, boundary bindings, source locations, and confidence. Imported by both @suss/behavioral-ir and @suss/intent-ir so neither depends on the other.",
6
6
  "keywords": [