@suss/ir-core 0.3.1 → 0.4.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/dist/index.d.cts CHANGED
@@ -1,69 +1,217 @@
1
1
  import { z } from 'zod';
2
- import { TypeShape, BoundaryBindingSchema, ConfidenceInfoSchema, ConfidenceLevelSchema, ConfidenceSourceSchema, CorroborationSchema, DeployableUnitSchema, SemanticsSchema, SourceLocationSchema } from './schemas.cjs';
3
- export { FunctionCallSemanticsSchema, GraphqlOperationSemanticsSchema, GraphqlResolverSemanticsSchema, MessageBusSemanticsSchema, RestSemanticsSchema, RuntimeConfigSemanticsSchema, StorageRelationalSemanticsSchema, TypeShapeSchema, typeDefinitionKey, withDefinitionsInlined } from './schemas.cjs';
2
+ import { T as TypeShape, S as Semantics, B as BoundaryBindingSchema, C as ConfidenceInfoSchema, a as ConfidenceLevelSchema, b as ConfidenceSourceSchema, c as CorroborationSchema, d as SourceLocationSchema, M as MessageBusTechnology } from './schemas-BWvfkxSH.cjs';
3
+ export { D as DeployableUnit, e as DeployableUnitSchema, F as FunctionCallSemantics, f as FunctionCallSemanticsSchema, G as GraphqlOperationSemantics, g as GraphqlOperationSemanticsSchema, h as GraphqlResolverSemantics, i as GraphqlResolverSemanticsSchema, j as MessageBusSemantics, k as MessageBusSemanticsSchema, R as RestSemantics, l as RestSemanticsSchema, m as RuntimeConfigSemantics, n as RuntimeConfigSemanticsSchema, o as SemanticsSchema, p as StorageRelationalSemantics, q as StorageRelationalSemanticsSchema, r as TypeShapeSchema, s as ecsContainerInstanceName, t as methodsAgree, u as normalizePath, v as routePathAdmits, w as typeDefinitionKey, x as withDefinitionsInlined } from './schemas-BWvfkxSH.cjs';
4
4
 
5
5
  /**
6
- * Normalize a route path to a canonical form for matching.
6
+ * Comparing two TypeShapes structurally.
7
7
  *
8
- * - Converts Express-style params (`:id`) to brace-style (`{id}`)
9
- * - Strips trailing slashes (except bare `/`)
10
- * - Lowercases the static segments (params stay case-sensitive)
8
+ * Both checkers do this. The behavioural checker compares a provider
9
+ * body against a declared contract, and the intent checker compares a
10
+ * code body against declared intent, and the two have to reach the same
11
+ * verdict for the same pair. The comparison is here, next to the
12
+ * TypeShape it works on, so neither checker owns it and the two cannot
13
+ * drift apart.
14
+ *
15
+ * The comparison is asymmetric, and the answer has three values rather
16
+ * than two. `unknown` is what keeps a shape nobody can see into from
17
+ * being reported as agreement.
18
+ */
19
+
20
+ /**
21
+ * A comparison result with three values:
22
+ * - "match": `actual` satisfies `declared`
23
+ * - "nomatch": there is a concrete, verifiable incompatibility
24
+ * - "unknown": uncertainty that would otherwise mask a mismatch
25
+ * (spreads, refs, unknown shapes)
26
+ */
27
+ type MatchResult = "match" | "nomatch" | "unknown";
28
+ /**
29
+ * Compare an actual body against a declared body and say whether the
30
+ * actual satisfies the declared.
31
+ *
32
+ * The two sides are not interchangeable. `actual` is the value that gets
33
+ * produced (a response body, a return value), and `declared` is the
34
+ * contract it has to conform to. `unknown` is a soft signal, and the
35
+ * caller decides whether to show it.
36
+ */
37
+ declare function bodyShapesMatch(actual: TypeShape, declared: TypeShape): MatchResult;
38
+
39
+ /**
40
+ * The contract a boundary protocol implements.
41
+ *
42
+ * A protocol (REST, message-bus, one side of GraphQL) is a single
43
+ * module in this directory. Its schema says what the identity fields
44
+ * are, its behavior says how those fields key and agree, and the two
45
+ * travel together so neither can be added without the other. Nothing
46
+ * outside a protocol's own module decides how its boundaries behave.
47
+ *
48
+ * These definitions ship with ir-core rather than with the packs,
49
+ * because a published summary has to mean the same thing to a reader
50
+ * who never installed the pack that wrote it. If a pack needs a
51
+ * protocol nobody has defined yet, add a module here.
11
52
  */
