@suss/checker-intent 0.33.1 → 0.34.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/dist/index.d.cts CHANGED
@@ -1,8 +1,87 @@
1
- import { BehavioralSummary } from '@suss/behavioral-ir';
2
- import { IntentFinding, IntentSummary } from '@suss/intent-ir';
1
+ import { BehavioralSummary, ReceiverClass, TypeShape, ProvenanceEntry, BoundaryGuard, Interaction, Transition, Deployment } from '@suss/behavioral-ir';
2
+ import { CoveringTestSpelling, IntentFinding, IntentSummary, IntentEffect, IntentOutcome } from '@suss/intent-ir';
3
3
  export { IntentFinding } from '@suss/intent-ir';
4
- import { SuppressionRule, Semantics } from '@suss/ir-core';
4
+ import { Relation, BoundaryBinding, SuppressionRule, Semantics } from '@suss/ir-core';
5
+ import { CallFacts, ReachTarget } from '@suss/checker';
5
6
 
7
+ /**
8
+ * Checks the tests a PRD scenario lists under `coveredBy`: that each
9
+ * one exists, that it runs, and that its calls reach what the scenario
10
+ * is about without going through a mock.
11
+ *
12
+ * Turning a spelled test or subject into summaries is the caller's
13
+ * job, through the resolver its commands already use, and arrives here
14
+ * as a `CoveringTestLookup`. The reach question is asked once for every
15
+ * test, through the call facts in @suss/checker, rather than once per
16
+ * scenario. It is asked a second time without honouring mocks only for
17
+ * the tests that missed, to tell a test that never reaches its subject
18
+ * from one that reaches it only through something it replaced.
19
+ */
20
+
21
+ type FoundTest = {
22
+ found: true;
23
+ unit: BehavioralSummary;
24
+ } | {
25
+ found: false;
26
+ message: string;
27
+ };
28
+ type FoundSubject = {
29
+ found: true;
30
+ target: ReachTarget;
31
+ label: string;
32
+ /**
33
+ * The classes the subject is, when it was spelled as a class or as
34
+ * a file a class is written in. A call a test sends to one of them
35
+ * reaches the subject. Empty for a single unit or a boundary.
36
+ */
37
+ classes?: ReadonlyArray<ReceiverClass>;
38
+ } | {
39
+ found: false;
40
+ message: string;
41
+ };
42
+ /** How the check finds the summaries a PRD's spellings mean. */
43
+ interface CoveringTestLookup {
44
+ /** The call facts over the summaries being checked. */
45
+ facts: CallFacts;
46
+ /** The test unit a `coveredBy` entry means, or why there is none. */
47
+ test(spelled: CoveringTestSpelling): FoundTest;
48
+ /** What a boundary or unit spelling means, the way `suss ask` reads it. */
49
+ subject(spelledAs: string): FoundSubject;
50
+ }
51
+
52
+ /**
53
+ * Compares the intent a team wrote with the summaries derived from code.
54
+ *
55
+ * This is kept apart from @suss/checker because the inputs and outputs
56
+ * differ: one side is an `IntentSummary`, and a finding says the code
57
+ * does not do what the team declared. It takes only the call facts from
58
+ * @suss/checker, to see whether a test reaches what a scenario is about.
59
+ *
60
+ * A boundary intent is paired with the code at its boundary key. A PRD
61
+ * has its scenario links resolved and its covering tests checked. Which
62
+ * severity each finding gets, and why a finding against inferred intent
63
+ * drops a level, is in the package design notes.
64
+ */
65
+
66
+ /** A code transition's terminal, reduced to the dimensions intent compares. */
67
+ interface CodeOutcome {
68
+ kind: "response" | "return" | "throw" | "exit";
69
+ /** A response's status, or the code an `exit` output ends the process with. */
70
+ status: number | null;
71
+ body: TypeShape | null;
72
+ errorType: string | null;
73
+ /**
74
+ * The literal a return hands back when the unit's return becomes the
75
+ * process's exit code, so `exits: 1` can match `return 1` there.
76
+ */
77
+ exitCode: number | null;
78
+ /** What the transition that ends this way did at other boundaries. */
79
+ effects: CodeEffect[];
80
+ /** The boundaries the branch leading here turned on. */
81
+ turnsOn: BoundaryGuard[];
82
+ /** The line the transition starts on, for a finding about one transition. */
83
+ line: number;
84
+ }
6
85
  /** A boundary intent that was paired and compared against code. */
