@orkestrel/rater 0.0.12 → 0.0.14

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.
@@ -1,14 +1,15 @@
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";
1
+ import { arrayOf, isArray, isBoolean, isJSONValue, isNumber, isRecord, isString, literalOf, objectOf, recordOf } from "@orkestrel/contract";
2
+ import { buildErrorResult, createQuantitativeReasoner, createReason, formatField, isAggregation, isComparison, isFieldPath, isQuantitativeDefinition } from "@orkestrel/reason";
3
3
  import { Emitter } from "@orkestrel/emitter";
4
4
  //#region src/core/errors.ts
5
5
  /**
6
- * A coded programmer error thrown by the rating layer.
6
+ * Represents a coded programmer error thrown by the rating layer.
7
7
  *
8
8
  * @remarks
9
9
  * `DEFINITION` — the `rate` input failed both the array-of-lines and rating
10
10
  * definition validation. `MISMATCH` — a rated subject is not a record.
11
- * `DESTROYED` — use of a destroyed entity.
11
+ * `DESTROYED` — use of a destroyed entity. `context` carries optional
12
+ * structured detail beside the message.
12
13
  *
13
14
  * @example
14
15
  * ```ts
@@ -28,10 +29,10 @@ var RaterError = class extends Error {
28
29
  }
29
30
  };
30
31
  /**
31
- * Narrow a caught value to a {@link RaterError}.
32
+ * Narrows a caught value to a {@link RaterError}.
32
33
  *
33
34
  * @param value - The caught value to test
34
- * @returns `true` when `value` is a `RaterError`
35
+ * @returns True if `value` is a `RaterError`; false otherwise
35
36
  *
36
37
  * @example
37
38
  * ```ts
@@ -50,10 +51,14 @@ function isRaterError(value) {
50
51
  //#endregion
51
52
  //#region src/core/validators.ts
52
53
  /**
53
- * Determine whether a value is a {@link Stage} literal.
54
+ * Determines whether a value is a {@link Stage} literal.
55
+ *
56
+ * @remarks
57
+ * A scalar union has no open or exact axis, so this guard accepts one of the
58
+ * `Stage` literals and leaves nothing unchecked.
54
59
  *
55
60
  * @param value - The value to test
56
- * @returns `true` when `value` is `'factor'`, `'group'`, or `'total'`
61
+ * @returns True if `value` is `'factor'`, `'group'`, or `'total'`; false otherwise
57
62
  *
58
63
  * @example
59
64
  * ```ts
@@ -65,21 +70,24 @@ function isRaterError(value) {
65
70
  */
66
71
  var isStage = literalOf("factor", "group", "total");
67
72
  /**
68
- * Determine whether a value is an exact {@link LineDefinition} record.
73
+ * Determines whether a value is an exact {@link LineDefinition} record.
69
74
  *
70
75
  * @remarks
71
- * Total guard (AGENTS §14): adversarial input (cycles, hostile prototypes)
72
- * returns `false`, never throws. The record shape is EXACT — an extra key fails.
76
+ * Every `LineDefinition` member is checked, including its quantitative
77
+ * definition. Total guard: adversarial input (cycles, hostile prototypes)
78
+ * returns `false`, never throws. The record shape is exact — this package owns
79
+ * the authored input record, so an extra key fails and nothing is left
80
+ * unchecked.
73
81
  *
74
82
  * @param value - The value to test
75
- * @returns `true` when `value` is a `LineDefinition`
83
+ * @returns True if `value` is a `LineDefinition`; false otherwise
76
84
  *
77
85
  * @example
78
86
  * ```ts
79
- * import { quantitativeDefinition } from '@orkestrel/reason'
87
+ * import { createQuantitativeDefinition } from '@orkestrel/reason'
80
88
  * import { isLineDefinition } from '@orkestrel/rater'
81
89
  *
82
- * isLineDefinition({ id: 'base', name: 'Base', rate: quantitativeDefinition('base', 'Base', []) }) // true
90
+ * isLineDefinition({ id: 'base', name: 'Base', rate: createQuantitativeDefinition('base', 'Base', []) }) // true
83
91
  * ```
84
92
  */
85
93
  function isLineDefinition(value) {
@@ -92,14 +100,17 @@ function isLineDefinition(value) {
92
100
  }, ["description", "metadata"])(value);
93
101
  }