12
- declare function normalizePath(path: string): string;
53
+
13
54
  /**
14
- * Compute a stable string key from a boundary binding for grouping.
15
- * Dispatches on `semantics.name`:
16
- * - `rest` → `"METHOD /normalized/path"` (null if method or path empty)
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)
22
- * - `function-call` → `"fn:<package>::<exportPath>"` when both
23
- * `package` and `exportPath` are set; other in-process function-call
24
- * units (intra-repo components, bare handlers) return null.
25
- * - everything else → null
55
+ * How one semantics variant keys its boundaries and pairs them up. Each
56
+ * variant fills this in inside its own module, and nothing else in the
57
+ * tree gets a say in how a boundary keys or agrees.
26
58
  */
59
+ interface BoundaryBehavior<S extends {
60
+ name: string;
61
+ }> {
62
+ /** Null when the source never gave the boundary a name. */
63
+ identityKey(semantics: S): string | null;
64
+ /**
65
+ * The bucket the pairing pass groups by. Defaults to `identityKey`.
66
+ * Define it where one side can know more than its counterpart, and put
67
+ * only the shared part in the bucket: a `"*"` REST route has to meet
68
+ * consumers that each specify one method, so REST buckets by path
69
+ * alone. Whatever the bucket leaves out, `sidesAgree` has to compare.
70
+ */
71
+ pairingKey?(semantics: S): string | null;
72
+ /**
73
+ * Settles whatever `pairingKey` left out of the bucket. A variant that
74
+ * does not define it always agrees.
75
+ */
76
+ sidesAgree?(a: S, b: S): boolean;
77
+ /** The line a reader sees for this boundary. Defaults to `identityKey`. */
78
+ displayLabel?(semantics: S): string | null;
79
+ /**
80
+ * The first protocol whose `claims` returns true normalizes a
81
+ * hand-written suppression boundary, and a string nobody claims is
82
+ * compared byte for byte. A protocol whose keys are exact declares
83
+ * nothing here and stays verbatim.
84
+ */
85
+ ruleBoundary?: {
86
+ claims(raw: string): boolean;
87
+ normalize(raw: string): string;
88
+ };
89
+ /**
90
+ * A protocol whose boundaries have no URL leaves this undefined, which
91
+ * is different from an "unknown" result: undefined means the question
92
+ * does not apply, and unknown means this declaration cannot settle it.
93
+ */
94
+ servesRequest?(semantics: S, method: string, path: string): MatchResult;
95
+ /**
96
+ * Whether a provider produces a status and a body that a consumer
97
+ * reads back. Every protocol has to state this, so that one added
98
+ * later says what it is instead of landing in the HTTP-style checks
99
+ * because nobody remembered to exclude it.
100
+ */
101
+ exchangesHttpResponses: boolean;
102
+ /**
103
+ * Whether this protocol's own pass already reports a boundary that
104
+ * paired with nothing, so the generic unmatched list can leave it out.
105
+ */
106
+ reportsUnpairedItself: boolean;
107
+ }
108
+ /**
109
+ * One protocol in full: the schema for its identity fields, and the
110
+ * behavior that keys them. The registry composes these into the
111
+ * `Semantics` union and the runtime lookup.
112
+ */
113
+ interface BoundarySemanticsDefinition<Z extends z.ZodType<{
114
+ name: string;
115
+ }>> {
116
+ name: z.infer<Z>["name"];
117
+ schema: Z;
118
+ behavior: BoundaryBehavior<z.infer<Z>>;
119
+ }
120
+
121
+ /**
122
+ * Keys for a boundary binding, and whether two of them agree. Every
123
+ * function here asks the binding's protocol and returns whatever it
124
+ * says, so the rules themselves are in the protocol's own module under
125
+ * `semantics/` and not in this file.
126
+ *
127
+ * The sharing is the point. The behavioural checker pairs code
128
+ * summaries by these keys, and the intent checker pairs intent against
129
+ * code by the same keys. If the two ever keyed differently, intent and
130
+ * code would stop lining up, so the keying is here next to the binding
131
+ * rather than in either checker.
132
+ */
133
+
27
134
  declare function boundaryKey(binding: BoundaryBinding): string | null;
