@orkestrel/reason 0.0.1
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/LICENSE +21 -0
- package/README.md +74 -0
- package/dist/src/core/index.cjs +6087 -0
- package/dist/src/core/index.cjs.map +1 -0
- package/dist/src/core/index.d.cts +4852 -0
- package/dist/src/core/index.d.ts +4852 -0
- package/dist/src/core/index.js +5912 -0
- package/dist/src/core/index.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["#reasoners","#bail","#validate","#emitter","#ensureAlive","#reasonOne","#destroyed","#id","#compare","#isBetween","#id","#id","#empty","#id","#evaluator","#transformer","#aggregator","#evaluateGroup","#evaluateFactor","#resolveSource","#id","#evaluator","#backward","#forward","#evaluateRule","#establish","#evaluateExpression","#proveExpression","#id","#solve","#evaluate","#isolate","#id","#backward","#forward","#findAllBindings","#calculatePremiseConfidence","#prove","#emitter","#equations","#ensureAlive","#destroyed","#emitter","#facts","#ensureAlive","#destroyed","#groups","#emitter","#ensureAlive","#locate","#destroyed","#emitter","#groups","#ensureAlive","#destroyed","#emitter","#inferences","#ensureAlive","#destroyed","#emitter","#rules","#ensureAlive","#destroyed","#emitter","#variables","#ensureAlive","#destroyed","#id","#emitter","#envelope","#strip","#ensureAlive","#compose","#seat","#isQuantitativeClearKey","#isLogicalClearKey","#isSymbolicClearKey","#isInferentialClearKey","#destroyed","#id","#emitter","#subject","#ensureAlive","#ensureNotId","#removeOne","#destroyed"],"sources":["../../../src/core/constants.ts","../../../src/core/errors.ts","../../../src/core/validators.ts","../../../src/core/helpers.ts","../../../src/core/Reason.ts","../../../src/core/operators/Evaluator.ts","../../../src/core/operators/Transformer.ts","../../../src/core/operators/Aggregator.ts","../../../src/core/reasoners/QuantitativeReasoner.ts","../../../src/core/reasoners/LogicalReasoner.ts","../../../src/core/reasoners/SymbolicReasoner.ts","../../../src/core/reasoners/InferentialReasoner.ts","../../../src/core/builders/managers/EquationManager.ts","../../../src/core/builders/managers/FactManager.ts","../../../src/core/builders/managers/FactorManager.ts","../../../src/core/builders/managers/GroupManager.ts","../../../src/core/builders/managers/InferenceManager.ts","../../../src/core/builders/managers/RuleManager.ts","../../../src/core/builders/managers/VariableManager.ts","../../../src/core/builders/DefinitionBuilder.ts","../../../src/core/builders/SubjectBuilder.ts","../../../src/core/factories.ts"],"sourcesContent":["import type { MathOperation } from './types.js'\n\n// Frozen default data for the reasons module (AGENTS §5 — constants are\n// UPPER_SNAKE_CASE data, the sole home for module-scope literal defaults).\n\n/**\n * Default `bail` for the `Reason` orchestrator — a reasoner throw is rethrown\n * after the `error` emit.\n *\n * @remarks\n * Named with the domain qualifier so the generic `DEFAULT_BAIL` stays free for\n * other modules' bail defaults on the shared `@src/core` barrel.\n */\nexport const DEFAULT_REASON_BAIL = true\n\n/** Default `validate` for the `Reason` orchestrator — per-call validation is skipped. */\nexport const DEFAULT_VALIDATE = false\n\n/**\n * Default `depth` for chaining definitions — the forward-iteration /\n * backward-recursion cap of the logical and inferential reasoners.\n */\nexport const DEFAULT_DEPTH = 10\n\n/** Default `base` added before aggregation, at both group and definition level. */\nexport const DEFAULT_BASE = 0\n\n/** Default `precision` (decimal places) for quantitative values and symbolic solutions. */\nexport const DEFAULT_PRECISION = 4\n\n/** Default `confidence` for facts, inferences, and injected subject facts. */\nexport const DEFAULT_CONFIDENCE = 1\n\n/** Default factor `weight` at group aggregation. */\nexport const DEFAULT_WEIGHT = 1\n\n/** Default factor / rule `priority` — evaluation order is ascending and stable. */\nexport const DEFAULT_PRIORITY = 0\n\n/**\n * Decimal places a derived fact's confidence is rounded to during forward\n * inferential chaining.\n *\n * @remarks\n * Fixed — unlike {@link DEFAULT_PRECISION} it is NOT overridable per\n * definition, so confidence products stay comparable across derivations.\n */\nexport const CONFIDENCE_PRECISION = 4\n\n/**\n * The math operations the symbolic reasoner can invert while isolating a\n * target variable — anything else (a `power`, an `abs`) fails the equation\n * with a non-invertible error.\n */\nexport const INVERTIBLE_OPERATIONS: ReadonlySet<MathOperation> = Object.freeze(\n\tnew Set<MathOperation>(['add', 'subtract', 'multiply', 'divide']),\n)\n\n/** Default `id` for an `Evaluator`. */\nexport const EVALUATOR_ID = 'evaluator'\n\n/** Default `id` for a `Transformer`. */\nexport const TRANSFORMER_ID = 'transformer'\n\n/** Default `id` for an `Aggregator`. */\nexport const AGGREGATOR_ID = 'aggregator'\n\n/** Default `id` for a `QuantitativeReasoner`. */\nexport const QUANTITATIVE_ID = 'quantitative'\n\n/** Default `id` for a `LogicalReasoner`. */\nexport const LOGICAL_ID = 'logical'\n\n/** Default `id` for a `SymbolicReasoner`. */\nexport const SYMBOLIC_ID = 'symbolic'\n\n/** Default `id` for an `InferentialReasoner`. */\nexport const INFERENTIAL_ID = 'inferential'\n\n/**\n * The `DefinitionBuilder` entity brand — a `unique symbol` key carrying\n * `readonly true` on every `DefinitionBuilderInterface` instance.\n *\n * @remarks\n * Only `isDefinitionBuilder` (`validators.ts`) reads this key, via\n * `Reflect.get`. A module-owned `unique symbol` cannot be produced by\n * `JSON.parse` or written by any consumer that does not import this constant,\n * so plain data can never forge the brand.\n */\nexport const DEFINITION_BUILDER_BRAND: unique symbol = Symbol('reasons.definitionBuilder')\n\n/**\n * The `SubjectBuilder` entity brand — a `unique symbol` key carrying\n * `readonly true` on every `SubjectBuilderInterface` instance.\n *\n * @remarks\n * Only `isSubjectBuilder` (`validators.ts`) reads this key, via `Reflect.get`.\n * Distinct from {@link DEFINITION_BUILDER_BRAND}, so the two entities can never\n * match each other's guard.\n */\nexport const SUBJECT_BUILDER_BRAND: unique symbol = Symbol('reasons.subjectBuilder')\n","import type { ReasonErrorCode } from './types.js'\n\n// AGENTS §12: misuse of the reasons layer `throw`s a `ReasonError` carrying a\n// machine-readable `code`, so a `catch` branches on `error.code`.\n\n/**\n * An error thrown by the reasons layer.\n *\n * @remarks\n * Thrown for: dispatching a definition no registered reasoner handles\n * (`MISSING`), a pre-run validation failure when the orchestrator's `validate`\n * option is on (`INVALID`), handing a reasoner a definition of a different\n * reasoning (`MISMATCH`), any use of a destroyed orchestrator (`DESTROYED`),\n * and an `appendById` / `prependById` (or per-kind `append*` / `prepend*`)\n * `target` id naming no existing element (`TARGET`). `context`, when present,\n * carries the definition id and the reasoning involved (or, for `TARGET`, the\n * offending `id` / `target`).\n */\nexport class ReasonError extends Error {\n\treadonly code: ReasonErrorCode\n\treadonly context?: Readonly<Record<string, unknown>>\n\n\tconstructor(code: ReasonErrorCode, message: string, context?: Readonly<Record<string, unknown>>) {\n\t\tsuper(message)\n\t\tthis.name = 'ReasonError'\n\t\tthis.code = code\n\t\tthis.context = context\n\t}\n}\n\n/**\n * Narrow an unknown caught value to a {@link ReasonError}.\n *\n * @param value - The value to test (typically a `catch` binding)\n * @returns `true` when `value` is a {@link ReasonError}\n *\n * @example\n * ```ts\n * try {\n * \treason.reason(subject, definition)\n * } catch (error) {\n * \tif (isReasonError(error) && error.code === 'MISSING') registerFallback()\n * }\n * ```\n */\nexport function isReasonError(value: unknown): value is ReasonError {\n\treturn value instanceof ReasonError\n}\n","import type { FieldPath, Guard } from '@orkestrel/contract'\nimport type {\n\tAggregation,\n\tBounds,\n\tChainingStrategy,\n\tCheck,\n\tComparison,\n\tDefinition,\n\tDefinitionBuilderInterface,\n\tEquation,\n\tExpression,\n\tFact,\n\tFactor,\n\tFactorGroup,\n\tFactorRange,\n\tInference,\n\tInferentialDefinition,\n\tLogicalDefinition,\n\tLogicalOperator,\n\tMathOperation,\n\tQuantitativeDefinition,\n\tReasoning,\n\tRule,\n\tSource,\n\tSubjectBuilderInterface,\n\tSymbolicDefinition,\n\tSymbolicExpression,\n\tTransform,\n} from './types.js'\nimport {\n\tarrayOf,\n\tisArray,\n\tisBoolean,\n\tisFiniteNumber,\n\tisObject,\n\tisRecord,\n\tisString,\n\tlazyOf,\n\tliteralOf,\n\tnotOf,\n\torOf,\n\trecordOf,\n\tunionOf,\n\twhereOf,\n} from '@orkestrel/contract'\nimport { DEFINITION_BUILDER_BRAND, SUBJECT_BUILDER_BRAND } from './constants.js'\n\n// AGENTS §14: every guard here is a TOTAL function — adversarial input (junk,\n// hostile prototypes, deep nesting) returns `false`, never throws. All guards\n// compose the contracts combinators; the two recursive shapes (`isExpression`,\n// `isSymbolicExpression`) recurse through `lazyOf`, the sanctioned recursion\n// entry point (a pathologically deep or cyclic input is contained, reporting a\n// non-match). Record guards are EXACT (`recordOf`): an extra key fails, so a\n// definition that drifted from its declared shape is rejected loudly. Numeric\n// definition fields guard with `isFiniteNumber` — JSON cannot carry `NaN` /\n// `±Infinity`, so a non-finite number marks a corrupted definition. The one\n// unconstrained field (`Check.value`, legitimately ANY value including `null`)\n// uses the trivially-true guard `notOf(unionOf())` — `unionOf()` of zero guards\n// is always-false, its negation always-true. Record-shape guards take the\n// declared-predicate function form (the `recordOf` shape inlined per call, so\n// no non-exported member lingers — §5; terminals precedent).\n\n/**\n * Determine whether a value is a {@link Reasoning} literal.\n *\n * @param value - The value to test\n * @returns `true` when `value` is one of the four reasoning strategies\n *\n * @example\n * ```ts\n * import { isReasoning } from '@src/core'\n *\n * isReasoning('logical') // true\n * isReasoning('fuzzy') // false\n * ```\n */\nexport const isReasoning: Guard<Reasoning> = literalOf(\n\t'quantitative',\n\t'logical',\n\t'symbolic',\n\t'inferential',\n)\n\n/**\n * Determine whether a value is a {@link ChainingStrategy} literal.\n *\n * @param value - The value to test\n * @returns `true` when `value` is `'forward'` or `'backward'`\n *\n * @example\n * ```ts\n * import { isChainingStrategy } from '@src/core'\n *\n * isChainingStrategy('forward') // true\n * isChainingStrategy('upward') // false\n * ```\n */\nexport const isChainingStrategy: Guard<ChainingStrategy> = literalOf('forward', 'backward')\n\n/**\n * Determine whether a value is a {@link MathOperation} literal.\n *\n * @param value - The value to test\n * @returns `true` when `value` is one of the thirteen math operations\n *\n * @example\n * ```ts\n * import { isMathOperation } from '@src/core'\n *\n * isMathOperation('multiply') // true\n * isMathOperation('modulo') // false\n * ```\n */\nexport const isMathOperation: Guard<MathOperation> = literalOf(\n\t'add',\n\t'subtract',\n\t'multiply',\n\t'divide',\n\t'percentage',\n\t'minimum',\n\t'maximum',\n\t'average',\n\t'power',\n\t'round',\n\t'ceil',\n\t'floor',\n\t'abs',\n)\n\n/**\n * Determine whether a value is an {@link Aggregation} literal.\n *\n * @param value - The value to test\n * @returns `true` when `value` is one of the five aggregations\n *\n * @example\n * ```ts\n * import { isAggregation } from '@src/core'\n *\n * isAggregation('sum') // true\n * isAggregation('median') // false\n * ```\n */\nexport const isAggregation: Guard<Aggregation> = literalOf(\n\t'sum',\n\t'product',\n\t'average',\n\t'minimum',\n\t'maximum',\n)\n\n/**\n * Determine whether a value is a {@link Comparison} literal.\n *\n * @param value - The value to test\n * @returns `true` when `value` is one of the ten comparison operators\n *\n * @example\n * ```ts\n * import { isComparison } from '@src/core'\n *\n * isComparison('between') // true\n * isComparison('greaterThan') // false — the operator vocabulary is single-word\n * ```\n */\nexport const isComparison: Guard<Comparison> = literalOf(\n\t'equals',\n\t'not',\n\t'above',\n\t'below',\n\t'from',\n\t'to',\n\t'any',\n\t'none',\n\t'between',\n\t'outside',\n)\n\n/**\n * Determine whether a value is a {@link LogicalOperator} literal.\n *\n * @param value - The value to test\n * @returns `true` when `value` is one of the five logical connectives\n *\n * @example\n * ```ts\n * import { isLogicalOperator } from '@src/core'\n *\n * isLogicalOperator('implies') // true\n * isLogicalOperator('nand') // false\n * ```\n */\nexport const isLogicalOperator: Guard<LogicalOperator> = literalOf(\n\t'and',\n\t'or',\n\t'not',\n\t'implies',\n\t'xor',\n)\n\n/**\n * Determine whether a value is a {@link FieldPath} — a single string key or an\n * array of keys descending into nested objects.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a string or an array of strings\n *\n * @example\n * ```ts\n * import { isFieldPath } from '@src/core'\n *\n * isFieldPath('age') // true — ONE key (never dot-split)\n * isFieldPath(['address', 'city']) // true — descends\n * isFieldPath(42) // false\n * ```\n */\nexport const isFieldPath: Guard<FieldPath> = orOf(isString, arrayOf(isString))\n\n/**\n * Determine whether a value is a `Subject` — a plain record of fields to reason\n * about.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a plain record (arrays and class instances fail)\n *\n * @example\n * ```ts\n * import { isSubject } from '@src/core'\n *\n * isSubject({ age: 30 }) // true\n * isSubject([1, 2, 3]) // false — an array is not a subject\n * ```\n */\nexport const isSubject: Guard<Readonly<Record<string, unknown>>> = isRecord\n\n/**\n * Determine whether a value is a record whose every value is a finite number —\n * the shape of a `LookupSource.table` and a `SymbolicDefinition.variables`.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a plain record of finite numbers\n *\n * @example\n * ```ts\n * import { isNumberRecord } from '@src/core'\n *\n * isNumberRecord({ CA: 1.2, NY: 0.8 }) // true\n * isNumberRecord({ CA: '1.2' }) // false — strings do not coerce here\n * ```\n */\nexport const isNumberRecord: Guard<Readonly<Record<string, number>>> = whereOf(\n\tisRecord,\n\t(record): record is Record<string, number> => Object.values(record).every(isFiniteNumber),\n)\n\n/**\n * Determine whether a value is a {@link Check} — a field / operator / value\n * predicate.\n *\n * @remarks\n * `value` may be ANYTHING (including `null` / `undefined`) but the key must be\n * PRESENT — exact-record semantics reject a check that lost its `value` key.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed check\n *\n * @example\n * ```ts\n * import { isCheck } from '@src/core'\n *\n * isCheck({ field: 'age', operator: 'above', value: 18 }) // true\n * isCheck({ field: 'age', operator: 'over', value: 18 }) // false — unknown operator\n * ```\n */\nexport function isCheck(value: unknown): value is Check {\n\treturn recordOf({\n\t\tfield: isFieldPath,\n\t\toperator: isComparison,\n\t\tvalue: notOf(unionOf()),\n\t})(value)\n}\n\n/**\n * Determine whether a value is a {@link Transform} — one math step.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed transform\n *\n * @example\n * ```ts\n * import { isTransform } from '@src/core'\n *\n * isTransform({ operation: 'multiply', operand: 2 }) // true\n * isTransform({ operation: 'round' }) // true — operand is optional\n * isTransform({ operation: 'multiply', by: 2 }) // false — extra key\n * ```\n */\nexport function isTransform(value: unknown): value is Transform {\n\treturn recordOf({ operation: isMathOperation, operand: isFiniteNumber }, ['operand'])(value)\n}\n\n/**\n * Determine whether a value is a {@link Bounds} — an inclusive numeric clamp.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed bounds record (both sides optional)\n *\n * @example\n * ```ts\n * import { isBounds } from '@src/core'\n *\n * isBounds({ minimum: 0, maximum: 100 }) // true\n * isBounds({}) // true — unbounded\n * isBounds({ minimum: NaN }) // false — non-finite\n * ```\n */\nexport function isBounds(value: unknown): value is Bounds {\n\treturn recordOf({ minimum: isFiniteNumber, maximum: isFiniteNumber }, true)(value)\n}\n\n/**\n * Determine whether a value is a {@link FactorRange} — one band of a range\n * source.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed factor range\n *\n * @example\n * ```ts\n * import { isFactorRange } from '@src/core'\n *\n * isFactorRange({ bounds: { maximum: 25 }, value: 1.5 }) // true\n * isFactorRange({ value: 42 }) // true — a catch-all band\n * ```\n */\nexport function isFactorRange(value: unknown): value is FactorRange {\n\treturn recordOf({ bounds: isBounds, value: isFiniteNumber }, ['bounds'])(value)\n}\n\n/**\n * Determine whether a value is a {@link Source} — any of the four factor\n * sources, discriminated by `origin`.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed static / field / lookup / range source\n *\n * @example\n * ```ts\n * import { isSource } from '@src/core'\n *\n * isSource({ origin: 'static', value: 42 }) // true\n * isSource({ origin: 'lookup', field: 'state', table: { CA: 5 } }) // true\n * isSource({ origin: 'random' }) // false\n * ```\n */\nexport function isSource(value: unknown): value is Source {\n\treturn unionOf(\n\t\trecordOf({ origin: literalOf('static'), value: isFiniteNumber }),\n\t\trecordOf({ origin: literalOf('field'), field: isFieldPath }),\n\t\trecordOf({ origin: literalOf('lookup'), field: isFieldPath, table: isNumberRecord }),\n\t\trecordOf({ origin: literalOf('range'), field: isFieldPath, ranges: arrayOf(isFactorRange) }),\n\t)(value)\n}\n\n/**\n * Determine whether a value is a {@link Factor} — one scored input of a\n * quantitative group.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed factor\n *\n * @example\n * ```ts\n * import { isFactor } from '@src/core'\n *\n * isFactor({ id: 'age', name: 'Age', source: { origin: 'field', field: 'age' } }) // true\n * isFactor({ id: 'age', name: 'Age' }) // false — no source\n * ```\n */\nexport function isFactor(value: unknown): value is Factor {\n\treturn recordOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\tsource: isSource,\n\t\t\tfallback: isFiniteNumber,\n\t\t\tchecks: arrayOf(isCheck),\n\t\t\ttransforms: arrayOf(isTransform),\n\t\t\tbounds: isBounds,\n\t\t\tweight: isFiniteNumber,\n\t\t\tpriority: isFiniteNumber,\n\t\t\tenabled: isBoolean,\n\t\t\trequired: isBoolean,\n\t\t},\n\t\t[\n\t\t\t'description',\n\t\t\t'fallback',\n\t\t\t'checks',\n\t\t\t'transforms',\n\t\t\t'bounds',\n\t\t\t'weight',\n\t\t\t'priority',\n\t\t\t'enabled',\n\t\t\t'required',\n\t\t],\n\t)(value)\n}\n\n/**\n * Determine whether a value is a {@link FactorGroup} — a group of factors\n * aggregated into one value.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed factor group\n *\n * @example\n * ```ts\n * import { isFactorGroup, staticFactor } from '@src/core'\n *\n * isFactorGroup({ id: 'g1', name: 'g1', aggregation: 'sum', factors: [staticFactor('f1', 10)] }) // true\n * isFactorGroup({ id: 'g1', name: 'g1', aggregation: 'median', factors: [] }) // false\n * ```\n */\nexport function isFactorGroup(value: unknown): value is FactorGroup {\n\treturn recordOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\tfactors: arrayOf(isFactor),\n\t\t\taggregation: isAggregation,\n\t\t\tbase: isFiniteNumber,\n\t\t\tbounds: isBounds,\n\t\t\tenabled: isBoolean,\n\t\t\tstrict: isBoolean,\n\t\t},\n\t\t['description', 'base', 'bounds', 'enabled', 'strict'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is an {@link Expression} — a boolean expression\n * tree of atoms and compounds, discriminated by `form`.\n *\n * @remarks\n * Recursive through `lazyOf` (AGENTS §14) — recursion is STACK-BOUNDED, not\n * unbounded: nesting beyond the engine's stack budget (roughly 1000 levels)\n * and cyclic input are CONTAINED as `false`, never a throw. Input past that\n * bound is rejected, not validated.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed expression tree\n *\n * @example\n * ```ts\n * import { atom, compound, isExpression } from '@src/core'\n *\n * isExpression(atom('age', 'from', 18)) // true\n * isExpression(compound('and', [atom('age', 'from', 18)])) // true\n * isExpression({ form: 'compound', operator: 'and' }) // false — operands missing\n * ```\n */\nexport function isExpression(value: unknown): value is Expression {\n\treturn unionOf(\n\t\trecordOf({ form: literalOf('atom'), check: isCheck }),\n\t\trecordOf({\n\t\t\tform: literalOf('compound'),\n\t\t\toperator: isLogicalOperator,\n\t\t\toperands: arrayOf(lazyOf(() => isExpression)),\n\t\t}),\n\t)(value)\n}\n\n/**\n * Determine whether a value is a {@link Rule} — premises and a conclusion.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed rule\n *\n * @example\n * ```ts\n * import { atom, isRule, rule } from '@src/core'\n *\n * isRule(rule('adult', [atom('age', 'from', 18)], atom('adult', 'equals', true))) // true\n * isRule({ id: 'adult' }) // false\n * ```\n */\nexport function isRule(value: unknown): value is Rule {\n\treturn recordOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\tpremises: arrayOf(isExpression),\n\t\t\tconclusion: isExpression,\n\t\t\tpriority: isFiniteNumber,\n\t\t\tenabled: isBoolean,\n\t\t},\n\t\t['description', 'priority', 'enabled'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is a {@link SymbolicExpression} — an algebraic\n * expression tree of variables, constants, and operations, discriminated by\n * `form`.\n *\n * @remarks\n * Recursive through `lazyOf` (AGENTS §14) — recursion is STACK-BOUNDED, not\n * unbounded: nesting beyond the engine's stack budget (roughly 1000 levels)\n * and cyclic input are CONTAINED as `false`, never a throw. Input past that\n * bound is rejected, not validated.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed symbolic expression tree\n *\n * @example\n * ```ts\n * import { constant, isSymbolicExpression, operation, variable } from '@src/core'\n *\n * isSymbolicExpression(operation('add', variable('x'), constant(1))) // true\n * isSymbolicExpression({ form: 'variable' }) // false — name missing\n * ```\n */\nexport function isSymbolicExpression(value: unknown): value is SymbolicExpression {\n\treturn unionOf(\n\t\trecordOf({ form: literalOf('variable'), name: isString }),\n\t\trecordOf({ form: literalOf('constant'), value: isFiniteNumber }),\n\t\trecordOf(\n\t\t\t{\n\t\t\t\tform: literalOf('operation'),\n\t\t\t\toperator: isMathOperation,\n\t\t\t\tleft: lazyOf(() => isSymbolicExpression),\n\t\t\t\tright: lazyOf(() => isSymbolicExpression),\n\t\t\t},\n\t\t\t['right'],\n\t\t),\n\t)(value)\n}\n\n/**\n * Determine whether a value is an {@link Equation} — `left = right`, solved for\n * `target`.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed equation\n *\n * @example\n * ```ts\n * import { constant, equation, isEquation, variable } from '@src/core'\n *\n * isEquation(equation('e1', variable('x'), constant(42), 'x')) // true\n * isEquation({ id: 'e1', target: 'x' }) // false — sides missing\n * ```\n */\nexport function isEquation(value: unknown): value is Equation {\n\treturn recordOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\tleft: isSymbolicExpression,\n\t\t\tright: isSymbolicExpression,\n\t\t\ttarget: isString,\n\t\t},\n\t\t['description'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is a {@link Fact} — a predicate over positional\n * terms.\n *\n * @remarks\n * `terms` elements are unconstrained (`unknown`) — a `'?'`-prefixed string term\n * is a unification variable, anything else a constant.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed fact\n *\n * @example\n * ```ts\n * import { isFact } from '@src/core'\n *\n * isFact({ id: 'f1', predicate: 'human', terms: ['socrates'] }) // true\n * isFact({ id: 'f1', predicate: 'human' }) // false — terms missing\n * ```\n */\nexport function isFact(value: unknown): value is Fact {\n\treturn recordOf(\n\t\t{ id: isString, predicate: isString, terms: isArray, confidence: isFiniteNumber },\n\t\t['confidence'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is an {@link Inference} — premise patterns and a\n * conclusion pattern.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed inference\n *\n * @example\n * ```ts\n * import { fact, inference, isInference } from '@src/core'\n *\n * isInference(inference('mortal', [fact('p1', 'human', ['?x'])], fact('c1', 'mortal', ['?x']))) // true\n * isInference({ id: 'mortal' }) // false\n * ```\n */\nexport function isInference(value: unknown): value is Inference {\n\treturn recordOf(\n\t\t{\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\tpremises: arrayOf(isFact),\n\t\t\tconclusion: isFact,\n\t\t\tconfidence: isFiniteNumber,\n\t\t\tenabled: isBoolean,\n\t\t},\n\t\t['description', 'confidence', 'enabled'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is a {@link QuantitativeDefinition}.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed quantitative definition\n *\n * @example\n * ```ts\n * import { isQuantitativeDefinition, quantitativeDefinition } from '@src/core'\n *\n * isQuantitativeDefinition(quantitativeDefinition('risk', 'Risk', [])) // true\n * isQuantitativeDefinition({ reasoning: 'quantitative', id: 'risk' }) // false\n * ```\n */\nexport function isQuantitativeDefinition(value: unknown): value is QuantitativeDefinition {\n\treturn recordOf(\n\t\t{\n\t\t\treasoning: literalOf('quantitative'),\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\tgroups: arrayOf(isFactorGroup),\n\t\t\taggregation: isAggregation,\n\t\t\tbase: isFiniteNumber,\n\t\t\tbounds: isBounds,\n\t\t\tprecision: isFiniteNumber,\n\t\t},\n\t\t['description', 'base', 'bounds', 'precision'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is a {@link LogicalDefinition}.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed logical definition\n *\n * @example\n * ```ts\n * import { isLogicalDefinition, logicalDefinition } from '@src/core'\n *\n * isLogicalDefinition(logicalDefinition('eligibility', 'Eligibility', [])) // true\n * isLogicalDefinition({ reasoning: 'logical', id: 'eligibility' }) // false\n * ```\n */\nexport function isLogicalDefinition(value: unknown): value is LogicalDefinition {\n\treturn recordOf(\n\t\t{\n\t\t\treasoning: literalOf('logical'),\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\trules: arrayOf(isRule),\n\t\t\tstrategy: isChainingStrategy,\n\t\t\tdepth: isFiniteNumber,\n\t\t},\n\t\t['description', 'depth'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is a {@link SymbolicDefinition}.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed symbolic definition\n *\n * @example\n * ```ts\n * import { isSymbolicDefinition, symbolicDefinition } from '@src/core'\n *\n * isSymbolicDefinition(symbolicDefinition('rate', 'Rate', [])) // true\n * isSymbolicDefinition({ reasoning: 'symbolic', id: 'rate' }) // false\n * ```\n */\nexport function isSymbolicDefinition(value: unknown): value is SymbolicDefinition {\n\treturn recordOf(\n\t\t{\n\t\t\treasoning: literalOf('symbolic'),\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\tequations: arrayOf(isEquation),\n\t\t\tvariables: isNumberRecord,\n\t\t\tprecision: isFiniteNumber,\n\t\t},\n\t\t['description', 'precision'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is an {@link InferentialDefinition}.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed inferential definition\n *\n * @example\n * ```ts\n * import { inferentialDefinition, isInferentialDefinition } from '@src/core'\n *\n * isInferentialDefinition(inferentialDefinition('birds', 'Birds', [], [])) // true\n * isInferentialDefinition({ reasoning: 'inferential', id: 'birds' }) // false\n * ```\n */\nexport function isInferentialDefinition(value: unknown): value is InferentialDefinition {\n\treturn recordOf(\n\t\t{\n\t\t\treasoning: literalOf('inferential'),\n\t\t\tid: isString,\n\t\t\tname: isString,\n\t\t\tdescription: isString,\n\t\t\tinferences: arrayOf(isInference),\n\t\t\tfacts: arrayOf(isFact),\n\t\t\tstrategy: isChainingStrategy,\n\t\t\tdepth: isFiniteNumber,\n\t\t},\n\t\t['description', 'depth'],\n\t)(value)\n}\n\n/**\n * Determine whether a value is a {@link Definition} — any of the four\n * definition shapes, discriminated by `reasoning`.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed definition of any reasoning\n *\n * @example\n * ```ts\n * import { isDefinition, logicalDefinition } from '@src/core'\n *\n * isDefinition(logicalDefinition('eligibility', 'Eligibility', [])) // true\n * isDefinition({ reasoning: 'quantum' }) // false\n * ```\n */\nexport function isDefinition(value: unknown): value is Definition {\n\treturn (\n\t\tisQuantitativeDefinition(value) ||\n\t\tisLogicalDefinition(value) ||\n\t\tisSymbolicDefinition(value) ||\n\t\tisInferentialDefinition(value)\n\t)\n}\n\n/**\n * Determine whether a value is a `DefinitionBuilder` ENTITY — the brand-guarded\n * stateful workspace, not the plain {@link Definition} data union.\n *\n * @remarks\n * A `unique symbol` brand check (`Reflect.get`, AGENTS §14): a plain subject\n * is an open record whose values may legally be functions, so a\n * method-presence check (`typeof value.build === 'function'`) is FORGEABLE —\n * this guard is not. A module-owned `unique symbol` cannot be produced by\n * `JSON.parse` or written by any consumer that does not import\n * `DEFINITION_BUILDER_BRAND`, so plain data can never forge it. Total: a\n * non-object, a missing brand, or a hostile prototype all return `false`,\n * never throw.\n *\n * @param value - The value to test\n * @returns `true` when `value` carries the `DefinitionBuilder` entity brand\n *\n * @example\n * ```ts\n * import { createDefinitionBuilder, isDefinitionBuilder, quantitativeDefinition } from '@src/core'\n *\n * const definition = createDefinitionBuilder(quantitativeDefinition('risk', 'Risk', []))\n * isDefinitionBuilder(definition) // true\n * isDefinitionBuilder({ build: () => undefined }) // false — forged build field\n * isDefinitionBuilder(quantitativeDefinition('r', 'R', [])) // false — plain data, not the entity\n * ```\n */\nexport function isDefinitionBuilder(value: unknown): value is DefinitionBuilderInterface {\n\treturn isObject(value) && Reflect.get(value, DEFINITION_BUILDER_BRAND) === true\n}\n\n/**\n * Determine whether a value is a `SubjectBuilder` ENTITY — the brand-guarded\n * stateful workspace, not the plain {@link Subject} data record.\n *\n * @remarks\n * A `unique symbol` brand check (`Reflect.get`, AGENTS §14), distinct from\n * {@link isDefinitionBuilder} — the two entities can never match each other's\n * guard. Total: a non-object, a missing brand, or a hostile prototype all\n * return `false`, never throw.\n *\n * @param value - The value to test\n * @returns `true` when `value` carries the `SubjectBuilder` entity brand\n *\n * @example\n * ```ts\n * import { createSubjectBuilder, isSubjectBuilder } from '@src/core'\n *\n * const subject = createSubjectBuilder({ id: 's1', age: 30 })\n * isSubjectBuilder(subject) // true\n * isSubjectBuilder({ build: () => ({}) }) // false — forged build field\n * isSubjectBuilder({ id: 's1', age: 30 }) // false — plain data, not the entity\n * ```\n */\nexport function isSubjectBuilder(value: unknown): value is SubjectBuilderInterface {\n\treturn isObject(value) && Reflect.get(value, SUBJECT_BUILDER_BRAND) === true\n}\n","import type {\n\tAggregation,\n\tAtom,\n\tBounds,\n\tCheck,\n\tComparison,\n\tDefinition,\n\tEquation,\n\tExpression,\n\tFact,\n\tFactor,\n\tFactorGroup,\n\tFactorRange,\n\tInference,\n\tInferentialDefinition,\n\tLogicalDefinition,\n\tLogicalOperator,\n\tMathOperation,\n\tQuantitativeDefinition,\n\tReasonResult,\n\tRule,\n\tSource,\n\tSubject,\n\tSymbolicDefinition,\n\tSymbolicExpression,\n\tTransform,\n} from './types.js'\nimport type { FieldPath } from '@orkestrel/contract'\nimport { isString, parseJSONAs } from '@orkestrel/contract'\nimport { DEFAULT_CONFIDENCE, DEFAULT_PRIORITY } from './constants.js'\nimport { ReasonError } from './errors.js'\nimport { isDefinition } from './validators.js'\n\n// Pure builders for the declarative definition vocabulary, plus the module's\n// numeric helpers. Every builder returns a fresh, JSON-serializable value and\n// OMITS absent optional keys entirely (never sets them to `undefined`), so the\n// output round-trips through the exact-record validators (AGENTS §14). Builders\n// with an `overrides` bag spread it LAST — an override always wins over a\n// default (a `name` defaults to the `id` wherever a display name is required).\n\n// === Field display\n\n/**\n * Format a {@link FieldPath} for display — the single string key itself, or the\n * array segments joined with `.`.\n *\n * @remarks\n * Display-only: the joined form is how a field appears in traces and derived\n * overlays; it is NOT re-parsed into a path (a string stays ONE key).\n *\n * @param field - The field path to format\n * @returns The display string\n *\n * @example\n * ```ts\n * formatField('age') // 'age'\n * formatField(['address', 'city']) // 'address.city'\n * ```\n */\nexport function formatField(field: FieldPath): string {\n\treturn isString(field) ? field : field.join('.')\n}\n\n// === Checks & expressions\n\n/**\n * Build a {@link Check} — one field predicate.\n *\n * @param field - The subject field to resolve (a string is ONE key; an array descends)\n * @param operator - The comparison to apply\n * @param value - The expected value (any type — the operator decides what is meaningful)\n * @returns A fresh check\n *\n * @example\n * ```ts\n * import { check } from '@src/core'\n *\n * check('age', 'from', 18) // { field: 'age', operator: 'from', value: 18 }\n * ```\n */\nexport function check(field: FieldPath, operator: Comparison, value: unknown): Check {\n\treturn { field, operator, value }\n}\n\n/**\n * Build an atom {@link Expression} — a leaf wrapping one {@link Check}.\n *\n * @param field - The subject field to resolve\n * @param operator - The comparison to apply\n * @param value - The expected value\n * @returns A fresh atom expression\n *\n * @example\n * ```ts\n * import { atom } from '@src/core'\n *\n * atom('age', 'from', 18) // { form: 'atom', check: { field: 'age', operator: 'from', value: 18 } }\n * ```\n */\nexport function atom(field: FieldPath, operator: Comparison, value: unknown): Expression {\n\treturn { form: 'atom', check: check(field, operator, value) }\n}\n\n/**\n * Build a compound {@link Expression} — a logical connective over nested\n * operands.\n *\n * @param operator - The logical connective\n * @param operands - The nested expressions it combines\n * @returns A fresh compound expression\n *\n * @example\n * ```ts\n * import { atom, compound } from '@src/core'\n *\n * compound('and', [atom('age', 'from', 18), atom('state', 'equals', 'CA')])\n * ```\n */\nexport function compound(operator: LogicalOperator, operands: readonly Expression[]): Expression {\n\treturn { form: 'compound', operator, operands }\n}\n\n/**\n * Build a {@link Rule} — premises and a conclusion.\n *\n * @remarks\n * `name` defaults to the `id`; set `name`, `description`, `priority`, or\n * `enabled` through `overrides`.\n *\n * @param id - The rule id\n * @param premises - The expressions that must ALL hold\n * @param conclusion - The expression whose atoms are asserted when they do\n * @param overrides - Optional {@link Rule} fields merged over the defaults\n * @returns A fresh rule\n *\n * @example\n * ```ts\n * import { atom, rule } from '@src/core'\n *\n * rule('adult', [atom('age', 'from', 18)], atom('adult', 'equals', true), { priority: 1 })\n * ```\n */\nexport function rule(\n\tid: string,\n\tpremises: readonly Expression[],\n\tconclusion: Expression,\n\toverrides?: Partial<Omit<Rule, 'id' | 'premises' | 'conclusion'>>,\n): Rule {\n\treturn { id, name: id, premises, conclusion, ...overrides }\n}\n\n// === Transforms & bounds\n\n/**\n * Build a {@link Transform} — one math step.\n *\n * @remarks\n * The `operand` key is OMITTED when absent (never set to `undefined`), so the\n * transform stays exact-record valid; the transformer then applies its\n * per-operation default (`1` for `multiply` / `divide` / `power`, `0` otherwise).\n *\n * @param operation - The math operation to apply\n * @param operand - The operand (ignored by the unary operations)\n * @returns A fresh transform\n *\n * @example\n * ```ts\n * import { transform } from '@src/core'\n *\n * transform('multiply', 2) // { operation: 'multiply', operand: 2 }\n * transform('round') // { operation: 'round' }\n * ```\n */\nexport function transform(operation: MathOperation, operand?: number): Transform {\n\treturn operand === undefined ? { operation } : { operation, operand }\n}\n\n/**\n * Build a {@link Bounds} — an inclusive numeric clamp.\n *\n * @remarks\n * Absent sides are OMITTED (never set to `undefined`) — an absent bound is\n * unbounded on that side.\n *\n * @param minimum - The inclusive lower bound\n * @param maximum - The inclusive upper bound\n * @returns A fresh bounds record\n *\n * @example\n * ```ts\n * import { bounds } from '@src/core'\n *\n * bounds(0, 100) // { minimum: 0, maximum: 100 }\n * bounds(undefined, 100) // { maximum: 100 }\n * ```\n */\nexport function bounds(minimum?: number, maximum?: number): Bounds {\n\treturn {\n\t\t...(minimum === undefined ? {} : { minimum }),\n\t\t...(maximum === undefined ? {} : { maximum }),\n\t}\n}\n\n// === Symbolic expressions\n\n/**\n * Build a variable {@link SymbolicExpression} leaf.\n *\n * @param name - The variable name\n * @returns A fresh variable node\n *\n * @example\n * ```ts\n * import { variable } from '@src/core'\n *\n * variable('x') // { form: 'variable', name: 'x' }\n * ```\n */\nexport function variable(name: string): SymbolicExpression {\n\treturn { form: 'variable', name }\n}\n\n/**\n * Build a constant {@link SymbolicExpression} leaf.\n *\n * @param value - The fixed number\n * @returns A fresh constant node\n *\n * @example\n * ```ts\n * import { constant } from '@src/core'\n *\n * constant(42) // { form: 'constant', value: 42 }\n * ```\n */\nexport function constant(value: number): SymbolicExpression {\n\treturn { form: 'constant', value }\n}\n\n/**\n * Build an operation {@link SymbolicExpression} node.\n *\n * @remarks\n * The `right` key is OMITTED when absent — correct for the unary operations\n * (`round` / `ceil` / `floor` / `abs`); a binary operation with no `right`\n * treats it as the constant `0`.\n *\n * @param operator - The math operation\n * @param left - The left operand\n * @param right - The right operand (omit for unary operations)\n * @returns A fresh operation node\n *\n * @example\n * ```ts\n * import { constant, operation, variable } from '@src/core'\n *\n * operation('add', variable('x'), constant(1))\n * operation('abs', variable('x')) // unary — no right operand\n * ```\n */\n// A const (not a hoisted function declaration) so `transform`'s `operation`\n// parameter above — named for the Transform key it fills — does not shadow it.\nexport const operation = (\n\toperator: MathOperation,\n\tleft: SymbolicExpression,\n\tright?: SymbolicExpression,\n): SymbolicExpression => {\n\treturn right === undefined\n\t\t? { form: 'operation', operator, left }\n\t\t: { form: 'operation', operator, left, right }\n}\n\n/**\n * Build an {@link Equation} — `left = right`, solved for `target`.\n *\n * @remarks\n * `name` defaults to the `id`; set `name` or `description` through `overrides`.\n *\n * @param id - The equation id\n * @param left - The left side\n * @param right - The right side\n * @param target - The variable name to solve for\n * @param overrides - Optional {@link Equation} fields merged over the defaults\n * @returns A fresh equation\n *\n * @example\n * ```ts\n * import { constant, equation, operation, variable } from '@src/core'\n *\n * // 2x + 3 = 11 — solved for x\n * equation('e1', operation('add', operation('multiply', constant(2), variable('x')), constant(3)), constant(11), 'x')\n * ```\n */\nexport function equation(\n\tid: string,\n\tleft: SymbolicExpression,\n\tright: SymbolicExpression,\n\ttarget: string,\n\toverrides?: Partial<Omit<Equation, 'id' | 'left' | 'right' | 'target'>>,\n): Equation {\n\treturn { id, name: id, left, right, target, ...overrides }\n}\n\n// === Facts & inferences\n\n/**\n * Build a {@link Fact} — a predicate over positional terms.\n *\n * @remarks\n * `confidence` defaults to `1` (the key is always set). A string term starting\n * with `?` is a unification variable.\n *\n * @param id - The fact id\n * @param predicate - The predicate name\n * @param terms - The positional terms\n * @param confidence - The fact's confidence (`0–1`, defaults to `1`)\n * @returns A fresh fact\n *\n * @example\n * ```ts\n * import { fact } from '@src/core'\n *\n * fact('f1', 'human', ['socrates']) // confidence 1\n * fact('f2', 'laysEggs', ['tweety'], 0.9) // explicit confidence\n * ```\n */\nexport function fact(\n\tid: string,\n\tpredicate: string,\n\tterms: readonly unknown[],\n\tconfidence?: number,\n): Fact {\n\treturn { id, predicate, terms, confidence: confidence ?? DEFAULT_CONFIDENCE }\n}\n\n/**\n * Build an {@link Inference} — premise patterns and a conclusion pattern.\n *\n * @remarks\n * `name` defaults to the `id`; set `name`, `description`, `confidence`, or\n * `enabled` through `overrides`.\n *\n * @param id - The inference id\n * @param premises - The fact patterns that must ALL unify\n * @param conclusion - The fact pattern derived when they do\n * @param overrides - Optional {@link Inference} fields merged over the defaults\n * @returns A fresh inference\n *\n * @example\n * ```ts\n * import { fact, inference } from '@src/core'\n *\n * inference('mortal', [fact('p1', 'human', ['?x'])], fact('c1', 'mortal', ['?x']), { confidence: 0.8 })\n * ```\n */\nexport function inference(\n\tid: string,\n\tpremises: readonly Fact[],\n\tconclusion: Fact,\n\toverrides?: Partial<Omit<Inference, 'id' | 'premises' | 'conclusion'>>,\n): Inference {\n\treturn { id, name: id, premises, conclusion, ...overrides }\n}\n\n// === Sources\n\n/**\n * Build a static {@link Source} — a fixed number.\n *\n * @param value - The fixed value\n * @returns A fresh static source\n *\n * @example\n * ```ts\n * import { staticSource } from '@src/core'\n *\n * staticSource(42) // { origin: 'static', value: 42 }\n * ```\n */\nexport function staticSource(value: number): Source {\n\treturn { origin: 'static', value }\n}\n\n/**\n * Build a field {@link Source} — a subject field read as a number.\n *\n * @param field - The subject field to resolve\n * @returns A fresh field source\n *\n * @example\n * ```ts\n * import { fieldSource } from '@src/core'\n *\n * fieldSource(['profile', 'score']) // descends into nested objects\n * ```\n */\nexport function fieldSource(field: FieldPath): Source {\n\treturn { origin: 'field', field }\n}\n\n/**\n * Build a lookup {@link Source} — a subject field mapped through a table.\n *\n * @param field - The subject field to resolve (stringified into a table key)\n * @param table - The lookup table\n * @returns A fresh lookup source\n *\n * @example\n * ```ts\n * import { lookupSource } from '@src/core'\n *\n * lookupSource('state', { CA: 5, NY: 8, TX: 2 })\n * ```\n */\nexport function lookupSource(field: FieldPath, table: Readonly<Record<string, number>>): Source {\n\treturn { origin: 'lookup', field, table }\n}\n\n/**\n * Build a range {@link Source} — a numeric subject field banded through ordered\n * ranges (first match wins).\n *\n * @param field - The subject field to resolve as a number\n * @param ranges - The bands, scanned in order\n * @returns A fresh range source\n *\n * @example\n * ```ts\n * import { bounds, rangeSource } from '@src/core'\n *\n * rangeSource('age', [\n * \t{ bounds: bounds(undefined, 24), value: 30 },\n * \t{ bounds: bounds(25, 64), value: 15 },\n * \t{ bounds: bounds(65), value: 10 },\n * ])\n * ```\n */\nexport function rangeSource(field: FieldPath, ranges: readonly FactorRange[]): Source {\n\treturn { origin: 'range', field, ranges }\n}\n\n// === Factors, groups & definitions\n\n/**\n * Build a {@link Factor} over a static {@link Source}.\n *\n * @remarks\n * `name` defaults to the `id`; every other {@link Factor} field (checks,\n * transforms, bounds, weight, priority, enabled, required, fallback) comes\n * through `overrides`.\n *\n * @param id - The factor id\n * @param value - The fixed source value\n * @param overrides - Optional {@link Factor} fields merged over the defaults\n * @returns A fresh factor\n *\n * @example\n * ```ts\n * import { staticFactor } from '@src/core'\n *\n * staticFactor('base-rate', 10, { weight: 2 })\n * ```\n */\nexport function staticFactor(\n\tid: string,\n\tvalue: number,\n\toverrides?: Partial<Omit<Factor, 'id' | 'source'>>,\n): Factor {\n\treturn { id, name: id, source: staticSource(value), ...overrides }\n}\n\n/**\n * Build a {@link Factor} over a field {@link Source}.\n *\n * @param id - The factor id\n * @param field - The subject field to resolve as a number\n * @param overrides - Optional {@link Factor} fields merged over the defaults\n * @returns A fresh factor\n *\n * @example\n * ```ts\n * import { fieldFactor, transform } from '@src/core'\n *\n * fieldFactor('income-score', 'income', { transforms: [transform('divide', 1000)], fallback: 0 })\n * ```\n */\nexport function fieldFactor(\n\tid: string,\n\tfield: FieldPath,\n\toverrides?: Partial<Omit<Factor, 'id' | 'source'>>,\n): Factor {\n\treturn { id, name: id, source: fieldSource(field), ...overrides }\n}\n\n/**\n * Build a {@link Factor} over a lookup {@link Source}.\n *\n * @param id - The factor id\n * @param field - The subject field to resolve (stringified into a table key)\n * @param table - The lookup table\n * @param overrides - Optional {@link Factor} fields merged over the defaults\n * @returns A fresh factor\n *\n * @example\n * ```ts\n * import { lookupFactor } from '@src/core'\n *\n * lookupFactor('state-score', 'state', { CA: 5, NY: 8 }, { fallback: 1 })\n * ```\n */\nexport function lookupFactor(\n\tid: string,\n\tfield: FieldPath,\n\ttable: Readonly<Record<string, number>>,\n\toverrides?: Partial<Omit<Factor, 'id' | 'source'>>,\n): Factor {\n\treturn { id, name: id, source: lookupSource(field, table), ...overrides }\n}\n\n/**\n * Build a {@link Factor} over a range {@link Source}.\n *\n * @param id - The factor id\n * @param field - The subject field to resolve as a number\n * @param ranges - The bands, scanned in order (first match wins)\n * @param overrides - Optional {@link Factor} fields merged over the defaults\n * @returns A fresh factor\n *\n * @example\n * ```ts\n * import { bounds, rangeFactor } from '@src/core'\n *\n * rangeFactor('age-band', 'age', [{ bounds: bounds(undefined, 24), value: 30 }])\n * ```\n */\nexport function rangeFactor(\n\tid: string,\n\tfield: FieldPath,\n\tranges: readonly FactorRange[],\n\toverrides?: Partial<Omit<Factor, 'id' | 'source'>>,\n): Factor {\n\treturn { id, name: id, source: rangeSource(field, ranges), ...overrides }\n}\n\n/**\n * Build a {@link FactorGroup}.\n *\n * @remarks\n * `name` defaults to the `id`; set `name`, `description`, `base`, `bounds`,\n * `enabled`, or `strict` through `overrides`.\n *\n * @param id - The group id\n * @param aggregation - How the applied factors' values reduce to one\n * @param factors - The group's factors\n * @param overrides - Optional {@link FactorGroup} fields merged over the defaults\n * @returns A fresh factor group\n *\n * @example\n * ```ts\n * import { factorGroup, staticFactor } from '@src/core'\n *\n * factorGroup('g1', 'sum', [staticFactor('f1', 10)], { base: 100 })\n * ```\n */\nexport function factorGroup(\n\tid: string,\n\taggregation: Aggregation,\n\tfactors: readonly Factor[],\n\toverrides?: Partial<Omit<FactorGroup, 'id' | 'aggregation' | 'factors'>>,\n): FactorGroup {\n\treturn { id, name: id, aggregation, factors, ...overrides }\n}\n\n/**\n * Build a {@link QuantitativeDefinition}.\n *\n * @remarks\n * `aggregation` defaults to `'sum'`; set `aggregation`, `description`, `base`,\n * `bounds`, or `precision` through `overrides`.\n *\n * @param id - The definition id\n * @param name - The display name\n * @param groups - The factor groups\n * @param overrides - Optional {@link QuantitativeDefinition} fields merged over the defaults\n * @returns A fresh quantitative definition\n *\n * @example\n * ```ts\n * import { factorGroup, fieldFactor, quantitativeDefinition } from '@src/core'\n *\n * quantitativeDefinition('risk', 'Risk Score', [factorGroup('g1', 'sum', [fieldFactor('age', 'age')])], {\n * \tbase: 100,\n * })\n * ```\n */\nexport function quantitativeDefinition(\n\tid: string,\n\tname: string,\n\tgroups: readonly FactorGroup[],\n\toverrides?: Partial<Omit<QuantitativeDefinition, 'reasoning' | 'id' | 'name' | 'groups'>>,\n): QuantitativeDefinition {\n\treturn { reasoning: 'quantitative', id, name, groups, aggregation: 'sum', ...overrides }\n}\n\n/**\n * Build a {@link LogicalDefinition}.\n *\n * @remarks\n * `strategy` defaults to `'forward'`; set `strategy`, `description`, or `depth`\n * through `overrides`.\n *\n * @param id - The definition id\n * @param name - The display name\n * @param rules - The deduction rules\n * @param overrides - Optional {@link LogicalDefinition} fields merged over the defaults\n * @returns A fresh logical definition\n *\n * @example\n * ```ts\n * import { atom, logicalDefinition, rule } from '@src/core'\n *\n * logicalDefinition('eligibility', 'Eligibility', [\n * \trule('adult', [atom('age', 'from', 18)], atom('adult', 'equals', true)),\n * ])\n * ```\n */\nexport function logicalDefinition(\n\tid: string,\n\tname: string,\n\trules: readonly Rule[],\n\toverrides?: Partial<Omit<LogicalDefinition, 'reasoning' | 'id' | 'name' | 'rules'>>,\n): LogicalDefinition {\n\treturn { reasoning: 'logical', id, name, rules, strategy: 'forward', ...overrides }\n}\n\n/**\n * Build a {@link SymbolicDefinition}.\n *\n * @remarks\n * `variables` defaults to `{}`; set `variables`, `description`, or `precision`\n * through `overrides`.\n *\n * @param id - The definition id\n * @param name - The display name\n * @param equations - The equations, solved in order\n * @param overrides - Optional {@link SymbolicDefinition} fields merged over the defaults\n * @returns A fresh symbolic definition\n *\n * @example\n * ```ts\n * import { constant, equation, symbolicDefinition, variable } from '@src/core'\n *\n * symbolicDefinition('rate', 'Rate', [equation('e1', variable('x'), constant(42), 'x')], {\n * \tprecision: 2,\n * })\n * ```\n */\nexport function symbolicDefinition(\n\tid: string,\n\tname: string,\n\tequations: readonly Equation[],\n\toverrides?: Partial<Omit<SymbolicDefinition, 'reasoning' | 'id' | 'name' | 'equations'>>,\n): SymbolicDefinition {\n\treturn { reasoning: 'symbolic', id, name, equations, variables: {}, ...overrides }\n}\n\n/**\n * Build an {@link InferentialDefinition}.\n *\n * @remarks\n * `strategy` defaults to `'forward'`; set `strategy`, `description`, or `depth`\n * through `overrides`.\n *\n * @param id - The definition id\n * @param name - The display name\n * @param facts - The base knowledge\n * @param inferences - The inference rules\n * @param overrides - Optional {@link InferentialDefinition} fields merged over the defaults\n * @returns A fresh inferential definition\n *\n * @example\n * ```ts\n * import { fact, inference, inferentialDefinition } from '@src/core'\n *\n * inferentialDefinition('mortality', 'Mortality', [fact('f1', 'human', ['socrates'])], [\n * \tinference('mortal', [fact('p1', 'human', ['?x'])], fact('c1', 'mortal', ['?x'])),\n * ])\n * ```\n */\nexport function inferentialDefinition(\n\tid: string,\n\tname: string,\n\tfacts: readonly Fact[],\n\tinferences: readonly Inference[],\n\toverrides?: Partial<\n\t\tOmit<InferentialDefinition, 'reasoning' | 'id' | 'name' | 'facts' | 'inferences'>\n\t>,\n): InferentialDefinition {\n\treturn {\n\t\treasoning: 'inferential',\n\t\tid,\n\t\tname,\n\t\tfacts,\n\t\tinferences,\n\t\tstrategy: 'forward',\n\t\t...overrides,\n\t}\n}\n\n// === Numeric helpers\n\n/**\n * Clamp a number to inclusive {@link Bounds}.\n *\n * @remarks\n * An absent bound (or absent `bounds` entirely) never constrains that side.\n * `NaN` flows through unchanged (every comparison with `NaN` is false).\n *\n * @param value - The number to clamp\n * @param limit - The inclusive bounds (either side optional)\n * @returns The clamped number\n *\n * @example\n * ```ts\n * import { clamp } from '@src/core'\n *\n * clamp(150, { minimum: 0, maximum: 100 }) // 100\n * clamp(150) // 150 — unbounded\n * ```\n */\nexport function clamp(value: number, limit?: Bounds): number {\n\tif (!limit) return value\n\tlet result = value\n\tif (limit.minimum !== undefined && result < limit.minimum) result = limit.minimum\n\tif (limit.maximum !== undefined && result > limit.maximum) result = limit.maximum\n\treturn result\n}\n\n/**\n * Round a number to a fixed count of decimal places.\n *\n * @remarks\n * `Math.round` semantics — halves round toward `+∞` (`2.5` → `3`, `-2.5` → `-2`).\n * A negative precision rounds at whole-number scales (`-1` → tens, `-2` →\n * hundreds). An EXTREME precision whose scale factor overflows the double range\n * (`10^p` → `Infinity` at roughly `p > 308`, `0` at roughly `p < -323`) returns\n * the value UNCHANGED — passthrough, never `NaN`.\n *\n * @param value - The number to round\n * @param precision - Decimal places to keep (defaults to `0`)\n * @returns The rounded number\n *\n * @example\n * ```ts\n * import { roundTo } from '@src/core'\n *\n * roundTo(3.14159, 2) // 3.14\n * roundTo(2.5) // 3\n * roundTo(1250, -2) // 1300 — tens/hundreds scales\n * roundTo(1.5, 400) // 1.5 — overflow passthrough\n * ```\n */\nexport function roundTo(value: number, precision = 0): number {\n\tconst factor = Math.pow(10, precision)\n\t// An overflowed scale factor (Infinity / 0) would turn every value into NaN —\n\t// rounding is meaningless there, so the value passes through unchanged.\n\tif (!Number.isFinite(factor) || factor === 0) return value\n\treturn Math.round(value * factor) / factor\n}\n\n// === Equality, ordering & uniqueness\n\n/**\n * Determine whether two values are SameValueZero-equal — strict `===` with\n * `NaN` equal to itself (and, unlike `Object.is`, `+0` equal to `-0`).\n *\n * @remarks\n * This is the derivation-bookkeeping equality of the chaining reasoners: the\n * logical overlay and the inferential fact-dedupe compare with it so a\n * NaN-valued conclusion or fact term derives exactly ONCE and the fixpoint\n * converges (raw `===` would re-derive it every iteration, never converging).\n * It matches `Array.prototype.includes` semantics — the same membership test\n * the `any` / `none` comparisons use.\n *\n * @param left - The first value\n * @param right - The second value\n * @returns `true` when the values are SameValueZero-equal\n *\n * @example\n * ```ts\n * import { equalValues } from '@src/core'\n *\n * equalValues(Number.NaN, Number.NaN) // true — unlike ===\n * equalValues(0, -0) // true — unlike Object.is\n * equalValues(1, '1') // false — no coercion\n * ```\n */\nexport function equalValues(left: unknown, right: unknown): boolean {\n\treturn left === right || (left !== left && right !== right)\n}\n\n/**\n * Sort items ascending by `priority ?? DEFAULT_PRIORITY` — a stable copy sort.\n *\n * @remarks\n * The shared evaluation-order helper of the quantitative (factors) and logical\n * (rules) reasoners: lower priorities run first, an absent `priority` defaults\n * to `0`, equal priorities keep DECLARATION order (stable), and the input array\n * is never mutated (AGENTS §11). An array hole, `null`, or other non-record\n * entry is dropped rather than sorted — the output may be shorter than the\n * input.\n *\n * @param items - The priority-carrying items to order\n * @returns A fresh array, sorted ascending by priority\n *\n * @example\n * ```ts\n * import { sortByPriority } from '@src/core'\n *\n * sortByPriority([{ priority: 5 }, {}, { priority: -1 }])\n * // [{ priority: -1 }, {}, { priority: 5 }] — default 0 sits between\n * ```\n */\nexport function sortByPriority<T extends { readonly priority?: number }>(\n\titems: readonly T[],\n): readonly T[] {\n\tconst usable: T[] = []\n\tfor (const item of items) {\n\t\tif (typeof item !== 'object' || item === null) continue\n\t\tusable.push(item)\n\t}\n\treturn usable.sort(\n\t\t(left, right) => (left.priority ?? DEFAULT_PRIORITY) - (right.priority ?? DEFAULT_PRIORITY),\n\t)\n}\n\n/**\n * Collect the ids that appear MORE THAN ONCE in an id-carrying list — each\n * duplicated id reported once, in first-occurrence order.\n *\n * @remarks\n * The shared uniqueness scan behind every reasoner's `validate()` duplicate-id\n * WARNINGS (rules, groups, factors, equations, inferences). Runtime stays\n * permissive about duplicates (first/last-wins artifacts) — this helper only\n * surfaces them.\n *\n * @param items - The id-carrying items to scan\n * @returns The duplicated ids, once each\n *\n * @example\n * ```ts\n * import { findDuplicates } from '@src/core'\n *\n * findDuplicates([{ id: 'a' }, { id: 'b' }, { id: 'a' }, { id: 'a' }]) // ['a']\n * ```\n */\nexport function findDuplicates(items: readonly { readonly id: string }[]): readonly string[] {\n\tconst counts = new Map<string, number>()\n\tfor (const item of items) counts.set(item.id, (counts.get(item.id) ?? 0) + 1)\n\treturn [...counts.entries()].filter(([, count]) => count > 1).map(([id]) => id)\n}\n\n// === Inferential fact machinery\n\n/**\n * Derive a fact's predicate+arity bucket key — length-prefixed so the\n * delimiter cannot be forged.\n *\n * @remarks\n * Keys both stored facts and premise patterns (both are `Fact`-shaped) for\n * {@link indexByArity}: `matchFacts` already rejects an arity mismatch, so\n * narrowing a same-predicate bucket to same-predicate-AND-same-arity only\n * excludes candidates that could never unify anyway. Only `predicate` — the\n * one free-form, adversary-controlled part — is length-prefixed\n * (`length + ':' + predicate`), mirroring {@link factToKey}'s framing so a\n * predicate string embedding the `' '` delimiter can never be mistaken for a\n * different predicate+arity pairing; `terms.length` is always a plain\n * non-negative integer (never itself contains a space) so it needs no prefix.\n *\n * @param source - The fact (or premise pattern) to key\n * @returns The predicate+arity key string\n *\n * @example\n * ```ts\n * import { fact, factToArityKey } from '@src/core'\n *\n * factToArityKey(fact('a', 'human', ['x'])) // arity 1\n * factToArityKey(fact('b', 'human', ['x', 'y'])) // arity 2 — distinct key\n * ```\n */\nexport function factToArityKey(source: Fact): string {\n\tconst p = source.predicate\n\treturn `${p.length}:${p} ${source.terms.length}`\n}\n\n/**\n * Bucket facts by predicate+arity, preserving append order within each bucket.\n *\n * @remarks\n * The index behind the inferential reasoner's same-predicate-and-arity join\n * scans (`#findAllBindings` / `#calculatePremiseConfidence`): `matchFacts`\n * already rejects a predicate OR arity mismatch, so restricting a premise's\n * search to its own predicate+arity bucket changes nothing but the cost — the\n * surviving matches and their append order are identical to a predicate-only\n * index. Append order within a bucket is preserved, so a \"first match wins\"\n * scan finds the same fact a full linear pass would.\n *\n * @param facts - The facts to index\n * @returns A fresh `Map` from {@link factToArityKey} to its facts, in append order\n *\n * @example\n * ```ts\n * import { fact, indexByArity } from '@src/core'\n *\n * const index = indexByArity([fact('a', 'human', ['x']), fact('b', 'human', ['y'])])\n * index.get(factToArityKey(fact('c', 'human', ['z'])))?.length // 2\n * ```\n */\nexport function indexByArity(facts: readonly Fact[]): Map<string, Fact[]> {\n\tconst index = new Map<string, Fact[]>()\n\tfor (const entry of facts) {\n\t\tconst key = factToArityKey(entry)\n\t\tconst bucket = index.get(key)\n\t\tif (bucket) bucket.push(entry)\n\t\telse index.set(key, [entry])\n\t}\n\treturn index\n}\n\n/**\n * Derive one fact term's contribution to a dedup key — reference identity for\n * non-null objects / functions, a SameValueZero value string for primitives.\n *\n * @remarks\n * The per-term half of {@link factToKey}, used by the inferential reasoner's\n * forward-chaining dedupe. Primitives (and `null`) key by value, typeof-prefixed\n * so `1` (`number:1`) never collides with `'1'` (`string:1`); `-0` folds to `+0`\n * (both `number:0`) and `NaN` is self-consistent (`number:NaN`), matching\n * SameValueZero. Objects and functions key by REFERENCE through `identities` — a\n * first sighting is assigned the map's current size as its id, so distinct\n * objects never collide and the SAME reference always reproduces its key.\n *\n * @param term - The term to key\n * @param identities - The reference-identity map, threaded across a dedupe pass (mutated: a new object/function is registered)\n * @returns The term's key string\n *\n * @example\n * ```ts\n * import { termToKey } from '@src/core'\n *\n * const identities = new Map<object, number>()\n * termToKey(1, identities) // 'number:1'\n * termToKey('1', identities) // 'string:1' — never collides with the number\n * ```\n */\nexport function termToKey(term: unknown, identities: Map<object, number>): string {\n\tif ((typeof term === 'object' && term !== null) || typeof term === 'function') {\n\t\tconst existing = identities.get(term)\n\t\tif (existing !== undefined) return `${typeof term}:#${existing}`\n\t\tconst id = identities.size\n\t\tidentities.set(term, id)\n\t\treturn `${typeof term}:#${id}`\n\t}\n\treturn `${typeof term}:${Object.is(term, -0) ? '0' : String(term)}`\n}\n\n/**\n * Derive a fact's canonical dedup key — predicate + arity + per-term\n * SameValueZero identity (confidence is NOT part of it).\n *\n * @remarks\n * The dedup key of the inferential reasoner's forward fixpoint: two facts with\n * the same predicate, arity, and SameValueZero-equal terms share a key (so a\n * NaN-term fact derives once and ±0 collapse keeping the first), while\n * confidence never enters the key. Each part — the predicate, the stringified\n * arity, and every {@link termToKey} — is LENGTH-PREFIXED (`length + ':' + part`)\n * before joining, so the delimiter can never be forged by an adversarial string\n * term embedding it: two distinct facts always produce distinct keys, even when\n * a term string contains the delimiter (an injective framing raw joining lacked).\n *\n * @param source - The fact to key\n * @param identities - The reference-identity map threaded across the dedupe pass (see {@link termToKey})\n * @returns The fact's canonical key string\n *\n * @example\n * ```ts\n * import { fact, factToKey } from '@src/core'\n *\n * const identities = new Map<object, number>()\n * // Same predicate + terms → same key regardless of confidence:\n * factToKey(fact('a', 'p', ['x'], 1), identities) === factToKey(fact('b', 'p', ['x'], 0.5), identities)\n * ```\n */\nexport function factToKey(source: Fact, identities: Map<object, number>): string {\n\tconst parts = [\n\t\tsource.predicate,\n\t\tString(source.terms.length),\n\t\t...Array.from(source.terms, (term) => termToKey(term, identities)),\n\t]\n\t// Length-prefix every part so the '\u0000' delimiter cannot be forged by a\n\t// term string that embeds it — the framing stays injective.\n\treturn parts.map((part) => `${part.length}:${part}`).join('\u0000')\n}\n\n/**\n * Positionally unify a pattern fact against a candidate fact — returning the\n * variable bindings on success, `undefined` on mismatch.\n *\n * @remarks\n * The bidirectional unification of the inferential reasoner: a `'?'`-prefixed\n * string term on EITHER side (pattern or candidate) is a variable that binds to\n * the opposite term (the `'?'` prefix is kept in the binding key), while\n * consistency is enforced within the match — a variable seen twice must bind the\n * SAME value (raw `!==`) or the whole match fails. A predicate mismatch or an\n * arity (term-count) mismatch fails immediately; non-variable terms must be\n * strictly (`===`) equal.\n *\n * @param pattern - The pattern fact (may carry `'?'` variables)\n * @param candidate - The candidate fact to unify against (may also carry `'?'` variables)\n * @returns A fresh bindings record, or `undefined` when they do not unify\n *\n * @example\n * ```ts\n * import { fact, matchFacts } from '@src/core'\n *\n * matchFacts(fact('p', 'parent', ['?x', 'bob']), fact('f', 'parent', ['alice', 'bob'])) // { '?x': 'alice' }\n * matchFacts(fact('p', 'parent', ['?x']), fact('f', 'human', ['x'])) // undefined — predicate\n * ```\n */\nexport function matchFacts(pattern: Fact, candidate: Fact): Record<string, unknown> | undefined {\n\tif (pattern.predicate !== candidate.predicate) return undefined\n\tif (pattern.terms.length !== candidate.terms.length) return undefined\n\n\tconst bindings: Record<string, unknown> = {}\n\n\tfor (let index = 0; index < pattern.terms.length; index++) {\n\t\tconst patternTerm = pattern.terms[index]\n\t\tconst factTerm = candidate.terms[index]\n\n\t\tif (typeof patternTerm === 'string' && patternTerm.startsWith('?')) {\n\t\t\tif (patternTerm in bindings) {\n\t\t\t\tif (bindings[patternTerm] !== factTerm) return undefined\n\t\t\t} else {\n\t\t\t\tbindings[patternTerm] = factTerm\n\t\t\t}\n\t\t} else if (typeof factTerm === 'string' && factTerm.startsWith('?')) {\n\t\t\tif (factTerm in bindings) {\n\t\t\t\tif (bindings[factTerm] !== patternTerm) return undefined\n\t\t\t} else {\n\t\t\t\tbindings[factTerm] = patternTerm\n\t\t\t}\n\t\t} else if (patternTerm !== factTerm) {\n\t\t\treturn undefined\n\t\t}\n\t}\n\n\treturn bindings\n}\n\n/**\n * Substitute a fact's bound `'?'`-variables with their values — a fresh fact\n * with unbound terms passed through unchanged.\n *\n * @remarks\n * The pattern-instantiation step of the inferential reasoner: a `'?'`-prefixed\n * string term that is present in `bindings` is replaced by its bound value;\n * every other term (constants and UNBOUND variables alike) is kept verbatim. The\n * returned fact is a fresh copy (`{ ...fact, terms }`) — the input is never\n * mutated (AGENTS §11).\n *\n * @param source - The fact (or pattern) to instantiate\n * @param bindings - The variable bindings to apply\n * @returns A fresh fact with bound variables substituted\n *\n * @example\n * ```ts\n * import { fact, instantiateFact } from '@src/core'\n *\n * instantiateFact(fact('c', 'mortal', ['?x']), { '?x': 'socrates' }).terms // ['socrates']\n * ```\n */\nexport function instantiateFact(source: Fact, bindings: Record<string, unknown>): Fact {\n\tconst terms = source.terms.map((term) => {\n\t\tif (typeof term === 'string' && term.startsWith('?') && term in bindings) {\n\t\t\treturn bindings[term]\n\t\t}\n\t\treturn term\n\t})\n\treturn { ...source, terms }\n}\n\n/**\n * Project a subject's scalar fields into `has(key, value)` base facts — the\n * inferential reasoner's subject-injection step.\n *\n * @remarks\n * Every own subject field EXCEPT `id` becomes a `has(key, value)` fact at full\n * `DEFAULT_CONFIDENCE`; `null` / `undefined` and any `object` (including arrays)\n * value is skipped. Each injection appends a line to `trace` (mutated), plus a\n * final count when at least one fact was produced. The injected fact ids are\n * `subject:<key>`.\n *\n * @param subject - The subject to project\n * @param trace - The trace accumulator to append to (mutated)\n * @returns The fresh `has(...)` facts (in `Object.keys` order)\n *\n * @example\n * ```ts\n * import { subjectToFacts } from '@src/core'\n *\n * const trace: string[] = []\n * subjectToFacts({ id: 'p1', age: 42, tags: ['a'] }, trace) // one fact: has('age', 42) — tags skipped\n * ```\n */\nexport function subjectToFacts(subject: Subject, trace: string[]): Fact[] {\n\tconst facts: Fact[] = []\n\n\tfor (const key of Object.keys(subject)) {\n\t\tif (key === 'id') continue\n\t\tconst value = subject[key]\n\t\tif (value === undefined || value === null) continue\n\t\tif (typeof value === 'object') continue\n\n\t\tfacts.push({\n\t\t\tid: `subject:${key}`,\n\t\t\tpredicate: 'has',\n\t\t\tterms: [key, value],\n\t\t\tconfidence: DEFAULT_CONFIDENCE,\n\t\t})\n\t\ttrace.push(`Subject field \"${key}\" → has(${key}, ${String(value)})`)\n\t}\n\n\tif (facts.length > 0) trace.push(`Injected ${facts.length} fact(s) from subject`)\n\treturn facts\n}\n\n/**\n * The `'?'`-prefixed variables an inference's conclusion introduces that no\n * premise binds.\n *\n * @remarks\n * The authoring-time footgun probe behind `InferentialReasoner.validate`'s\n * unbound-variable warning: backward proving establishes each premise\n * independently with no cross-premise binding consistency, so a conclusion\n * term that no premise's `terms` ever names stays uninstantiated in the\n * derived fact. Gathers the `?`-prefixed string terms of `conclusion.terms`,\n * subtracts every `?`-prefixed string term appearing in any premise's\n * `terms`, and returns the remainder once each, in the conclusion's authored\n * order.\n *\n * @param source - The inference whose conclusion is checked against its premises\n * @returns The unbound conclusion variable names, once each, authored order\n *\n * @example\n * ```ts\n * import { fact, findUnboundVariables, inference } from '@src/core'\n *\n * findUnboundVariables(\n * \tinference('i', 'I', [fact('p', 'human', ['?x'])], fact('c', 'mortal', ['?x', '?y'])),\n * ) // ['?y'] — '?x' is bound by the premise, '?y' is not\n * ```\n */\nexport function findUnboundVariables(source: Inference): readonly string[] {\n\tconst bound = new Set<string>()\n\tfor (const premise of source.premises) {\n\t\tfor (const term of premise.terms) {\n\t\t\tif (isString(term) && term.startsWith('?')) bound.add(term)\n\t\t}\n\t}\n\n\tconst unbound: string[] = []\n\tconst seen = new Set<string>()\n\tfor (const term of source.conclusion.terms) {\n\t\tif (!isString(term) || !term.startsWith('?')) continue\n\t\tif (bound.has(term) || seen.has(term)) continue\n\t\tseen.add(term)\n\t\tunbound.push(term)\n\t}\n\n\treturn unbound\n}\n\n// === Symbolic algebra machinery\n\n/**\n * Determine whether a symbolic expression contains an UNBOUND occurrence of a\n * target variable.\n *\n * @remarks\n * The variable-presence probe of the symbolic reasoner's isolation: a `variable`\n * node matches only when its name is `target` AND `target` is not already in\n * `bindings` (a pre-bound target is a known value, not an unknown to isolate); a\n * `constant` never matches; an `operation` recurses into both operands (the\n * `right` operand may be absent on a unary node). The walk is an ITERATIVE\n * worklist (never recursive) with short-circuit `true` on the first hit, so it\n * stays total on pathologically deep expression trees.\n *\n * @param expression - The expression to probe\n * @param target - The variable name being sought\n * @param bindings - The known bindings (a bound target does NOT count as present)\n * @returns `true` when an unbound `target` occurs in the expression\n *\n * @example\n * ```ts\n * import { containsVariable, operation, variable, constant } from '@src/core'\n *\n * containsVariable(operation('add', variable('x'), constant(1)), 'x', {}) // true\n * containsVariable(operation('add', variable('x'), constant(1)), 'x', { x: 5 }) // false — pre-bound\n * ```\n */\nexport function containsVariable(\n\texpression: SymbolicExpression,\n\ttarget: string,\n\tbindings: Record<string, number>,\n): boolean {\n\tconst worklist: SymbolicExpression[] = [expression]\n\n\twhile (worklist.length > 0) {\n\t\tconst node = worklist.pop()\n\t\tif (node === undefined) continue\n\t\tif (node.form === 'variable') {\n\t\t\tif (node.name === target && !(target in bindings)) return true\n\t\t} else if (node.form === 'operation') {\n\t\t\tworklist.push(node.left)\n\t\t\tif (node.right) worklist.push(node.right)\n\t\t}\n\t}\n\n\treturn false\n}\n\n/**\n * Invert a `x op right = value` step, solving for the LEFT operand `x`.\n *\n * @remarks\n * The left-operand inverse of the symbolic reasoner's isolation: `add` inverts\n * to subtraction, `subtract` to addition, `multiply` to division, `divide` to\n * multiplication. Inversion by zero yields `NaN` (never a throw) — a `multiply`\n * with a zero `right` has no unique solution, and `x / 0 = value` has none\n * either, so both surface `NaN` for the non-finite check to report rather than a\n * bogus value. A non-invertible operator throws (caught per equation upstream).\n *\n * @param operator - The math operation to invert\n * @param value - The known result of `x op right`\n * @param rightValue - The known right operand\n * @returns The isolated left operand (`NaN` on a zero-division inverse)\n *\n * @example\n * ```ts\n * import { invertLeft } from '@src/core'\n *\n * invertLeft('add', 10, 3) // 7 — x + 3 = 10\n * invertLeft('multiply', 10, 0) // NaN — x * 0 = 10 has no solution\n * ```\n */\nexport function invertLeft(operator: MathOperation, value: number, rightValue: number): number {\n\tswitch (operator) {\n\t\tcase 'add':\n\t\t\treturn value - rightValue\n\t\tcase 'subtract':\n\t\t\treturn value + rightValue\n\t\tcase 'multiply':\n\t\t\treturn rightValue === 0 ? Number.NaN : value / rightValue\n\t\tcase 'divide':\n\t\t\t// `x / 0 = value` has NO solution — NaN (uniform with the other\n\t\t\t// zero guards), so the non-finite check reports it rather than\n\t\t\t// a bogus `x = 0`.\n\t\t\treturn rightValue === 0 ? Number.NaN : value * rightValue\n\t\tdefault:\n\t\t\tthrow new Error(`Cannot invert operation \"${operator}\" for left operand`)\n\t}\n}\n\n/**\n * Invert a `left op x = value` step, solving for the RIGHT operand `x`.\n *\n * @remarks\n * The right-operand inverse of the symbolic reasoner's isolation: `add` inverts\n * to `value - left`, `subtract` to `left - value`, `multiply` to `value / left`\n * (with a zero `left` yielding `NaN`), `divide` to `left / value` (with a zero\n * `value` yielding `NaN`). Inversion by zero yields `NaN`, never a throw; a\n * non-invertible operator throws (caught per equation upstream).\n *\n * @param operator - The math operation to invert\n * @param value - The known result of `left op x`\n * @param leftValue - The known left operand\n * @returns The isolated right operand (`NaN` on a zero-division inverse)\n *\n * @example\n * ```ts\n * import { invertRight } from '@src/core'\n *\n * invertRight('subtract', 4, 10) // 6 — 10 - x = 4\n * invertRight('divide', 0, 10) // NaN — 10 / x = 0 has no finite solution\n * ```\n */\nexport function invertRight(operator: MathOperation, value: number, leftValue: number): number {\n\tswitch (operator) {\n\t\tcase 'add':\n\t\t\treturn value - leftValue\n\t\tcase 'subtract':\n\t\t\treturn leftValue - value\n\t\tcase 'multiply':\n\t\t\treturn leftValue === 0 ? Number.NaN : value / leftValue\n\t\tcase 'divide':\n\t\t\treturn value === 0 ? Number.NaN : leftValue / value\n\t\tdefault:\n\t\t\tthrow new Error(`Cannot invert operation \"${operator}\" for right operand`)\n\t}\n}\n\n/**\n * Apply one binary/unary math operation to already-evaluated operands.\n *\n * @remarks\n * The arithmetic core of the symbolic reasoner's expression evaluation: the full\n * {@link MathOperation} vocabulary plus its zero / unary conventions — `divide`\n * by zero is `NaN` (never a throw), the unary operations (`round` / `ceil` /\n * `floor` / `abs`) ignore `right`, and `percentage` is `left * (right / 100)`.\n * `operator` is typed `string` because untrusted definitions reach here\n * unchecked; the ONE throwing path is the unknown-operator default (caught per\n * equation upstream).\n *\n * @param operator - The operation name (untrusted — an unknown one throws)\n * @param left - The left operand\n * @param right - The right operand (ignored by the unary operations)\n * @returns The operation's result (`NaN` on divide-by-zero)\n *\n * @example\n * ```ts\n * import { applyOperation } from '@src/core'\n *\n * applyOperation('add', 2, 3) // 5\n * applyOperation('divide', 1, 0) // NaN\n * ```\n */\nexport function applyOperation(operator: string, left: number, right: number): number {\n\tswitch (operator) {\n\t\tcase 'add':\n\t\t\treturn left + right\n\t\tcase 'subtract':\n\t\t\treturn left - right\n\t\tcase 'multiply':\n\t\t\treturn left * right\n\t\tcase 'divide':\n\t\t\treturn right === 0 ? Number.NaN : left / right\n\t\tcase 'power':\n\t\t\treturn Math.pow(left, right)\n\t\tcase 'minimum':\n\t\t\treturn Math.min(left, right)\n\t\tcase 'maximum':\n\t\t\treturn Math.max(left, right)\n\t\tcase 'average':\n\t\t\treturn (left + right) / 2\n\t\tcase 'percentage':\n\t\t\treturn left * (right / 100)\n\t\tcase 'round':\n\t\t\treturn Math.round(left)\n\t\tcase 'ceil':\n\t\t\treturn Math.ceil(left)\n\t\tcase 'floor':\n\t\t\treturn Math.floor(left)\n\t\tcase 'abs':\n\t\t\treturn Math.abs(left)\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown operator: ${operator}`)\n\t}\n}\n\n// === Logical conclusion extraction & error results\n\n/**\n * Return every atom leaf of an expression tree, depth-first, left-to-right.\n *\n * @remarks\n * The shared atom-walk behind both {@link extractConclusions} and the raters'\n * conclusion merge: an `atom` yields itself; a compound flattens its operands in\n * authored order, so a later operand's atoms follow an earlier one's. The walk is\n * an ITERATIVE explicit-stack traversal (never recursive), so it stays total on\n * pathologically deep expression trees; a hole in an `operands` array is skipped,\n * matching `flatMap`'s hole-skipping behavior.\n *\n * @param expression - The expression tree to walk\n * @returns A fresh, ordered list of the atom leaves\n *\n * @example\n * ```ts\n * import { atom, compound, extractAtoms } from '@src/core'\n *\n * extractAtoms(atom('a', 'equals', 1)).length // 1\n * extractAtoms(compound('and', [atom('a', 'equals', 1), atom('b', 'equals', 2)])).length // 2\n * ```\n */\nexport function extractAtoms(expression: Expression): readonly Atom[] {\n\tconst atoms: Atom[] = []\n\tconst stack: Expression[] = [expression]\n\n\twhile (stack.length > 0) {\n\t\tconst node = stack.pop()\n\t\tif (node === undefined) continue\n\t\tif (node.form === 'atom') {\n\t\t\tatoms.push(node)\n\t\t\tcontinue\n\t\t}\n\t\tconst operands = node.operands\n\t\tfor (let index = operands.length - 1; index >= 0; index--) {\n\t\t\tif (index in operands) stack.push(operands[index])\n\t\t}\n\t}\n\n\treturn atoms\n}\n\n/**\n * Flatten a logical conclusion expression into its asserted `field = value`\n * pairs — connectives IGNORED.\n *\n * @remarks\n * The conclusion-extraction step of the logical reasoner's chaining: every\n * `atom` inside the expression asserts its `formatField(check.field) =\n * check.value` pair, and compounds are walked without regard to the connective\n * (an atom under `not` / `or` is asserted just the same). Later operands WIN on\n * a key clash (`Object.assign` order). Recursion runs through this exported\n * function itself; the derived-overlay keys are `formatField` strings (an array\n * field path flattens to its dot-joined form).\n *\n * @param expression - The conclusion expression to flatten\n * @returns A fresh record of asserted `field → value` pairs\n *\n * @example\n * ```ts\n * import { atom, compound, extractConclusions } from '@src/core'\n *\n * extractConclusions(atom('adult', 'equals', true)) // { adult: true }\n * extractConclusions(compound('and', [atom('a', 'equals', 1), atom('b', 'equals', 2)])) // { a: 1, b: 2 }\n * ```\n */\nexport function extractConclusions(expression: Expression): Record<string, unknown> {\n\tconst conclusions: Record<string, unknown> = {}\n\tfor (const leaf of extractAtoms(expression))\n\t\tconclusions[formatField(leaf.check.field)] = leaf.check.value\n\treturn conclusions\n}\n\n/**\n * The `formatField`-flattened overlay keys an array-path conclusion atom\n * writes ANYWHERE among `rules` that an array-path premise atom also reads\n * ANYWHERE among `rules`.\n *\n * @remarks\n * The cross-rule authoring-time footgun probe behind\n * `LogicalReasoner.validate`'s overlay-key-mismatch warning: a logical\n * conclusion's derived overlay is a FLAT record keyed by\n * `formatField(check.field)` — an array `FieldPath` dot-joins into one string\n * key. A premise that reads the same field via a DOTTED-STRING path resolves\n * that flat key correctly, but a premise that reads it via an ARRAY path\n * calls `resolveField`, which descends key-by-key into nesting the flat\n * overlay never created, so the chain silently fails to connect. Collects the\n * flattened keys of every array-path conclusion atom across `rules` (once\n * each, authored order), then returns the ones that also appear as the\n * flattened key of some array-path premise atom anywhere in `rules` — a\n * single pass over every rule's conclusion and premise atoms, so the cost is\n * linear in total atom count, never quadratic.\n *\n * @param rules - The rules to scan for the array-path write/read overlap\n * @returns The mismatched overlay keys, once each, authored order\n *\n * @example\n * ```ts\n * import { atom, findOverlayMismatches, rule } from '@src/core'\n *\n * findOverlayMismatches([\n * \trule('a', [], atom(['address', 'city'], 'equals', 'NYC')),\n * \trule('b', [atom(['address', 'city'], 'equals', 'NYC')], atom('eligible', 'equals', true)),\n * ]) // ['address.city']\n * ```\n */\nexport function findOverlayMismatches(rules: readonly Rule[]): readonly string[] {\n\tconst writeKeys: string[] = []\n\tconst seenWrites = new Set<string>()\n\tfor (const candidate of rules) {\n\t\tfor (const atomLeaf of extractAtoms(candidate.conclusion)) {\n\t\t\tif (!Array.isArray(atomLeaf.check.field)) continue\n\t\t\tconst key = formatField(atomLeaf.check.field)\n\t\t\tif (seenWrites.has(key)) continue\n\t\t\tseenWrites.add(key)\n\t\t\twriteKeys.push(key)\n\t\t}\n\t}\n\n\tconst readKeys = new Set<string>()\n\tfor (const candidate of rules) {\n\t\tfor (const premise of candidate.premises) {\n\t\t\tfor (const atomLeaf of extractAtoms(premise)) {\n\t\t\t\tif (!Array.isArray(atomLeaf.check.field)) continue\n\t\t\t\treadKeys.add(formatField(atomLeaf.check.field))\n\t\t\t}\n\t\t}\n\t}\n\n\treturn writeKeys.filter((key) => readKeys.has(key))\n}\n\n/**\n * Build the empty, type-shaped failure {@link ReasonResult} matching a\n * definition's reasoning.\n *\n * @remarks\n * The `bail: false` fallback of the `Reason` orchestrator: when a reasoner\n * throws and bail is off, the throw becomes an empty failure result carrying the\n * message as its sole `errors` entry. Each reasoning gets its own zero-valued\n * shape (`quantitative` → `value: 0` / empty `groups`; `logical` → `conclusion:\n * false` / empty `rules`; `symbolic` → empty `solutions`; `inferential` → empty\n * `derived`), always with `success: false` and an empty `trace`.\n *\n * @param definition - The definition whose reasoning selects the result shape\n * @param message - The error message to carry as the result's sole `errors` entry\n * @returns A fresh failure result of the matching reasoning\n *\n * @example\n * ```ts\n * import { buildErrorResult, logicalDefinition } from '@src/core'\n *\n * const result = buildErrorResult(logicalDefinition('e', 'E', []), 'boom')\n * // { reasoning: 'logical', conclusion: false, rules: [], count: 0, success: false, trace: [], errors: ['boom'] }\n * ```\n */\nexport function buildErrorResult(definition: Definition, message: string): ReasonResult {\n\tswitch (definition.reasoning) {\n\t\tcase 'quantitative':\n\t\t\treturn {\n\t\t\t\treasoning: 'quantitative',\n\t\t\t\tvalue: 0,\n\t\t\t\tgroups: [],\n\t\t\t\tcount: 0,\n\t\t\t\tsuccess: false,\n\t\t\t\ttrace: [],\n\t\t\t\terrors: [message],\n\t\t\t}\n\t\tcase 'logical':\n\t\t\treturn {\n\t\t\t\treasoning: 'logical',\n\t\t\t\tconclusion: false,\n\t\t\t\trules: [],\n\t\t\t\tcount: 0,\n\t\t\t\tsuccess: false,\n\t\t\t\ttrace: [],\n\t\t\t\terrors: [message],\n\t\t\t}\n\t\tcase 'symbolic':\n\t\t\treturn {\n\t\t\t\treasoning: 'symbolic',\n\t\t\t\tsolutions: {},\n\t\t\t\tsuccess: false,\n\t\t\t\ttrace: [],\n\t\t\t\terrors: [message],\n\t\t\t}\n\t\tcase 'inferential':\n\t\t\treturn {\n\t\t\t\treasoning: 'inferential',\n\t\t\t\tderived: [],\n\t\t\t\tsuccess: false,\n\t\t\t\ttrace: [],\n\t\t\t\terrors: [message],\n\t\t\t}\n\t}\n}\n\n// === Id-keyed collection primitives (PROPOSAL.md §7)\n//\n// Five exported generic primitives every per-kind change/merge helper below\n// composes over. Per AGENTS §4.2.4 no parameter selects behavior: `appendById`\n// and `prependById` are separately named functions, and the optional `target`\n// each takes is DATA — an id to anchor on — never a behavior switch. Every\n// primitive is copy-on-write (AGENTS §11): the input array is never mutated,\n// and a fresh array is always returned.\n\n/**\n * Insert `item` into an id-keyed collection, deduping any existing element\n * sharing its id, then placing it at the END (or immediately AFTER `target`).\n *\n * @remarks\n * `filtered` is `items` with every `item.id` twin removed FIRST (dedup-on-\n * insert — input arrays may already carry same-id twins per PROPOSAL.md §7).\n * Re-appending an existing id therefore REPOSITIONS it rather than updating it\n * in place — {@link replaceById} is the position-preserving alternative. With\n * no `target`, `item` lands at the end; with a `target`, it lands immediately\n * after the element whose `id === target` (searched in the DEDUPED array). A\n * `target` naming no element throws {@link ReasonError} (`'TARGET'`).\n *\n * @typeParam T - An id-carrying element type\n * @param items - The collection to insert into\n * @param item - The element to insert\n * @param target - Optional id to insert immediately after; appends at the end when absent\n * @returns A fresh array with `item` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no element in `items`\n *\n * @example\n * ```ts\n * import { appendById } from '@src/core'\n *\n * appendById([{ id: 'a' }, { id: 'b' }], { id: 'c' }) // [a, b, c]\n * appendById([{ id: 'a' }, { id: 'b' }], { id: 'c' }, 'a') // [a, c, b]\n * ```\n */\nexport function appendById<T extends { readonly id: string }>(\n\titems: readonly T[],\n\titem: T,\n\ttarget?: string,\n): readonly T[] {\n\tconst filtered = items.filter((existing) => existing.id !== item.id)\n\tif (target === undefined) return [...filtered, item]\n\tconst index = filtered.findIndex((existing) => existing.id === target)\n\tif (index === -1)\n\t\tthrow new ReasonError('TARGET', `Target id \"${target}\" not found`, {\n\t\t\tid: item.id,\n\t\t\ttarget,\n\t\t\tcollection: 'items',\n\t\t})\n\treturn [...filtered.slice(0, index + 1), item, ...filtered.slice(index + 1)]\n}\n\n/**\n * Insert `item` into an id-keyed collection, deduping any existing element\n * sharing its id, then placing it at the START (or immediately BEFORE `target`).\n *\n * @remarks\n * Mirrors {@link appendById}'s dedup-then-insert semantics exactly, only the\n * placement differs: no `target` lands `item` at the start; a `target` lands\n * it immediately before the element whose `id === target` (searched in the\n * deduped array). A `target` naming no element throws {@link ReasonError}\n * (`'TARGET'`).\n *\n * @typeParam T - An id-carrying element type\n * @param items - The collection to insert into\n * @param item - The element to insert\n * @param target - Optional id to insert immediately before; prepends at the start when absent\n * @returns A fresh array with `item` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no element in `items`\n *\n * @example\n * ```ts\n * import { prependById } from '@src/core'\n *\n * prependById([{ id: 'a' }, { id: 'b' }], { id: 'c' }) // [c, a, b]\n * prependById([{ id: 'a' }, { id: 'b' }], { id: 'c' }, 'b') // [a, c, b]\n * ```\n */\nexport function prependById<T extends { readonly id: string }>(\n\titems: readonly T[],\n\titem: T,\n\ttarget?: string,\n): readonly T[] {\n\tconst filtered = items.filter((existing) => existing.id !== item.id)\n\tif (target === undefined) return [item, ...filtered]\n\tconst index = filtered.findIndex((existing) => existing.id === target)\n\tif (index === -1)\n\t\tthrow new ReasonError('TARGET', `Target id \"${target}\" not found`, {\n\t\t\tid: item.id,\n\t\t\ttarget,\n\t\t\tcollection: 'items',\n\t\t})\n\treturn [...filtered.slice(0, index), item, ...filtered.slice(index)]\n}\n\n/**\n * Swap the element sharing `item.id` IN PLACE, preserving its position.\n *\n * @remarks\n * The position-preserving update primitive — unlike {@link appendById}, which\n * repositions a re-inserted id to the end/target. Appends `item` at the end\n * when no same-id element exists (never throws).\n *\n * @typeParam T - An id-carrying element type\n * @param items - The collection to update\n * @param item - The replacement element\n * @returns A fresh array with the same-id element replaced (or `item` appended)\n *\n * @example\n * ```ts\n * import { replaceById } from '@src/core'\n *\n * replaceById([{ id: 'a', v: 1 }, { id: 'b', v: 2 }], { id: 'a', v: 9 }) // [{a,9}, {b,2}]\n * replaceById([{ id: 'a' }], { id: 'z' }) // [{a}, {z}] — appended\n * ```\n */\nexport function replaceById<T extends { readonly id: string }>(\n\titems: readonly T[],\n\titem: T,\n): readonly T[] {\n\tconst index = items.findIndex((existing) => existing.id === item.id)\n\tif (index === -1) return [...items, item]\n\treturn [...items.slice(0, index), item, ...items.slice(index + 1)]\n}\n\n/**\n * Filter every element sharing `id` out of an id-keyed collection.\n *\n * @remarks\n * An absent `id` yields a same-length fresh copy — a no-op, never a throw.\n *\n * @typeParam T - An id-carrying element type\n * @param items - The collection to remove from\n * @param id - The id to remove every occurrence of\n * @returns A fresh array with every `id`-matching element removed\n *\n * @example\n * ```ts\n * import { removeById } from '@src/core'\n *\n * removeById([{ id: 'a' }, { id: 'b' }], 'a') // [{ id: 'b' }]\n * removeById([{ id: 'a' }], 'z') // [{ id: 'a' }] — no-op\n * ```\n */\nexport function removeById<T extends { readonly id: string }>(\n\titems: readonly T[],\n\tid: string,\n): readonly T[] {\n\treturn items.filter((item) => item.id !== id)\n}\n\n/**\n * Reconcile two id-keyed collections — an incoming-order upsert with\n * base-only survivors appended after.\n *\n * @remarks\n * The Strategic-Merge-Patch-style id-keyed upsert of PROPOSAL.md §6-§7:\n * the result is ordered by `incoming`'s id order FIRST (each element resolved\n * through `resolve` when its id also exists in `base`, defaulting to\n * incoming-wins-wholesale), THEN the `base`-only survivors in `base`'s own\n * order (retained, never deleted — merge is additive). Same-id twins within\n * EITHER input are deduped to their first occurrence.\n *\n * @typeParam T - An id-carrying element type\n * @param base - The base collection\n * @param incoming - The incoming collection (its order and matches take priority)\n * @param resolve - How to reconcile a matched (same-id) pair; defaults to keeping the incoming element wholesale\n * @returns A fresh, deduped, incoming-ordered-then-base-survivors array\n *\n * @example\n * ```ts\n * import { mergeById } from '@src/core'\n *\n * mergeById([{ id: 'a', v: 1 }, { id: 'b', v: 2 }], [{ id: 'a', v: 9 }])\n * // [{ id: 'a', v: 9 }, { id: 'b', v: 2 }] — incoming order first, base-only survivor after\n * ```\n */\nexport function mergeById<T extends { readonly id: string }>(\n\tbase: readonly T[],\n\tincoming: readonly T[],\n\tresolve?: (base: T, incoming: T) => T,\n): readonly T[] {\n\tconst baseById = new Map<string, T>()\n\tfor (const item of base) if (!baseById.has(item.id)) baseById.set(item.id, item)\n\n\tconst seen = new Set<string>()\n\tconst merged: T[] = []\n\tfor (const item of incoming) {\n\t\tif (seen.has(item.id)) continue\n\t\tseen.add(item.id)\n\t\tconst existing = baseById.get(item.id)\n\t\tmerged.push(existing === undefined ? item : resolve ? resolve(existing, item) : item)\n\t}\n\tfor (const item of base) {\n\t\tif (seen.has(item.id)) continue\n\t\tseen.add(item.id)\n\t\tmerged.push(item)\n\t}\n\treturn merged\n}\n\n// === Quantitative change/extend helpers (PROPOSAL.md §8)\n\n/**\n * Insert `group` into a {@link QuantitativeDefinition}'s `groups` — dedup-then-\n * insert at the end, or immediately after `target`.\n *\n * @remarks\n * Group order is COSMETIC (group aggregation is order-independent) but honored\n * uniformly, same as every `append*` helper. Composes with {@link appendFactor}:\n * `appendGroup(def, appendFactor(group, factor))`.\n *\n * @param definition - The definition to insert into\n * @param group - The group to insert\n * @param target - Optional group id to insert immediately after\n * @returns A fresh definition with `group` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no existing group\n *\n * @example\n * ```ts\n * import { appendGroup, factorGroup, quantitativeDefinition } from '@src/core'\n *\n * appendGroup(quantitativeDefinition('risk', 'Risk', []), factorGroup('g1', 'sum', []))\n * ```\n */\nexport function appendGroup(\n\tdefinition: QuantitativeDefinition,\n\tgroup: FactorGroup,\n\ttarget?: string,\n): QuantitativeDefinition {\n\treturn { ...definition, groups: appendById(definition.groups, group, target) }\n}\n\n/**\n * Insert `group` into a {@link QuantitativeDefinition}'s `groups` — dedup-then-\n * insert at the start, or immediately before `target`.\n *\n * @param definition - The definition to insert into\n * @param group - The group to insert\n * @param target - Optional group id to insert immediately before\n * @returns A fresh definition with `group` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no existing group\n *\n * @example\n * ```ts\n * import { factorGroup, prependGroup, quantitativeDefinition } from '@src/core'\n *\n * prependGroup(quantitativeDefinition('risk', 'Risk', []), factorGroup('g1', 'sum', []))\n * ```\n */\nexport function prependGroup(\n\tdefinition: QuantitativeDefinition,\n\tgroup: FactorGroup,\n\ttarget?: string,\n): QuantitativeDefinition {\n\treturn { ...definition, groups: prependById(definition.groups, group, target) }\n}\n\n/**\n * Swap the group sharing `group.id` in a {@link QuantitativeDefinition} IN\n * PLACE, preserving its position (appends when absent).\n *\n * @param definition - The definition to update\n * @param group - The replacement group\n * @returns A fresh definition with the group replaced\n *\n * @example\n * ```ts\n * import { factorGroup, quantitativeDefinition, replaceGroup } from '@src/core'\n *\n * const definition = quantitativeDefinition('risk', 'Risk', [factorGroup('g1', 'sum', [])])\n * replaceGroup(definition, factorGroup('g1', 'product', []))\n * ```\n */\nexport function replaceGroup(\n\tdefinition: QuantitativeDefinition,\n\tgroup: FactorGroup,\n): QuantitativeDefinition {\n\treturn { ...definition, groups: replaceById(definition.groups, group) }\n}\n\n/**\n * Remove every group sharing `id` from a {@link QuantitativeDefinition}\n * (no-op when absent).\n *\n * @param definition - The definition to update\n * @param id - The group id to remove\n * @returns A fresh definition with the group removed\n *\n * @example\n * ```ts\n * import { factorGroup, quantitativeDefinition, removeGroup } from '@src/core'\n *\n * const definition = quantitativeDefinition('risk', 'Risk', [factorGroup('g1', 'sum', [])])\n * removeGroup(definition, 'g1').groups // []\n * ```\n */\nexport function removeGroup(\n\tdefinition: QuantitativeDefinition,\n\tid: string,\n): QuantitativeDefinition {\n\treturn { ...definition, groups: removeById(definition.groups, id) }\n}\n\n/**\n * Insert `factor` into a {@link FactorGroup}'s `factors` — dedup-then-insert\n * at the end, or immediately after `target`.\n *\n * @remarks\n * Factor order is LOAD-BEARING: the same-priority tiebreak is declaration\n * order ({@link sortByPriority} is a stable ascending sort). Operates on the\n * factor's DIRECT container — compose into a definition via\n * `appendGroup(def, appendFactor(group, factor))`.\n *\n * @param group - The group to insert into\n * @param factor - The factor to insert\n * @param target - Optional factor id to insert immediately after\n * @returns A fresh group with `factor` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no existing factor\n *\n * @example\n * ```ts\n * import { appendFactor, factorGroup, staticFactor } from '@src/core'\n *\n * appendFactor(factorGroup('g1', 'sum', []), staticFactor('f1', 10))\n * ```\n */\nexport function appendFactor(group: FactorGroup, factor: Factor, target?: string): FactorGroup {\n\treturn { ...group, factors: appendById(group.factors, factor, target) }\n}\n\n/**\n * Insert `factor` into a {@link FactorGroup}'s `factors` — dedup-then-insert\n * at the start, or immediately before `target`.\n *\n * @param group - The group to insert into\n * @param factor - The factor to insert\n * @param target - Optional factor id to insert immediately before\n * @returns A fresh group with `factor` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no existing factor\n *\n * @example\n * ```ts\n * import { factorGroup, prependFactor, staticFactor } from '@src/core'\n *\n * prependFactor(factorGroup('g1', 'sum', []), staticFactor('f1', 10))\n * ```\n */\nexport function prependFactor(group: FactorGroup, factor: Factor, target?: string): FactorGroup {\n\treturn { ...group, factors: prependById(group.factors, factor, target) }\n}\n\n/**\n * Swap the factor sharing `factor.id` in a {@link FactorGroup} IN PLACE,\n * preserving its position (appends when absent).\n *\n * @param group - The group to update\n * @param factor - The replacement factor\n * @returns A fresh group with the factor replaced\n *\n * @example\n * ```ts\n * import { factorGroup, replaceFactor, staticFactor } from '@src/core'\n *\n * const group = factorGroup('g1', 'sum', [staticFactor('f1', 10)])\n * replaceFactor(group, staticFactor('f1', 20))\n * ```\n */\nexport function replaceFactor(group: FactorGroup, factor: Factor): FactorGroup {\n\treturn { ...group, factors: replaceById(group.factors, factor) }\n}\n\n/**\n * Remove every factor sharing `id` from a {@link FactorGroup} (no-op when\n * absent).\n *\n * @param group - The group to update\n * @param id - The factor id to remove\n * @returns A fresh group with the factor removed\n *\n * @example\n * ```ts\n * import { factorGroup, removeFactor, staticFactor } from '@src/core'\n *\n * removeFactor(factorGroup('g1', 'sum', [staticFactor('f1', 10)]), 'f1').factors // []\n * ```\n */\nexport function removeFactor(group: FactorGroup, id: string): FactorGroup {\n\treturn { ...group, factors: removeById(group.factors, id) }\n}\n\n// === Logical change/extend helpers (PROPOSAL.md §8)\n\n/**\n * Insert `rule` into a {@link LogicalDefinition}'s `rules` — dedup-then-insert\n * at the end, or immediately after `target`.\n *\n * @remarks\n * Order is LOAD-BEARING: the forward conclusion is the LAST declared\n * non-disabled rule, so `appendRule` without a `target` makes the new rule the\n * conclusion.\n *\n * @param definition - The definition to insert into\n * @param source - The rule to insert\n * @param target - Optional rule id to insert immediately after\n * @returns A fresh definition with `rule` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no existing rule\n *\n * @example\n * ```ts\n * import { appendRule, atom, logicalDefinition, rule } from '@src/core'\n *\n * appendRule(logicalDefinition('e', 'E', []), rule('r1', [], atom('a', 'equals', true)))\n * ```\n */\nexport function appendRule(\n\tdefinition: LogicalDefinition,\n\tsource: Rule,\n\ttarget?: string,\n): LogicalDefinition {\n\treturn { ...definition, rules: appendById(definition.rules, source, target) }\n}\n\n/**\n * Insert `rule` into a {@link LogicalDefinition}'s `rules` — dedup-then-insert\n * at the start, or immediately before `target`.\n *\n * @param definition - The definition to insert into\n * @param source - The rule to insert\n * @param target - Optional rule id to insert immediately before\n * @returns A fresh definition with `rule` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no existing rule\n *\n * @example\n * ```ts\n * import { atom, logicalDefinition, prependRule, rule } from '@src/core'\n *\n * prependRule(logicalDefinition('e', 'E', []), rule('r1', [], atom('a', 'equals', true)))\n * ```\n */\nexport function prependRule(\n\tdefinition: LogicalDefinition,\n\tsource: Rule,\n\ttarget?: string,\n): LogicalDefinition {\n\treturn { ...definition, rules: prependById(definition.rules, source, target) }\n}\n\n/**\n * Swap the rule sharing `rule.id` in a {@link LogicalDefinition} IN PLACE,\n * preserving its position (appends when absent).\n *\n * @param definition - The definition to update\n * @param source - The replacement rule\n * @returns A fresh definition with the rule replaced\n *\n * @example\n * ```ts\n * import { atom, logicalDefinition, replaceRule, rule } from '@src/core'\n *\n * const definition = logicalDefinition('e', 'E', [rule('r1', [], atom('a', 'equals', true))])\n * replaceRule(definition, rule('r1', [], atom('a', 'equals', false)))\n * ```\n */\nexport function replaceRule(definition: LogicalDefinition, source: Rule): LogicalDefinition {\n\treturn { ...definition, rules: replaceById(definition.rules, source) }\n}\n\n/**\n * Remove every rule sharing `id` from a {@link LogicalDefinition} (no-op when\n * absent).\n *\n * @param definition - The definition to update\n * @param id - The rule id to remove\n * @returns A fresh definition with the rule removed\n *\n * @example\n * ```ts\n * import { atom, logicalDefinition, removeRule, rule } from '@src/core'\n *\n * const definition = logicalDefinition('e', 'E', [rule('r1', [], atom('a', 'equals', true))])\n * removeRule(definition, 'r1').rules // []\n * ```\n */\nexport function removeRule(definition: LogicalDefinition, id: string): LogicalDefinition {\n\treturn { ...definition, rules: removeById(definition.rules, id) }\n}\n\n// === Symbolic change/extend helpers (PROPOSAL.md §8)\n\n/**\n * Insert `equation` into a {@link SymbolicDefinition}'s `equations` — dedup-\n * then-insert at the end, or immediately after `target`.\n *\n * @remarks\n * Order is STRONGLY load-bearing: equations solve strictly in order and each\n * rounded solution feeds forward.\n *\n * @param definition - The definition to insert into\n * @param source - The equation to insert\n * @param target - Optional equation id to insert immediately after\n * @returns A fresh definition with `equation` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no existing equation\n *\n * @example\n * ```ts\n * import { appendEquation, constant, equation, symbolicDefinition, variable } from '@src/core'\n *\n * appendEquation(symbolicDefinition('e', 'E', []), equation('e1', variable('x'), constant(1), 'x'))\n * ```\n */\nexport function appendEquation(\n\tdefinition: SymbolicDefinition,\n\tsource: Equation,\n\ttarget?: string,\n): SymbolicDefinition {\n\treturn { ...definition, equations: appendById(definition.equations, source, target) }\n}\n\n/**\n * Insert `equation` into a {@link SymbolicDefinition}'s `equations` — dedup-\n * then-insert at the start, or immediately before `target`.\n *\n * @param definition - The definition to insert into\n * @param source - The equation to insert\n * @param target - Optional equation id to insert immediately before\n * @returns A fresh definition with `equation` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no existing equation\n *\n * @example\n * ```ts\n * import { constant, equation, prependEquation, symbolicDefinition, variable } from '@src/core'\n *\n * prependEquation(symbolicDefinition('e', 'E', []), equation('e1', variable('x'), constant(1), 'x'))\n * ```\n */\nexport function prependEquation(\n\tdefinition: SymbolicDefinition,\n\tsource: Equation,\n\ttarget?: string,\n): SymbolicDefinition {\n\treturn { ...definition, equations: prependById(definition.equations, source, target) }\n}\n\n/**\n * Swap the equation sharing `equation.id` in a {@link SymbolicDefinition} IN\n * PLACE, preserving its position (appends when absent).\n *\n * @param definition - The definition to update\n * @param source - The replacement equation\n * @returns A fresh definition with the equation replaced\n *\n * @example\n * ```ts\n * import { constant, equation, replaceEquation, symbolicDefinition, variable } from '@src/core'\n *\n * const definition = symbolicDefinition('e', 'E', [equation('e1', variable('x'), constant(1), 'x')])\n * replaceEquation(definition, equation('e1', variable('x'), constant(2), 'x'))\n * ```\n */\nexport function replaceEquation(\n\tdefinition: SymbolicDefinition,\n\tsource: Equation,\n): SymbolicDefinition {\n\treturn { ...definition, equations: replaceById(definition.equations, source) }\n}\n\n/**\n * Remove every equation sharing `id` from a {@link SymbolicDefinition} (no-op\n * when absent).\n *\n * @param definition - The definition to update\n * @param id - The equation id to remove\n * @returns A fresh definition with the equation removed\n *\n * @example\n * ```ts\n * import { constant, equation, removeEquation, symbolicDefinition, variable } from '@src/core'\n *\n * const definition = symbolicDefinition('e', 'E', [equation('e1', variable('x'), constant(1), 'x')])\n * removeEquation(definition, 'e1').equations // []\n * ```\n */\nexport function removeEquation(definition: SymbolicDefinition, id: string): SymbolicDefinition {\n\treturn { ...definition, equations: removeById(definition.equations, id) }\n}\n\n/**\n * Upsert one entry of a {@link SymbolicDefinition}'s `variables`.\n *\n * @remarks\n * `variables` is a name-keyed unordered record, so `add`/`remove` (no\n * placement) are the correct verbs — mirrored by {@link removeVariable}.\n *\n * @param definition - The definition to update\n * @param name - The variable name\n * @param value - The variable's value\n * @returns A fresh definition with the variable set\n *\n * @example\n * ```ts\n * import { addVariable, symbolicDefinition } from '@src/core'\n *\n * addVariable(symbolicDefinition('e', 'E', []), 'x', 5).variables // { x: 5 }\n * ```\n */\nexport function addVariable(\n\tdefinition: SymbolicDefinition,\n\tname: string,\n\tvalue: number,\n): SymbolicDefinition {\n\treturn { ...definition, variables: { ...definition.variables, [name]: value } }\n}\n\n/**\n * Remove one entry of a {@link SymbolicDefinition}'s `variables`.\n *\n * @remarks\n * The destructure-rest form OMITS the key entirely (never sets it to\n * `undefined`), keeping the result exact-record valid. A no-op (fresh copy)\n * when `name` is absent.\n *\n * @param definition - The definition to update\n * @param name - The variable name to remove\n * @returns A fresh definition with the variable removed\n *\n * @example\n * ```ts\n * import { removeVariable, symbolicDefinition } from '@src/core'\n *\n * removeVariable(symbolicDefinition('e', 'E', [], { variables: { x: 5 } }), 'x').variables // {}\n * ```\n */\nexport function removeVariable(definition: SymbolicDefinition, name: string): SymbolicDefinition {\n\tconst { [name]: _drop, ...rest } = definition.variables\n\treturn { ...definition, variables: rest }\n}\n\n// === Inferential change/extend helpers (PROPOSAL.md §8)\n\n/**\n * Insert `fact` into an {@link InferentialDefinition}'s `facts` — dedup-then-\n * insert at the end, or immediately after `target`.\n *\n * @remarks\n * `Fact.id` is an AUTHORING label — the runtime content-dedups facts by\n * predicate+arity+terms ({@link factToKey}), independently of this helper's\n * id-keyed dedup.\n *\n * @param definition - The definition to insert into\n * @param source - The fact to insert\n * @param target - Optional fact id to insert immediately after\n * @returns A fresh definition with `fact` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no existing fact\n *\n * @example\n * ```ts\n * import { appendFact, fact, inferentialDefinition } from '@src/core'\n *\n * appendFact(inferentialDefinition('m', 'M', [], []), fact('f1', 'human', ['socrates']))\n * ```\n */\nexport function appendFact(\n\tdefinition: InferentialDefinition,\n\tsource: Fact,\n\ttarget?: string,\n): InferentialDefinition {\n\treturn { ...definition, facts: appendById(definition.facts, source, target) }\n}\n\n/**\n * Insert `fact` into an {@link InferentialDefinition}'s `facts` — dedup-then-\n * insert at the start, or immediately before `target`.\n *\n * @param definition - The definition to insert into\n * @param source - The fact to insert\n * @param target - Optional fact id to insert immediately before\n * @returns A fresh definition with `fact` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no existing fact\n *\n * @example\n * ```ts\n * import { fact, inferentialDefinition, prependFact } from '@src/core'\n *\n * prependFact(inferentialDefinition('m', 'M', [], []), fact('f1', 'human', ['socrates']))\n * ```\n */\nexport function prependFact(\n\tdefinition: InferentialDefinition,\n\tsource: Fact,\n\ttarget?: string,\n): InferentialDefinition {\n\treturn { ...definition, facts: prependById(definition.facts, source, target) }\n}\n\n/**\n * Swap the fact sharing `fact.id` in an {@link InferentialDefinition} IN\n * PLACE, preserving its position (appends when absent).\n *\n * @param definition - The definition to update\n * @param source - The replacement fact\n * @returns A fresh definition with the fact replaced\n *\n * @example\n * ```ts\n * import { fact, inferentialDefinition, replaceFact } from '@src/core'\n *\n * const definition = inferentialDefinition('m', 'M', [fact('f1', 'human', ['socrates'])], [])\n * replaceFact(definition, fact('f1', 'human', ['plato']))\n * ```\n */\nexport function replaceFact(\n\tdefinition: InferentialDefinition,\n\tsource: Fact,\n): InferentialDefinition {\n\treturn { ...definition, facts: replaceById(definition.facts, source) }\n}\n\n/**\n * Remove every fact sharing `id` from an {@link InferentialDefinition} (no-op\n * when absent).\n *\n * @param definition - The definition to update\n * @param id - The fact id to remove\n * @returns A fresh definition with the fact removed\n *\n * @example\n * ```ts\n * import { fact, inferentialDefinition, removeFact } from '@src/core'\n *\n * const definition = inferentialDefinition('m', 'M', [fact('f1', 'human', ['socrates'])], [])\n * removeFact(definition, 'f1').facts // []\n * ```\n */\nexport function removeFact(definition: InferentialDefinition, id: string): InferentialDefinition {\n\treturn { ...definition, facts: removeById(definition.facts, id) }\n}\n\n/**\n * Insert `inference` into an {@link InferentialDefinition}'s `inferences` —\n * dedup-then-insert at the end, or immediately after `target`.\n *\n * @remarks\n * Order is LOAD-BEARING: backward proving iterates in declaration order and\n * returns on first success.\n *\n * @param definition - The definition to insert into\n * @param source - The inference to insert\n * @param target - Optional inference id to insert immediately after\n * @returns A fresh definition with `inference` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no existing inference\n *\n * @example\n * ```ts\n * import { appendInference, fact, inference, inferentialDefinition } from '@src/core'\n *\n * appendInference(\n * \tinferentialDefinition('m', 'M', [], []),\n * \tinference('i1', [fact('p', 'human', ['?x'])], fact('c', 'mortal', ['?x'])),\n * )\n * ```\n */\nexport function appendInference(\n\tdefinition: InferentialDefinition,\n\tsource: Inference,\n\ttarget?: string,\n): InferentialDefinition {\n\treturn { ...definition, inferences: appendById(definition.inferences, source, target) }\n}\n\n/**\n * Insert `inference` into an {@link InferentialDefinition}'s `inferences` —\n * dedup-then-insert at the start, or immediately before `target`.\n *\n * @param definition - The definition to insert into\n * @param source - The inference to insert\n * @param target - Optional inference id to insert immediately before\n * @returns A fresh definition with `inference` inserted\n * @throws {@link ReasonError} `'TARGET'` when `target` names no existing inference\n *\n * @example\n * ```ts\n * import { fact, inference, inferentialDefinition, prependInference } from '@src/core'\n *\n * prependInference(\n * \tinferentialDefinition('m', 'M', [], []),\n * \tinference('i1', [fact('p', 'human', ['?x'])], fact('c', 'mortal', ['?x'])),\n * )\n * ```\n */\nexport function prependInference(\n\tdefinition: InferentialDefinition,\n\tsource: Inference,\n\ttarget?: string,\n): InferentialDefinition {\n\treturn { ...definition, inferences: prependById(definition.inferences, source, target) }\n}\n\n/**\n * Swap the inference sharing `inference.id` in an {@link InferentialDefinition}\n * IN PLACE, preserving its position (appends when absent).\n *\n * @param definition - The definition to update\n * @param source - The replacement inference\n * @returns A fresh definition with the inference replaced\n *\n * @example\n * ```ts\n * import { fact, inference, inferentialDefinition, replaceInference } from '@src/core'\n *\n * const original = inference('i1', [fact('p', 'human', ['?x'])], fact('c', 'mortal', ['?x']))\n * const definition = inferentialDefinition('m', 'M', [], [original])\n * replaceInference(definition, inference('i1', [], fact('c', 'mortal', ['?x'])))\n * ```\n */\nexport function replaceInference(\n\tdefinition: InferentialDefinition,\n\tsource: Inference,\n): InferentialDefinition {\n\treturn { ...definition, inferences: replaceById(definition.inferences, source) }\n}\n\n/**\n * Remove every inference sharing `id` from an {@link InferentialDefinition}\n * (no-op when absent).\n *\n * @param definition - The definition to update\n * @param id - The inference id to remove\n * @returns A fresh definition with the inference removed\n *\n * @example\n * ```ts\n * import { fact, inference, inferentialDefinition, removeInference } from '@src/core'\n *\n * const original = inference('i1', [fact('p', 'human', ['?x'])], fact('c', 'mortal', ['?x']))\n * removeInference(inferentialDefinition('m', 'M', [], [original]), 'i1').inferences // []\n * ```\n */\nexport function removeInference(\n\tdefinition: InferentialDefinition,\n\tid: string,\n): InferentialDefinition {\n\treturn { ...definition, inferences: removeById(definition.inferences, id) }\n}\n\n// === Merge helpers — whole-definition reconciliation (PROPOSAL.md §9)\n//\n// Model: id-keyed upsert, incoming order wins, base-only survivors retained\n// (never deleted — additive). `base.id` (and `reasoning`) are preserved.\n// Scalars / value-object fields are incoming-wins-WHEN-PRESENT, else base is\n// kept — merge NEVER clears (that is `clear*`'s job, §10).\n\n/**\n * Reconcile two {@link QuantitativeDefinition}s onto `base`'s id.\n *\n * @remarks\n * `groups` merges via {@link mergeById}; a matched (same-id) PAIR of groups\n * recurses one level deeper — their `factors` also merge via `mergeById` — the\n * one exception to incoming-wins-wholesale (PROPOSAL.md §9). Every other\n * scalar / value-object field is incoming-wins-when-present, else base kept.\n *\n * @param base - The definition merge targets (its `id` is preserved)\n * @param incoming - The definition merged in (its order and matches take priority)\n * @returns A fresh, reconciled definition\n *\n * @example\n * ```ts\n * import { factorGroup, mergeQuantitativeDefinition, quantitativeDefinition } from '@src/core'\n *\n * const base = quantitativeDefinition('risk', 'Risk', [factorGroup('g1', 'sum', [])])\n * const incoming = quantitativeDefinition('risk', 'Risk v2', [factorGroup('g2', 'sum', [])])\n * mergeQuantitativeDefinition(base, incoming).groups.map((g) => g.id) // ['g2', 'g1']\n * ```\n */\nexport function mergeQuantitativeDefinition(\n\tbase: QuantitativeDefinition,\n\tincoming: QuantitativeDefinition,\n): QuantitativeDefinition {\n\tconst groups = mergeById(base.groups, incoming.groups, (baseGroup, incomingGroup) => ({\n\t\t...incomingGroup,\n\t\tfactors: mergeById(baseGroup.factors, incomingGroup.factors),\n\t}))\n\treturn {\n\t\t...base,\n\t\tname: incoming.name,\n\t\taggregation: incoming.aggregation,\n\t\tgroups,\n\t\t...(Object.hasOwn(incoming, 'description') ? { description: incoming.description } : {}),\n\t\t...(Object.hasOwn(incoming, 'base') ? { base: incoming.base } : {}),\n\t\t...(Object.hasOwn(incoming, 'bounds') ? { bounds: incoming.bounds } : {}),\n\t\t...(Object.hasOwn(incoming, 'precision') ? { precision: incoming.precision } : {}),\n\t}\n}\n\n/**\n * Reconcile two {@link LogicalDefinition}s onto `base`'s id.\n *\n * @remarks\n * `rules` merges via {@link mergeById} (incoming-wins-wholesale on a matched\n * id). Every other scalar field is incoming-wins-when-present, else base kept.\n *\n * @param base - The definition merge targets (its `id` is preserved)\n * @param incoming - The definition merged in (its order and matches take priority)\n * @returns A fresh, reconciled definition\n *\n * @example\n * ```ts\n * import { atom, logicalDefinition, mergeLogicalDefinition, rule } from '@src/core'\n *\n * const base = logicalDefinition('e', 'E', [rule('r1', [], atom('a', 'equals', true))])\n * const incoming = logicalDefinition('e', 'E2', [rule('r2', [], atom('b', 'equals', true))])\n * mergeLogicalDefinition(base, incoming).rules.map((r) => r.id) // ['r2', 'r1']\n * ```\n */\nexport function mergeLogicalDefinition(\n\tbase: LogicalDefinition,\n\tincoming: LogicalDefinition,\n): LogicalDefinition {\n\treturn {\n\t\t...base,\n\t\tname: incoming.name,\n\t\tstrategy: incoming.strategy,\n\t\trules: mergeById(base.rules, incoming.rules),\n\t\t...(Object.hasOwn(incoming, 'description') ? { description: incoming.description } : {}),\n\t\t...(Object.hasOwn(incoming, 'depth') ? { depth: incoming.depth } : {}),\n\t}\n}\n\n/**\n * Reconcile two {@link SymbolicDefinition}s onto `base`'s id.\n *\n * @remarks\n * `equations` merges via {@link mergeById} (incoming-wins-wholesale on a\n * matched id); `variables` is a plain incoming-wins spread\n * (`{ ...base.variables, ...incoming.variables }`). Every other scalar field\n * is incoming-wins-when-present, else base kept.\n *\n * @param base - The definition merge targets (its `id` is preserved)\n * @param incoming - The definition merged in (its order, matches, and variables take priority)\n * @returns A fresh, reconciled definition\n *\n * @example\n * ```ts\n * import { constant, equation, mergeSymbolicDefinition, symbolicDefinition, variable } from '@src/core'\n *\n * const base = symbolicDefinition('e', 'E', [], { variables: { x: 1 } })\n * const incoming = symbolicDefinition('e', 'E2', [equation('e1', variable('x'), constant(2), 'x')], {\n * \tvariables: { y: 2 },\n * })\n * mergeSymbolicDefinition(base, incoming).variables // { x: 1, y: 2 }\n * ```\n */\nexport function mergeSymbolicDefinition(\n\tbase: SymbolicDefinition,\n\tincoming: SymbolicDefinition,\n): SymbolicDefinition {\n\treturn {\n\t\t...base,\n\t\tname: incoming.name,\n\t\tequations: mergeById(base.equations, incoming.equations),\n\t\tvariables: { ...base.variables, ...incoming.variables },\n\t\t...(Object.hasOwn(incoming, 'description') ? { description: incoming.description } : {}),\n\t\t...(Object.hasOwn(incoming, 'precision') ? { precision: incoming.precision } : {}),\n\t}\n}\n\n/**\n * Reconcile two {@link InferentialDefinition}s onto `base`'s id.\n *\n * @remarks\n * `inferences` and `facts` each merge via {@link mergeById}\n * (incoming-wins-wholesale on a matched id). Every other scalar field is\n * incoming-wins-when-present, else base kept.\n *\n * @param base - The definition merge targets (its `id` is preserved)\n * @param incoming - The definition merged in (its order and matches take priority)\n * @returns A fresh, reconciled definition\n *\n * @example\n * ```ts\n * import { fact, inferentialDefinition, mergeInferentialDefinition } from '@src/core'\n *\n * const base = inferentialDefinition('m', 'M', [fact('f1', 'human', ['a'])], [])\n * const incoming = inferentialDefinition('m', 'M2', [fact('f2', 'human', ['b'])], [])\n * mergeInferentialDefinition(base, incoming).facts.map((f) => f.id) // ['f2', 'f1']\n * ```\n */\nexport function mergeInferentialDefinition(\n\tbase: InferentialDefinition,\n\tincoming: InferentialDefinition,\n): InferentialDefinition {\n\treturn {\n\t\t...base,\n\t\tname: incoming.name,\n\t\tstrategy: incoming.strategy,\n\t\tinferences: mergeById(base.inferences, incoming.inferences),\n\t\tfacts: mergeById(base.facts, incoming.facts),\n\t\t...(Object.hasOwn(incoming, 'description') ? { description: incoming.description } : {}),\n\t\t...(Object.hasOwn(incoming, 'depth') ? { depth: incoming.depth } : {}),\n\t}\n}\n\n// === Clear helpers — optional-field key-deletion (PROPOSAL.md §10)\n//\n// `const { [key]: _drop, ...rest } = definition; return rest` — the\n// destructure-rest form sidesteps oxlint `no-param-reassign` friction, and the\n// result OMITS the key entirely (never sets it to `undefined`), keeping the\n// definition exact-record valid.\n\n/**\n * Delete one optional field of a {@link QuantitativeDefinition}.\n *\n * @param definition - The definition to update\n * @param key - The optional field to clear\n * @returns A fresh definition with `key` omitted\n *\n * @example\n * ```ts\n * import { clearQuantitativeDefinition, quantitativeDefinition } from '@src/core'\n *\n * const definition = quantitativeDefinition('risk', 'Risk', [], { precision: 2 })\n * 'precision' in clearQuantitativeDefinition(definition, 'precision') // false\n * ```\n */\nexport function clearQuantitativeDefinition(\n\tdefinition: QuantitativeDefinition,\n\tkey: 'description' | 'base' | 'bounds' | 'precision',\n): QuantitativeDefinition {\n\tconst { [key]: _drop, ...rest } = definition\n\treturn rest\n}\n\n/**\n * Delete one optional field of a {@link LogicalDefinition}.\n *\n * @param definition - The definition to update\n * @param key - The optional field to clear\n * @returns A fresh definition with `key` omitted\n *\n * @example\n * ```ts\n * import { clearLogicalDefinition, logicalDefinition } from '@src/core'\n *\n * const definition = logicalDefinition('e', 'E', [], { depth: 5 })\n * 'depth' in clearLogicalDefinition(definition, 'depth') // false\n * ```\n */\nexport function clearLogicalDefinition(\n\tdefinition: LogicalDefinition,\n\tkey: 'description' | 'depth',\n): LogicalDefinition {\n\tconst { [key]: _drop, ...rest } = definition\n\treturn rest\n}\n\n/**\n * Delete one optional field of a {@link SymbolicDefinition}.\n *\n * @param definition - The definition to update\n * @param key - The optional field to clear\n * @returns A fresh definition with `key` omitted\n *\n * @example\n * ```ts\n * import { clearSymbolicDefinition, symbolicDefinition } from '@src/core'\n *\n * const definition = symbolicDefinition('e', 'E', [], { precision: 2 })\n * 'precision' in clearSymbolicDefinition(definition, 'precision') // false\n * ```\n */\nexport function clearSymbolicDefinition(\n\tdefinition: SymbolicDefinition,\n\tkey: 'description' | 'precision',\n): SymbolicDefinition {\n\tconst { [key]: _drop, ...rest } = definition\n\treturn rest\n}\n\n/**\n * Delete one optional field of an {@link InferentialDefinition}.\n *\n * @param definition - The definition to update\n * @param key - The optional field to clear\n * @returns A fresh definition with `key` omitted\n *\n * @example\n * ```ts\n * import { clearInferentialDefinition, inferentialDefinition } from '@src/core'\n *\n * const definition = inferentialDefinition('m', 'M', [], [], { depth: 5 })\n * 'depth' in clearInferentialDefinition(definition, 'depth') // false\n * ```\n */\nexport function clearInferentialDefinition(\n\tdefinition: InferentialDefinition,\n\tkey: 'description' | 'depth',\n): InferentialDefinition {\n\tconst { [key]: _drop, ...rest } = definition\n\treturn rest\n}\n\n// === Store-ability (PROPOSAL.md §12)\n\n/**\n * Parse a JSON string into a {@link Definition}, failing safe to `undefined`.\n *\n * @remarks\n * The safe inverse of the builders: `parseJSONAs` composed with the data guard\n * {@link isDefinition}. A built definition body IS the durable JSON payload —\n * `JSON.stringify(definition)` round-trips through `parseDefinition`. Two\n * authoring hazards: a required `Check.value: undefined` drops its key on\n * `JSON.stringify` (author `null` instead), and a `Fact.terms` element of\n * `undefined` serializes to `null` (terms must be JSON-safe scalars/strings).\n *\n * @param json - The JSON text to parse\n * @returns A {@link Definition} of any reasoning, or `undefined` when malformed\n *\n * @example\n * ```ts\n * import { logicalDefinition, parseDefinition } from '@src/core'\n *\n * const text = JSON.stringify(logicalDefinition('e', 'E', []))\n * parseDefinition(text) // the definition, restored\n * parseDefinition('{}') // undefined — fails safe\n * ```\n */\nexport function parseDefinition(json: string): Definition | undefined {\n\treturn parseJSONAs(json, isDefinition)\n}\n\n// === Subject engine (PROPOSAL.md §11)\n//\n// The subject counterpart of the definition engine above — four pure helpers.\n// Records are unordered, so there is no `append*`/`prepend*` on a subject\n// (mirrors the `addVariable`/`removeVariable` note, §8). Named `assignField`,\n// not `setField` — the core layer already exports a `FieldPath`-deep, in-place\n// `setField` (`src/core/helpers.ts:139`, returns `void`); reusing that token\n// for this pure, `Subject`-returning upsert would collide in the `@src/core`\n// barrel and violate AGENTS §4.4 (identical verbs must mean identical things).\n\n/**\n * Upsert one field of a {@link Subject} — copy-on-write spread.\n *\n * @remarks\n * Id-agnostic: overwrites an `id` key like any other field — id protection is\n * an entity's job, not this helper's.\n *\n * @param subject - The subject to update\n * @param key - The field to set\n * @param value - The value to set it to\n * @returns A fresh subject with `key` set to `value`\n *\n * @example\n * ```ts\n * import { assignField } from '@src/core'\n *\n * assignField({ id: 's1', age: 30 }, 'age', 31) // { id: 's1', age: 31 }\n * ```\n */\nexport function assignField(subject: Subject, key: string, value: unknown): Subject {\n\treturn { ...subject, [key]: value }\n}\n\n/**\n * Delete one field of a {@link Subject} — destructure-rest omit.\n *\n * @remarks\n * The key is DELETED entirely (never set to `undefined`), keeping the result\n * exact-record valid. A no-op (fresh copy) when `key` is absent.\n *\n * @param subject - The subject to update\n * @param key - The field to delete\n * @returns A fresh subject with `key` omitted\n *\n * @example\n * ```ts\n * import { removeField } from '@src/core'\n *\n * removeField({ id: 's1', age: 30 }, 'age') // { id: 's1' }\n * ```\n */\nexport function removeField(subject: Subject, key: string): Subject {\n\tconst { [key]: _drop, ...rest } = subject\n\treturn rest\n}\n\n/**\n * Reconcile two {@link Subject}s — incoming-wins spread, with the base `id`\n * preserved when present.\n *\n * @remarks\n * Mirrors the definition merge's base-id-wins rule: `{ ...base, ...incoming }`\n * with `base.id` restored afterward when `base` carries an own `id`.\n *\n * @param base - The subject merge targets (its `id` is preserved when present)\n * @param incoming - The subject merged in (its fields take priority)\n * @returns A fresh, reconciled subject\n *\n * @example\n * ```ts\n * import { mergeSubjects } from '@src/core'\n *\n * mergeSubjects({ id: 's1', age: 30 }, { age: 31, name: 'Alice' })\n * // { id: 's1', age: 31, name: 'Alice' }\n * ```\n */\nexport function mergeSubjects(base: Subject, incoming: Subject): Subject {\n\tconst merged = { ...base, ...incoming }\n\treturn Object.hasOwn(base, 'id') ? { ...merged, id: base.id } : merged\n}\n\n/**\n * Produce `count` deterministic clones of a {@link Subject}.\n *\n * @remarks\n * When `subject.id` is a string, each clone's id is minted\n * `` `${baseId}-${index}` `` (index from `0`); with no string `id`, the clones\n * pass through unchanged (still fresh copies). Pure and deterministic — the\n * same input always produces the same output (run-twice equality) — and does\n * NOT emit. `count <= 0` yields an empty array.\n *\n * @param subject - The subject to clone\n * @param count - How many clones to produce\n * @returns The `count`-long array of clones\n *\n * @example\n * ```ts\n * import { repeatSubject } from '@src/core'\n *\n * repeatSubject({ id: 's1', age: 30 }, 2) // [{ id: 's1-0', age: 30 }, { id: 's1-1', age: 30 }]\n * repeatSubject({ age: 30 }, 2) // [{ age: 30 }, { age: 30 }] — no id to mint from\n * ```\n */\nexport function repeatSubject(subject: Subject, count: number): readonly Subject[] {\n\tconst baseId = subject.id\n\tconst clones: Subject[] = []\n\tfor (let index = 0; index < count; index += 1) {\n\t\tclones.push(\n\t\t\ttypeof baseId === 'string' ? { ...subject, id: `${baseId}-${index}` } : { ...subject },\n\t\t)\n\t}\n\treturn clones\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tDefinition,\n\tReasonEventMap,\n\tReasonInterface,\n\tReasonOptions,\n\tReasoning,\n\tReasonResult,\n\tReasonValidationResult,\n\tReasonerInterface,\n\tSubject,\n} from './types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { isArray } from '@orkestrel/contract'\nimport { buildErrorResult } from './helpers.js'\nimport { DEFAULT_REASON_BAIL, DEFAULT_VALIDATE } from './constants.js'\nimport { ReasonError } from './errors.js'\n\n/**\n * The reasoning orchestrator — a thin router over registered\n * {@link ReasonerInterface}s.\n *\n * @remarks\n * Holds NO strategy-specific logic: dispatch is purely a registry lookup by\n * `definition.reasoning` (one reasoner per reasoning; re-registration\n * replaces). A missing reasoner throws `MISSING` and a pre-run validation\n * failure (when the `validate` option is on) throws `INVALID` — both BYPASS\n * `bail` and emit nothing. A reasoner throw emits `error` with the raw thrown\n * value, then rethrows under `bail: true` (the default) or converts to a\n * type-shaped failure result under `bail: false`; only SUCCESSFUL results emit\n * `reason` (synchronously, before returning). The batch overload maps subjects\n * in order (validation, when on, repeats per subject). `destroy()` clears the\n * registry, emits `destroy`, then destroys the emitter LAST (AGENTS §13) and is\n * idempotent; every other method afterwards throws `DESTROYED` — only the\n * {@link emitter} getter keeps working.\n */\nexport class Reason implements ReasonInterface {\n\treadonly #reasoners = new Map<Reasoning, ReasonerInterface>()\n\treadonly #bail: boolean\n\treadonly #validate: boolean\n\treadonly #emitter: Emitter<ReasonEventMap>\n\t#destroyed = false\n\n\tconstructor(options?: ReasonOptions) {\n\t\tthis.#bail = options?.bail ?? DEFAULT_REASON_BAIL\n\t\tthis.#validate = options?.validate ?? DEFAULT_VALIDATE\n\t\tthis.#emitter = new Emitter<ReasonEventMap>({ on: options?.on, error: options?.error })\n\t\t// A later entry of the same reasoning replaces an earlier one.\n\t\tfor (const reasoner of options?.reasoners ?? []) {\n\t\t\tthis.#reasoners.set(reasoner.reasoning, reasoner)\n\t\t}\n\t}\n\n\tget emitter(): EmitterInterface<ReasonEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\t// Array overload first (AGENTS §9) so a list resolves to the batch form.\n\treason(subjects: readonly Subject[], definition: Definition): readonly ReasonResult[]\n\treason(subject: Subject, definition: Definition): ReasonResult\n\treason(\n\t\tsubject: Subject | readonly Subject[],\n\t\tdefinition: Definition,\n\t): ReasonResult | readonly ReasonResult[] {\n\t\tthis.#ensureAlive()\n\t\tif (isArray<Subject>(subject)) {\n\t\t\treturn subject.map((entry) => this.#reasonOne(entry, definition))\n\t\t}\n\t\treturn this.#reasonOne(subject, definition)\n\t}\n\n\tregister(reasoner: ReasonerInterface): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#reasoners.set(reasoner.reasoning, reasoner)\n\t\tthis.#emitter.emit('register', reasoner.reasoning)\n\t}\n\n\treasoner(reasoning: Reasoning): ReasonerInterface | undefined {\n\t\tthis.#ensureAlive()\n\t\treturn this.#reasoners.get(reasoning)\n\t}\n\n\treasoners(): readonly ReasonerInterface[] {\n\t\tthis.#ensureAlive()\n\t\treturn [...this.#reasoners.values()]\n\t}\n\n\tsupports(reasoning: Reasoning): boolean {\n\t\tthis.#ensureAlive()\n\t\treturn this.#reasoners.has(reasoning)\n\t}\n\n\tvalidate(definition: Definition): ReasonValidationResult {\n\t\tthis.#ensureAlive()\n\t\tconst reasoner = this.#reasoners.get(definition.reasoning)\n\t\t// A missing reasoner is an invalid RESULT here (reason() is where it throws).\n\t\tif (!reasoner) {\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\terrors: [`No reasoner registered for reasoning \"${definition.reasoning}\"`],\n\t\t\t\twarnings: [],\n\t\t\t}\n\t\t}\n\t\treturn reasoner.validate(definition)\n\t}\n\n\tdestroy(): void {\n\t\t// Idempotent by construction: a second call clears an empty registry and\n\t\t// emits into an already-destroyed emitter (a no-op).\n\t\tthis.#reasoners.clear()\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.emit('destroy')\n\t\tthis.#emitter.destroy()\n\t}\n\n\t// Dispatch one subject: registry lookup → optional validation → run, with\n\t// the bail policy deciding whether a reasoner throw escapes.\n\t#reasonOne(subject: Subject, definition: Definition): ReasonResult {\n\t\tconst reasoner = this.#reasoners.get(definition.reasoning)\n\t\tif (!reasoner) {\n\t\t\t// Bypasses bail and emits nothing — a registry miss is caller misuse (§12).\n\t\t\tthrow new ReasonError(\n\t\t\t\t'MISSING',\n\t\t\t\t`No reasoner registered for reasoning \"${definition.reasoning}\"`,\n\t\t\t\t{ definition: definition.id, reasoning: definition.reasoning },\n\t\t\t)\n\t\t}\n\n\t\tif (this.#validate) {\n\t\t\tconst validation = reasoner.validate(definition)\n\t\t\tif (!validation.valid) {\n\t\t\t\t// Also bypasses bail and emits nothing — pre-run, not a reasoner fault.\n\t\t\t\tthrow new ReasonError('INVALID', `Validation failed: ${validation.errors.join(', ')}`, {\n\t\t\t\t\tdefinition: definition.id,\n\t\t\t\t\treasoning: definition.reasoning,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = reasoner.reason(subject, definition)\n\t\t\tthis.#emitter.emit('reason', result)\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t\tif (this.#bail) throw error\n\t\t\t// bail: false converts the throw into a type-shaped failure result —\n\t\t\t// which does NOT emit 'reason'.\n\t\t\tconst message = error instanceof Error ? error.message : String(error)\n\t\t\treturn buildErrorResult(definition, message)\n\t\t}\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) {\n\t\t\tthrow new ReasonError('DESTROYED', 'Reason has been destroyed')\n\t\t}\n\t}\n}\n","import type { Check, CheckResult, EvaluatorInterface, EvaluatorOptions, Subject } from '../types.js'\nimport { isArray, isNumber, resolveField } from '@orkestrel/contract'\nimport { EVALUATOR_ID } from '../constants.js'\n\n/**\n * Evaluates {@link Check}s against subjects — the shared predicate engine of the\n * quantitative and logical reasoners.\n *\n * @remarks\n * TOTAL and strict: `evaluate` never throws (an unknown operator is caught and\n * surfaced as `CheckResult.error` with `met: false`) and never coerces —\n * `equals` / `not` are raw `===` / `!==`, the ordering operators demand numbers\n * on BOTH sides, `any` / `none` demand an array expected value (a non-array is\n * not met for either — `none` is NOT the raw complement of `any` on malformed\n * input), while `outside` IS the pure negation of `between` (so a malformed\n * range is `outside`). Fields resolve through the core `resolveField` — a string\n * is ONE key, an array descends. Stateless and deterministic.\n */\nexport class Evaluator implements EvaluatorInterface {\n\treadonly #id: string\n\n\tconstructor(options?: EvaluatorOptions) {\n\t\tthis.#id = options?.id ?? EVALUATOR_ID\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tevaluate(check: Check, subject: Subject): CheckResult {\n\t\tconst actual = resolveField(subject, check.field)\n\t\ttry {\n\t\t\tconst met = this.#compare(actual, check.operator, check.value)\n\t\t\treturn { field: check.field, met, actual }\n\t\t} catch (error) {\n\t\t\tconst message = error instanceof Error ? error.message : String(error)\n\t\t\treturn { field: check.field, met: false, actual, error: message }\n\t\t}\n\t}\n\n\tbatch(checks: readonly Check[], subject: Subject): readonly CheckResult[] {\n\t\treturn checks.map((check) => this.evaluate(check, subject))\n\t}\n\n\t// The one throwing path is the unknown-operator default — caught by `evaluate`.\n\t// `operator` is typed `string` because untrusted definitions reach here unchecked.\n\t#compare(actual: unknown, operator: string, expected: unknown): boolean {\n\t\tswitch (operator) {\n\t\t\tcase 'equals':\n\t\t\t\treturn actual === expected\n\t\t\tcase 'not':\n\t\t\t\treturn actual !== expected\n\t\t\tcase 'above':\n\t\t\t\treturn isNumber(actual) && isNumber(expected) && actual > expected\n\t\t\tcase 'below':\n\t\t\t\treturn isNumber(actual) && isNumber(expected) && actual < expected\n\t\t\tcase 'from':\n\t\t\t\treturn isNumber(actual) && isNumber(expected) && actual >= expected\n\t\t\tcase 'to':\n\t\t\t\treturn isNumber(actual) && isNumber(expected) && actual <= expected\n\t\t\tcase 'any':\n\t\t\t\treturn isArray(expected) && expected.includes(actual)\n\t\t\tcase 'none':\n\t\t\t\treturn isArray(expected) && !expected.includes(actual)\n\t\t\tcase 'between':\n\t\t\t\treturn this.#isBetween(actual, expected)\n\t\t\tcase 'outside':\n\t\t\t\treturn !this.#isBetween(actual, expected)\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unknown comparison operator: ${operator}`)\n\t\t}\n\t}\n\n\t// Inclusive on both ends; only the first two array elements are read.\n\t#isBetween(actual: unknown, expected: unknown): boolean {\n\t\tif (!isNumber(actual)) return false\n\t\tif (!isArray(expected) || expected.length < 2) return false\n\t\tconst minimum = expected[0]\n\t\tconst maximum = expected[1]\n\t\tif (!isNumber(minimum) || !isNumber(maximum)) return false\n\t\treturn actual >= minimum && actual <= maximum\n\t}\n}\n","import type { Transform, TransformerInterface, TransformerOptions } from '../types.js'\nimport { TRANSFORMER_ID } from '../constants.js'\n\n/**\n * Applies math {@link Transform}s to numbers — the quantitative reasoner's\n * per-factor pipeline stage.\n *\n * @remarks\n * TOTAL: never throws. Absent-`operand` defaults are operation-specific —\n * identity-preserving `1` for `multiply` / `divide` / `power`, `0` for every\n * other binary operation; `round` / `ceil` / `floor` / `abs` are unary and\n * ignore the operand. `divide` by zero yields `NaN` (deliberately not JS's\n * `Infinity`), an unknown operation returns the value unchanged, and `chain` is\n * a strict left fold — `NaN` flows through untouched. Stateless and\n * deterministic.\n */\nexport class Transformer implements TransformerInterface {\n\treadonly #id: string\n\n\tconstructor(options?: TransformerOptions) {\n\t\tthis.#id = options?.id ?? TRANSFORMER_ID\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tapply(value: number, transform: Transform): number {\n\t\tswitch (transform.operation) {\n\t\t\tcase 'add':\n\t\t\t\treturn value + (transform.operand ?? 0)\n\t\t\tcase 'subtract':\n\t\t\t\treturn value - (transform.operand ?? 0)\n\t\t\tcase 'multiply':\n\t\t\t\treturn value * (transform.operand ?? 1)\n\t\t\tcase 'divide': {\n\t\t\t\tconst divisor = transform.operand ?? 1\n\t\t\t\treturn divisor === 0 ? Number.NaN : value / divisor\n\t\t\t}\n\t\t\tcase 'percentage':\n\t\t\t\treturn value * ((transform.operand ?? 0) / 100)\n\t\t\tcase 'minimum':\n\t\t\t\treturn Math.min(value, transform.operand ?? 0)\n\t\t\tcase 'maximum':\n\t\t\t\treturn Math.max(value, transform.operand ?? 0)\n\t\t\tcase 'average':\n\t\t\t\treturn (value + (transform.operand ?? 0)) / 2\n\t\t\tcase 'power':\n\t\t\t\treturn Math.pow(value, transform.operand ?? 1)\n\t\t\tcase 'round':\n\t\t\t\treturn Math.round(value)\n\t\t\tcase 'ceil':\n\t\t\t\treturn Math.ceil(value)\n\t\t\tcase 'floor':\n\t\t\t\treturn Math.floor(value)\n\t\t\tcase 'abs':\n\t\t\t\treturn Math.abs(value)\n\t\t\tdefault:\n\t\t\t\t// An unknown operation from an untrusted definition is a silent no-op.\n\t\t\t\treturn value\n\t\t}\n\t}\n\n\tchain(value: number, transforms: readonly Transform[]): number {\n\t\treturn transforms.reduce((result, transform) => this.apply(result, transform), value)\n\t}\n}\n","import type { Aggregation, AggregatorInterface, AggregatorOptions } from '../types.js'\nimport { AGGREGATOR_ID, DEFAULT_WEIGHT } from '../constants.js'\n\n/**\n * Reduces number lists to one number per {@link Aggregation} — the quantitative\n * reasoner's group and definition combiner.\n *\n * @remarks\n * TOTAL: never throws. Empty-input identities: `sum` / `average` → `0`,\n * `product` → `1`, `minimum` / `maximum` → `NaN` (the deliberate \"no data\"\n * signal). Weights are honored ONLY when their length matches `values` exactly\n * (otherwise silently unweighted): a weight multiplies into a `sum`, acts as an\n * EXPONENT for a `product`, is the weight of a weighted mean for `average`\n * (a zero total weight yields `0`, never a division blow-up), and is ignored by\n * `minimum` / `maximum`. An unknown aggregation yields `0`. Stateless and\n * deterministic.\n */\nexport class Aggregator implements AggregatorInterface {\n\treadonly #id: string\n\n\tconstructor(options?: AggregatorOptions) {\n\t\tthis.#id = options?.id ?? AGGREGATOR_ID\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\taggregate(\n\t\tvalues: readonly number[],\n\t\taggregation: Aggregation,\n\t\tweights?: readonly number[],\n\t): number {\n\t\tif (values.length === 0) return this.#empty(aggregation)\n\t\t// Weights apply only on an exact length match — anything else is unweighted.\n\t\tconst scaled = weights !== undefined && weights.length === values.length ? weights : undefined\n\t\tswitch (aggregation) {\n\t\t\tcase 'sum':\n\t\t\t\treturn scaled\n\t\t\t\t\t? values.reduce(\n\t\t\t\t\t\t\t(total, value, index) => total + value * (scaled[index] ?? DEFAULT_WEIGHT),\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t)\n\t\t\t\t\t: values.reduce((total, value) => total + value, 0)\n\t\t\tcase 'product':\n\t\t\t\treturn scaled\n\t\t\t\t\t? values.reduce(\n\t\t\t\t\t\t\t(total, value, index) => total * Math.pow(value, scaled[index] ?? DEFAULT_WEIGHT),\n\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t)\n\t\t\t\t\t: values.reduce((total, value) => total * value, 1)\n\t\t\tcase 'average': {\n\t\t\t\tif (scaled) {\n\t\t\t\t\tconst totalWeight = scaled.reduce((total, weight) => total + weight, 0)\n\t\t\t\t\tif (totalWeight === 0) return 0\n\t\t\t\t\tconst weightedSum = values.reduce(\n\t\t\t\t\t\t(total, value, index) => total + value * (scaled[index] ?? DEFAULT_WEIGHT),\n\t\t\t\t\t\t0,\n\t\t\t\t\t)\n\t\t\t\t\treturn weightedSum / totalWeight\n\t\t\t\t}\n\t\t\t\treturn values.reduce((total, value) => total + value, 0) / values.length\n\t\t\t}\n\t\t\tcase 'minimum':\n\t\t\t\t// Seedless pairwise reduce (values is non-empty — #empty short-circuits\n\t\t\t\t// the 0-length case above), so an arbitrarily large list never spreads\n\t\t\t\t// past the argument-count limit. Math.min keeps NaN-propagation and the\n\t\t\t\t// -0 < +0 sign rule a `a < b ? a : b` fold would lose.\n\t\t\t\treturn values.reduce((minimum, value) => Math.min(minimum, value))\n\t\t\tcase 'maximum':\n\t\t\t\treturn values.reduce((maximum, value) => Math.max(maximum, value))\n\t\t\tdefault:\n\t\t\t\t// An unknown aggregation from an untrusted definition yields 0.\n\t\t\t\treturn 0\n\t\t}\n\t}\n\n\t// Empty-input identity per aggregation — NaN for min/max signals \"no data\".\n\t#empty(aggregation: Aggregation): number {\n\t\tswitch (aggregation) {\n\t\t\tcase 'sum':\n\t\t\tcase 'average':\n\t\t\t\treturn 0\n\t\t\tcase 'product':\n\t\t\t\treturn 1\n\t\t\tcase 'minimum':\n\t\t\tcase 'maximum':\n\t\t\t\treturn Number.NaN\n\t\t\tdefault:\n\t\t\t\treturn 0\n\t\t}\n\t}\n}\n","import type {\n\tAggregatorInterface,\n\tDefinition,\n\tEvaluatorInterface,\n\tFactor,\n\tFactorGroup,\n\tFactorResult,\n\tGroupResult,\n\tQuantitativeReasonerOptions,\n\tReasoning,\n\tReasonResult,\n\tReasonValidationResult,\n\tReasonerInterface,\n\tSource,\n\tSubject,\n\tTransformerInterface,\n} from '../types.js'\nimport { parseNumberField, resolveField } from '@orkestrel/contract'\nimport { clamp, findDuplicates, roundTo, sortByPriority } from '../helpers.js'\nimport { DEFAULT_BASE, DEFAULT_PRECISION, DEFAULT_WEIGHT, QUANTITATIVE_ID } from '../constants.js'\nimport { ReasonError } from '../errors.js'\nimport { Evaluator } from '../operators/Evaluator.js'\nimport { Transformer } from '../operators/Transformer.js'\nimport { Aggregator } from '../operators/Aggregator.js'\n\n/**\n * The quantitative reasoner — factor-based numeric scoring.\n *\n * @remarks\n * Each factor runs a fixed pipeline: checks gate (ALL met) → source resolve\n * (`fallback` when unresolvable) → finite check → transforms chain → bounds\n * clamp → finite recheck. Factors evaluate in stable ascending `priority`\n * order; a `strict` group is all-or-nothing; a group's value is its `base` plus\n * the weighted aggregation of its APPLIED factors, clamped (never rounded); the\n * definition's value is its `base` plus the unweighted aggregation of the\n * APPLIED groups' values, clamped, then rounded to `precision`. A\n * required-factor failure or non-finite value appends an error (`success:\n * false`) without aborting — the numeric `value` is always computed. The\n * definition-level value is finite-checked AFTER rounding: a non-finite\n * aggregate (a `minimum` / `maximum` over zero applied groups) appends an error\n * while the `NaN` stays visible in `value`. Field sources coerce through the\n * contracts `parseNumberField`: a non-finite subject number or a non-numeric\n * string is unresolvable and takes the fallback path. Lookup sources read only\n * OWN table keys, and a missing / `null` field falls back directly. Nothing\n * mutates its inputs; fully deterministic (AGENTS §11).\n */\nexport class QuantitativeReasoner implements ReasonerInterface {\n\treadonly #id: string\n\treadonly #evaluator: EvaluatorInterface\n\treadonly #transformer: TransformerInterface\n\treadonly #aggregator: AggregatorInterface\n\n\tconstructor(options?: QuantitativeReasonerOptions) {\n\t\tthis.#id = options?.id ?? QUANTITATIVE_ID\n\t\tthis.#evaluator = options?.evaluator ?? new Evaluator()\n\t\tthis.#transformer = options?.transformer ?? new Transformer()\n\t\tthis.#aggregator = options?.aggregator ?? new Aggregator()\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget reasoning(): Reasoning {\n\t\treturn 'quantitative'\n\t}\n\n\tsupports(definition: Definition): boolean {\n\t\treturn definition.reasoning === 'quantitative'\n\t}\n\n\tvalidate(definition: Definition): ReasonValidationResult {\n\t\tconst errors: string[] = []\n\t\tconst warnings: string[] = []\n\n\t\tif (definition.reasoning !== 'quantitative') {\n\t\t\terrors.push(`Expected reasoning \"quantitative\", got \"${definition.reasoning}\"`)\n\t\t\treturn { valid: false, errors, warnings }\n\t\t}\n\n\t\tif (!definition.id) errors.push('Definition must have an id')\n\t\tif (!definition.name) errors.push('Definition must have a name')\n\t\tif (!definition.groups || definition.groups.length === 0) {\n\t\t\terrors.push('Definition must have at least one group')\n\t\t}\n\n\t\t// Duplicate ids are WARNINGS (runtime stays permissive: a weight lookup\n\t\t// takes the FIRST same-id twin) — once per duplicated id.\n\t\tfor (const id of findDuplicates(definition.groups ?? [])) {\n\t\t\twarnings.push(`Duplicate group id \"${id}\"`)\n\t\t}\n\n\t\tfor (const group of definition.groups ?? []) {\n\t\t\tif (!group.id) errors.push('Group must have an id')\n\t\t\tif (!group.factors || group.factors.length === 0) {\n\t\t\t\twarnings.push(`Group \"${group.id}\" has no factors`)\n\t\t\t}\n\t\t\tfor (const id of findDuplicates(group.factors ?? [])) {\n\t\t\t\twarnings.push(`Duplicate factor id \"${id}\"`)\n\t\t\t}\n\t\t\tfor (const factor of group.factors ?? []) {\n\t\t\t\tif (!factor.id) errors.push('Factor must have an id')\n\t\t\t\tif (!factor.source) errors.push(`Factor \"${factor.id}\" must have a source`)\n\t\t\t}\n\t\t}\n\n\t\treturn { valid: errors.length === 0, errors, warnings }\n\t}\n\n\treason(subject: Subject, definition: Definition): ReasonResult {\n\t\tif (definition.reasoning !== 'quantitative') {\n\t\t\tthrow new ReasonError(\n\t\t\t\t'MISMATCH',\n\t\t\t\t`Expected quantitative definition, got \"${definition.reasoning}\"`,\n\t\t\t\t{ definition: definition.id, reasoning: this.reasoning },\n\t\t\t)\n\t\t}\n\n\t\t// Runtime never assumes validate() ran — a malformed shape is a failure\n\t\t// result, not a throw.\n\t\tif (!definition.groups || !Array.isArray(definition.groups)) {\n\t\t\treturn {\n\t\t\t\treasoning: 'quantitative',\n\t\t\t\tvalue: 0,\n\t\t\t\tgroups: [],\n\t\t\t\tcount: 0,\n\t\t\t\tsuccess: false,\n\t\t\t\ttrace: [],\n\t\t\t\terrors: ['Definition must have a \"groups\" array'],\n\t\t\t}\n\t\t}\n\n\t\tconst trace: string[] = []\n\t\tconst errors: string[] = []\n\t\tlet count = 0\n\n\t\tconst groupResults: GroupResult[] = []\n\t\tfor (const group of definition.groups) {\n\t\t\tif (typeof group !== 'object' || group === null) continue\n\t\t\tif (group.enabled === false) {\n\t\t\t\ttrace.push(`Skipped group \"${group.id}\" (disabled)`)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst groupResult = this.#evaluateGroup(group, subject, trace, errors)\n\t\t\tgroupResults.push(groupResult)\n\t\t\tif (groupResult.applied) count++\n\t\t}\n\n\t\tconst groupValues = groupResults.filter((group) => group.applied).map((group) => group.value)\n\n\t\tconst base = definition.base ?? DEFAULT_BASE\n\t\tlet value = base + this.#aggregator.aggregate(groupValues, definition.aggregation)\n\t\ttrace.push(\n\t\t\t`Aggregated ${groupValues.length} groups with \"${definition.aggregation}\": base=${base}, raw=${value}`,\n\t\t)\n\n\t\tvalue = clamp(value, definition.bounds)\n\t\tvalue = roundTo(value, definition.precision ?? DEFAULT_PRECISION)\n\n\t\t// Definition-level finite check (mirrors the factor-level formatter): a\n\t\t// minimum / maximum over zero applied groups aggregates to NaN — that is\n\t\t// the aggregator's deliberate \"no data\" signal, surfaced here as an error\n\t\t// while the non-finite value stays visible.\n\t\tif (!Number.isFinite(value)) {\n\t\t\tconst description = Number.isNaN(value) ? 'NaN' : String(value)\n\t\t\ttrace.push(`Definition \"${definition.id}\": produced non-finite value (${description})`)\n\t\t\terrors.push(`Definition \"${definition.id}\" produced non-finite value: ${description}`)\n\t\t}\n\n\t\treturn {\n\t\t\treasoning: 'quantitative',\n\t\t\tvalue,\n\t\t\tgroups: groupResults,\n\t\t\tcount,\n\t\t\tsuccess: errors.length === 0,\n\t\t\ttrace,\n\t\t\terrors,\n\t\t}\n\t}\n\n\t// Group pipeline: stable priority sort → skip disabled → strict all-or-nothing\n\t// → weighted aggregation of applied values → base → clamp (never rounded).\n\t#evaluateGroup(\n\t\tgroup: FactorGroup,\n\t\tsubject: Subject,\n\t\ttrace: string[],\n\t\terrors: string[],\n\t): GroupResult {\n\t\tif (!group.factors || group.factors.length === 0) {\n\t\t\ttrace.push(`Group \"${group.id}\": no factors defined`)\n\t\t\treturn { id: group.id, applied: false, value: group.base ?? DEFAULT_BASE, factors: [] }\n\t\t}\n\n\t\tconst factorResults: FactorResult[] = []\n\t\tfor (const factor of sortByPriority(group.factors)) {\n\t\t\tif (factor.enabled === false) {\n\t\t\t\ttrace.push(`Skipped factor \"${factor.id}\" (disabled)`)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfactorResults.push(this.#evaluateFactor(factor, subject, trace, errors))\n\t\t}\n\n\t\tconst appliedFactors = factorResults.filter((factor) => factor.applied)\n\n\t\tif (group.strict && appliedFactors.length !== factorResults.length) {\n\t\t\ttrace.push(`Group \"${group.id}\" strict mode: not all factors applied`)\n\t\t\treturn {\n\t\t\t\tid: group.id,\n\t\t\t\tapplied: false,\n\t\t\t\tvalue: group.base ?? DEFAULT_BASE,\n\t\t\t\tfactors: factorResults,\n\t\t\t}\n\t\t}\n\n\t\tconst factorValues = appliedFactors.map((factor) => factor.value)\n\t\t// Weights come from the ORIGINAL factor list by id, not the priority-sorted\n\t\t// copy — hoisted to one id→weight Map (FIRST same-id twin wins, matching the\n\t\t// old `.find`) so the per-applied-factor lookup is O(1) instead of O(factors).\n\t\tconst weightById = new Map<string, number>()\n\t\tfor (const original of group.factors) {\n\t\t\tif (typeof original !== 'object' || original === null) continue\n\t\t\tif (!weightById.has(original.id))\n\t\t\t\tweightById.set(original.id, original.weight ?? DEFAULT_WEIGHT)\n\t\t}\n\t\tconst weights = appliedFactors.map((factor) => weightById.get(factor.id) ?? DEFAULT_WEIGHT)\n\n\t\tconst base = group.base ?? DEFAULT_BASE\n\t\tlet value = base + this.#aggregator.aggregate(factorValues, group.aggregation, weights)\n\t\tvalue = clamp(value, group.bounds)\n\n\t\ttrace.push(\n\t\t\t`Group \"${group.id}\": ${appliedFactors.length}/${factorResults.length} factors applied, value=${value}`,\n\t\t)\n\n\t\treturn { id: group.id, applied: appliedFactors.length > 0, value, factors: factorResults }\n\t}\n\n\t// Factor pipeline: checks gate → source resolve → finite check → transforms\n\t// → bounds clamp → finite recheck. Weight is NOT applied here — it feeds the\n\t// group aggregation.\n\t#evaluateFactor(\n\t\tfactor: Factor,\n\t\tsubject: Subject,\n\t\ttrace: string[],\n\t\terrors: string[],\n\t): FactorResult {\n\t\tif (factor.checks && factor.checks.length > 0) {\n\t\t\tconst checkResults = this.#evaluator.batch(factor.checks, subject)\n\t\t\tconst allMet = checkResults.every((result) => result.met)\n\t\t\tif (!allMet) {\n\t\t\t\ttrace.push(`Factor \"${factor.id}\": checks not met`)\n\t\t\t\tif (factor.required) {\n\t\t\t\t\terrors.push(`Required factor \"${factor.id}\" checks not met`)\n\t\t\t\t}\n\t\t\t\treturn { id: factor.id, applied: false, value: 0, checks: checkResults }\n\t\t\t}\n\t\t}\n\n\t\tconst raw = this.#resolveSource(factor.source, subject, factor.fallback)\n\t\tif (raw === undefined) {\n\t\t\ttrace.push(`Factor \"${factor.id}\": could not resolve source`)\n\t\t\tif (factor.required) {\n\t\t\t\terrors.push(`Required factor \"${factor.id}\" could not resolve source`)\n\t\t\t}\n\t\t\t// `raw` is documented as ABSENT when the source never resolved.\n\t\t\treturn { id: factor.id, applied: false, value: 0 }\n\t\t}\n\n\t\tif (!Number.isFinite(raw)) {\n\t\t\tconst description = Number.isNaN(raw) ? 'NaN' : String(raw)\n\t\t\ttrace.push(`Factor \"${factor.id}\": source produced non-finite value (${description})`)\n\t\t\terrors.push(`Factor \"${factor.id}\" produced non-finite value: ${description}`)\n\t\t\treturn { id: factor.id, applied: false, value: 0, raw }\n\t\t}\n\n\t\tlet value = raw\n\t\tif (factor.transforms && factor.transforms.length > 0) {\n\t\t\tvalue = this.#transformer.chain(value, factor.transforms)\n\t\t}\n\n\t\tvalue = clamp(value, factor.bounds)\n\n\t\tif (!Number.isFinite(value)) {\n\t\t\tconst description = Number.isNaN(value) ? 'NaN' : String(value)\n\t\t\ttrace.push(`Factor \"${factor.id}\": produced non-finite value (${description})`)\n\t\t\terrors.push(`Factor \"${factor.id}\" produced non-finite value: ${description}`)\n\t\t\treturn { id: factor.id, applied: false, value: 0, raw }\n\t\t}\n\n\t\ttrace.push(`Factor \"${factor.id}\": raw=${raw}, value=${value}`)\n\t\treturn { id: factor.id, applied: true, value, raw }\n\t}\n\n\t// Source resolution: static passes through; field/range coerce via parseNumberField\n\t// (non-finite / non-numeric → fallback); lookup stringifies PRESENT values into\n\t// the table's OWN keys (missing/null field and absent/inherited key → fallback).\n\t#resolveSource(source: Source, subject: Subject, fallback?: number): number | undefined {\n\t\t// A malformed factor may carry no source at all — the fallback path, not a crash.\n\t\tif (!source) return fallback\n\t\tswitch (source.origin) {\n\t\t\tcase 'static':\n\t\t\t\treturn source.value\n\t\t\tcase 'field':\n\t\t\t\treturn parseNumberField(subject, source.field) ?? fallback\n\t\t\tcase 'lookup': {\n\t\t\t\tconst resolved = resolveField(subject, source.field)\n\t\t\t\t// A missing / null field never reaches the table (a '' key must not\n\t\t\t\t// intercept absent data); a PRESENT value still stringifies, so a\n\t\t\t\t// real '' value may hit a '' key.\n\t\t\t\tif (resolved === undefined || resolved === null) return fallback\n\t\t\t\tconst key = String(resolved)\n\t\t\t\treturn Object.hasOwn(source.table, key) ? source.table[key] : fallback\n\t\t\t}\n\t\t\tcase 'range': {\n\t\t\t\tconst value = parseNumberField(subject, source.field)\n\t\t\t\tif (value === undefined) return fallback\n\t\t\t\tfor (const range of source.ranges) {\n\t\t\t\t\tif (typeof range !== 'object' || range === null) continue\n\t\t\t\t\tconst bounds = range.bounds\n\t\t\t\t\t// A band without bounds is a catch-all; an absent side is open.\n\t\t\t\t\tif (!bounds) return range.value\n\t\t\t\t\tconst aboveMinimum = bounds.minimum === undefined || value >= bounds.minimum\n\t\t\t\t\tconst belowMaximum = bounds.maximum === undefined || value <= bounds.maximum\n\t\t\t\t\tif (aboveMinimum && belowMaximum) return range.value\n\t\t\t\t}\n\t\t\t\treturn fallback\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn fallback\n\t\t}\n\t}\n}\n","import type {\n\tDefinition,\n\tEvaluatorInterface,\n\tExpression,\n\tLogicalDefinition,\n\tLogicalReasonerOptions,\n\tReasoning,\n\tReasonResult,\n\tReasonValidationResult,\n\tReasonerInterface,\n\tRule,\n\tRuleResult,\n\tSubject,\n} from '../types.js'\nimport {\n\tequalValues,\n\textractConclusions,\n\tfindDuplicates,\n\tfindOverlayMismatches,\n\tformatField,\n\tsortByPriority,\n} from '../helpers.js'\nimport { DEFAULT_DEPTH, LOGICAL_ID } from '../constants.js'\nimport { ReasonError } from '../errors.js'\nimport { Evaluator } from '../operators/Evaluator.js'\n\n/**\n * The logical reasoner — rule-based boolean deduction with forward or backward\n * chaining.\n *\n * @remarks\n * Forward chaining is a naive fixpoint capped at `depth` iterations: rules run\n * in ascending `priority` order each pass, and a firing rule's conclusion atoms\n * become a derived overlay that SHADOWS same-named subject fields on later\n * passes (derived keys are `formatField(check.field)` strings). Convergence —\n * one full pass with no new derivation — appends a trace containing\n * `converged`. Final rule results re-evaluate against the settled overlay in\n * ORIGINAL rule order (forward) / priority-sorted order (backward), and the\n * overall `conclusion` is the LAST result's conclusion. Backward chaining\n * proves EVERY rule goal-first: an unmet premise triggers sub-goal search\n * through rules whose conclusion atoms assert the needed `field = value` pair,\n * guarded by a visited-rule set (cycle-safe) plus the depth cap; `not` succeeds\n * when its operand cannot be established (negation-as-failure) and `implies` is\n * vacuously true on an unprovable antecedent. Expression evaluation is EAGER\n * (no short-circuit); conclusion extraction IGNORES connectives — every atom\n * inside a conclusion is asserted, even under `not` / `or`. Overlay bookkeeping\n * compares with SameValueZero (`equalValues`), so a NaN-valued conclusion\n * derives once and the fixpoint converges. Nothing mutates its inputs; fully\n * deterministic (AGENTS §11).\n */\nexport class LogicalReasoner implements ReasonerInterface {\n\treadonly #id: string\n\treadonly #evaluator: EvaluatorInterface\n\n\tconstructor(options?: LogicalReasonerOptions) {\n\t\tthis.#id = options?.id ?? LOGICAL_ID\n\t\tthis.#evaluator = options?.evaluator ?? new Evaluator()\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget reasoning(): Reasoning {\n\t\treturn 'logical'\n\t}\n\n\tsupports(definition: Definition): boolean {\n\t\treturn definition.reasoning === 'logical'\n\t}\n\n\tvalidate(definition: Definition): ReasonValidationResult {\n\t\tconst errors: string[] = []\n\t\tconst warnings: string[] = []\n\n\t\tif (definition.reasoning !== 'logical') {\n\t\t\terrors.push(`Expected reasoning \"logical\", got \"${definition.reasoning}\"`)\n\t\t\treturn { valid: false, errors, warnings }\n\t\t}\n\n\t\tif (!definition.id) errors.push('Definition must have an id')\n\t\tif (!definition.name) errors.push('Definition must have a name')\n\t\tif (!definition.rules || definition.rules.length === 0) {\n\t\t\terrors.push('Definition must have at least one rule')\n\t\t}\n\n\t\t// Duplicate ids are WARNINGS (runtime stays permissive: a degenerate rule\n\t\t// id-poisons its same-id twin in the forward exclusion set).\n\t\tfor (const id of findDuplicates(definition.rules ?? [])) {\n\t\t\twarnings.push(`Duplicate rule id \"${id}\"`)\n\t\t}\n\n\t\tfor (const rule of definition.rules ?? []) {\n\t\t\tif (!rule.id) errors.push('Rule must have an id')\n\t\t\tif (!rule.premises || rule.premises.length === 0) {\n\t\t\t\twarnings.push(`Rule \"${rule.id}\" has no premises`)\n\t\t\t}\n\t\t\tif (!rule.conclusion) {\n\t\t\t\terrors.push(`Rule \"${rule.id}\" must have a conclusion`)\n\t\t\t}\n\t\t}\n\n\t\t// Cross-rule overlay-key mismatch: an array-path conclusion write whose\n\t\t// flat overlay key is also read via an array-path premise elsewhere.\n\t\tfor (const key of findOverlayMismatches(definition.rules ?? [])) {\n\t\t\twarnings.push(\n\t\t\t\t`Overlay key \"${key}\" is written via an array path AND also read via an array path — the flat overlay key will not resolve`,\n\t\t\t)\n\t\t}\n\n\t\treturn { valid: errors.length === 0, errors, warnings }\n\t}\n\n\treason(subject: Subject, definition: Definition): ReasonResult {\n\t\tif (definition.reasoning !== 'logical') {\n\t\t\tthrow new ReasonError(\n\t\t\t\t'MISMATCH',\n\t\t\t\t`Expected logical definition, got \"${definition.reasoning}\"`,\n\t\t\t\t{ definition: definition.id, reasoning: this.reasoning },\n\t\t\t)\n\t\t}\n\n\t\t// Runtime never assumes validate() ran — a malformed shape is a failure\n\t\t// result, not a throw.\n\t\tif (!definition.rules || !Array.isArray(definition.rules)) {\n\t\t\treturn {\n\t\t\t\treasoning: 'logical',\n\t\t\t\tconclusion: false,\n\t\t\t\trules: [],\n\t\t\t\tcount: 0,\n\t\t\t\tsuccess: false,\n\t\t\t\ttrace: [],\n\t\t\t\terrors: ['Definition must have a \"rules\" array'],\n\t\t\t}\n\t\t}\n\n\t\tconst trace: string[] = []\n\t\tconst errors: string[] = []\n\n\t\tconst result =\n\t\t\tdefinition.strategy === 'backward'\n\t\t\t\t? this.#backward(definition, subject, trace, errors)\n\t\t\t\t: this.#forward(definition, subject, trace, errors)\n\n\t\treturn {\n\t\t\treasoning: 'logical',\n\t\t\tconclusion: result.conclusion,\n\t\t\trules: result.rules,\n\t\t\tcount: result.rules.filter((rule) => rule.applied).length,\n\t\t\tsuccess: errors.length === 0,\n\t\t\ttrace,\n\t\t\terrors,\n\t\t}\n\t}\n\n\t// Data-driven fixpoint: derive until a pass adds nothing new (or depth caps),\n\t// then re-evaluate every runnable rule in ORIGINAL order for the results.\n\t#forward(\n\t\tdefinition: LogicalDefinition,\n\t\tsubject: Subject,\n\t\ttrace: string[],\n\t\terrors: string[],\n\t): { conclusion: boolean; rules: RuleResult[] } {\n\t\tconst maxDepth = definition.depth ?? DEFAULT_DEPTH\n\t\tconst derived: Record<string, unknown> = {}\n\n\t\tif (definition.rules.length === 0) trace.push('No rules defined')\n\n\t\tconst sortedRules = sortByPriority(definition.rules)\n\n\t\t// Pre-pass: a premise-less or conclusion-less rule errors ONCE and is\n\t\t// excluded from every later pass.\n\t\tconst reportedErrors = new Set<string>()\n\t\tfor (const rule of sortedRules) {\n\t\t\tif (typeof rule !== 'object' || rule === null) continue\n\t\t\tif (rule.enabled === false) continue\n\t\t\tif (!rule.premises || rule.premises.length === 0) {\n\t\t\t\terrors.push(`Rule \"${rule.id}\" has no premises — skipped`)\n\t\t\t\treportedErrors.add(rule.id)\n\t\t\t} else if (!rule.conclusion) {\n\t\t\t\terrors.push(`Rule \"${rule.id}\" has no conclusion — skipped`)\n\t\t\t\treportedErrors.add(rule.id)\n\t\t\t}\n\t\t}\n\n\t\tfor (let iteration = 0; iteration < maxDepth; iteration++) {\n\t\t\tlet newDerivation = false\n\t\t\tconst currentSubject: Subject = { ...subject, ...derived }\n\n\t\t\tfor (const rule of sortedRules) {\n\t\t\t\tif (rule.enabled === false) {\n\t\t\t\t\ttrace.push(`Skipped rule \"${rule.id}\" (disabled)`)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (reportedErrors.has(rule.id)) continue\n\n\t\t\t\tconst ruleResult = this.#evaluateRule(rule, currentSubject)\n\n\t\t\t\tif (ruleResult.applied && ruleResult.conclusion) {\n\t\t\t\t\tconst conclusions = extractConclusions(rule.conclusion)\n\t\t\t\t\tfor (const [key, value] of Object.entries(conclusions)) {\n\t\t\t\t\t\t// SameValueZero — a NaN conclusion must not re-derive forever.\n\t\t\t\t\t\tif (!equalValues(derived[key], value)) {\n\t\t\t\t\t\t\tderived[key] = value\n\t\t\t\t\t\t\tnewDerivation = true\n\t\t\t\t\t\t\ttrace.push(\n\t\t\t\t\t\t\t\t`Rule \"${rule.id}\" derived: ${key}=${String(value)} (iteration ${iteration + 1})`,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!newDerivation) {\n\t\t\t\ttrace.push(`Forward chaining converged at iteration ${iteration + 1}`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tconst finalSubject: Subject = { ...subject, ...derived }\n\t\tconst finalResults: RuleResult[] = []\n\t\tfor (const rule of definition.rules) {\n\t\t\tif (typeof rule !== 'object' || rule === null) continue\n\t\t\tif (rule.enabled === false) continue\n\t\t\tif (reportedErrors.has(rule.id)) continue\n\t\t\tfinalResults.push(this.#evaluateRule(rule, finalSubject))\n\t\t}\n\n\t\tconst conclusion =\n\t\t\tfinalResults.length > 0 ? (finalResults[finalResults.length - 1]?.conclusion ?? false) : false\n\n\t\treturn { conclusion, rules: finalResults }\n\t}\n\n\t// Goal-driven proving over EVERY rule in priority order, sharing a growing\n\t// derived overlay; the visited-rule set plus the depth cap keep cycles safe.\n\t#backward(\n\t\tdefinition: LogicalDefinition,\n\t\tsubject: Subject,\n\t\ttrace: string[],\n\t\terrors: string[],\n\t): { conclusion: boolean; rules: RuleResult[] } {\n\t\tconst maxDepth = definition.depth ?? DEFAULT_DEPTH\n\t\tconst derived: Record<string, unknown> = {}\n\t\tconst ruleResults = new Map<string, RuleResult>()\n\n\t\tif (definition.rules.length === 0) trace.push('No rules defined')\n\n\t\tconst sortedRules = sortByPriority(\n\t\t\tdefinition.rules.filter((rule) => {\n\t\t\t\tif (typeof rule !== 'object' || rule === null) return false\n\t\t\t\tif (rule.enabled === false) return false\n\t\t\t\t// A missing / non-array premises cannot be walked — errored and\n\t\t\t\t// excluded. An EMPTY premises array is kept: backward applies it\n\t\t\t\t// VACUOUSLY (scsr semantics — forward reports it instead).\n\t\t\t\tif (!rule.premises || !Array.isArray(rule.premises)) {\n\t\t\t\t\terrors.push(`Rule \"${rule.id}\" has no premises — skipped`)\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tif (!rule.conclusion) {\n\t\t\t\t\terrors.push(`Rule \"${rule.id}\" has no conclusion — skipped`)\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\treturn true\n\t\t\t}),\n\t\t)\n\n\t\tfor (const rule of definition.rules) {\n\t\t\tif (typeof rule !== 'object' || rule === null) continue\n\t\t\tif (rule.enabled === false) trace.push(`Skipped rule \"${rule.id}\" (disabled)`)\n\t\t}\n\n\t\tconst prove = (rule: Rule, depth: number, visited: ReadonlySet<string>): boolean => {\n\t\t\tif (depth > maxDepth) return false\n\t\t\tif (visited.has(rule.id)) return false\n\n\t\t\tconst nextVisited = new Set(visited)\n\t\t\tnextVisited.add(rule.id)\n\n\t\t\tconst currentSubject: Subject = { ...subject, ...derived }\n\t\t\tconst premiseResults: boolean[] = []\n\n\t\t\tfor (const premise of rule.premises) {\n\t\t\t\tpremiseResults.push(\n\t\t\t\t\tthis.#establish(\n\t\t\t\t\t\tpremise,\n\t\t\t\t\t\tcurrentSubject,\n\t\t\t\t\t\tsortedRules,\n\t\t\t\t\t\tdepth + 1,\n\t\t\t\t\t\tnextVisited,\n\t\t\t\t\t\tderived,\n\t\t\t\t\t\tsubject,\n\t\t\t\t\t\ttrace,\n\t\t\t\t\t\truleResults,\n\t\t\t\t\t\tmaxDepth,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tconst allMet = premiseResults.every(Boolean)\n\n\t\t\truleResults.set(rule.id, {\n\t\t\t\tid: rule.id,\n\t\t\t\tapplied: allMet,\n\t\t\t\tpremises: premiseResults,\n\t\t\t\tconclusion: allMet,\n\t\t\t})\n\n\t\t\tif (allMet) {\n\t\t\t\tconst conclusions = extractConclusions(rule.conclusion)\n\t\t\t\tfor (const [key, value] of Object.entries(conclusions)) {\n\t\t\t\t\t// SameValueZero — a NaN conclusion derives (and traces) once.\n\t\t\t\t\tif (!equalValues(derived[key], value)) {\n\t\t\t\t\t\tderived[key] = value\n\t\t\t\t\t\ttrace.push(\n\t\t\t\t\t\t\t`Rule \"${rule.id}\" derived: ${key}=${String(value)} (backward, depth ${depth})`,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttrace.push(`Rule \"${rule.id}\": does not hold (backward, depth ${depth})`)\n\t\t\t}\n\n\t\t\treturn allMet\n\t\t}\n\n\t\tfor (const rule of sortedRules) {\n\t\t\tprove(rule, 0, new Set())\n\t\t}\n\n\t\tconst finalResults: RuleResult[] = []\n\t\tfor (const rule of sortedRules) {\n\t\t\tconst existing = ruleResults.get(rule.id)\n\t\t\tif (existing) {\n\t\t\t\tfinalResults.push(existing)\n\t\t\t} else {\n\t\t\t\tfinalResults.push(this.#evaluateRule(rule, { ...subject, ...derived }))\n\t\t\t}\n\t\t}\n\n\t\tconst conclusion =\n\t\t\tfinalResults.length > 0 ? (finalResults[finalResults.length - 1]?.conclusion ?? false) : false\n\n\t\treturn { conclusion, rules: finalResults }\n\t}\n\n\t// Evaluate an expression against a settled overlay, then fall back to\n\t// sub-goal proving — the shared establish step of every backward branch.\n\t#establish(\n\t\texpression: Expression,\n\t\tcurrentSubject: Subject,\n\t\trules: readonly Rule[],\n\t\tdepth: number,\n\t\tvisited: ReadonlySet<string>,\n\t\tderived: Record<string, unknown>,\n\t\tsubject: Subject,\n\t\ttrace: string[],\n\t\truleResults: Map<string, RuleResult>,\n\t\tmaxDepth: number,\n\t): boolean {\n\t\tif (this.#evaluateExpression(expression, currentSubject)) return true\n\t\treturn this.#proveExpression(\n\t\t\texpression,\n\t\t\trules,\n\t\t\tdepth,\n\t\t\tvisited,\n\t\t\tderived,\n\t\t\tsubject,\n\t\t\ttrace,\n\t\t\truleResults,\n\t\t\tmaxDepth,\n\t\t)\n\t}\n\n\t// Sub-goal search: establish an atom by firing rules whose conclusion atoms\n\t// assert the needed field = value pair; compounds get connective-aware proving.\n\t// The depth cap mirrors the top-level `prove` guard — a sub-goal past\n\t// `maxDepth` fails (unproven), never throws.\n\t#proveExpression(\n\t\texpression: Expression,\n\t\trules: readonly Rule[],\n\t\tdepth: number,\n\t\tvisited: ReadonlySet<string>,\n\t\tderived: Record<string, unknown>,\n\t\tsubject: Subject,\n\t\ttrace: string[],\n\t\truleResults: Map<string, RuleResult>,\n\t\tmaxDepth: number,\n\t): boolean {\n\t\tif (depth > maxDepth) return false\n\n\t\tif (expression.form === 'atom') {\n\t\t\tfor (const rule of rules) {\n\t\t\t\tif (typeof rule !== 'object' || rule === null) continue\n\t\t\t\tif (visited.has(rule.id)) continue\n\t\t\t\tconst conclusionFacts = extractConclusions(rule.conclusion)\n\t\t\t\tconst field = formatField(expression.check.field)\n\t\t\t\tconst value = expression.check.value\n\n\t\t\t\tif (field in conclusionFacts && conclusionFacts[field] === value) {\n\t\t\t\t\tconst nextVisited = new Set(visited)\n\t\t\t\t\tnextVisited.add(rule.id)\n\n\t\t\t\t\tconst currentSubject: Subject = { ...subject, ...derived }\n\t\t\t\t\tconst premiseResults: boolean[] = []\n\t\t\t\t\tlet allMet = true\n\n\t\t\t\t\tfor (const premise of rule.premises) {\n\t\t\t\t\t\tconst met = this.#establish(\n\t\t\t\t\t\t\tpremise,\n\t\t\t\t\t\t\tcurrentSubject,\n\t\t\t\t\t\t\trules,\n\t\t\t\t\t\t\tdepth + 1,\n\t\t\t\t\t\t\tnextVisited,\n\t\t\t\t\t\t\tderived,\n\t\t\t\t\t\t\tsubject,\n\t\t\t\t\t\t\ttrace,\n\t\t\t\t\t\t\truleResults,\n\t\t\t\t\t\t\tmaxDepth,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tpremiseResults.push(met)\n\t\t\t\t\t\tif (!met) {\n\t\t\t\t\t\t\tallMet = false\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\truleResults.set(rule.id, {\n\t\t\t\t\t\tid: rule.id,\n\t\t\t\t\t\tapplied: allMet,\n\t\t\t\t\t\tpremises: premiseResults,\n\t\t\t\t\t\tconclusion: allMet,\n\t\t\t\t\t})\n\n\t\t\t\t\tif (allMet) {\n\t\t\t\t\t\tfor (const [key, entry] of Object.entries(conclusionFacts)) {\n\t\t\t\t\t\t\t// SameValueZero — a NaN conclusion derives (and traces) once.\n\t\t\t\t\t\t\tif (!equalValues(derived[key], entry)) {\n\t\t\t\t\t\t\t\tderived[key] = entry\n\t\t\t\t\t\t\t\ttrace.push(\n\t\t\t\t\t\t\t\t\t`Rule \"${rule.id}\" derived: ${key}=${String(entry)} (backward, depth ${depth})`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (expression.form === 'compound') {\n\t\t\tconst currentSubject: Subject = { ...subject, ...derived }\n\n\t\t\tswitch (expression.operator) {\n\t\t\t\tcase 'and':\n\t\t\t\t\treturn expression.operands.every((operand) =>\n\t\t\t\t\t\tthis.#establish(\n\t\t\t\t\t\t\toperand,\n\t\t\t\t\t\t\tcurrentSubject,\n\t\t\t\t\t\t\trules,\n\t\t\t\t\t\t\tdepth,\n\t\t\t\t\t\t\tvisited,\n\t\t\t\t\t\t\tderived,\n\t\t\t\t\t\t\tsubject,\n\t\t\t\t\t\t\ttrace,\n\t\t\t\t\t\t\truleResults,\n\t\t\t\t\t\t\tmaxDepth,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\tcase 'or':\n\t\t\t\t\treturn expression.operands.some((operand) =>\n\t\t\t\t\t\tthis.#establish(\n\t\t\t\t\t\t\toperand,\n\t\t\t\t\t\t\tcurrentSubject,\n\t\t\t\t\t\t\trules,\n\t\t\t\t\t\t\tdepth,\n\t\t\t\t\t\t\tvisited,\n\t\t\t\t\t\t\tderived,\n\t\t\t\t\t\t\tsubject,\n\t\t\t\t\t\t\ttrace,\n\t\t\t\t\t\t\truleResults,\n\t\t\t\t\t\t\tmaxDepth,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\tcase 'not': {\n\t\t\t\t\t// Negation-as-failure: succeeds when the operand cannot be established.\n\t\t\t\t\tif (expression.operands.length === 0) return true\n\t\t\t\t\tconst first = expression.operands[0]\n\t\t\t\t\tif (!first) return true\n\t\t\t\t\treturn !this.#establish(\n\t\t\t\t\t\tfirst,\n\t\t\t\t\t\tcurrentSubject,\n\t\t\t\t\t\trules,\n\t\t\t\t\t\tdepth,\n\t\t\t\t\t\tvisited,\n\t\t\t\t\t\tderived,\n\t\t\t\t\t\tsubject,\n\t\t\t\t\t\ttrace,\n\t\t\t\t\t\truleResults,\n\t\t\t\t\t\tmaxDepth,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcase 'implies': {\n\t\t\t\t\t// Vacuously true when the antecedent cannot be established.\n\t\t\t\t\tif (expression.operands.length < 2) return true\n\t\t\t\t\tconst antecedent = expression.operands[0]\n\t\t\t\t\tconst consequent = expression.operands[1]\n\t\t\t\t\tif (!antecedent || !consequent) return true\n\t\t\t\t\tconst antecedentMet = this.#establish(\n\t\t\t\t\t\tantecedent,\n\t\t\t\t\t\tcurrentSubject,\n\t\t\t\t\t\trules,\n\t\t\t\t\t\tdepth,\n\t\t\t\t\t\tvisited,\n\t\t\t\t\t\tderived,\n\t\t\t\t\t\tsubject,\n\t\t\t\t\t\ttrace,\n\t\t\t\t\t\truleResults,\n\t\t\t\t\t\tmaxDepth,\n\t\t\t\t\t)\n\t\t\t\t\tif (!antecedentMet) return true\n\t\t\t\t\treturn this.#establish(\n\t\t\t\t\t\tconsequent,\n\t\t\t\t\t\tcurrentSubject,\n\t\t\t\t\t\trules,\n\t\t\t\t\t\tdepth,\n\t\t\t\t\t\tvisited,\n\t\t\t\t\t\tderived,\n\t\t\t\t\t\tsubject,\n\t\t\t\t\t\ttrace,\n\t\t\t\t\t\truleResults,\n\t\t\t\t\t\tmaxDepth,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tcase 'xor': {\n\t\t\t\t\tif (expression.operands.length < 2) return false\n\t\t\t\t\tconst left = expression.operands[0]\n\t\t\t\t\tconst right = expression.operands[1]\n\t\t\t\t\tif (!left || !right) return false\n\t\t\t\t\tconst leftMet = this.#establish(\n\t\t\t\t\t\tleft,\n\t\t\t\t\t\tcurrentSubject,\n\t\t\t\t\t\trules,\n\t\t\t\t\t\tdepth,\n\t\t\t\t\t\tvisited,\n\t\t\t\t\t\tderived,\n\t\t\t\t\t\tsubject,\n\t\t\t\t\t\ttrace,\n\t\t\t\t\t\truleResults,\n\t\t\t\t\t\tmaxDepth,\n\t\t\t\t\t)\n\t\t\t\t\tconst rightMet = this.#establish(\n\t\t\t\t\t\tright,\n\t\t\t\t\t\tcurrentSubject,\n\t\t\t\t\t\trules,\n\t\t\t\t\t\tdepth,\n\t\t\t\t\t\tvisited,\n\t\t\t\t\t\tderived,\n\t\t\t\t\t\tsubject,\n\t\t\t\t\t\ttrace,\n\t\t\t\t\t\truleResults,\n\t\t\t\t\t\tmaxDepth,\n\t\t\t\t\t)\n\t\t\t\t\treturn leftMet !== rightMet\n\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\treturn false\n\t}\n\n\t// A rule applies exactly when ALL premises hold — `applied` and `conclusion`\n\t// are the same boolean; a premise-less or conclusion-less rule never applies.\n\t#evaluateRule(rule: Rule, subject: Subject): RuleResult {\n\t\tif (!rule.premises || rule.premises.length === 0) {\n\t\t\treturn { id: rule.id, applied: false, premises: [], conclusion: false }\n\t\t}\n\t\tif (!rule.conclusion) {\n\t\t\treturn { id: rule.id, applied: false, premises: [], conclusion: false }\n\t\t}\n\n\t\tconst premiseResults = rule.premises.map((premise) =>\n\t\t\tthis.#evaluateExpression(premise, subject),\n\t\t)\n\t\tconst allPremisesMet = premiseResults.every(Boolean)\n\n\t\treturn {\n\t\t\tid: rule.id,\n\t\t\tapplied: allPremisesMet,\n\t\t\tpremises: premiseResults,\n\t\t\tconclusion: allPremisesMet,\n\t\t}\n\t}\n\n\t// EAGER evaluation (no short-circuit): `not` reads only its first operand\n\t// (empty → vacuously true); `implies` / `xor` read their first two.\n\t#evaluateExpression(expression: Expression, subject: Subject): boolean {\n\t\tif (expression.form === 'atom') {\n\t\t\treturn this.#evaluator.evaluate(expression.check, subject).met\n\t\t}\n\n\t\tconst results = expression.operands.map((operand) => this.#evaluateExpression(operand, subject))\n\n\t\tswitch (expression.operator) {\n\t\t\tcase 'and':\n\t\t\t\treturn results.every(Boolean)\n\t\t\tcase 'or':\n\t\t\t\treturn results.some(Boolean)\n\t\t\tcase 'not':\n\t\t\t\treturn results.length > 0 ? !results[0] : true\n\t\t\tcase 'implies':\n\t\t\t\treturn results.length < 2 ? true : !results[0] || (results[1] ?? false)\n\t\t\tcase 'xor':\n\t\t\t\treturn results.length < 2 ? false : results[0] !== results[1]\n\t\t\tdefault:\n\t\t\t\treturn false\n\t\t}\n\t}\n}\n","import type {\n\tDefinition,\n\tEquation,\n\tReasoning,\n\tReasonResult,\n\tReasonValidationResult,\n\tReasonerInterface,\n\tSubject,\n\tSymbolicExpression,\n\tSymbolicReasonerOptions,\n} from '../types.js'\nimport { parseNumber } from '@orkestrel/contract'\nimport {\n\tapplyOperation,\n\tcontainsVariable,\n\tfindDuplicates,\n\tinvertLeft,\n\tinvertRight,\n\troundTo,\n} from '../helpers.js'\nimport { DEFAULT_PRECISION, INVERTIBLE_OPERATIONS, SYMBOLIC_ID } from '../constants.js'\nimport { ReasonError } from '../errors.js'\n\n/**\n * The symbolic reasoner — algebraic equation solving by variable isolation.\n *\n * @remarks\n * Bindings seed from `definition.variables`, then numeric subject fields (a\n * finite number or a numeric string, coerced through the contracts\n * `parseNumber`) OVERRIDE same-named variables — the `id` field is skipped.\n * Equations solve strictly in order: when the `target` is unbound and appears\n * on exactly ONE side, it is isolated by peeling invertible operations (`add` /\n * `subtract` / `multiply` / `divide`); a non-invertible operation, a target on\n * both sides of an operation, or an unbound variable throws internally — the\n * throw is caught PER EQUATION and surfaced as a result error (`Equation\n * \"<id>\": <message>` plus a `FAILED` trace) while later equations still run.\n * Inversion or division by zero yields `NaN`, caught by the non-finite check.\n * A solved value is rounded to `precision` BEFORE binding, so later equations\n * see the rounded value; `solutions` reads FINAL bindings keyed by each\n * equation's target (a failed equation's target still appears when bound\n * elsewhere). Nothing mutates its inputs; fully deterministic (AGENTS §11).\n */\nexport class SymbolicReasoner implements ReasonerInterface {\n\treadonly #id: string\n\n\tconstructor(options?: SymbolicReasonerOptions) {\n\t\tthis.#id = options?.id ?? SYMBOLIC_ID\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget reasoning(): Reasoning {\n\t\treturn 'symbolic'\n\t}\n\n\tsupports(definition: Definition): boolean {\n\t\treturn definition.reasoning === 'symbolic'\n\t}\n\n\tvalidate(definition: Definition): ReasonValidationResult {\n\t\tconst errors: string[] = []\n\t\tconst warnings: string[] = []\n\n\t\tif (definition.reasoning !== 'symbolic') {\n\t\t\terrors.push(`Expected reasoning \"symbolic\", got \"${definition.reasoning}\"`)\n\t\t\treturn { valid: false, errors, warnings }\n\t\t}\n\n\t\tif (!definition.id) errors.push('Definition must have an id')\n\t\tif (!definition.name) errors.push('Definition must have a name')\n\t\tif (!definition.equations || definition.equations.length === 0) {\n\t\t\terrors.push('Definition must have at least one equation')\n\t\t}\n\n\t\t// Duplicate ids are WARNINGS — the runtime stays permissive about them.\n\t\tfor (const id of findDuplicates(definition.equations ?? [])) {\n\t\t\twarnings.push(`Duplicate equation id \"${id}\"`)\n\t\t}\n\n\t\tfor (const equation of definition.equations ?? []) {\n\t\t\tif (!equation.id) errors.push('Equation must have an id')\n\t\t\tif (!equation.target) errors.push(`Equation \"${equation.id}\" must have a target variable`)\n\t\t}\n\n\t\treturn { valid: errors.length === 0, errors, warnings }\n\t}\n\n\treason(subject: Subject, definition: Definition): ReasonResult {\n\t\tif (definition.reasoning !== 'symbolic') {\n\t\t\tthrow new ReasonError(\n\t\t\t\t'MISMATCH',\n\t\t\t\t`Expected symbolic definition, got \"${definition.reasoning}\"`,\n\t\t\t\t{ definition: definition.id, reasoning: this.reasoning },\n\t\t\t)\n\t\t}\n\n\t\t// Runtime never assumes validate() ran — a malformed shape is a failure\n\t\t// result, not a throw.\n\t\tif (!definition.equations || !Array.isArray(definition.equations)) {\n\t\t\treturn {\n\t\t\t\treasoning: 'symbolic',\n\t\t\t\tsolutions: {},\n\t\t\t\tsuccess: false,\n\t\t\t\ttrace: [],\n\t\t\t\terrors: ['Definition must have an \"equations\" array'],\n\t\t\t}\n\t\t}\n\n\t\tconst trace: string[] = []\n\t\tconst errors: string[] = []\n\t\tconst precision = definition.precision ?? DEFAULT_PRECISION\n\n\t\tconst bindings: Record<string, number> = { ...definition.variables }\n\n\t\t// Numeric subject fields bind as variables, OVERRIDING definition\n\t\t// variables of the same name; the `id` field is traceability, not data.\n\t\tlet bound = 0\n\t\tfor (const key of Object.keys(subject)) {\n\t\t\tif (key === 'id') continue\n\t\t\tconst value = parseNumber(subject[key])\n\t\t\tif (value !== undefined) {\n\t\t\t\tbindings[key] = value\n\t\t\t\ttrace.push(`Subject field \"${key}\" bound as ${key} = ${value}`)\n\t\t\t\tbound++\n\t\t\t}\n\t\t}\n\t\tif (bound > 0) trace.push(`Bound ${bound} variable(s) from subject`)\n\n\t\tif (definition.equations.length === 0) {\n\t\t\ttrace.push('No equations to solve')\n\t\t\treturn { reasoning: 'symbolic', solutions: {}, success: true, trace, errors }\n\t\t}\n\n\t\tfor (const equation of definition.equations) {\n\t\t\tif (typeof equation !== 'object' || equation === null) continue\n\t\t\ttry {\n\t\t\t\tconst value = this.#solve(equation, bindings)\n\t\t\t\tconst rounded = roundTo(value, precision)\n\t\t\t\t// The finite gate now covers BOTH a non-finite solved value AND a finite\n\t\t\t\t// value that OVERFLOWS during rounding (a huge constant scaled past the\n\t\t\t\t// double range → ±Infinity) — the latter previously slipped past the\n\t\t\t\t// pre-round check and bound Infinity with success:true. Describe whichever\n\t\t\t\t// is non-finite: the pre-round value keeps its exact rendering (e.g. a\n\t\t\t\t// non-numeric \"[object Object]\"), a round-overflow renders the ±Infinity.\n\t\t\t\tif (!Number.isFinite(value) || !Number.isFinite(rounded)) {\n\t\t\t\t\tconst offender = Number.isFinite(value) ? rounded : value\n\t\t\t\t\tconst description = Number.isNaN(offender) ? 'NaN' : `${offender}`\n\t\t\t\t\terrors.push(`Equation \"${equation.id}\": produced non-finite value (${description})`)\n\t\t\t\t\ttrace.push(\n\t\t\t\t\t\t`Equation \"${equation.id}\": FAILED — produced non-finite value (${description})`,\n\t\t\t\t\t)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\t// Rounded BEFORE binding — later equations see the rounded value.\n\t\t\t\tbindings[equation.target] = rounded\n\t\t\t\ttrace.push(`Equation \"${equation.id}\": ${equation.target} = ${rounded}`)\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error)\n\t\t\t\terrors.push(`Equation \"${equation.id}\": ${message}`)\n\t\t\t\ttrace.push(`Equation \"${equation.id}\": FAILED — ${message}`)\n\t\t\t}\n\t\t}\n\n\t\tconst solutions: Record<string, number> = {}\n\t\tfor (const equation of definition.equations) {\n\t\t\tif (typeof equation !== 'object' || equation === null) continue\n\t\t\tconst value = bindings[equation.target]\n\t\t\tif (value !== undefined) solutions[equation.target] = value\n\t\t}\n\n\t\treturn { reasoning: 'symbolic', solutions, success: errors.length === 0, trace, errors }\n\t}\n\n\t// Isolate around whichever side holds the unbound target; a pre-bound target\n\t// (or one absent from both sides) just re-evaluates the right side.\n\t#solve(equation: Equation, bindings: Record<string, number>): number {\n\t\tconst target = equation.target\n\t\tconst leftHas = containsVariable(equation.left, target, bindings)\n\t\tconst rightHas = containsVariable(equation.right, target, bindings)\n\n\t\tif (leftHas && rightHas) return this.#evaluate(equation.right, bindings)\n\t\tif (leftHas) {\n\t\t\tconst rhs = this.#evaluate(equation.right, bindings)\n\t\t\treturn this.#isolate(equation.left, target, rhs, bindings)\n\t\t}\n\t\tif (rightHas) {\n\t\t\tconst lhs = this.#evaluate(equation.left, bindings)\n\t\t\treturn this.#isolate(equation.right, target, lhs, bindings)\n\t\t}\n\t\treturn this.#evaluate(equation.right, bindings)\n\t}\n\n\t// Peel invertible operations off around the target until the bare variable\n\t// remains; every unsolvable shape throws (caught per equation by `reason`).\n\t#isolate(\n\t\texpression: SymbolicExpression,\n\t\ttarget: string,\n\t\tvalue: number,\n\t\tbindings: Record<string, number>,\n\t): number {\n\t\tif (expression.form === 'variable' && expression.name === target) return value\n\t\tif (expression.form !== 'operation') {\n\t\t\tthrow new Error(`Cannot isolate \"${target}\" — unexpected node form \"${expression.form}\"`)\n\t\t}\n\n\t\tconst operator = expression.operator\n\t\tif (!INVERTIBLE_OPERATIONS.has(operator)) {\n\t\t\tthrow new Error(`Cannot isolate \"${target}\" through non-invertible operation \"${operator}\"`)\n\t\t}\n\n\t\tconst leftHas = containsVariable(expression.left, target, bindings)\n\t\tconst rightExpression = expression.right\n\t\tconst rightHas = rightExpression ? containsVariable(rightExpression, target, bindings) : false\n\n\t\tif (leftHas && rightHas) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot isolate \"${target}\" — variable appears on both sides of \"${operator}\"`,\n\t\t\t)\n\t\t}\n\n\t\tif (leftHas) {\n\t\t\tconst rightValue = rightExpression ? this.#evaluate(rightExpression, bindings) : 0\n\t\t\treturn this.#isolate(\n\t\t\t\texpression.left,\n\t\t\t\ttarget,\n\t\t\t\tinvertLeft(operator, value, rightValue),\n\t\t\t\tbindings,\n\t\t\t)\n\t\t}\n\n\t\tif (rightHas && rightExpression) {\n\t\t\tconst leftValue = this.#evaluate(expression.left, bindings)\n\t\t\treturn this.#isolate(\n\t\t\t\trightExpression,\n\t\t\t\ttarget,\n\t\t\t\tinvertRight(operator, value, leftValue),\n\t\t\t\tbindings,\n\t\t\t)\n\t\t}\n\n\t\tthrow new Error(`Cannot isolate \"${target}\" — variable not found in expression`)\n\t}\n\n\t// Unary operations ignore `right`; a binary operation with no right operand\n\t// treats it as 0; an unbound variable throws (caught per equation).\n\t#evaluate(expression: SymbolicExpression, bindings: Record<string, number>): number {\n\t\tswitch (expression.form) {\n\t\t\tcase 'constant':\n\t\t\t\treturn expression.value\n\t\t\tcase 'variable': {\n\t\t\t\tconst value = bindings[expression.name]\n\t\t\t\tif (value === undefined) throw new Error(`Unbound variable: ${expression.name}`)\n\t\t\t\treturn value\n\t\t\t}\n\t\t\tcase 'operation': {\n\t\t\t\tconst operator = expression.operator\n\t\t\t\tconst left = this.#evaluate(expression.left, bindings)\n\t\t\t\tif (\n\t\t\t\t\toperator === 'round' ||\n\t\t\t\t\toperator === 'ceil' ||\n\t\t\t\t\toperator === 'floor' ||\n\t\t\t\t\toperator === 'abs'\n\t\t\t\t) {\n\t\t\t\t\treturn applyOperation(operator, left, 0)\n\t\t\t\t}\n\t\t\t\tconst right = expression.right ? this.#evaluate(expression.right, bindings) : 0\n\t\t\t\treturn applyOperation(operator, left, right)\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tthrow new Error('Unknown expression form')\n\t\t}\n\t}\n}\n","import type {\n\tDefinition,\n\tFact,\n\tInference,\n\tInferentialDefinition,\n\tInferentialReasonerOptions,\n\tProofNode,\n\tReasoning,\n\tReasonResult,\n\tReasonValidationResult,\n\tReasonerInterface,\n\tSubject,\n} from '../types.js'\nimport {\n\tfactToArityKey,\n\tfactToKey,\n\tfindDuplicates,\n\tfindUnboundVariables,\n\tindexByArity,\n\tinstantiateFact,\n\tmatchFacts,\n\troundTo,\n\tsubjectToFacts,\n} from '../helpers.js'\nimport {\n\tCONFIDENCE_PRECISION,\n\tDEFAULT_CONFIDENCE,\n\tDEFAULT_DEPTH,\n\tINFERENTIAL_ID,\n} from '../constants.js'\nimport { ReasonError } from '../errors.js'\n\n/**\n * The inferential reasoner — fact derivation with unification variables and\n * proof trees.\n *\n * @remarks\n * A string term starting with `?` is a unification variable — matching is\n * positional and BIDIRECTIONAL (variables may sit in facts as well as\n * patterns), with binding consistency enforced within one match and across\n * premises through pre-instantiation. Scalar subject fields (except `id`;\n * `null` / `undefined` / objects / arrays skipped) inject as\n * `has(key, value)` facts. Forward chaining is a naive fixpoint capped at\n * `depth` iterations: every consistent premise unification derives the\n * instantiated conclusion, with confidence = Π matched premise-fact confidences\n * × the inference's own `confidence`, rounded to four decimal places, and\n * duplicate facts (same predicate, arity, and SameValueZero-equal terms — a\n * NaN term derives once and converges) are never re-derived. Backward chaining\n * proves each inference's conclusion in\n * declaration order and RETURNS ON THE FIRST SUCCESS with one derived fact\n * (confidence = the inference's own — premise confidences are NOT propagated)\n * plus its {@link ProofNode} tree; recursion is guarded only by the depth cap.\n * Deriving nothing is still success. Nothing mutates its inputs; fully\n * deterministic (AGENTS §11).\n */\nexport class InferentialReasoner implements ReasonerInterface {\n\treadonly #id: string\n\n\tconstructor(options?: InferentialReasonerOptions) {\n\t\tthis.#id = options?.id ?? INFERENTIAL_ID\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget reasoning(): Reasoning {\n\t\treturn 'inferential'\n\t}\n\n\tsupports(definition: Definition): boolean {\n\t\treturn definition.reasoning === 'inferential'\n\t}\n\n\tvalidate(definition: Definition): ReasonValidationResult {\n\t\tconst errors: string[] = []\n\t\tconst warnings: string[] = []\n\n\t\tif (definition.reasoning !== 'inferential') {\n\t\t\terrors.push(`Expected reasoning \"inferential\", got \"${definition.reasoning}\"`)\n\t\t\treturn { valid: false, errors, warnings }\n\t\t}\n\n\t\tif (!definition.id) errors.push('Definition must have an id')\n\t\tif (!definition.name) errors.push('Definition must have a name')\n\n\t\t// An empty inference set is suspicious but runnable — a WARNING, not an\n\t\t// error (unlike the other reasoners' empty collections).\n\t\tif (!definition.inferences || definition.inferences.length === 0) {\n\t\t\twarnings.push('Definition has no inference rules')\n\t\t}\n\n\t\t// Duplicate ids are WARNINGS — the runtime stays permissive about them.\n\t\tfor (const id of findDuplicates(definition.inferences ?? [])) {\n\t\t\twarnings.push(`Duplicate inference id \"${id}\"`)\n\t\t}\n\n\t\t// Confidence is a 0–1 multiplicative weight; anything outside is\n\t\t// suspicious but runnable — a WARNING, never an error.\n\t\tfor (const fact of definition.facts ?? []) {\n\t\t\tif (typeof fact !== 'object' || fact === null) continue\n\t\t\tif (fact.confidence !== undefined && !(fact.confidence >= 0 && fact.confidence <= 1)) {\n\t\t\t\twarnings.push(`Fact \"${fact.id}\" confidence outside [0, 1]`)\n\t\t\t}\n\t\t}\n\n\t\tfor (const inference of definition.inferences ?? []) {\n\t\t\tif (typeof inference !== 'object' || inference === null) continue\n\t\t\tif (!inference.id) errors.push('Inference must have an id')\n\t\t\tif (!inference.premises || inference.premises.length === 0) {\n\t\t\t\twarnings.push(`Inference \"${inference.id}\" has no premises`)\n\t\t\t}\n\t\t\tif (!inference.conclusion) {\n\t\t\t\terrors.push(`Inference \"${inference.id}\" must have a conclusion`)\n\t\t\t}\n\t\t\tif (\n\t\t\t\tinference.confidence !== undefined &&\n\t\t\t\t!(inference.confidence >= 0 && inference.confidence <= 1)\n\t\t\t) {\n\t\t\t\twarnings.push(`Inference \"${inference.id}\" confidence outside [0, 1]`)\n\t\t\t}\n\t\t\t// Unbound-variable footgun: only meaningful for an enabled,\n\t\t\t// conclusion-bearing inference (a missing conclusion has nothing to check).\n\t\t\tif (inference.enabled !== false && inference.conclusion) {\n\t\t\t\tfor (const name of findUnboundVariables(inference)) {\n\t\t\t\t\twarnings.push(\n\t\t\t\t\t\t`Inference \"${inference.id}\" conclusion variable \"${name}\" is unbound by all premises`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn { valid: errors.length === 0, errors, warnings }\n\t}\n\n\treason(subject: Subject, definition: Definition): ReasonResult {\n\t\tif (definition.reasoning !== 'inferential') {\n\t\t\tthrow new ReasonError(\n\t\t\t\t'MISMATCH',\n\t\t\t\t`Expected inferential definition, got \"${definition.reasoning}\"`,\n\t\t\t\t{ definition: definition.id, reasoning: this.reasoning },\n\t\t\t)\n\t\t}\n\n\t\t// Runtime never assumes validate() ran — a malformed shape is a failure\n\t\t// result, not a throw.\n\t\tif (\n\t\t\t!definition.facts ||\n\t\t\t!Array.isArray(definition.facts) ||\n\t\t\t!definition.inferences ||\n\t\t\t!Array.isArray(definition.inferences)\n\t\t) {\n\t\t\treturn {\n\t\t\t\treasoning: 'inferential',\n\t\t\t\tderived: [],\n\t\t\t\tsuccess: false,\n\t\t\t\ttrace: [],\n\t\t\t\terrors: ['Definition must have \"facts\" and \"inferences\" arrays'],\n\t\t\t}\n\t\t}\n\n\t\tconst trace: string[] = []\n\t\tconst errors: string[] = []\n\t\tconst subjectFacts = subjectToFacts(subject, trace)\n\n\t\tconst result =\n\t\t\tdefinition.strategy === 'backward'\n\t\t\t\t? this.#backward(definition, subjectFacts, trace, errors)\n\t\t\t\t: this.#forward(definition, subjectFacts, trace, errors)\n\n\t\treturn {\n\t\t\treasoning: 'inferential',\n\t\t\tderived: result.derived,\n\t\t\tproof: result.proof,\n\t\t\tsuccess: errors.length === 0,\n\t\t\ttrace,\n\t\t\terrors,\n\t\t}\n\t}\n\n\t// Data-driven fixpoint: derive every consistent unification per iteration,\n\t// dedupe against known facts, and stop on convergence or the depth cap.\n\t#forward(\n\t\tdefinition: InferentialDefinition,\n\t\tsubjectFacts: readonly Fact[],\n\t\ttrace: string[],\n\t\terrors: string[],\n\t): { derived: Fact[]; proof?: ProofNode } {\n\t\tconst maxDepth = definition.depth ?? DEFAULT_DEPTH\n\t\tconst knownFacts: Fact[] = []\n\t\tfor (const known of [...definition.facts, ...subjectFacts]) {\n\t\t\tif (typeof known !== 'object' || known === null) continue\n\t\t\tknownFacts.push(known)\n\t\t}\n\t\tconst derived: Fact[] = []\n\t\t// Dedup via a Set of canonical fact keys maintained ALONGSIDE knownFacts, so\n\t\t// membership is O(1) instead of a full linear rescan per candidate. `identities`\n\t\t// keys object/function terms by REFERENCE (mirroring equalValues' `===`) so\n\t\t// distinct objects never collide; primitives collapse under SameValueZero.\n\t\tconst identities = new Map<object, number>()\n\t\tconst seen = new Set<string>()\n\t\tfor (const known of knownFacts) seen.add(factToKey(known, identities))\n\t\t// A predicate+arity index maintained INCREMENTALLY alongside `seen` (seeded\n\t\t// from the base facts, appended at every derivation) so the same-predicate\n\t\t// join scans never rebuild it per premise. It reflects EVERY fact known so\n\t\t// far — including ones derived earlier in THIS pass — preserving the live\n\t\t// intra-iteration growth (an early derivation feeds a later inference in the\n\t\t// same pass). Arity-refinement only NARROWS each bucket to facts matchFacts\n\t\t// would have accepted anyway, so the surviving matches and their append\n\t\t// order are identical to a predicate-only index.\n\t\tconst byArity = indexByArity(knownFacts)\n\n\t\tif (definition.inferences.length === 0) {\n\t\t\ttrace.push('No inference rules defined')\n\t\t\treturn { derived }\n\t\t}\n\n\t\t// Pre-filter: disabled inferences skip silently; a premise-less or\n\t\t// conclusion-less inference errors once and is excluded.\n\t\tconst validInferences: Inference[] = []\n\t\tfor (const inference of definition.inferences) {\n\t\t\tif (typeof inference !== 'object' || inference === null) continue\n\t\t\tif (inference.enabled === false) continue\n\t\t\tif (!inference.premises || inference.premises.length === 0) {\n\t\t\t\terrors.push(`Inference \"${inference.id}\" has no premises — skipped`)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (!inference.conclusion) {\n\t\t\t\terrors.push(`Inference \"${inference.id}\" has no conclusion — skipped`)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvalidInferences.push(inference)\n\t\t}\n\n\t\tfor (let iteration = 0; iteration < maxDepth; iteration++) {\n\t\t\tlet newDerivation = false\n\n\t\t\tfor (const inference of validInferences) {\n\t\t\t\tconst allBindings = this.#findAllBindings(inference.premises, byArity)\n\n\t\t\t\tfor (const bindings of allBindings) {\n\t\t\t\t\tconst conclusion = instantiateFact(inference.conclusion, bindings)\n\t\t\t\t\tconst premiseConfidence = this.#calculatePremiseConfidence(\n\t\t\t\t\t\tinference.premises,\n\t\t\t\t\t\tbyArity,\n\t\t\t\t\t\tbindings,\n\t\t\t\t\t)\n\t\t\t\t\tconst inferenceConfidence = inference.confidence ?? DEFAULT_CONFIDENCE\n\t\t\t\t\tconst finalConfidence = premiseConfidence * inferenceConfidence\n\n\t\t\t\t\tconst derivedFact: Fact = {\n\t\t\t\t\t\t...conclusion,\n\t\t\t\t\t\tconfidence: roundTo(finalConfidence, CONFIDENCE_PRECISION),\n\t\t\t\t\t}\n\n\t\t\t\t\tconst key = factToKey(derivedFact, identities)\n\t\t\t\t\tif (!seen.has(key)) {\n\t\t\t\t\t\tknownFacts.push(derivedFact)\n\t\t\t\t\t\t// Mirror the push into the live index (same order) so later premises\n\t\t\t\t\t\t// in this very pass can join against the freshly derived fact.\n\t\t\t\t\t\tconst arityKey = factToArityKey(derivedFact)\n\t\t\t\t\t\tconst bucket = byArity.get(arityKey)\n\t\t\t\t\t\tif (bucket) bucket.push(derivedFact)\n\t\t\t\t\t\telse byArity.set(arityKey, [derivedFact])\n\t\t\t\t\t\tseen.add(key)\n\t\t\t\t\t\tderived.push(derivedFact)\n\t\t\t\t\t\tnewDerivation = true\n\t\t\t\t\t\ttrace.push(\n\t\t\t\t\t\t\t`Derived ${derivedFact.predicate}(${derivedFact.terms.join(', ')}) ` +\n\t\t\t\t\t\t\t\t`via \"${inference.id}\" [confidence: ${derivedFact.confidence}] (iteration ${iteration + 1})`,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!newDerivation) {\n\t\t\t\ttrace.push(`Forward chaining converged at iteration ${iteration + 1}`)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\treturn { derived }\n\t}\n\n\t// Goal-driven: prove each inference's conclusion in declaration order and\n\t// return on the FIRST success with its proof tree.\n\t#backward(\n\t\tdefinition: InferentialDefinition,\n\t\tsubjectFacts: readonly Fact[],\n\t\ttrace: string[],\n\t\terrors: string[],\n\t): { derived: Fact[]; proof?: ProofNode } {\n\t\tconst maxDepth = definition.depth ?? DEFAULT_DEPTH\n\t\tconst derived: Fact[] = []\n\t\tconst allBaseFacts: Fact[] = []\n\t\tfor (const known of [...definition.facts, ...subjectFacts]) {\n\t\t\tif (typeof known !== 'object' || known === null) continue\n\t\t\tallBaseFacts.push(known)\n\t\t}\n\n\t\tif (definition.inferences.length === 0) {\n\t\t\ttrace.push('No inference rules defined')\n\t\t\treturn { derived }\n\t\t}\n\n\t\tfor (const inference of definition.inferences) {\n\t\t\tif (typeof inference !== 'object' || inference === null) continue\n\t\t\tif (inference.enabled === false) continue\n\n\t\t\tif (!inference.conclusion) {\n\t\t\t\terrors.push(`Inference \"${inference.id}\" has no conclusion — skipped`)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst proof = this.#prove(\n\t\t\t\tinference.conclusion,\n\t\t\t\tdefinition.inferences,\n\t\t\t\tallBaseFacts,\n\t\t\t\t0,\n\t\t\t\tmaxDepth,\n\t\t\t)\n\n\t\t\tif (proof) {\n\t\t\t\t// Backward confidence is the inference's own — premise confidences\n\t\t\t\t// are NOT propagated here.\n\t\t\t\tconst derivedFact: Fact = {\n\t\t\t\t\t...inference.conclusion,\n\t\t\t\t\tconfidence: inference.confidence ?? DEFAULT_CONFIDENCE,\n\t\t\t\t}\n\t\t\t\tderived.push(derivedFact)\n\t\t\t\ttrace.push(\n\t\t\t\t\t`Proved ${inference.conclusion.predicate}(${inference.conclusion.terms.join(', ')})`,\n\t\t\t\t)\n\t\t\t\treturn { derived, proof }\n\t\t\t}\n\t\t}\n\n\t\treturn { derived }\n\t}\n\n\t// A goal proves as a base-fact leaf, or through an inference whose conclusion\n\t// unifies and whose premises all prove at depth + 1. No memoization; the\n\t// depth cap is the only recursion guard.\n\t#prove(\n\t\tgoal: Fact,\n\t\tinferences: readonly Inference[],\n\t\tbaseFacts: readonly Fact[],\n\t\tdepth: number,\n\t\tmaxDepth: number,\n\t): ProofNode | undefined {\n\t\tif (depth > maxDepth) return undefined\n\n\t\tfor (const fact of baseFacts) {\n\t\t\tif (matchFacts(goal, fact)) {\n\t\t\t\treturn { fact: fact.id, depth }\n\t\t\t}\n\t\t}\n\n\t\tfor (const inference of inferences) {\n\t\t\tif (typeof inference !== 'object' || inference === null) continue\n\t\t\tif (inference.enabled === false) continue\n\t\t\t// A candidate whose premises are missing / not an array cannot be\n\t\t\t// walked — skipped SILENTLY (backward's error posture reports only\n\t\t\t// missing conclusions; the forward pre-filter is where premises error).\n\t\t\tif (!inference.premises || !Array.isArray(inference.premises)) continue\n\t\t\t// A conclusion-less candidate has nothing to unify the goal against.\n\t\t\tif (!inference.conclusion) continue\n\n\t\t\tconst conclusionBindings = matchFacts(goal, inference.conclusion)\n\t\t\tif (!conclusionBindings) continue\n\n\t\t\tconst children: ProofNode[] = []\n\t\t\tlet allProved = true\n\n\t\t\tfor (const premise of inference.premises) {\n\t\t\t\tconst instantiated = instantiateFact(premise, conclusionBindings)\n\t\t\t\tconst child = this.#prove(instantiated, inferences, baseFacts, depth + 1, maxDepth)\n\t\t\t\tif (child) {\n\t\t\t\t\tchildren.push(child)\n\t\t\t\t} else {\n\t\t\t\t\tallProved = false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (allProved) {\n\t\t\t\treturn { fact: goal.id, inference: inference.id, children, depth }\n\t\t\t}\n\t\t}\n\n\t\treturn undefined\n\t}\n\n\t// Relational join: thread accumulated bindings through each premise in turn,\n\t// branching per matching fact; any empty stage short-circuits to none. Reads the\n\t// LIVE predicate+arity index (maintained by #forward), so each premise scans only\n\t// its own predicate+arity bucket (append order kept) rather than the whole fact\n\t// base — matchFacts already rejects a predicate OR arity mismatch, so the matches\n\t// are identical.\n\t#findAllBindings(\n\t\tpremises: readonly Fact[],\n\t\tbyArity: ReadonlyMap<string, Fact[]>,\n\t): Record<string, unknown>[] {\n\t\tif (premises.length === 0) return [{}]\n\n\t\tlet currentBindings: Record<string, unknown>[] = [{}]\n\n\t\tfor (const premise of premises) {\n\t\t\tconst nextBindings: Record<string, unknown>[] = []\n\t\t\tconst candidates = byArity.get(factToArityKey(premise)) ?? []\n\n\t\t\tfor (const existing of currentBindings) {\n\t\t\t\tconst instantiated = instantiateFact(premise, existing)\n\t\t\t\tfor (const fact of candidates) {\n\t\t\t\t\tconst match = matchFacts(instantiated, fact)\n\t\t\t\t\tif (match) nextBindings.push({ ...existing, ...match })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrentBindings = nextBindings\n\t\t\tif (currentBindings.length === 0) break\n\t\t}\n\n\t\treturn currentBindings\n\t}\n\n\t// Multiply in the FIRST matching fact's confidence per premise; a premise\n\t// with no match contributes nothing. Reads the LIVE predicate+arity index\n\t// (append order kept), so the FIRST bucket match is the same fact the full\n\t// scan would.\n\t#calculatePremiseConfidence(\n\t\tpremises: readonly Fact[],\n\t\tbyArity: ReadonlyMap<string, Fact[]>,\n\t\tbindings: Record<string, unknown>,\n\t): number {\n\t\tlet confidence = 1\n\n\t\tfor (const premise of premises) {\n\t\t\tconst instantiated = instantiateFact(premise, bindings)\n\t\t\tfor (const fact of byArity.get(factToArityKey(premise)) ?? []) {\n\t\t\t\tif (matchFacts(instantiated, fact)) {\n\t\t\t\t\tconfidence *= fact.confidence ?? DEFAULT_CONFIDENCE\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn confidence\n\t}\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tEquation,\n\tEquationManagerEventMap,\n\tEquationManagerInterface,\n\tEquationManagerOptions,\n} from '../../types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { appendById, prependById, removeById, replaceById } from '../../helpers.js'\nimport { ReasonError } from '../../errors.js'\n\n/**\n * The {@link EquationManagerInterface} implementation — a self-owning,\n * kind-free manager over a symbolic definition's `equations`.\n *\n * @remarks\n * OWNS its `#equations` collection as private copy-on-write state and its own\n * {@link Emitter} over {@link EquationManagerEventMap}. Equation order is\n * STRONGLY load-bearing — equations solve strictly in order and each rounded\n * solution feeds forward. The write-only `collection` setter is the owning\n * builder's silent bulk re-seat channel (used by `merge`). `destroy()` is\n * idempotent and tears the emitter down LAST; any other call after it throws\n * `ReasonError('DESTROYED', …)`.\n */\nexport class EquationManager implements EquationManagerInterface {\n\t#equations: readonly Equation[]\n\treadonly #emitter: Emitter<EquationManagerEventMap>\n\t#destroyed = false\n\n\tconstructor(options?: EquationManagerOptions) {\n\t\tthis.#equations = options?.equations ?? []\n\t\tthis.#emitter = new Emitter<EquationManagerEventMap>({\n\t\t\ton: options?.on,\n\t\t\terror: options?.error,\n\t\t})\n\t}\n\n\tget emitter(): EmitterInterface<EquationManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tset collection(value: readonly Equation[]) {\n\t\tthis.#ensureAlive()\n\t\tthis.#equations = value\n\t}\n\n\tequation(id: string): Equation | undefined {\n\t\tthis.#ensureAlive()\n\t\treturn this.#equations.find((equation) => equation.id === id)\n\t}\n\n\tequations(): readonly Equation[] {\n\t\tthis.#ensureAlive()\n\t\treturn this.#equations\n\t}\n\n\tappend(equation: Equation, target?: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#equations = appendById(this.#equations, equation, target)\n\t\tthis.#emitter.emit('append', equation.id)\n\t}\n\n\tprepend(equation: Equation, target?: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#equations = prependById(this.#equations, equation, target)\n\t\tthis.#emitter.emit('prepend', equation.id)\n\t}\n\n\treplace(equation: Equation): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#equations = replaceById(this.#equations, equation)\n\t\tthis.#emitter.emit('replace', equation.id)\n\t}\n\n\tremove(id: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#equations = removeById(this.#equations, id)\n\t\tthis.#emitter.emit('remove', id)\n\t}\n\n\tdestroy(): void {\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.emit('destroy')\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) {\n\t\t\tthrow new ReasonError('DESTROYED', 'EquationManager has been destroyed')\n\t\t}\n\t}\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tFact,\n\tFactManagerEventMap,\n\tFactManagerInterface,\n\tFactManagerOptions,\n} from '../../types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { appendById, prependById, removeById, replaceById } from '../../helpers.js'\nimport { ReasonError } from '../../errors.js'\n\n/**\n * The {@link FactManagerInterface} implementation — a self-owning, kind-free\n * manager over an inferential definition's `facts`.\n *\n * @remarks\n * OWNS its `#facts` collection as private copy-on-write state and its own\n * {@link Emitter} over {@link FactManagerEventMap}. `Fact.id` is an AUTHORING\n * label — the runtime content-dedups facts by predicate+arity+terms,\n * independently of this manager's id-keyed dedup. The write-only `collection`\n * setter is the owning builder's silent bulk re-seat channel (used by `merge`).\n * `destroy()` is idempotent and tears the emitter down LAST; any other call\n * after it throws `ReasonError('DESTROYED', …)`.\n */\nexport class FactManager implements FactManagerInterface {\n\t#facts: readonly Fact[]\n\treadonly #emitter: Emitter<FactManagerEventMap>\n\t#destroyed = false\n\n\tconstructor(options?: FactManagerOptions) {\n\t\tthis.#facts = options?.facts ?? []\n\t\tthis.#emitter = new Emitter<FactManagerEventMap>({ on: options?.on, error: options?.error })\n\t}\n\n\tget emitter(): EmitterInterface<FactManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tset collection(value: readonly Fact[]) {\n\t\tthis.#ensureAlive()\n\t\tthis.#facts = value\n\t}\n\n\tfact(id: string): Fact | undefined {\n\t\tthis.#ensureAlive()\n\t\treturn this.#facts.find((fact) => fact.id === id)\n\t}\n\n\tfacts(): readonly Fact[] {\n\t\tthis.#ensureAlive()\n\t\treturn this.#facts\n\t}\n\n\tappend(fact: Fact, target?: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#facts = appendById(this.#facts, fact, target)\n\t\tthis.#emitter.emit('append', fact.id)\n\t}\n\n\tprepend(fact: Fact, target?: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#facts = prependById(this.#facts, fact, target)\n\t\tthis.#emitter.emit('prepend', fact.id)\n\t}\n\n\treplace(fact: Fact): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#facts = replaceById(this.#facts, fact)\n\t\tthis.#emitter.emit('replace', fact.id)\n\t}\n\n\tremove(id: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#facts = removeById(this.#facts, id)\n\t\tthis.#emitter.emit('remove', id)\n\t}\n\n\tdestroy(): void {\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.emit('destroy')\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) {\n\t\t\tthrow new ReasonError('DESTROYED', 'FactManager has been destroyed')\n\t\t}\n\t}\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tFactor,\n\tFactorGroup,\n\tFactorManagerEventMap,\n\tFactorManagerInterface,\n\tFactorManagerOptions,\n\tGroupManagerInterface,\n} from '../../types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { appendFactor, prependFactor, removeFactor, replaceFactor } from '../../helpers.js'\nimport { ReasonError } from '../../errors.js'\n\n/**\n * The {@link FactorManagerInterface} implementation — the sole DIVERGENT\n * manager: factors nest inside groups, so it holds NO collection state of its\n * own and threads a required `groupId` locator.\n *\n * @remarks\n * Constructor-injected with the sibling {@link GroupManagerInterface}: each\n * write verb reads the located group (`groups.group(groupId)`), applies the\n * factor-level pure helper ({@link appendFactor} etc.), and writes the updated\n * group back via `groups.replace(…)`. A `groupId` naming no existing group\n * throws `ReasonError('TARGET', …, { groupId })`. It still owns its OWN\n * {@link Emitter} over {@link FactorManagerEventMap} (factor-id payloads).\n * `destroy()` is idempotent and tears the emitter down LAST; any other call\n * after it throws `ReasonError('DESTROYED', …)`.\n */\nexport class FactorManager implements FactorManagerInterface {\n\treadonly #groups: GroupManagerInterface\n\treadonly #emitter: Emitter<FactorManagerEventMap>\n\t#destroyed = false\n\n\tconstructor(groups: GroupManagerInterface, options?: FactorManagerOptions) {\n\t\tthis.#groups = groups\n\t\tthis.#emitter = new Emitter<FactorManagerEventMap>({ on: options?.on, error: options?.error })\n\t}\n\n\tget emitter(): EmitterInterface<FactorManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tfactor(groupId: string, id: string): Factor | undefined {\n\t\tthis.#ensureAlive()\n\t\treturn this.#locate(groupId).factors.find((factor) => factor.id === id)\n\t}\n\n\tfactors(groupId: string): readonly Factor[] {\n\t\tthis.#ensureAlive()\n\t\treturn this.#locate(groupId).factors\n\t}\n\n\tappend(groupId: string, factor: Factor, target?: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#groups.replace(appendFactor(this.#locate(groupId), factor, target))\n\t\tthis.#emitter.emit('append', factor.id)\n\t}\n\n\tprepend(groupId: string, factor: Factor, target?: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#groups.replace(prependFactor(this.#locate(groupId), factor, target))\n\t\tthis.#emitter.emit('prepend', factor.id)\n\t}\n\n\treplace(groupId: string, factor: Factor): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#groups.replace(replaceFactor(this.#locate(groupId), factor))\n\t\tthis.#emitter.emit('replace', factor.id)\n\t}\n\n\tremove(groupId: string, id: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#groups.replace(removeFactor(this.#locate(groupId), id))\n\t\tthis.#emitter.emit('remove', id)\n\t}\n\n\tdestroy(): void {\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.emit('destroy')\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) {\n\t\t\tthrow new ReasonError('DESTROYED', 'FactorManager has been destroyed')\n\t\t}\n\t}\n\n\t// A `groupId` naming no existing group is an unresolved locator — the same\n\t// `TARGET` code the optional `target` id uses.\n\t#locate(groupId: string): FactorGroup {\n\t\tconst group = this.#groups.group(groupId)\n\t\tif (group === undefined) {\n\t\t\tthrow new ReasonError('TARGET', `Target group id \"${groupId}\" not found`, { groupId })\n\t\t}\n\t\treturn group\n\t}\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tFactorGroup,\n\tGroupManagerEventMap,\n\tGroupManagerInterface,\n\tGroupManagerOptions,\n} from '../../types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { appendById, prependById, removeById, replaceById } from '../../helpers.js'\nimport { ReasonError } from '../../errors.js'\n\n/**\n * The {@link GroupManagerInterface} implementation — a self-owning, kind-free\n * manager over a quantitative definition's `groups`.\n *\n * @remarks\n * OWNS its `#groups` collection as private copy-on-write state and its own\n * {@link Emitter} over {@link GroupManagerEventMap}. Every write verb delegates\n * to the matching collection-level pure helper ({@link appendById} etc.),\n * reassigns the fresh array, then emits (the affected group id) AFTER the\n * mutation. The write-only `collection` setter is the owning builder's silent\n * bulk re-seat channel (used by `merge`). `destroy()` is idempotent and tears\n * the emitter down LAST; any other call after it throws\n * `ReasonError('DESTROYED', …)`.\n */\nexport class GroupManager implements GroupManagerInterface {\n\t#groups: readonly FactorGroup[]\n\treadonly #emitter: Emitter<GroupManagerEventMap>\n\t#destroyed = false\n\n\tconstructor(options?: GroupManagerOptions) {\n\t\tthis.#groups = options?.groups ?? []\n\t\tthis.#emitter = new Emitter<GroupManagerEventMap>({ on: options?.on, error: options?.error })\n\t}\n\n\tget emitter(): EmitterInterface<GroupManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\t// The owning builder's bulk re-seat channel — replaces the whole collection\n\t// in one silent assignment (no per-element events); used by `merge`.\n\tset collection(value: readonly FactorGroup[]) {\n\t\tthis.#ensureAlive()\n\t\tthis.#groups = value\n\t}\n\n\tgroup(id: string): FactorGroup | undefined {\n\t\tthis.#ensureAlive()\n\t\treturn this.#groups.find((group) => group.id === id)\n\t}\n\n\tgroups(): readonly FactorGroup[] {\n\t\tthis.#ensureAlive()\n\t\treturn this.#groups\n\t}\n\n\tappend(group: FactorGroup, target?: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#groups = appendById(this.#groups, group, target)\n\t\tthis.#emitter.emit('append', group.id)\n\t}\n\n\tprepend(group: FactorGroup, target?: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#groups = prependById(this.#groups, group, target)\n\t\tthis.#emitter.emit('prepend', group.id)\n\t}\n\n\treplace(group: FactorGroup): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#groups = replaceById(this.#groups, group)\n\t\tthis.#emitter.emit('replace', group.id)\n\t}\n\n\tremove(id: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#groups = removeById(this.#groups, id)\n\t\tthis.#emitter.emit('remove', id)\n\t}\n\n\tdestroy(): void {\n\t\t// Idempotent: a second call re-flags an already-destroyed manager and\n\t\t// emits into an already-destroyed emitter (a no-op).\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.emit('destroy')\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) {\n\t\t\tthrow new ReasonError('DESTROYED', 'GroupManager has been destroyed')\n\t\t}\n\t}\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tInference,\n\tInferenceManagerEventMap,\n\tInferenceManagerInterface,\n\tInferenceManagerOptions,\n} from '../../types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { appendById, prependById, removeById, replaceById } from '../../helpers.js'\nimport { ReasonError } from '../../errors.js'\n\n/**\n * The {@link InferenceManagerInterface} implementation — a self-owning,\n * kind-free manager over an inferential definition's `inferences`.\n *\n * @remarks\n * OWNS its `#inferences` collection as private copy-on-write state and its own\n * {@link Emitter} over {@link InferenceManagerEventMap}. Inference order is\n * LOAD-BEARING — backward proving iterates in declaration order and returns on\n * first success. The write-only `collection` setter is the owning builder's\n * silent bulk re-seat channel (used by `merge`). `destroy()` is idempotent and\n * tears the emitter down LAST; any other call after it throws\n * `ReasonError('DESTROYED', …)`.\n */\nexport class InferenceManager implements InferenceManagerInterface {\n\t#inferences: readonly Inference[]\n\treadonly #emitter: Emitter<InferenceManagerEventMap>\n\t#destroyed = false\n\n\tconstructor(options?: InferenceManagerOptions) {\n\t\tthis.#inferences = options?.inferences ?? []\n\t\tthis.#emitter = new Emitter<InferenceManagerEventMap>({\n\t\t\ton: options?.on,\n\t\t\terror: options?.error,\n\t\t})\n\t}\n\n\tget emitter(): EmitterInterface<InferenceManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tset collection(value: readonly Inference[]) {\n\t\tthis.#ensureAlive()\n\t\tthis.#inferences = value\n\t}\n\n\tinference(id: string): Inference | undefined {\n\t\tthis.#ensureAlive()\n\t\treturn this.#inferences.find((inference) => inference.id === id)\n\t}\n\n\tinferences(): readonly Inference[] {\n\t\tthis.#ensureAlive()\n\t\treturn this.#inferences\n\t}\n\n\tappend(inference: Inference, target?: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#inferences = appendById(this.#inferences, inference, target)\n\t\tthis.#emitter.emit('append', inference.id)\n\t}\n\n\tprepend(inference: Inference, target?: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#inferences = prependById(this.#inferences, inference, target)\n\t\tthis.#emitter.emit('prepend', inference.id)\n\t}\n\n\treplace(inference: Inference): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#inferences = replaceById(this.#inferences, inference)\n\t\tthis.#emitter.emit('replace', inference.id)\n\t}\n\n\tremove(id: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#inferences = removeById(this.#inferences, id)\n\t\tthis.#emitter.emit('remove', id)\n\t}\n\n\tdestroy(): void {\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.emit('destroy')\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) {\n\t\t\tthrow new ReasonError('DESTROYED', 'InferenceManager has been destroyed')\n\t\t}\n\t}\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tRule,\n\tRuleManagerEventMap,\n\tRuleManagerInterface,\n\tRuleManagerOptions,\n} from '../../types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { appendById, prependById, removeById, replaceById } from '../../helpers.js'\nimport { ReasonError } from '../../errors.js'\n\n/**\n * The {@link RuleManagerInterface} implementation — a self-owning, kind-free\n * manager over a logical definition's `rules`.\n *\n * @remarks\n * OWNS its `#rules` collection as private copy-on-write state and its own\n * {@link Emitter} over {@link RuleManagerEventMap}. Rule order is LOAD-BEARING —\n * the forward conclusion is the LAST declared non-disabled rule, so `append`\n * without a `target` makes the new rule the conclusion. The write-only\n * `collection` setter is the owning builder's silent bulk re-seat channel\n * (used by `merge`). `destroy()` is idempotent and tears the emitter down LAST;\n * any other call after it throws `ReasonError('DESTROYED', …)`.\n */\nexport class RuleManager implements RuleManagerInterface {\n\t#rules: readonly Rule[]\n\treadonly #emitter: Emitter<RuleManagerEventMap>\n\t#destroyed = false\n\n\tconstructor(options?: RuleManagerOptions) {\n\t\tthis.#rules = options?.rules ?? []\n\t\tthis.#emitter = new Emitter<RuleManagerEventMap>({ on: options?.on, error: options?.error })\n\t}\n\n\tget emitter(): EmitterInterface<RuleManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tset collection(value: readonly Rule[]) {\n\t\tthis.#ensureAlive()\n\t\tthis.#rules = value\n\t}\n\n\trule(id: string): Rule | undefined {\n\t\tthis.#ensureAlive()\n\t\treturn this.#rules.find((rule) => rule.id === id)\n\t}\n\n\trules(): readonly Rule[] {\n\t\tthis.#ensureAlive()\n\t\treturn this.#rules\n\t}\n\n\tappend(rule: Rule, target?: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#rules = appendById(this.#rules, rule, target)\n\t\tthis.#emitter.emit('append', rule.id)\n\t}\n\n\tprepend(rule: Rule, target?: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#rules = prependById(this.#rules, rule, target)\n\t\tthis.#emitter.emit('prepend', rule.id)\n\t}\n\n\treplace(rule: Rule): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#rules = replaceById(this.#rules, rule)\n\t\tthis.#emitter.emit('replace', rule.id)\n\t}\n\n\tremove(id: string): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#rules = removeById(this.#rules, id)\n\t\tthis.#emitter.emit('remove', id)\n\t}\n\n\tdestroy(): void {\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.emit('destroy')\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) {\n\t\t\tthrow new ReasonError('DESTROYED', 'RuleManager has been destroyed')\n\t\t}\n\t}\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tVariableManagerEventMap,\n\tVariableManagerInterface,\n\tVariableManagerOptions,\n} from '../../types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { ReasonError } from '../../errors.js'\n\n/**\n * The {@link VariableManagerInterface} implementation — a self-owning,\n * kind-free manager over a symbolic definition's `variables`, a name-keyed\n * unordered record.\n *\n * @remarks\n * OWNS its `#variables` record as private copy-on-write state and its own\n * {@link Emitter} over {@link VariableManagerEventMap}. The record has no\n * placement, so only `add` / `remove` exist (no `append` / `prepend`): `add`\n * upserts and emits `add(name)`, `remove` omits the key entirely (never sets\n * `undefined`) and emits `remove(name)`. The write-only `collection` setter is\n * the owning builder's silent bulk re-seat channel (used by `merge`).\n * `destroy()` is idempotent and tears the emitter down LAST; any other call\n * after it throws `ReasonError('DESTROYED', …)`.\n */\nexport class VariableManager implements VariableManagerInterface {\n\t#variables: Readonly<Record<string, number>>\n\treadonly #emitter: Emitter<VariableManagerEventMap>\n\t#destroyed = false\n\n\tconstructor(options?: VariableManagerOptions) {\n\t\tthis.#variables = options?.variables ?? {}\n\t\tthis.#emitter = new Emitter<VariableManagerEventMap>({\n\t\t\ton: options?.on,\n\t\t\terror: options?.error,\n\t\t})\n\t}\n\n\tget emitter(): EmitterInterface<VariableManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tset collection(value: Readonly<Record<string, number>>) {\n\t\tthis.#ensureAlive()\n\t\tthis.#variables = value\n\t}\n\n\tvariable(name: string): number | undefined {\n\t\tthis.#ensureAlive()\n\t\treturn this.#variables[name]\n\t}\n\n\tvariables(): Readonly<Record<string, number>> {\n\t\tthis.#ensureAlive()\n\t\treturn this.#variables\n\t}\n\n\tadd(name: string, value: number): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#variables = { ...this.#variables, [name]: value }\n\t\tthis.#emitter.emit('add', name)\n\t}\n\n\tremove(name: string): void {\n\t\tthis.#ensureAlive()\n\t\t// Destructure-rest OMITS the key entirely, keeping the record exact.\n\t\tconst { [name]: _drop, ...rest } = this.#variables\n\t\tthis.#variables = rest\n\t\tthis.#emitter.emit('remove', name)\n\t}\n\n\tdestroy(): void {\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.emit('destroy')\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) {\n\t\t\tthrow new ReasonError('DESTROYED', 'VariableManager has been destroyed')\n\t\t}\n\t}\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tDefinition,\n\tDefinitionBuilderEventMap,\n\tDefinitionBuilderInterface,\n\tDefinitionBuilderOptions,\n\tDefinitionEnvelope,\n\tEquationManagerInterface,\n\tFactManagerInterface,\n\tFactorManagerInterface,\n\tGroupManagerInterface,\n\tInferenceManagerInterface,\n\tReasoning,\n\tRuleManagerInterface,\n\tVariableManagerInterface,\n} from '../types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport {\n\tclearInferentialDefinition,\n\tclearLogicalDefinition,\n\tclearQuantitativeDefinition,\n\tclearSymbolicDefinition,\n\tmergeInferentialDefinition,\n\tmergeLogicalDefinition,\n\tmergeQuantitativeDefinition,\n\tmergeSymbolicDefinition,\n} from '../helpers.js'\nimport { DEFINITION_BUILDER_BRAND } from '../constants.js'\nimport { ReasonError } from '../errors.js'\nimport { EquationManager } from './managers/EquationManager.js'\nimport { FactManager } from './managers/FactManager.js'\nimport { FactorManager } from './managers/FactorManager.js'\nimport { GroupManager } from './managers/GroupManager.js'\nimport { InferenceManager } from './managers/InferenceManager.js'\nimport { RuleManager } from './managers/RuleManager.js'\nimport { VariableManager } from './managers/VariableManager.js'\n\n/**\n * A stateful workspace builder accumulating a {@link Definition} through seven\n * always-present self-owning manager properties, shaped like `AgentContext`\n * (AGENTS §4.2.2): a private SCALAR ENVELOPE (reasoning / id / name plus the\n * kind's scalars) composed with each collection read from its manager.\n *\n * @remarks\n * Each manager is BRING-YOUR-OWN (a supplied one is reused) or a fresh one\n * seeded from the seed's matching collection (empty for off-kind collections).\n * Managers are KIND-FREE — an off-kind manager is simply ignored by `build()`,\n * never a `MISMATCH`. `build()` is TOTAL, deterministic, and returns a FRESH\n * plain {@link Definition} each call. `merge(incoming)` requires the SAME\n * `reasoning` (else `MISMATCH`) and distributes incoming scalars into the\n * envelope and collections into the managers via the matching `merge*` helper.\n * `clear(key)` deletes one optional field of the envelope for the instance's\n * `reasoning` (a non-clearable key throws `MISMATCH`). `destroy()` cascades to\n * all seven managers, emits `destroy`, then tears the builder emitter down LAST\n * (AGENTS §13); it is idempotent, and post-destroy mutation / build throws\n * `ReasonError('DESTROYED', …)`.\n */\nexport class DefinitionBuilder implements DefinitionBuilderInterface {\n\treadonly [DEFINITION_BUILDER_BRAND]: true = true\n\treadonly #id: string\n\treadonly #emitter: Emitter<DefinitionBuilderEventMap>\n\treadonly groups: GroupManagerInterface\n\treadonly factors: FactorManagerInterface\n\treadonly rules: RuleManagerInterface\n\treadonly equations: EquationManagerInterface\n\treadonly variables: VariableManagerInterface\n\treadonly facts: FactManagerInterface\n\treadonly inferences: InferenceManagerInterface\n\t#envelope: DefinitionEnvelope\n\t#destroyed = false\n\n\tconstructor(seed: Definition, options?: DefinitionBuilderOptions) {\n\t\tthis.#id = options?.id ?? seed.id\n\t\tconst seeded: Definition = { ...seed, id: this.#id }\n\t\tthis.#envelope = this.#strip(seeded)\n\t\tthis.#emitter = new Emitter<DefinitionBuilderEventMap>({\n\t\t\ton: options?.on,\n\t\t\terror: options?.error,\n\t\t})\n\n\t\tthis.groups =\n\t\t\toptions?.groups ??\n\t\t\tnew GroupManager({ groups: seeded.reasoning === 'quantitative' ? seeded.groups : [] })\n\t\tthis.factors = options?.factors ?? new FactorManager(this.groups)\n\t\tthis.rules =\n\t\t\toptions?.rules ??\n\t\t\tnew RuleManager({ rules: seeded.reasoning === 'logical' ? seeded.rules : [] })\n\t\tthis.equations =\n\t\t\toptions?.equations ??\n\t\t\tnew EquationManager({ equations: seeded.reasoning === 'symbolic' ? seeded.equations : [] })\n\t\tthis.variables =\n\t\t\toptions?.variables ??\n\t\t\tnew VariableManager({ variables: seeded.reasoning === 'symbolic' ? seeded.variables : {} })\n\t\tthis.facts =\n\t\t\toptions?.facts ??\n\t\t\tnew FactManager({ facts: seeded.reasoning === 'inferential' ? seeded.facts : [] })\n\t\tthis.inferences =\n\t\t\toptions?.inferences ??\n\t\t\tnew InferenceManager({\n\t\t\t\tinferences: seeded.reasoning === 'inferential' ? seeded.inferences : [],\n\t\t\t})\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget reasoning(): Reasoning {\n\t\treturn this.#envelope.reasoning\n\t}\n\n\tget emitter(): EmitterInterface<DefinitionBuilderEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tbuild(): Definition {\n\t\tthis.#ensureAlive()\n\t\treturn this.#compose()\n\t}\n\n\tmerge(incoming: Definition): void {\n\t\tthis.#ensureAlive()\n\t\tconst current = this.#compose()\n\t\tif (current.reasoning !== incoming.reasoning) {\n\t\t\tthrow new ReasonError(\n\t\t\t\t'MISMATCH',\n\t\t\t\t`Expected \"${current.reasoning}\" definition, got \"${incoming.reasoning}\"`,\n\t\t\t\t{ definition: this.#id, reasoning: current.reasoning },\n\t\t\t)\n\t\t}\n\t\tlet merged: Definition\n\t\tif (current.reasoning === 'quantitative' && incoming.reasoning === 'quantitative') {\n\t\t\tmerged = mergeQuantitativeDefinition(current, incoming)\n\t\t} else if (current.reasoning === 'logical' && incoming.reasoning === 'logical') {\n\t\t\tmerged = mergeLogicalDefinition(current, incoming)\n\t\t} else if (current.reasoning === 'symbolic' && incoming.reasoning === 'symbolic') {\n\t\t\tmerged = mergeSymbolicDefinition(current, incoming)\n\t\t} else if (current.reasoning === 'inferential' && incoming.reasoning === 'inferential') {\n\t\t\tmerged = mergeInferentialDefinition(current, incoming)\n\t\t} else {\n\t\t\tmerged = current\n\t\t}\n\t\tthis.#seat(merged)\n\t\tthis.#emitter.emit('merge', merged.reasoning)\n\t}\n\n\tclear(key: string): void {\n\t\tthis.#ensureAlive()\n\t\tconst current = this.#compose()\n\t\tlet next: Definition\n\t\tif (current.reasoning === 'quantitative' && this.#isQuantitativeClearKey(key)) {\n\t\t\tnext = clearQuantitativeDefinition(current, key)\n\t\t} else if (current.reasoning === 'logical' && this.#isLogicalClearKey(key)) {\n\t\t\tnext = clearLogicalDefinition(current, key)\n\t\t} else if (current.reasoning === 'symbolic' && this.#isSymbolicClearKey(key)) {\n\t\t\tnext = clearSymbolicDefinition(current, key)\n\t\t} else if (current.reasoning === 'inferential' && this.#isInferentialClearKey(key)) {\n\t\t\tnext = clearInferentialDefinition(current, key)\n\t\t} else {\n\t\t\tthrow new ReasonError(\n\t\t\t\t'MISMATCH',\n\t\t\t\t`\"${key}\" is not a clearable field for reasoning \"${current.reasoning}\"`,\n\t\t\t\t{ key, reasoning: current.reasoning },\n\t\t\t)\n\t\t}\n\t\tthis.#envelope = this.#strip(next)\n\t\tthis.#emitter.emit('clear', key)\n\t}\n\n\tdestroy(): void {\n\t\t// Cascade to every manager first (each idempotent, emitter LAST), then the\n\t\t// builder's own destroy emit, then its emitter LAST — idempotent overall.\n\t\tthis.groups.destroy()\n\t\tthis.factors.destroy()\n\t\tthis.rules.destroy()\n\t\tthis.equations.destroy()\n\t\tthis.variables.destroy()\n\t\tthis.facts.destroy()\n\t\tthis.inferences.destroy()\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.emit('destroy')\n\t\tthis.#emitter.destroy()\n\t}\n\n\t// Compose the current plain definition from the scalar envelope and the\n\t// kind's collections (off-kind managers ignored) — the `build()` body sans\n\t// the alive guard, reused by `merge` / `clear`.\n\t#compose(): Definition {\n\t\tconst envelope = this.#envelope\n\t\tswitch (envelope.reasoning) {\n\t\t\tcase 'quantitative':\n\t\t\t\treturn { ...envelope, groups: this.groups.groups() }\n\t\t\tcase 'logical':\n\t\t\t\treturn { ...envelope, rules: this.rules.rules() }\n\t\t\tcase 'symbolic':\n\t\t\t\treturn {\n\t\t\t\t\t...envelope,\n\t\t\t\t\tequations: this.equations.equations(),\n\t\t\t\t\tvariables: this.variables.variables(),\n\t\t\t\t}\n\t\t\tcase 'inferential':\n\t\t\t\treturn {\n\t\t\t\t\t...envelope,\n\t\t\t\t\tfacts: this.facts.facts(),\n\t\t\t\t\tinferences: this.inferences.inferences(),\n\t\t\t\t}\n\t\t}\n\t}\n\n\t// Distribute a whole definition back into the envelope + managers: the\n\t// scalars strip into the envelope, the kind's collections re-seat wholesale\n\t// through the managers' silent `collection` setters (no per-element events).\n\t#seat(definition: Definition): void {\n\t\tswitch (definition.reasoning) {\n\t\t\tcase 'quantitative':\n\t\t\t\tthis.groups.collection = definition.groups\n\t\t\t\tbreak\n\t\t\tcase 'logical':\n\t\t\t\tthis.rules.collection = definition.rules\n\t\t\t\tbreak\n\t\t\tcase 'symbolic':\n\t\t\t\tthis.equations.collection = definition.equations\n\t\t\t\tthis.variables.collection = definition.variables\n\t\t\t\tbreak\n\t\t\tcase 'inferential':\n\t\t\t\tthis.facts.collection = definition.facts\n\t\t\t\tthis.inferences.collection = definition.inferences\n\t\t\t\tbreak\n\t\t}\n\t\tthis.#envelope = this.#strip(definition)\n\t}\n\n\t// Project a definition to its scalar envelope — the collections drop out\n\t// (rest-sibling omission), leaving reasoning / id / name + the kind's scalars.\n\t#strip(definition: Definition): DefinitionEnvelope {\n\t\tswitch (definition.reasoning) {\n\t\t\tcase 'quantitative': {\n\t\t\t\tconst { groups, ...rest } = definition\n\t\t\t\treturn rest\n\t\t\t}\n\t\t\tcase 'logical': {\n\t\t\t\tconst { rules, ...rest } = definition\n\t\t\t\treturn rest\n\t\t\t}\n\t\t\tcase 'symbolic': {\n\t\t\t\tconst { equations, variables, ...rest } = definition\n\t\t\t\treturn rest\n\t\t\t}\n\t\t\tcase 'inferential': {\n\t\t\t\tconst { facts, inferences, ...rest } = definition\n\t\t\t\treturn rest\n\t\t\t}\n\t\t}\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) {\n\t\t\tthrow new ReasonError('DESTROYED', 'DefinitionBuilder has been destroyed')\n\t\t}\n\t}\n\n\t#isQuantitativeClearKey(key: string): key is 'description' | 'base' | 'bounds' | 'precision' {\n\t\treturn key === 'description' || key === 'base' || key === 'bounds' || key === 'precision'\n\t}\n\n\t#isLogicalClearKey(key: string): key is 'description' | 'depth' {\n\t\treturn key === 'description' || key === 'depth'\n\t}\n\n\t#isSymbolicClearKey(key: string): key is 'description' | 'precision' {\n\t\treturn key === 'description' || key === 'precision'\n\t}\n\n\t#isInferentialClearKey(key: string): key is 'description' | 'depth' {\n\t\treturn key === 'description' || key === 'depth'\n\t}\n}\n","import type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tSubject,\n\tSubjectBuilderEventMap,\n\tSubjectBuilderInterface,\n\tSubjectBuilderOptions,\n} from '../types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { isArray } from '@orkestrel/contract'\nimport { assignField, mergeSubjects, removeField, repeatSubject } from '../helpers.js'\nimport { SUBJECT_BUILDER_BRAND } from '../constants.js'\nimport { ReasonError } from '../errors.js'\n\n/**\n * A stateful workspace builder accumulating a {@link Subject}, taverna\n * `Workspace`-shaped (AGENTS §4.2.2): a single flat collection, no managers —\n * a flat sibling of `Reason.ts`.\n *\n * @remarks\n * `id` is OPTIONAL (`options?.id ?? seed.id`). When present, the builder is\n * id-ful and behaves as before. When absent, the builder is ANONYMOUS —\n * `.id` is `undefined` and the accumulated subject carries no `id` key.\n * `field(key)` / `fields()` are the AGENTS §9.1 accessor pair over TOP-LEVEL\n * keys only. `set(key, value)` delegates to `assignField`; `set('id', …)`\n * throws `ReasonError('MISMATCH', …)` — id is immutable via the entity,\n * id-ful or anonymous alike. `remove` is the AGENTS §9.2 batch overload\n * (array form declared first); removing `'id'` throws the same `MISMATCH`\n * for the same reason. `merge(incoming)` delegates to `mergeSubjects`\n * (incoming-wins, base `id` preserved — plain {@link Subject} data only).\n * `clear()` removes every non-id field, restoring `{ id }` when id-ful or\n * an empty record when anonymous. `repeat(count)` returns `count`\n * deterministic minted-id clones as PLAIN payloads — a pure read that does\n * NOT emit. `build(): Subject` is total, deterministic, and returns a fresh\n * durable payload each call. Post-destroy mutation throws\n * `ReasonError('DESTROYED', …)` — only the `emitter` getter and `destroy`\n * itself keep working, mirroring `Reason`. `destroy()` is idempotent and\n * tears the emitter down LAST (AGENTS §13).\n */\nexport class SubjectBuilder implements SubjectBuilderInterface {\n\treadonly [SUBJECT_BUILDER_BRAND]: true = true\n\treadonly #id: string | undefined\n\treadonly #emitter: Emitter<SubjectBuilderEventMap>\n\t#subject: Subject\n\t#destroyed = false\n\n\tconstructor(seed: Subject, options?: SubjectBuilderOptions) {\n\t\tconst id = options?.id ?? seed.id\n\t\tthis.#id = typeof id === 'string' ? id : undefined\n\t\tif (typeof this.#id === 'string') {\n\t\t\tthis.#subject = { ...seed, id: this.#id }\n\t\t} else {\n\t\t\t// Anonymous: strip any non-string `seed.id` (AGENTS §4.6.1 rest-omit) so\n\t\t\t// the accumulated subject never carries an `id` key.\n\t\t\tconst { id: _id, ...rest } = seed\n\t\t\tthis.#subject = rest\n\t\t}\n\t\tthis.#emitter = new Emitter<SubjectBuilderEventMap>({\n\t\t\ton: options?.on,\n\t\t\terror: options?.error,\n\t\t})\n\t}\n\n\tget id(): string | undefined {\n\t\treturn this.#id\n\t}\n\n\tget emitter(): EmitterInterface<SubjectBuilderEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tfield(key: string): unknown {\n\t\tthis.#ensureAlive()\n\t\treturn this.#subject[key]\n\t}\n\n\tfields(): Subject {\n\t\tthis.#ensureAlive()\n\t\treturn this.#subject\n\t}\n\n\tset(key: string, value: unknown): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#ensureNotId(key)\n\t\tthis.#subject = assignField(this.#subject, key, value)\n\t\tthis.#emitter.emit('set', key, value)\n\t}\n\n\t// Array overload first (AGENTS §9) so a list resolves to the batch form.\n\tremove(keys: readonly string[]): boolean\n\tremove(key: string): boolean\n\tremove(keyOrKeys: readonly string[] | string): boolean {\n\t\tthis.#ensureAlive()\n\t\tif (isArray<string>(keyOrKeys)) {\n\t\t\tlet all = true\n\t\t\tfor (const key of keyOrKeys) {\n\t\t\t\tif (!this.#removeOne(key)) all = false\n\t\t\t}\n\t\t\treturn all\n\t\t}\n\t\treturn this.#removeOne(keyOrKeys)\n\t}\n\n\tmerge(incoming: Subject): void {\n\t\tthis.#ensureAlive()\n\t\tconst merged = mergeSubjects(this.#subject, incoming)\n\t\t// `mergeSubjects` only preserves a BASE id — an anonymous base has none,\n\t\t// so an incoming subject's own `id` key would otherwise survive into the\n\t\t// merged result. Strip it here so an anonymous builder never carries an\n\t\t// `id` key through this path either (AGENTS §4.6.1 rest-omit).\n\t\tif (typeof this.#id !== 'string' && Object.hasOwn(merged, 'id')) {\n\t\t\tconst { id: _id, ...rest } = merged\n\t\t\tthis.#subject = rest\n\t\t} else {\n\t\t\tthis.#subject = merged\n\t\t}\n\t\tthis.#emitter.emit('merge', incoming)\n\t}\n\n\tclear(): void {\n\t\tthis.#ensureAlive()\n\t\tthis.#subject = typeof this.#id === 'string' ? { id: this.#id } : {}\n\t\tthis.#emitter.emit('clear')\n\t}\n\n\trepeat(count: number): readonly Subject[] {\n\t\tthis.#ensureAlive()\n\t\treturn repeatSubject(this.#subject, count)\n\t}\n\n\tbuild(): Subject {\n\t\tthis.#ensureAlive()\n\t\treturn { ...this.#subject }\n\t}\n\n\tdestroy(): void {\n\t\t// Idempotent by construction: a second call re-clears an already-empty\n\t\t// destroyed flag and emits into an already-destroyed emitter (a no-op).\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.emit('destroy')\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) {\n\t\t\tthrow new ReasonError('DESTROYED', 'SubjectBuilder has been destroyed')\n\t\t}\n\t}\n\n\t// `id` is immutable via the entity — writing or removing it through the\n\t// generic key-based verbs would desync `this.#id` from `this.#subject`.\n\t#ensureNotId(key: string): void {\n\t\tif (key === 'id') {\n\t\t\tthrow new ReasonError('MISMATCH', 'SubjectBuilder id is immutable via this method', { key })\n\t\t}\n\t}\n\n\t#removeOne(key: string): boolean {\n\t\tthis.#ensureNotId(key)\n\t\tconst existed = Object.hasOwn(this.#subject, key)\n\t\tthis.#subject = removeField(this.#subject, key)\n\t\tthis.#emitter.emit('remove', key)\n\t\treturn existed\n\t}\n}\n","import type {\n\tAggregatorInterface,\n\tAggregatorOptions,\n\tDefinition,\n\tDefinitionBuilderInterface,\n\tDefinitionBuilderOptions,\n\tEquationManagerInterface,\n\tEquationManagerOptions,\n\tEvaluatorInterface,\n\tEvaluatorOptions,\n\tFactManagerInterface,\n\tFactManagerOptions,\n\tFactorManagerInterface,\n\tFactorManagerOptions,\n\tGroupManagerInterface,\n\tGroupManagerOptions,\n\tInferenceManagerInterface,\n\tInferenceManagerOptions,\n\tInferentialReasonerOptions,\n\tLogicalReasonerOptions,\n\tQuantitativeReasonerOptions,\n\tReasonInterface,\n\tReasonOptions,\n\tReasonerInterface,\n\tRuleManagerInterface,\n\tRuleManagerOptions,\n\tSubject,\n\tSubjectBuilderInterface,\n\tSubjectBuilderOptions,\n\tSymbolicReasonerOptions,\n\tTransformerInterface,\n\tTransformerOptions,\n\tVariableManagerInterface,\n\tVariableManagerOptions,\n} from './types.js'\nimport { Reason } from './Reason.js'\nimport { Evaluator } from './operators/Evaluator.js'\nimport { Transformer } from './operators/Transformer.js'\nimport { Aggregator } from './operators/Aggregator.js'\nimport { QuantitativeReasoner } from './reasoners/QuantitativeReasoner.js'\nimport { LogicalReasoner } from './reasoners/LogicalReasoner.js'\nimport { SymbolicReasoner } from './reasoners/SymbolicReasoner.js'\nimport { InferentialReasoner } from './reasoners/InferentialReasoner.js'\nimport { DefinitionBuilder } from './builders/DefinitionBuilder.js'\nimport { SubjectBuilder } from './builders/SubjectBuilder.js'\nimport { GroupManager } from './builders/managers/GroupManager.js'\nimport { FactorManager } from './builders/managers/FactorManager.js'\nimport { RuleManager } from './builders/managers/RuleManager.js'\nimport { EquationManager } from './builders/managers/EquationManager.js'\nimport { VariableManager } from './builders/managers/VariableManager.js'\nimport { FactManager } from './builders/managers/FactManager.js'\nimport { InferenceManager } from './builders/managers/InferenceManager.js'\n\n/**\n * Create a check evaluator.\n *\n * @remarks\n * `id` — the evaluator's identity string (defaults to `'evaluator'`).\n *\n * @param options - Optional `id`\n * @returns A stateless {@link EvaluatorInterface}\n *\n * @example\n * ```ts\n * import { createEvaluator } from '@src/core'\n *\n * const evaluator = createEvaluator()\n * evaluator.evaluate({ field: 'age', operator: 'above', value: 18 }, { age: 25 })\n * // { field: 'age', met: true, actual: 25 }\n * ```\n */\nexport function createEvaluator(options?: EvaluatorOptions): EvaluatorInterface {\n\treturn new Evaluator(options)\n}\n\n/**\n * Create a math transformer.\n *\n * @remarks\n * `id` — the transformer's identity string (defaults to `'transformer'`).\n *\n * @param options - Optional `id`\n * @returns A stateless {@link TransformerInterface}\n *\n * @example\n * ```ts\n * import { createTransformer, transform } from '@src/core'\n *\n * const transformer = createTransformer()\n * transformer.chain(100, [transform('add', 50), transform('multiply', 2)]) // 300\n * ```\n */\nexport function createTransformer(options?: TransformerOptions): TransformerInterface {\n\treturn new Transformer(options)\n}\n\n/**\n * Create a number aggregator.\n *\n * @remarks\n * `id` — the aggregator's identity string (defaults to `'aggregator'`).\n *\n * @param options - Optional `id`\n * @returns A stateless {@link AggregatorInterface}\n *\n * @example\n * ```ts\n * import { createAggregator } from '@src/core'\n *\n * const aggregator = createAggregator()\n * aggregator.aggregate([10, 20], 'average', [1, 3]) // 17.5 — weighted mean\n * ```\n */\nexport function createAggregator(options?: AggregatorOptions): AggregatorInterface {\n\treturn new Aggregator(options)\n}\n\n/**\n * Create the quantitative reasoner — factor-based numeric scoring.\n *\n * @remarks\n * `id` — the reasoner's identity string (defaults to `'quantitative'`).\n * `evaluator` / `transformer` / `aggregator` — injectable operators, each\n * defaulting to a fresh default-constructed instance.\n *\n * @param options - Optional `id` and operator injections\n * @returns A {@link ReasonerInterface} with reasoning `'quantitative'`\n *\n * @example\n * ```ts\n * import { createQuantitativeReasoner, fieldFactor, factorGroup, quantitativeDefinition } from '@src/core'\n *\n * const reasoner = createQuantitativeReasoner()\n * const definition = quantitativeDefinition('risk', 'Risk', [\n * \tfactorGroup('g1', 'sum', [fieldFactor('age', 'age')]),\n * ], { base: 100 })\n * reasoner.reason({ age: 25 }, definition) // value 125\n * ```\n */\nexport function createQuantitativeReasoner(\n\toptions?: QuantitativeReasonerOptions,\n): ReasonerInterface {\n\treturn new QuantitativeReasoner(options)\n}\n\n/**\n * Create the logical reasoner — rule-based deduction with forward / backward\n * chaining.\n *\n * @remarks\n * `id` — the reasoner's identity string (defaults to `'logical'`). `evaluator`\n * — the injectable check evaluator (defaults to a fresh instance).\n *\n * @param options - Optional `id` and evaluator injection\n * @returns A {@link ReasonerInterface} with reasoning `'logical'`\n *\n * @example\n * ```ts\n * import { atom, createLogicalReasoner, logicalDefinition, rule } from '@src/core'\n *\n * const reasoner = createLogicalReasoner()\n * const definition = logicalDefinition('eligibility', 'Eligibility', [\n * \trule('adult', [atom('age', 'from', 18)], atom('adult', 'equals', true)),\n * ])\n * reasoner.reason({ age: 25 }, definition) // conclusion true\n * ```\n */\nexport function createLogicalReasoner(options?: LogicalReasonerOptions): ReasonerInterface {\n\treturn new LogicalReasoner(options)\n}\n\n/**\n * Create the symbolic reasoner — algebraic equation solving by variable\n * isolation.\n *\n * @remarks\n * `id` — the reasoner's identity string (defaults to `'symbolic'`).\n *\n * @param options - Optional `id`\n * @returns A {@link ReasonerInterface} with reasoning `'symbolic'`\n *\n * @example\n * ```ts\n * import { constant, createSymbolicReasoner, equation, operation, symbolicDefinition, variable } from '@src/core'\n *\n * const reasoner = createSymbolicReasoner()\n * const definition = symbolicDefinition('double', 'Double', [\n * \tequation('e1', variable('y'), operation('multiply', variable('x'), constant(2)), 'y'),\n * ])\n * reasoner.reason({ x: 21 }, definition) // solutions.y === 42\n * ```\n */\nexport function createSymbolicReasoner(options?: SymbolicReasonerOptions): ReasonerInterface {\n\treturn new SymbolicReasoner(options)\n}\n\n/**\n * Create the inferential reasoner — fact derivation with unification variables\n * and proof trees.\n *\n * @remarks\n * `id` — the reasoner's identity string (defaults to `'inferential'`).\n *\n * @param options - Optional `id`\n * @returns A {@link ReasonerInterface} with reasoning `'inferential'`\n *\n * @example\n * ```ts\n * import { createInferentialReasoner, fact, inference, inferentialDefinition } from '@src/core'\n *\n * const reasoner = createInferentialReasoner()\n * const definition = inferentialDefinition('mortality', 'Mortality',\n * \t[fact('f1', 'human', ['socrates'])],\n * \t[inference('mortal', [fact('p1', 'human', ['?x'])], fact('c1', 'mortal', ['?x']))],\n * )\n * reasoner.reason({}, definition) // derives mortal(socrates)\n * ```\n */\nexport function createInferentialReasoner(options?: InferentialReasonerOptions): ReasonerInterface {\n\treturn new InferentialReasoner(options)\n}\n\n/**\n * Create the reasoning orchestrator.\n *\n * @remarks\n * `reasoners` — the initial registry (a later entry of the same reasoning\n * replaces an earlier one; the orchestrator ships with NO defaults). `bail` —\n * `true` (the default) rethrows a reasoner throw after the `error` emit;\n * `false` converts it to a failure result. `validate` — validate every\n * definition before running it, throwing `INVALID` on failure (default\n * `false`). `on` — initial event listeners (AGENTS §8). `error` — the\n * emitter's listener-error handler (AGENTS §13).\n *\n * @param options - Optional registry, policies, and emitter hooks\n * @returns A {@link ReasonInterface}\n *\n * @example\n * ```ts\n * import { createLogicalReasoner, createQuantitativeReasoner, createReason } from '@src/core'\n *\n * const reason = createReason({\n * \treasoners: [createQuantitativeReasoner(), createLogicalReasoner()],\n * \ton: { reason: (result) => console.log(result.success) },\n * })\n * const result = reason.reason({ age: 25 }, definition)\n * reason.destroy()\n * ```\n */\nexport function createReason(options?: ReasonOptions): ReasonInterface {\n\treturn new Reason(options)\n}\n\n/**\n * Create a `DefinitionBuilder` — a stateful workspace builder accumulating a\n * {@link Definition} through seven self-owning manager properties.\n *\n * @remarks\n * `id` defaults to `seed.id`. Each manager slot is BRING-YOUR-OWN (a supplied\n * one is reused, else a fresh one is seeded from the seed's matching\n * collection). `on` — initial event listeners (AGENTS §8). `error` — the\n * emitter's listener-error handler (AGENTS §13). Mutate through the manager\n * properties (`groups` / `factors` / `rules` / `equations` / `variables` /\n * `facts` / `inferences`) and `merge` / `clear`, then call `build()` to produce\n * a fresh, plain {@link Definition} snapshot.\n *\n * @param seed - The starting definition (any of the four reasoning kinds)\n * @param options - Optional `id` override, manager injections, and emitter hooks\n * @returns A {@link DefinitionBuilderInterface}\n *\n * @example\n * ```ts\n * import { createDefinitionBuilder, quantitativeDefinition } from '@src/core'\n *\n * const definition = createDefinitionBuilder(quantitativeDefinition('risk', 'Risk', []))\n * definition.groups.append({ id: 'g1', name: 'g1', aggregation: 'sum', factors: [] })\n * definition.build() // a fresh QuantitativeDefinition with the group applied\n * definition.destroy()\n * ```\n */\nexport function createDefinitionBuilder(\n\tseed: Definition,\n\toptions?: DefinitionBuilderOptions,\n): DefinitionBuilderInterface {\n\treturn new DefinitionBuilder(seed, options)\n}\n\n/**\n * Create a `SubjectBuilder` — a stateful workspace builder accumulating a\n * {@link Subject}.\n *\n * @remarks\n * `id` defaults to `seed.id` and is OPTIONAL — when neither `options.id` nor\n * a string `seed.id` is present the builder is ANONYMOUS (`.id` is\n * `undefined`, `build()` emits no `id` key). `on` — initial event listeners\n * (AGENTS §8). `error` — the emitter's listener-error handler (AGENTS §13).\n * Mutate through `set` / `remove` / `merge` / `clear`, then call `build()` to\n * produce a fresh, plain {@link Subject} snapshot.\n *\n * @param seed - The starting subject\n * @param options - Optional `id` override and emitter hooks\n * @returns A {@link SubjectBuilderInterface}\n *\n * @example\n * ```ts\n * import { createSubjectBuilder } from '@src/core'\n *\n * const subject = createSubjectBuilder({ id: 's1', age: 30 })\n * subject.set('age', 31)\n * subject.build() // { id: 's1', age: 31 }\n * subject.destroy()\n * ```\n */\nexport function createSubjectBuilder(\n\tseed: Subject,\n\toptions?: SubjectBuilderOptions,\n): SubjectBuilderInterface {\n\treturn new SubjectBuilder(seed, options)\n}\n\n/**\n * Create a `GroupManager` — a self-owning manager over a quantitative\n * definition's `groups`.\n *\n * @remarks\n * `groups` — the initial collection (defaults to empty). `on` / `error` —\n * emitter hooks (AGENTS §8 / §13). Kind-free: hand it to a\n * {@link createDefinitionBuilder} `groups` slot regardless of reasoning.\n *\n * @param options - Optional seed collection and emitter hooks\n * @returns A {@link GroupManagerInterface}\n *\n * @example\n * ```ts\n * import { createGroupManager, factorGroup } from '@src/core'\n *\n * const groups = createGroupManager({ groups: [factorGroup('g1', 'sum', [])] })\n * groups.append(factorGroup('g2', 'sum', []))\n * ```\n */\nexport function createGroupManager(options?: GroupManagerOptions): GroupManagerInterface {\n\treturn new GroupManager(options)\n}\n\n/**\n * Create a `FactorManager` — the divergent manager over a group's `factors`,\n * threaded through a required `groupId` locator.\n *\n * @remarks\n * Holds no collection state of its own — it reads and writes factors through\n * the injected sibling {@link GroupManagerInterface}. `on` / `error` — emitter\n * hooks (AGENTS §8 / §13).\n *\n * @param groups - The sibling group manager factors are located within\n * @param options - Optional emitter hooks\n * @returns A {@link FactorManagerInterface}\n *\n * @example\n * ```ts\n * import { createFactorManager, createGroupManager, factorGroup, staticFactor } from '@src/core'\n *\n * const groups = createGroupManager({ groups: [factorGroup('g1', 'sum', [])] })\n * const factors = createFactorManager(groups)\n * factors.append('g1', staticFactor('f1', 10))\n * ```\n */\nexport function createFactorManager(\n\tgroups: GroupManagerInterface,\n\toptions?: FactorManagerOptions,\n): FactorManagerInterface {\n\treturn new FactorManager(groups, options)\n}\n\n/**\n * Create a `RuleManager` — a self-owning manager over a logical definition's\n * `rules`.\n *\n * @remarks\n * `rules` — the initial collection (defaults to empty). `on` / `error` —\n * emitter hooks (AGENTS §8 / §13). Rule order is load-bearing.\n *\n * @param options - Optional seed collection and emitter hooks\n * @returns A {@link RuleManagerInterface}\n *\n * @example\n * ```ts\n * import { atom, createRuleManager, rule } from '@src/core'\n *\n * const rules = createRuleManager()\n * rules.append(rule('adult', [atom('age', 'from', 18)], atom('adult', 'equals', true)))\n * ```\n */\nexport function createRuleManager(options?: RuleManagerOptions): RuleManagerInterface {\n\treturn new RuleManager(options)\n}\n\n/**\n * Create an `EquationManager` — a self-owning manager over a symbolic\n * definition's `equations`.\n *\n * @remarks\n * `equations` — the initial collection (defaults to empty). `on` / `error` —\n * emitter hooks (AGENTS §8 / §13). Equation order is strongly load-bearing.\n *\n * @param options - Optional seed collection and emitter hooks\n * @returns An {@link EquationManagerInterface}\n *\n * @example\n * ```ts\n * import { constant, createEquationManager, equation, variable } from '@src/core'\n *\n * const equations = createEquationManager()\n * equations.append(equation('e1', variable('y'), constant(2), 'y'))\n * ```\n */\nexport function createEquationManager(options?: EquationManagerOptions): EquationManagerInterface {\n\treturn new EquationManager(options)\n}\n\n/**\n * Create a `VariableManager` — a self-owning manager over a symbolic\n * definition's `variables` (a name-keyed record; `add` / `remove` only).\n *\n * @remarks\n * `variables` — the initial record (defaults to empty). `on` / `error` —\n * emitter hooks (AGENTS §8 / §13).\n *\n * @param options - Optional seed record and emitter hooks\n * @returns A {@link VariableManagerInterface}\n *\n * @example\n * ```ts\n * import { createVariableManager } from '@src/core'\n *\n * const variables = createVariableManager({ variables: { x: 1 } })\n * variables.add('y', 2)\n * ```\n */\nexport function createVariableManager(options?: VariableManagerOptions): VariableManagerInterface {\n\treturn new VariableManager(options)\n}\n\n/**\n * Create a `FactManager` — a self-owning manager over an inferential\n * definition's `facts`.\n *\n * @remarks\n * `facts` — the initial collection (defaults to empty). `on` / `error` —\n * emitter hooks (AGENTS §8 / §13).\n *\n * @param options - Optional seed collection and emitter hooks\n * @returns A {@link FactManagerInterface}\n *\n * @example\n * ```ts\n * import { createFactManager, fact } from '@src/core'\n *\n * const facts = createFactManager()\n * facts.append(fact('f1', 'human', ['socrates']))\n * ```\n */\nexport function createFactManager(options?: FactManagerOptions): FactManagerInterface {\n\treturn new FactManager(options)\n}\n\n/**\n * Create an `InferenceManager` — a self-owning manager over an inferential\n * definition's `inferences`.\n *\n * @remarks\n * `inferences` — the initial collection (defaults to empty). `on` / `error` —\n * emitter hooks (AGENTS §8 / §13). Inference order is load-bearing.\n *\n * @param options - Optional seed collection and emitter hooks\n * @returns An {@link InferenceManagerInterface}\n *\n * @example\n * ```ts\n * import { createInferenceManager, fact, inference } from '@src/core'\n *\n * const inferences = createInferenceManager()\n * inferences.append(inference('m', [fact('p', 'human', ['?x'])], fact('c', 'mortal', ['?x'])))\n * ```\n */\nexport function createInferenceManager(\n\toptions?: InferenceManagerOptions,\n): InferenceManagerInterface {\n\treturn new InferenceManager(options)\n}\n"],"mappings":"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"}
|