@suss/extractor 0.0.1 → 0.1.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 +1 -1
- package/dist/index.cjs +14 -0
- package/dist/index.d.cts +106 -2
- package/dist/index.d.ts +106 -2
- package/dist/index.js +14 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Assembly engine that turns raw language-adapter output into a `BehavioralSummary
|
|
|
4
4
|
|
|
5
5
|
## What this package is
|
|
6
6
|
|
|
7
|
-
`@suss/extractor` is the core assembly layer of the suss pipeline. Language adapters (such as `@suss/adapter-typescript`) parse source code and produce a `RawCodeStructure
|
|
7
|
+
`@suss/extractor` is the core assembly layer of the suss pipeline. Language adapters (such as `@suss/adapter-typescript`) parse source code and produce a `RawCodeStructure`, a normalized, adapter-specific intermediate form. The extractor's `assembleSummary` function converts that structure into the final `BehavioralSummary` IR, handling condition polarity, terminal mapping, gap detection, confidence assessment, and `expectedInput` pass-through for client field tracking. It also exports the `RawCodeStructure` type, the `PatternPack` interface, and all related raw types so adapters can share a common contract.
|
|
8
8
|
|
|
9
9
|
## Where it sits in suss
|
|
10
10
|
|
package/dist/index.cjs
CHANGED
|
@@ -150,6 +150,17 @@ function detectGaps(raw, transitions, options) {
|
|
|
150
150
|
return [];
|
|
151
151
|
}
|
|
152
152
|
const gaps = [];
|
|
153
|
+
if (raw.unmatchedReturns !== void 0 && raw.unmatchedReturns > 0) {
|
|
154
|
+
const count = raw.unmatchedReturns;
|
|
155
|
+
gaps.push({
|
|
156
|
+
// Not a contract violation: the handler may be answering
|
|
157
|
+
// correctly, in a shape nobody taught the pack.
|
|
158
|
+
type: "unreadOutcome",
|
|
159
|
+
conditions: [],
|
|
160
|
+
consequence: "unknown",
|
|
161
|
+
description: count === 1 ? "One return in this function matches none of the terminal shapes this pack looks for, so what it produces is not described here" : `${count} returns in this function match none of the terminal shapes this pack looks for, so what they produce is not described here`
|
|
162
|
+
});
|
|
163
|
+
}
|
|
153
164
|
if (raw.declaredContract) {
|
|
154
165
|
const producedStatuses = new Set(
|
|
155
166
|
transitions.flatMap((t) => {
|
|
@@ -190,6 +201,9 @@ function detectGaps(raw, transitions, options) {
|
|
|
190
201
|
return gaps;
|
|
191
202
|
}
|
|
192
203
|
function assessConfidence(raw) {
|
|
204
|
+
if ((raw.unmatchedReturns ?? 0) > 0) {
|
|
205
|
+
return { source: "inferred_static", level: "low" };
|
|
206
|
+
}
|
|
193
207
|
let total = 0;
|
|
194
208
|
let opaque = 0;
|
|
195
209
|
for (const branch of raw.branches) {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Predicate, TypeShape, RenderNode, CodeUnitKind, BoundaryBinding, BehavioralSummary, ConfidenceInfo, Transition, Gap, Input, Output } from '@suss/behavioral-ir';
|
|
1
|
+
import { Effect, MessageBusSemantics, Predicate, TypeShape, RenderNode, CodeUnitKind, BoundaryBinding, BehavioralSummary, ConfidenceInfo, Transition, Gap, Input, Output } from '@suss/behavioral-ir';
|
|
2
2
|
|
|
3
3
|
type DiscoveryMatch = {
|
|
4
4
|
type: "namedExport";
|
|
@@ -374,7 +374,49 @@ type BindingExtraction = {
|
|
|
374
374
|
type: "fromRegistration";
|
|
375
375
|
position: number;
|
|
376
376
|
} | {
|
|
377
|
+
type: "fromArgumentProperty";
|
|
378
|
+
position: number;
|
|
379
|
+
property: string;
|
|
380
|
+
} | {
|
|
381
|
+
/**
|
|
382
|
+
* The route path comes from where the file sits, which is how
|
|
383
|
+
* Next.js and React Router describe their routes. The pack
|
|
384
|
+
* spells out its own convention here, since the adapter knows
|
|
385
|
+
* about files and the pack knows what the framework does with
|
|
386
|
+
* their names.
|
|
387
|
+
*
|
|
388
|
+
* `app/api/orders/[id]/route.ts` under `{ root: "app",
|
|
389
|
+
* dropBasenames: ["route"], dynamic: "brackets" }` comes out as
|
|
390
|
+
* `/api/orders/{id}`, which pairs with an Express provider
|
|
391
|
+
* writing `/api/orders/:id`.
|
|
392
|
+
*/
|
|
377
393
|
type: "fromFilename";
|
|
394
|
+
/**
|
|
395
|
+
* Where a route path starts. The directories below it become
|
|
396
|
+
* the path; everything above it belongs to the project layout
|
|
397
|
+
* and is dropped.
|
|
398
|
+
*/
|
|
399
|
+
root: string;
|
|
400
|
+
/**
|
|
401
|
+
* Filenames that say what a file is rather than adding a
|
|
402
|
+
* segment: `route`, `page`, `index`, `_index`.
|
|
403
|
+
*/
|
|
404
|
+
dropBasenames?: string[];
|
|
405
|
+
/**
|
|
406
|
+
* How the framework writes a parameter in a filename. Next.js
|
|
407
|
+
* uses `[id]`, React Router uses `$id`.
|
|
408
|
+
*/
|
|
409
|
+
dynamic?: "brackets" | "dollarPrefix";
|
|
410
|
+
/**
|
|
411
|
+
* Whether a directory in parentheses organises files without
|
|
412
|
+
* appearing in the URL, as `app/(marketing)/about` does.
|
|
413
|
+
*/
|
|
414
|
+
dropParenthesized?: boolean;
|
|
415
|
+
/**
|
|
416
|
+
* Whether one filename holds the whole path with dots between
|
|
417
|
+
* the segments, as `routes/orders.$id.tsx` does.
|
|
418
|
+
*/
|
|
419
|
+
flat?: boolean;
|
|
378
420
|
} | {
|
|
379
421
|
type: "fromContract";
|
|
380
422
|
} | {
|
|
@@ -487,6 +529,10 @@ interface TerminalExtraction {
|
|
|
487
529
|
} | {
|
|
488
530
|
from: "constructor";
|
|
489
531
|
codes: Record<string, number>;
|
|
532
|
+
} | {
|
|
533
|
+
from: "argumentProperty";
|
|
534
|
+
position: number;
|
|
535
|
+
name: string;
|
|
490
536
|
} | {
|
|
491
537
|
from: "argumentConstructor";
|
|
492
538
|
position: number;
|
|
@@ -619,6 +665,23 @@ interface ResponsePropertyMapping {
|
|
|
619
665
|
/** What the value semantically represents */
|
|
620
666
|
semantics: ResponsePropertyMeaning;
|
|
621
667
|
}
|
|
668
|
+
/**
|
|
669
|
+
* A library wrapper whose result is the function it was handed. The
|
|
670
|
+
* adapter works this out on its own for factories declared in the
|
|
671
|
+
* project by reading their bodies. A library's body is not readable,
|
|
672
|
+
* so the pack states it.
|
|
673
|
+
*/
|
|
674
|
+
interface TransparentWrapper {
|
|
675
|
+
/** Callee text as written, e.g. "Sentry.wrapHandler". */
|
|
676
|
+
callee: string;
|
|
677
|
+
/** Which argument holds the wrapped function. */
|
|
678
|
+
argument: number;
|
|
679
|
+
/**
|
|
680
|
+
* The module the callee has to have been imported from. Without it a
|
|
681
|
+
* local object spelled the same way would be taken for the library.
|
|
682
|
+
*/
|
|
683
|
+
module: string;
|
|
684
|
+
}
|
|
622
685
|
interface PatternPack {
|
|
623
686
|
name: string;
|
|
624
687
|
/**
|
|
@@ -792,6 +855,17 @@ interface PatternPack {
|
|
|
792
855
|
* available without an import).
|
|
793
856
|
*/
|
|
794
857
|
requiresImport?: string[];
|
|
858
|
+
/**
|
|
859
|
+
* Library wrappers whose result is the wrapped function. The adapter
|
|
860
|
+
* derives this automatically for project-local factories by reading
|
|
861
|
+
* their bodies; a library wrapper's body is not readable, so the
|
|
862
|
+
* pack states the judgment: a call to `callee` resolves to its
|
|
863
|
+
* `argument`-th argument.
|
|
864
|
+
*
|
|
865
|
+
* `callee` matches the call expression text as written, e.g.
|
|
866
|
+
* `"Sentry.wrapHandler"`.
|
|
867
|
+
*/
|
|
868
|
+
transparentWrappers?: TransparentWrapper[];
|
|
795
869
|
/**
|
|
796
870
|
* Per-property-access recognizers — sister to
|
|
797
871
|
* `invocationRecognizers` but firing on `PropertyAccessExpression`
|
|
@@ -884,6 +958,29 @@ interface DiscoveredCustomUnit {
|
|
|
884
958
|
method: string;
|
|
885
959
|
path: string;
|
|
886
960
|
};
|
|
961
|
+
/**
|
|
962
|
+
* GraphQL field identity for units a callback discovers against an
|
|
963
|
+
* external manifest rather than an in-code resolver map. AppSync
|
|
964
|
+
* routes a field to a Lambda in the deploy template, so the field is
|
|
965
|
+
* the boundary that code serves. When set, the adapter builds a
|
|
966
|
+
* `graphql-resolver` binding from `(typeName, fieldName)`, which
|
|
967
|
+
* pairs with the operations a client sends.
|
|
968
|
+
*/
|
|
969
|
+
resolverInfo?: {
|
|
970
|
+
typeName: string;
|
|
971
|
+
fieldName: string;
|
|
972
|
+
};
|
|
973
|
+
/**
|
|
974
|
+
* Message-bus channel identity for consumer units a callback
|
|
975
|
+
* discovers against a subject the code itself names (a handler
|
|
976
|
+
* factory whose config carries the expected subject). When set, the
|
|
977
|
+
* adapter builds a `message-bus` binding from `(messageBus, channel)`,
|
|
978
|
+
* which pairs with producers sending on the same channel.
|
|
979
|
+
*/
|
|
980
|
+
channelInfo?: {
|
|
981
|
+
messageBus: MessageBusSemantics["messageBus"];
|
|
982
|
+
channel: string;
|
|
983
|
+
};
|
|
887
984
|
/**
|
|
888
985
|
* Metadata merged onto the resulting summary's `metadata` field.
|
|
889
986
|
*/
|
|
@@ -1188,6 +1285,13 @@ interface RawCodeStructure {
|
|
|
1188
1285
|
boundaryBinding: BoundaryBinding | null;
|
|
1189
1286
|
parameters: RawParameter[];
|
|
1190
1287
|
branches: RawBranch[];
|
|
1288
|
+
/**
|
|
1289
|
+
* Return statements in the body that none of the pack's terminals
|
|
1290
|
+
* matched. A handler shaped in a way the pack does not describe still
|
|
1291
|
+
* returns something, and saying nothing about it reads the same as
|
|
1292
|
+
* saying it does nothing.
|
|
1293
|
+
*/
|
|
1294
|
+
unmatchedReturns?: number;
|
|
1191
1295
|
dependencyCalls: RawDependencyCall[];
|
|
1192
1296
|
declaredContract: RawDeclaredContract | null;
|
|
1193
1297
|
/**
|
|
@@ -1266,4 +1370,4 @@ declare function terminalToOutput(terminal: RawTerminal): Output;
|
|
|
1266
1370
|
declare function effectToIR(effect: RawEffect): Effect;
|
|
1267
1371
|
declare function paramToInput(param: RawParameter): Input;
|
|
1268
1372
|
|
|
1269
|
-
export { type AccessRecognizer, type BindingExtraction, type ContractPattern, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type ExtractorOptions, type InputMappingPattern, type InvocationRecognizer, type PatternPack, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type ResponsePropertyMapping, type ResponsePropertyMeaning, type TerminalExtraction, type TerminalMatch, type TerminalPattern, assembleSummary, assessConfidence, detectGaps, effectToIR, httpRouteDiscovery, makeTransitionId, paramToInput, terminalToOutput };
|
|
1373
|
+
export { type AccessRecognizer, type BindingExtraction, type ContractPattern, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type ExtractorOptions, type InputMappingPattern, type InvocationRecognizer, type PatternPack, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type ResponsePropertyMapping, type ResponsePropertyMeaning, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type TransparentWrapper, assembleSummary, assessConfidence, detectGaps, effectToIR, httpRouteDiscovery, makeTransitionId, paramToInput, terminalToOutput };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Effect, Predicate, TypeShape, RenderNode, CodeUnitKind, BoundaryBinding, BehavioralSummary, ConfidenceInfo, Transition, Gap, Input, Output } from '@suss/behavioral-ir';
|
|
1
|
+
import { Effect, MessageBusSemantics, Predicate, TypeShape, RenderNode, CodeUnitKind, BoundaryBinding, BehavioralSummary, ConfidenceInfo, Transition, Gap, Input, Output } from '@suss/behavioral-ir';
|
|
2
2
|
|
|
3
3
|
type DiscoveryMatch = {
|
|
4
4
|
type: "namedExport";
|
|
@@ -374,7 +374,49 @@ type BindingExtraction = {
|
|
|
374
374
|
type: "fromRegistration";
|
|
375
375
|
position: number;
|
|
376
376
|
} | {
|
|
377
|
+
type: "fromArgumentProperty";
|
|
378
|
+
position: number;
|
|
379
|
+
property: string;
|
|
380
|
+
} | {
|
|
381
|
+
/**
|
|
382
|
+
* The route path comes from where the file sits, which is how
|
|
383
|
+
* Next.js and React Router describe their routes. The pack
|
|
384
|
+
* spells out its own convention here, since the adapter knows
|
|
385
|
+
* about files and the pack knows what the framework does with
|
|
386
|
+
* their names.
|
|
387
|
+
*
|
|
388
|
+
* `app/api/orders/[id]/route.ts` under `{ root: "app",
|
|
389
|
+
* dropBasenames: ["route"], dynamic: "brackets" }` comes out as
|
|
390
|
+
* `/api/orders/{id}`, which pairs with an Express provider
|
|
391
|
+
* writing `/api/orders/:id`.
|
|
392
|
+
*/
|
|
377
393
|
type: "fromFilename";
|
|
394
|
+
/**
|
|
395
|
+
* Where a route path starts. The directories below it become
|
|
396
|
+
* the path; everything above it belongs to the project layout
|
|
397
|
+
* and is dropped.
|
|
398
|
+
*/
|
|
399
|
+
root: string;
|
|
400
|
+
/**
|
|
401
|
+
* Filenames that say what a file is rather than adding a
|
|
402
|
+
* segment: `route`, `page`, `index`, `_index`.
|
|
403
|
+
*/
|
|
404
|
+
dropBasenames?: string[];
|
|
405
|
+
/**
|
|
406
|
+
* How the framework writes a parameter in a filename. Next.js
|
|
407
|
+
* uses `[id]`, React Router uses `$id`.
|
|
408
|
+
*/
|
|
409
|
+
dynamic?: "brackets" | "dollarPrefix";
|
|
410
|
+
/**
|
|
411
|
+
* Whether a directory in parentheses organises files without
|
|
412
|
+
* appearing in the URL, as `app/(marketing)/about` does.
|
|
413
|
+
*/
|
|
414
|
+
dropParenthesized?: boolean;
|
|
415
|
+
/**
|
|
416
|
+
* Whether one filename holds the whole path with dots between
|
|
417
|
+
* the segments, as `routes/orders.$id.tsx` does.
|
|
418
|
+
*/
|
|
419
|
+
flat?: boolean;
|
|
378
420
|
} | {
|
|
379
421
|
type: "fromContract";
|
|
380
422
|
} | {
|
|
@@ -487,6 +529,10 @@ interface TerminalExtraction {
|
|
|
487
529
|
} | {
|
|
488
530
|
from: "constructor";
|
|
489
531
|
codes: Record<string, number>;
|
|
532
|
+
} | {
|
|
533
|
+
from: "argumentProperty";
|
|
534
|
+
position: number;
|
|
535
|
+
name: string;
|
|
490
536
|
} | {
|
|
491
537
|
from: "argumentConstructor";
|
|
492
538
|
position: number;
|
|
@@ -619,6 +665,23 @@ interface ResponsePropertyMapping {
|
|
|
619
665
|
/** What the value semantically represents */
|
|
620
666
|
semantics: ResponsePropertyMeaning;
|
|
621
667
|
}
|
|
668
|
+
/**
|
|
669
|
+
* A library wrapper whose result is the function it was handed. The
|
|
670
|
+
* adapter works this out on its own for factories declared in the
|
|
671
|
+
* project by reading their bodies. A library's body is not readable,
|
|
672
|
+
* so the pack states it.
|
|
673
|
+
*/
|
|
674
|
+
interface TransparentWrapper {
|
|
675
|
+
/** Callee text as written, e.g. "Sentry.wrapHandler". */
|
|
676
|
+
callee: string;
|
|
677
|
+
/** Which argument holds the wrapped function. */
|
|
678
|
+
argument: number;
|
|
679
|
+
/**
|
|
680
|
+
* The module the callee has to have been imported from. Without it a
|
|
681
|
+
* local object spelled the same way would be taken for the library.
|
|
682
|
+
*/
|
|
683
|
+
module: string;
|
|
684
|
+
}
|
|
622
685
|
interface PatternPack {
|
|
623
686
|
name: string;
|
|
624
687
|
/**
|
|
@@ -792,6 +855,17 @@ interface PatternPack {
|
|
|
792
855
|
* available without an import).
|
|
793
856
|
*/
|
|
794
857
|
requiresImport?: string[];
|
|
858
|
+
/**
|
|
859
|
+
* Library wrappers whose result is the wrapped function. The adapter
|
|
860
|
+
* derives this automatically for project-local factories by reading
|
|
861
|
+
* their bodies; a library wrapper's body is not readable, so the
|
|
862
|
+
* pack states the judgment: a call to `callee` resolves to its
|
|
863
|
+
* `argument`-th argument.
|
|
864
|
+
*
|
|
865
|
+
* `callee` matches the call expression text as written, e.g.
|
|
866
|
+
* `"Sentry.wrapHandler"`.
|
|
867
|
+
*/
|
|
868
|
+
transparentWrappers?: TransparentWrapper[];
|
|
795
869
|
/**
|
|
796
870
|
* Per-property-access recognizers — sister to
|
|
797
871
|
* `invocationRecognizers` but firing on `PropertyAccessExpression`
|
|
@@ -884,6 +958,29 @@ interface DiscoveredCustomUnit {
|
|
|
884
958
|
method: string;
|
|
885
959
|
path: string;
|
|
886
960
|
};
|
|
961
|
+
/**
|
|
962
|
+
* GraphQL field identity for units a callback discovers against an
|
|
963
|
+
* external manifest rather than an in-code resolver map. AppSync
|
|
964
|
+
* routes a field to a Lambda in the deploy template, so the field is
|
|
965
|
+
* the boundary that code serves. When set, the adapter builds a
|
|
966
|
+
* `graphql-resolver` binding from `(typeName, fieldName)`, which
|
|
967
|
+
* pairs with the operations a client sends.
|
|
968
|
+
*/
|
|
969
|
+
resolverInfo?: {
|
|
970
|
+
typeName: string;
|
|
971
|
+
fieldName: string;
|
|
972
|
+
};
|
|
973
|
+
/**
|
|
974
|
+
* Message-bus channel identity for consumer units a callback
|
|
975
|
+
* discovers against a subject the code itself names (a handler
|
|
976
|
+
* factory whose config carries the expected subject). When set, the
|
|
977
|
+
* adapter builds a `message-bus` binding from `(messageBus, channel)`,
|
|
978
|
+
* which pairs with producers sending on the same channel.
|
|
979
|
+
*/
|
|
980
|
+
channelInfo?: {
|
|
981
|
+
messageBus: MessageBusSemantics["messageBus"];
|
|
982
|
+
channel: string;
|
|
983
|
+
};
|
|
887
984
|
/**
|
|
888
985
|
* Metadata merged onto the resulting summary's `metadata` field.
|
|
889
986
|
*/
|
|
@@ -1188,6 +1285,13 @@ interface RawCodeStructure {
|
|
|
1188
1285
|
boundaryBinding: BoundaryBinding | null;
|
|
1189
1286
|
parameters: RawParameter[];
|
|
1190
1287
|
branches: RawBranch[];
|
|
1288
|
+
/**
|
|
1289
|
+
* Return statements in the body that none of the pack's terminals
|
|
1290
|
+
* matched. A handler shaped in a way the pack does not describe still
|
|
1291
|
+
* returns something, and saying nothing about it reads the same as
|
|
1292
|
+
* saying it does nothing.
|
|
1293
|
+
*/
|
|
1294
|
+
unmatchedReturns?: number;
|
|
1191
1295
|
dependencyCalls: RawDependencyCall[];
|
|
1192
1296
|
declaredContract: RawDeclaredContract | null;
|
|
1193
1297
|
/**
|
|
@@ -1266,4 +1370,4 @@ declare function terminalToOutput(terminal: RawTerminal): Output;
|
|
|
1266
1370
|
declare function effectToIR(effect: RawEffect): Effect;
|
|
1267
1371
|
declare function paramToInput(param: RawParameter): Input;
|
|
1268
1372
|
|
|
1269
|
-
export { type AccessRecognizer, type BindingExtraction, type ContractPattern, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type ExtractorOptions, type InputMappingPattern, type InvocationRecognizer, type PatternPack, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type ResponsePropertyMapping, type ResponsePropertyMeaning, type TerminalExtraction, type TerminalMatch, type TerminalPattern, assembleSummary, assessConfidence, detectGaps, effectToIR, httpRouteDiscovery, makeTransitionId, paramToInput, terminalToOutput };
|
|
1373
|
+
export { type AccessRecognizer, type BindingExtraction, type ContractPattern, type DiscoveredCustomUnit, type DiscoveredSubUnit, type DiscoveredSubUnitParent, type DiscoveryMatch, type DiscoveryPattern, type EffectArg, type ExtractorOptions, type InputMappingPattern, type InvocationRecognizer, type PatternPack, type RawBranch, type RawCodeStructure, type RawCondition, type RawDeclaredContract, type RawDependencyCall, type RawEffect, type RawParameter, type RawTerminal, type ResponsePropertyMapping, type ResponsePropertyMeaning, type TerminalExtraction, type TerminalMatch, type TerminalPattern, type TransparentWrapper, assembleSummary, assessConfidence, detectGaps, effectToIR, httpRouteDiscovery, makeTransitionId, paramToInput, terminalToOutput };
|
package/dist/index.js
CHANGED
|
@@ -119,6 +119,17 @@ function detectGaps(raw, transitions, options) {
|
|
|
119
119
|
return [];
|
|
120
120
|
}
|
|
121
121
|
const gaps = [];
|
|
122
|
+
if (raw.unmatchedReturns !== void 0 && raw.unmatchedReturns > 0) {
|
|
123
|
+
const count = raw.unmatchedReturns;
|
|
124
|
+
gaps.push({
|
|
125
|
+
// Not a contract violation: the handler may be answering
|
|
126
|
+
// correctly, in a shape nobody taught the pack.
|
|
127
|
+
type: "unreadOutcome",
|
|
128
|
+
conditions: [],
|
|
129
|
+
consequence: "unknown",
|
|
130
|
+
description: count === 1 ? "One return in this function matches none of the terminal shapes this pack looks for, so what it produces is not described here" : `${count} returns in this function match none of the terminal shapes this pack looks for, so what they produce is not described here`
|
|
131
|
+
});
|
|
132
|
+
}
|
|
122
133
|
if (raw.declaredContract) {
|
|
123
134
|
const producedStatuses = new Set(
|
|
124
135
|
transitions.flatMap((t) => {
|
|
@@ -159,6 +170,9 @@ function detectGaps(raw, transitions, options) {
|
|
|
159
170
|
return gaps;
|
|
160
171
|
}
|
|
161
172
|
function assessConfidence(raw) {
|
|
173
|
+
if ((raw.unmatchedReturns ?? 0) > 0) {
|
|
174
|
+
return { source: "inferred_static", level: "low" };
|
|
175
|
+
}
|
|
162
176
|
let total = 0;
|
|
163
177
|
let opaque = 0;
|
|
164
178
|
for (const branch of raw.branches) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/extractor",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Framework-agnostic extraction pipeline that turns raw extractions into suss behavioral summaries.",
|
|
6
6
|
"keywords": [
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"typecheck": "tsc --noEmit"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@suss/behavioral-ir": "0.0
|
|
48
|
+
"@suss/behavioral-ir": "0.1.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"tsup": "*",
|