7
86
  interface CheckedBoundaryIntent {
8
87
  kind: "boundary";
@@ -22,34 +101,46 @@ interface CheckedPrd {
22
101
  scenarios: number;
23
102
  /** Scenarios whose every link resolved to a declared outcome (had >=1 link). */
24
103
  resolved: number;
25
- /** Scenarios carrying no structured link (a valid pending state). */
104
+ /**
105
+ * Scenarios whose every covering test exists, runs and reaches its
106
+ * subject. Zero when the check was given no way to look tests up.
107
+ */
108
+ covered: number;
109
+ /** Scenarios with neither a link nor a covering test. */
26
110
  unlinked: number;
27
111
  }
28
112
  /**
29
113
  * A declared intent that was compared, either a boundary intent paired
30
114
  * against code or a PRD whose scenario links were resolved. Discriminated
31
- * on `kind` so callers render both without a parallel structure; when a
32
- * third doc kind (workflow) ships it extends this union.
115
+ * on `kind`, so a caller renders both from one list.
33
116
  */
34
117
  type CheckedIntent = CheckedBoundaryIntent | CheckedPrd;
35
- /** An intent doc that was loaded but not compared, and why. */
118
+ /**
119
+ * Intent that was loaded and not compared, and why. `unkeyable` is a
120
+ * whole document whose boundary cannot be paired. `unreadValue` is one
121
+ * `from` source the code gave no answer to compare against.
122
+ * `unfollowedCall` is a covering test that never reaches its subject
123
+ * through the calls suss followed, and makes calls suss did not follow.
124
+ */
36
125
  interface UncheckedIntent {
37
126
  /** The intent doc's `name` (boundary) or `title` (prd). */
38
127
  intent: string;
39
- reason: "unkeyable";
128
+ reason: "unkeyable" | "unreadValue" | "unfollowedCall";
129
+ /** The outcome the claim is on, for a claim narrower than the document. */
130
+ outcomeId?: string;
131
+ /** The scenario the claim is on, by its title or its position, for a covering test. */
132
+ scenario?: string;
133
+ /** The covering test, as the scenario lists it. */
134
+ coveredBy?: string;
40
135
  /** Human-readable explanation, render-ready. */
41
136
  detail: string;
42
137
  }
43
138
  /**
44
- * The full result of an intent-agreement pass. Mirrors the behavioural
45
- * checker's shape philosophy (`checkAll` → findings + pairs +
46
- * unmatched): findings are what to fix; checked / unchecked are the
47
- * coverage accounting: which declared intent was actually compared.
48
- * Callers render or gate on this without knowing which doc kinds the
49
- * checker compared: boundary intents and PRDs both land in `checked`
50
- * (a discriminated union). `unchecked` is reserved for intent that
51
- * couldn't be compared at all (an unkeyable boundary), never silently
52
- * dropped.
139
+ * The result of an intent-agreement pass, laid out like the behavioural
140
+ * checker's `checkAll` result. `findings` are what to fix. `checked`
141
+ * lists every declared intent that was compared, boundary intents and
142
+ * PRDs alike. `unchecked` lists intent that could not be compared at
143
+ * all, such as an unkeyable boundary, so nothing is dropped silently.
53
144
  */
54
145
  interface CheckIntentResult {
55
146
  findings: IntentFinding[];
@@ -59,33 +150,82 @@ interface CheckIntentResult {
59
150
  /**
60
151
  * Compare every loaded intent doc against what's known. Boundary intents
61
152
  * pair against the code summaries sharing their boundary key; PRDs resolve
62
- * each scenario's link against the loaded boundary intents (coverage). An
63
- * intent that can't be compared (an unkeyable boundary) is reported in
64
- * `unchecked`, never silently dropped.
153
+ * each scenario's link against the loaded boundary intents, and check the
154
+ * tests it lists under `coveredBy` through `tests`. Without `tests`, those
155
+ * scenarios count as backed and their tests go unchecked. An unkeyable
156
+ * boundary is reported in `unchecked`, never silently dropped.
65
157
  *
66
158
  * Findings against `source: "inferred"` intent are downgraded one severity
67
159
  * level: the intent describes what the code did when the inference ran, so
68
160
  * a divergence is most likely a code change since, not an authoring error.
69
161
  * Curation (`"inferred, curated"`) restores full severity.
70
162
  */
71
- declare function checkIntentAgreement(intents: IntentSummary[], code: BehavioralSummary[]): CheckIntentResult;
163
+ declare function checkIntentAgreement(intents: IntentSummary[], code: BehavioralSummary[], tests?: CoveringTestLookup): CheckIntentResult;
72
164
  /**
73
- * Apply .sussignore rules to intent findings, using the shared
74
- * pipeline from @suss/ir-core (same rule shape and semantics as the
75
- * behavioural checker's `applySuppressions`). Rule discriminators map
76
- * as: `kind` → the intent finding kind; `boundary` → the finding's
77
- * boundary key (exact for `fn:` / `gql:` keys, path-normalized for
78
- * REST). A rule that specifies `consumer` or `provider` never matches
79
- * an intent finding: it has neither side.
165
+ * Apply .sussignore rules to intent findings, through the same pipeline
166
+ * in @suss/ir-core that the behavioural checker's `applySuppressions`
167
+ * uses. A rule's `kind` matches the finding kind, and its `boundary`
168
+ * matches the finding's boundary key, exactly for `fn:` and `gql:` keys
169
+ * and path-normalized for REST. A rule's `scenario` matches the title
170
+ * of the PRD scenario the finding is about. A rule that gives
171
+ * `consumer` or `provider` never matches, since an intent finding has
172
+ * neither side.
80
173
  */
81
174
  declare function applyIntentSuppressions(findings: IntentFinding[], rules: SuppressionRule[], opts?: {
82
175
  keepHidden?: boolean;
83
176
  }): IntentFinding[];
177
+ /**
178
+ * Whether an effect the code makes is the one the intent declared. The
179
+ * boundary is resolved with `namesBoundary`, the matcher that resolves
180
+ * what somebody types at `suss ask`, so a document and a question that
181
+ * spell a store the same way pick out the same one.
182
+ */
183
+ declare function effectMatches(declared: IntentEffect, made: CodeEffect): boolean;
184
+ /** How a transition ends, in the terms intent states an ending in. */
185
+ type CodeEnding = Pick<CodeOutcome, "kind" | "status" | "body" | "errorType" | "exitCode">;
186
+ /**
187
+ * How a transition ends, or null for an ending intent has no word for,
188
+ * such as a render. A status the code computes has no literal, so it
189
+ * comes back null and matches no declared status. `returnIsExitCode`
190
+ * says the unit's return becomes the process's exit code.
191
+ */
192
+ declare function endingOf(t: Transition, returnIsExitCode?: boolean): CodeEnding | null;
193
+ /** One verb and one boundary this transition reaches. */
194
+ interface CodeEffect {
195
+ does: Relation;
196
+ binding: BoundaryBinding;
197
+ /** How a report writes that boundary, for a message about it. */
198
+ label: string;
199
+ /** The columns the access states, empty when it states none. */
200
+ fields: string[];
201
+ /** What the access picks the item out by, empty when it states none. */
202
+ by: string[];
203
+ /** The shape of what a write put out, when the code says. */
204
+ payload?: TypeShape;
205
+ /** Where the values in this effect's slots came from, when the summary says. */
206
+ slots?: ProvenanceEntry[];
207
+ /** The line the transition that has this effect starts on. */
208
+ line?: number;
209
+ }
210
+ /** Every verb and boundary the transition reaches, grounded against the deployment. */
211
+ declare function codeEffectsOf(t: Transition, deployment: Deployment): CodeEffect[];
212
+ /**
213
+ * The fields an access states: a storage access's columns and key, or
214
+ * the variable a config read takes, which is a field of the runtime's
215
+ * contract. Nothing for any other class.
216
+ */
217
+ declare function accessDetail(interaction: Interaction): {
218
+ fields: string[];
219
+ by: string[];
220
+ payload?: TypeShape;
221
+ };
222
+ /** Whether the code ends the way the intent says. The body is compared elsewhere. */
223
+ declare function outcomeMatches(intent: Pick<IntentOutcome, "kind" | "status" | "errorType">, code: CodeEnding): boolean;
84
224
  /**
85
225
  * What each protocol needs before an intent doc written against one of
86
226
  * its boundaries can be paired, in the doc author's terms. The
87
- * drafter says the same thing about a boundary it could not write.
227
+ * drafter gives the same reason for a boundary it could not write.
88
228
  */
89
229
  declare function whatWouldKeyIt(protocol: Semantics["name"]): string;
90
230
 
91
- export { type CheckIntentResult, type CheckedBoundaryIntent, type CheckedIntent, type CheckedPrd, type UncheckedIntent, applyIntentSuppressions, checkIntentAgreement, whatWouldKeyIt };
231
+ export { type CheckIntentResult, type CheckedBoundaryIntent, type CheckedIntent, type CheckedPrd, type CodeEffect, type CodeEnding, type CoveringTestLookup, type FoundSubject, type FoundTest, type UncheckedIntent, accessDetail, applyIntentSuppressions, checkIntentAgreement, codeEffectsOf, effectMatches, endingOf, outcomeMatches, whatWouldKeyIt };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,87 @@
1
- import { BehavioralSummary } from '@suss/behavioral-ir';
2
- import { IntentFinding, IntentSummary } from '@suss/intent-ir';
1
+ import { BehavioralSummary, ReceiverClass, TypeShape, ProvenanceEntry, BoundaryGuard, Interaction, Transition, Deployment } from '@suss/behavioral-ir';
2
+ import { CoveringTestSpelling, IntentFinding, IntentSummary, IntentEffect, IntentOutcome } from '@suss/intent-ir';
3
3
  export { IntentFinding } from '@suss/intent-ir';
4
- import { SuppressionRule, Semantics } from '@suss/ir-core';
4
+ import { Relation, BoundaryBinding, SuppressionRule, Semantics } from '@suss/ir-core';
5
+ import { CallFacts, ReachTarget } from '@suss/checker';
5
6
 
7
+ /**
8
+ * Checks the tests a PRD scenario lists under `coveredBy`: that each
9
+ * one exists, that it runs, and that its calls reach what the scenario
10
+ * is about without going through a mock.
11
+ *
12
+ * Turning a spelled test or subject into summaries is the caller's
13
+ * job, through the resolver its commands already use, and arrives here
14
+ * as a `CoveringTestLookup`. The reach question is asked once for every
15
+ * test, through the call facts in @suss/checker, rather than once per
16
+ * scenario. It is asked a second time without honouring mocks only for
17
+ * the tests that missed, to tell a test that never reaches its subject
18
+ * from one that reaches it only through something it replaced.
19
+ */
20
+
21
+ type FoundTest = {
22
+ found: true;
23
+ unit: BehavioralSummary;
24
+ } | {
25
+ found: false;
26
+ message: string;
27
+ };
28
+ type FoundSubject = {
29
+ found: true;
30
+ target: ReachTarget;
31
+ label: string;
32
+ /**
33
+ * The classes the subject is, when it was spelled as a class or as
34
+ * a file a class is written in. A call a test sends to one of them
35
+ * reaches the subject. Empty for a single unit or a boundary.
36
+ */
37
+ classes?: ReadonlyArray<ReceiverClass>;
38
+ } | {
39
+ found: false;
40
+ message: string;
41
+ };
42
+ /** How the check finds the summaries a PRD's spellings mean. */
43
+ interface CoveringTestLookup {
44
+ /** The call facts over the summaries being checked. */
45
+ facts: CallFacts;
46
+ /** The test unit a `coveredBy` entry means, or why there is none. */
47
+ test(spelled: CoveringTestSpelling): FoundTest;
48
+ /** What a boundary or unit spelling means, the way `suss ask` reads it. */
49
+ subject(spelledAs: string): FoundSubject;
50
+ }
51
+
52
+ /**
53
+ * Compares the intent a team wrote with the summaries derived from code.
54
+ *
55
+ * This is kept apart from @suss/checker because the inputs and outputs
56
+ * differ: one side is an `IntentSummary`, and a finding says the code
57
+ * does not do what the team declared. It takes only the call facts from
58
+ * @suss/checker, to see whether a test reaches what a scenario is about.
59
+ *
60
+ * A boundary intent is paired with the code at its boundary key. A PRD
61
+ * has its scenario links resolved and its covering tests checked. Which
62
+ * severity each finding gets, and why a finding against inferred intent
63
+ * drops a level, is in the package design notes.
64
+ */
65
+
66
+ /** A code transition's terminal, reduced to the dimensions intent compares. */
67
+ interface CodeOutcome {
68
+ kind: "response" | "return" | "throw" | "exit";
69
+ /** A response's status, or the code an `exit` output ends the process with. */
70
+ status: number | null;
71
+ body: TypeShape | null;
72
+ errorType: string | null;
73
+ /**
74
+ * The literal a return hands back when the unit's return becomes the
75
+ * process's exit code, so `exits: 1` can match `return 1` there.
76
+ */
77
+ exitCode: number | null;
78
+ /** What the transition that ends this way did at other boundaries. */
79
+ effects: CodeEffect[];
80
+ /** The boundaries the branch leading here turned on. */
81
+ turnsOn: BoundaryGuard[];
82
+ /** The line the transition starts on, for a finding about one transition. */
83
+ line: number;
84
+ }
6
85
  /** A boundary intent that was paired and compared against code. */
7
86
  interface CheckedBoundaryIntent {
8
87
  kind: "boundary";
@@ -22,34 +101,46 @@ interface CheckedPrd {
22
101
  scenarios: number;
23
102
  /** Scenarios whose every link resolved to a declared outcome (had >=1 link). */
24
103
  resolved: number;
25
- /** Scenarios carrying no structured link (a valid pending state). */
104
+ /**
105
+ * Scenarios whose every covering test exists, runs and reaches its
106
+ * subject. Zero when the check was given no way to look tests up.
107
+ */
108
+ covered: number;
109
+ /** Scenarios with neither a link nor a covering test. */
26
110
  unlinked: number;
27
111
  }
28
112
  /**
29
113
  * A declared intent that was compared, either a boundary intent paired
30
114
  * against code or a PRD whose scenario links were resolved. Discriminated
31
- * on `kind` so callers render both without a parallel structure; when a
32
- * third doc kind (workflow) ships it extends this union.
115
+ * on `kind`, so a caller renders both from one list.
33
116
  */
34
117
  type CheckedIntent = CheckedBoundaryIntent | CheckedPrd;
35
- /** An intent doc that was loaded but not compared, and why. */
118
+ /**
119
+ * Intent that was loaded and not compared, and why. `unkeyable` is a
120
+ * whole document whose boundary cannot be paired. `unreadValue` is one
121
+ * `from` source the code gave no answer to compare against.
122
+ * `unfollowedCall` is a covering test that never reaches its subject
123
+ * through the calls suss followed, and makes calls suss did not follow.
124
+ */
36
125
  interface UncheckedIntent {
37
126
  /** The intent doc's `name` (boundary) or `title` (prd). */
38
127
  intent: string;
39
- reason: "unkeyable";
128
+ reason: "unkeyable" | "unreadValue" | "unfollowedCall";
129
+ /** The outcome the claim is on, for a claim narrower than the document. */
130
+ outcomeId?: string;
131
+ /** The scenario the claim is on, by its title or its position, for a covering test. */
132
+ scenario?: string;
133
+ /** The covering test, as the scenario lists it. */
134
+ coveredBy?: string;
40
135
  /** Human-readable explanation, render-ready. */
41
136
  detail: string;
42
137
  }
43
138
  /**
44
- * The full result of an intent-agreement pass. Mirrors the behavioural
45
- * checker's shape philosophy (`checkAll` → findings + pairs +
46
- * unmatched): findings are what to fix; checked / unchecked are the
47
- * coverage accounting: which declared intent was actually compared.
48
- * Callers render or gate on this without knowing which doc kinds the
49
- * checker compared: boundary intents and PRDs both land in `checked`
50
- * (a discriminated union). `unchecked` is reserved for intent that
51
- * couldn't be compared at all (an unkeyable boundary), never silently
52
- * dropped.
139
+ * The result of an intent-agreement pass, laid out like the behavioural
140
+ * checker's `checkAll` result. `findings` are what to fix. `checked`
141
+ * lists every declared intent that was compared, boundary intents and
142
+ * PRDs alike. `unchecked` lists intent that could not be compared at
143
+ * all, such as an unkeyable boundary, so nothing is dropped silently.
53
144
  */
54
145
  interface CheckIntentResult {
55
146
  findings: IntentFinding[];
@@ -59,33 +150,82 @@ interface CheckIntentResult {
59
150
  /**
60
151
  * Compare every loaded intent doc against what's known. Boundary intents
61
152
  * pair against the code summaries sharing their boundary key; PRDs resolve
62
- * each scenario's link against the loaded boundary intents (coverage). An
63
- * intent that can't be compared (an unkeyable boundary) is reported in
64
- * `unchecked`, never silently dropped.
153
+ * each scenario's link against the loaded boundary intents, and check the
154
+ * tests it lists under `coveredBy` through `tests`. Without `tests`, those
155
+ * scenarios count as backed and their tests go unchecked. An unkeyable
156
+ * boundary is reported in `unchecked`, never silently dropped.
65
157
  *
66
158
  * Findings against `source: "inferred"` intent are downgraded one severity
67
159
  * level: the intent describes what the code did when the inference ran, so
68
160
  * a divergence is most likely a code change since, not an authoring error.
69
161
  * Curation (`"inferred, curated"`) restores full severity.
70
162
  */
71
- declare function checkIntentAgreement(intents: IntentSummary[], code: BehavioralSummary[]): CheckIntentResult;
163
+ declare function checkIntentAgreement(intents: IntentSummary[], code: BehavioralSummary[], tests?: CoveringTestLookup): CheckIntentResult;
72
164
  /**
73
- * Apply .sussignore rules to intent findings, using the shared
74
- * pipeline from @suss/ir-core (same rule shape and semantics as the
75
- * behavioural checker's `applySuppressions`). Rule discriminators map
76
- * as: `kind` → the intent finding kind; `boundary` → the finding's
77
- * boundary key (exact for `fn:` / `gql:` keys, path-normalized for
78
- * REST). A rule that specifies `consumer` or `provider` never matches
79
- * an intent finding: it has neither side.
165
+ * Apply .sussignore rules to intent findings, through the same pipeline
166
+ * in @suss/ir-core that the behavioural checker's `applySuppressions`
167
+ * uses. A rule's `kind` matches the finding kind, and its `boundary`
168
+ * matches the finding's boundary key, exactly for `fn:` and `gql:` keys
169
+ * and path-normalized for REST. A rule's `scenario` matches the title
170
+ * of the PRD scenario the finding is about. A rule that gives
171
+ * `consumer` or `provider` never matches, since an intent finding has
172
+ * neither side.
80
173
  */
81
174
  declare function applyIntentSuppressions(findings: IntentFinding[], rules: SuppressionRule[], opts?: {
82
175
  keepHidden?: boolean;
83
176
  }): IntentFinding[];
177
+ /**
178
+ * Whether an effect the code makes is the one the intent declared. The
179
+ * boundary is resolved with `namesBoundary`, the matcher that resolves
180
+ * what somebody types at `suss ask`, so a document and a question that
181
+ * spell a store the same way pick out the same one.
182
+ */
183
+ declare function effectMatches(declared: IntentEffect, made: CodeEffect): boolean;
184
+ /** How a transition ends, in the terms intent states an ending in. */
185
+ type CodeEnding = Pick<CodeOutcome, "kind" | "status" | "body" | "errorType" | "exitCode">;
186
+ /**
187
+ * How a transition ends, or null for an ending intent has no word for,
188
+ * such as a render. A status the code computes has no literal, so it
189
+ * comes back null and matches no declared status. `returnIsExitCode`
190
+ * says the unit's return becomes the process's exit code.
191
+ */
192
+ declare function endingOf(t: Transition, returnIsExitCode?: boolean): CodeEnding | null;
193
+ /** One verb and one boundary this transition reaches. */
194
+ interface CodeEffect {
195
+ does: Relation;
196
+ binding: BoundaryBinding;
197
+ /** How a report writes that boundary, for a message about it. */
198
+ label: string;
199
+ /** The columns the access states, empty when it states none. */
200
+ fields: string[];
201
+ /** What the access picks the item out by, empty when it states none. */
202
+ by: string[];
203
+ /** The shape of what a write put out, when the code says. */
204
+ payload?: TypeShape;
205
+ /** Where the values in this effect's slots came from, when the summary says. */
206
+ slots?: ProvenanceEntry[];
207
+ /** The line the transition that has this effect starts on. */
208
+ line?: number;
209
+ }
210
+ /** Every verb and boundary the transition reaches, grounded against the deployment. */
211
+ declare function codeEffectsOf(t: Transition, deployment: Deployment): CodeEffect[];
212
+ /**
213
+ * The fields an access states: a storage access's columns and key, or
214
+ * the variable a config read takes, which is a field of the runtime's
215
+ * contract. Nothing for any other class.
216
+ */
217
+ declare function accessDetail(interaction: Interaction): {
218
+ fields: string[];
219
+ by: string[];
220
+ payload?: TypeShape;
221
+ };
222
+ /** Whether the code ends the way the intent says. The body is compared elsewhere. */
223
+ declare function outcomeMatches(intent: Pick<IntentOutcome, "kind" | "status" | "errorType">, code: CodeEnding): boolean;
84
224
  /**
85
225
  * What each protocol needs before an intent doc written against one of
86
226
  * its boundaries can be paired, in the doc author's terms. The
87
- * drafter says the same thing about a boundary it could not write.
227
+ * drafter gives the same reason for a boundary it could not write.
88
228
  */
89
229
  declare function whatWouldKeyIt(protocol: Semantics["name"]): string;
90
230
 
91
- export { type CheckIntentResult, type CheckedBoundaryIntent, type CheckedIntent, type CheckedPrd, type UncheckedIntent, applyIntentSuppressions, checkIntentAgreement, whatWouldKeyIt };
231
+ export { type CheckIntentResult, type CheckedBoundaryIntent, type CheckedIntent, type CheckedPrd, type CodeEffect, type CodeEnding, type CoveringTestLookup, type FoundSubject, type FoundTest, type UncheckedIntent, accessDetail, applyIntentSuppressions, checkIntentAgreement, codeEffectsOf, effectMatches, endingOf, outcomeMatches, whatWouldKeyIt };