94
102
  /**
95
- * Determine whether a value is an exact {@link RatingDefinition} record.
103
+ * Determines whether a value is an exact {@link RatingDefinition} record.
96
104
  *
97
105
  * @remarks
98
- * Total guard (AGENTS §14): adversarial input (cycles, hostile prototypes)
99
- * returns `false`, never throws. The record shape is EXACT — an extra key fails.
106
+ * Every `RatingDefinition` member is checked, including each nested line
107
+ * definition. Total guard: adversarial input (cycles, hostile prototypes)
108
+ * returns `false`, never throws. The record shape is exact — this package owns
109
+ * the authored input record, so an extra key fails and nothing is left
110
+ * unchecked.
100
111
  *
101
112
  * @param value - The value to test
102
- * @returns `true` when `value` is a `RatingDefinition`
113
+ * @returns True if `value` is a `RatingDefinition`; false otherwise
103
114
  *
104
115
  * @example
105
116
  * ```ts
@@ -118,16 +129,19 @@ function isRatingDefinition(value) {
118
129
  }, ["description", "metadata"])(value);
119
130
  }
120
131
  /**
121
- * Determine whether a value is an open result-side {@link Evidence} object.
132
+ * Determines whether a value is an open result-side {@link Evidence} object.
122
133
  *
123
134
  * @remarks
135
+ * Optional `field` is checked as a `FieldPath`, `label` as a string,
136
+ * `comparison` as a `Comparison`, and `met` as a boolean, each when defined.
124
137
  * Unknown members, prototypes, and class instances are admitted. Arrays are
125
138
  * 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.
139
+ * check them and a borrowed result is never narrowed on them; either member may
140
+ * also be absent because `objectOf` reads declared members rather than
141
+ * requiring or enumerating own keys.
128
142
  *
129
143
  * @param value - The value to test
130
- * @returns `true` when every checked `Evidence` member conforms
144
+ * @returns True if every checked `Evidence` member conforms; false otherwise
131
145
  *
132
146
  * @example
133
147
  * ```ts
@@ -150,14 +164,17 @@ function isEvidence(value) {
150
164
  ])(value);
151
165
  }
152
166
  /**
153
- * Determine whether a value is an open {@link WorksheetFactor} result object.
167
+ * Determines whether a value is an open {@link WorksheetFactor} result object.
154
168
  *
155
169
  * @remarks
156
- * Unknown members, prototypes, and class instances are admitted. Arrays are
157
- * refused. Optional members may be absent or read as `undefined`.
170
+ * `id`, the optional authored text, `applied`, an optional plain-number
171
+ * `value`, and each `Evidence` entry are checked. Unknown members, prototypes,
172
+ * and class instances are admitted and left unchecked, because a borrowed
173
+ * result implementation may add them. Arrays are refused. Optional members may
174
+ * be absent or read as `undefined`.
158
175
  *
159
176
  * @param value - The value to test
160
- * @returns `true` when every published worksheet-factor member conforms
177
+ * @returns True if every published worksheet-factor member conforms; false otherwise
161
178
  *
162
179
  * @example
163
180
  * ```ts
@@ -181,14 +198,17 @@ function isWorksheetFactor(value) {
181
198
  ])(value);
182
199
  }
183
200
  /**
184
- * Determine whether a value is an open {@link WorksheetGroup} result object.
201
+ * Determines whether a value is an open {@link WorksheetGroup} result object.
185
202
  *
186
203
  * @remarks
187
- * Unknown members, prototypes, and class instances are admitted. Arrays are
188
- * refused. Optional members may be absent or read as `undefined`.
204
+ * `id`, the optional authored text, `applied`, a plain-number `value`, and each
205
+ * `WorksheetFactor` entry are checked. Unknown members, prototypes, and class
206
+ * instances are admitted and left unchecked, because a borrowed result
207
+ * implementation may add them. Arrays are refused. Optional members may be
208
+ * absent or read as `undefined`.
189
209
  *
190
210
  * @param value - The value to test
191
- * @returns `true` when every published worksheet-group member conforms
211
+ * @returns True if every published worksheet-group member conforms; false otherwise
192
212
  *
193
213
  * @example
194
214
  * ```ts
@@ -208,14 +228,17 @@ function isWorksheetGroup(value) {
208
228
  }, ["name", "description"])(value);
209
229
  }
210
230
  /**
211
- * Determine whether a value is an open {@link Step} result object.
231
+ * Determines whether a value is an open {@link Step} result object.
212
232
  *
213
233
  * @remarks
214
- * Unknown members, prototypes, and class instances are admitted. Arrays are
215
- * refused. Optional members may be absent or read as `undefined`.
234
+ * `stage` is checked through `isStage`, `id`, `name`, and `expression` when
235
+ * defined, and `value` as a plain number. Unknown members, prototypes, and
236
+ * class instances are admitted and left unchecked, because a borrowed result
237
+ * implementation may add them. Arrays are refused. Optional members may be
238
+ * absent or read as `undefined`.
216
239
  *
217
240
  * @param value - The value to test
218
- * @returns `true` when every published worksheet-step member conforms
241
+ * @returns True if every published worksheet-step member conforms; false otherwise
219
242
  *
220
243
  * @example
221
244
  * ```ts
@@ -238,14 +261,18 @@ function isStep(value) {
238
261
  ])(value);
239
262
  }
240
263
  /**
241
- * Determine whether a value is an open {@link Worksheet} result object.
264
+ * Determines whether a value is an open {@link Worksheet} result object.
242
265
  *
243
266
  * @remarks
244
- * Unknown members, prototypes, and class instances are admitted. Arrays are
245
- * refused. Optional members may be absent or read as `undefined`.
267
+ * Identity, `aggregation` through reason's `isAggregation`, an optional
268
+ * plain-number `precision`, a plain-number `value`, the nested groups and steps,
269
+ * `trace`, `errors`, and `success` are checked. Unknown members, prototypes, and
270
+ * class instances are admitted and left unchecked, because a borrowed result
271
+ * implementation may add them. Arrays are refused. Optional members may be
272
+ * absent or read as `undefined`.
246
273
  *
247
274
  * @param value - The value to test
248
- * @returns `true` when every published worksheet member conforms
275
+ * @returns True if every published worksheet member conforms; false otherwise
249
276
  *
250
277
  * @example
251
278
  * ```ts
@@ -269,21 +296,26 @@ function isWorksheet(value) {
269
296
  }, ["precision"])(value);
270
297
  }
271
298
  /**
272
- * Determine whether a value is an open {@link LineResult} object.
299
+ * Determines whether a value is an open {@link LineResult} object.
273
300
  *
274
301
  * @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.
302
+ * Identity, an optional plain-number `amount`, and the nested `Worksheet` that
303
+ * carries the line's outcome are checked. Unknown members, prototypes, and
304
+ * class instances are admitted and left unchecked, because a borrowed result
305
+ * implementation may add them, and so is the relationship between `amount` and
306
+ * `worksheet.success`, which the published interface types independently.
307
+ * Arrays are refused. `amount` may be absent or read as `undefined`; when
308
+ * present it stays a plain JavaScript `number` without a finite or range
309
+ * refinement.
278
310
  *
279
311
  * @param value - The value to test
280
- * @returns `true` when every published line-result member conforms
312
+ * @returns True if every published line-result member conforms; false otherwise
281
313
  *
282
314
  * @example
283
315
  * ```ts
284
316
  * import { isLineResult } from '@orkestrel/rater'
285
317
  *
286
- * isLineResult({ id: 'base', name: 'Base', worksheet: { id: 'base', name: 'Base', aggregation: 'sum', value: 0, groups: [], steps: [], trace: [], errors: [], success: false }, success: false }) // true
318
+ * isLineResult({ id: 'base', name: 'Base', worksheet: { id: 'base', name: 'Base', aggregation: 'sum', value: 0, groups: [], steps: [], trace: [], errors: [], success: false } }) // true
287
319
  * ```
288
320
  */