135
+ declare function pairingKey(binding: BoundaryBinding): string | null;
136
+ declare function semanticsAgree(a: Semantics, b: Semantics): boolean;
137
+ declare function boundaryLabel(binding: BoundaryBinding): string | null;
138
+ declare function displayLabel(binding: BoundaryBinding): string;
139
+ /**
140
+ * A boundary string that no protocol claims keeps its case, because
141
+ * message-bus keys are case-sensitive and uppercasing one would break
142
+ * the rule without saying so.
143
+ */
144
+ declare function normalizeRuleBoundary(raw: string): string;
145
+ declare function exchangesHttpResponses(binding: BoundaryBinding): boolean;
146
+ declare function reportsUnpairedItself(binding: BoundaryBinding): boolean;
147
+ /**
148
+ * Null means the protocol does not address its boundaries by method and
149
+ * path at all, which a caller has to tell apart from an unknown answer:
150
+ * unknown means it does, but this declaration cannot settle the question.
151
+ */
152
+ declare function servesRequest(binding: BoundaryBinding, method: string, path: string): MatchResult | null;
28
153
 
29
154
  /**
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.
155
+ * Deciding when two message-bus channel strings mean the same thing.
156
+ *
157
+ * A channel is a subject, optionally qualified by the bus that carries
158
+ * it, written `${bus}#${subject}`. The two sides of a pairing rarely
159
+ * know the same amount, so they pair on the subject and the buses have
160
+ * to agree only when both sides know one. The package README works
161
+ * through why, with examples.
162
+ *
163
+ * Everything that writes or reads that string goes through
164
+ * `formatChannel` and `parseChannel`, so the wire format has a single
165
+ * author. A template reader that hand-writes the `#` would be a second
166
+ * author, and the two would drift the first time either one changed.
34
167
  */
168
+ /** A channel string, written `${bus}#${subject}`, split into its two parts. */
35
169
  interface ParsedChannel {
36
170
  bus: string | null;
37
171
  subject: string;
38
172
  }
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
173
  declare function parseChannel(channel: string): ParsedChannel;
45
- /** Two buses agree when they are the same, or when either is unknown. */
174
+ declare function formatChannel(bus: string | null, subject: string): string;
46
175
  declare function busesAgree(a: string | null, b: string | null): boolean;
47
- /** Whether two channels name the same subject on agreeing buses. */
48
176
  declare function channelsPair(a: string, b: string): boolean;
49
177
 
178
+ /**
179
+ * One convention for the source directory a deployable unit is built
180
+ * from, and one test for whether a file is inside it.
181
+ *
182
+ * A deploy template gives a directory per unit, and a summary stores it
183
+ * as `metadata.codeScope.path`. Producers write that path and the
184
+ * checker reads it back as a prefix test, so the two sides have to
185
+ * agree on whether it ends in a slash. Normalizing it in one place is
186
+ * what keeps them agreeing. The test also has to stop at a segment
187
+ * boundary, or `src/foo` would cover `src/foobar` and a handler would
188
+ * pair with the wrong function.
189
+ */
50
190
  /**
51
191
  * The canonical form of a code-scope directory: no leading `./`, no
52
192
  * trailing slash, no surrounding whitespace. An empty result means the
53
- * scope names the project root.
193
+ * scope is the project root.
54
194
  */
