@orkestrel/rater 0.0.9 → 0.0.10

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.
@@ -82,6 +82,27 @@ export declare interface Evidence {
82
82
  */
83
83
  export declare function evidenceCheck(check: Check, actual: unknown, met: boolean | undefined, labels?: Readonly<Record<string, string>>): Evidence;
84
84
 
85
+ /**
86
+ * Determine whether a value is an open result-side {@link Evidence} object.
87
+ *
88
+ * @remarks
89
+ * Unknown members, prototypes, and class instances are admitted. Arrays are
90
+ * refused. `expected` and `actual` are `unknown`, so this guard does not read or
91
+ * check them; either member may also be absent because `objectOf` reads declared
92
+ * members rather than requiring or enumerating own keys.
93
+ *
94
+ * @param value - The value to test
95
+ * @returns `true` when every checked `Evidence` member conforms
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * import { isEvidence } from '@orkestrel/rater'
100
+ *
101
+ * isEvidence({ field: 'age', comparison: 'above', expected: 18, actual: 25, met: true }) // true
102
+ * ```
103
+ */
104
+ export declare function isEvidence(value: unknown): value is Evidence;
105
+
85
106
  /**
86
107
  * Determine whether a value is an exact {@link LineDefinition} record.
87
108
  *
@@ -102,6 +123,26 @@ export declare function evidenceCheck(check: Check, actual: unknown, met: boolea
102
123
  */
103
124
  export declare function isLineDefinition(value: unknown): value is LineDefinition;
104
125
 
126
+ /**
127
+ * Determine whether a value is an open {@link LineResult} object.
128
+ *
129
+ * @remarks
130
+ * Unknown members, prototypes, and class instances are admitted. Arrays are
131
+ * refused. `amount` may be absent or read as `undefined`; when present it stays
132
+ * a plain JavaScript `number` without a finite or range refinement.
133
+ *
134
+ * @param value - The value to test
135
+ * @returns `true` when every published line-result member conforms
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * import { isLineResult } from '@orkestrel/rater'
140
+ *
141
+ * isLineResult({ id: 'base', name: 'Base', worksheet: { id: 'base', name: 'Base', aggregation: 'sum', value: 0, groups: [], steps: [], trace: [], errors: [], success: false }, success: false }) // true
142
+ * ```
143
+ */
144
+ export declare function isLineResult(value: unknown): value is LineResult;
145
+
105
146
  /**
106
147
  * Narrow a caught value to a {@link RaterError}.
107
148
  *
@@ -140,6 +181,27 @@ export declare function isRaterError(value: unknown): value is RaterError;
140
181
  */
141
182
  export declare function isRatingDefinition(value: unknown): value is RatingDefinition;
142
183
 
184
+ /**
185
+ * Determine whether a value is an open {@link RatingResult} object.
186
+ *
187
+ * @remarks
188
+ * Use this guard for a result returned by a borrowed `RaterInterface`. Unknown
189
+ * members, prototypes, and class instances are admitted. Arrays are refused.
190
+ * `total` may be absent or read as `undefined`; when present it stays a plain
191
+ * JavaScript `number` without a finite or range refinement.
192
+ *
193
+ * @param value - The value to test
194
+ * @returns `true` when every published rating-result member conforms
195
+ *
196
+ * @example
197
+ * ```ts
198
+ * import { isRatingResult } from '@orkestrel/rater'
199
+ *
200
+ * isRatingResult({ lines: [], success: true }) // true
201
+ * ```
202
+ */
203
+ export declare function isRatingResult(value: unknown): value is RatingResult;
204
+
143
205
  /**
144
206
  * Determine whether a value is a {@link Stage} literal.
145
207
  *
@@ -156,6 +218,82 @@ export declare function isRatingDefinition(value: unknown): value is RatingDefin
156
218
  */
157
219
  export declare const isStage: Guard<Stage>;
158
220
 
221
+ /**
222
+ * Determine whether a value is an open {@link Step} result object.
223
+ *
224
+ * @remarks
225
+ * Unknown members, prototypes, and class instances are admitted. Arrays are
226
+ * refused. Optional members may be absent or read as `undefined`.
227
+ *
228
+ * @param value - The value to test
229
+ * @returns `true` when every published worksheet-step member conforms
230
+ *
231
+ * @example
232
+ * ```ts
233
+ * import { isStep } from '@orkestrel/rater'
234
+ *
235
+ * isStep({ stage: 'total', value: 100 }) // true
236
+ * ```
237
+ */
238
+ export declare function isStep(value: unknown): value is Step;
239
+
240
+ /**
241
+ * Determine whether a value is an open {@link Worksheet} result object.
242
+ *
243
+ * @remarks
244
+ * Unknown members, prototypes, and class instances are admitted. Arrays are
245
+ * refused. Optional members may be absent or read as `undefined`.
246
+ *
247
+ * @param value - The value to test
248
+ * @returns `true` when every published worksheet member conforms
249
+ *
250
+ * @example
251
+ * ```ts
252
+ * import { isWorksheet } from '@orkestrel/rater'
253
+ *
254
+ * isWorksheet({ id: 'quote', name: 'Quote', aggregation: 'sum', value: 0, groups: [], steps: [], trace: [], errors: [], success: true }) // true
255
+ * ```
256
+ */
257
+ export declare function isWorksheet(value: unknown): value is Worksheet;
258
+
259
+ /**
260
+ * Determine whether a value is an open {@link WorksheetFactor} result object.
261
+ *
262
+ * @remarks
263
+ * Unknown members, prototypes, and class instances are admitted. Arrays are
264
+ * refused. Optional members may be absent or read as `undefined`.
265
+ *
266
+ * @param value - The value to test
267
+ * @returns `true` when every published worksheet-factor member conforms
268
+ *
269
+ * @example
270
+ * ```ts
271
+ * import { isWorksheetFactor } from '@orkestrel/rater'
272
+ *
273
+ * isWorksheetFactor({ id: 'base', applied: true, value: 100, evidence: [] }) // true
274
+ * ```
275
+ */
276
+ export declare function isWorksheetFactor(value: unknown): value is WorksheetFactor;
277
+
278
+ /**
279
+ * Determine whether a value is an open {@link WorksheetGroup} result object.
280
+ *
281
+ * @remarks
282
+ * Unknown members, prototypes, and class instances are admitted. Arrays are
283
+ * refused. Optional members may be absent or read as `undefined`.
284
+ *
285
+ * @param value - The value to test
286
+ * @returns `true` when every published worksheet-group member conforms
287
+ *
288
+ * @example
289
+ * ```ts
290
+ * import { isWorksheetGroup } from '@orkestrel/rater'
291
+ *
292
+ * isWorksheetGroup({ id: 'charges', applied: true, value: 100, factors: [] }) // true
293
+ * ```
294
+ */
295
+ export declare function isWorksheetGroup(value: unknown): value is WorksheetGroup;
296
+
159
297
  /**
160
298
  * One rateable line — a quantitative definition joined to display metadata.
161
299
  *
@@ -1,5 +1,5 @@
1
- import { arrayOf, isArray, isJSONValue, isString, literalOf, recordOf } from "@orkestrel/contract";
2
- import { buildErrorResult, createQuantitativeReasoner, createReason, formatField, isQuantitativeDefinition, isSubject } from "@orkestrel/reason";
1
+ import { arrayOf, isArray, isBoolean, isJSONValue, isNumber, isString, literalOf, objectOf, recordOf } from "@orkestrel/contract";
2
+ import { buildErrorResult, createQuantitativeReasoner, createReason, formatField, isAggregation, isComparison, isFieldPath, isQuantitativeDefinition, isSubject } from "@orkestrel/reason";
3
3
  import { Emitter } from "@orkestrel/emitter";
4
4
  //#region src/core/errors.ts
5
5
  /**
@@ -117,9 +117,265 @@ function isRatingDefinition(value) {
117
117
  metadata: isJSONValue
118
118
  }, ["description", "metadata"])(value);
119
119
  }
120
+ /**
121
+ * Determine whether a value is an open result-side {@link Evidence} object.
122
+ *
123
+ * @remarks
124
+ * Unknown members, prototypes, and class instances are admitted. Arrays are
125
+ * refused. `expected` and `actual` are `unknown`, so this guard does not read or
126
+ * check them; either member may also be absent because `objectOf` reads declared
127
+ * members rather than requiring or enumerating own keys.
128
+ *
129
+ * @param value - The value to test
130
+ * @returns `true` when every checked `Evidence` member conforms
131
+ *
132
+ * @example
133
+ * ```ts
134
+ * import { isEvidence } from '@orkestrel/rater'
135
+ *
136
+ * isEvidence({ field: 'age', comparison: 'above', expected: 18, actual: 25, met: true }) // true
137
+ * ```
138
+ */
139
+ function isEvidence(value) {
140
+ return objectOf({
141
+ field: isFieldPath,
142
+ label: isString,
143
+ comparison: isComparison,
144
+ met: isBoolean
145
+ }, [
146
+ "field",
147
+ "label",
148
+ "comparison",
149
+ "met"
150
+ ])(value);
151
+ }
152
+ /**
153
+ * Determine whether a value is an open {@link WorksheetFactor} result object.
154
+ *
155
+ * @remarks
156
+ * Unknown members, prototypes, and class instances are admitted. Arrays are
157
+ * refused. Optional members may be absent or read as `undefined`.
158
+ *
159
+ * @param value - The value to test
160
+ * @returns `true` when every published worksheet-factor member conforms
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * import { isWorksheetFactor } from '@orkestrel/rater'
165
+ *
166
+ * isWorksheetFactor({ id: 'base', applied: true, value: 100, evidence: [] }) // true
167
+ * ```
168
+ */
169
+ function isWorksheetFactor(value) {
170
+ return objectOf({
171
+ id: isString,
172
+ name: isString,
173
+ description: isString,
174
+ applied: isBoolean,
175
+ value: isNumber,
176
+ evidence: arrayOf(isEvidence)
177
+ }, [
178
+ "name",
179
+ "description",
180
+ "value"
181
+ ])(value);
182
+ }
183
+ /**
184
+ * Determine whether a value is an open {@link WorksheetGroup} result object.
185
+ *
186
+ * @remarks
187
+ * Unknown members, prototypes, and class instances are admitted. Arrays are
188
+ * refused. Optional members may be absent or read as `undefined`.
189
+ *
190
+ * @param value - The value to test
191
+ * @returns `true` when every published worksheet-group member conforms
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * import { isWorksheetGroup } from '@orkestrel/rater'
196
+ *
197
+ * isWorksheetGroup({ id: 'charges', applied: true, value: 100, factors: [] }) // true
198
+ * ```
199
+ */
200
+ function isWorksheetGroup(value) {
201
+ return objectOf({
202
+ id: isString,
203
+ name: isString,
204
+ description: isString,
205
+ applied: isBoolean,
206
+ value: isNumber,
207
+ factors: arrayOf(isWorksheetFactor)
208
+ }, ["name", "description"])(value);
209
+ }
210
+ /**
211
+ * Determine whether a value is an open {@link Step} result object.
212
+ *
213
+ * @remarks
214
+ * Unknown members, prototypes, and class instances are admitted. Arrays are
215
+ * refused. Optional members may be absent or read as `undefined`.
216
+ *
217
+ * @param value - The value to test
218
+ * @returns `true` when every published worksheet-step member conforms
219
+ *
220
+ * @example
221
+ * ```ts
222
+ * import { isStep } from '@orkestrel/rater'
223
+ *
224
+ * isStep({ stage: 'total', value: 100 }) // true
225
+ * ```
226
+ */
227
+ function isStep(value) {
228
+ return objectOf({
229
+ stage: isStage,
230
+ id: isString,
231
+ name: isString,
232
+ value: isNumber,
233
+ expression: isString
234
+ }, [
235
+ "id",
236
+ "name",
237
+ "expression"
238
+ ])(value);
239
+ }
240
+ /**
241
+ * Determine whether a value is an open {@link Worksheet} result object.
242
+ *
243
+ * @remarks
244
+ * Unknown members, prototypes, and class instances are admitted. Arrays are
245
+ * refused. Optional members may be absent or read as `undefined`.
246
+ *
247
+ * @param value - The value to test
248
+ * @returns `true` when every published worksheet member conforms
249
+ *
250
+ * @example
251
+ * ```ts
252
+ * import { isWorksheet } from '@orkestrel/rater'
253
+ *
254
+ * isWorksheet({ id: 'quote', name: 'Quote', aggregation: 'sum', value: 0, groups: [], steps: [], trace: [], errors: [], success: true }) // true
255
+ * ```
256
+ */
257
+ function isWorksheet(value) {
258
+ return objectOf({
259
+ id: isString,
260
+ name: isString,
261
+ aggregation: isAggregation,
262
+ precision: isNumber,
263
+ value: isNumber,
264
+ groups: arrayOf(isWorksheetGroup),
265
+ steps: arrayOf(isStep),
266
+ trace: arrayOf(isString),
267
+ errors: arrayOf(isString),
268
+ success: isBoolean
269
+ }, ["precision"])(value);
270
+ }
271
+ /**
272
+ * Determine whether a value is an open {@link LineResult} object.
273
+ *
274
+ * @remarks
275
+ * Unknown members, prototypes, and class instances are admitted. Arrays are
276
+ * refused. `amount` may be absent or read as `undefined`; when present it stays
277
+ * a plain JavaScript `number` without a finite or range refinement.
278
+ *
279
+ * @param value - The value to test
280
+ * @returns `true` when every published line-result member conforms
281
+ *
282
+ * @example
283
+ * ```ts
284
+ * import { isLineResult } from '@orkestrel/rater'
285
+ *
286
+ * isLineResult({ id: 'base', name: 'Base', worksheet: { id: 'base', name: 'Base', aggregation: 'sum', value: 0, groups: [], steps: [], trace: [], errors: [], success: false }, success: false }) // true
287
+ * ```
288
+ */
289
+ function isLineResult(value) {
290
+ return objectOf({
291
+ id: isString,
292
+ name: isString,
293
+ amount: isNumber,
294
+ worksheet: isWorksheet,
295
+ success: isBoolean
296
+ }, ["amount"])(value);
297
+ }
298
+ /**
299
+ * Determine whether a value is an open {@link RatingResult} object.
300
+ *
301
+ * @remarks
302
+ * Use this guard for a result returned by a borrowed `RaterInterface`. Unknown
303
+ * members, prototypes, and class instances are admitted. Arrays are refused.
304
+ * `total` may be absent or read as `undefined`; when present it stays a plain
305
+ * JavaScript `number` without a finite or range refinement.
306
+ *
307
+ * @param value - The value to test
308
+ * @returns `true` when every published rating-result member conforms
309
+ *
310
+ * @example
311
+ * ```ts
312
+ * import { isRatingResult } from '@orkestrel/rater'
313
+ *
314
+ * isRatingResult({ lines: [], success: true }) // true
315
+ * ```
316
+ */
317
+ function isRatingResult(value) {
318
+ return objectOf({
319
+ lines: arrayOf(isLineResult),
320
+ total: isNumber,
321
+ success: isBoolean
322
+ }, ["total"])(value);
323
+ }
120
324
  //#endregion
121
325
  //#region src/core/helpers.ts
122
326
  /**
327
+ * Build a {@link LineDefinition}.
328
+ *
329
+ * @param id - The line id
330
+ * @param name - The display name
331
+ * @param rate - The line's quantitative rating definition
332
+ * @param overrides - Optional {@link LineDefinition} fields merged over the defaults
333
+ * @returns A fresh line definition
334
+ *
335
+ * @example
336
+ * ```ts
337
+ * import { quantitativeDefinition } from '@orkestrel/reason'
338
+ * import { lineDefinition } from '@orkestrel/rater'
339
+ *
340
+ * lineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', []))
341
+ * ```
342
+ */
343
+ function lineDefinition(id, name, rate, overrides) {
344
+ return {
345
+ id,
346
+ name,
347
+ rate,
348
+ ...overrides
349
+ };
350
+ }
351
+ /**
352
+ * Build a {@link RatingDefinition}.
353
+ *
354
+ * @param id - The rating id
355
+ * @param name - The display name
356
+ * @param lines - The rating's ordered lines
357
+ * @param overrides - Optional {@link RatingDefinition} fields merged over the defaults
358
+ * @returns A fresh rating definition
359
+ *
360
+ * @example
361
+ * ```ts
362
+ * import { lineDefinition, ratingDefinition } from '@orkestrel/rater'
363
+ * import { quantitativeDefinition } from '@orkestrel/reason'
364
+ *
365
+ * ratingDefinition('r1', 'Rating', [
366
+ * lineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', [])),
367
+ * ])
368
+ * ```
369
+ */
370
+ function ratingDefinition(id, name, lines, overrides) {
371
+ return {
372
+ id,
373
+ name,
374
+ lines,
375
+ ...overrides
376
+ };
377
+ }
378
+ /**
123
379
  * Build an {@link Evidence} row from an evaluated {@link Check}.
124
380
  *
125
381
  * @param check - The authored check
@@ -495,59 +751,7 @@ var Rater = class {
495
751
  function createRater(options) {
496
752
  return new Rater(options);
497
753
  }
498
- /**
499
- * Build a {@link LineDefinition}.
500
- *
501
- * @param id - The line id
502
- * @param name - The display name
503
- * @param rate - The line's quantitative rating definition
504
- * @param overrides - Optional {@link LineDefinition} fields merged over the defaults
505
- * @returns A fresh line definition
506
- *
507
- * @example
508
- * ```ts
509
- * import { quantitativeDefinition } from '@orkestrel/reason'
510
- * import { lineDefinition } from '@orkestrel/rater'
511
- *
512
- * lineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', []))
513
- * ```
514
- */
515
- function lineDefinition(id, name, rate, overrides) {
516
- return {
517
- id,
518
- name,
519
- rate,
520
- ...overrides
521
- };
522
- }
523
- /**
524
- * Build a {@link RatingDefinition}.
525
- *
526
- * @param id - The rating id
527
- * @param name - The display name
528
- * @param lines - The rating's ordered lines
529
- * @param overrides - Optional {@link RatingDefinition} fields merged over the defaults
530
- * @returns A fresh rating definition
531
- *
532
- * @example
533
- * ```ts
534
- * import { lineDefinition, ratingDefinition } from '@orkestrel/rater'
535
- * import { quantitativeDefinition } from '@orkestrel/reason'
536
- *
537
- * ratingDefinition('r1', 'Rating', [
538
- * lineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', [])),
539
- * ])
540
- * ```
541
- */
542
- function ratingDefinition(id, name, lines, overrides) {
543
- return {
544
- id,
545
- name,
546
- lines,
547
- ...overrides
548
- };
549
- }
550
754
  //#endregion
551
- export { Rater, RaterError, checkEvidence, createRater, evidenceCheck, isLineDefinition, isRaterError, isRatingDefinition, isStage, lineDefinition, ratedLine, ratingDefinition, resultsWorksheet, sumAmounts, worksheetFactor, worksheetGroup, worksheetStep, worksheetSteps };
755
+ export { Rater, RaterError, checkEvidence, createRater, evidenceCheck, isEvidence, isLineDefinition, isLineResult, isRaterError, isRatingDefinition, isRatingResult, isStage, isStep, isWorksheet, isWorksheetFactor, isWorksheetGroup, lineDefinition, ratedLine, ratingDefinition, resultsWorksheet, sumAmounts, worksheetFactor, worksheetGroup, worksheetStep, worksheetSteps };
552
756
 
553
757
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["#emitter","#engine","#owned","#total","#labels","#ensureAlive","#normalize","#rateLine","#destroyed","#reasonQuantitative"],"sources":["../../../src/core/errors.ts","../../../src/core/validators.ts","../../../src/core/helpers.ts","../../../src/core/Rater.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { RaterErrorCode } from './types.js'\n\n/**\n * A coded programmer error thrown by the rating layer.\n *\n * @remarks\n * `DEFINITION` — the `rate` input failed both the array-of-lines and rating\n * definition validation. `MISMATCH` — a rated subject is not a record.\n * `DESTROYED` — use of a destroyed entity.\n *\n * @example\n * ```ts\n * import { RaterError } from '@orkestrel/rater'\n *\n * throw new RaterError('MISMATCH', 'Subject must be a record')\n * ```\n */\nexport class RaterError extends Error {\n\treadonly code: RaterErrorCode\n\treadonly context?: Readonly<Record<string, unknown>>\n\n\tconstructor(code: RaterErrorCode, message: string, context?: Readonly<Record<string, unknown>>) {\n\t\tsuper(message)\n\t\tthis.name = 'RaterError'\n\t\tthis.code = code\n\t\tif (context !== undefined) this.context = context\n\t}\n}\n\n/**\n * Narrow a caught value to a {@link RaterError}.\n *\n * @param value - The caught value to test\n * @returns `true` when `value` is a `RaterError`\n *\n * @example\n * ```ts\n * import { isRaterError, RaterError } from '@orkestrel/rater'\n *\n * try {\n * \tthrow new RaterError('DESTROYED', 'Rater has been destroyed')\n * } catch (error) {\n * \tif (isRaterError(error)) error.code // 'DESTROYED'\n * }\n * ```\n */\nexport function isRaterError(value: unknown): value is RaterError {\n\treturn value instanceof RaterError\n}\n","import type { Guard } from '@orkestrel/contract'\nimport type { LineDefinition, RatingDefinition, Stage } from './types.js'\nimport { arrayOf, isJSONValue, isString, literalOf, recordOf } from '@orkestrel/contract'\nimport { isQuantitativeDefinition } from '@orkestrel/reason'\n\n/**\n * Determine whether a value is a {@link Stage} literal.\n *\n * @param value - The value to test\n * @returns `true` when `value` is `'factor'`, `'group'`, or `'total'`\n *\n * @example\n * ```ts\n * import { isStage } from '@orkestrel/rater'\n *\n * isStage('group') // true\n * isStage('step') // false\n * ```\n */\nexport const isStage: Guard<Stage> = literalOf('factor', 'group', 'total')\n\n/**\n * Determine whether a value is an exact {@link LineDefinition} record.\n *\n * @remarks\n * Total guard (AGENTS §14): adversarial input (cycles, hostile prototypes)\n * returns `false`, never throws. The record shape is EXACT — an extra key fails.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a `LineDefinition`\n *\n * @example\n * ```ts\n * import { quantitativeDefinition } from '@orkestrel/reason'\n * import { isLineDefinition } from '@orkestrel/rater'\n *\n * isLineDefinition({ id: 'base', name: 'Base', rate: quantitativeDefinition('base', 'Base', []) }) // true\n * ```\n */\nexport function isLineDefinition(value: unknown): value is LineDefinition {\n\treturn recordOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\trate: isQuantitativeDefinition,\n\t\t\tmetadata: isJSONValue,\n\t\t},\n\t\t['description', 'metadata'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is an exact {@link RatingDefinition} record.\n *\n * @remarks\n * Total guard (AGENTS §14): adversarial input (cycles, hostile prototypes)\n * returns `false`, never throws. The record shape is EXACT — an extra key fails.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a `RatingDefinition`\n *\n * @example\n * ```ts\n * import { isRatingDefinition } from '@orkestrel/rater'\n *\n * isRatingDefinition({ id: 'r1', name: 'Rating', lines: [] }) // true\n * ```\n */\nexport function isRatingDefinition(value: unknown): value is RatingDefinition {\n\treturn recordOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\tlines: arrayOf(isLineDefinition),\n\t\t\tmetadata: isJSONValue,\n\t\t},\n\t\t['description', 'metadata'],\n\t)(value)\n}\n","import type {\n\tCheck,\n\tCheckResult,\n\tFactor,\n\tFactorResult,\n\tGroupResult,\n\tQuantitativeDefinition,\n\tQuantitativeResult,\n} from '@orkestrel/reason'\nimport type {\n\tEvidence,\n\tLineDefinition,\n\tLineResult,\n\tStage,\n\tStep,\n\tWorksheet,\n\tWorksheetFactor,\n\tWorksheetGroup,\n} from './types.js'\nimport { formatField } from '@orkestrel/reason'\n\n/**\n * Build an {@link Evidence} row from an evaluated {@link Check}.\n *\n * @param check - The authored check\n * @param actual - The resolved subject value\n * @param met - Whether the check was met (absent when not yet evaluated)\n * @param labels - Optional field-to-label overrides, keyed by dot-joined field\n * @returns A fresh evidence row\n *\n * @example\n * ```ts\n * import { check } from '@orkestrel/reason'\n * import { evidenceCheck } from '@orkestrel/rater'\n *\n * const entry = check('age', 'above', 18)\n * evidenceCheck(entry, 25, true) // { field: 'age', comparison: 'above', expected: 18, actual: 25, met: true }\n * ```\n */\nexport function evidenceCheck(\n\tcheck: Check,\n\tactual: unknown,\n\tmet: boolean | undefined,\n\tlabels?: Readonly<Record<string, string>>,\n): Evidence {\n\tconst field = formatField(check.field)\n\treturn {\n\t\tfield: check.field,\n\t\t...(labels?.[field] === undefined ? {} : { label: labels[field] }),\n\t\tcomparison: check.operator,\n\t\texpected: check.value,\n\t\tactual,\n\t\t...(met === undefined ? {} : { met }),\n\t}\n}\n\n/**\n * Build evidence rows from a quantitative factor's authored checks and\n * evaluated check results.\n *\n * @param checks - The factor's authored checks\n * @param results - The corresponding {@link CheckResult}s, in the same order\n * @param labels - Optional field-to-label overrides, keyed by dot-joined field\n * @returns A fresh list of evidence rows, one per authored check\n *\n * @example\n * ```ts\n * import { check } from '@orkestrel/reason'\n * import { checkEvidence } from '@orkestrel/rater'\n *\n * const checks = [check('age', 'above', 18)]\n * checkEvidence(checks, [{ field: 'age', met: true, actual: 25 }])\n * ```\n */\nexport function checkEvidence(\n\tchecks: readonly Check[] | undefined,\n\tresults: readonly CheckResult[] | undefined,\n\tlabels?: Readonly<Record<string, string>>,\n): readonly Evidence[] {\n\treturn (checks ?? []).map((check, index) => {\n\t\tconst result = results?.[index]\n\t\treturn evidenceCheck(check, result?.actual, result?.met, labels)\n\t})\n}\n\n/**\n * Join one authored quantitative factor to its evaluated {@link FactorResult}.\n *\n * @param definition - The authored factor\n * @param results - The group's factor results\n * @param labels - Optional field-to-label overrides, keyed by dot-joined field\n * @returns A fresh worksheet factor\n *\n * @example\n * ```ts\n * import { fieldFactor } from '@orkestrel/reason'\n * import { worksheetFactor } from '@orkestrel/rater'\n *\n * const factor = fieldFactor('seats', 'seats')\n * worksheetFactor(factor, [{ id: 'seats', applied: true, value: 10 }])\n * ```\n */\nexport function worksheetFactor(\n\tdefinition: Factor,\n\tresults: readonly FactorResult[],\n\tlabels?: Readonly<Record<string, string>>,\n): WorksheetFactor {\n\tconst result = results.find((entry) => entry.id === definition.id)\n\treturn {\n\t\tid: definition.id,\n\t\tname: definition.name,\n\t\t...(definition.description === undefined ? {} : { description: definition.description }),\n\t\tapplied: result?.applied ?? false,\n\t\t...(result?.value === undefined ? {} : { value: result.value }),\n\t\tevidence: checkEvidence(definition.checks, result?.checks, labels),\n\t}\n}\n\n/**\n * Join one authored quantitative group to its evaluated {@link GroupResult}.\n *\n * @param definition - The authored group\n * @param results - The definition's group results\n * @param labels - Optional field-to-label overrides, keyed by dot-joined field\n * @returns A fresh worksheet group\n *\n * @example\n * ```ts\n * import { factorGroup, staticFactor } from '@orkestrel/reason'\n * import { worksheetGroup } from '@orkestrel/rater'\n *\n * const group = factorGroup('charge', 'sum', [staticFactor('base', 100)])\n * worksheetGroup(group, [{ id: 'charge', applied: true, value: 100, factors: [] }])\n * ```\n */\nexport function worksheetGroup(\n\tdefinition: QuantitativeDefinition['groups'][number],\n\tresults: readonly GroupResult[],\n\tlabels?: Readonly<Record<string, string>>,\n): WorksheetGroup {\n\tconst result = results.find((entry) => entry.id === definition.id)\n\treturn {\n\t\tid: definition.id,\n\t\tname: definition.name,\n\t\t...(definition.description === undefined ? {} : { description: definition.description }),\n\t\tapplied: result?.applied ?? false,\n\t\tvalue: result?.value ?? 0,\n\t\tfactors: definition.factors.map((factor) =>\n\t\t\tworksheetFactor(factor, result?.factors ?? [], labels),\n\t\t),\n\t}\n}\n\n/**\n * Build one display-neutral {@link Step} row.\n *\n * @param stage - The step's stage\n * @param id - The stage's authored id, when it has one\n * @param name - The stage's authored name, when it has one\n * @param value - The stage's resolved value\n * @param expression - A display-neutral expression string\n * @returns A fresh step\n *\n * @example\n * ```ts\n * import { worksheetStep } from '@orkestrel/rater'\n *\n * worksheetStep('total', 'quote', 'Quote', 110, 'sum = 110')\n * // { stage: 'total', id: 'quote', name: 'Quote', value: 110, expression: 'sum = 110' }\n * ```\n */\nexport function worksheetStep(\n\tstage: Stage,\n\tid: string | undefined,\n\tname: string | undefined,\n\tvalue: number,\n\texpression: string,\n): Step {\n\treturn {\n\t\tstage,\n\t\t...(id === undefined ? {} : { id }),\n\t\t...(name === undefined ? {} : { name }),\n\t\tvalue,\n\t\texpression,\n\t}\n}\n\n/**\n * Build the ordered {@link Step} rows for a resolved {@link Worksheet}.\n *\n * @param definition - The authored quantitative definition\n * @param result - The evaluated quantitative result\n * @param groups - The definition's already-joined worksheet groups\n * @returns A fresh, ordered list of steps: applied factors, then groups, then the total\n *\n * @example\n * ```ts\n * import { createQuantitativeReasoner, createReason, factorGroup, quantitativeDefinition, staticFactor } from '@orkestrel/reason'\n * import { worksheetGroup, worksheetSteps } from '@orkestrel/rater'\n *\n * const definition = quantitativeDefinition('base', 'Base', [factorGroup('g', 'sum', [staticFactor('flat', 100)])])\n * const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, definition)\n * if (result.reasoning === 'quantitative') {\n * \tworksheetSteps(definition, result, definition.groups.map((group) => worksheetGroup(group, result.groups)))\n * }\n * ```\n */\nexport function worksheetSteps(\n\tdefinition: QuantitativeDefinition,\n\tresult: QuantitativeResult,\n\tgroups: readonly WorksheetGroup[],\n): readonly Step[] {\n\tconst output: Step[] = []\n\tfor (const group of groups) {\n\t\tfor (const factor of group.factors) {\n\t\t\tif (factor.applied && factor.value !== undefined) {\n\t\t\t\toutput.push(\n\t\t\t\t\tworksheetStep(\n\t\t\t\t\t\t'factor',\n\t\t\t\t\t\tfactor.id,\n\t\t\t\t\t\tfactor.name,\n\t\t\t\t\t\tfactor.value,\n\t\t\t\t\t\t`${factor.id} = ${factor.value}`,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\toutput.push(\n\t\t\tworksheetStep('group', group.id, group.name, group.value, `${group.id} = ${group.value}`),\n\t\t)\n\t}\n\toutput.push(\n\t\tworksheetStep(\n\t\t\t'total',\n\t\t\tdefinition.id,\n\t\t\tdefinition.name,\n\t\t\tresult.value,\n\t\t\t`${definition.aggregation} = ${result.value}`,\n\t\t),\n\t)\n\treturn output\n}\n\n/**\n * Join a {@link QuantitativeDefinition} and its {@link QuantitativeResult} into\n * a {@link Worksheet} — the rating audit trail.\n *\n * @param definition - The authored quantitative definition\n * @param result - The evaluated quantitative result\n * @param labels - Optional field-to-label overrides, keyed by dot-joined field\n * @returns A fresh worksheet\n *\n * @example\n * ```ts\n * import { createQuantitativeReasoner, createReason, factorGroup, quantitativeDefinition, staticFactor } from '@orkestrel/reason'\n * import { resultsWorksheet } from '@orkestrel/rater'\n *\n * const definition = quantitativeDefinition('base', 'Base', [factorGroup('g', 'sum', [staticFactor('flat', 100)])])\n * const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, definition)\n * if (result.reasoning === 'quantitative') resultsWorksheet(definition, result) // the full audit trail\n * ```\n */\nexport function resultsWorksheet(\n\tdefinition: QuantitativeDefinition,\n\tresult: QuantitativeResult,\n\tlabels?: Readonly<Record<string, string>>,\n): Worksheet {\n\tconst groups = definition.groups.map((group) => worksheetGroup(group, result.groups, labels))\n\treturn {\n\t\tid: definition.id,\n\t\tname: definition.name,\n\t\taggregation: definition.aggregation,\n\t\t...(definition.precision === undefined ? {} : { precision: definition.precision }),\n\t\tvalue: result.value,\n\t\tgroups,\n\t\tsteps: worksheetSteps(definition, result, groups),\n\t\ttrace: result.trace,\n\t\terrors: result.errors,\n\t\tsuccess: result.success,\n\t}\n}\n\n/**\n * Build a rated {@link LineResult} from a line's evaluated\n * {@link QuantitativeResult}.\n *\n * @param definition - The authored line definition\n * @param result - The evaluated quantitative result\n * @param labels - Optional field-to-label overrides, keyed by dot-joined field\n * @returns A fresh line result\n *\n * @example\n * ```ts\n * import { createQuantitativeReasoner, createReason, quantitativeDefinition } from '@orkestrel/reason'\n * import { lineDefinition, ratedLine } from '@orkestrel/rater'\n *\n * const line = lineDefinition('base', 'Base', quantitativeDefinition('base', 'Base', []))\n * const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, line.rate)\n * if (result.reasoning === 'quantitative') ratedLine(line, result) // amount present only when success\n * ```\n */\nexport function ratedLine(\n\tdefinition: LineDefinition,\n\tresult: QuantitativeResult,\n\tlabels?: Readonly<Record<string, string>>,\n): LineResult {\n\treturn {\n\t\tid: definition.id,\n\t\tname: definition.name,\n\t\t...(result.success ? { amount: result.value } : {}),\n\t\tworksheet: resultsWorksheet(definition.rate, result, labels),\n\t\tsuccess: result.success,\n\t}\n}\n\n/**\n * Sum defined line amounts.\n *\n * @param lines - The rated lines\n * @returns The sum of every line's `amount`, or `undefined` when no line has one\n *\n * @example\n * ```ts\n * import { createQuantitativeReasoner, createReason, factorGroup, quantitativeDefinition, staticFactor } from '@orkestrel/reason'\n * import { lineDefinition, ratedLine, sumAmounts } from '@orkestrel/rater'\n *\n * const rate = quantitativeDefinition('base', 'Base', [factorGroup('g', 'sum', [staticFactor('flat', 100)])])\n * const line = lineDefinition('base', 'Base', rate)\n * const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, rate)\n * if (result.reasoning === 'quantitative') sumAmounts([ratedLine(line, result)]) // 100\n * ```\n */\nexport function sumAmounts(lines: readonly LineResult[]): number | undefined {\n\tlet total = 0\n\tlet count = 0\n\tfor (const rated of lines) {\n\t\tif (rated.amount !== undefined) {\n\t\t\ttotal += rated.amount\n\t\t\tcount += 1\n\t\t}\n\t}\n\treturn count === 0 ? undefined : total\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tQuantitativeDefinition,\n\tQuantitativeResult,\n\tReasonInterface,\n\tSubject,\n} from '@orkestrel/reason'\nimport type {\n\tLineDefinition,\n\tLineResult,\n\tRaterEventMap,\n\tRaterInterface,\n\tRaterOptions,\n\tRatingDefinition,\n\tRatingResult,\n\tTotalHandler,\n} from './types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { arrayOf, isArray } from '@orkestrel/contract'\nimport {\n\tbuildErrorResult,\n\tcreateQuantitativeReasoner,\n\tcreateReason,\n\tisSubject,\n} from '@orkestrel/reason'\nimport { RaterError } from './errors.js'\nimport { ratedLine, sumAmounts } from './helpers.js'\nimport { isLineDefinition, isRatingDefinition } from './validators.js'\n\n/**\n * The rating orchestrator — owns (or receives) the shared quantitative\n * reasoning engine and projects results into the rating domain vocabulary.\n *\n * @remarks\n * When no `engine` is injected, `Rater` builds and OWNS its own\n * quantitative-only engine (`bail: false`) — Rater performs NO evaluation\n * arithmetic of its own; it only orchestrates and projects. The\n * array-of-lines `rate` overload is declared FIRST (AGENTS §9.2). `destroy()`\n * destroys an OWNED engine, then the emitter LAST (AGENTS §13); an INJECTED\n * engine is never destroyed. Afterwards every other method throws\n * {@link RaterError} `'DESTROYED'`.\n *\n * @example\n * ```ts\n * import { Rater } from '@orkestrel/rater'\n *\n * const rater = new Rater()\n * rater.rate([], { id: 'subject-1' }) // { lines: [], success: true }\n * rater.destroy()\n * ```\n */\nexport class Rater implements RaterInterface {\n\treadonly #emitter: Emitter<RaterEventMap>\n\treadonly #engine: ReasonInterface\n\treadonly #owned: boolean\n\treadonly #total: TotalHandler | undefined\n\treadonly #labels: Readonly<Record<string, string>> | undefined\n\t#destroyed = false\n\n\tconstructor(options?: RaterOptions) {\n\t\tthis.#emitter = new Emitter<RaterEventMap>({\n\t\t\t...(options?.on === undefined ? {} : { on: options.on }),\n\t\t\t...(options?.error === undefined ? {} : { error: options.error }),\n\t\t})\n\t\tif (options?.engine === undefined) {\n\t\t\tthis.#engine = createReason({ reasoners: [createQuantitativeReasoner()], bail: false })\n\t\t\tthis.#owned = true\n\t\t} else {\n\t\t\tthis.#engine = options.engine\n\t\t\tthis.#owned = false\n\t\t}\n\t\tthis.#total = options?.total\n\t\tthis.#labels = options?.labels\n\t}\n\n\tget emitter(): EmitterInterface<RaterEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\t// Array overload first (AGENTS §9.2) so a plain line list resolves to that form.\n\trate(lines: readonly LineDefinition[], subject: Subject): RatingResult\n\trate(definition: RatingDefinition, subject: Subject): RatingResult\n\trate(input: readonly LineDefinition[] | RatingDefinition, subject: Subject): RatingResult {\n\t\tthis.#ensureAlive()\n\t\tconst lines = this.#normalize(input)\n\t\tif (!isSubject(subject)) throw new RaterError('MISMATCH', 'Subject must be a record')\n\t\tconst results = lines.map((line) => this.#rateLine(line, subject))\n\t\tconst total = (this.#total ?? sumAmounts)(results)\n\t\tconst success = results.every((entry) => entry.success)\n\t\tconst result: RatingResult = {\n\t\t\tlines: results,\n\t\t\t...(total === undefined ? {} : { total }),\n\t\t\tsuccess,\n\t\t}\n\t\tthis.#emitter.emit('rate', subject, result)\n\t\treturn result\n\t}\n\n\tdestroy(): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#destroyed = true\n\t\tif (this.#owned) this.#engine.destroy()\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#normalize(input: readonly LineDefinition[] | RatingDefinition): readonly LineDefinition[] {\n\t\tif (arrayOf(isLineDefinition)(input)) return input\n\t\tif (isRatingDefinition(input)) return input.lines\n\t\tthrow new RaterError(\n\t\t\t'DEFINITION',\n\t\t\t'Rating input must be an array of line definitions or a rating definition',\n\t\t)\n\t}\n\n\t#rateLine(line: LineDefinition, subject: Subject): LineResult {\n\t\tconst result = this.#reasonQuantitative(subject, line.rate)\n\t\treturn ratedLine(line, result, this.#labels)\n\t}\n\n\t// Narrows the engine's tagged ReasonResult union down to a QuantitativeResult\n\t// for a definition the engine is guaranteed (by dispatch-by-reasoning, given\n\t// only the quantitative reasoner is ever registered) to resolve as such — a\n\t// defensive, total fallback rather than an assertion. A nonconforming\n\t// injected engine result missing (or with a non-array) `errors` contributes\n\t// no errors from that side rather than throwing.\n\t#reasonQuantitative(subject: Subject, definition: QuantitativeDefinition): QuantitativeResult {\n\t\tconst result = this.#engine.reason(subject, definition)\n\t\tif (result.reasoning === 'quantitative') return result\n\t\tconst failure = buildErrorResult(\n\t\t\tdefinition,\n\t\t\t`Expected quantitative result, got ${result.reasoning}`,\n\t\t)\n\t\tconst errors = [...(isArray<string>(result.errors) ? result.errors : []), ...failure.errors]\n\t\tif (failure.reasoning === 'quantitative') return { ...failure, errors }\n\t\treturn {\n\t\t\treasoning: 'quantitative',\n\t\t\tvalue: 0,\n\t\t\tgroups: [],\n\t\t\tcount: 0,\n\t\t\tsuccess: false,\n\t\t\ttrace: [],\n\t\t\terrors,\n\t\t}\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) throw new RaterError('DESTROYED', 'Rater has been destroyed')\n\t}\n}\n","import type { QuantitativeDefinition } from '@orkestrel/reason'\nimport type { LineDefinition, RatingDefinition, RaterInterface, RaterOptions } from './types.js'\nimport { Rater } from './Rater.js'\n\n/**\n * Create a rating orchestrator.\n *\n * @param options - Optional total handler, labels, injected engine, and emitter hooks\n * @returns A {@link RaterInterface}\n *\n * @example\n * ```ts\n * import { createRater } from '@orkestrel/rater'\n *\n * const rater = createRater()\n * rater.destroy()\n * ```\n */\nexport function createRater(options?: RaterOptions): RaterInterface {\n\treturn new Rater(options)\n}\n\n/**\n * Build a {@link LineDefinition}.\n *\n * @param id - The line id\n * @param name - The display name\n * @param rate - The line's quantitative rating definition\n * @param overrides - Optional {@link LineDefinition} fields merged over the defaults\n * @returns A fresh line definition\n *\n * @example\n * ```ts\n * import { quantitativeDefinition } from '@orkestrel/reason'\n * import { lineDefinition } from '@orkestrel/rater'\n *\n * lineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', []))\n * ```\n */\nexport function lineDefinition(\n\tid: string,\n\tname: string,\n\trate: QuantitativeDefinition,\n\toverrides?: Partial<Omit<LineDefinition, 'id' | 'name' | 'rate'>>,\n): LineDefinition {\n\treturn { id, name, rate, ...overrides }\n}\n\n/**\n * Build a {@link RatingDefinition}.\n *\n * @param id - The rating id\n * @param name - The display name\n * @param lines - The rating's ordered lines\n * @param overrides - Optional {@link RatingDefinition} fields merged over the defaults\n * @returns A fresh rating definition\n *\n * @example\n * ```ts\n * import { lineDefinition, ratingDefinition } from '@orkestrel/rater'\n * import { quantitativeDefinition } from '@orkestrel/reason'\n *\n * ratingDefinition('r1', 'Rating', [\n * \tlineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', [])),\n * ])\n * ```\n */\nexport function ratingDefinition(\n\tid: string,\n\tname: string,\n\tlines: readonly LineDefinition[],\n\toverrides?: Partial<Omit<RatingDefinition, 'id' | 'name' | 'lines'>>,\n): RatingDefinition {\n\treturn { id, name, lines, ...overrides }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["#emitter","#engine","#owned","#total","#labels","#ensureAlive","#normalize","#rateLine","#destroyed","#reasonQuantitative"],"sources":["../../../src/core/errors.ts","../../../src/core/validators.ts","../../../src/core/helpers.ts","../../../src/core/Rater.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { RaterErrorCode } from './types.js'\n\n/**\n * A coded programmer error thrown by the rating layer.\n *\n * @remarks\n * `DEFINITION` — the `rate` input failed both the array-of-lines and rating\n * definition validation. `MISMATCH` — a rated subject is not a record.\n * `DESTROYED` — use of a destroyed entity.\n *\n * @example\n * ```ts\n * import { RaterError } from '@orkestrel/rater'\n *\n * throw new RaterError('MISMATCH', 'Subject must be a record')\n * ```\n */\nexport class RaterError extends Error {\n\treadonly code: RaterErrorCode\n\treadonly context?: Readonly<Record<string, unknown>>\n\n\tconstructor(code: RaterErrorCode, message: string, context?: Readonly<Record<string, unknown>>) {\n\t\tsuper(message)\n\t\tthis.name = 'RaterError'\n\t\tthis.code = code\n\t\tif (context !== undefined) this.context = context\n\t}\n}\n\n/**\n * Narrow a caught value to a {@link RaterError}.\n *\n * @param value - The caught value to test\n * @returns `true` when `value` is a `RaterError`\n *\n * @example\n * ```ts\n * import { isRaterError, RaterError } from '@orkestrel/rater'\n *\n * try {\n * \tthrow new RaterError('DESTROYED', 'Rater has been destroyed')\n * } catch (error) {\n * \tif (isRaterError(error)) error.code // 'DESTROYED'\n * }\n * ```\n */\nexport function isRaterError(value: unknown): value is RaterError {\n\treturn value instanceof RaterError\n}\n","import type { Guard } from '@orkestrel/contract'\nimport type {\n\tEvidence,\n\tLineDefinition,\n\tLineResult,\n\tRatingDefinition,\n\tRatingResult,\n\tStage,\n\tStep,\n\tWorksheet,\n\tWorksheetFactor,\n\tWorksheetGroup,\n} from './types.js'\nimport {\n\tarrayOf,\n\tisBoolean,\n\tisJSONValue,\n\tisNumber,\n\tisString,\n\tliteralOf,\n\tobjectOf,\n\trecordOf,\n} from '@orkestrel/contract'\nimport {\n\tisAggregation,\n\tisComparison,\n\tisFieldPath,\n\tisQuantitativeDefinition,\n} from '@orkestrel/reason'\n\n/**\n * Determine whether a value is a {@link Stage} literal.\n *\n * @param value - The value to test\n * @returns `true` when `value` is `'factor'`, `'group'`, or `'total'`\n *\n * @example\n * ```ts\n * import { isStage } from '@orkestrel/rater'\n *\n * isStage('group') // true\n * isStage('step') // false\n * ```\n */\nexport const isStage: Guard<Stage> = literalOf('factor', 'group', 'total')\n\n/**\n * Determine whether a value is an exact {@link LineDefinition} record.\n *\n * @remarks\n * Total guard (AGENTS §14): adversarial input (cycles, hostile prototypes)\n * returns `false`, never throws. The record shape is EXACT — an extra key fails.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a `LineDefinition`\n *\n * @example\n * ```ts\n * import { quantitativeDefinition } from '@orkestrel/reason'\n * import { isLineDefinition } from '@orkestrel/rater'\n *\n * isLineDefinition({ id: 'base', name: 'Base', rate: quantitativeDefinition('base', 'Base', []) }) // true\n * ```\n */\nexport function isLineDefinition(value: unknown): value is LineDefinition {\n\treturn recordOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\trate: isQuantitativeDefinition,\n\t\t\tmetadata: isJSONValue,\n\t\t},\n\t\t['description', 'metadata'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is an exact {@link RatingDefinition} record.\n *\n * @remarks\n * Total guard (AGENTS §14): adversarial input (cycles, hostile prototypes)\n * returns `false`, never throws. The record shape is EXACT — an extra key fails.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a `RatingDefinition`\n *\n * @example\n * ```ts\n * import { isRatingDefinition } from '@orkestrel/rater'\n *\n * isRatingDefinition({ id: 'r1', name: 'Rating', lines: [] }) // true\n * ```\n */\nexport function isRatingDefinition(value: unknown): value is RatingDefinition {\n\treturn recordOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\tlines: arrayOf(isLineDefinition),\n\t\t\tmetadata: isJSONValue,\n\t\t},\n\t\t['description', 'metadata'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is an open result-side {@link Evidence} object.\n *\n * @remarks\n * Unknown members, prototypes, and class instances are admitted. Arrays are\n * refused. `expected` and `actual` are `unknown`, so this guard does not read or\n * check them; either member may also be absent because `objectOf` reads declared\n * members rather than requiring or enumerating own keys.\n *\n * @param value - The value to test\n * @returns `true` when every checked `Evidence` member conforms\n *\n * @example\n * ```ts\n * import { isEvidence } from '@orkestrel/rater'\n *\n * isEvidence({ field: 'age', comparison: 'above', expected: 18, actual: 25, met: true }) // true\n * ```\n */\nexport function isEvidence(value: unknown): value is Evidence {\n\treturn objectOf(\n\t\t{\n\t\t\tfield: isFieldPath,\n\t\t\tlabel: isString,\n\t\t\tcomparison: isComparison,\n\t\t\tmet: isBoolean,\n\t\t},\n\t\t['field', 'label', 'comparison', 'met'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is an open {@link WorksheetFactor} result object.\n *\n * @remarks\n * Unknown members, prototypes, and class instances are admitted. Arrays are\n * refused. Optional members may be absent or read as `undefined`.\n *\n * @param value - The value to test\n * @returns `true` when every published worksheet-factor member conforms\n *\n * @example\n * ```ts\n * import { isWorksheetFactor } from '@orkestrel/rater'\n *\n * isWorksheetFactor({ id: 'base', applied: true, value: 100, evidence: [] }) // true\n * ```\n */\nexport function isWorksheetFactor(value: unknown): value is WorksheetFactor {\n\treturn objectOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\tapplied: isBoolean,\n\t\t\tvalue: isNumber,\n\t\t\tevidence: arrayOf(isEvidence),\n\t\t},\n\t\t['name', 'description', 'value'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is an open {@link WorksheetGroup} result object.\n *\n * @remarks\n * Unknown members, prototypes, and class instances are admitted. Arrays are\n * refused. Optional members may be absent or read as `undefined`.\n *\n * @param value - The value to test\n * @returns `true` when every published worksheet-group member conforms\n *\n * @example\n * ```ts\n * import { isWorksheetGroup } from '@orkestrel/rater'\n *\n * isWorksheetGroup({ id: 'charges', applied: true, value: 100, factors: [] }) // true\n * ```\n */\nexport function isWorksheetGroup(value: unknown): value is WorksheetGroup {\n\treturn objectOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\tapplied: isBoolean,\n\t\t\tvalue: isNumber,\n\t\t\tfactors: arrayOf(isWorksheetFactor),\n\t\t},\n\t\t['name', 'description'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is an open {@link Step} result object.\n *\n * @remarks\n * Unknown members, prototypes, and class instances are admitted. Arrays are\n * refused. Optional members may be absent or read as `undefined`.\n *\n * @param value - The value to test\n * @returns `true` when every published worksheet-step member conforms\n *\n * @example\n * ```ts\n * import { isStep } from '@orkestrel/rater'\n *\n * isStep({ stage: 'total', value: 100 }) // true\n * ```\n */\nexport function isStep(value: unknown): value is Step {\n\treturn objectOf(\n\t\t{\n\t\t\tstage: isStage,\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tvalue: isNumber,\n\t\t\texpression: isString,\n\t\t},\n\t\t['id', 'name', 'expression'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is an open {@link Worksheet} result object.\n *\n * @remarks\n * Unknown members, prototypes, and class instances are admitted. Arrays are\n * refused. Optional members may be absent or read as `undefined`.\n *\n * @param value - The value to test\n * @returns `true` when every published worksheet member conforms\n *\n * @example\n * ```ts\n * import { isWorksheet } from '@orkestrel/rater'\n *\n * isWorksheet({ id: 'quote', name: 'Quote', aggregation: 'sum', value: 0, groups: [], steps: [], trace: [], errors: [], success: true }) // true\n * ```\n */\nexport function isWorksheet(value: unknown): value is Worksheet {\n\treturn objectOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\taggregation: isAggregation,\n\t\t\tprecision: isNumber,\n\t\t\tvalue: isNumber,\n\t\t\tgroups: arrayOf(isWorksheetGroup),\n\t\t\tsteps: arrayOf(isStep),\n\t\t\ttrace: arrayOf(isString),\n\t\t\terrors: arrayOf(isString),\n\t\t\tsuccess: isBoolean,\n\t\t},\n\t\t['precision'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is an open {@link LineResult} object.\n *\n * @remarks\n * Unknown members, prototypes, and class instances are admitted. Arrays are\n * refused. `amount` may be absent or read as `undefined`; when present it stays\n * a plain JavaScript `number` without a finite or range refinement.\n *\n * @param value - The value to test\n * @returns `true` when every published line-result member conforms\n *\n * @example\n * ```ts\n * import { isLineResult } from '@orkestrel/rater'\n *\n * isLineResult({ id: 'base', name: 'Base', worksheet: { id: 'base', name: 'Base', aggregation: 'sum', value: 0, groups: [], steps: [], trace: [], errors: [], success: false }, success: false }) // true\n * ```\n */\nexport function isLineResult(value: unknown): value is LineResult {\n\treturn objectOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tamount: isNumber,\n\t\t\tworksheet: isWorksheet,\n\t\t\tsuccess: isBoolean,\n\t\t},\n\t\t['amount'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is an open {@link RatingResult} object.\n *\n * @remarks\n * Use this guard for a result returned by a borrowed `RaterInterface`. Unknown\n * members, prototypes, and class instances are admitted. Arrays are refused.\n * `total` may be absent or read as `undefined`; when present it stays a plain\n * JavaScript `number` without a finite or range refinement.\n *\n * @param value - The value to test\n * @returns `true` when every published rating-result member conforms\n *\n * @example\n * ```ts\n * import { isRatingResult } from '@orkestrel/rater'\n *\n * isRatingResult({ lines: [], success: true }) // true\n * ```\n */\nexport function isRatingResult(value: unknown): value is RatingResult {\n\treturn objectOf(\n\t\t{\n\t\t\tlines: arrayOf(isLineResult),\n\t\t\ttotal: isNumber,\n\t\t\tsuccess: isBoolean,\n\t\t},\n\t\t['total'],\n\t)(value)\n}\n","import type {\n\tCheck,\n\tCheckResult,\n\tFactor,\n\tFactorResult,\n\tGroupResult,\n\tQuantitativeDefinition,\n\tQuantitativeResult,\n} from '@orkestrel/reason'\nimport type {\n\tEvidence,\n\tLineDefinition,\n\tLineResult,\n\tRatingDefinition,\n\tStage,\n\tStep,\n\tWorksheet,\n\tWorksheetFactor,\n\tWorksheetGroup,\n} from './types.js'\nimport { formatField } from '@orkestrel/reason'\n\n/**\n * Build a {@link LineDefinition}.\n *\n * @param id - The line id\n * @param name - The display name\n * @param rate - The line's quantitative rating definition\n * @param overrides - Optional {@link LineDefinition} fields merged over the defaults\n * @returns A fresh line definition\n *\n * @example\n * ```ts\n * import { quantitativeDefinition } from '@orkestrel/reason'\n * import { lineDefinition } from '@orkestrel/rater'\n *\n * lineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', []))\n * ```\n */\nexport function lineDefinition(\n\tid: string,\n\tname: string,\n\trate: QuantitativeDefinition,\n\toverrides?: Partial<Omit<LineDefinition, 'id' | 'name' | 'rate'>>,\n): LineDefinition {\n\treturn { id, name, rate, ...overrides }\n}\n\n/**\n * Build a {@link RatingDefinition}.\n *\n * @param id - The rating id\n * @param name - The display name\n * @param lines - The rating's ordered lines\n * @param overrides - Optional {@link RatingDefinition} fields merged over the defaults\n * @returns A fresh rating definition\n *\n * @example\n * ```ts\n * import { lineDefinition, ratingDefinition } from '@orkestrel/rater'\n * import { quantitativeDefinition } from '@orkestrel/reason'\n *\n * ratingDefinition('r1', 'Rating', [\n * \tlineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', [])),\n * ])\n * ```\n */\nexport function ratingDefinition(\n\tid: string,\n\tname: string,\n\tlines: readonly LineDefinition[],\n\toverrides?: Partial<Omit<RatingDefinition, 'id' | 'name' | 'lines'>>,\n): RatingDefinition {\n\treturn { id, name, lines, ...overrides }\n}\n\n/**\n * Build an {@link Evidence} row from an evaluated {@link Check}.\n *\n * @param check - The authored check\n * @param actual - The resolved subject value\n * @param met - Whether the check was met (absent when not yet evaluated)\n * @param labels - Optional field-to-label overrides, keyed by dot-joined field\n * @returns A fresh evidence row\n *\n * @example\n * ```ts\n * import { check } from '@orkestrel/reason'\n * import { evidenceCheck } from '@orkestrel/rater'\n *\n * const entry = check('age', 'above', 18)\n * evidenceCheck(entry, 25, true) // { field: 'age', comparison: 'above', expected: 18, actual: 25, met: true }\n * ```\n */\nexport function evidenceCheck(\n\tcheck: Check,\n\tactual: unknown,\n\tmet: boolean | undefined,\n\tlabels?: Readonly<Record<string, string>>,\n): Evidence {\n\tconst field = formatField(check.field)\n\treturn {\n\t\tfield: check.field,\n\t\t...(labels?.[field] === undefined ? {} : { label: labels[field] }),\n\t\tcomparison: check.operator,\n\t\texpected: check.value,\n\t\tactual,\n\t\t...(met === undefined ? {} : { met }),\n\t}\n}\n\n/**\n * Build evidence rows from a quantitative factor's authored checks and\n * evaluated check results.\n *\n * @param checks - The factor's authored checks\n * @param results - The corresponding {@link CheckResult}s, in the same order\n * @param labels - Optional field-to-label overrides, keyed by dot-joined field\n * @returns A fresh list of evidence rows, one per authored check\n *\n * @example\n * ```ts\n * import { check } from '@orkestrel/reason'\n * import { checkEvidence } from '@orkestrel/rater'\n *\n * const checks = [check('age', 'above', 18)]\n * checkEvidence(checks, [{ field: 'age', met: true, actual: 25 }])\n * ```\n */\nexport function checkEvidence(\n\tchecks: readonly Check[] | undefined,\n\tresults: readonly CheckResult[] | undefined,\n\tlabels?: Readonly<Record<string, string>>,\n): readonly Evidence[] {\n\treturn (checks ?? []).map((check, index) => {\n\t\tconst result = results?.[index]\n\t\treturn evidenceCheck(check, result?.actual, result?.met, labels)\n\t})\n}\n\n/**\n * Join one authored quantitative factor to its evaluated {@link FactorResult}.\n *\n * @param definition - The authored factor\n * @param results - The group's factor results\n * @param labels - Optional field-to-label overrides, keyed by dot-joined field\n * @returns A fresh worksheet factor\n *\n * @example\n * ```ts\n * import { fieldFactor } from '@orkestrel/reason'\n * import { worksheetFactor } from '@orkestrel/rater'\n *\n * const factor = fieldFactor('seats', 'seats')\n * worksheetFactor(factor, [{ id: 'seats', applied: true, value: 10 }])\n * ```\n */\nexport function worksheetFactor(\n\tdefinition: Factor,\n\tresults: readonly FactorResult[],\n\tlabels?: Readonly<Record<string, string>>,\n): WorksheetFactor {\n\tconst result = results.find((entry) => entry.id === definition.id)\n\treturn {\n\t\tid: definition.id,\n\t\tname: definition.name,\n\t\t...(definition.description === undefined ? {} : { description: definition.description }),\n\t\tapplied: result?.applied ?? false,\n\t\t...(result?.value === undefined ? {} : { value: result.value }),\n\t\tevidence: checkEvidence(definition.checks, result?.checks, labels),\n\t}\n}\n\n/**\n * Join one authored quantitative group to its evaluated {@link GroupResult}.\n *\n * @param definition - The authored group\n * @param results - The definition's group results\n * @param labels - Optional field-to-label overrides, keyed by dot-joined field\n * @returns A fresh worksheet group\n *\n * @example\n * ```ts\n * import { factorGroup, staticFactor } from '@orkestrel/reason'\n * import { worksheetGroup } from '@orkestrel/rater'\n *\n * const group = factorGroup('charge', 'sum', [staticFactor('base', 100)])\n * worksheetGroup(group, [{ id: 'charge', applied: true, value: 100, factors: [] }])\n * ```\n */\nexport function worksheetGroup(\n\tdefinition: QuantitativeDefinition['groups'][number],\n\tresults: readonly GroupResult[],\n\tlabels?: Readonly<Record<string, string>>,\n): WorksheetGroup {\n\tconst result = results.find((entry) => entry.id === definition.id)\n\treturn {\n\t\tid: definition.id,\n\t\tname: definition.name,\n\t\t...(definition.description === undefined ? {} : { description: definition.description }),\n\t\tapplied: result?.applied ?? false,\n\t\tvalue: result?.value ?? 0,\n\t\tfactors: definition.factors.map((factor) =>\n\t\t\tworksheetFactor(factor, result?.factors ?? [], labels),\n\t\t),\n\t}\n}\n\n/**\n * Build one display-neutral {@link Step} row.\n *\n * @param stage - The step's stage\n * @param id - The stage's authored id, when it has one\n * @param name - The stage's authored name, when it has one\n * @param value - The stage's resolved value\n * @param expression - A display-neutral expression string\n * @returns A fresh step\n *\n * @example\n * ```ts\n * import { worksheetStep } from '@orkestrel/rater'\n *\n * worksheetStep('total', 'quote', 'Quote', 110, 'sum = 110')\n * // { stage: 'total', id: 'quote', name: 'Quote', value: 110, expression: 'sum = 110' }\n * ```\n */\nexport function worksheetStep(\n\tstage: Stage,\n\tid: string | undefined,\n\tname: string | undefined,\n\tvalue: number,\n\texpression: string,\n): Step {\n\treturn {\n\t\tstage,\n\t\t...(id === undefined ? {} : { id }),\n\t\t...(name === undefined ? {} : { name }),\n\t\tvalue,\n\t\texpression,\n\t}\n}\n\n/**\n * Build the ordered {@link Step} rows for a resolved {@link Worksheet}.\n *\n * @param definition - The authored quantitative definition\n * @param result - The evaluated quantitative result\n * @param groups - The definition's already-joined worksheet groups\n * @returns A fresh, ordered list of steps: applied factors, then groups, then the total\n *\n * @example\n * ```ts\n * import { createQuantitativeReasoner, createReason, factorGroup, quantitativeDefinition, staticFactor } from '@orkestrel/reason'\n * import { worksheetGroup, worksheetSteps } from '@orkestrel/rater'\n *\n * const definition = quantitativeDefinition('base', 'Base', [factorGroup('g', 'sum', [staticFactor('flat', 100)])])\n * const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, definition)\n * if (result.reasoning === 'quantitative') {\n * \tworksheetSteps(definition, result, definition.groups.map((group) => worksheetGroup(group, result.groups)))\n * }\n * ```\n */\nexport function worksheetSteps(\n\tdefinition: QuantitativeDefinition,\n\tresult: QuantitativeResult,\n\tgroups: readonly WorksheetGroup[],\n): readonly Step[] {\n\tconst output: Step[] = []\n\tfor (const group of groups) {\n\t\tfor (const factor of group.factors) {\n\t\t\tif (factor.applied && factor.value !== undefined) {\n\t\t\t\toutput.push(\n\t\t\t\t\tworksheetStep(\n\t\t\t\t\t\t'factor',\n\t\t\t\t\t\tfactor.id,\n\t\t\t\t\t\tfactor.name,\n\t\t\t\t\t\tfactor.value,\n\t\t\t\t\t\t`${factor.id} = ${factor.value}`,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\toutput.push(\n\t\t\tworksheetStep('group', group.id, group.name, group.value, `${group.id} = ${group.value}`),\n\t\t)\n\t}\n\toutput.push(\n\t\tworksheetStep(\n\t\t\t'total',\n\t\t\tdefinition.id,\n\t\t\tdefinition.name,\n\t\t\tresult.value,\n\t\t\t`${definition.aggregation} = ${result.value}`,\n\t\t),\n\t)\n\treturn output\n}\n\n/**\n * Join a {@link QuantitativeDefinition} and its {@link QuantitativeResult} into\n * a {@link Worksheet} — the rating audit trail.\n *\n * @param definition - The authored quantitative definition\n * @param result - The evaluated quantitative result\n * @param labels - Optional field-to-label overrides, keyed by dot-joined field\n * @returns A fresh worksheet\n *\n * @example\n * ```ts\n * import { createQuantitativeReasoner, createReason, factorGroup, quantitativeDefinition, staticFactor } from '@orkestrel/reason'\n * import { resultsWorksheet } from '@orkestrel/rater'\n *\n * const definition = quantitativeDefinition('base', 'Base', [factorGroup('g', 'sum', [staticFactor('flat', 100)])])\n * const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, definition)\n * if (result.reasoning === 'quantitative') resultsWorksheet(definition, result) // the full audit trail\n * ```\n */\nexport function resultsWorksheet(\n\tdefinition: QuantitativeDefinition,\n\tresult: QuantitativeResult,\n\tlabels?: Readonly<Record<string, string>>,\n): Worksheet {\n\tconst groups = definition.groups.map((group) => worksheetGroup(group, result.groups, labels))\n\treturn {\n\t\tid: definition.id,\n\t\tname: definition.name,\n\t\taggregation: definition.aggregation,\n\t\t...(definition.precision === undefined ? {} : { precision: definition.precision }),\n\t\tvalue: result.value,\n\t\tgroups,\n\t\tsteps: worksheetSteps(definition, result, groups),\n\t\ttrace: result.trace,\n\t\terrors: result.errors,\n\t\tsuccess: result.success,\n\t}\n}\n\n/**\n * Build a rated {@link LineResult} from a line's evaluated\n * {@link QuantitativeResult}.\n *\n * @param definition - The authored line definition\n * @param result - The evaluated quantitative result\n * @param labels - Optional field-to-label overrides, keyed by dot-joined field\n * @returns A fresh line result\n *\n * @example\n * ```ts\n * import { createQuantitativeReasoner, createReason, quantitativeDefinition } from '@orkestrel/reason'\n * import { lineDefinition, ratedLine } from '@orkestrel/rater'\n *\n * const line = lineDefinition('base', 'Base', quantitativeDefinition('base', 'Base', []))\n * const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, line.rate)\n * if (result.reasoning === 'quantitative') ratedLine(line, result) // amount present only when success\n * ```\n */\nexport function ratedLine(\n\tdefinition: LineDefinition,\n\tresult: QuantitativeResult,\n\tlabels?: Readonly<Record<string, string>>,\n): LineResult {\n\treturn {\n\t\tid: definition.id,\n\t\tname: definition.name,\n\t\t...(result.success ? { amount: result.value } : {}),\n\t\tworksheet: resultsWorksheet(definition.rate, result, labels),\n\t\tsuccess: result.success,\n\t}\n}\n\n/**\n * Sum defined line amounts.\n *\n * @param lines - The rated lines\n * @returns The sum of every line's `amount`, or `undefined` when no line has one\n *\n * @example\n * ```ts\n * import { createQuantitativeReasoner, createReason, factorGroup, quantitativeDefinition, staticFactor } from '@orkestrel/reason'\n * import { lineDefinition, ratedLine, sumAmounts } from '@orkestrel/rater'\n *\n * const rate = quantitativeDefinition('base', 'Base', [factorGroup('g', 'sum', [staticFactor('flat', 100)])])\n * const line = lineDefinition('base', 'Base', rate)\n * const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, rate)\n * if (result.reasoning === 'quantitative') sumAmounts([ratedLine(line, result)]) // 100\n * ```\n */\nexport function sumAmounts(lines: readonly LineResult[]): number | undefined {\n\tlet total = 0\n\tlet count = 0\n\tfor (const rated of lines) {\n\t\tif (rated.amount !== undefined) {\n\t\t\ttotal += rated.amount\n\t\t\tcount += 1\n\t\t}\n\t}\n\treturn count === 0 ? undefined : total\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tQuantitativeDefinition,\n\tQuantitativeResult,\n\tReasonInterface,\n\tSubject,\n} from '@orkestrel/reason'\nimport type {\n\tLineDefinition,\n\tLineResult,\n\tRaterEventMap,\n\tRaterInterface,\n\tRaterOptions,\n\tRatingDefinition,\n\tRatingResult,\n\tTotalHandler,\n} from './types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { arrayOf, isArray } from '@orkestrel/contract'\nimport {\n\tbuildErrorResult,\n\tcreateQuantitativeReasoner,\n\tcreateReason,\n\tisSubject,\n} from '@orkestrel/reason'\nimport { RaterError } from './errors.js'\nimport { ratedLine, sumAmounts } from './helpers.js'\nimport { isLineDefinition, isRatingDefinition } from './validators.js'\n\n/**\n * The rating orchestrator — owns (or receives) the shared quantitative\n * reasoning engine and projects results into the rating domain vocabulary.\n *\n * @remarks\n * When no `engine` is injected, `Rater` builds and OWNS its own\n * quantitative-only engine (`bail: false`) — Rater performs NO evaluation\n * arithmetic of its own; it only orchestrates and projects. The\n * array-of-lines `rate` overload is declared FIRST (AGENTS §9.2). `destroy()`\n * destroys an OWNED engine, then the emitter LAST (AGENTS §13); an INJECTED\n * engine is never destroyed. Afterwards every other method throws\n * {@link RaterError} `'DESTROYED'`.\n *\n * @example\n * ```ts\n * import { Rater } from '@orkestrel/rater'\n *\n * const rater = new Rater()\n * rater.rate([], { id: 'subject-1' }) // { lines: [], success: true }\n * rater.destroy()\n * ```\n */\nexport class Rater implements RaterInterface {\n\treadonly #emitter: Emitter<RaterEventMap>\n\treadonly #engine: ReasonInterface\n\treadonly #owned: boolean\n\treadonly #total: TotalHandler | undefined\n\treadonly #labels: Readonly<Record<string, string>> | undefined\n\t#destroyed = false\n\n\tconstructor(options?: RaterOptions) {\n\t\tthis.#emitter = new Emitter<RaterEventMap>({\n\t\t\t...(options?.on === undefined ? {} : { on: options.on }),\n\t\t\t...(options?.error === undefined ? {} : { error: options.error }),\n\t\t})\n\t\tif (options?.engine === undefined) {\n\t\t\tthis.#engine = createReason({ reasoners: [createQuantitativeReasoner()], bail: false })\n\t\t\tthis.#owned = true\n\t\t} else {\n\t\t\tthis.#engine = options.engine\n\t\t\tthis.#owned = false\n\t\t}\n\t\tthis.#total = options?.total\n\t\tthis.#labels = options?.labels\n\t}\n\n\tget emitter(): EmitterInterface<RaterEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\t// Array overload first (AGENTS §9.2) so a plain line list resolves to that form.\n\trate(lines: readonly LineDefinition[], subject: Subject): RatingResult\n\trate(definition: RatingDefinition, subject: Subject): RatingResult\n\trate(input: readonly LineDefinition[] | RatingDefinition, subject: Subject): RatingResult {\n\t\tthis.#ensureAlive()\n\t\tconst lines = this.#normalize(input)\n\t\tif (!isSubject(subject)) throw new RaterError('MISMATCH', 'Subject must be a record')\n\t\tconst results = lines.map((line) => this.#rateLine(line, subject))\n\t\tconst total = (this.#total ?? sumAmounts)(results)\n\t\tconst success = results.every((entry) => entry.success)\n\t\tconst result: RatingResult = {\n\t\t\tlines: results,\n\t\t\t...(total === undefined ? {} : { total }),\n\t\t\tsuccess,\n\t\t}\n\t\tthis.#emitter.emit('rate', subject, result)\n\t\treturn result\n\t}\n\n\tdestroy(): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#destroyed = true\n\t\tif (this.#owned) this.#engine.destroy()\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#normalize(input: readonly LineDefinition[] | RatingDefinition): readonly LineDefinition[] {\n\t\tif (arrayOf(isLineDefinition)(input)) return input\n\t\tif (isRatingDefinition(input)) return input.lines\n\t\tthrow new RaterError(\n\t\t\t'DEFINITION',\n\t\t\t'Rating input must be an array of line definitions or a rating definition',\n\t\t)\n\t}\n\n\t#rateLine(line: LineDefinition, subject: Subject): LineResult {\n\t\tconst result = this.#reasonQuantitative(subject, line.rate)\n\t\treturn ratedLine(line, result, this.#labels)\n\t}\n\n\t// Narrows the engine's tagged ReasonResult union down to a QuantitativeResult\n\t// for a definition the engine is guaranteed (by dispatch-by-reasoning, given\n\t// only the quantitative reasoner is ever registered) to resolve as such — a\n\t// defensive, total fallback rather than an assertion. A nonconforming\n\t// injected engine result missing (or with a non-array) `errors` contributes\n\t// no errors from that side rather than throwing.\n\t#reasonQuantitative(subject: Subject, definition: QuantitativeDefinition): QuantitativeResult {\n\t\tconst result = this.#engine.reason(subject, definition)\n\t\tif (result.reasoning === 'quantitative') return result\n\t\tconst failure = buildErrorResult(\n\t\t\tdefinition,\n\t\t\t`Expected quantitative result, got ${result.reasoning}`,\n\t\t)\n\t\tconst errors = [...(isArray<string>(result.errors) ? result.errors : []), ...failure.errors]\n\t\tif (failure.reasoning === 'quantitative') return { ...failure, errors }\n\t\treturn {\n\t\t\treasoning: 'quantitative',\n\t\t\tvalue: 0,\n\t\t\tgroups: [],\n\t\t\tcount: 0,\n\t\t\tsuccess: false,\n\t\t\ttrace: [],\n\t\t\terrors,\n\t\t}\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) throw new RaterError('DESTROYED', 'Rater has been destroyed')\n\t}\n}\n","import type { RaterInterface, RaterOptions } from './types.js'\nimport { Rater } from './Rater.js'\n\n/**\n * Create a rating orchestrator.\n *\n * @param options - Optional total handler, labels, injected engine, and emitter hooks\n * @returns A {@link RaterInterface}\n *\n * @example\n * ```ts\n * import { createRater } from '@orkestrel/rater'\n *\n * const rater = createRater()\n * rater.destroy()\n * ```\n */\nexport function createRater(options?: RaterOptions): RaterInterface {\n\treturn new Rater(options)\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiBA,IAAa,aAAb,cAAgC,MAAM;CACrC;CACA;CAEA,YAAY,MAAsB,SAAiB,SAA6C;EAC/F,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,OAAO;EACZ,IAAI,YAAY,KAAA,GAAW,KAAK,UAAU;CAC3C;AACD;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,aAAa,OAAqC;CACjE,OAAO,iBAAiB;AACzB;;;;;;;;;;;;;;;;;ACJA,IAAa,UAAwB,UAAU,UAAU,SAAS,OAAO;;;;;;;;;;;;;;;;;;;AAoBzE,SAAgB,iBAAiB,OAAyC;CACzE,OAAO,SACN;EACC,IAAI;EACJ,MAAM;EACN,aAAa;EACb,MAAM;EACN,UAAU;CACX,GACA,CAAC,eAAe,UAAU,CAC3B,CAAC,CAAC,KAAK;AACR;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,mBAAmB,OAA2C;CAC7E,OAAO,SACN;EACC,IAAI;EACJ,MAAM;EACN,aAAa;EACb,OAAO,QAAQ,gBAAgB;EAC/B,UAAU;CACX,GACA,CAAC,eAAe,UAAU,CAC3B,CAAC,CAAC,KAAK;AACR;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,WAAW,OAAmC;CAC7D,OAAO,SACN;EACC,OAAO;EACP,OAAO;EACP,YAAY;EACZ,KAAK;CACN,GACA;EAAC;EAAS;EAAS;EAAc;CAAK,CACvC,CAAC,CAAC,KAAK;AACR;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,kBAAkB,OAA0C;CAC3E,OAAO,SACN;EACC,IAAI;EACJ,MAAM;EACN,aAAa;EACb,SAAS;EACT,OAAO;EACP,UAAU,QAAQ,UAAU;CAC7B,GACA;EAAC;EAAQ;EAAe;CAAO,CAChC,CAAC,CAAC,KAAK;AACR;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,iBAAiB,OAAyC;CACzE,OAAO,SACN;EACC,IAAI;EACJ,MAAM;EACN,aAAa;EACb,SAAS;EACT,OAAO;EACP,SAAS,QAAQ,iBAAiB;CACnC,GACA,CAAC,QAAQ,aAAa,CACvB,CAAC,CAAC,KAAK;AACR;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,OAAO,OAA+B;CACrD,OAAO,SACN;EACC,OAAO;EACP,IAAI;EACJ,MAAM;EACN,OAAO;EACP,YAAY;CACb,GACA;EAAC;EAAM;EAAQ;CAAY,CAC5B,CAAC,CAAC,KAAK;AACR;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,YAAY,OAAoC;CAC/D,OAAO,SACN;EACC,IAAI;EACJ,MAAM;EACN,aAAa;EACb,WAAW;EACX,OAAO;EACP,QAAQ,QAAQ,gBAAgB;EAChC,OAAO,QAAQ,MAAM;EACrB,OAAO,QAAQ,QAAQ;EACvB,QAAQ,QAAQ,QAAQ;EACxB,SAAS;CACV,GACA,CAAC,WAAW,CACb,CAAC,CAAC,KAAK;AACR;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,aAAa,OAAqC;CACjE,OAAO,SACN;EACC,IAAI;EACJ,MAAM;EACN,QAAQ;EACR,WAAW;EACX,SAAS;CACV,GACA,CAAC,QAAQ,CACV,CAAC,CAAC,KAAK;AACR;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,eAAe,OAAuC;CACrE,OAAO,SACN;EACC,OAAO,QAAQ,YAAY;EAC3B,OAAO;EACP,SAAS;CACV,GACA,CAAC,OAAO,CACT,CAAC,CAAC,KAAK;AACR;;;;;;;;;;;;;;;;;;;;AC7RA,SAAgB,eACf,IACA,MACA,MACA,WACiB;CACjB,OAAO;EAAE;EAAI;EAAM;EAAM,GAAG;CAAU;AACvC;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,iBACf,IACA,MACA,OACA,WACmB;CACnB,OAAO;EAAE;EAAI;EAAM;EAAO,GAAG;CAAU;AACxC;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,cACf,OACA,QACA,KACA,QACW;CACX,MAAM,QAAQ,YAAY,MAAM,KAAK;CACrC,OAAO;EACN,OAAO,MAAM;EACb,GAAI,SAAS,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,OAAO,OAAO;EAChE,YAAY,MAAM;EAClB,UAAU,MAAM;EAChB;EACA,GAAI,QAAQ,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI;CACpC;AACD;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,cACf,QACA,SACA,QACsB;CACtB,QAAQ,UAAU,CAAC,EAAA,CAAG,KAAK,OAAO,UAAU;EAC3C,MAAM,SAAS,UAAU;EACzB,OAAO,cAAc,OAAO,QAAQ,QAAQ,QAAQ,KAAK,MAAM;CAChE,CAAC;AACF;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,gBACf,YACA,SACA,QACkB;CAClB,MAAM,SAAS,QAAQ,MAAM,UAAU,MAAM,OAAO,WAAW,EAAE;CACjE,OAAO;EACN,IAAI,WAAW;EACf,MAAM,WAAW;EACjB,GAAI,WAAW,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,WAAW,YAAY;EACtF,SAAS,QAAQ,WAAW;EAC5B,GAAI,QAAQ,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,OAAO,MAAM;EAC7D,UAAU,cAAc,WAAW,QAAQ,QAAQ,QAAQ,MAAM;CAClE;AACD;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,eACf,YACA,SACA,QACiB;CACjB,MAAM,SAAS,QAAQ,MAAM,UAAU,MAAM,OAAO,WAAW,EAAE;CACjE,OAAO;EACN,IAAI,WAAW;EACf,MAAM,WAAW;EACjB,GAAI,WAAW,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,WAAW,YAAY;EACtF,SAAS,QAAQ,WAAW;EAC5B,OAAO,QAAQ,SAAS;EACxB,SAAS,WAAW,QAAQ,KAAK,WAChC,gBAAgB,QAAQ,QAAQ,WAAW,CAAC,GAAG,MAAM,CACtD;CACD;AACD;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,cACf,OACA,IACA,MACA,OACA,YACO;CACP,OAAO;EACN;EACA,GAAI,OAAO,KAAA,IAAY,CAAC,IAAI,EAAE,GAAG;EACjC,GAAI,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,KAAK;EACrC;EACA;CACD;AACD;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,eACf,YACA,QACA,QACkB;CAClB,MAAM,SAAiB,CAAC;CACxB,KAAK,MAAM,SAAS,QAAQ;EAC3B,KAAK,MAAM,UAAU,MAAM,SAC1B,IAAI,OAAO,WAAW,OAAO,UAAU,KAAA,GACtC,OAAO,KACN,cACC,UACA,OAAO,IACP,OAAO,MACP,OAAO,OACP,GAAG,OAAO,GAAG,KAAK,OAAO,OAC1B,CACD;EAGF,OAAO,KACN,cAAc,SAAS,MAAM,IAAI,MAAM,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,KAAK,MAAM,OAAO,CACzF;CACD;CACA,OAAO,KACN,cACC,SACA,WAAW,IACX,WAAW,MACX,OAAO,OACP,GAAG,WAAW,YAAY,KAAK,OAAO,OACvC,CACD;CACA,OAAO;AACR;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,iBACf,YACA,QACA,QACY;CACZ,MAAM,SAAS,WAAW,OAAO,KAAK,UAAU,eAAe,OAAO,OAAO,QAAQ,MAAM,CAAC;CAC5F,OAAO;EACN,IAAI,WAAW;EACf,MAAM,WAAW;EACjB,aAAa,WAAW;EACxB,GAAI,WAAW,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,WAAW,UAAU;EAChF,OAAO,OAAO;EACd;EACA,OAAO,eAAe,YAAY,QAAQ,MAAM;EAChD,OAAO,OAAO;EACd,QAAQ,OAAO;EACf,SAAS,OAAO;CACjB;AACD;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,UACf,YACA,QACA,QACa;CACb,OAAO;EACN,IAAI,WAAW;EACf,MAAM,WAAW;EACjB,GAAI,OAAO,UAAU,EAAE,QAAQ,OAAO,MAAM,IAAI,CAAC;EACjD,WAAW,iBAAiB,WAAW,MAAM,QAAQ,MAAM;EAC3D,SAAS,OAAO;CACjB;AACD;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,WAAW,OAAkD;CAC5E,IAAI,QAAQ;CACZ,IAAI,QAAQ;CACZ,KAAK,MAAM,SAAS,OACnB,IAAI,MAAM,WAAW,KAAA,GAAW;EAC/B,SAAS,MAAM;EACf,SAAS;CACV;CAED,OAAO,UAAU,IAAI,KAAA,IAAY;AAClC;;;;;;;;;;;;;;;;;;;;;;;;;AC1VA,IAAa,QAAb,MAA6C;CAC5C;CACA;CACA;CACA;CACA;CACA,aAAa;CAEb,YAAY,SAAwB;EACnC,KAAKA,WAAW,IAAI,QAAuB;GAC1C,GAAI,SAAS,OAAO,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI,QAAQ,GAAG;GACtD,GAAI,SAAS,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,MAAM;EAChE,CAAC;EACD,IAAI,SAAS,WAAW,KAAA,GAAW;GAClC,KAAKC,UAAU,aAAa;IAAE,WAAW,CAAC,2BAA2B,CAAC;IAAG,MAAM;GAAM,CAAC;GACtF,KAAKC,SAAS;EACf,OAAO;GACN,KAAKD,UAAU,QAAQ;GACvB,KAAKC,SAAS;EACf;EACA,KAAKC,SAAS,SAAS;EACvB,KAAKC,UAAU,SAAS;CACzB;CAEA,IAAI,UAA2C;EAC9C,OAAO,KAAKJ;CACb;CAKA,KAAK,OAAqD,SAAgC;EACzF,KAAKK,aAAa;EAClB,MAAM,QAAQ,KAAKC,WAAW,KAAK;EACnC,IAAI,CAAC,UAAU,OAAO,GAAG,MAAM,IAAI,WAAW,YAAY,0BAA0B;EACpF,MAAM,UAAU,MAAM,KAAK,SAAS,KAAKC,UAAU,MAAM,OAAO,CAAC;EACjE,MAAM,SAAS,KAAKJ,UAAU,WAAA,CAAY,OAAO;EACjD,MAAM,UAAU,QAAQ,OAAO,UAAU,MAAM,OAAO;EACtD,MAAM,SAAuB;GAC5B,OAAO;GACP,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;GACvC;EACD;EACA,KAAKH,SAAS,KAAK,QAAQ,SAAS,MAAM;EAC1C,OAAO;CACR;CAEA,UAAgB;EACf,IAAI,KAAKQ,YAAY;EACrB,KAAKA,aAAa;EAClB,IAAI,KAAKN,QAAQ,KAAKD,QAAQ,QAAQ;EACtC,KAAKD,SAAS,QAAQ;CACvB;CAEA,WAAW,OAAgF;EAC1F,IAAI,QAAQ,gBAAgB,CAAC,CAAC,KAAK,GAAG,OAAO;EAC7C,IAAI,mBAAmB,KAAK,GAAG,OAAO,MAAM;EAC5C,MAAM,IAAI,WACT,cACA,0EACD;CACD;CAEA,UAAU,MAAsB,SAA8B;EAE7D,OAAO,UAAU,MADF,KAAKS,oBAAoB,SAAS,KAAK,IAC/B,GAAQ,KAAKL,OAAO;CAC5C;CAQA,oBAAoB,SAAkB,YAAwD;EAC7F,MAAM,SAAS,KAAKH,QAAQ,OAAO,SAAS,UAAU;EACtD,IAAI,OAAO,cAAc,gBAAgB,OAAO;EAChD,MAAM,UAAU,iBACf,YACA,qCAAqC,OAAO,WAC7C;EACA,MAAM,SAAS,CAAC,GAAI,QAAgB,OAAO,MAAM,IAAI,OAAO,SAAS,CAAC,GAAI,GAAG,QAAQ,MAAM;EAC3F,IAAI,QAAQ,cAAc,gBAAgB,OAAO;GAAE,GAAG;GAAS;EAAO;EACtE,OAAO;GACN,WAAW;GACX,OAAO;GACP,QAAQ,CAAC;GACT,OAAO;GACP,SAAS;GACT,OAAO,CAAC;GACR;EACD;CACD;CAEA,eAAqB;EACpB,IAAI,KAAKO,YAAY,MAAM,IAAI,WAAW,aAAa,0BAA0B;CAClF;AACD;;;;;;;;;;;;;;;;;ACnIA,SAAgB,YAAY,SAAwC;CACnE,OAAO,IAAI,MAAM,OAAO;AACzB"}