289
321
  function isLineResult(value) {
@@ -291,21 +323,23 @@ function isLineResult(value) {
291
323
  id: isString,
292
324
  name: isString,
293
325
  amount: isNumber,
294
- worksheet: isWorksheet,
295
- success: isBoolean
326
+ worksheet: isWorksheet
296
327
  }, ["amount"])(value);
297
328
  }
298
329
  /**
299
- * Determine whether a value is an open {@link RatingResult} object.
330
+ * Determines whether a value is an open {@link RatingResult} object.
300
331
  *
301
332
  * @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.
333
+ * Use this guard for a result returned by a borrowed `RaterInterface`. Every
334
+ * nested `LineResult`, an optional plain-number `total`, and a boolean `success`
335
+ * are checked. Unknown members, prototypes, and class instances are admitted and
336
+ * left unchecked, and so are the relationships among totals, lines, and success,
337
+ * because the borrowed interface publishes only their member types. Arrays are
338
+ * refused. `total` may be absent or read as `undefined`; when present it stays a
339
+ * plain JavaScript `number` without a finite or range refinement.
306
340
  *
307
341
  * @param value - The value to test
308
- * @returns `true` when every published rating-result member conforms
342
+ * @returns True if every published rating-result member conforms; false otherwise
309
343
  *
310
344
  * @example
311
345
  * ```ts
@@ -324,7 +358,9 @@ function isRatingResult(value) {
324
358
  //#endregion
325
359
  //#region src/core/helpers.ts
326
360
  /**
327
- * Build a {@link LineDefinition}.
361
+ * Builds a fresh {@link LineDefinition} from a line id, a display name, and the
362
+ * line's quantitative rating definition, with `overrides` merged over those
363
+ * defaults.
328
364
  *
329
365
  * @param id - The line id
330
366
  * @param name - The display name
@@ -334,13 +370,13 @@ function isRatingResult(value) {
334
370
  *
335
371
  * @example
336
372
  * ```ts
337
- * import { quantitativeDefinition } from '@orkestrel/reason'
338
- * import { lineDefinition } from '@orkestrel/rater'
373
+ * import { createQuantitativeDefinition } from '@orkestrel/reason'
374
+ * import { buildLineDefinition } from '@orkestrel/rater'
339
375
  *
340
- * lineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', []))
376
+ * buildLineDefinition('base', 'Base Amount', createQuantitativeDefinition('base', 'Base', []))
341
377
  * ```
342
378
  */
