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