js-rigor: reliability crucibles across the campaigns; denied-decision leak fixed

The reliability gap found last round was invisible to every parity mirror
(they compared possibility only). Hardened the existing campaigns so the
mirrors carry reliability too:

- batch-order-parity: batch ops carry reliability; the mirror tracks
  last-write-wins reliability and the crucible asserts engine reliability
  parity (mirror corrected: add-on-existing preserves reliability, it does
  not reset it).
- rule-kind-partial-parity: the TTU differential property now generates
  per-edge reliabilities and asserts the winning intermediate's
  reliability (tupleset.reli * computed.reli); a new chain reliability
  differential property does the same for 2-step chains.
- snapshot-quantization-parity: edges carry deterministic reliabilities and
  the round-trip pins the codec's reliability channel (product-aware
  tolerance: chain reliability multiplies two quantized inputs).
- model-based-graph: the reference model tracks reliability per tuple and
  checks it alongside possibility for direct and chain queries.

The model crucible immediately caught a real bug: the direct-check fast
path returned the relation's reliability on a DENIED decision (possibility
0), while the rule-collection path zeroes it — denied results leaked
reliability. Both fast-path branches (direct match and threshold_not_met)
now report reliability 0 when the decision is denied.
This commit is contained in:
John Dvorak
2026-08-01 11:18:20 -07:00
parent 4fd4e20bd0
commit ff6e52111d
5 changed files with 229 additions and 38 deletions
+6 -1
View File
@@ -155,13 +155,18 @@ export class AuthorizationChecker {
if (effectiveThreshold !== null && directRel.possibility < effectiveThreshold) {
result = {
possibility: 0,
reliability: 0,
...(includeMeta && { meta: { reason: 'threshold_not_met', threshold: effectiveThreshold, actual: directRel.possibility } }),
reason: 'threshold_not_met'
};
} else {
result = {
possibility: directRel.possibility,
reliability: directRel.reliability !== undefined ? directRel.reliability : 1.0,
// A denied decision (possibility 0) must not leak the
// relation's reliability — the rule-collection path zeroes it.
reliability: directRel.possibility > 0
? (directRel.reliability !== undefined ? directRel.reliability : 1.0)
: 0,
...(includeMeta && {
meta: {
allow: {