js-rigor: value-collection crucibles; TTU 0-strength paths, crash, fusion reliability
The new value-collection crucibles in the TTU and chain differential campaigns immediately found three engine defects: - TTU join pushed 0-strength 'matches' (missing computed leg, or 0-possibility edges, with minPossibility 0) as valid paths: denied decisions reported tuple_to_userset_found and leaked the tupleset edge's value into collectedValues. Both join modes now require combined > 0. - A ReferenceError (bare resolveKey) crashed the computed-join mode under collectValues, silently turning the whole check into an evaluation_error denial. Fixed the call to this.arbiter.resolveKey. - Multi-path TTU fusion fell back to Math.max over all path reliabilities, pairing the winning possibility with another intermediate's reliability. The fallback now picks the max-possibility path's reliability. New campaigns: defeasible and intersection differential properties (when/unless and min-children with reliability parity under persistent/ partial splits). The model-based campaign keeps its reliability crucible; its value comparison was reverted — the harness's shrink reporting is opaque and unreconstructable there, and the value semantics are covered by the TTU/chain campaigns instead.
This commit is contained in:
@@ -264,7 +264,11 @@ export class TupleToUsersetRule extends BaseRule {
|
||||
const combinedPossibility = Math.min(resolvePossibility(tupleEdge.possibility), res.possibility);
|
||||
const combinedReliability = resolveReliability(tupleEdge.reliability) * (res.reliability !== undefined ? res.reliability : 1.0);
|
||||
|
||||
if (combinedPossibility >= minPossibility) {
|
||||
// A 0-strength "match" (e.g. the computed leg missing with
|
||||
// minPossibility 0) is not a valid path: it would report
|
||||
// tuple_to_userset_found and leak the tupleset value into the
|
||||
// collected values on a denied decision.
|
||||
if (combinedPossibility > 0 && combinedPossibility >= minPossibility) {
|
||||
const path = {
|
||||
possibility: combinedPossibility,
|
||||
reliability: combinedReliability,
|
||||
@@ -279,7 +283,7 @@ export class TupleToUsersetRule extends BaseRule {
|
||||
computedRelation: { relation: rule.computedRelation, possibility: res.possibility, reliability: res.reliability, meta: res.meta }
|
||||
}
|
||||
}),
|
||||
...(!useLightweightPaths && collectValues && { collectedValue: buildCollectedValue(tupleEdge, resolveKey(tupleEdge.src, options), intermediateKey) })
|
||||
...(!useLightweightPaths && collectValues && { collectedValue: buildCollectedValue(tupleEdge, this.arbiter.resolveKey(tupleEdge.src, options), intermediateKey) })
|
||||
};
|
||||
allValidPaths.push(path);
|
||||
if (!bestPath || combinedPossibility > bestPath.possibility) {
|
||||
@@ -374,7 +378,9 @@ export class TupleToUsersetRule extends BaseRule {
|
||||
const combinedPossibility = Math.min(resolvePossibility(t.possibility), res.possibility);
|
||||
const combinedReliability = resolveReliability(t.reliability) * (res.reliability !== undefined ? res.reliability : 1.0);
|
||||
|
||||
if (combinedPossibility >= minPossibility) {
|
||||
// 0-strength tuples (missing computed leg, or 0-possibility edges)
|
||||
// must not count as found paths (see computed join mode).
|
||||
if (combinedPossibility > 0 && combinedPossibility >= minPossibility) {
|
||||
const pathData = {
|
||||
possibility: combinedPossibility,
|
||||
reliability: combinedReliability,
|
||||
@@ -512,11 +518,15 @@ export class TupleToUsersetRule extends BaseRule {
|
||||
const winningPath = validPathData.find(p => p.meta.intermediateKey === fusionResult.meta.intermediateKey && p.meta.pathType === fusionResult.meta.pathType);
|
||||
if (winningPath) {
|
||||
fusedReliability = winningPath.reliability;
|
||||
} else if (reliabilities.length > 0) {
|
||||
fusedReliability = Math.max(...reliabilities); // Use max reliability for performance
|
||||
}
|
||||
} else if (reliabilities.length > 0) {
|
||||
fusedReliability = Math.max(...reliabilities);
|
||||
}
|
||||
}
|
||||
if (fusedReliability === 1.0 && reliabilities.length > 0) {
|
||||
// Fallback: the fusion aggregator is max, so the winner is the
|
||||
// max-possibility path — its reliability, not the max reliability
|
||||
// (which would pair a possibility from one intermediate with a
|
||||
// reliability from another).
|
||||
const maxIndex = possibilities.indexOf(Math.max(...possibilities));
|
||||
fusedReliability = maxIndex >= 0 ? (reliabilities[maxIndex] ?? 1.0) : 1.0;
|
||||
}
|
||||
|
||||
if (evaluationMeta) {
|
||||
|
||||
Reference in New Issue
Block a user