55
195
  declare function codeScopePath(raw: string): string;
56
196
  /**
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.
197
+ * Whether a project-relative file is inside a code scope. Matching stops
198
+ * at a segment boundary, so `src/foo` covers `src/foo/a.ts` and never
199
+ * `src/foobar/a.ts`. A scope that is the project root covers every file.
61
200
  *
62
- * Both arguments pass through `codeScopePath`, so a scope stored under
63
- * either of the older trailing-slash conventions still reads correctly.
201
+ * Both arguments go through `codeScopePath`, so a scope stored with a
202
+ * trailing slash and one stored without it are read the same way.
64
203
  */
65
204
  declare function fileInCodeScope(file: string, scope: string): boolean;
66
205
 
206
+ /**
207
+ * The DispatchTable idiom: dispatch on a discriminated union through a
208
+ * mapped-type Record, so a missing variant is a type error rather than a
209
+ * runtime fall-through. It is decision #8 in docs/internal/style.md.
210
+ *
211
+ * It is here rather than in one package because the decision applies
212
+ * repo-wide, and every package that walks an IR union needs it. Three
213
+ * of them had written their own copy before this one existed.
214
+ */
67
215
  type DispatchTable<T extends {
68
216
  type: string;
69
217
  }, R> = {
@@ -75,6 +223,21 @@ declare function dispatchByType<T extends {
75
223
  type: string;
76
224
  }, R>(table: DispatchTable<T, R>, value: T): R;
77
225
 
226
+ /**
227
+ * The suppression pipeline, over the smallest finding both checkers share.
228
+ *
229
+ * Behavioural `Finding` and intent `IntentFinding` both have `kind`,
230
+ * `severity`, and an optional `suppressed`, which is all the pipeline
231
+ * needs. The rule schema, first-match-wins matching, effect application,
232
+ * and threshold counting are here so the two checkers share one
233
+ * implementation without depending on each other. Only the matching of a
234
+ * rule's discriminators differs, and a caller passes that in.
235
+ *
236
+ * The module owns rules and matching, not file I/O. The CLI reads a
237
+ * .sussignore file, checks each kind against the published enums, and
238
+ * hands the parsed rules over.
239
+ */
240
+
78
241
  declare const SuppressionRuleSchema: z.ZodObject<{
79
242
  kind: z.ZodOptional<z.ZodString>;
80
243
  boundary: z.ZodOptional<z.ZodString>;
@@ -133,9 +296,9 @@ interface FindingSuppression {
133
296
  originalSeverity?: SuppressableSeverity | undefined;
134
297
  }
135
298
  /**
136
- * The structural base both finding shapes satisfy. Behavioural
299
+ * The structural base that both finding types satisfy. Behavioural
137
300
  * `Finding` and intent `IntentFinding` each declare these fields in
138
- * their own schemas (kept structurally identical); the pipeline needs
301
+ * their own schemas, kept structurally identical, and the pipeline needs
139
302
  * nothing more. The `| undefined` unions match what zod infers for
140
303
  * `.optional()` fields under exactOptionalPropertyTypes.
141
304
  */
@@ -145,32 +308,24 @@ interface SuppressibleFinding {
145
308
  suppressed?: FindingSuppression | undefined;
146
309
  }
147
310
  /**
148
- * Validate that a narrow rule actually constrains *something* — a bare
149
- * rule with only `reason` would suppress every finding in the codebase,
150
- * which is almost always a mistake. Broad-scope rules deliberately
151
- * allow less-specific matching.
311
+ * Check that a narrow rule constrains something. A bare rule with only
312
+ * a `reason` would suppress every finding in the codebase, which is
313
+ * almost always a mistake. Broad-scope rules are allowed to match less
314
+ * specifically, on purpose.
152
315
  */
153
316
  declare function validateRule(rule: SuppressionRule): string | null;
317
+
154
318
  /**
155
- * Normalize a rule's boundary string to match `boundaryKey`'s output
156
- * format. Authors may write "GET /pet/:id" or "GET /pet/{id}"; we
157
- * accept either. Method is uppercased; the path goes through
158
- * `normalizePath` (colon-to-brace, trailing-slash stripping, lowercase
159
- * static segments). Non-REST keys ("fn:...", "gql:...") don't have the
160
- * METHOD-space-path shape and are compared verbatim by callers.
161
- */
162
- declare function normalizeRuleBoundary(raw: string): string;
163
- /**
164
- * Does a rule's `boundary` discriminator match a finding's boundary
165
- * key? Exact match first (covers "fn:...", "gql:..."), then the
166
- * REST-normalized form.
319
+ * Whether a rule's `boundary` discriminator matches a finding's boundary
320
+ * key. It tries an exact match first, which covers "fn:..." and
321
+ * "gql:...", and then the REST-normalized form.
167
322
  */
168
323
  declare function ruleBoundaryMatchesKey(ruleBoundary: string, key: string | null): boolean;
169
324
  /**
170
- * Apply suppression rules to a list of findings. Generic over the
171
- * finding shape: `matches` decides whether a rule's discriminators
172
- * beyond `kind` (boundary, consumer, ...) match a finding — the kind
173
- * check itself is universal and handled here.
325
+ * Apply suppression rules to a list of findings. This works for either
326
+ * finding type: `matches` decides whether a rule's discriminators past
327
+ * `kind` (boundary, consumer, and so on) match a finding, and the kind
328
+ * check itself is the same everywhere, so it happens here.
174
329
  *
175
330
  * Returns a new array. Findings with `effect: "hide"` are omitted from
176
331
  * the output entirely unless `keepHidden` is set. Findings with
@@ -181,30 +336,23 @@ declare function applySuppressionsToFindings<T extends SuppressibleFinding>(find
181
336
  keepHidden?: boolean;
182
337
  }): T[];
183
338
  /**
184
- * `hide` and `mark` findings are excluded from exit-code threshold
185
- * calculations; `downgrade` findings count at their post-downgrade
186
- * severity. Callers use this to decide whether a finding contributes
187
- * to `hasErrors`-style gating.
339
+ * `hide` and `mark` findings are left out of the exit-code threshold,
340
+ * and a `downgrade` finding counts at the severity it was downgraded
341
+ * to. Callers use this to decide whether a finding contributes to
342
+ * `hasErrors`-style gating.
188
343
  */
189
344
  declare function countsForThreshold(finding: SuppressibleFinding): boolean;
190
345
 
191
346
  /**
192
- * Three-valued comparison result:
193
- * - "match" — `actual` satisfies `declared`
194
- * - "nomatch" — a concrete, verifiable incompatibility exists
195
- * - "unknown" — uncertainty that would mask a real mismatch (spreads,
196
- * refs, unknown shapes)
197
- */
198
- type MatchResult = "match" | "nomatch" | "unknown";
199
- /**
200
- * Compare an actual body shape against a declared body shape and report
201
- * whether the actual satisfies the declared.
347
+ * @suss/ir-core: primitives shared across suss IRs.
202
348
  *
203
- * Semantics are asymmetric: `actual` is the produced value (a response
204
- * body, a return value) and `declared` is the contract it must conform
205
- * to. `unknown` is a soft signal; callers decide whether to surface it.
349
+ * The schemas are the single source of truth, and the types come from
350
+ * them. Each boundary protocol's schema and behavior are in one module
351
+ * under `./semantics`, and everything else is in `./schemas`. The
352
+ * boundary-binding constructors are here too, so that any package that
353
+ * produces an IR object (pattern packs, contract readers, intent docs,
354
+ * tests) can build a binding without depending on a specific IR.
206
355
  */
207
- declare function bodyShapesMatch(actual: TypeShape, declared: TypeShape): MatchResult;
208
356
 
209
357
  type ConfidenceSource = z.infer<typeof ConfidenceSourceSchema>;
210
358
  type ConfidenceLevel = z.infer<typeof ConfidenceLevelSchema>;
@@ -212,39 +360,17 @@ type ConfidenceInfo = z.infer<typeof ConfidenceInfoSchema>;
212
360
  type Corroboration = z.infer<typeof CorroborationSchema>;
213
361
  type SourceLocation = z.infer<typeof SourceLocationSchema>;
214
362
  type BoundaryBinding = z.infer<typeof BoundaryBindingSchema>;
215
- type Semantics = z.infer<typeof SemanticsSchema>;
216
- type RestSemantics = Extract<Semantics, {
217
- name: "rest";
218
- }>;
219
- type FunctionCallSemantics = Extract<Semantics, {
220
- name: "function-call";
221
- }>;
222
- type GraphqlResolverSemantics = Extract<Semantics, {
223
- name: "graphql-resolver";
224
- }>;
225
- type GraphqlOperationSemantics = Extract<Semantics, {
226
- name: "graphql-operation";
227
- }>;
228
- type RuntimeConfigSemantics = Extract<Semantics, {
229
- name: "runtime-config";
230
- }>;
231
- type StorageRelationalSemantics = Extract<Semantics, {
232
- name: "storage-relational";
233
- }>;
234
- type MessageBusSemantics = Extract<Semantics, {
235
- name: "message-bus";
236
- }>;
237
- type DeployableUnit = z.infer<typeof DeployableUnitSchema>;
238
363
 
239
364
  /**
240
- * Build a REST-semantics binding. `method` and `path` can be empty
241
- * strings to signal "not yet resolved" (the adapter's wrapper-expansion
242
- * pass uses this); pairing treats empty method/path as unplaced.
365
+ * Build a REST-semantics binding. `method` and `path` are null when the
366
+ * source does not specify them. `"*"` is the method wildcard, for a
367
+ * handler that responds to every method. When pairing, null means
368
+ * unspecified and matches nothing, and `"*"` matches every concrete method.
243
369
  */
244
370
  declare function restBinding(opts: {
245
371
  transport: string;
246
- method: string;
247
- path: string;
372
+ method: string | null;
373
+ path: string | null;
248
374
  recognition: string;
249
375
  declaredResponses?: number[];
250
376
  }): BoundaryBinding;
@@ -261,9 +387,9 @@ declare function functionCallBinding(opts: {
261
387
  exportPath?: string[];
262
388
  }): BoundaryBinding;
263
389
  /**
264
- * Build a function-call binding that identifies a public package export
265
- * — the provider side of a library boundary. Transport defaults to
266
- * `"in-process"` for typical TypeScript library consumption.
390
+ * Build a function-call binding that identifies a public package export,
391
+ * which is the provider side of a library boundary. Transport defaults
392
+ * to `"in-process"`, which is how a TypeScript library is usually used.
267
393
  */
268
394
  declare function packageExportBinding(opts: {
269
395
  transport?: string;
@@ -278,12 +404,13 @@ declare function packageExportBinding(opts: {
278
404
  declare function graphqlResolverBinding(opts: {
279
405
  transport: string;
280
406
  recognition: string;
281
- typeName: string;
407
+ /** Null when the source never says which type the resolver attaches to. */
408
+ typeName: string | null;
282
409
  fieldName: string;
283
410
  }): BoundaryBinding;
284
411
  /**
285
- * Build a graphql-operation-semantics binding — the consumer side of a
286
- * GraphQL boundary. Anonymous operations leave `operationName` unset.
412
+ * Build a graphql-operation-semantics binding, which is the consumer side
413
+ * of a GraphQL boundary. Anonymous operations leave `operationName` unset.
287
414
  */
288
415
  declare function graphqlOperationBinding(opts: {
289
416
  transport: string;
@@ -292,10 +419,10 @@ declare function graphqlOperationBinding(opts: {
292
419
  operationName?: string;
293
420
  }): BoundaryBinding;
294
421
  /**
295
- * Build a runtime-config binding — the provider side of a runtime
296
- * configuration channel (env vars on a Lambda / ECS task / container /
297
- * k8s pod). Transport is `"os"`: env vars are handed to the process by
298
- * the OS at startup regardless of the deployment medium.
422
+ * Build a runtime-config binding, the provider side of a runtime
423
+ * configuration channel (env vars on a Lambda, ECS task, container, or
424
+ * k8s pod). Transport is `"os"` because the OS hands env vars to the
425
+ * process at startup no matter what the deployment medium is.
299
426
  */
300
427
  declare function runtimeConfigBinding(opts: {
301
428
  recognition: string;
@@ -303,10 +430,10 @@ declare function runtimeConfigBinding(opts: {
303
430
  instanceName: string;
304
431
  }): BoundaryBinding;
305
432
  /**
306
- * Build a storage-relational binding — the provider side of a
307
- * relational storage table. Transport carries the `storageSystem`
308
- * value so the layering stays informative without a separate
309
- * wire-protocol taxonomy.
433
+ * Build a storage-relational binding, the provider side of a relational
434
+ * storage table. Transport stores the `storageSystem` value, which keeps
435
+ * the layering informative without needing a separate wire-protocol
436
+ * taxonomy.
310
437
  */
311
438
  declare function storageRelationalBinding(opts: {
312
439
  recognition: string;
@@ -315,13 +442,14 @@ declare function storageRelationalBinding(opts: {
315
442
  table: string;
316
443
  }): BoundaryBinding;
317
444
  /**
318
- * Build a message-bus binding — the boundary between a producer that
445
+ * Build a message-bus binding, the boundary between a producer that
319
446
  * sends discrete messages and the consumer(s) that receive them.
320
447
  */
321
448
  declare function messageBusBinding(opts: {
322
449
  recognition: string;
323
- messageBus: "sqs" | "eventbridge" | "bullmq" | "kafka" | "nats";
324
- channel: string;
450
+ messageBus: MessageBusTechnology;
451
+ /** Null when this source does not say which channel. */
452
+ channel: string | null;
325
453
  }): BoundaryBinding;
326
454
 
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 };
455
+ export { type BoundaryBehavior, type BoundaryBinding, BoundaryBindingSchema, type BoundarySemanticsDefinition, type ConfidenceInfo, ConfidenceInfoSchema, type ConfidenceLevel, ConfidenceLevelSchema, type ConfidenceSource, ConfidenceSourceSchema, type Corroboration, CorroborationSchema, type DispatchTable, type FindingSuppression, type MatchResult, MessageBusTechnology, type ParsedChannel, Semantics, type SourceLocation, SourceLocationSchema, type SuppressableSeverity, type SuppressibleFinding, type SuppressionFile, SuppressionFileSchema, type SuppressionRule, SuppressionRuleSchema, TypeShape, applySuppressionsToFindings, bodyShapesMatch, boundaryKey, boundaryLabel, busesAgree, channelsPair, codeScopePath, countsForThreshold, dispatchByType, displayLabel, exchangesHttpResponses, fileInCodeScope, formatChannel, functionCallBinding, graphqlOperationBinding, graphqlResolverBinding, messageBusBinding, normalizeRuleBoundary, packageExportBinding, pairingKey, parseChannel, reportsUnpairedItself, restBinding, ruleBoundaryMatchesKey, runtimeConfigBinding, semanticsAgree, servesRequest, storageRelationalBinding, validateRule };