343
- function lineDefinition(id, name, rate, overrides) {
379
+ function buildLineDefinition(id, name, rate, overrides) {
344
380
  return {
345
381
  id,
346
382
  name,
@@ -349,7 +385,8 @@ function lineDefinition(id, name, rate, overrides) {
349
385
  };
350
386
  }
351
387
  /**
352
- * Build a {@link RatingDefinition}.
388
+ * Builds a fresh {@link RatingDefinition} from a rating id, a display name, and
389
+ * the rating's ordered lines, with `overrides` merged over those defaults.
353
390
  *
354
391
  * @param id - The rating id
355
392
  * @param name - The display name
@@ -359,15 +396,15 @@ function lineDefinition(id, name, rate, overrides) {
359
396
  *
360
397
  * @example
361
398
  * ```ts
362
- * import { lineDefinition, ratingDefinition } from '@orkestrel/rater'
363
- * import { quantitativeDefinition } from '@orkestrel/reason'
399
+ * import { buildLineDefinition, buildRatingDefinition } from '@orkestrel/rater'
400
+ * import { createQuantitativeDefinition } from '@orkestrel/reason'
364
401
  *
365
- * ratingDefinition('r1', 'Rating', [
366
- * lineDefinition('base', 'Base Amount', quantitativeDefinition('base', 'Base', [])),
402
+ * buildRatingDefinition('r1', 'Rating', [
403
+ * buildLineDefinition('base', 'Base Amount', createQuantitativeDefinition('base', 'Base', [])),
367
404
  * ])
368
405
  * ```
369
406
  */
370
- function ratingDefinition(id, name, lines, overrides) {
407
+ function buildRatingDefinition(id, name, lines, overrides) {
371
408
  return {
372
409
  id,
373
410
  name,
@@ -376,24 +413,25 @@ function ratingDefinition(id, name, lines, overrides) {
376
413
  };
377
414
  }
378
415
  /**
379
- * Build an {@link Evidence} row from an evaluated {@link Check}.
416
+ * Builds an {@link Evidence} row from an evaluated {@link Check}.
380
417
  *
381
418
  * @param check - The authored check
382
419
  * @param actual - The resolved subject value
383
- * @param met - Whether the check was met (absent when not yet evaluated)
420
+ * @param met - If `true`, the check was met; if `false`, it was not; absent when the check
421
+ * was not yet evaluated
384
422
  * @param labels - Optional field-to-label overrides, keyed by dot-joined field
385
423
  * @returns A fresh evidence row
386
424
  *
387
425
  * @example
388
426
  * ```ts
389
- * import { check } from '@orkestrel/reason'
390
- * import { evidenceCheck } from '@orkestrel/rater'
427
+ * import { createCheck } from '@orkestrel/reason'
428
+ * import { buildEvidence } from '@orkestrel/rater'
391
429
  *
392
- * const entry = check('age', 'above', 18)
393
- * evidenceCheck(entry, 25, true) // { field: 'age', comparison: 'above', expected: 18, actual: 25, met: true }
430
+ * const entry = createCheck('age', 'above', 18)
431
+ * buildEvidence(entry, 25, true) // { field: 'age', comparison: 'above', expected: 18, actual: 25, met: true }
394
432
  * ```
395
433
  */
396
- function evidenceCheck(check, actual, met, labels) {
434
+ function buildEvidence(check, actual, met, labels) {
397
435
  const field = formatField(check.field);
398
436
  return {
399
437
  field: check.field,
@@ -405,8 +443,8 @@ function evidenceCheck(check, actual, met, labels) {
405
443
  };
406
444
  }
407
445
  /**
408
- * Build evidence rows from a quantitative factor's authored checks and
409
- * evaluated check results.
446
+ * Builds one evidence row per authored check of a quantitative factor, joined
447
+ * to that check's evaluated result.
410
448
  *
411
449
  * @param checks - The factor's authored checks
412
450
  * @param results - The corresponding {@link CheckResult}s, in the same order
@@ -415,21 +453,21 @@ function evidenceCheck(check, actual, met, labels) {
415
453
  *
416
454
  * @example
417
455
  * ```ts
418
- * import { check } from '@orkestrel/reason'
419
- * import { checkEvidence } from '@orkestrel/rater'
456
+ * import { createCheck } from '@orkestrel/reason'
457
+ * import { buildEvidenceRows } from '@orkestrel/rater'
420
458
  *
421
- * const checks = [check('age', 'above', 18)]
422
- * checkEvidence(checks, [{ field: 'age', met: true, actual: 25 }])
459
+ * const checks = [createCheck('age', 'above', 18)]
460
+ * buildEvidenceRows(checks, [{ field: 'age', met: true, actual: 25 }])
423
461
  * ```
424
462
  */
425
- function checkEvidence(checks, results, labels) {
463
+ function buildEvidenceRows(checks, results, labels) {
426
464
  return (checks ?? []).map((check, index) => {
427
465
  const result = results?.[index];
428
- return evidenceCheck(check, result?.actual, result?.met, labels);
466
+ return buildEvidence(check, result?.actual, result?.met, labels);
429
467
  });
430
468
  }
431
469
  /**
432
- * Join one authored quantitative factor to its evaluated {@link FactorResult}.
470
+ * Joins one authored quantitative factor to its evaluated {@link FactorResult}.
433
471
  *
434
472
  * @param definition - The authored factor
435
473
  * @param results - The group's factor results
@@ -438,14 +476,14 @@ function checkEvidence(checks, results, labels) {
438
476
  *
439
477
  * @example
440
478
  * ```ts
441
- * import { fieldFactor } from '@orkestrel/reason'
442
- * import { worksheetFactor } from '@orkestrel/rater'
479
+ * import { createFieldFactor } from '@orkestrel/reason'
480
+ * import { buildWorksheetFactor } from '@orkestrel/rater'
443
481
  *
444
- * const factor = fieldFactor('seats', 'seats')
445
- * worksheetFactor(factor, [{ id: 'seats', applied: true, value: 10 }])
482
+ * const factor = createFieldFactor('seats', 'seats')
483
+ * buildWorksheetFactor(factor, [{ id: 'seats', applied: true, value: 10 }])
446
484
  * ```
447
485
  */
448
- function worksheetFactor(definition, results, labels) {
486
+ function buildWorksheetFactor(definition, results, labels) {
449
487
  const result = results.find((entry) => entry.id === definition.id);
450
488
  return {
451
489
  id: definition.id,
@@ -453,11 +491,11 @@ function worksheetFactor(definition, results, labels) {
453
491
  ...definition.description === void 0 ? {} : { description: definition.description },
454
492
  applied: result?.applied ?? false,
455
493
  ...result?.value === void 0 ? {} : { value: result.value },
456
- evidence: checkEvidence(definition.checks, result?.checks, labels)
494
+ evidence: buildEvidenceRows(definition.checks, result?.checks, labels)
457
495
  };
458
496
  }
459
497
  /**
460
- * Join one authored quantitative group to its evaluated {@link GroupResult}.
498
+ * Joins one authored quantitative group to its evaluated {@link GroupResult}.
461
499
  *
462
500
  * @param definition - The authored group
463
501
  * @param results - The definition's group results
@@ -466,14 +504,14 @@ function worksheetFactor(definition, results, labels) {
466
504
  *
467
505
  * @example
468
506
  * ```ts
469
- * import { factorGroup, staticFactor } from '@orkestrel/reason'
470
- * import { worksheetGroup } from '@orkestrel/rater'
507
+ * import { createFactorGroup, createStaticFactor } from '@orkestrel/reason'
508
+ * import { buildWorksheetGroup } from '@orkestrel/rater'
471
509
  *
472
- * const group = factorGroup('charge', 'sum', [staticFactor('base', 100)])
473
- * worksheetGroup(group, [{ id: 'charge', applied: true, value: 100, factors: [] }])
510
+ * const group = createFactorGroup('charge', 'sum', [createStaticFactor('base', 100)])
511
+ * buildWorksheetGroup(group, [{ id: 'charge', applied: true, value: 100, factors: [] }])
474
512
  * ```
475
513
  */
476
- function worksheetGroup(definition, results, labels) {
514
+ function buildWorksheetGroup(definition, results, labels) {
477
515
  const result = results.find((entry) => entry.id === definition.id);
478
516
  return {
479
517
  id: definition.id,
@@ -481,11 +519,11 @@ function worksheetGroup(definition, results, labels) {
481
519
  ...definition.description === void 0 ? {} : { description: definition.description },
482
520
  applied: result?.applied ?? false,
483
521
  value: result?.value ?? 0,
484
- factors: definition.factors.map((factor) => worksheetFactor(factor, result?.factors ?? [], labels))
522
+ factors: definition.factors.map((factor) => buildWorksheetFactor(factor, result?.factors ?? [], labels))
485
523
  };
486
524
  }
487
525
  /**
488
- * Build one display-neutral {@link Step} row.
526
+ * Builds one display-neutral {@link Step} row.
489
527
  *
490
528
  * @param stage - The step's stage
491
529
  * @param id - The stage's authored id, when it has one
@@ -496,13 +534,13 @@ function worksheetGroup(definition, results, labels) {
496
534
  *
497
535
  * @example
498
536
  * ```ts
499
- * import { worksheetStep } from '@orkestrel/rater'
537
+ * import { buildWorksheetStep } from '@orkestrel/rater'
500
538
  *
501
- * worksheetStep('total', 'quote', 'Quote', 110, 'sum = 110')
539
+ * buildWorksheetStep('total', 'quote', 'Quote', 110, 'sum = 110')
502
540
  * // { stage: 'total', id: 'quote', name: 'Quote', value: 110, expression: 'sum = 110' }
503
541
  * ```
504
542
  */
505
- function worksheetStep(stage, id, name, value, expression) {
543
+ function buildWorksheetStep(stage, id, name, value, expression) {
506
544
  return {
507
545
  stage,
508
546
  ...id === void 0 ? {} : { id },
@@ -512,7 +550,7 @@ function worksheetStep(stage, id, name, value, expression) {
512
550
  };
513
551
  }
514
552
  /**
515
- * Build the ordered {@link Step} rows for a resolved {@link Worksheet}.
553
+ * Builds the ordered {@link Step} rows for a resolved {@link Worksheet}.
516
554
  *
517
555
  * @param definition - The authored quantitative definition
518
556
  * @param result - The evaluated quantitative result
@@ -521,27 +559,27 @@ function worksheetStep(stage, id, name, value, expression) {
521
559
  *
522
560
  * @example
523
561
  * ```ts
524
- * import { createQuantitativeReasoner, createReason, factorGroup, quantitativeDefinition, staticFactor } from '@orkestrel/reason'
525
- * import { worksheetGroup, worksheetSteps } from '@orkestrel/rater'
562
+ * import { createFactorGroup, createQuantitativeDefinition, createQuantitativeReasoner, createReason, createStaticFactor } from '@orkestrel/reason'
563
+ * import { buildWorksheetGroup, buildWorksheetSteps } from '@orkestrel/rater'
526
564
  *
527
- * const definition = quantitativeDefinition('base', 'Base', [factorGroup('g', 'sum', [staticFactor('flat', 100)])])
565
+ * const definition = createQuantitativeDefinition('base', 'Base', [createFactorGroup('g', 'sum', [createStaticFactor('flat', 100)])])
528
566
  * const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, definition)
529
567
  * if (result.reasoning === 'quantitative') {
530
- * worksheetSteps(definition, result, definition.groups.map((group) => worksheetGroup(group, result.groups)))
568
+ * buildWorksheetSteps(definition, result, definition.groups.map((group) => buildWorksheetGroup(group, result.groups)))
531
569
  * }
532
570
  * ```
533
571
  */
534
- function worksheetSteps(definition, result, groups) {
572
+ function buildWorksheetSteps(definition, result, groups) {
535
573
  const output = [];
536
574
  for (const group of groups) {
537
- for (const factor of group.factors) if (factor.applied && factor.value !== void 0) output.push(worksheetStep("factor", factor.id, factor.name, factor.value, `${factor.id} = ${factor.value}`));
538
- output.push(worksheetStep("group", group.id, group.name, group.value, `${group.id} = ${group.value}`));
575
+ for (const factor of group.factors) if (factor.applied && factor.value !== void 0) output.push(buildWorksheetStep("factor", factor.id, factor.name, factor.value, `${factor.id} = ${factor.value}`));
576
+ output.push(buildWorksheetStep("group", group.id, group.name, group.value, `${group.id} = ${group.value}`));
539
577
  }
540
- output.push(worksheetStep("total", definition.id, definition.name, result.value, `${definition.aggregation} = ${result.value}`));
578
+ output.push(buildWorksheetStep("total", definition.id, definition.name, result.value, `${definition.aggregation} = ${result.value}`));
541
579
  return output;
542
580
  }
543
581
  /**
544
- * Join a {@link QuantitativeDefinition} and its {@link QuantitativeResult} into
582
+ * Joins a {@link QuantitativeDefinition} and its {@link QuantitativeResult} into
545
583
  * a {@link Worksheet} — the rating audit trail.
546
584
  *
547
585
  * @param definition - The authored quantitative definition
@@ -551,16 +589,16 @@ function worksheetSteps(definition, result, groups) {
551
589
  *
552
590
  * @example
553
591
  * ```ts
554
- * import { createQuantitativeReasoner, createReason, factorGroup, quantitativeDefinition, staticFactor } from '@orkestrel/reason'
555
- * import { resultsWorksheet } from '@orkestrel/rater'
592
+ * import { createFactorGroup, createQuantitativeDefinition, createQuantitativeReasoner, createReason, createStaticFactor } from '@orkestrel/reason'
593
+ * import { buildWorksheet } from '@orkestrel/rater'
556
594
  *
557
- * const definition = quantitativeDefinition('base', 'Base', [factorGroup('g', 'sum', [staticFactor('flat', 100)])])
595
+ * const definition = createQuantitativeDefinition('base', 'Base', [createFactorGroup('g', 'sum', [createStaticFactor('flat', 100)])])
558
596
  * const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, definition)
559
- * if (result.reasoning === 'quantitative') resultsWorksheet(definition, result) // the full audit trail
597
+ * if (result.reasoning === 'quantitative') buildWorksheet(definition, result) // the full audit trail
560
598
  * ```
561
599
  */
562
- function resultsWorksheet(definition, result, labels) {
563
- const groups = definition.groups.map((group) => worksheetGroup(group, result.groups, labels));
600
+ function buildWorksheet(definition, result, labels) {
601
+ const groups = definition.groups.map((group) => buildWorksheetGroup(group, result.groups, labels));
564
602
  return {
565
603
  id: definition.id,
566
604
  name: definition.name,
@@ -568,14 +606,14 @@ function resultsWorksheet(definition, result, labels) {
568
606
  ...definition.precision === void 0 ? {} : { precision: definition.precision },
569
607
  value: result.value,
570
608
  groups,
571
- steps: worksheetSteps(definition, result, groups),
609
+ steps: buildWorksheetSteps(definition, result, groups),
572
610
  trace: result.trace,
573
611
  errors: result.errors,
574
612
  success: result.success
575
613
  };
576
614
  }
577
615
  /**
578
- * Build a rated {@link LineResult} from a line's evaluated
616
+ * Builds a rated {@link LineResult} from a line's evaluated
579
617
  * {@link QuantitativeResult}.
580
618
  *
581
619
  * @param definition - The authored line definition
@@ -585,38 +623,37 @@ function resultsWorksheet(definition, result, labels) {
585
623
  *
586
624
  * @example
587
625
  * ```ts
588
- * import { createQuantitativeReasoner, createReason, quantitativeDefinition } from '@orkestrel/reason'
589
- * import { lineDefinition, ratedLine } from '@orkestrel/rater'
626
+ * import { createQuantitativeDefinition, createQuantitativeReasoner, createReason } from '@orkestrel/reason'
627
+ * import { buildLineDefinition, buildLineResult } from '@orkestrel/rater'
590
628
  *
591
- * const line = lineDefinition('base', 'Base', quantitativeDefinition('base', 'Base', []))
629
+ * const line = buildLineDefinition('base', 'Base', createQuantitativeDefinition('base', 'Base', []))
592
630
  * const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, line.rate)
593
- * if (result.reasoning === 'quantitative') ratedLine(line, result) // amount present only when success
631
+ * if (result.reasoning === 'quantitative') buildLineResult(line, result) // amount present only on a successful worksheet
594
632
  * ```
595
633
  */
596
- function ratedLine(definition, result, labels) {
634
+ function buildLineResult(definition, result, labels) {
597
635
  return {
598
636
  id: definition.id,
599
637
  name: definition.name,
600
638
  ...result.success ? { amount: result.value } : {},
601
- worksheet: resultsWorksheet(definition.rate, result, labels),
602
- success: result.success
639
+ worksheet: buildWorksheet(definition.rate, result, labels)
603
640
  };
604
641
  }
605
642
  /**
606
- * Sum defined line amounts.
643
+ * Sums defined line amounts.
607
644
  *
608
645
  * @param lines - The rated lines
609
646
  * @returns The sum of every line's `amount`, or `undefined` when no line has one
610
647
  *
611
648
  * @example
612
649
  * ```ts
613
- * import { createQuantitativeReasoner, createReason, factorGroup, quantitativeDefinition, staticFactor } from '@orkestrel/reason'
614
- * import { lineDefinition, ratedLine, sumAmounts } from '@orkestrel/rater'
650
+ * import { createFactorGroup, createQuantitativeDefinition, createQuantitativeReasoner, createReason, createStaticFactor } from '@orkestrel/reason'
651
+ * import { buildLineDefinition, buildLineResult, sumAmounts } from '@orkestrel/rater'
615
652
  *
616
- * const rate = quantitativeDefinition('base', 'Base', [factorGroup('g', 'sum', [staticFactor('flat', 100)])])
617
- * const line = lineDefinition('base', 'Base', rate)
653
+ * const rate = createQuantitativeDefinition('base', 'Base', [createFactorGroup('g', 'sum', [createStaticFactor('flat', 100)])])
654
+ * const line = buildLineDefinition('base', 'Base', rate)
618
655
  * const result = createReason({ reasoners: [createQuantitativeReasoner()] }).reason({}, rate)
619
- * if (result.reasoning === 'quantitative') sumAmounts([ratedLine(line, result)]) // 100
656
+ * if (result.reasoning === 'quantitative') sumAmounts([buildLineResult(line, result)]) // 100
620
657
  * ```
621
658
  */
622
659
  function sumAmounts(lines) {
@@ -631,17 +668,17 @@ function sumAmounts(lines) {
631
668
  //#endregion
632
669
  //#region src/core/Rater.ts
633
670
  /**
634
- * The rating orchestrator — owns (or receives) the shared quantitative
671
+ * Orchestrates rating — owns (or receives) the shared quantitative
635
672
  * reasoning engine and projects results into the rating domain vocabulary.
636
673
  *
637
674
  * @remarks
638
- * When no `engine` is injected, `Rater` builds and OWNS its own
639
- * quantitative-only engine (`bail: false`) — Rater performs NO evaluation
675
+ * When no `engine` is injected, `Rater` builds and owns its own
676
+ * quantitative-only engine (`bail: false`) — Rater performs no evaluation
640
677
  * arithmetic of its own; it only orchestrates and projects. The
641
- * array-of-lines `rate` overload is declared FIRST (AGENTS §9.2). `destroy()`
642
- * destroys an OWNED engine, then the emitter LAST (AGENTS §13); an INJECTED
643
- * engine is never destroyed. Afterwards every other method throws
644
- * {@link RaterError} `'DESTROYED'`.
678
+ * array-of-lines `rate` overload is declared first so a plain line list
679
+ * resolves to that form. `destroy()` destroys an owned engine, then the
680
+ * emitter last; an injected engine is never destroyed. Afterwards every
681
+ * other method throws {@link RaterError} `'DESTROYED'`.
645
682
  *
646
683
  * @example
647
684
  * ```ts
@@ -683,10 +720,10 @@ var Rater = class {
683
720
  rate(input, subject) {
684
721
  this.#ensureAlive();
685
722
  const lines = this.#normalize(input);
686
- if (!isSubject(subject)) throw new RaterError("MISMATCH", "Subject must be a record");
723
+ if (!isRecord(subject)) throw new RaterError("MISMATCH", "Subject must be a record");
687
724
  const results = lines.map((line) => this.#rateLine(line, subject));
688
725
  const total = (this.#total ?? sumAmounts)(results);
689
- const success = results.every((entry) => entry.success);
726
+ const success = results.every((entry) => entry.worksheet.success);
690
727
  const result = {
691
728
  lines: results,
692
729
  ...total === void 0 ? {} : { total },
@@ -707,7 +744,7 @@ var Rater = class {
707
744
  throw new RaterError("DEFINITION", "Rating input must be an array of line definitions or a rating definition");
708
745
  }
709
746
  #rateLine(line, subject) {
710
- return ratedLine(line, this.#reasonQuantitative(subject, line.rate), this.#labels);
747
+ return buildLineResult(line, this.#reasonQuantitative(subject, line.rate), this.#labels);
711
748
  }
712
749
  #reasonQuantitative(subject, definition) {
713
750
  const result = this.#engine.reason(subject, definition);
@@ -735,12 +772,13 @@ var Rater = class {
735
772
  //#endregion
736
773
  //#region src/core/factories.ts
737
774
  /**
738
- * Create a rating orchestrator.
775
+ * Creates a rating orchestrator over the shared quantitative engine, seeded
776
+ * from {@link RaterOptions} and returning a {@link RaterInterface}.
739
777
  *
740
778
  * @param options - Optional total handler, labels, injected engine, and emitter hooks
741
779
  * @returns A {@link RaterInterface}
742
780
  *
743
- * @example
781
+ * @example Create a rater
744
782
  * ```ts
745
783
  * import { createRater } from '@orkestrel/rater'
746
784
  *
@@ -752,6 +790,6 @@ function createRater(options) {
752
790
  return new Rater(options);
753
791
  }
754
792
  //#endregion
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 };
793
+ export { Rater, RaterError, buildEvidence, buildEvidenceRows, buildLineDefinition, buildLineResult, buildRatingDefinition, buildWorksheet, buildWorksheetFactor, buildWorksheetGroup, buildWorksheetStep, buildWorksheetSteps, createRater, isEvidence, isLineDefinition, isLineResult, isRaterError, isRatingDefinition, isRatingResult, isStage, isStep, isWorksheet, isWorksheetFactor, isWorksheetGroup, sumAmounts };
756
794
 
757
795
  //# sourceMappingURL=index.js.map