@orkestrel/reason 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -48,7 +48,7 @@ var DEFAULT_PRIORITY = 0;
48
48
  * inferential chaining.
49
49
  *
50
50
  * @remarks
51
- * Fixed — unlike {@link DEFAULT_PRECISION} it is NOT overridable per
51
+ * Fixed — unlike {@link DEFAULT_PRECISION} it is not overridable per
52
52
  * definition, so confidence products stay comparable across derivations.
53
53
  */
54
54
  var CONFIDENCE_PRECISION = 4;
@@ -94,8 +94,8 @@ var DEFINITION_BUILDER_BRAND = Symbol("reasons.definitionBuilder");
94
94
  *
95
95
  * @remarks
96
96
  * Only `isSubjectBuilder` (`validators.ts`) reads this key, through `Reflect.get`.
97
- * Distinct from {@link DEFINITION_BUILDER_BRAND}, so the two entities can never
98
- * match each other's guard.
97
+ * Distinct from {@link DEFINITION_BUILDER_BRAND}, so neither entity can ever
98
+ * match the other's guard.
99
99
  */
100
100
  var SUBJECT_BUILDER_BRAND = Symbol("reasons.subjectBuilder");
101
101
  //#endregion
@@ -152,7 +152,7 @@ function isReasonError(value) {
152
152
  * Determines whether a value is a {@link Reasoning} literal.
153
153
  *
154
154
  * @param value - The value to test
155
- * @returns True if `value` is one of the four reasoning strategies; false otherwise
155
+ * @returns True if `value` names a reasoning strategy; false otherwise
156
156
  *
157
157
  * @example
158
158
  * ```ts
@@ -197,7 +197,7 @@ var isMathOperation = (0, _orkestrel_contract.literalOf)("add", "subtract", "mul
197
197
  * Determines whether a value is an {@link Aggregation} literal.
198
198
  *
199
199
  * @param value - The value to test
200
- * @returns True if `value` is one of the five aggregations; false otherwise
200
+ * @returns True if `value` names an aggregation; false otherwise
201
201
  *
202
202
  * @example
203
203
  * ```ts
@@ -212,7 +212,7 @@ var isAggregation = (0, _orkestrel_contract.literalOf)("sum", "product", "averag
212
212
  * Determines whether a value is a {@link Comparison} literal.
213
213
  *
214
214
  * @param value - The value to test
215
- * @returns True if `value` is one of the ten comparison operators; false otherwise
215
+ * @returns True if `value` names a comparison operator; false otherwise
216
216
  *
217
217
  * @example
218
218
  * ```ts
@@ -227,7 +227,7 @@ var isComparison = (0, _orkestrel_contract.literalOf)("equals", "not", "above",
227
227
  * Determines whether a value is a {@link LogicalOperator} literal.
228
228
  *
229
229
  * @param value - The value to test
230
- * @returns True if `value` is one of the five logical connectives; false otherwise
230
+ * @returns True if `value` names a logical connective; false otherwise
231
231
  *
232
232
  * @example
233
233
  * ```ts
@@ -249,7 +249,7 @@ var isLogicalOperator = (0, _orkestrel_contract.literalOf)("and", "or", "not", "
249
249
  * ```ts
250
250
  * import { isFieldPath } from '@src/core'
251
251
  *
252
- * isFieldPath('age') // true — ONE key (never dot-split)
252
+ * isFieldPath('age') // true — a single key (never dot-split)
253
253
  * isFieldPath(['address', 'city']) // true — descends
254
254
  * isFieldPath(42) // false
255
255
  * ```
@@ -276,8 +276,8 @@ var isNumberRecord = (0, _orkestrel_contract.whereOf)(_orkestrel_contract.isReco
276
276
  * predicate.
277
277
  *
278
278
  * @remarks
279
- * `value` may be ANYTHING (including `null` / `undefined`) but the key must be
280
- * PRESENT — exact-record semantics reject a check that lost its `value` key.
279
+ * `value` may be anything (including `null` / `undefined`) but the key must be
280
+ * present — exact-record semantics reject a check that lost its `value` key.
281
281
  *
282
282
  * @param value - The value to test
283
283
  * @returns True if `value` is a well-formed check; false otherwise
@@ -361,8 +361,8 @@ function isFactorRange(value) {
361
361
  }, ["bounds"])(value);
362
362
  }
363
363
  /**
364
- * Determines whether a value is a {@link Source} — any of the four factor
365
- * sources, discriminated by `origin`.
364
+ * Determines whether a value is a {@link Source} — a static, field, lookup, or
365
+ * range factor source, discriminated by `origin`.
366
366
  *
367
367
  * @param value - The value to test
368
368
  * @returns True if `value` is a well-formed static / field / lookup / range source; false otherwise
@@ -473,9 +473,9 @@ function isFactorGroup(value) {
473
473
  * tree of atoms and compounds, discriminated by `form`.
474
474
  *
475
475
  * @remarks
476
- * Recursive through `lazyOf` — recursion is STACK-BOUNDED, not
476
+ * Recursive through `lazyOf` — recursion is bounded by the stack, not
477
477
  * unbounded: nesting beyond the engine's stack budget (roughly 1000 levels)
478
- * and cyclic input are CONTAINED as `false`, never a throw. Input past that
478
+ * and cyclic input are contained as `false`, never a throw. Input past that
479
479
  * bound is rejected, not validated.
480
480
  *
481
481
  * @param value - The value to test
@@ -535,9 +535,9 @@ function isRule(value) {
535
535
  * `form`.
536
536
  *
537
537
  * @remarks
538
- * Recursive through `lazyOf` — recursion is STACK-BOUNDED, not
538
+ * Recursive through `lazyOf` — recursion is bounded by the stack, not
539
539
  * unbounded: nesting beyond the engine's stack budget (roughly 1000 levels)
540
- * and cyclic input are CONTAINED as `false`, never a throw. Input past that
540
+ * and cyclic input are contained as `false`, never a throw. Input past that
541
541
  * bound is rejected, not validated.
542
542
  *
543
543
  * @param value - The value to test
@@ -756,8 +756,8 @@ function isInferentialDefinition(value) {
756
756
  }, ["description", "depth"])(value);
757
757
  }
758
758
  /**
759
- * Determines whether a value is a {@link Definition} — any of the four
760
- * definition shapes, discriminated by `reasoning`.
759
+ * Determines whether a value is a {@link Definition} — a quantitative, logical,
760
+ * symbolic, or inferential definition shape, discriminated by `reasoning`.
761
761
  *
762
762
  * @param value - The value to test
763
763
  * @returns True if `value` is a well-formed definition of any reasoning; false otherwise
@@ -865,6 +865,12 @@ function isResultFact(value) {
865
865
  /**
866
866
  * Determines whether a value is a {@link CheckResult}.
867
867
  *
868
+ * @remarks
869
+ * `actual` must be present and may hold anything, including `undefined` — the
870
+ * guard reads its presence, never its value. A result whose `actual` is
871
+ * `undefined` therefore does not survive a JSON round trip: `JSON.stringify`
872
+ * drops the key, and the parsed record is refused here.
873
+ *
868
874
  * @param value - The value to test
869
875
  * @returns True if every published check-result member is valid; false otherwise
870
876
  *
@@ -886,6 +892,10 @@ function isCheckResult(value) {
886
892
  /**
887
893
  * Determines whether a value is a {@link FactorResult}.
888
894
  *
895
+ * @remarks
896
+ * The optional `raw` and `checks` members are absent-or-valid: an absent key
897
+ * passes, a present key is checked in full.
898
+ *
889
899
  * @param value - The value to test
890
900
  * @returns True if every published factor-result member is valid; false otherwise
891
901
  *
@@ -1057,7 +1067,7 @@ function isLogicalResult(value) {
1057
1067
  * Determines whether a value is a {@link SymbolicResult}.
1058
1068
  *
1059
1069
  * @remarks
1060
- * `solutions` is checked across its OWN string-named members, enumerable or
1070
+ * `solutions` is checked across its own string-named members, enumerable or
1061
1071
  * not. Inherited members are deliberately unread: they belong to the
1062
1072
  * accepted-prototype property, not to the record this guard certifies.
1063
1073
  *
@@ -1135,13 +1145,13 @@ function isReasonValidationResult(value) {
1135
1145
  })(value);
1136
1146
  }
1137
1147
  /**
1138
- * Determines whether a value is a `DefinitionBuilder` ENTITY — the brand-guarded
1148
+ * Determines whether a value is a `DefinitionBuilder` entity — the brand-guarded
1139
1149
  * stateful workspace, not the plain {@link Definition} data union.
1140
1150
  *
1141
1151
  * @remarks
1142
1152
  * A `unique symbol` brand check (`Reflect.get`): a plain subject
1143
1153
  * is an open record whose values may legally be functions, so a
1144
- * method-presence check (`typeof value.build === 'function'`) is FORGEABLE —
1154
+ * method-presence check (`typeof value.build === 'function'`) is forgeable —
1145
1155
  * this guard is not. A module-owned `unique symbol` cannot be produced by
1146
1156
  * `JSON.parse` or written by any consumer that does not import
1147
1157
  * `DEFINITION_BUILDER_BRAND`, so plain data can never forge it. Total: a
@@ -1165,12 +1175,12 @@ function isDefinitionBuilder(value) {
1165
1175
  return (0, _orkestrel_contract.isObject)(value) && Reflect.get(value, DEFINITION_BUILDER_BRAND) === true;
1166
1176
  }
1167
1177
  /**
1168
- * Determines whether a value is a `SubjectBuilder` ENTITY — the brand-guarded
1178
+ * Determines whether a value is a `SubjectBuilder` entity — the brand-guarded
1169
1179
  * stateful workspace, not the plain {@link Subject} data record.
1170
1180
  *
1171
1181
  * @remarks
1172
1182
  * A `unique symbol` brand check (`Reflect.get`), distinct from
1173
- * {@link isDefinitionBuilder} — the two entities can never match each other's
1183
+ * {@link isDefinitionBuilder} — neither entity can ever match the other's
1174
1184
  * guard. Total: a non-object, a missing brand, or a hostile prototype all
1175
1185
  * return `false`, never throw.
1176
1186
  *
@@ -1198,7 +1208,7 @@ function isSubjectBuilder(value) {
1198
1208
  *
1199
1209
  * @remarks
1200
1210
  * Display-only: the joined form is how a field appears in traces and derived
1201
- * overlays; it is NOT re-parsed into a path (a string stays ONE key).
1211
+ * overlays; it is never re-parsed into a path (a string stays a single key).
1202
1212
  *
1203
1213
  * @param field - The field path to format
1204
1214
  * @returns The display string
@@ -1243,7 +1253,7 @@ function clamp(value, limit) {
1243
1253
  *
1244
1254
  * @remarks
1245
1255
  * The range test behind the `between` and `outside` `Comparison` operators: only
1246
- * the FIRST TWO elements of `range` are read, both ends are inclusive, and a
1256
+ * the first two elements of `range` are read, each end is inclusive, and a
1247
1257
  * non-numeric `value`, a non-array `range`, a `range` shorter than two
1248
1258
  * elements, or a non-numeric bound all report `false`. `outside` is the pure
1249
1259
  * negation of this predicate, so a malformed range reads as outside.
@@ -1307,9 +1317,9 @@ function emptyAggregate(aggregation) {
1307
1317
  * source passes its value through; `field` and `range` coerce through the
1308
1318
  * contracts `parseNumberField`, so a non-finite subject number or a
1309
1319
  * non-numeric string is unresolvable and takes `fallback`; `lookup` reads only
1310
- * OWN table keys, and a missing or `null` field takes `fallback` directly
1320
+ * the table's own keys, and a missing or `null` field takes `fallback` directly
1311
1321
  * rather than letting a `''` key intercept absent data. A `range` scans its
1312
- * bands in order and the FIRST match wins — a band without `bounds` is a
1322
+ * bands in order and the first match wins — a band without `bounds` is a
1313
1323
  * catch-all and an absent bound side is open. A malformed factor carrying no
1314
1324
  * source at all takes `fallback` rather than crashing.
1315
1325
  *
@@ -1359,9 +1369,9 @@ function resolveSource(source, subject, fallback) {
1359
1369
  * @remarks
1360
1370
  * `Math.round` semantics — halves round toward `+∞` (`2.5` → `3`, `-2.5` → `-2`).
1361
1371
  * A negative precision rounds at whole-number scales (`-1` → tens, `-2` →
1362
- * hundreds). An EXTREME precision whose scale factor overflows the double range
1372
+ * hundreds). A precision whose scale factor overflows the double range
1363
1373
  * (`10^p` → `Infinity` at roughly `p > 308`, `0` at roughly `p < -323`) returns
1364
- * the value UNCHANGED — passthrough, never `NaN`.
1374
+ * the value unchanged — passthrough, never `NaN`.
1365
1375
  *
1366
1376
  * @param value - The number to round
1367
1377
  * @param precision - Decimal places to keep (defaults to `0`)
@@ -1389,7 +1399,7 @@ function roundTo(value, precision = 0) {
1389
1399
  * @remarks
1390
1400
  * This is the derivation-bookkeeping equality of the chaining reasoners: the
1391
1401
  * logical overlay and the inferential fact-dedupe compare with it so a
1392
- * NaN-valued conclusion or fact term derives exactly ONCE and the fixpoint
1402
+ * NaN-valued conclusion or fact term derives exactly once and the fixpoint
1393
1403
  * converges (raw `===` would re-derive it every iteration, never converging).
1394
1404
  * It matches `Array.prototype.includes` semantics — the same membership test
1395
1405
  * the `any` / `none` comparisons use.
@@ -1416,7 +1426,7 @@ function equalValues(left, right) {
1416
1426
  * @remarks
1417
1427
  * The shared evaluation-order helper of the quantitative (factors) and logical
1418
1428
  * (rules) reasoners: lower priorities run first, an absent `priority` defaults
1419
- * to `0`, equal priorities keep DECLARATION order (stable), and the input array
1429
+ * to `0`, equal priorities keep declaration order (stable), and the input array
1420
1430
  * is never mutated. An array hole, `null`, or other non-record entry is dropped
1421
1431
  * rather than sorted — the output may be shorter than the input.
1422
1432
  *
@@ -1440,12 +1450,12 @@ function sortByPriority(items) {
1440
1450
  return usable.sort((left, right) => (left.priority ?? 0) - (right.priority ?? 0));
1441
1451
  }
1442
1452
  /**
1443
- * Collects the ids that appear MORE THAN ONCE in an id-carrying list — each
1453
+ * Collects the ids that appear more than once in an id-carrying list — each
1444
1454
  * duplicated id reported once, in first-occurrence order.
1445
1455
  *
1446
1456
  * @remarks
1447
1457
  * The shared uniqueness scan behind every reasoner's `validate()` duplicate-id
1448
- * WARNINGS (rules, groups, factors, equations, inferences). Runtime stays
1458
+ * warnings (rules, groups, factors, equations, inferences). Runtime stays
1449
1459
  * permissive about duplicates (first/last-wins artifacts) — this helper only
1450
1460
  * surfaces them.
1451
1461
  *
@@ -1471,7 +1481,7 @@ function findDuplicates(items) {
1471
1481
  * @remarks
1472
1482
  * Keys both stored facts and premise patterns (both are `Fact`-shaped) for
1473
1483
  * {@link indexByArity}: `matchFacts` already rejects an arity mismatch, so
1474
- * narrowing a same-predicate bucket to same-predicate-AND-same-arity only
1484
+ * narrowing a same-predicate bucket to one of the same predicate and arity only
1475
1485
  * excludes candidates that could never unify anyway. Only `predicate` — the
1476
1486
  * one free-form, adversary-controlled part — is length-prefixed
1477
1487
  * (`length + ':' + predicate`), mirroring {@link factToKey}'s framing so a
@@ -1500,7 +1510,7 @@ function factToArityKey(fact) {
1500
1510
  * @remarks
1501
1511
  * The index behind the inferential reasoner's same-predicate-and-arity join
1502
1512
  * scans (`#findAllBindings` / `#calculatePremiseConfidence`): `matchFacts`
1503
- * already rejects a predicate OR arity mismatch, so restricting a premise's
1513
+ * already rejects a predicate or an arity mismatch, so restricting a premise's
1504
1514
  * search to its own predicate+arity bucket changes nothing but the cost — the
1505
1515
  * surviving matches and their append order are identical to a predicate-only
1506
1516
  * index. Append order within a bucket is preserved, so a "first match wins"
@@ -1536,9 +1546,9 @@ function indexByArity(facts) {
1536
1546
  * forward-chaining dedupe. Primitives (and `null`) key by value, typeof-prefixed
1537
1547
  * so `1` (`number:1`) never collides with `'1'` (`string:1`); `-0` folds to `+0`
1538
1548
  * (both `number:0`) and `NaN` is self-consistent (`number:NaN`), matching
1539
- * SameValueZero. Objects and functions key by REFERENCE through `identities` — a
1549
+ * SameValueZero. Objects and functions key by reference through `identities` — a
1540
1550
  * first sighting is assigned the map's current size as its id, so distinct
1541
- * objects never collide and the SAME reference always reproduces its key.
1551
+ * objects never collide and the same reference always reproduces its key.
1542
1552
  *
1543
1553
  * @param term - The term to key
1544
1554
  * @param identities - The caller-created reference-identity ledger, threaded across a dedupe pass (a newly seen object/function is registered in it)
@@ -1565,14 +1575,14 @@ function termToKey(term, identities) {
1565
1575
  }
1566
1576
  /**
1567
1577
  * Derives a fact's canonical dedup key — predicate + arity + per-term
1568
- * SameValueZero identity (confidence is NOT part of it).
1578
+ * SameValueZero identity, with confidence excluded from it.
1569
1579
  *
1570
1580
  * @remarks
1571
1581
  * The dedup key of the inferential reasoner's forward fixpoint: two facts with
1572
1582
  * the same predicate, arity, and SameValueZero-equal terms share a key (so a
1573
1583
  * NaN-term fact derives once and ±0 collapse keeping the first), while
1574
1584
  * confidence never enters the key. Each part — the predicate, the stringified
1575
- * arity, and every {@link termToKey} — is LENGTH-PREFIXED (`length + ':' + part`)
1585
+ * arity, and every {@link termToKey} — is length-prefixed (`length + ':' + part`)
1576
1586
  * before joining, so the delimiter can never be forged by an adversarial string
1577
1587
  * term embedding it: two distinct facts always produce distinct keys, even when
1578
1588
  * a term string contains the delimiter (an injective framing raw joining lacked).
@@ -1603,10 +1613,10 @@ function factToKey(fact, identities) {
1603
1613
  *
1604
1614
  * @remarks
1605
1615
  * The bidirectional unification of the inferential reasoner: a `'?'`-prefixed
1606
- * string term on EITHER side (pattern or candidate) is a variable that binds to
1616
+ * string term on either side (pattern or candidate) is a variable that binds to
1607
1617
  * the opposite term (the `'?'` prefix is kept in the binding key), while
1608
1618
  * consistency is enforced within the match — a variable seen twice must bind the
1609
- * SAME value (raw `!==`) or the whole match fails. A predicate mismatch or an
1619
+ * same value (raw `!==`) or the whole match fails. A predicate mismatch or an
1610
1620
  * arity (term-count) mismatch fails immediately; non-variable terms must be
1611
1621
  * strictly (`===`) equal.
1612
1622
  *
@@ -1648,7 +1658,7 @@ function matchFacts(pattern, candidate) {
1648
1658
  * @remarks
1649
1659
  * The pattern-instantiation step of the inferential reasoner: a `'?'`-prefixed
1650
1660
  * string term that is present in `bindings` is replaced by its bound value;
1651
- * every other term (constants and UNBOUND variables alike) is kept verbatim. The
1661
+ * every other term (constants and unbound variables alike) is kept verbatim. The
1652
1662
  * returned fact is a fresh copy (`{ ...fact, terms }`) — the input is never
1653
1663
  * mutated.
1654
1664
  *
@@ -1675,7 +1685,7 @@ function instantiateFact(fact, bindings) {
1675
1685
  }
1676
1686
  /**
1677
1687
  * Computes the confidence a set of matched premises contributes to a derived
1678
- * fact — the product of each premise's FIRST matching fact's confidence.
1688
+ * fact — the product of each premise's first matching fact's confidence.
1679
1689
  *
1680
1690
  * @remarks
1681
1691
  * The confidence half of the inferential reasoner's forward derivation: each
@@ -1716,7 +1726,7 @@ function computePremiseConfidence(premises, index, bindings) {
1716
1726
  * inferential reasoner's subject-injection step.
1717
1727
  *
1718
1728
  * @remarks
1719
- * Every own subject field EXCEPT `id` becomes a `has(key, value)` fact at full
1729
+ * Every own subject field except `id` becomes a `has(key, value)` fact at full
1720
1730
  * `DEFAULT_CONFIDENCE`; `null` / `undefined` and any `object` (including arrays)
1721
1731
  * value is skipped. The returned `trace` carries one line per injection plus a
1722
1732
  * final count when at least one fact was produced, so no caller-owned
@@ -1794,21 +1804,21 @@ function findUnboundVariables(inference) {
1794
1804
  return unbound;
1795
1805
  }
1796
1806
  /**
1797
- * Determines whether a symbolic expression contains an UNBOUND occurrence of a
1807
+ * Determines whether a symbolic expression contains an unbound occurrence of a
1798
1808
  * target variable.
1799
1809
  *
1800
1810
  * @remarks
1801
1811
  * The variable-presence probe of the symbolic reasoner's isolation: a `variable`
1802
- * node matches only when its name is `target` AND `target` is not already in
1812
+ * node matches only when its name is `target` and `target` is not already in
1803
1813
  * `bindings` (a pre-bound target is a known value, not an unknown to isolate); a
1804
1814
  * `constant` never matches; an `operation` recurses into both operands (the
1805
- * `right` operand may be absent on a unary node). The walk is an ITERATIVE
1815
+ * `right` operand may be absent on a unary node). The walk is an iterative
1806
1816
  * worklist (never recursive) with short-circuit `true` on the first hit, so it
1807
1817
  * stays total on pathologically deep expression trees.
1808
1818
  *
1809
1819
  * @param expression - The expression to probe
1810
1820
  * @param target - The variable name being sought
1811
- * @param bindings - The known bindings (a bound target does NOT count as present)
1821
+ * @param bindings - The known bindings (a bound target does not count as present)
1812
1822
  * @returns True if an unbound `target` occurs in the expression; false otherwise
1813
1823
  *
1814
1824
  * @example
@@ -1834,7 +1844,7 @@ function containsVariable(expression, target, bindings) {
1834
1844
  return false;
1835
1845
  }
1836
1846
  /**
1837
- * Inverts a `x op right = value` step, solving for the LEFT operand `x`.
1847
+ * Inverts a `x op right = value` step, solving for the left operand `x`.
1838
1848
  *
1839
1849
  * @remarks
1840
1850
  * The left-operand inverse of the symbolic reasoner's isolation: `add` inverts
@@ -1869,7 +1879,7 @@ function invertLeft(operator, value, rightValue) {
1869
1879
  }
1870
1880
  }
1871
1881
  /**
1872
- * Inverts a `left op x = value` step, solving for the RIGHT operand `x`.
1882
+ * Inverts a `left op x = value` step, solving for the right operand `x`.
1873
1883
  *
1874
1884
  * @remarks
1875
1885
  * The right-operand inverse of the symbolic reasoner's isolation: `add` inverts
@@ -1911,7 +1921,7 @@ function invertRight(operator, value, leftValue) {
1911
1921
  * by zero is `NaN` (never a throw), the unary operations (`round` / `ceil` /
1912
1922
  * `floor` / `abs`) ignore `right`, and `percentage` is `left * (right / 100)`.
1913
1923
  * `operator` is typed `string` because untrusted definitions reach here
1914
- * unchecked; the ONE throwing path is the unknown-operator default, which
1924
+ * unchecked; the only throwing path is the unknown-operator default, which
1915
1925
  * throws `ReasonError('OPERATOR', …, { operator })` and is caught per equation
1916
1926
  * upstream.
1917
1927
  *
@@ -1982,7 +1992,7 @@ function resolveOperand(operation, operand) {
1982
1992
  * The shared atom-walk behind both {@link extractConclusions} and the raters'
1983
1993
  * conclusion merge: an `atom` yields itself; a compound flattens its operands in
1984
1994
  * authored order, so a later operand's atoms follow an earlier one's. The walk is
1985
- * an ITERATIVE explicit-stack traversal (never recursive), so it stays total on
1995
+ * an iterative explicit-stack traversal (never recursive), so it stays total on
1986
1996
  * pathologically deep expression trees; a hole in an `operands` array is skipped,
1987
1997
  * matching `flatMap`'s hole-skipping behavior.
1988
1998
  *
@@ -2017,13 +2027,13 @@ function extractAtoms(expression) {
2017
2027
  }
2018
2028
  /**
2019
2029
  * Flattens a logical conclusion expression into its asserted `field = value`
2020
- * pairs — connectives IGNORED.
2030
+ * pairs, ignoring the connectives.
2021
2031
  *
2022
2032
  * @remarks
2023
2033
  * The conclusion-extraction step of the logical reasoner's chaining: every
2024
2034
  * `atom` inside the expression asserts its `formatField(check.field) =
2025
2035
  * check.value` pair, and compounds are walked without regard to the connective
2026
- * (an atom under `not` / `or` is asserted the same way). Later operands WIN on
2036
+ * (an atom under `not` / `or` is asserted the same way). A later operand wins on
2027
2037
  * a key clash (`Object.assign` order). Recursion runs through this exported
2028
2038
  * function itself; the derived-overlay keys are `formatField` strings (an array
2029
2039
  * field path flattens to its dot-joined form).
@@ -2050,13 +2060,13 @@ function extractConclusions(expression) {
2050
2060
  *
2051
2061
  * @remarks
2052
2062
  * The reported keys are the `formatField`-flattened overlay keys an array-path
2053
- * conclusion atom writes ANYWHERE among `rules` that an array-path premise atom
2054
- * also reads ANYWHERE among `rules`. The cross-rule authoring-time footgun
2063
+ * conclusion atom writes anywhere among `rules` that an array-path premise atom
2064
+ * also reads anywhere among `rules`. The cross-rule authoring-time footgun
2055
2065
  * probe behind `LogicalReasoner.validate`'s overlay-key-mismatch warning: a
2056
- * logical conclusion's derived overlay is a FLAT record keyed by
2066
+ * logical conclusion's derived overlay is a flat record keyed by
2057
2067
  * `formatField(check.field)` — an array `FieldPath` dot-joins into one string
2058
- * key. A premise that reads the same field through a DOTTED-STRING path resolves
2059
- * that flat key correctly, but a premise that reads it through an ARRAY path
2068
+ * key. A premise that reads the same field through a dotted-string path resolves
2069
+ * that flat key correctly, but a premise that reads it through an array path
2060
2070
  * calls `resolveField`, which descends key-by-key into nesting the flat
2061
2071
  * overlay never created, so the chain silently fails to connect. Collects the
2062
2072
  * flattened keys of every array-path conclusion atom across `rules` (once
@@ -2198,15 +2208,15 @@ function definitionToEnvelope(definition) {
2198
2208
  }
2199
2209
  /**
2200
2210
  * Inserts `item` into an id-keyed collection, deduping any existing element
2201
- * sharing its id, then placing it at the END (or immediately AFTER `target`).
2211
+ * sharing its id, then placing it at the end, or immediately after `target`.
2202
2212
  *
2203
2213
  * @remarks
2204
- * Insertion DEDUPES on the id first: `filtered` is `items` with every `item.id`
2214
+ * Insertion dedupes on the id first: `filtered` is `items` with every `item.id`
2205
2215
  * twin removed, because an input array may already carry same-id twins.
2206
- * Re-appending an existing id therefore REPOSITIONS it rather than updating it
2216
+ * Re-appending an existing id therefore repositions it rather than updating it
2207
2217
  * in place — {@link replaceById} is the position-preserving alternative. With
2208
2218
  * no `target`, `item` lands at the end; with a `target`, it lands immediately
2209
- * after the element whose `id === target` (searched in the DEDUPED array). A
2219
+ * after the element whose `id === target` (searched in the deduped array). A
2210
2220
  * `target` naming no element throws {@link ReasonError} (`'TARGET'`).
2211
2221
  *
2212
2222
  * @typeParam T - An id-carrying element type
@@ -2241,7 +2251,7 @@ function appendById(items, item, target) {
2241
2251
  }
2242
2252
  /**
2243
2253
  * Inserts `item` into an id-keyed collection, deduping any existing element
2244
- * sharing its id, then placing it at the START (or immediately BEFORE `target`).
2254
+ * sharing its id, then placing it at the start, or immediately before `target`.
2245
2255
  *
2246
2256
  * @remarks
2247
2257
  * Mirrors {@link appendById}'s dedup-then-insert semantics exactly, only the
@@ -2281,7 +2291,7 @@ function prependById(items, item, target) {
2281
2291
  ];
2282
2292
  }
2283
2293
  /**
2284
- * Swaps the element sharing `item.id` IN PLACE, preserving its position.
2294
+ * Swaps the element sharing `item.id` in place, preserving its position.
2285
2295
  *
2286
2296
  * @remarks
2287
2297
  * The position-preserving update primitive — unlike {@link appendById}, which
@@ -2338,11 +2348,11 @@ function removeById(items, id) {
2338
2348
  *
2339
2349
  * @remarks
2340
2350
  * A Strategic-Merge-Patch-style id-keyed upsert:
2341
- * the result is ordered by `incoming`'s id order FIRST (each element resolved
2351
+ * the result is ordered by `incoming`'s id order first (each element resolved
2342
2352
  * through `resolve` when its id also exists in `base`, defaulting to
2343
- * incoming-wins-wholesale), THEN the `base`-only survivors in `base`'s own
2353
+ * incoming-wins-wholesale), then the `base`-only survivors in `base`'s own
2344
2354
  * order (retained, never deleted — merge is additive). Same-id twins within
2345
- * EITHER input are deduped to their first occurrence.
2355
+ * either input are deduped to their first occurrence.
2346
2356
  *
2347
2357
  * @typeParam T - An id-carrying element type
2348
2358
  * @param base - The base collection
@@ -2381,7 +2391,7 @@ function mergeById(base, incoming, resolve) {
2381
2391
  * insert at the end, or immediately after `target`.
2382
2392
  *
2383
2393
  * @remarks
2384
- * Group order is COSMETIC (group aggregation is order-independent) but honored
2394
+ * Group order is cosmetic (group aggregation is order-independent) but honored
2385
2395
  * uniformly, same as every `append*` helper. Composes with {@link appendFactor}:
2386
2396
  * `appendGroup(def, appendFactor(group, factor))`.
2387
2397
  *
@@ -2428,8 +2438,8 @@ function prependGroup(definition, group, target) {
2428
2438
  };
2429
2439
  }
2430
2440
  /**
2431
- * Swaps the group sharing `group.id` in a {@link QuantitativeDefinition} IN
2432
- * PLACE, preserving its position (appends when absent).
2441
+ * Swaps the group sharing `group.id` in a {@link QuantitativeDefinition} in
2442
+ * place, preserving its position (appended when absent).
2433
2443
  *
2434
2444
  * @param definition - The definition to update
2435
2445
  * @param group - The replacement group
@@ -2476,9 +2486,9 @@ function removeGroup(definition, id) {
2476
2486
  * at the end, or immediately after `target`.
2477
2487
  *
2478
2488
  * @remarks
2479
- * Factor order is LOAD-BEARING: the same-priority tiebreak is declaration
2489
+ * Factor order is load-bearing: the same-priority tiebreak is declaration
2480
2490
  * order ({@link sortByPriority} is a stable ascending sort). Operates on the
2481
- * factor's DIRECT container — compose into a definition through
2491
+ * factor's direct container — compose into a definition through
2482
2492
  * `appendGroup(def, appendFactor(group, factor))`.
2483
2493
  *
2484
2494
  * @param group - The group to insert into
@@ -2524,8 +2534,8 @@ function prependFactor(group, factor, target) {
2524
2534
  };
2525
2535
  }
2526
2536
  /**
2527
- * Swaps the factor sharing `factor.id` in a {@link FactorGroup} IN PLACE,
2528
- * preserving its position (appends when absent).
2537
+ * Swaps the factor sharing `factor.id` in a {@link FactorGroup} in place,
2538
+ * preserving its position (appended when absent).
2529
2539
  *
2530
2540
  * @param group - The group to update
2531
2541
  * @param factor - The replacement factor
@@ -2571,7 +2581,7 @@ function removeFactor(group, id) {
2571
2581
  * at the end, or immediately after `target`.
2572
2582
  *
2573
2583
  * @remarks
2574
- * Order is LOAD-BEARING: the forward conclusion is the LAST declared
2584
+ * Order is load-bearing: the forward conclusion is the last declared
2575
2585
  * non-disabled rule, so `appendRule` without a `target` makes the new rule the
2576
2586
  * conclusion.
2577
2587
  *
@@ -2618,8 +2628,8 @@ function prependRule(definition, rule, target) {
2618
2628
  };
2619
2629
  }
2620
2630
  /**
2621
- * Swaps the rule sharing `rule.id` in a {@link LogicalDefinition} IN PLACE,
2622
- * preserving its position (appends when absent).
2631
+ * Swaps the rule sharing `rule.id` in a {@link LogicalDefinition} in place,
2632
+ * preserving its position (appended when absent).
2623
2633
  *
2624
2634
  * @param definition - The definition to update
2625
2635
  * @param rule - The replacement rule
@@ -2666,8 +2676,8 @@ function removeRule(definition, id) {
2666
2676
  * then-insert at the end, or immediately after `target`.
2667
2677
  *
2668
2678
  * @remarks
2669
- * Order is STRONGLY load-bearing: equations solve strictly in order and each
2670
- * rounded solution feeds forward.
2679
+ * Order is load-bearing: equations solve strictly in order and each rounded
2680
+ * solution feeds forward.
2671
2681
  *
2672
2682
  * @param definition - The definition to insert into
2673
2683
  * @param equation - The equation to insert
@@ -2712,8 +2722,8 @@ function prependEquation(definition, equation, target) {
2712
2722
  };
2713
2723
  }
2714
2724
  /**
2715
- * Swaps the equation sharing `equation.id` in a {@link SymbolicDefinition} IN
2716
- * PLACE, preserving its position (appends when absent).
2725
+ * Swaps the equation sharing `equation.id` in a {@link SymbolicDefinition} in
2726
+ * place, preserving its position (appended when absent).
2717
2727
  *
2718
2728
  * @param definition - The definition to update
2719
2729
  * @param equation - The replacement equation
@@ -2787,7 +2797,7 @@ function addVariable(definition, name, value) {
2787
2797
  * Removes one entry of a {@link SymbolicDefinition}'s `variables`.
2788
2798
  *
2789
2799
  * @remarks
2790
- * The destructure-rest form OMITS the key entirely (never sets it to
2800
+ * The destructure-rest form omits the key entirely (never sets it to
2791
2801
  * `undefined`), keeping the result exact-record valid. A no-op (fresh copy)
2792
2802
  * when `name` is absent.
2793
2803
  *
@@ -2814,7 +2824,7 @@ function removeVariable(definition, name) {
2814
2824
  * insert at the end, or immediately after `target`.
2815
2825
  *
2816
2826
  * @remarks
2817
- * `Fact.id` is an AUTHORING label — the runtime content-dedups facts by
2827
+ * `Fact.id` is an authoring label — the runtime content-dedups facts by
2818
2828
  * predicate+arity+terms ({@link factToKey}), independently of this helper's
2819
2829
  * id-keyed dedup.
2820
2830
  *
@@ -2861,8 +2871,8 @@ function prependFact(definition, fact, target) {
2861
2871
  };
2862
2872
  }
2863
2873
  /**
2864
- * Swaps the fact sharing `fact.id` in an {@link InferentialDefinition} IN
2865
- * PLACE, preserving its position (appends when absent).
2874
+ * Swaps the fact sharing `fact.id` in an {@link InferentialDefinition} in
2875
+ * place, preserving its position (appended when absent).
2866
2876
  *
2867
2877
  * @param definition - The definition to update
2868
2878
  * @param fact - The replacement fact
@@ -2909,7 +2919,7 @@ function removeFact(definition, id) {
2909
2919
  * dedup-then-insert at the end, or immediately after `target`.
2910
2920
  *
2911
2921
  * @remarks
2912
- * Order is LOAD-BEARING: backward proving iterates in declaration order and
2922
+ * Order is load-bearing: backward proving iterates in declaration order and
2913
2923
  * returns on first success.
2914
2924
  *
2915
2925
  * @param definition - The definition to insert into
@@ -2962,7 +2972,7 @@ function prependInference(definition, inference, target) {
2962
2972
  }
2963
2973
  /**
2964
2974
  * Swaps the inference sharing `inference.id` in an {@link InferentialDefinition}
2965
- * IN PLACE, preserving its position (appends when absent).
2975
+ * in place, preserving its position (appended when absent).
2966
2976
  *
2967
2977
  * @param definition - The definition to update
2968
2978
  * @param inference - The replacement inference
@@ -3009,10 +3019,10 @@ function removeInference(definition, id) {
3009
3019
  * Reconciles two {@link QuantitativeDefinition}s onto `base`'s id.
3010
3020
  *
3011
3021
  * @remarks
3012
- * The merge is ADDITIVE: a base-only group survives into the result and is
3022
+ * The merge is additive: a base-only group survives into the result and is
3013
3023
  * never deleted, and a scalar absent from `incoming` keeps its base value —
3014
3024
  * merge never clears a field, which is what {@link clearQuantitativeDefinition}
3015
- * is for. `groups` merges through {@link mergeById}; a matched (same-id) PAIR of
3025
+ * is for. `groups` merges through {@link mergeById}; a matched (same-id) pair of
3016
3026
  * groups recurses one level deeper — their `factors` also merge through
3017
3027
  * `mergeById` — the one exception to incoming-wins-wholesale. Every other
3018
3028
  * scalar / value-object field is incoming-wins-when-present, else base kept.
@@ -3050,7 +3060,7 @@ function mergeQuantitativeDefinition(base, incoming) {
3050
3060
  * Reconciles two {@link LogicalDefinition}s onto `base`'s id.
3051
3061
  *
3052
3062
  * @remarks
3053
- * The merge is ADDITIVE: a base-only rule survives into the result and is never
3063
+ * The merge is additive: a base-only rule survives into the result and is never
3054
3064
  * deleted, and a scalar absent from `incoming` keeps its base value — merge
3055
3065
  * never clears a field, which is what {@link clearLogicalDefinition} is for.
3056
3066
  * `rules` merges through {@link mergeById} (incoming-wins-wholesale on a matched
@@ -3083,7 +3093,7 @@ function mergeLogicalDefinition(base, incoming) {
3083
3093
  * Reconciles two {@link SymbolicDefinition}s onto `base`'s id.
3084
3094
  *
3085
3095
  * @remarks
3086
- * The merge is ADDITIVE: a base-only equation or variable survives into the
3096
+ * The merge is additive: a base-only equation or variable survives into the
3087
3097
  * result and is never deleted, and a scalar absent from `incoming` keeps its
3088
3098
  * base value — merge never clears a field, which is what
3089
3099
  * {@link clearSymbolicDefinition} is for. `equations` merges through
@@ -3123,7 +3133,7 @@ function mergeSymbolicDefinition(base, incoming) {
3123
3133
  * Reconciles two {@link InferentialDefinition}s onto `base`'s id.
3124
3134
  *
3125
3135
  * @remarks
3126
- * The merge is ADDITIVE: a base-only inference or fact survives into the result
3136
+ * The merge is additive: a base-only inference or fact survives into the result
3127
3137
  * and is never deleted, and a scalar absent from `incoming` keeps its base
3128
3138
  * value — merge never clears a field, which is what
3129
3139
  * {@link clearInferentialDefinition} is for. `inferences` and `facts` each
@@ -3234,7 +3244,7 @@ function clearInferentialDefinition(definition, key) {
3234
3244
  * Upserts one field of a {@link Subject} — copy-on-write spread.
3235
3245
  *
3236
3246
  * @remarks
3237
- * Named `assignField` rather than `setField` because it RETURNS a fresh subject
3247
+ * Named `assignField` rather than `setField` because it returns a fresh subject
3238
3248
  * instead of writing into the one it is given — `set*` reads as an in-place
3239
3249
  * write. Id-agnostic: overwrites an `id` key like any other field — id
3240
3250
  * protection is an entity's job, not this helper's.
@@ -3261,7 +3271,7 @@ function assignField(subject, key, value) {
3261
3271
  * Deletes one field of a {@link Subject} — destructure-rest omit.
3262
3272
  *
3263
3273
  * @remarks
3264
- * The key is DELETED entirely (never set to `undefined`), keeping the result
3274
+ * The key is deleted entirely (never set to `undefined`), keeping the result
3265
3275
  * exact-record valid. A no-op (fresh copy) when `key` is absent.
3266
3276
  *
3267
3277
  * @param subject - The subject to update
@@ -3316,8 +3326,8 @@ function mergeSubjects(base, incoming) {
3316
3326
  * When `subject.id` is a string, each clone's id is minted
3317
3327
  * `` `${baseId}-${index}` `` (index from `0`); with no string `id`, the clones
3318
3328
  * pass through unchanged (still fresh copies). Pure and deterministic — the
3319
- * same input always produces the same output (run-twice equality) — and does
3320
- * NOT emit. `count <= 0` yields an empty array.
3329
+ * same input always produces the same output (run-twice equality) — and emits
3330
+ * nothing. `count <= 0` yields an empty array.
3321
3331
  *
3322
3332
  * @param subject - The subject to clone
3323
3333
  * @param count - How many clones to produce
@@ -3347,8 +3357,8 @@ function repeatSubject(subject, count) {
3347
3357
  *
3348
3358
  * @remarks
3349
3359
  * The safe inverse of the builders: `parseJSONAs` composed with the data guard
3350
- * {@link isDefinition}. A built definition body IS the durable JSON payload —
3351
- * `JSON.stringify(definition)` round-trips through `parseDefinition`. Two
3360
+ * {@link isDefinition}. A built definition body is the durable JSON payload —
3361
+ * `JSON.stringify(definition)` round-trips through `parseDefinition`. The
3352
3362
  * authoring hazards: a required `Check.value: undefined` drops its key on
3353
3363
  * `JSON.stringify` (author `null` instead), and a `Fact.terms` element of
3354
3364
  * `undefined` serializes to `null` (terms must be JSON-safe scalars/strings).
@@ -3375,16 +3385,16 @@ function parseDefinition(json) {
3375
3385
  * {@link ReasonerInterface}s.
3376
3386
  *
3377
3387
  * @remarks
3378
- * Holds NO strategy-specific logic: dispatch is purely a registry lookup by
3388
+ * Holds no strategy-specific logic: dispatch is purely a registry lookup by
3379
3389
  * `definition.reasoning` (one reasoner per reasoning; re-registration
3380
3390
  * replaces). A missing reasoner throws `MISSING` and a pre-run validation
3381
- * failure (when the `validate` option is on) throws `INVALID` — both BYPASS
3382
- * `bail` and emit nothing. A reasoner throw emits `error` with the raw thrown
3391
+ * failure (when the `validate` option is on) throws `INVALID` — each bypasses
3392
+ * `bail` and emits nothing. A reasoner throw emits `error` with the raw thrown
3383
3393
  * value, then rethrows under `bail: true` (the default) or converts to a
3384
- * type-shaped failure result under `bail: false`; only SUCCESSFUL results emit
3394
+ * type-shaped failure result under `bail: false`; only a successful result emits
3385
3395
  * `reason` (synchronously, before returning). The batch overload maps subjects
3386
3396
  * in order (validation, when on, repeats per subject). `destroy()` clears the
3387
- * registry, emits `destroy`, then destroys the emitter LAST and is
3397
+ * registry, emits `destroy`, then destroys the emitter last and is
3388
3398
  * idempotent; every other method afterwards throws `DESTROYED` — only the
3389
3399
  * {@link emitter} getter keeps working.
3390
3400
  *
@@ -3503,14 +3513,14 @@ var Reason = class {
3503
3513
  * quantitative and logical reasoners.
3504
3514
  *
3505
3515
  * @remarks
3506
- * TOTAL and strict: `evaluate` never throws (an unknown operator is caught and
3516
+ * Total and strict: `evaluate` never throws (an unknown operator is caught and
3507
3517
  * surfaced as `CheckResult.error` with `met: false`) and never coerces —
3508
3518
  * `equals` / `not` are raw `===` / `!==`, the ordering operators demand numbers
3509
- * on BOTH sides, `any` / `none` demand an array expected value (a non-array is
3510
- * not met for either — `none` is NOT the raw complement of `any` on malformed
3511
- * input), while `outside` IS the pure negation of `between` (so a malformed
3519
+ * on each side, `any` / `none` demand an array expected value (a non-array is
3520
+ * not met for either — `none` is not the raw complement of `any` on malformed
3521
+ * input), while `outside` is the pure negation of `between` (so a malformed
3512
3522
  * range is `outside`). Fields resolve through the core `resolveField` — a string
3513
- * is ONE key, an array descends. Stateless and deterministic.
3523
+ * is a single key, an array descends. Stateless and deterministic.
3514
3524
  *
3515
3525
  * @example
3516
3526
  * ```ts
@@ -3574,7 +3584,7 @@ var Evaluator = class {
3574
3584
  * per-factor pipeline stage.
3575
3585
  *
3576
3586
  * @remarks
3577
- * TOTAL: never throws. Absent-`operand` defaults are operation-specific —
3587
+ * Total: never throws. Absent-`operand` defaults are operation-specific —
3578
3588
  * identity-preserving `1` for `multiply` / `divide` / `power`, `0` for every
3579
3589
  * other binary operation; `round` / `ceil` / `floor` / `abs` are unary and
3580
3590
  * ignore the operand. `divide` by zero yields `NaN` (deliberately not JS's
@@ -3614,11 +3624,11 @@ var Transformer = class {
3614
3624
  * reasoner's group and definition combiner.
3615
3625
  *
3616
3626
  * @remarks
3617
- * TOTAL: never throws. Empty-input identities: `sum` / `average` → `0`,
3627
+ * Total: never throws. Empty-input identities: `sum` / `average` → `0`,
3618
3628
  * `product` → `1`, `minimum` / `maximum` → `NaN` (the deliberate "no data"
3619
- * signal). Weights are honored ONLY when their length matches `values` exactly
3629
+ * signal). Weights are honored only when their length matches `values` exactly
3620
3630
  * (otherwise silently unweighted): a weight multiplies into a `sum`, acts as an
3621
- * EXPONENT for a `product`, is the weight of a weighted mean for `average`
3631
+ * exponent for a `product`, is the weight of a weighted mean for `average`
3622
3632
  * (a zero total weight yields `0`, never a division blow-up), and is ignored by
3623
3633
  * `minimum` / `maximum`. An unknown aggregation yields `0`. Stateless and
3624
3634
  * deterministic.
@@ -3664,21 +3674,21 @@ var Aggregator = class {
3664
3674
  * Performs factor-based numeric scoring.
3665
3675
  *
3666
3676
  * @remarks
3667
- * Each factor runs a fixed pipeline: checks gate (ALL met) → source resolve
3668
- * (`fallback` when unresolvable) → finite check → transforms chain → bounds
3669
- * clamp → finite recheck. Factors evaluate in stable ascending `priority`
3677
+ * Each factor runs a fixed pipeline: checks gate (every check met) → source
3678
+ * resolve (`fallback` when unresolvable) → finite check → transforms chain →
3679
+ * bounds clamp → finite recheck. Factors evaluate in stable ascending `priority`
3670
3680
  * order; a `strict` group is all-or-nothing; a group's value is its `base` plus
3671
- * the weighted aggregation of its APPLIED factors, clamped (never rounded); the
3681
+ * the weighted aggregation of its applied factors, clamped (never rounded); the
3672
3682
  * definition's value is its `base` plus the unweighted aggregation of the
3673
- * APPLIED groups' values, clamped, then rounded to `precision`. A
3683
+ * applied groups' values, clamped, then rounded to `precision`. A
3674
3684
  * required-factor failure or non-finite value appends an error (`success:
3675
3685
  * false`) without aborting — the numeric `value` is always computed. The
3676
- * definition-level value is finite-checked AFTER rounding: a non-finite
3686
+ * definition-level value is finite-checked after rounding: a non-finite
3677
3687
  * aggregate (a `minimum` / `maximum` over zero applied groups) appends an error
3678
3688
  * while the `NaN` stays visible in `value`. Field sources coerce through the
3679
3689
  * contracts `parseNumberField`: a non-finite subject number or a non-numeric
3680
3690
  * string is unresolvable and takes the fallback path. Lookup sources read only
3681
- * OWN table keys, and a missing / `null` field falls back directly. Nothing
3691
+ * the table's own keys, and a missing / `null` field falls back directly. Nothing
3682
3692
  * mutates its inputs; fully deterministic.
3683
3693
  *
3684
3694
  * @example
@@ -3910,18 +3920,18 @@ var QuantitativeReasoner = class {
3910
3920
  * @remarks
3911
3921
  * Forward chaining is a naive fixpoint capped at `depth` iterations: rules run
3912
3922
  * in ascending `priority` order each pass, and a firing rule's conclusion atoms
3913
- * become a derived overlay that SHADOWS same-named subject fields on later
3923
+ * become a derived overlay that shadows same-named subject fields on later
3914
3924
  * passes (derived keys are `formatField(check.field)` strings). Convergence —
3915
3925
  * one full pass with no new derivation — appends a trace containing
3916
3926
  * `converged`. Final rule results re-evaluate against the settled overlay in
3917
- * ORIGINAL rule order (forward) / priority-sorted order (backward), and the
3918
- * overall `conclusion` is whether the LAST result applied. Backward chaining
3919
- * proves EVERY rule goal-first: an unmet premise triggers sub-goal search
3927
+ * original rule order (forward) / priority-sorted order (backward), and the
3928
+ * overall `conclusion` is whether the last result applied. Backward chaining
3929
+ * proves every rule goal-first: an unmet premise triggers sub-goal search
3920
3930
  * through rules whose conclusion atoms assert the needed `field = value` pair,
3921
3931
  * guarded by a visited-rule set (cycle-safe) plus the depth cap; `not` succeeds
3922
3932
  * when its operand cannot be established (negation-as-failure) and `implies` is
3923
- * vacuously true on an unprovable antecedent. Expression evaluation is EAGER
3924
- * (no short-circuit); conclusion extraction IGNORES connectives — every atom
3933
+ * vacuously true on an unprovable antecedent. Expression evaluation is eager
3934
+ * (no short-circuit); conclusion extraction ignores connectives — every atom
3925
3935
  * inside a conclusion is asserted, even under `not` / `or`. Overlay bookkeeping
3926
3936
  * compares with SameValueZero (`equalValues`), so a NaN-valued conclusion
3927
3937
  * derives once and the fixpoint converges. Nothing mutates its inputs; fully
@@ -4254,16 +4264,16 @@ var LogicalReasoner = class {
4254
4264
  * @remarks
4255
4265
  * Bindings seed from `definition.variables`, then numeric subject fields (a
4256
4266
  * finite number or a numeric string, coerced through the contracts
4257
- * `parseNumber`) OVERRIDE same-named variables — the `id` field is skipped.
4267
+ * `parseNumber`) override same-named variables — the `id` field is skipped.
4258
4268
  * Equations solve strictly in order: when the `target` is unbound and appears
4259
- * on exactly ONE side, it is isolated by peeling invertible operations (`add` /
4269
+ * on exactly one side, it is isolated by peeling invertible operations (`add` /
4260
4270
  * `subtract` / `multiply` / `divide`); a non-invertible operation, a target on
4261
4271
  * both sides of an operation, or an unbound variable throws internally — the
4262
- * throw is caught PER EQUATION and surfaced as a result error (`Equation
4272
+ * throw is caught per equation and surfaced as a result error (`Equation
4263
4273
  * "<id>": <message>` plus a `FAILED` trace) while later equations still run.
4264
4274
  * Inversion or division by zero yields `NaN`, caught by the non-finite check.
4265
- * A solved value is rounded to `precision` BEFORE binding, so later equations
4266
- * see the rounded value; `solutions` reads FINAL bindings keyed by each
4275
+ * A solved value is rounded to `precision` before binding, so later equations
4276
+ * see the rounded value; `solutions` reads the settled bindings keyed by each
4267
4277
  * equation's target (a failed equation's target still appears when bound
4268
4278
  * elsewhere). Nothing mutates its inputs; fully deterministic.
4269
4279
  *
@@ -4456,7 +4466,7 @@ var SymbolicReasoner = class {
4456
4466
  *
4457
4467
  * @remarks
4458
4468
  * A string term starting with `?` is a unification variable — matching is
4459
- * positional and BIDIRECTIONAL (variables may sit in facts as well as
4469
+ * positional and bidirectional (variables may sit in facts as well as
4460
4470
  * patterns), with binding consistency enforced within one match and across
4461
4471
  * premises through pre-instantiation. Scalar subject fields (except `id`;
4462
4472
  * `null` / `undefined` / objects / arrays skipped) inject as
@@ -4467,8 +4477,8 @@ var SymbolicReasoner = class {
4467
4477
  * duplicate facts (same predicate, arity, and SameValueZero-equal terms — a
4468
4478
  * NaN term derives once and converges) are never re-derived. Backward chaining
4469
4479
  * proves each inference's conclusion in
4470
- * declaration order and RETURNS ON THE FIRST SUCCESS with one derived fact
4471
- * (confidence = the inference's own — premise confidences are NOT propagated)
4480
+ * declaration order and returns on the first success with one derived fact
4481
+ * (confidence = the inference's own — premise confidences are not propagated)
4472
4482
  * plus its {@link ProofNode} tree; recursion is guarded only by the depth cap.
4473
4483
  * Deriving nothing is still success. Nothing mutates its inputs; fully
4474
4484
  * deterministic.
@@ -4800,17 +4810,17 @@ var Collection = class {
4800
4810
  * kind-free manager over a symbolic definition's `equations`.
4801
4811
  *
4802
4812
  * @remarks
4803
- * OWNS its `equations` as a private {@link Collection} — copy-on-write state
4813
+ * Owns its `equations` as a private {@link Collection} — copy-on-write state
4804
4814
  * shared by composition with the other list managers — plus its own
4805
4815
  * {@link Emitter} over {@link EquationManagerEventMap}. Equation order is
4806
- * STRONGLY load-bearing — equations solve strictly in order and each rounded
4807
- * solution feeds forward. `remove` is the batch family (array form declared
4808
- * FIRST): no argument removes every equation, one id removes that equation, an
4816
+ * load-bearing — equations solve strictly in order and each rounded solution
4817
+ * feeds forward. `remove` is the batch family (array form declared
4818
+ * first): no argument removes every equation, one id removes that equation, an
4809
4819
  * id list removes those equations and returns true only when every named id
4810
4820
  * existed. It emits one `remove` per equation actually removed.
4811
4821
  * `seat` is the owning builder's silent bulk re-seat
4812
4822
  * channel (used by `merge`). `destroy()` is idempotent and tears the emitter
4813
- * down LAST; any other call after it throws `ReasonError('DESTROYED', …)`.
4823
+ * down last; any other call after it throws `ReasonError('DESTROYED', …)`.
4814
4824
  *
4815
4825
  * @example
4816
4826
  * ```ts
@@ -4893,17 +4903,17 @@ var EquationManager = class {
4893
4903
  * manager over an inferential definition's `facts`.
4894
4904
  *
4895
4905
  * @remarks
4896
- * OWNS its `facts` as a private {@link Collection} — copy-on-write state shared
4906
+ * Owns its `facts` as a private {@link Collection} — copy-on-write state shared
4897
4907
  * by composition with the other list managers — plus its own {@link Emitter}
4898
- * over {@link FactManagerEventMap}. `Fact.id` is an AUTHORING label — the
4908
+ * over {@link FactManagerEventMap}. `Fact.id` is an authoring label — the
4899
4909
  * runtime content-dedups facts by predicate+arity+terms, independently of this
4900
4910
  * manager's id-keyed dedup. `remove` is the batch family (array form declared
4901
- * FIRST): no argument removes every fact, one id removes that fact, an id list
4911
+ * first): no argument removes every fact, one id removes that fact, an id list
4902
4912
  * removes those facts and returns true only when every named id existed. It
4903
4913
  * emits one `remove` per fact actually removed.
4904
4914
  * `seat` is the owning builder's silent bulk re-seat
4905
4915
  * channel (used by `merge`). `destroy()` is idempotent and tears the emitter
4906
- * down LAST; any other call after it throws `ReasonError('DESTROYED', …)`.
4916
+ * down last; any other call after it throws `ReasonError('DESTROYED', …)`.
4907
4917
  *
4908
4918
  * @example
4909
4919
  * ```ts
@@ -4977,24 +4987,25 @@ var FactManager = class {
4977
4987
  //#endregion
4978
4988
  //#region src/core/builders/managers/FactorManager.ts
4979
4989
  /**
4980
- * Implements the {@link FactorManagerInterface} — the sole DIVERGENT
4981
- * manager: factors nest inside groups, so it holds NO collection state of its
4990
+ * Implements the {@link FactorManagerInterface} — the one divergent
4991
+ * manager: factors nest inside groups, so it holds no collection state of its
4982
4992
  * own and threads a required `groupId` locator.
4983
4993
  *
4984
4994
  * @remarks
4985
4995
  * Constructor-injected with the sibling {@link GroupManagerInterface}: each
4986
4996
  * write verb reads the located group (`groups.group(groupId)`), applies the
4987
- * factor-level pure helper ({@link appendFactor} etc.), and writes the updated
4997
+ * factor-level pure helper ({@link appendFactor}, {@link prependFactor},
4998
+ * {@link replaceFactor}, or {@link removeFactor}), and writes the updated
4988
4999
  * group back through `groups.replace(…)`. A `groupId` naming no existing group
4989
- * throws `ReasonError('TARGET', …, { groupId })`. It still owns its OWN
5000
+ * throws `ReasonError('TARGET', …, { groupId })`. It still owns its own
4990
5001
  * {@link Emitter} over {@link FactorManagerEventMap} (factor-id payloads).
4991
5002
  * `remove` is the batch family behind the leading `groupId` locator (array form
4992
- * declared FIRST): the locator alone removes every factor of that group, a
5003
+ * declared first): the locator alone removes every factor of that group, a
4993
5004
  * further id removes that factor, a further id list removes those factors and
4994
5005
  * returns true only when every named id existed. It emits one `remove` per
4995
5006
  * factor actually removed, each paired with a `replace` on the sibling
4996
5007
  * `GroupManagerInterface` for the containing group.
4997
- * `destroy()` is idempotent and tears the emitter down LAST; any other call
5008
+ * `destroy()` is idempotent and tears the emitter down last; any other call
4998
5009
  * after it throws `ReasonError('DESTROYED', …)`.
4999
5010
  *
5000
5011
  * @example
@@ -5093,16 +5104,16 @@ var FactorManager = class {
5093
5104
  * manager over a quantitative definition's `groups`.
5094
5105
  *
5095
5106
  * @remarks
5096
- * OWNS its `groups` as a private {@link Collection} — copy-on-write state
5107
+ * Owns its `groups` as a private {@link Collection} — copy-on-write state
5097
5108
  * shared by composition with the other list managers — plus its own
5098
5109
  * {@link Emitter} over {@link GroupManagerEventMap}. Every write verb delegates
5099
- * to the collection, then emits (the affected group id) AFTER the mutation.
5100
- * `remove` is the batch family (array form declared FIRST): no argument removes
5110
+ * to the collection, then emits (the affected group id) after the mutation.
5111
+ * `remove` is the batch family (array form declared first): no argument removes
5101
5112
  * every group, one id removes that group, an id list removes those groups and
5102
5113
  * returns true only when every named id existed. It emits one `remove` per
5103
5114
  * group actually removed.
5104
5115
  * `seat` is the owning builder's silent bulk re-seat channel (used by `merge`).
5105
- * `destroy()` is idempotent and tears the emitter down LAST; any other call
5116
+ * `destroy()` is idempotent and tears the emitter down last; any other call
5106
5117
  * after it throws `ReasonError('DESTROYED', …)`.
5107
5118
  *
5108
5119
  * @example
@@ -5181,16 +5192,16 @@ var GroupManager = class {
5181
5192
  * kind-free manager over an inferential definition's `inferences`.
5182
5193
  *
5183
5194
  * @remarks
5184
- * OWNS its `inferences` as a private {@link Collection} — copy-on-write state
5195
+ * Owns its `inferences` as a private {@link Collection} — copy-on-write state
5185
5196
  * shared by composition with the other list managers — plus its own
5186
5197
  * {@link Emitter} over {@link InferenceManagerEventMap}. Inference order is
5187
- * LOAD-BEARING — backward proving iterates in declaration order and returns on
5188
- * first success. `remove` is the batch family (array form declared FIRST): no
5198
+ * load-bearing — backward proving iterates in declaration order and returns on
5199
+ * first success. `remove` is the batch family (array form declared first): no
5189
5200
  * argument removes every inference, one id removes that inference, an id list
5190
5201
  * removes those inferences and returns true only when every named id existed.
5191
5202
  * It emits one `remove` per inference actually removed.
5192
5203
  * `seat` is the owning builder's silent bulk re-seat channel
5193
- * (used by `merge`). `destroy()` is idempotent and tears the emitter down LAST;
5204
+ * (used by `merge`). `destroy()` is idempotent and tears the emitter down last;
5194
5205
  * any other call after it throws `ReasonError('DESTROYED', …)`.
5195
5206
  *
5196
5207
  * @example
@@ -5279,17 +5290,17 @@ var InferenceManager = class {
5279
5290
  * manager over a logical definition's `rules`.
5280
5291
  *
5281
5292
  * @remarks
5282
- * OWNS its `rules` as a private {@link Collection} — copy-on-write state shared
5293
+ * Owns its `rules` as a private {@link Collection} — copy-on-write state shared
5283
5294
  * by composition with the other list managers — plus its own {@link Emitter}
5284
- * over {@link RuleManagerEventMap}. Rule order is LOAD-BEARING — the forward
5285
- * conclusion is the LAST declared non-disabled rule, so `append` without a
5295
+ * over {@link RuleManagerEventMap}. Rule order is load-bearing — the forward
5296
+ * conclusion is the last declared non-disabled rule, so `append` without a
5286
5297
  * `target` makes the new rule the conclusion. `remove` is the batch family
5287
- * (array form declared FIRST): no argument removes every rule, one id removes
5298
+ * (array form declared first): no argument removes every rule, one id removes
5288
5299
  * that rule, an id list removes those rules and returns true only when every
5289
5300
  * named id existed. It emits one `remove` per rule actually removed. `seat` is
5290
5301
  * the owning builder's
5291
5302
  * silent bulk re-seat channel (used by `merge`). `destroy()` is idempotent and
5292
- * tears the emitter down LAST; any other call after it throws
5303
+ * tears the emitter down last; any other call after it throws
5293
5304
  * `ReasonError('DESTROYED', …)`.
5294
5305
  *
5295
5306
  * @example
@@ -5371,17 +5382,17 @@ var RuleManager = class {
5371
5382
  * unordered record.
5372
5383
  *
5373
5384
  * @remarks
5374
- * OWNS its `#variables` record as private copy-on-write state and its own
5385
+ * Owns its `#variables` record as private copy-on-write state and its own
5375
5386
  * {@link Emitter} over {@link VariableManagerEventMap}. The record has no
5376
5387
  * placement, so only `add` / `remove` exist (no `append` / `prepend`): `add`
5377
5388
  * upserts and emits `add(name)`, `remove` omits the key entirely (never sets
5378
5389
  * `undefined`) and emits `remove(name)`. `remove` is the batch family over
5379
- * NAMES (array form declared FIRST): no argument removes every variable, one
5390
+ * names (array form declared first): no argument removes every variable, one
5380
5391
  * name removes that variable, a name list removes those variables and returns
5381
5392
  * true only when every named variable existed. It emits one `remove` per
5382
5393
  * variable actually removed. `seat` is the owning builder's silent
5383
5394
  * bulk re-seat channel (used by `merge`). `destroy()` is idempotent and tears
5384
- * the emitter down LAST; any other call after it throws
5395
+ * the emitter down last; any other call after it throws
5385
5396
  * `ReasonError('DESTROYED', …)`.
5386
5397
  *
5387
5398
  * @example
@@ -5462,22 +5473,22 @@ var VariableManager = class {
5462
5473
  //#region src/core/builders/DefinitionBuilder.ts
5463
5474
  /**
5464
5475
  * Implements a stateful workspace builder accumulating a {@link Definition}
5465
- * through always-present self-owning manager properties: a private SCALAR
5466
- * ENVELOPE (reasoning / id / name plus the kind's scalars) composed with each
5476
+ * through always-present self-owning manager properties: a private scalar
5477
+ * envelope (reasoning / id / name plus the kind's scalars) composed with each
5467
5478
  * collection read from its manager.
5468
5479
  *
5469
5480
  * @remarks
5470
- * Each manager is BRING-YOUR-OWN (a supplied one is reused) or a fresh one
5471
- * seeded from the seed's matching collection (empty for off-kind collections).
5472
- * Managers are KIND-FREE — an off-kind manager is ignored by `build()`,
5473
- * never a `MISMATCH`. `build()` is TOTAL, deterministic, and returns a FRESH
5474
- * plain {@link Definition} each call. `merge(incoming)` requires the SAME
5481
+ * Each manager is the one the caller supplies, or a fresh one seeded from the
5482
+ * seed's matching collection (empty for off-kind collections). Managers are
5483
+ * kind-free — `build()` ignores an off-kind manager, never a `MISMATCH`.
5484
+ * `build()` is total, deterministic, and returns a fresh plain
5485
+ * {@link Definition} each call. `merge(incoming)` requires the same
5475
5486
  * `reasoning` (else `MISMATCH`) and distributes incoming scalars into the
5476
5487
  * envelope and collections into the managers through the matching `merge*`
5477
5488
  * helper. `clear(key)` deletes one optional field of the envelope for the
5478
5489
  * instance's `reasoning` (a non-clearable key throws `MISMATCH`). `destroy()`
5479
5490
  * cascades to every manager, emits `destroy`, then tears the builder emitter
5480
- * down LAST; it is idempotent, and post-destroy mutation / build throws
5491
+ * down last; it is idempotent, and post-destroy mutation / build throws
5481
5492
  * `ReasonError('DESTROYED', …)`.
5482
5493
  *
5483
5494
  * @example
@@ -5659,27 +5670,26 @@ var DefinitionBuilder = class {
5659
5670
  * flat key-value collection, no managers.
5660
5671
  *
5661
5672
  * @remarks
5662
- * `id` is OPTIONAL (`options?.id ?? seed.id`). When present, the builder is
5673
+ * `id` is optional (`options?.id ?? seed.id`). When present, the builder is
5663
5674
  * id-ful: `build()` carries that `id` and `clear()` restores it. When absent,
5664
- * the builder is ANONYMOUS —
5665
- * `.id` is `undefined` and the accumulated subject carries no `id` key.
5666
- * `field(key)` / `fields()` are the singular / plural accessor pair over
5667
- * TOP-LEVEL keys only. `set(key, value)` delegates to `assignField`;
5668
- * `set('id', …)` throws `ReasonError('MISMATCH', …)` — id is immutable through the entity,
5669
- * id-ful or anonymous alike. `remove` is the batch family (array form
5670
- * declared first): no argument removes every non-id field and emits one
5671
- * `remove` per key in key order, one key removes that field, and a key list
5672
- * removes those fields. Removing `'id'` through a keyed form throws the same
5673
- * `MISMATCH` for the same reason. `merge(incoming)` delegates to `mergeSubjects`
5674
- * (incoming-wins, base `id` preserved — plain {@link Subject} data only).
5675
- * `clear()` removes every non-id field, restoring `{ id }` when id-ful or
5676
- * an empty record when anonymous. `repeat(count)` returns `count`
5677
- * deterministic minted-id clones as PLAIN payloads — a pure read that does
5678
- * NOT emit. `build(): Subject` is total, deterministic, and returns a fresh
5679
- * durable payload each call. Post-destroy mutation throws
5675
+ * the builder is anonymous — `.id` is `undefined` and the accumulated subject
5676
+ * carries no `id` key. `field(key)` / `fields()` are the singular / plural
5677
+ * accessor pair over top-level keys only. `set(key, value)` delegates to
5678
+ * `assignField`; setting `id` throws `ReasonError('MISMATCH', …)`, because the
5679
+ * id is immutable through the entity, id-ful or anonymous alike. `remove` is
5680
+ * the batch family (array form declared first): no argument removes every
5681
+ * non-id field and emits one `remove` per key in key order, one key removes
5682
+ * that field, and a key list removes those fields. Removing `'id'` through a
5683
+ * keyed form throws the same `MISMATCH` for the same reason. `merge(incoming)`
5684
+ * delegates to `mergeSubjects` (incoming-wins, base `id` preserved — plain
5685
+ * {@link Subject} data only). `clear()` removes every non-id field, restoring
5686
+ * `{ id }` when id-ful or an empty record when anonymous. `repeat(count)`
5687
+ * returns `count` deterministic minted-id clones as plain payloads — a pure
5688
+ * read that emits nothing. `build(): Subject` is total, deterministic, and
5689
+ * returns a fresh durable payload each call. Post-destroy mutation throws
5680
5690
  * `ReasonError('DESTROYED', …)` — only the `emitter` getter and `destroy`
5681
5691
  * itself keep working, mirroring `Reason`. `destroy()` is idempotent and
5682
- * tears the emitter down LAST.
5692
+ * tears the emitter down last.
5683
5693
  *
5684
5694
  * @example
5685
5695
  * ```ts
@@ -5688,7 +5698,7 @@ var DefinitionBuilder = class {
5688
5698
  * const applicant = createSubjectBuilder({ id: 'alice', age: 25 })
5689
5699
  * applicant.set('region', 'CA')
5690
5700
  * applicant.merge({ licensed: true, accidents: 0 }) // incoming wins, id kept
5691
- * applicant.remove(['accidents']) // batch form first — true when ALL existed
5701
+ * applicant.remove(['accidents']) // batch form first — true when every key existed
5692
5702
  * applicant.field('region') // 'CA'
5693
5703
  * applicant.fields() // the live record
5694
5704
  * applicant.repeat(2) // ids 'alice-0', 'alice-1'
@@ -5957,7 +5967,7 @@ function createInferentialReasoner(options) {
5957
5967
  *
5958
5968
  * @remarks
5959
5969
  * `reasoners` — the initial registry (a later entry of the same reasoning
5960
- * replaces an earlier one; the orchestrator ships with NO defaults). `bail` —
5970
+ * replaces an earlier one; the orchestrator ships with no defaults). `bail` —
5961
5971
  * `true` (the default) rethrows a reasoner throw after the `error` emit;
5962
5972
  * `false` converts it to a failure result. `validate` — validate every
5963
5973
  * definition before running it, throwing `INVALID` on failure (default
@@ -5967,16 +5977,32 @@ function createInferentialReasoner(options) {
5967
5977
  * @param options - Optional registry, policies, and emitter hooks
5968
5978
  * @returns A {@link ReasonInterface}
5969
5979
  *
5970
- * @example
5980
+ * @example Create an orchestrator and score a subject
5971
5981
  * ```ts
5972
- * import { createLogicalReasoner, createQuantitativeReasoner, createReason } from '@src/core'
5982
+ * import {
5983
+ * createFactorGroup,
5984
+ * createFieldFactor,
5985
+ * createQuantitativeDefinition,
5986
+ * createQuantitativeReasoner,
5987
+ * createReason,
5988
+ * createStaticFactor,
5989
+ * } from '@orkestrel/reason'
5973
5990
  *
5974
- * const reason = createReason({
5975
- * reasoners: [createQuantitativeReasoner(), createLogicalReasoner()],
5976
- * on: { reason: (result) => console.log(result.success) },
5977
- * })
5978
- * const result = reason.reason({ age: 25 }, definition)
5979
- * reason.destroy()
5991
+ * const reason = createReason({ reasoners: [createQuantitativeReasoner()] })
5992
+ *
5993
+ * const definition = createQuantitativeDefinition('risk', 'Risk score', [
5994
+ * createFactorGroup('drivers', 'sum', [
5995
+ * createFieldFactor('age', 'age'), // reads subject.age, parseNumber-coerced
5996
+ * createStaticFactor('floor', 10), // a fixed contribution
5997
+ * ]),
5998
+ * ])
5999
+ *
6000
+ * const result = reason.reason({ age: 25 }, definition) // one subject → one result
6001
+ * if (result.reasoning === 'quantitative') result.value // 35 — narrow by the discriminant
6002
+ * result.trace // the step-by-step account of how the value came to be
6003
+ *
6004
+ * reason.supports('quantitative') // true — a reasoner is registered for this reasoning
6005
+ * reason.reasoner('quantitative')?.supports(definition) // the reasoner's own guard, same check
5980
6006
  * ```
5981
6007
  */
5982
6008
  function createReason(options) {
@@ -5988,15 +6014,14 @@ function createReason(options) {
5988
6014
  * `variables`, `facts`, and `inferences` self-owning manager properties.
5989
6015
  *
5990
6016
  * @remarks
5991
- * `id`. Default: `seed.id`. Each manager slot is BRING-YOUR-OWN (a supplied
5992
- * one is reused, else a fresh one is seeded from the seed's matching
5993
- * collection). `on` — initial event listeners. `error` — the emitter's
5994
- * listener-error handler. Mutate through the manager
5995
- * properties (`groups` / `factors` / `rules` / `equations` / `variables` /
5996
- * `facts` / `inferences`) and `merge` / `clear`, then call `build()` to produce
5997
- * a fresh, plain {@link Definition} snapshot.
5998
- *
5999
- * @param seed - The starting definition (any of the four reasoning kinds)
6017
+ * `id`. Default: `seed.id`. Each manager slot takes the manager the caller
6018
+ * supplies, or a fresh one seeded from the seed's matching collection. `on` —
6019
+ * initial event listeners. `error` — the emitter's listener-error handler.
6020
+ * Mutate through the manager properties (`groups` / `factors` / `rules` /
6021
+ * `equations` / `variables` / `facts` / `inferences`) and `merge` / `clear`,
6022
+ * then call `build()` to produce a fresh, plain {@link Definition} snapshot.
6023
+ *
6024
+ * @param seed - The starting definition, of any reasoning
6000
6025
  * @param options - Optional `id` override, manager injections, and emitter hooks
6001
6026
  * @returns A {@link DefinitionBuilderInterface}
6002
6027
  *
@@ -6018,8 +6043,8 @@ function createDefinitionBuilder(seed, options) {
6018
6043
  * {@link Subject}.
6019
6044
  *
6020
6045
  * @remarks
6021
- * `id`. Default: `seed.id`; OPTIONAL — when neither `options.id` nor
6022
- * a string `seed.id` is present the builder is ANONYMOUS (`.id` is
6046
+ * `id`. Default: `seed.id`; it is optional — when neither `options.id` nor
6047
+ * a string `seed.id` is present the builder is anonymous (`.id` is
6023
6048
  * `undefined`, `build()` emits no `id` key). `on` — initial event listeners.
6024
6049
  * `error` — the emitter's listener-error handler.
6025
6050
  * Mutate through `set` / `remove` / `merge` / `clear`, then call `build()` to
@@ -6203,7 +6228,7 @@ function createInferenceManager(options) {
6203
6228
  /**
6204
6229
  * Creates a {@link Check} — one field predicate.
6205
6230
  *
6206
- * @param field - The subject field to resolve (a string is ONE key; an array descends)
6231
+ * @param field - The subject field to resolve (a string is a single key; an array descends)
6207
6232
  * @param operator - The comparison to apply
6208
6233
  * @param value - The expected value (any type — the operator decides what is meaningful)
6209
6234
  * @returns A fresh check
@@ -6273,7 +6298,7 @@ function createCompound(operator, operands) {
6273
6298
  * `enabled` through `overrides`.
6274
6299
  *
6275
6300
  * @param id - The rule id
6276
- * @param premises - The expressions that must ALL hold
6301
+ * @param premises - The expressions that must all hold
6277
6302
  * @param conclusion - The expression whose atoms are asserted when they do
6278
6303
  * @param overrides - Optional {@link Rule} fields merged over the defaults
6279
6304
  * @returns A fresh rule
@@ -6298,7 +6323,7 @@ function createRule(id, premises, conclusion, overrides) {
6298
6323
  * Creates a {@link Transform} — one math step.
6299
6324
  *
6300
6325
  * @remarks
6301
- * The `operand` key is OMITTED when absent (never set to `undefined`), so the
6326
+ * The `operand` key is omitted when absent (never set to `undefined`), so the
6302
6327
  * transform stays exact-record valid; the transformer then applies its
6303
6328
  * per-operation default (`1` for `multiply` / `divide` / `power`, `0` otherwise).
6304
6329
  *
@@ -6324,7 +6349,7 @@ function createTransform(operator, operand) {
6324
6349
  * Creates a {@link Bounds} — an inclusive numeric clamp.
6325
6350
  *
6326
6351
  * @remarks
6327
- * Absent sides are OMITTED (never set to `undefined`) — an absent bound is
6352
+ * Absent sides are omitted (never set to `undefined`) — an absent bound is
6328
6353
  * unbounded on that side.
6329
6354
  *
6330
6355
  * @param minimum - The inclusive lower bound
@@ -6387,7 +6412,7 @@ function createConstant(value) {
6387
6412
  * Creates an operation {@link SymbolicExpression} node.
6388
6413
  *
6389
6414
  * @remarks
6390
- * The `right` key is OMITTED when absent — correct for the unary operations
6415
+ * The `right` key is omitted when absent — correct for the unary operations
6391
6416
  * (`round` / `ceil` / `floor` / `abs`); a binary operation with no `right`
6392
6417
  * treats it as the constant `0`.
6393
6418
  *
@@ -6484,7 +6509,7 @@ function createFact(id, predicate, terms, confidence) {
6484
6509
  * `enabled` through `overrides`.
6485
6510
  *
6486
6511
  * @param id - The inference id
6487
- * @param premises - The fact patterns that must ALL unify
6512
+ * @param premises - The fact patterns that must all unify
6488
6513
  * @param conclusion - The fact pattern derived when they do
6489
6514
  * @param overrides - Optional {@link Inference} fields merged over the defaults
6490
6515
  * @returns A fresh inference