@orkestrel/scaffold 0.0.67 → 0.0.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/main.js +67 -44
- package/dist/bin/main.js.map +1 -1
- package/dist/host/agents/templates/brief.md +9 -0
- package/dist/host/claude/agents/orkestrel.md +4 -4
- package/dist/host/claude/rules/names.md +15 -0
- package/dist/host/claude/rules/tests.md +33 -4
- package/dist/host/claude/rules/workspace.md +14 -2
- package/dist/host/dotfiles/prettierignore +3 -0
- package/dist/host/guides/README.md +65 -0
- package/dist/host/guides/abort.md +169 -0
- package/dist/host/guides/agent.md +1509 -0
- package/dist/host/guides/brief.md +1266 -0
- package/dist/host/guides/browser.md +2200 -0
- package/dist/host/guides/budget.md +196 -0
- package/dist/host/guides/codec.md +519 -0
- package/dist/host/guides/console.md +785 -0
- package/dist/host/guides/contract.md +1193 -0
- package/dist/host/guides/csv.md +541 -0
- package/dist/host/guides/database.md +2518 -0
- package/dist/host/guides/emitter.md +233 -0
- package/dist/host/guides/form.md +1791 -0
- package/dist/host/guides/html.md +717 -0
- package/dist/host/guides/indexeddb.md +505 -0
- package/dist/host/guides/interpret.md +1029 -0
- package/dist/host/guides/lsp.md +515 -0
- package/dist/host/guides/markdown.md +964 -0
- package/dist/host/guides/mcp.md +5554 -0
- package/dist/host/guides/middleware.md +927 -0
- package/dist/host/guides/msg.md +440 -0
- package/dist/host/guides/ndjson.md +120 -0
- package/dist/host/guides/ollama.md +380 -0
- package/dist/host/guides/pool.md +280 -0
- package/dist/host/guides/probe.md +1210 -0
- package/dist/host/guides/process.md +1620 -0
- package/dist/host/guides/program.md +1110 -0
- package/dist/host/guides/qualifier.md +854 -0
- package/dist/host/guides/queue.md +370 -0
- package/dist/host/guides/rater.md +330 -0
- package/dist/host/guides/reason.md +1122 -0
- package/dist/host/guides/relation.md +373 -0
- package/dist/host/guides/router.md +753 -0
- package/dist/host/guides/scaffold.md +192 -31
- package/dist/host/guides/sea.md +383 -0
- package/dist/host/guides/server.md +752 -0
- package/dist/host/guides/sqlite.md +330 -0
- package/dist/host/guides/sse.md +187 -0
- package/dist/host/guides/supervisor.md +4890 -0
- package/dist/host/guides/table.md +1556 -0
- package/dist/host/guides/template.md +280 -0
- package/dist/host/guides/terminal.md +1145 -0
- package/dist/host/guides/test.md +2969 -0
- package/dist/host/guides/timeout.md +252 -0
- package/dist/host/guides/tool.md +311 -0
- package/dist/host/guides/toolbox.md +1038 -0
- package/dist/host/guides/websocket.md +282 -0
- package/dist/host/guides/worker.md +615 -0
- package/dist/host/guides/workflow.md +1507 -0
- package/dist/host/guides/workspace.md +595 -0
- package/dist/host/manifest.json +1218 -10
- package/dist/host/tests/policy.test.ts +279 -2
- package/dist/host/tests/setupPolicy.ts +437 -6
- package/dist/src/core/index.cjs +38 -16
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +33 -9
- package/dist/src/core/index.d.ts +33 -9
- package/dist/src/core/index.js +37 -17
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +1750 -1567
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +106 -24
- package/dist/src/server/index.d.ts +106 -24
- package/dist/src/server/index.js +1751 -1570
- package/dist/src/server/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
# Rater
|
|
2
|
+
|
|
3
|
+
> A typed quantitative rating layer over `@orkestrel/reason`'s shared engine: authored
|
|
4
|
+
> lines, each a plain reason `QuantitativeDefinition` joined to display metadata, rated
|
|
5
|
+
> against one subject to produce a `LineResult` per line — an `amount` and its
|
|
6
|
+
> `Worksheet` audit trail — and one `RatingResult` carrying every line's outcome and a
|
|
7
|
+
> derived `total`.
|
|
8
|
+
|
|
9
|
+
A subject is a plain data record, and the caller decides which lines to rate for it:
|
|
10
|
+
`Rater` rates the lines it is handed, reports what each one resolved to, and performs no
|
|
11
|
+
evaluation arithmetic of its own. Rating never mutates its inputs, so every result is a
|
|
12
|
+
fresh object. A rater either receives an injected `ReasonInterface`, which it never
|
|
13
|
+
destroys, or builds and owns its own quantitative-only engine (`bail: false`) and
|
|
14
|
+
destroys that engine in `destroy()`. An injected engine must be able to dispatch a
|
|
15
|
+
quantitative definition: one it cannot dispatch surfaces the engine's own error, which
|
|
16
|
+
this package never wraps. Every `rate` call fires once through the rater's typed
|
|
17
|
+
`emitter`. Source: [`src/core`](../src/core). Surfaced through the `@src/core` barrel.
|
|
18
|
+
|
|
19
|
+
## Surface
|
|
20
|
+
|
|
21
|
+
Create a rater, rate one subject against a list of lines (or a full rating
|
|
22
|
+
definition), read the derived total:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { buildLineDefinition, createRater } from '@orkestrel/rater'
|
|
26
|
+
import {
|
|
27
|
+
createFactorGroup,
|
|
28
|
+
createQuantitativeDefinition,
|
|
29
|
+
createStaticFactor,
|
|
30
|
+
} from '@orkestrel/reason'
|
|
31
|
+
|
|
32
|
+
const rater = createRater()
|
|
33
|
+
|
|
34
|
+
const base = buildLineDefinition(
|
|
35
|
+
'base',
|
|
36
|
+
'Base Amount',
|
|
37
|
+
createQuantitativeDefinition('base', 'Base', [
|
|
38
|
+
createFactorGroup('amount', 'sum', [createStaticFactor('flat', 100)]),
|
|
39
|
+
]),
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
const result = rater.rate([base], { id: 'subject-1' })
|
|
43
|
+
result.lines[0]?.amount // 100
|
|
44
|
+
result.total // 100
|
|
45
|
+
|
|
46
|
+
rater.emitter.on('rate', (subject, rated) => rated.success)
|
|
47
|
+
|
|
48
|
+
rater.destroy()
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`rate` dispatches by input shape — the array-of-lines overload is declared first so a
|
|
52
|
+
plain line list resolves to that form; a `RatingDefinition` resolves the same way
|
|
53
|
+
through its own `lines`. Each overload rates exactly one subject — there is no batch
|
|
54
|
+
overload, and the subject must be a plain record or `rate` throws `RaterError`
|
|
55
|
+
`'MISMATCH'`; an input that is neither an array of lines nor a `RatingDefinition`
|
|
56
|
+
throws `RaterError` `'DEFINITION'`. A line that fails to resolve (a missing lookup
|
|
57
|
+
entry, a failed required factor) is a rating failure reported on its own `LineResult`
|
|
58
|
+
(`worksheet.success: false`, no `amount`, a populated `worksheet.errors`) — the caller decides
|
|
59
|
+
what to do with a failed line, and `Rater` reports exactly what each line resolved
|
|
60
|
+
to. `total` is derived from every line's `amount` by a `TotalHandler` (default
|
|
61
|
+
`sumAmounts`, overridable through `RaterOptions.total`). A `LineResult` carries an
|
|
62
|
+
`amount` only when its `worksheet.success` is `true`, and a `RatingResult`'s `success`
|
|
63
|
+
is `true` only when every line's `worksheet.success` is `true`.
|
|
64
|
+
|
|
65
|
+
### Types
|
|
66
|
+
|
|
67
|
+
A `Shape` cell holds an interface's data members as bare names in braces, `?` marking an
|
|
68
|
+
optional member and `plus` introducing its call-signature members, and a type alias's own
|
|
69
|
+
type literal with a union's arms escaped as `\|`.
|
|
70
|
+
|
|
71
|
+
| Type | Kind | Shape | Summary |
|
|
72
|
+
| ------------------ | --------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
|
73
|
+
| `Stage` | type | `'factor' \| 'group' \| 'total'` | Names a worksheet derivation step stage. |
|
|
74
|
+
| `RaterErrorCode` | type | `'DEFINITION' \| 'MISMATCH' \| 'DESTROYED'` | Names a coded `RaterError` programmer-error code. |
|
|
75
|
+
| `TotalHandler` | type | `(lines: readonly LineResult[]) => number \| undefined` | Represents a pure total port over resolved lines. |
|
|
76
|
+
| `LineDefinition` | interface | `{ id, name, description?, rate, metadata? }` | Represents one rateable line — a quantitative definition joined to display metadata. |
|
|
77
|
+
| `RatingDefinition` | interface | `{ id, name, description?, lines, metadata? }` | Represents a pure authored rating — a named, ordered set of lines. |
|
|
78
|
+
| `Evidence` | interface | `{ field?, label?, comparison?, expected?, actual?, met? }` | Represents a checked-evidence row rendered into a display-neutral sentence. |
|
|
79
|
+
| `WorksheetFactor` | interface | `{ id, name?, description?, applied, value?, evidence }` | Represents a resolved quantitative factor, joined to its authored metadata. |
|
|
80
|
+
| `WorksheetGroup` | interface | `{ id, name?, description?, applied, value, factors }` | Represents a resolved quantitative group, joined to its authored metadata. |
|
|
81
|
+
| `Step` | interface | `{ stage, id?, name?, value, expression? }` | Represents a display-neutral worksheet derivation step. |
|
|
82
|
+
| `Worksheet` | interface | `{ id, name, aggregation, precision?, value, groups, steps, trace, errors, success }` | Represents a quantitative definition joined to its result — the rating audit trail. |
|
|
83
|
+
| `LineResult` | interface | `{ id, name, amount?, worksheet }` | Represents one line's rating outcome. |
|
|
84
|
+
| `RatingResult` | interface | `{ lines, total?, success }` | Represents a rated outcome across every line of one `rate` call. |
|
|
85
|
+
| `RaterEventMap` | type | `{ rate }` | Represents the push observation surface of a `RaterInterface`. |
|
|
86
|
+
| `RaterOptions` | interface | `{ on?, error?, engine?, total?, labels? }` | Configures `createRater` and the `Rater` constructor. |
|
|
87
|
+
| `RaterInterface` | interface | `{ emitter } plus rate, destroy` | Represents the rating orchestrator over the shared quantitative reasoning engine. |
|
|
88
|
+
|
|
89
|
+
`RaterInterface`'s `emitter` is a `readonly` data member and stays in this table's
|
|
90
|
+
`Shape` cell; the interface's call-signature members are documented under
|
|
91
|
+
[Methods](#methods).
|
|
92
|
+
|
|
93
|
+
### Errors
|
|
94
|
+
|
|
95
|
+
Every `RaterError` carries a `code` — `'DEFINITION'`, `'MISMATCH'`, or `'DESTROYED'` —
|
|
96
|
+
and an optional `context` record of structured detail beside its message.
|
|
97
|
+
|
|
98
|
+
| API | Kind | Summary |
|
|
99
|
+
| -------------- | -------- | --------------------------------------------------------------- |
|
|
100
|
+
| `RaterError` | class | Represents a coded programmer error thrown by the rating layer. |
|
|
101
|
+
| `isRaterError` | function | Narrows a caught value to a `RaterError`. |
|
|
102
|
+
|
|
103
|
+
The `isRaterError` guard narrows a caught value, so a handler reads the `code` member
|
|
104
|
+
off it:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import { isRaterError, RaterError } from '@orkestrel/rater'
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
throw new RaterError('DESTROYED', 'Rater has been destroyed')
|
|
111
|
+
} catch (error) {
|
|
112
|
+
if (isRaterError(error)) error.code // 'DESTROYED'
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Validators
|
|
117
|
+
|
|
118
|
+
Total guards composed from `@orkestrel/contract` combinators — adversarial input
|
|
119
|
+
(junk, cycles, hostile prototypes) returns `false`, never throws. The guards take their
|
|
120
|
+
posture from who produces the value. Authored definitions supplied to this package use
|
|
121
|
+
exact `recordOf` guards because this package owns that input shape; extra keys fail.
|
|
122
|
+
Results returned by a borrowed `RaterInterface` use open `objectOf` guards because
|
|
123
|
+
another valid implementation may return class instances, inherited members,
|
|
124
|
+
or extra members. `isRatingResult` is the borrowed-engine boundary: it and its nested
|
|
125
|
+
result guards reject arrays and check every published typed member without narrowing
|
|
126
|
+
plain numbers, strings, or unknown values.
|
|
127
|
+
|
|
128
|
+
In a guard table a `Shape` cell holds the type the guard narrows to.
|
|
129
|
+
|
|
130
|
+
| API | Kind | Shape | Summary |
|
|
131
|
+
| -------------------- | -------- | ------------------ | ---------------------------------------------------------------------- |
|
|
132
|
+
| `isStage` | const | `Stage` | Determines whether a value is a `Stage` literal. |
|
|
133
|
+
| `isLineDefinition` | function | `LineDefinition` | Determines whether a value is an exact `LineDefinition` record. |
|
|
134
|
+
| `isRatingDefinition` | function | `RatingDefinition` | Determines whether a value is an exact `RatingDefinition` record. |
|
|
135
|
+
| `isEvidence` | function | `Evidence` | Determines whether a value is an open result-side `Evidence` object. |
|
|
136
|
+
| `isWorksheetFactor` | function | `WorksheetFactor` | Determines whether a value is an open `WorksheetFactor` result object. |
|
|
137
|
+
| `isWorksheetGroup` | function | `WorksheetGroup` | Determines whether a value is an open `WorksheetGroup` result object. |
|
|
138
|
+
| `isStep` | function | `Step` | Determines whether a value is an open `Step` result object. |
|
|
139
|
+
| `isWorksheet` | function | `Worksheet` | Determines whether a value is an open `Worksheet` result object. |
|
|
140
|
+
| `isLineResult` | function | `LineResult` | Determines whether a value is an open `LineResult` object. |
|
|
141
|
+
| `isRatingResult` | function | `RatingResult` | Determines whether a value is an open `RatingResult` object. |
|
|
142
|
+
|
|
143
|
+
Each guard answers `true` for a value of its own shape:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import { isLineDefinition, isRatingDefinition, isStage } from '@orkestrel/rater'
|
|
147
|
+
import { createQuantitativeDefinition } from '@orkestrel/reason'
|
|
148
|
+
|
|
149
|
+
isStage('group') // true
|
|
150
|
+
isLineDefinition({
|
|
151
|
+
id: 'base',
|
|
152
|
+
name: 'Base Amount',
|
|
153
|
+
rate: createQuantitativeDefinition('base', 'Base', []),
|
|
154
|
+
}) // true
|
|
155
|
+
isRatingDefinition({ id: 'r1', name: 'Rating', lines: [] }) // true
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Helpers
|
|
159
|
+
|
|
160
|
+
Pure, exported utility functions — the definition builders, the evidence construction,
|
|
161
|
+
and the worksheet-joining behind `Rater`'s `rate` projection.
|
|
162
|
+
|
|
163
|
+
| API | Kind | Summary |
|
|
164
|
+
| ----------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
165
|
+
| `buildLineDefinition` | function | Builds a fresh `LineDefinition` from a line id, a display name, and the line's quantitative rating definition, with `overrides` merged over those defaults. |
|
|
166
|
+
| `buildRatingDefinition` | function | Builds a fresh `RatingDefinition` from a rating id, a display name, and the rating's ordered lines, with `overrides` merged over those defaults. |
|
|
167
|
+
| `buildEvidence` | function | Builds an `Evidence` row from an evaluated `Check`. |
|
|
168
|
+
| `buildEvidenceRows` | function | Builds one evidence row per authored check of a quantitative factor, joined to that check's evaluated result. |
|
|
169
|
+
| `buildWorksheetFactor` | function | Joins one authored quantitative factor to its evaluated `FactorResult`. |
|
|
170
|
+
| `buildWorksheetGroup` | function | Joins one authored quantitative group to its evaluated `GroupResult`. |
|
|
171
|
+
| `buildWorksheetStep` | function | Builds one display-neutral `Step` row. |
|
|
172
|
+
| `buildWorksheetSteps` | function | Builds the ordered `Step` rows for a resolved `Worksheet`. |
|
|
173
|
+
| `buildWorksheet` | function | Joins a `QuantitativeDefinition` and its `QuantitativeResult` into a `Worksheet` — the rating audit trail. |
|
|
174
|
+
| `buildLineResult` | function | Builds a rated `LineResult` from a line's evaluated `QuantitativeResult`. |
|
|
175
|
+
| `sumAmounts` | function | Sums defined line amounts. |
|
|
176
|
+
|
|
177
|
+
Each definition builder returns a fresh object and omits an absent optional key
|
|
178
|
+
entirely:
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
import { buildLineDefinition, buildRatingDefinition } from '@orkestrel/rater'
|
|
182
|
+
import { createQuantitativeDefinition } from '@orkestrel/reason'
|
|
183
|
+
|
|
184
|
+
const base = buildLineDefinition(
|
|
185
|
+
'base',
|
|
186
|
+
'Base Amount',
|
|
187
|
+
createQuantitativeDefinition('base', 'Base', []),
|
|
188
|
+
)
|
|
189
|
+
buildRatingDefinition('r1', 'Rating', [base])
|
|
190
|
+
buildRatingDefinition('r1', 'Rating', [base], { description: 'A rating' }) // overrides merged over the defaults
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Evidence construction — a `Check` (and its evaluated result) rendered into a
|
|
194
|
+
display-neutral `Evidence` row; `labels` (keyed by dot-joined field) override the resolved
|
|
195
|
+
`label`:
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
import { buildEvidence, buildEvidenceRows } from '@orkestrel/rater'
|
|
199
|
+
import { createCheck } from '@orkestrel/reason'
|
|
200
|
+
|
|
201
|
+
const evaluated = createCheck('age', 'above', 18)
|
|
202
|
+
buildEvidence(evaluated, 25, true) // { field: 'age', comparison: 'above', expected: 18, actual: 25, met: true }
|
|
203
|
+
buildEvidence(evaluated, 25, true, { age: 'Age' }) // labels override → adds { label: 'Age' }
|
|
204
|
+
buildEvidenceRows([evaluated], [{ field: 'age', met: true, actual: 25 }])
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Worksheet joining and line assembly — one authored quantitative definition and its
|
|
208
|
+
evaluated result, walked into the display-neutral `Worksheet` audit trail and then a
|
|
209
|
+
rated `LineResult`:
|
|
210
|
+
|
|
211
|
+
```ts
|
|
212
|
+
import {
|
|
213
|
+
buildLineDefinition,
|
|
214
|
+
buildLineResult,
|
|
215
|
+
buildWorksheet,
|
|
216
|
+
buildWorksheetFactor,
|
|
217
|
+
buildWorksheetGroup,
|
|
218
|
+
buildWorksheetStep,
|
|
219
|
+
buildWorksheetSteps,
|
|
220
|
+
sumAmounts,
|
|
221
|
+
} from '@orkestrel/rater'
|
|
222
|
+
import {
|
|
223
|
+
createFactorGroup,
|
|
224
|
+
createFieldFactor,
|
|
225
|
+
createQuantitativeDefinition,
|
|
226
|
+
createQuantitativeReasoner,
|
|
227
|
+
createReason,
|
|
228
|
+
} from '@orkestrel/reason'
|
|
229
|
+
|
|
230
|
+
const definition = createQuantitativeDefinition('risk', 'Risk', [
|
|
231
|
+
createFactorGroup('drivers', 'sum', [createFieldFactor('age', 'age')]),
|
|
232
|
+
])
|
|
233
|
+
const engine = createReason({ reasoners: [createQuantitativeReasoner()] })
|
|
234
|
+
const result = engine.reason({ age: 25 }, definition)
|
|
235
|
+
|
|
236
|
+
if (result.reasoning === 'quantitative') {
|
|
237
|
+
const group = definition.groups[0]
|
|
238
|
+
const groupResult = result.groups[0]
|
|
239
|
+
if (group !== undefined && groupResult !== undefined) {
|
|
240
|
+
const factor = group.factors[0]
|
|
241
|
+
if (factor !== undefined) buildWorksheetFactor(factor, groupResult.factors) // one factor joined to its result
|
|
242
|
+
buildWorksheetGroup(group, result.groups) // one group joined to its result
|
|
243
|
+
}
|
|
244
|
+
buildWorksheetStep('total', definition.id, definition.name, result.value, `sum = ${result.value}`)
|
|
245
|
+
buildWorksheetSteps(
|
|
246
|
+
definition,
|
|
247
|
+
result,
|
|
248
|
+
definition.groups.map((entry) => buildWorksheetGroup(entry, result.groups)),
|
|
249
|
+
) // the full ordered step list: factors, groups, then the total
|
|
250
|
+
buildWorksheet(definition, result) // the whole worksheet — groups, steps, trace, errors, success
|
|
251
|
+
|
|
252
|
+
const line = buildLineDefinition('risk', 'Risk', definition)
|
|
253
|
+
buildLineResult(line, result) // the line's rated LineResult — amount present only on a successful worksheet
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
sumAmounts([]) // undefined — no line carries an amount
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Factories
|
|
260
|
+
|
|
261
|
+
| API | Kind | Summary |
|
|
262
|
+
| ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
263
|
+
| `createRater` | function | Creates a rating orchestrator over the shared quantitative engine, seeded from `RaterOptions` and returning a `RaterInterface`. |
|
|
264
|
+
|
|
265
|
+
`createRater` returns a live entity that owns an engine unless one is injected, so every
|
|
266
|
+
rater is destroyed when its work is done.
|
|
267
|
+
|
|
268
|
+
#### Create a rater
|
|
269
|
+
|
|
270
|
+
The demonstration builds a rater over its own engine and destroys that rater:
|
|
271
|
+
|
|
272
|
+
```ts
|
|
273
|
+
import { createRater } from '@orkestrel/rater'
|
|
274
|
+
|
|
275
|
+
const rater = createRater()
|
|
276
|
+
rater.destroy()
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Classes
|
|
280
|
+
|
|
281
|
+
| API | Kind | Summary |
|
|
282
|
+
| ------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
|
283
|
+
| `Rater` | class | Orchestrates rating — owns (or receives) the shared quantitative reasoning engine and projects results into the rating domain vocabulary. |
|
|
284
|
+
|
|
285
|
+
## Methods
|
|
286
|
+
|
|
287
|
+
The public methods of `RaterInterface` — one table, keyed by its backticked name, every
|
|
288
|
+
call-signature member listed, and the `readonly` data member `emitter` left off it.
|
|
289
|
+
`Rater` exposes exactly its interface's methods, so this doubles as the per-instance
|
|
290
|
+
method surface.
|
|
291
|
+
|
|
292
|
+
#### `RaterInterface`
|
|
293
|
+
|
|
294
|
+
The array-of-lines overload of `rate` is declared first so a plain line list resolves
|
|
295
|
+
to that form; each overload rates exactly one subject. `destroy()` is idempotent — it
|
|
296
|
+
destroys an owned engine (never an injected one), then the emitter last. Afterwards
|
|
297
|
+
every other method throws `RaterError` `'DESTROYED'`.
|
|
298
|
+
|
|
299
|
+
| Method | Returns | Summary |
|
|
300
|
+
| --------- | -------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
301
|
+
| `rate` | `RatingResult` | Rates an array of lines, or a `RatingDefinition`, against one subject over the shared quantitative engine. |
|
|
302
|
+
| `destroy` | `void` | Destroys an owned engine and then the emitter, and does nothing on a later call. |
|
|
303
|
+
|
|
304
|
+
The array-of-lines and rating-definition forms of `rate` each take one subject and
|
|
305
|
+
return equal results for the same lines:
|
|
306
|
+
|
|
307
|
+
```ts
|
|
308
|
+
import { buildLineDefinition, createRater } from '@orkestrel/rater'
|
|
309
|
+
import { createQuantitativeDefinition } from '@orkestrel/reason'
|
|
310
|
+
|
|
311
|
+
const rater = createRater()
|
|
312
|
+
const base = buildLineDefinition(
|
|
313
|
+
'base',
|
|
314
|
+
'Base Amount',
|
|
315
|
+
createQuantitativeDefinition('base', 'Base', []),
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
rater.rate([base], { id: 'subject-1' }) // the array-of-lines overload
|
|
319
|
+
rater.rate({ id: 'r1', name: 'Rating', lines: [base] }, { id: 'subject-1' }) // the RatingDefinition overload
|
|
320
|
+
|
|
321
|
+
rater.destroy()
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Tests
|
|
325
|
+
|
|
326
|
+
- [`tests/guides.test.ts`](../tests/guides.test.ts) — the `## Surface` ↔ `src/core` bijection (value and type exports), the `RaterInterface` ↔ `Rater` method bijection, and the equality gate: every `Summary` cell against its declaration's description paragraph, the titled `Create a rater` fence against the `@example` block of that title (pinned so the titled pair cannot be retired silently), and the README pitch against this guide's tagline. It also runs the flagship fences and asserts the values their comments claim.
|
|
327
|
+
- [`tests/src/core/Rater.test.ts`](../tests/src/core/Rater.test.ts) — line selection (only the supplied lines are evaluated, exactly once each, and an omitted line never is), the result shape (`LineResult` carries an `amount` only on a successful worksheet; `RatingResult` carries a `total` only when one is defined), quantitative-only dispatch against an injected engine that also carries a logical reasoner, rating failures (a missing lookup key with no fallback, a failed required check), totals (a custom `TotalHandler`, an all-failed rating, an empty line list), immutability against frozen inputs, engine ownership and `destroy` (idempotence, `'DESTROYED'` afterwards, an injected engine surviving), the array-of-lines and rating-definition `rate` overloads agreeing, the `'DEFINITION'` and `'MISMATCH'` errors, the `rate` event firing once per call, `labels` threading into a resolved `Evidence.label`, the defensive fallback for a non-quantitative or malformed engine result, and the finite-arithmetic guarantees.
|
|
328
|
+
- [`tests/src/core/factories.test.ts`](../tests/src/core/factories.test.ts) — `createRater` returns a rater usable immediately, threads an injected engine, a total override, labels, and an `on.rate` hook together, and tears down an owned engine on `destroy` while leaving an injected one working.
|
|
329
|
+
- [`tests/src/core/helpers.test.ts`](../tests/src/core/helpers.test.ts) — evidence construction and label application, the factor and group joins with their defaults for an absent result, the step ordering (applied factors, then the group, then the total), the full worksheet join passing `trace`, `errors`, and `success` through, `buildLineResult` carrying an `amount` only on success, `sumAmounts` over defined, negative-zero, overflowing, `NaN`, and opposing-infinity amounts, the definition builders' override merge and optional-key omission, and the round trip from each builder back through its guard.
|
|
330
|
+
- [`tests/src/core/validators.test.ts`](../tests/src/core/validators.test.ts) — each guard against its accepted shapes, its wrong-typed and missing members, adversarial input (junk, cycles, hostile prototypes, revoked proxies) answered without throwing, the exact `recordOf` posture rejecting an extra key on an authored definition, and the open `objectOf` posture admitting unknown members, prototypes, and class instances on a borrowed result.
|