@orkestrel/rater 0.0.1 → 0.0.3
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 +19 -27
- package/dist/src/core/index.cjs +238 -1292
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +469 -1092
- package/dist/src/core/index.d.ts +469 -1092
- package/dist/src/core/index.js +237 -1235
- package/dist/src/core/index.js.map +1 -1
- package/package.json +5 -5
package/dist/src/core/index.d.ts
CHANGED
|
@@ -5,1167 +5,544 @@ import { Comparison } from '@orkestrel/reason';
|
|
|
5
5
|
import { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
6
6
|
import { EmitterHooks } from '@orkestrel/emitter';
|
|
7
7
|
import { EmitterInterface } from '@orkestrel/emitter';
|
|
8
|
-
import { EvaluatorInterface } from '@orkestrel/reason';
|
|
9
|
-
import { Expression } from '@orkestrel/reason';
|
|
10
8
|
import { Factor } from '@orkestrel/reason';
|
|
11
9
|
import { FactorResult } from '@orkestrel/reason';
|
|
12
10
|
import { FieldPath } from '@orkestrel/contract';
|
|
13
11
|
import { GroupResult } from '@orkestrel/reason';
|
|
14
12
|
import { Guard } from '@orkestrel/contract';
|
|
15
13
|
import { JSONValue } from '@orkestrel/contract';
|
|
16
|
-
import { LogicalDefinition } from '@orkestrel/reason';
|
|
17
|
-
import { LogicalResult } from '@orkestrel/reason';
|
|
18
14
|
import { QuantitativeDefinition } from '@orkestrel/reason';
|
|
19
15
|
import { QuantitativeResult } from '@orkestrel/reason';
|
|
20
16
|
import { ReasonInterface } from '@orkestrel/reason';
|
|
21
|
-
import { Rule } from '@orkestrel/reason';
|
|
22
17
|
import { Subject } from '@orkestrel/reason';
|
|
23
18
|
|
|
24
|
-
/**
|
|
25
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Build evidence rows from a quantitative factor's authored checks and
|
|
21
|
+
* evaluated check results.
|
|
22
|
+
*
|
|
23
|
+
* @param checks - The factor's authored checks
|
|
24
|
+
* @param results - The corresponding {@link CheckResult}s, in the same order
|
|
25
|
+
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
26
|
+
* @returns A fresh list of evidence rows, one per authored check
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* import { check } from '@orkestrel/reason'
|
|
31
|
+
* import { checkEvidence } from '@orkestrel/rater'
|
|
32
|
+
*
|
|
33
|
+
* const checks = [check('age', 'above', 18)]
|
|
34
|
+
* checkEvidence(checks, [{ field: 'age', met: true, actual: 25 }])
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function checkEvidence(checks: readonly Check[] | undefined, results: readonly CheckResult[] | undefined, labels?: Readonly<Record<string, string>>): readonly Evidence[];
|
|
26
38
|
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Create a rating orchestrator.
|
|
41
|
+
*
|
|
42
|
+
* @param options - Optional total handler, labels, injected engine, and emitter hooks
|
|
43
|
+
* @returns A {@link RaterInterface}
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* import { createRater } from '@orkestrel/rater'
|
|
48
|
+
*
|
|
49
|
+
* const rater = createRater()
|
|
50
|
+
* rater.destroy()
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function createRater(options?: RaterOptions): RaterInterface;
|
|
54
|
+
|
|
55
|
+
/** A checked-evidence row rendered into a display-neutral sentence. */
|
|
56
|
+
export declare interface Evidence {
|
|
57
|
+
readonly field?: FieldPath;
|
|
58
|
+
readonly label?: string;
|
|
59
|
+
readonly comparison?: Comparison;
|
|
60
|
+
readonly expected?: unknown;
|
|
61
|
+
readonly actual?: unknown;
|
|
62
|
+
readonly met?: boolean;
|
|
32
63
|
}
|
|
33
64
|
|
|
34
65
|
/**
|
|
35
|
-
* Build an {@link
|
|
66
|
+
* Build an {@link Evidence} row from an evaluated {@link Check}.
|
|
36
67
|
*
|
|
37
|
-
* @param
|
|
38
|
-
* @param
|
|
39
|
-
* @param
|
|
40
|
-
* @
|
|
68
|
+
* @param check - The authored check
|
|
69
|
+
* @param actual - The resolved subject value
|
|
70
|
+
* @param met - Whether the check was met (absent when not yet evaluated)
|
|
71
|
+
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
72
|
+
* @returns A fresh evidence row
|
|
41
73
|
*
|
|
42
74
|
* @example
|
|
43
75
|
* ```ts
|
|
44
|
-
* import {
|
|
76
|
+
* import { check } from '@orkestrel/reason'
|
|
77
|
+
* import { evidenceCheck } from '@orkestrel/rater'
|
|
45
78
|
*
|
|
46
|
-
*
|
|
79
|
+
* const entry = check('age', 'above', 18)
|
|
80
|
+
* evidenceCheck(entry, 25, true) // { field: 'age', comparison: 'above', expected: 18, actual: 25, met: true }
|
|
47
81
|
* ```
|
|
48
82
|
*/
|
|
49
|
-
export declare function
|
|
83
|
+
export declare function evidenceCheck(check: Check, actual: unknown, met: boolean | undefined, labels?: Readonly<Record<string, string>>): Evidence;
|
|
50
84
|
|
|
51
85
|
/**
|
|
52
|
-
*
|
|
86
|
+
* Determine whether a value is an exact {@link LineDefinition} record.
|
|
87
|
+
*
|
|
88
|
+
* @remarks
|
|
89
|
+
* Total guard (AGENTS §14): adversarial input (cycles, hostile prototypes)
|
|
90
|
+
* returns `false`, never throws. The record shape is EXACT — an extra key fails.
|
|
53
91
|
*
|
|
54
|
-
* @param
|
|
55
|
-
* @returns
|
|
92
|
+
* @param value - The value to test
|
|
93
|
+
* @returns `true` when `value` is a `LineDefinition`
|
|
56
94
|
*
|
|
57
95
|
* @example
|
|
58
96
|
* ```ts
|
|
59
|
-
* import {
|
|
97
|
+
* import { quantitativeDefinition } from '@orkestrel/reason'
|
|
98
|
+
* import { isLineDefinition } from '@orkestrel/rater'
|
|
60
99
|
*
|
|
61
|
-
*
|
|
100
|
+
* isLineDefinition({ id: 'base', name: 'Base', rate: quantitativeDefinition('base', 'Base', []) }) // true
|
|
62
101
|
* ```
|
|
63
102
|
*/
|
|
64
|
-
export declare function
|
|
103
|
+
export declare function isLineDefinition(value: unknown): value is LineDefinition;
|
|
65
104
|
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Narrow a caught value to a {@link RaterError}.
|
|
107
|
+
*
|
|
108
|
+
* @param value - The caught value to test
|
|
109
|
+
* @returns `true` when `value` is a `RaterError`
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* import { isRaterError, RaterError } from '@orkestrel/rater'
|
|
114
|
+
*
|
|
115
|
+
* try {
|
|
116
|
+
* throw new RaterError('DESTROYED', 'Rater has been destroyed')
|
|
117
|
+
* } catch (error) {
|
|
118
|
+
* if (isRaterError(error)) error.code // 'DESTROYED'
|
|
119
|
+
* }
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
export declare function isRaterError(value: unknown): value is RaterError;
|
|
72
123
|
|
|
73
124
|
/**
|
|
74
|
-
*
|
|
75
|
-
* partition.
|
|
125
|
+
* Determine whether a value is an exact {@link RatingDefinition} record.
|
|
76
126
|
*
|
|
77
127
|
* @remarks
|
|
78
|
-
*
|
|
79
|
-
* `
|
|
80
|
-
*
|
|
81
|
-
*
|
|
128
|
+
* Total guard (AGENTS §14): adversarial input (cycles, hostile prototypes)
|
|
129
|
+
* returns `false`, never throws. The record shape is EXACT — an extra key fails.
|
|
130
|
+
*
|
|
131
|
+
* @param value - The value to test
|
|
132
|
+
* @returns `true` when `value` is a `RatingDefinition`
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```ts
|
|
136
|
+
* import { isRatingDefinition } from '@orkestrel/rater'
|
|
82
137
|
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* @param by - The partition key field; no partition is built when absent
|
|
86
|
-
* @returns A fresh list of aggregate groups, or an empty list when `by` is absent
|
|
138
|
+
* isRatingDefinition({ id: 'r1', name: 'Rating', lines: [] }) // true
|
|
139
|
+
* ```
|
|
87
140
|
*/
|
|
88
|
-
export declare function
|
|
141
|
+
export declare function isRatingDefinition(value: unknown): value is RatingDefinition;
|
|
89
142
|
|
|
90
143
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
144
|
+
* Determine whether a value is a {@link Stage} literal.
|
|
145
|
+
*
|
|
146
|
+
* @param value - The value to test
|
|
147
|
+
* @returns `true` when `value` is `'factor'`, `'group'`, or `'total'`
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* import { isStage } from '@orkestrel/rater'
|
|
93
152
|
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* @returns A fresh aggregate projection record
|
|
153
|
+
* isStage('group') // true
|
|
154
|
+
* isStage('step') // false
|
|
155
|
+
* ```
|
|
98
156
|
*/
|
|
99
|
-
export declare
|
|
157
|
+
export declare const isStage: Guard<Stage>;
|
|
100
158
|
|
|
101
159
|
/**
|
|
102
|
-
*
|
|
160
|
+
* One rateable line — a quantitative definition joined to display metadata.
|
|
103
161
|
*
|
|
104
|
-
* @
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* @returns A fresh record carrying the aggregate projection under {@link AGGREGATE_KEY}
|
|
162
|
+
* @remarks
|
|
163
|
+
* `rate` is a plain reason {@link QuantitativeDefinition}; Rater delegates every
|
|
164
|
+
* actual evaluation of it to the shared engine.
|
|
108
165
|
*/
|
|
109
|
-
export declare
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
readonly
|
|
114
|
-
readonly
|
|
115
|
-
readonly groups: readonly AggregateGroup[];
|
|
116
|
-
readonly tallies: Readonly<Record<string, Readonly<Record<Status, Tally>>>>;
|
|
117
|
-
readonly count: number;
|
|
118
|
-
readonly sums: Readonly<Record<string, number>>;
|
|
166
|
+
export declare interface LineDefinition {
|
|
167
|
+
readonly id: string;
|
|
168
|
+
readonly name: string;
|
|
169
|
+
readonly description?: string;
|
|
170
|
+
readonly rate: QuantitativeDefinition;
|
|
171
|
+
readonly metadata?: JSONValue;
|
|
119
172
|
}
|
|
120
173
|
|
|
121
174
|
/**
|
|
122
|
-
*
|
|
175
|
+
* Build a {@link LineDefinition}.
|
|
176
|
+
*
|
|
177
|
+
* @param id - The line id
|
|
178
|
+
* @param name - The display name
|
|
179
|
+
* @param rate - The line's quantitative rating definition
|
|
180
|
+
* @param overrides - Optional {@link LineDefinition} fields merged over the defaults
|
|
181
|
+
* @returns A fresh line definition
|
|
123
182
|
*
|
|
124
|
-
* @
|
|
125
|
-
*
|
|
126
|
-
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* import { quantitativeDefinition } from '@orkestrel/reason'
|
|
186
|
+
* import { lineDefinition } from '@orkestrel/rater'
|
|
187
|
+
*
|
|
188
|
+
* lineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', []))
|
|
189
|
+
* ```
|
|
127
190
|
*/
|
|
128
|
-
export declare function
|
|
191
|
+
export declare function lineDefinition(id: string, name: string, rate: QuantitativeDefinition, overrides?: Partial<Omit<LineDefinition, 'id' | 'name' | 'rate'>>): LineDefinition;
|
|
129
192
|
|
|
130
193
|
/**
|
|
131
|
-
*
|
|
194
|
+
* One line's rating outcome.
|
|
132
195
|
*
|
|
133
|
-
* @
|
|
134
|
-
*
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
* @param rulings - Authored consequences, keyed by rule id
|
|
146
|
-
* @param working - The working subject the authority ran against
|
|
147
|
-
* @param evaluator - The shared reason check evaluator
|
|
148
|
-
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
149
|
-
* @returns A fresh list of `limit` determinations
|
|
150
|
-
*/
|
|
151
|
-
export declare function authorityToDeterminations(definition: LogicalDefinition, result: LogicalResult, rulings: Readonly<Record<string, Ruling>> | undefined, working: Subject, evaluator: EvaluatorInterface, labels?: Readonly<Record<string, string>>): readonly Determination[];
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Build premises from a quantitative factor's authored checks and evaluated
|
|
155
|
-
* check results.
|
|
156
|
-
*
|
|
157
|
-
* @param checks - The factor's authored checks
|
|
158
|
-
* @param results - The corresponding {@link CheckResult}s, in the same order
|
|
159
|
-
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
160
|
-
* @returns A fresh list of premises, one per authored check
|
|
161
|
-
*/
|
|
162
|
-
export declare function checkPremises(checks: readonly Check[] | undefined, results: readonly CheckResult[] | undefined, labels?: Readonly<Record<string, string>>): readonly Premise[];
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Return the most severe {@link Eligibility} in a list.
|
|
166
|
-
*
|
|
167
|
-
* @param eligibilities - The eligibilities to combine
|
|
168
|
-
* @returns The most severe eligibility, or `'eligible'` for an empty list
|
|
169
|
-
*
|
|
170
|
-
* @example
|
|
171
|
-
* ```ts
|
|
172
|
-
* import { combineEligibilities } from '@orkestrel/rater'
|
|
173
|
-
*
|
|
174
|
-
* combineEligibilities(['eligible', 'referral']) // 'referral'
|
|
175
|
-
* ```
|
|
176
|
-
*/
|
|
177
|
-
export declare function combineEligibilities(eligibilities: readonly Eligibility[]): Eligibility;
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Complete a partial status tally record with zero entries for every missing
|
|
181
|
-
* {@link Status}.
|
|
182
|
-
*
|
|
183
|
-
* @param entries - The partial tally entries to complete
|
|
184
|
-
* @returns A record with all five statuses present
|
|
185
|
-
*/
|
|
186
|
-
export declare function completeTallies(entries: Partial<Record<Status, Tally>>): Readonly<Record<Status, Tally>>;
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Create and validate one compiled program over a shared reasoning engine.
|
|
190
|
-
*
|
|
191
|
-
* @param definition - The authored program definition
|
|
192
|
-
* @param reason - The shared reasoning engine, injected (never owned or destroyed by the program)
|
|
193
|
-
* @param options - Optional total handler and labels
|
|
194
|
-
* @returns A {@link ProgramInterface}
|
|
195
|
-
* @throws {@link RaterError} `'DEFINITION'` when the definition fails {@link isProgramDefinition}
|
|
196
|
-
*
|
|
197
|
-
* @example
|
|
198
|
-
* ```ts
|
|
199
|
-
* import { createLogicalReasoner, createQuantitativeReasoner, createReason } from '@orkestrel/reason'
|
|
200
|
-
* import { createProgram, programDefinition } from '@orkestrel/rater'
|
|
201
|
-
*
|
|
202
|
-
* const reason = createReason({ reasoners: [createQuantitativeReasoner(), createLogicalReasoner()], bail: false })
|
|
203
|
-
* const program = createProgram(programDefinition('p1', 'Program', []), reason)
|
|
204
|
-
* ```
|
|
205
|
-
*/
|
|
206
|
-
export declare function createProgram(definition: ProgramDefinition, reason: ReasonInterface, options?: ProgramOptions): ProgramInterface;
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Create an ordered manager over compiled programs (AGENTS §9), built over an
|
|
210
|
-
* injected, shared reasoning engine.
|
|
211
|
-
*
|
|
212
|
-
* @param reason - The shared reasoning engine, injected into every compiled program
|
|
213
|
-
* @param options - Optional total handler, labels, validation policy, and emitter hooks
|
|
214
|
-
* @returns A {@link ProgramManagerInterface}
|
|
215
|
-
*
|
|
216
|
-
* @example
|
|
217
|
-
* ```ts
|
|
218
|
-
* import { createLogicalReasoner, createQuantitativeReasoner, createReason } from '@orkestrel/reason'
|
|
219
|
-
* import { createProgramManager, programDefinition } from '@orkestrel/rater'
|
|
220
|
-
*
|
|
221
|
-
* const reason = createReason({ reasoners: [createQuantitativeReasoner(), createLogicalReasoner()], bail: false })
|
|
222
|
-
* const manager = createProgramManager(reason)
|
|
223
|
-
* manager.add(programDefinition('p1', 'Program', []))
|
|
224
|
-
* manager.destroy()
|
|
225
|
-
* ```
|
|
226
|
-
*/
|
|
227
|
-
export declare function createProgramManager(reason: ReasonInterface, options?: ProgramManagerOptions): ProgramManagerInterface;
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Create a rating orchestrator.
|
|
231
|
-
*
|
|
232
|
-
* @param options - Optional total handler, seed programs, labels, validation policy, and emitter hooks
|
|
233
|
-
* @returns A {@link RaterInterface}
|
|
234
|
-
*
|
|
235
|
-
* @example
|
|
236
|
-
* ```ts
|
|
237
|
-
* import { createRater } from '@orkestrel/rater'
|
|
238
|
-
*
|
|
239
|
-
* const rater = createRater()
|
|
240
|
-
* rater.destroy()
|
|
241
|
-
* ```
|
|
242
|
-
*/
|
|
243
|
-
export declare function createRater(options?: RaterOptions): RaterInterface;
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Convert an {@link Eligibility} to its deterministic authority {@link Decision}.
|
|
247
|
-
*
|
|
248
|
-
* @param eligibility - The eligibility to convert
|
|
249
|
-
* @returns The matching decision
|
|
250
|
-
*/
|
|
251
|
-
export declare function decideEligibility(eligibility: Eligibility): Decision;
|
|
252
|
-
|
|
253
|
-
/** Deterministic authority decision derived from eligibility. */
|
|
254
|
-
export declare type Decision = 'approved' | 'denied' | 'submitted';
|
|
255
|
-
|
|
256
|
-
/** Default definition validation policy for `ProgramManager.add`. */
|
|
257
|
-
export declare const DEFAULT_RATER_VALIDATE = true;
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Derive the eligibility impact of a set of determinations.
|
|
261
|
-
*
|
|
262
|
-
* @param determinations - The determinations to fold
|
|
263
|
-
* @returns The most severe eligibility any APPLIED determination's effect carries
|
|
264
|
-
*
|
|
265
|
-
* @example
|
|
266
|
-
* ```ts
|
|
267
|
-
* import { deriveDeterminationEligibility } from '@orkestrel/rater'
|
|
268
|
-
*
|
|
269
|
-
* deriveDeterminationEligibility([{ id: 'r1', effect: 'restriction', applied: true, premises: [] }])
|
|
270
|
-
* // 'ineligible'
|
|
271
|
-
* ```
|
|
272
|
-
*/
|
|
273
|
-
export declare function deriveDeterminationEligibility(determinations: readonly Determination[]): Eligibility;
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Derive the final {@link Status} from eligibility, determinations, and rated
|
|
277
|
-
* line evidence.
|
|
278
|
-
*
|
|
279
|
-
* @param eligibility - The program's combined eligibility
|
|
280
|
-
* @param determinations - Every determination in scope (program and line)
|
|
281
|
-
* @param lines - The program's rated lines
|
|
282
|
-
* @returns The derived status
|
|
283
|
-
*/
|
|
284
|
-
export declare function deriveStatus(eligibility: Eligibility, determinations: readonly Determination[], lines: readonly LineResult[]): Status;
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Describe a {@link Premise} comparison as a display-neutral verb phrase.
|
|
288
|
-
*
|
|
289
|
-
* @param comparison - The comparison to describe
|
|
290
|
-
* @returns A display-neutral phrase
|
|
291
|
-
*
|
|
292
|
-
* @example
|
|
293
|
-
* ```ts
|
|
294
|
-
* import { describeComparison } from '@orkestrel/rater'
|
|
295
|
-
*
|
|
296
|
-
* describeComparison('above') // 'is more than'
|
|
297
|
-
* ```
|
|
298
|
-
*/
|
|
299
|
-
export declare function describeComparison(comparison: NonNullable<Premise['comparison']>): string;
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Describe a logical {@link Expression} tree without atom-specific evidence.
|
|
303
|
-
*
|
|
304
|
-
* @param expression - The expression to describe
|
|
305
|
-
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
306
|
-
* @returns A display-neutral description
|
|
307
|
-
*/
|
|
308
|
-
export declare function describeExpression(expression: Expression, labels?: Readonly<Record<string, string>>): string;
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Render one {@link Premise} into a display-neutral sentence.
|
|
312
|
-
*
|
|
313
|
-
* @param entry - The premise to render
|
|
314
|
-
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
315
|
-
* @returns A display-neutral sentence
|
|
316
|
-
*
|
|
317
|
-
* @example
|
|
318
|
-
* ```ts
|
|
319
|
-
* import { describePremise } from '@orkestrel/rater'
|
|
320
|
-
*
|
|
321
|
-
* describePremise({ field: 'age', comparison: 'above', expected: 18, actual: 25, met: true })
|
|
322
|
-
* // 'age is more than 18 ? met'
|
|
323
|
-
* ```
|
|
324
|
-
*/
|
|
325
|
-
export declare function describePremise(entry: Premise, labels?: Readonly<Record<string, string>>): string;
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* Render a structured or scalar value display-neutrally.
|
|
329
|
-
*
|
|
330
|
-
* @remarks
|
|
331
|
-
* An array renders as its elements, each `String`-coerced, joined with
|
|
332
|
-
* `', '`. A Bounds-shaped record (a reason `Bounds` — the `between`/`outside`
|
|
333
|
-
* comparison's expected value shape) renders its present sides joined with
|
|
334
|
-
* the word `and`; an absent side is omitted. A finite number and everything
|
|
335
|
-
* else fall back to plain `String()` coercion — a finite number is NOT
|
|
336
|
-
* grouped here (that grouping is {@link interpolateMessage}'s own,
|
|
337
|
-
* message-token-only behavior).
|
|
338
|
-
*
|
|
339
|
-
* @param value - The value to render
|
|
340
|
-
* @returns A display-neutral rendering
|
|
341
|
-
*
|
|
342
|
-
* @example
|
|
343
|
-
* ```ts
|
|
344
|
-
* import { describeValue } from '@orkestrel/rater'
|
|
345
|
-
*
|
|
346
|
-
* describeValue([18, 25, 40]) // '18, 25, 40'
|
|
347
|
-
* describeValue({ minimum: 18, maximum: 65 }) // '18 and 65'
|
|
348
|
-
* describeValue(42) // '42'
|
|
349
|
-
* ```
|
|
350
|
-
*/
|
|
351
|
-
export declare function describeValue(value: unknown): string;
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
* A resolved rule, authority, or notice outcome.
|
|
355
|
-
*
|
|
356
|
-
* @remarks
|
|
357
|
-
* `premises` lists only content-bearing premises — content-free atoms (an
|
|
358
|
-
* empty `any`/`none` membership check) are omitted, so its length may be
|
|
359
|
-
* smaller than the engine's boolean premise count.
|
|
360
|
-
*/
|
|
361
|
-
export declare interface Determination {
|
|
362
|
-
readonly id: string;
|
|
363
|
-
readonly effect: Effect;
|
|
364
|
-
readonly applied: boolean;
|
|
365
|
-
readonly line?: string;
|
|
366
|
-
readonly message?: string;
|
|
367
|
-
readonly premises: readonly Premise[];
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
/** A resolved determination effect. */
|
|
371
|
-
export declare type Effect = 'restriction' | 'referral' | 'condition' | 'notice' | 'limit';
|
|
372
|
-
|
|
373
|
-
/** The direct eligibility impact of an applied determination, by its effect. */
|
|
374
|
-
export declare const EFFECT_ELIGIBILITIES: Readonly<Record<Effect, Eligibility | undefined>>;
|
|
375
|
-
|
|
376
|
-
/** Advisory eligibility axis a program or line outcome carries. */
|
|
377
|
-
export declare type Eligibility = 'eligible' | 'ineligible' | 'referral';
|
|
378
|
-
|
|
379
|
-
/** The deterministic authority decision for each eligibility. */
|
|
380
|
-
export declare const ELIGIBILITY_DECISIONS: Readonly<Record<Eligibility, Decision>>;
|
|
381
|
-
|
|
382
|
-
/** Eligibility severity order, most severe first — the {@link combineEligibilities} scan order. */
|
|
383
|
-
export declare const ELIGIBILITY_PRECEDENCE: readonly Eligibility[];
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Build zero sums for a set of fields.
|
|
387
|
-
*
|
|
388
|
-
* @param fields - The fields to zero
|
|
389
|
-
* @returns A fresh record of dot-joined field to `0`
|
|
390
|
-
*/
|
|
391
|
-
export declare function emptySums(fields: readonly FieldPath[]): Readonly<Record<string, number>>;
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* Build empty status tallies in precedence order.
|
|
395
|
-
*
|
|
396
|
-
* @param fields - The fields each tally's sums are zeroed for
|
|
397
|
-
* @returns A fresh, complete tally record
|
|
398
|
-
*/
|
|
399
|
-
export declare function emptyTallies(fields: readonly FieldPath[]): Readonly<Record<Status, Tally>>;
|
|
400
|
-
|
|
401
|
-
/**
|
|
402
|
-
* Keep only the determinations scoped to one line.
|
|
403
|
-
*
|
|
404
|
-
* @param determinations - The determinations to filter
|
|
405
|
-
* @param id - The line id to keep
|
|
406
|
-
* @returns The determinations whose `line` matches `id`
|
|
407
|
-
*/
|
|
408
|
-
export declare function filterLineDeterminations(determinations: readonly Determination[], id: string): readonly Determination[];
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* Keep only program-scoped (line-unscoped) determinations.
|
|
412
|
-
*
|
|
413
|
-
* @param determinations - The determinations to filter
|
|
414
|
-
* @returns The determinations with no `line`
|
|
415
|
-
*/
|
|
416
|
-
export declare function filterProgramDeterminations(determinations: readonly Determination[]): readonly Determination[];
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Return authored line references (in passes, rulings, or notices) that name
|
|
420
|
-
* no line on the program.
|
|
421
|
-
*
|
|
422
|
-
* @param definition - The program definition to check
|
|
423
|
-
* @returns A fresh, deduped list of missing line ids
|
|
424
|
-
*/
|
|
425
|
-
export declare function findMissingLineReferences(definition: ProgramDefinition): readonly string[];
|
|
426
|
-
|
|
427
|
-
/**
|
|
428
|
-
* Locate a {@link ProgramDefinition}'s reserved-key collisions — a quantitative
|
|
429
|
-
* pass whose id shadows {@link AGGREGATE_KEY} / {@link OUTCOME_KEY}, or a
|
|
430
|
-
* logical pass's or the authority's fired rule conclusion whose asserted
|
|
431
|
-
* field's FIRST path segment shadows one.
|
|
432
|
-
*
|
|
433
|
-
* @remarks
|
|
434
|
-
* A quantitative pass writes its value onto the working subject under its own
|
|
435
|
-
* definition id (`assignField`), silently clobbering the reserved aggregate or
|
|
436
|
-
* outcome projection when the id collides. A fired rule's conclusion atoms
|
|
437
|
-
* merge onto the working subject (`mergeSubjects`/`extractConclusions`) keyed
|
|
438
|
-
* by `formatField(check.field)` — an atom whose field's first segment is a
|
|
439
|
-
* reserved key is flagged here even when its FULL formatted key is a nested
|
|
440
|
-
* form (`outcome.total`), since authoring a conclusion under a reserved
|
|
441
|
-
* top-level segment is never intentional.
|
|
442
|
-
*
|
|
443
|
-
* @param definition - The program definition to scan
|
|
444
|
-
* @returns A fresh, deduped list of offending pass or rule ids
|
|
445
|
-
*
|
|
446
|
-
* @example
|
|
447
|
-
* ```ts
|
|
448
|
-
* import { quantitativeDefinition } from '@orkestrel/reason'
|
|
449
|
-
* import { findReservedCollisions, passDefinition, programDefinition } from '@orkestrel/rater'
|
|
450
|
-
*
|
|
451
|
-
* findReservedCollisions(
|
|
452
|
-
* programDefinition('p1', 'P1', [], {
|
|
453
|
-
* passes: [passDefinition(quantitativeDefinition('aggregate', 'Aggregate', []))],
|
|
454
|
-
* }),
|
|
455
|
-
* ) // ['aggregate']
|
|
456
|
-
* ```
|
|
457
|
-
*/
|
|
458
|
-
export declare function findReservedCollisions(definition: ProgramDefinition): readonly string[];
|
|
459
|
-
|
|
460
|
-
/**
|
|
461
|
-
* Locate an authored {@link Rule} by id.
|
|
462
|
-
*
|
|
463
|
-
* @param definition - The logical definition to search
|
|
464
|
-
* @param id - The rule id
|
|
465
|
-
* @returns The matching rule, or `undefined`
|
|
466
|
-
*/
|
|
467
|
-
export declare function findRule(definition: LogicalDefinition, id: string): Rule | undefined;
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* Locate the {@link AggregateGroup} a subject belongs to.
|
|
471
|
-
*
|
|
472
|
-
* @remarks
|
|
473
|
-
* The lookup key is the resolved `by` field, coerced with `String` —
|
|
474
|
-
* `undefined` collapses to the empty string, matching {@link aggregateGroups}'
|
|
475
|
-
* partition-key coercion (a missing key and an empty-string key collide, and
|
|
476
|
-
* a numeric `1` collides with the string `'1'`).
|
|
477
|
-
*
|
|
478
|
-
* @param subject - The subject to key
|
|
479
|
-
* @param groups - The candidate groups to search
|
|
480
|
-
* @param by - The partition key field; no group is found when absent
|
|
481
|
-
* @returns The subject's matching group, or `undefined`
|
|
482
|
-
*
|
|
483
|
-
* @example
|
|
484
|
-
* ```ts
|
|
485
|
-
* import { groupFor } from '@orkestrel/rater'
|
|
486
|
-
*
|
|
487
|
-
* groupFor({ region: 'east' }, [{ key: 'east', count: 1, sums: {} }], ['region'])
|
|
488
|
-
* // { key: 'east', count: 1, sums: {} }
|
|
489
|
-
* ```
|
|
490
|
-
*/
|
|
491
|
-
export declare function groupFor(subject: Subject, groups: readonly AggregateGroup[], by?: FieldPath): AggregateGroup | undefined;
|
|
492
|
-
|
|
493
|
-
/** Determine whether a working record already carries a reserved rater key. */
|
|
494
|
-
export declare function hasReservedKey(subject: Readonly<Record<string, unknown>>): boolean;
|
|
495
|
-
|
|
496
|
-
/**
|
|
497
|
-
* Interpolate `{{dotted.path}}` tokens in a message template against a record.
|
|
498
|
-
*
|
|
499
|
-
* @remarks
|
|
500
|
-
* Each token is split on `.` into a {@link FieldPath} array and resolved with
|
|
501
|
-
* the contracts {@link resolveField} (a plain string field is ONE key, never
|
|
502
|
-
* dot-split — the split here is the token-to-path bridge). A finite number
|
|
503
|
-
* renders with `en-US` thousand grouping (`5010` → `5,010`); any other resolved
|
|
504
|
-
* value String-coerces. An UNRESOLVED path (the resolved value is `undefined`)
|
|
505
|
-
* renders as the empty string — the deterministic "nothing to show" rule.
|
|
506
|
-
*
|
|
507
|
-
* @param template - The message template carrying `{{dotted.path}}` tokens
|
|
508
|
-
* @param record - The record tokens resolve against
|
|
509
|
-
* @returns The template with every token replaced
|
|
510
|
-
*
|
|
511
|
-
* @example
|
|
512
|
-
* ```ts
|
|
513
|
-
* import { interpolateMessage } from '@orkestrel/rater'
|
|
514
|
-
*
|
|
515
|
-
* interpolateMessage('Limit is {{limit}}', { limit: 5010 }) // 'Limit is 5,010'
|
|
516
|
-
* interpolateMessage('Missing {{gone}}', {}) // 'Missing '
|
|
517
|
-
* ```
|
|
518
|
-
*/
|
|
519
|
-
export declare function interpolateMessage(template: string, record: Readonly<Record<string, unknown>>): string;
|
|
520
|
-
|
|
521
|
-
/** Determine whether a value is an exact {@link AggregateDefinition} record. */
|
|
522
|
-
export declare function isAggregateDefinition(value: unknown): value is AggregateDefinition;
|
|
523
|
-
|
|
524
|
-
/** Determine whether a value is a {@link Decision} literal. */
|
|
525
|
-
export declare const isDecision: Guard<Decision>;
|
|
526
|
-
|
|
527
|
-
/** Determine whether a value is an {@link Effect} literal. */
|
|
528
|
-
export declare const isEffect: Guard<Effect>;
|
|
529
|
-
|
|
530
|
-
/** Determine whether a value is an {@link Eligibility} literal. */
|
|
531
|
-
export declare const isEligibility: Guard<Eligibility>;
|
|
532
|
-
|
|
533
|
-
/** Determine whether a value is an exact {@link LineDefinition} record. */
|
|
534
|
-
export declare function isLineDefinition(value: unknown): value is LineDefinition;
|
|
535
|
-
|
|
536
|
-
/** Determine whether a value is an exact {@link Notice} record. */
|
|
537
|
-
export declare function isNotice(value: unknown): value is Notice;
|
|
538
|
-
|
|
539
|
-
/** Determine whether a value is an exact {@link PassDefinition} record. */
|
|
540
|
-
export declare function isPassDefinition(value: unknown): value is PassDefinition;
|
|
541
|
-
|
|
542
|
-
/** Determine whether a value is an exact {@link ProgramDefinition} record. */
|
|
543
|
-
export declare function isProgramDefinition(value: unknown): value is ProgramDefinition;
|
|
544
|
-
|
|
545
|
-
/** Narrow a caught value to a {@link RaterError}. */
|
|
546
|
-
export declare function isRaterError(value: unknown): value is RaterError;
|
|
547
|
-
|
|
548
|
-
/** Determine whether a value is an exact {@link Ruling} record. */
|
|
549
|
-
export declare function isRuling(value: unknown): value is Ruling;
|
|
550
|
-
|
|
551
|
-
/** Determine whether a value is a rule-id-keyed {@link Ruling} record. */
|
|
552
|
-
export declare const isRulings: Guard<Readonly<Record<string, Ruling>>>;
|
|
553
|
-
|
|
554
|
-
/** Determine whether a value is a {@link Stage} literal. */
|
|
555
|
-
export declare const isStage: Guard<Stage>;
|
|
556
|
-
|
|
557
|
-
/** Determine whether a value is a {@link Status} literal. */
|
|
558
|
-
export declare const isStatus: Guard<Status>;
|
|
559
|
-
|
|
560
|
-
/**
|
|
561
|
-
* One rateable line — a quantitative definition joined to display metadata.
|
|
562
|
-
*
|
|
563
|
-
* @remarks
|
|
564
|
-
* `rate` is a plain reason {@link QuantitativeDefinition}; Rater delegates every
|
|
565
|
-
* actual evaluation of it to the shared engine.
|
|
566
|
-
*/
|
|
567
|
-
export declare interface LineDefinition {
|
|
568
|
-
readonly id: string;
|
|
569
|
-
readonly name: string;
|
|
570
|
-
readonly description?: string;
|
|
571
|
-
readonly rate: QuantitativeDefinition;
|
|
572
|
-
readonly metadata?: JSONValue;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
/**
|
|
576
|
-
* Build a {@link LineDefinition}.
|
|
577
|
-
*
|
|
578
|
-
* @param id - The line id
|
|
579
|
-
* @param name - The display name
|
|
580
|
-
* @param rate - The line's quantitative rating definition
|
|
581
|
-
* @param overrides - Optional {@link LineDefinition} fields merged over the defaults
|
|
582
|
-
* @returns A fresh line definition
|
|
583
|
-
*
|
|
584
|
-
* @example
|
|
585
|
-
* ```ts
|
|
586
|
-
* import { quantitativeDefinition } from '@orkestrel/reason'
|
|
587
|
-
* import { lineDefinition } from '@orkestrel/rater'
|
|
588
|
-
*
|
|
589
|
-
* lineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', []))
|
|
590
|
-
* ```
|
|
591
|
-
*/
|
|
592
|
-
export declare function lineDefinition(id: string, name: string, rate: QuantitativeDefinition, overrides?: Partial<Omit<LineDefinition, 'id' | 'name' | 'rate'>>): LineDefinition;
|
|
593
|
-
|
|
594
|
-
/** One line's rating outcome. */
|
|
595
|
-
export declare interface LineResult {
|
|
596
|
-
readonly id: string;
|
|
597
|
-
readonly name: string;
|
|
598
|
-
readonly eligibility: Eligibility;
|
|
599
|
-
readonly amount?: number;
|
|
600
|
-
readonly worksheet?: Worksheet;
|
|
601
|
-
readonly determinations: readonly Determination[];
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* Build rich premises for one fired {@link Rule} by walking its premise atoms
|
|
606
|
-
* and re-evaluating each against the working subject.
|
|
607
|
-
*
|
|
608
|
-
* @remarks
|
|
609
|
-
* A reason {@link RuleResult} carries only booleans, so this is rater's own
|
|
610
|
-
* premise-audit projection: each authored premise expression is flattened to
|
|
611
|
-
* its atom leaves via {@link extractAtoms}, and each leaf's {@link Check} is
|
|
612
|
-
* re-evaluated through the injected `evaluator`. A membership check (`any` /
|
|
613
|
-
* `none`) over an EMPTY array value is content-free — a tautology or
|
|
614
|
-
* contradiction that reads as "is none of —" in every surface — and is skipped.
|
|
615
|
-
*
|
|
616
|
-
* @param rule - The authored rule
|
|
617
|
-
* @param working - The working subject to evaluate against
|
|
618
|
-
* @param evaluator - The shared reason check evaluator
|
|
619
|
-
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
620
|
-
* @returns A fresh, ordered list of rich premises
|
|
621
|
-
*/
|
|
622
|
-
export declare function logicalPremises(rule: Rule, working: Subject, evaluator: EvaluatorInterface, labels?: Readonly<Record<string, string>>): readonly Premise[];
|
|
623
|
-
|
|
624
|
-
/** An authored informational determination emitted unconditionally. */
|
|
625
|
-
export declare interface Notice {
|
|
626
|
-
readonly id: string;
|
|
627
|
-
readonly message: string;
|
|
628
|
-
readonly line?: string;
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
/**
|
|
632
|
-
* Build a {@link Notice}.
|
|
633
|
-
*
|
|
634
|
-
* @param id - The notice id
|
|
635
|
-
* @param message - An interpolated message template
|
|
636
|
-
* @param line - The line id this notice is scoped to, when it is line-scoped
|
|
637
|
-
* @returns A fresh notice
|
|
638
|
-
*
|
|
639
|
-
* @example
|
|
640
|
-
* ```ts
|
|
641
|
-
* import { noticeDefinition } from '@orkestrel/rater'
|
|
642
|
-
*
|
|
643
|
-
* noticeDefinition('n1', 'Rated on {{date}}')
|
|
644
|
-
* ```
|
|
645
|
-
*/
|
|
646
|
-
export declare function noticeDefinition(id: string, message: string, line?: string): Notice;
|
|
647
|
-
|
|
648
|
-
/**
|
|
649
|
-
* Convert authored {@link Notice}s into unconditionally-applied
|
|
650
|
-
* `notice` {@link Determination}s.
|
|
651
|
-
*
|
|
652
|
-
* @param notices - The authored notices
|
|
653
|
-
* @param working - The working subject to interpolate messages against
|
|
654
|
-
* @returns A fresh list of notice determinations
|
|
655
|
-
*/
|
|
656
|
-
export declare function noticesToDeterminations(notices: readonly Notice[] | undefined, working: Readonly<Record<string, unknown>>): readonly Determination[];
|
|
657
|
-
|
|
658
|
-
/** The reserved working-subject key an authority's outcome projection is written under. */
|
|
659
|
-
export declare const OUTCOME_KEY = "outcome";
|
|
660
|
-
|
|
661
|
-
/**
|
|
662
|
-
* Build an authority outcome projection from an assembled {@link ProgramResult}.
|
|
663
|
-
*
|
|
664
|
-
* @param result - The program result computed before authority runs
|
|
665
|
-
* @returns A record shaped for the authority's `outcome` projection
|
|
666
|
-
*/
|
|
667
|
-
export declare function outcomeProjection(result: ProgramResult): Readonly<Record<string, unknown>>;
|
|
668
|
-
|
|
669
|
-
/**
|
|
670
|
-
* An ordered pre-rating pass over the working subject.
|
|
671
|
-
*
|
|
672
|
-
* @remarks
|
|
673
|
-
* `line` scopes a logical pass's determinations to one line; a quantitative pass
|
|
674
|
-
* has no line scope (its value is assigned onto the working subject under its own
|
|
675
|
-
* definition id).
|
|
676
|
-
*/
|
|
677
|
-
export declare interface PassDefinition {
|
|
678
|
-
readonly line?: string;
|
|
679
|
-
readonly definition: LogicalDefinition | QuantitativeDefinition;
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
/**
|
|
683
|
-
* Build a {@link PassDefinition}.
|
|
684
|
-
*
|
|
685
|
-
* @param definition - The pass's logical or quantitative definition
|
|
686
|
-
* @param line - The line id this pass is scoped to, when it is line-scoped
|
|
687
|
-
* @returns A fresh pass definition
|
|
688
|
-
*
|
|
689
|
-
* @example
|
|
690
|
-
* ```ts
|
|
691
|
-
* import { quantitativeDefinition } from '@orkestrel/reason'
|
|
692
|
-
* import { passDefinition } from '@orkestrel/rater'
|
|
693
|
-
*
|
|
694
|
-
* passDefinition(quantitativeDefinition('surcharge', 'Surcharge', []))
|
|
695
|
-
* ```
|
|
696
|
-
*/
|
|
697
|
-
export declare function passDefinition(definition: LogicalDefinition | QuantitativeDefinition, line?: string): PassDefinition;
|
|
698
|
-
|
|
699
|
-
/** A shared checked-evidence row rendered into a display-neutral sentence. */
|
|
700
|
-
export declare interface Premise {
|
|
701
|
-
readonly field?: FieldPath;
|
|
702
|
-
readonly label?: string;
|
|
703
|
-
readonly description?: string;
|
|
704
|
-
readonly comparison?: Comparison;
|
|
705
|
-
readonly expected?: unknown;
|
|
706
|
-
readonly actual?: unknown;
|
|
707
|
-
readonly met?: boolean;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
/**
|
|
711
|
-
* Build a {@link Premise} from an evaluated {@link Check}.
|
|
712
|
-
*
|
|
713
|
-
* @param check - The authored check
|
|
714
|
-
* @param actual - The resolved subject value
|
|
715
|
-
* @param met - Whether the check was met (absent when not yet evaluated)
|
|
716
|
-
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
717
|
-
* @returns A fresh premise
|
|
718
|
-
*/
|
|
719
|
-
export declare function premiseCheck(check: Check, actual: unknown, met: boolean | undefined, labels?: Readonly<Record<string, string>>): Premise;
|
|
720
|
-
|
|
721
|
-
/**
|
|
722
|
-
* A compiled program — rates one subject at a time over an injected, shared
|
|
723
|
-
* reasoning engine.
|
|
724
|
-
*
|
|
725
|
-
* @remarks
|
|
726
|
-
* The engine is INJECTED and never owned, destroyed, or otherwise mutated by
|
|
727
|
-
* the program: every actual evaluation (passes, lines, authority) delegates to
|
|
728
|
-
* it. `rate` builds its working subject through copy-on-write overlays only —
|
|
729
|
-
* the caller's `subject` is never mutated.
|
|
730
|
-
*/
|
|
731
|
-
export declare class Program implements ProgramInterface {
|
|
732
|
-
#private;
|
|
733
|
-
constructor(definition: ProgramDefinition, reason: ReasonInterface, options?: ProgramOptions);
|
|
734
|
-
get id(): string;
|
|
735
|
-
get name(): string;
|
|
736
|
-
get definition(): ProgramDefinition;
|
|
737
|
-
rate(subject: Subject, aggregate?: Readonly<Record<string, unknown>>): ProgramResult;
|
|
738
|
-
}
|
|
739
|
-
|
|
740
|
-
/**
|
|
741
|
-
* A pure authored program definition.
|
|
742
|
-
*
|
|
743
|
-
* @remarks
|
|
744
|
-
* `passes` runs in order before `lines`; `authority` (a logical definition) runs
|
|
745
|
-
* over the assembled result, extended with an outcome projection, to derive limit
|
|
746
|
-
* determinations and the final decision.
|
|
747
|
-
*/
|
|
748
|
-
export declare interface ProgramDefinition {
|
|
749
|
-
readonly id: string;
|
|
750
|
-
readonly name: string;
|
|
751
|
-
readonly description?: string;
|
|
752
|
-
readonly passes?: readonly PassDefinition[];
|
|
753
|
-
readonly lines: readonly LineDefinition[];
|
|
754
|
-
readonly rulings?: Readonly<Record<string, Ruling>>;
|
|
755
|
-
readonly notices?: readonly Notice[];
|
|
756
|
-
readonly authority?: LogicalDefinition;
|
|
757
|
-
readonly aggregate?: AggregateDefinition;
|
|
758
|
-
readonly metadata?: JSONValue;
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
/**
|
|
762
|
-
* Build a {@link ProgramDefinition}.
|
|
763
|
-
*
|
|
764
|
-
* @param id - The program id
|
|
765
|
-
* @param name - The display name
|
|
766
|
-
* @param lines - The program's rateable lines
|
|
767
|
-
* @param overrides - Optional {@link ProgramDefinition} fields merged over the defaults
|
|
768
|
-
* @returns A fresh program definition
|
|
769
|
-
*
|
|
770
|
-
* @example
|
|
771
|
-
* ```ts
|
|
772
|
-
* import { programDefinition } from '@orkestrel/rater'
|
|
773
|
-
*
|
|
774
|
-
* programDefinition('p1', 'Program', [])
|
|
775
|
-
* ```
|
|
776
|
-
*/
|
|
777
|
-
export declare function programDefinition(id: string, name: string, lines: readonly LineDefinition[], overrides?: Partial<Omit<ProgramDefinition, 'id' | 'name' | 'lines'>>): ProgramDefinition;
|
|
778
|
-
|
|
779
|
-
/**
|
|
780
|
-
* A compiled program — engine-injected, rates one subject at a time against its
|
|
781
|
-
* frozen definition.
|
|
782
|
-
*/
|
|
783
|
-
export declare interface ProgramInterface {
|
|
784
|
-
readonly id: string;
|
|
785
|
-
readonly name: string;
|
|
786
|
-
readonly definition: ProgramDefinition;
|
|
787
|
-
rate(subject: Subject, aggregate?: Readonly<Record<string, unknown>>): ProgramResult;
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
/**
|
|
791
|
-
* An ordered manager over compiled {@link ProgramInterface}s (AGENTS §9), built
|
|
792
|
-
* over an injected, shared reasoning engine.
|
|
793
|
-
*
|
|
794
|
-
* @remarks
|
|
795
|
-
* OWNS its `#programs` collection and its own {@link Emitter} over
|
|
796
|
-
* {@link ProgramManagerEventMap}. `destroy()` is idempotent and tears the
|
|
797
|
-
* emitter down LAST; every other call afterwards throws
|
|
798
|
-
* {@link RaterError} `'DESTROYED'`.
|
|
799
|
-
*/
|
|
800
|
-
export declare class ProgramManager implements ProgramManagerInterface {
|
|
801
|
-
#private;
|
|
802
|
-
constructor(engine: ReasonInterface, options?: ProgramManagerOptions);
|
|
803
|
-
get emitter(): EmitterInterface<ProgramManagerEventMap>;
|
|
804
|
-
get size(): number;
|
|
805
|
-
has(id: string): boolean;
|
|
806
|
-
program(id: string): ProgramInterface | undefined;
|
|
807
|
-
programs(): readonly ProgramInterface[];
|
|
808
|
-
add(definition: ProgramDefinition, options?: ProgramOptions): ProgramInterface;
|
|
809
|
-
remove(ids: readonly string[]): boolean;
|
|
810
|
-
remove(id: string): boolean;
|
|
811
|
-
remove(): void;
|
|
812
|
-
destroy(): void;
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
/**
|
|
816
|
-
* The push observation surface of a {@link ProgramManagerInterface} (AGENTS §13).
|
|
817
|
-
*/
|
|
818
|
-
export declare type ProgramManagerEventMap = {
|
|
819
|
-
/** A program was added — carries its id. */
|
|
820
|
-
readonly add: readonly [id: string];
|
|
821
|
-
/** A program was removed — carries its id. */
|
|
822
|
-
readonly remove: readonly [id: string];
|
|
823
|
-
/** The manager was destroyed. */
|
|
824
|
-
readonly destroy: readonly [];
|
|
825
|
-
};
|
|
826
|
-
|
|
827
|
-
/** An ordered manager over compiled programs (AGENTS §9). */
|
|
828
|
-
export declare interface ProgramManagerInterface {
|
|
829
|
-
readonly emitter: EmitterInterface<ProgramManagerEventMap>;
|
|
830
|
-
readonly size: number;
|
|
831
|
-
has(id: string): boolean;
|
|
832
|
-
program(id: string): ProgramInterface | undefined;
|
|
833
|
-
programs(): readonly ProgramInterface[];
|
|
834
|
-
add(definition: ProgramDefinition, options?: ProgramOptions): ProgramInterface;
|
|
835
|
-
remove(ids: readonly string[]): boolean;
|
|
836
|
-
remove(id: string): boolean;
|
|
837
|
-
remove(): void;
|
|
838
|
-
destroy(): void;
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
/** Options for `createProgramManager` / the `ProgramManager` constructor. */
|
|
842
|
-
export declare interface ProgramManagerOptions {
|
|
843
|
-
readonly on?: EmitterHooks<ProgramManagerEventMap>;
|
|
844
|
-
readonly error?: EmitterErrorHandler;
|
|
845
|
-
readonly total?: TotalHandler;
|
|
846
|
-
readonly labels?: Readonly<Record<string, string>>;
|
|
847
|
-
readonly validate?: boolean;
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
/** Runtime options for one compiled program. */
|
|
851
|
-
export declare interface ProgramOptions {
|
|
852
|
-
readonly total?: TotalHandler;
|
|
853
|
-
readonly labels?: Readonly<Record<string, string>>;
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
/** One program's rating outcome. */
|
|
857
|
-
export declare interface ProgramResult {
|
|
858
|
-
readonly id: string;
|
|
859
|
-
readonly name: string;
|
|
860
|
-
readonly eligibility: Eligibility;
|
|
861
|
-
readonly status: Status;
|
|
862
|
-
/**
|
|
863
|
-
* @remarks
|
|
864
|
-
* Present ONLY when the program HAS an `authority`, the authority result is
|
|
865
|
-
* `logical`, NO `limit` determinations fired, and the authority result
|
|
866
|
-
* carries no errors — absent otherwise.
|
|
867
|
-
*/
|
|
868
|
-
readonly decision?: Decision;
|
|
869
|
-
readonly lines: readonly LineResult[];
|
|
870
|
-
readonly determinations: readonly Determination[];
|
|
871
|
-
readonly derivations: readonly Worksheet[];
|
|
872
|
-
readonly total?: number;
|
|
873
|
-
readonly success: boolean;
|
|
874
|
-
readonly trace: readonly string[];
|
|
875
|
-
readonly errors: readonly string[];
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
/**
|
|
879
|
-
* Assemble a final {@link ProgramResult} from its rated parts.
|
|
880
|
-
*
|
|
881
|
-
* @param definition - The authored program definition
|
|
882
|
-
* @param lines - The program's rated lines
|
|
883
|
-
* @param determinations - The program-scoped determinations
|
|
884
|
-
* @param derivations - The pass-level quantitative worksheets
|
|
885
|
-
* @param total - The program's total amount, when the total handler produced one
|
|
886
|
-
* @param decision - The authority-derived decision, when one was reached
|
|
887
|
-
* @param trace - The accumulated reasoning trace
|
|
888
|
-
* @param errors - The accumulated reasoning errors
|
|
889
|
-
* @returns A fresh program result
|
|
890
|
-
*/
|
|
891
|
-
export declare function programResult(definition: ProgramDefinition, lines: readonly LineResult[], determinations: readonly Determination[], derivations: readonly Worksheet[], total: number | undefined, decision: Decision | undefined, trace: readonly string[], errors: readonly string[]): ProgramResult;
|
|
892
|
-
|
|
893
|
-
/**
|
|
894
|
-
* Build a rated {@link LineResult} from a line's evaluated
|
|
895
|
-
* {@link QuantitativeResult}.
|
|
896
|
-
*
|
|
897
|
-
* @param definition - The authored line definition
|
|
898
|
-
* @param result - The evaluated quantitative result
|
|
899
|
-
* @param determinations - The line-scoped determinations
|
|
900
|
-
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
901
|
-
* @returns A fresh line result
|
|
902
|
-
*/
|
|
903
|
-
export declare function ratedLine(definition: LineDefinition, result: QuantitativeResult, determinations: readonly Determination[], labels?: Readonly<Record<string, string>>): LineResult;
|
|
904
|
-
|
|
905
|
-
/**
|
|
906
|
-
* The rating orchestrator — owns the shared reasoning engine and an ordered
|
|
907
|
-
* {@link ProgramManager}, and projects results into the rating domain
|
|
908
|
-
* vocabulary.
|
|
909
|
-
*
|
|
910
|
-
* @remarks
|
|
911
|
-
* Constructs ONE shared reason engine (quantitative + logical reasoners,
|
|
912
|
-
* `bail: false`) and injects it into every compiled program — Rater performs
|
|
913
|
-
* NO evaluation arithmetic of its own; it only orchestrates and projects. The
|
|
914
|
-
* batch `rate` overload is declared FIRST (AGENTS §9.2) so an array subject
|
|
915
|
-
* resolves to the batch form. `destroy()` tears down the manager, then the
|
|
916
|
-
* engine, then the emitter LAST (AGENTS §13); afterwards every other method
|
|
917
|
-
* throws {@link RaterError} `'DESTROYED'`.
|
|
918
|
-
*/
|
|
919
|
-
export declare class Rater implements RaterInterface {
|
|
920
|
-
#private;
|
|
921
|
-
constructor(options?: RaterOptions);
|
|
922
|
-
get emitter(): EmitterInterface<RaterEventMap>;
|
|
923
|
-
get programs(): ProgramManagerInterface;
|
|
924
|
-
rate(subjects: readonly Subject[]): AggregateResult;
|
|
925
|
-
rate(subject: Subject): SubjectResult;
|
|
926
|
-
destroy(): void;
|
|
927
|
-
}
|
|
928
|
-
|
|
929
|
-
/**
|
|
930
|
-
* A coded programmer error thrown by the rating layer.
|
|
931
|
-
*
|
|
932
|
-
* @remarks
|
|
933
|
-
* `DUPLICATE` — a program id collision on `ProgramManager.add`. `MISSING` — an
|
|
934
|
-
* unknown authored line reference at compile time.
|
|
935
|
-
* `DEFINITION` — a program definition failed `isProgramDefinition`. `MISMATCH` —
|
|
936
|
-
* a rated subject is not a record, or uses a reserved working-subject key.
|
|
937
|
-
* `DESTROYED` — use of a destroyed entity.
|
|
938
|
-
*/
|
|
939
|
-
export declare class RaterError extends Error {
|
|
940
|
-
readonly code: RaterErrorCode;
|
|
941
|
-
readonly context?: Readonly<Record<string, unknown>>;
|
|
942
|
-
constructor(code: RaterErrorCode, message: string, context?: Readonly<Record<string, unknown>>);
|
|
943
|
-
}
|
|
944
|
-
|
|
945
|
-
/** A coded {@link RaterError} programmer-error code. */
|
|
946
|
-
export declare type RaterErrorCode = 'DUPLICATE' | 'MISSING' | 'DEFINITION' | 'MISMATCH' | 'DESTROYED';
|
|
947
|
-
|
|
948
|
-
/**
|
|
949
|
-
* The push observation surface of a {@link RaterInterface} (AGENTS §13).
|
|
950
|
-
*
|
|
951
|
-
* @remarks
|
|
952
|
-
* `rate` fires once per rated subject (batch or single); `aggregate` fires once
|
|
953
|
-
* per batch call; `determine` fires per APPLIED determination; `decide` fires
|
|
954
|
-
* once a program derives a decision.
|
|
955
|
-
*/
|
|
956
|
-
export declare type RaterEventMap = {
|
|
957
|
-
/** A subject was rated — carries its result. */
|
|
958
|
-
readonly rate: readonly [result: SubjectResult];
|
|
959
|
-
/** A batch was rated — carries the aggregate result. */
|
|
960
|
-
readonly aggregate: readonly [result: AggregateResult];
|
|
961
|
-
/** An applied determination was produced — carries it. */
|
|
962
|
-
readonly determine: readonly [determination: Determination];
|
|
963
|
-
/** A program derived a decision — carries the decision and its result. */
|
|
964
|
-
readonly decide: readonly [decision: Decision, result: ProgramResult];
|
|
965
|
-
};
|
|
966
|
-
|
|
967
|
-
/**
|
|
968
|
-
* The rating orchestrator over the program manager and the shared reasoning
|
|
969
|
-
* engine.
|
|
970
|
-
*
|
|
971
|
-
* @remarks
|
|
972
|
-
* The batch `rate` overload is declared FIRST (AGENTS §9.2) so an array subject
|
|
973
|
-
* resolves to the batch form.
|
|
974
|
-
*/
|
|
975
|
-
export declare interface RaterInterface {
|
|
976
|
-
readonly emitter: EmitterInterface<RaterEventMap>;
|
|
977
|
-
readonly programs: ProgramManagerInterface;
|
|
978
|
-
rate(subjects: readonly Subject[]): AggregateResult;
|
|
979
|
-
rate(subject: Subject): SubjectResult;
|
|
980
|
-
destroy(): void;
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
/** Options for `createRater` / the `Rater` constructor. */
|
|
984
|
-
export declare interface RaterOptions {
|
|
985
|
-
readonly on?: EmitterHooks<RaterEventMap>;
|
|
986
|
-
readonly error?: EmitterErrorHandler;
|
|
987
|
-
readonly total?: TotalHandler;
|
|
988
|
-
readonly programs?: readonly ProgramDefinition[];
|
|
989
|
-
readonly labels?: Readonly<Record<string, string>>;
|
|
990
|
-
readonly validate?: boolean;
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
/**
|
|
994
|
-
* Join a {@link QuantitativeDefinition} and its {@link QuantitativeResult} into
|
|
995
|
-
* a {@link Worksheet} — the rating audit trail.
|
|
996
|
-
*
|
|
997
|
-
* @param definition - The authored quantitative definition
|
|
998
|
-
* @param result - The evaluated quantitative result
|
|
999
|
-
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
1000
|
-
* @returns A fresh worksheet
|
|
1001
|
-
*/
|
|
1002
|
-
export declare function resultsWorksheet(definition: QuantitativeDefinition, result: QuantitativeResult, labels?: Readonly<Record<string, string>>): Worksheet;
|
|
1003
|
-
|
|
1004
|
-
/**
|
|
1005
|
-
* Convert fired logical {@link RuleResult}s into line- or program-scoped
|
|
1006
|
-
* {@link Determination}s.
|
|
1007
|
-
*
|
|
1008
|
-
* @param definition - The authored logical definition
|
|
1009
|
-
* @param result - The evaluated logical result
|
|
1010
|
-
* @param rulings - Authored consequences, keyed by rule id
|
|
1011
|
-
* @param working - The working subject the rules ran against
|
|
1012
|
-
* @param line - The line id this pass is scoped to, when it is line-scoped
|
|
1013
|
-
* @param evaluator - The shared reason check evaluator
|
|
1014
|
-
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
1015
|
-
* @returns A fresh list of determinations
|
|
1016
|
-
*/
|
|
1017
|
-
export declare function rulesToDeterminations(definition: LogicalDefinition, result: LogicalResult, rulings: Readonly<Record<string, Ruling>> | undefined, working: Subject, line: string | undefined, evaluator: EvaluatorInterface, labels?: Readonly<Record<string, string>>): readonly Determination[];
|
|
1018
|
-
|
|
1019
|
-
/** An authored consequence routed to a fired rule by its id. */
|
|
1020
|
-
export declare interface Ruling {
|
|
1021
|
-
readonly effect: Effect;
|
|
1022
|
-
readonly line?: string;
|
|
1023
|
-
readonly message?: string;
|
|
1024
|
-
}
|
|
196
|
+
* @remarks
|
|
197
|
+
* `worksheet` is always present — even a failed evaluation resolves to a
|
|
198
|
+
* type-shaped failure worksheet, so a `LineResult` is always constructible.
|
|
199
|
+
* `amount` is present ONLY when `success` is `true`.
|
|
200
|
+
*/
|
|
201
|
+
export declare interface LineResult {
|
|
202
|
+
readonly id: string;
|
|
203
|
+
readonly name: string;
|
|
204
|
+
readonly amount?: number;
|
|
205
|
+
readonly worksheet: Worksheet;
|
|
206
|
+
readonly success: boolean;
|
|
207
|
+
}
|
|
1025
208
|
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
209
|
+
/**
|
|
210
|
+
* Build a rated {@link LineResult} from a line's evaluated
|
|
211
|
+
* {@link QuantitativeResult}.
|
|
212
|
+
*
|
|
213
|
+
* @param definition - The authored line definition
|
|
214
|
+
* @param result - The evaluated quantitative result
|
|
215
|
+
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
216
|
+
* @returns A fresh line result
|
|
217
|
+
*
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* import { createQuantitativeReasoner, createReason, quantitativeDefinition } from '@orkestrel/reason'
|
|
221
|
+
* import { lineDefinition, ratedLine } from '@orkestrel/rater'
|
|
222
|
+
*
|
|
223
|
+
* const line = lineDefinition('base', 'Base', quantitativeDefinition('base', 'Base', []))
|
|
224
|
+
* const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, line.rate)
|
|
225
|
+
* if (result.reasoning === 'quantitative') ratedLine(line, result) // amount present only when success
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
export declare function ratedLine(definition: LineDefinition, result: QuantitativeResult, labels?: Readonly<Record<string, string>>): LineResult;
|
|
1042
229
|
|
|
1043
|
-
|
|
1044
|
-
|
|
230
|
+
/**
|
|
231
|
+
* The rating orchestrator — owns (or receives) the shared quantitative
|
|
232
|
+
* reasoning engine and projects results into the rating domain vocabulary.
|
|
233
|
+
*
|
|
234
|
+
* @remarks
|
|
235
|
+
* When no `engine` is injected, `Rater` builds and OWNS its own
|
|
236
|
+
* quantitative-only engine (`bail: false`) — Rater performs NO evaluation
|
|
237
|
+
* arithmetic of its own; it only orchestrates and projects. The
|
|
238
|
+
* array-of-lines `rate` overload is declared FIRST (AGENTS §9.2). `destroy()`
|
|
239
|
+
* destroys an OWNED engine, then the emitter LAST (AGENTS §13); an INJECTED
|
|
240
|
+
* engine is never destroyed. Afterwards every other method throws
|
|
241
|
+
* {@link RaterError} `'DESTROYED'`.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```ts
|
|
245
|
+
* import { Rater } from '@orkestrel/rater'
|
|
246
|
+
*
|
|
247
|
+
* const rater = new Rater()
|
|
248
|
+
* rater.rate([], { id: 'subject-1' }) // { lines: [], success: true }
|
|
249
|
+
* rater.destroy()
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
export declare class Rater implements RaterInterface {
|
|
253
|
+
#private;
|
|
254
|
+
constructor(options?: RaterOptions);
|
|
255
|
+
get emitter(): EmitterInterface<RaterEventMap>;
|
|
256
|
+
rate(lines: readonly LineDefinition[], subject: Subject): RatingResult;
|
|
257
|
+
rate(definition: RatingDefinition, subject: Subject): RatingResult;
|
|
258
|
+
destroy(): void;
|
|
259
|
+
}
|
|
1045
260
|
|
|
1046
|
-
|
|
1047
|
-
|
|
261
|
+
/**
|
|
262
|
+
* A coded programmer error thrown by the rating layer.
|
|
263
|
+
*
|
|
264
|
+
* @remarks
|
|
265
|
+
* `DEFINITION` — the `rate` input failed both the array-of-lines and rating
|
|
266
|
+
* definition validation. `MISMATCH` — a rated subject is not a record.
|
|
267
|
+
* `DESTROYED` — use of a destroyed entity.
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* ```ts
|
|
271
|
+
* import { RaterError } from '@orkestrel/rater'
|
|
272
|
+
*
|
|
273
|
+
* throw new RaterError('MISMATCH', 'Subject must be a record')
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
export declare class RaterError extends Error {
|
|
277
|
+
readonly code: RaterErrorCode;
|
|
278
|
+
readonly context?: Readonly<Record<string, unknown>>;
|
|
279
|
+
constructor(code: RaterErrorCode, message: string, context?: Readonly<Record<string, unknown>>);
|
|
280
|
+
}
|
|
1048
281
|
|
|
1049
|
-
|
|
1050
|
-
|
|
282
|
+
/** A coded {@link RaterError} programmer-error code. */
|
|
283
|
+
export declare type RaterErrorCode = 'DEFINITION' | 'MISMATCH' | 'DESTROYED';
|
|
1051
284
|
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
285
|
+
/**
|
|
286
|
+
* The push observation surface of a {@link RaterInterface} (AGENTS §13).
|
|
287
|
+
*
|
|
288
|
+
* @remarks
|
|
289
|
+
* `rate` fires once per `rate` call, carrying the rated subject and the result.
|
|
290
|
+
*/
|
|
291
|
+
export declare type RaterEventMap = {
|
|
292
|
+
/** A subject was rated — carries the subject and its result. */
|
|
293
|
+
readonly rate: readonly [subject: Subject, result: RatingResult];
|
|
294
|
+
};
|
|
1060
295
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
296
|
+
/**
|
|
297
|
+
* The rating orchestrator over the shared quantitative reasoning engine.
|
|
298
|
+
*
|
|
299
|
+
* @remarks
|
|
300
|
+
* The array-of-lines `rate` overload is declared FIRST (AGENTS §9.2). Both
|
|
301
|
+
* overloads rate a SINGLE subject — there is no batch-of-subjects overload.
|
|
302
|
+
*/
|
|
303
|
+
export declare interface RaterInterface {
|
|
304
|
+
readonly emitter: EmitterInterface<RaterEventMap>;
|
|
305
|
+
rate(lines: readonly LineDefinition[], subject: Subject): RatingResult;
|
|
306
|
+
rate(definition: RatingDefinition, subject: Subject): RatingResult;
|
|
307
|
+
destroy(): void;
|
|
308
|
+
}
|
|
1066
309
|
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
310
|
+
/**
|
|
311
|
+
* Options for `createRater` / the `Rater` constructor.
|
|
312
|
+
*
|
|
313
|
+
* @remarks
|
|
314
|
+
* `engine` — an injected {@link ReasonInterface}; when omitted, `Rater` builds
|
|
315
|
+
* and OWNS its own quantitative-only engine (`bail: false`), destroying it on
|
|
316
|
+
* `destroy()`. `total` — a {@link TotalHandler} overriding the default
|
|
317
|
+
* {@link sumAmounts} projection. `labels` — field-to-label display overrides
|
|
318
|
+
* threaded into every resolved {@link Evidence}.
|
|
319
|
+
*/
|
|
320
|
+
export declare interface RaterOptions {
|
|
321
|
+
readonly on?: EmitterHooks<RaterEventMap>;
|
|
322
|
+
readonly error?: EmitterErrorHandler;
|
|
323
|
+
readonly engine?: ReasonInterface;
|
|
324
|
+
readonly total?: TotalHandler;
|
|
325
|
+
readonly labels?: Readonly<Record<string, string>>;
|
|
326
|
+
}
|
|
1074
327
|
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
328
|
+
/**
|
|
329
|
+
* A pure authored rating — a named, ordered set of lines.
|
|
330
|
+
*
|
|
331
|
+
* @remarks
|
|
332
|
+
* `rate` accepts either a plain `readonly LineDefinition[]` or a full
|
|
333
|
+
* `RatingDefinition`; the array overload is the terse path, this shape adds
|
|
334
|
+
* an id, a name, and optional metadata for authoring and storage.
|
|
335
|
+
*/
|
|
336
|
+
export declare interface RatingDefinition {
|
|
337
|
+
readonly id: string;
|
|
338
|
+
readonly name: string;
|
|
339
|
+
readonly description?: string;
|
|
340
|
+
readonly lines: readonly LineDefinition[];
|
|
341
|
+
readonly metadata?: JSONValue;
|
|
342
|
+
}
|
|
1080
343
|
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
344
|
+
/**
|
|
345
|
+
* Build a {@link RatingDefinition}.
|
|
346
|
+
*
|
|
347
|
+
* @param id - The rating id
|
|
348
|
+
* @param name - The display name
|
|
349
|
+
* @param lines - The rating's ordered lines
|
|
350
|
+
* @param overrides - Optional {@link RatingDefinition} fields merged over the defaults
|
|
351
|
+
* @returns A fresh rating definition
|
|
352
|
+
*
|
|
353
|
+
* @example
|
|
354
|
+
* ```ts
|
|
355
|
+
* import { lineDefinition, ratingDefinition } from '@orkestrel/rater'
|
|
356
|
+
* import { quantitativeDefinition } from '@orkestrel/reason'
|
|
357
|
+
*
|
|
358
|
+
* ratingDefinition('r1', 'Rating', [
|
|
359
|
+
* lineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', [])),
|
|
360
|
+
* ])
|
|
361
|
+
* ```
|
|
362
|
+
*/
|
|
363
|
+
export declare function ratingDefinition(id: string, name: string, lines: readonly LineDefinition[], overrides?: Partial<Omit<RatingDefinition, 'id' | 'name' | 'lines'>>): RatingDefinition;
|
|
1091
364
|
|
|
1092
|
-
|
|
1093
|
-
|
|
365
|
+
/**
|
|
366
|
+
* A rated outcome across every line of one `rate` call.
|
|
367
|
+
*
|
|
368
|
+
* @remarks
|
|
369
|
+
* `total` is derived by the {@link TotalHandler} (default {@link sumAmounts})
|
|
370
|
+
* over `lines` — only successfully rated lines carry an `amount`. `success`
|
|
371
|
+
* is `true` only when every line succeeded.
|
|
372
|
+
*/
|
|
373
|
+
export declare interface RatingResult {
|
|
374
|
+
readonly lines: readonly LineResult[];
|
|
375
|
+
readonly total?: number;
|
|
376
|
+
readonly success: boolean;
|
|
377
|
+
}
|
|
1094
378
|
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
379
|
+
/**
|
|
380
|
+
* Join a {@link QuantitativeDefinition} and its {@link QuantitativeResult} into
|
|
381
|
+
* a {@link Worksheet} — the rating audit trail.
|
|
382
|
+
*
|
|
383
|
+
* @param definition - The authored quantitative definition
|
|
384
|
+
* @param result - The evaluated quantitative result
|
|
385
|
+
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
386
|
+
* @returns A fresh worksheet
|
|
387
|
+
*
|
|
388
|
+
* @example
|
|
389
|
+
* ```ts
|
|
390
|
+
* import { createQuantitativeReasoner, createReason, factorGroup, quantitativeDefinition, staticFactor } from '@orkestrel/reason'
|
|
391
|
+
* import { resultsWorksheet } from '@orkestrel/rater'
|
|
392
|
+
*
|
|
393
|
+
* const definition = quantitativeDefinition('base', 'Base', [factorGroup('g', 'sum', [staticFactor('flat', 100)])])
|
|
394
|
+
* const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, definition)
|
|
395
|
+
* if (result.reasoning === 'quantitative') resultsWorksheet(definition, result) // the full audit trail
|
|
396
|
+
* ```
|
|
397
|
+
*/
|
|
398
|
+
export declare function resultsWorksheet(definition: QuantitativeDefinition, result: QuantitativeResult, labels?: Readonly<Record<string, string>>): Worksheet;
|
|
399
|
+
|
|
400
|
+
/** A worksheet derivation step stage. */
|
|
401
|
+
export declare type Stage = 'factor' | 'group' | 'total';
|
|
402
|
+
|
|
403
|
+
/** A display-neutral worksheet derivation step. */
|
|
404
|
+
export declare interface Step {
|
|
405
|
+
readonly stage: Stage;
|
|
406
|
+
readonly id?: string;
|
|
407
|
+
readonly name?: string;
|
|
408
|
+
readonly value: number;
|
|
409
|
+
readonly expression?: string;
|
|
410
|
+
}
|
|
1108
411
|
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
412
|
+
/**
|
|
413
|
+
* Sum defined line amounts.
|
|
414
|
+
*
|
|
415
|
+
* @param lines - The rated lines
|
|
416
|
+
* @returns The sum of every line's `amount`, or `undefined` when no line has one
|
|
417
|
+
*
|
|
418
|
+
* @example
|
|
419
|
+
* ```ts
|
|
420
|
+
* import { createQuantitativeReasoner, createReason, factorGroup, quantitativeDefinition, staticFactor } from '@orkestrel/reason'
|
|
421
|
+
* import { lineDefinition, ratedLine, sumAmounts } from '@orkestrel/rater'
|
|
422
|
+
*
|
|
423
|
+
* const rate = quantitativeDefinition('base', 'Base', [factorGroup('g', 'sum', [staticFactor('flat', 100)])])
|
|
424
|
+
* const line = lineDefinition('base', 'Base', rate)
|
|
425
|
+
* const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, rate)
|
|
426
|
+
* if (result.reasoning === 'quantitative') sumAmounts([ratedLine(line, result)]) // 100
|
|
427
|
+
* ```
|
|
428
|
+
*/
|
|
429
|
+
export declare function sumAmounts(lines: readonly LineResult[]): number | undefined;
|
|
430
|
+
|
|
431
|
+
/** A pure total port over resolved lines. */
|
|
432
|
+
export declare type TotalHandler = (lines: readonly LineResult[]) => number | undefined;
|
|
433
|
+
|
|
434
|
+
/** A quantitative definition joined to its result — the rating audit trail. */
|
|
435
|
+
export declare interface Worksheet {
|
|
436
|
+
readonly id: string;
|
|
437
|
+
readonly name: string;
|
|
438
|
+
readonly aggregation: Aggregation;
|
|
439
|
+
readonly precision?: number;
|
|
440
|
+
readonly value: number;
|
|
441
|
+
readonly groups: readonly WorksheetGroup[];
|
|
442
|
+
readonly steps: readonly Step[];
|
|
443
|
+
readonly trace: readonly string[];
|
|
444
|
+
readonly errors: readonly string[];
|
|
445
|
+
readonly success: boolean;
|
|
446
|
+
}
|
|
1118
447
|
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
448
|
+
/** A resolved quantitative factor, joined to its authored metadata. */
|
|
449
|
+
export declare interface WorksheetFactor {
|
|
450
|
+
readonly id: string;
|
|
451
|
+
readonly name?: string;
|
|
452
|
+
readonly description?: string;
|
|
453
|
+
readonly applied: boolean;
|
|
454
|
+
readonly value?: number;
|
|
455
|
+
readonly evidence: readonly Evidence[];
|
|
456
|
+
}
|
|
1128
457
|
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
458
|
+
/**
|
|
459
|
+
* Join one authored quantitative factor to its evaluated {@link FactorResult}.
|
|
460
|
+
*
|
|
461
|
+
* @param definition - The authored factor
|
|
462
|
+
* @param results - The group's factor results
|
|
463
|
+
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
464
|
+
* @returns A fresh worksheet factor
|
|
465
|
+
*
|
|
466
|
+
* @example
|
|
467
|
+
* ```ts
|
|
468
|
+
* import { fieldFactor } from '@orkestrel/reason'
|
|
469
|
+
* import { worksheetFactor } from '@orkestrel/rater'
|
|
470
|
+
*
|
|
471
|
+
* const factor = fieldFactor('seats', 'seats')
|
|
472
|
+
* worksheetFactor(factor, [{ id: 'seats', applied: true, value: 10 }])
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
export declare function worksheetFactor(definition: Factor, results: readonly FactorResult[], labels?: Readonly<Record<string, string>>): WorksheetFactor;
|
|
476
|
+
|
|
477
|
+
/** A resolved quantitative group, joined to its authored metadata. */
|
|
478
|
+
export declare interface WorksheetGroup {
|
|
479
|
+
readonly id: string;
|
|
480
|
+
readonly name?: string;
|
|
481
|
+
readonly description?: string;
|
|
482
|
+
readonly applied: boolean;
|
|
483
|
+
readonly value: number;
|
|
484
|
+
readonly factors: readonly WorksheetFactor[];
|
|
485
|
+
}
|
|
1138
486
|
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
487
|
+
/**
|
|
488
|
+
* Join one authored quantitative group to its evaluated {@link GroupResult}.
|
|
489
|
+
*
|
|
490
|
+
* @param definition - The authored group
|
|
491
|
+
* @param results - The definition's group results
|
|
492
|
+
* @param labels - Optional field-to-label overrides, keyed by dot-joined field
|
|
493
|
+
* @returns A fresh worksheet group
|
|
494
|
+
*
|
|
495
|
+
* @example
|
|
496
|
+
* ```ts
|
|
497
|
+
* import { factorGroup, staticFactor } from '@orkestrel/reason'
|
|
498
|
+
* import { worksheetGroup } from '@orkestrel/rater'
|
|
499
|
+
*
|
|
500
|
+
* const group = factorGroup('charge', 'sum', [staticFactor('base', 100)])
|
|
501
|
+
* worksheetGroup(group, [{ id: 'charge', applied: true, value: 100, factors: [] }])
|
|
502
|
+
* ```
|
|
503
|
+
*/
|
|
504
|
+
export declare function worksheetGroup(definition: QuantitativeDefinition['groups'][number], results: readonly GroupResult[], labels?: Readonly<Record<string, string>>): WorksheetGroup;
|
|
1148
505
|
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
506
|
+
/**
|
|
507
|
+
* Build one display-neutral {@link Step} row.
|
|
508
|
+
*
|
|
509
|
+
* @param stage - The step's stage
|
|
510
|
+
* @param id - The stage's authored id, when it has one
|
|
511
|
+
* @param name - The stage's authored name, when it has one
|
|
512
|
+
* @param value - The stage's resolved value
|
|
513
|
+
* @param expression - A display-neutral expression string
|
|
514
|
+
* @returns A fresh step
|
|
515
|
+
*
|
|
516
|
+
* @example
|
|
517
|
+
* ```ts
|
|
518
|
+
* import { worksheetStep } from '@orkestrel/rater'
|
|
519
|
+
*
|
|
520
|
+
* worksheetStep('total', 'quote', 'Quote', 110, 'sum = 110')
|
|
521
|
+
* // { stage: 'total', id: 'quote', name: 'Quote', value: 110, expression: 'sum = 110' }
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
524
|
+
export declare function worksheetStep(stage: Stage, id: string | undefined, name: string | undefined, value: number, expression: string): Step;
|
|
1160
525
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
526
|
+
/**
|
|
527
|
+
* Build the ordered {@link Step} rows for a resolved {@link Worksheet}.
|
|
528
|
+
*
|
|
529
|
+
* @param definition - The authored quantitative definition
|
|
530
|
+
* @param result - The evaluated quantitative result
|
|
531
|
+
* @param groups - The definition's already-joined worksheet groups
|
|
532
|
+
* @returns A fresh, ordered list of steps: applied factors, then groups, then the total
|
|
533
|
+
*
|
|
534
|
+
* @example
|
|
535
|
+
* ```ts
|
|
536
|
+
* import { createQuantitativeReasoner, createReason, factorGroup, quantitativeDefinition, staticFactor } from '@orkestrel/reason'
|
|
537
|
+
* import { worksheetGroup, worksheetSteps } from '@orkestrel/rater'
|
|
538
|
+
*
|
|
539
|
+
* const definition = quantitativeDefinition('base', 'Base', [factorGroup('g', 'sum', [staticFactor('flat', 100)])])
|
|
540
|
+
* const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, definition)
|
|
541
|
+
* if (result.reasoning === 'quantitative') {
|
|
542
|
+
* worksheetSteps(definition, result, definition.groups.map((group) => worksheetGroup(group, result.groups)))
|
|
543
|
+
* }
|
|
544
|
+
* ```
|
|
545
|
+
*/
|
|
546
|
+
export declare function worksheetSteps(definition: QuantitativeDefinition, result: QuantitativeResult, groups: readonly WorksheetGroup[]): readonly Step[];
|
|
1170
547
|
|
|
1171
|
-
|
|
548
|
+
export { }
|