Commit Graph

5 Commits

Author SHA1 Message Date
John Dvorak dab9671d20 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.
2026-08-01 22:34:00 -07:00
John Dvorak f0dc14fb72 js-rigor: TTU operand values flow; modify honors changed_last_at override
Two issues found by the extended probe sweep:

- A relational_comparator operand backed by a tuple_to_userset rule always
  denied: the TTU rule collected only the intermediate KEY, which the
  operand extraction skips as non-numeric, so no value was ever available.
  The TTU rule now emits a value-carrying collected entry when the
  tupleset edge carries a numeric value (entityKey = tuple src, relation =
  tupleset relation), keeping the bare intermediate key when there is no
  value. Comparator-with-TTU-operand now allows/denies on the tuple value
  through both persistent and partial contexts.

- _modifyRelation ignored the changed_last_at override that the add path
  honors: value-changing modifies stamped fresh Date.now() regardless of
  the pin, so replay/restore tools pinning timestamps got different
  semantics via modify vs add. The override now applies to refresh events
  (value/reliability/possibility change) and is ignored for value-unchanged
  writes, preserving the TTL parity contract that identical replays never
  un-expire old values.

Verified clean: intersection through partial, defeasible with logical
when, challenge subject object/session with sessionKey, non-binary
minAllowPossibility threshold, batch value updates, explain agreement
under partial.
2026-08-01 08:08:36 -07:00
John Dvorak 30fc7e5017 js-rigor: TTU reverse+tuplesetDirection-in now honors direction
The reverse branch of TupleToUsersetRule ignored tuplesetDirection: it
looked up the tupleset relation as outgoing-from-user even when 'in' was
set, while the join honored 'in' by using t.src as the intermediate —
the documented shape (intermediates hold the relation TO the user) never
matched, and only a degenerate join-on-user shape produced results. The
same gap existed in the compiled direct_join optimization.

Fixed the fallback tupleset lookup (including the graph-neighbor path and
the computed-join tupleEdge direction) and the optimized direct_join to
honor tuplesetDirection in reverse mode. Matrix pins reverse-in (both
evaluation paths, persistent + partial), multi_hop reverse, chain-in,
union-with-chain-child, defeasible split legs, TTU value flow, and
challenge-via-binary.
2026-07-31 18:54:57 -07:00
John Dvorak 0149926344 js-rigor: fix TTU computed-join possibility loss and logical cache staleness
Two real bugs found by the new rule-kind x partial-graph parity campaign:

- TupleToUsersetRule 'computed' join mode (computed side has fewer
  intermediates than the tupleset side) pushed path objects carrying
  combinedPossibility, but _buildFinalResult reads path.possibility —
  every valid TTU grant in that mode silently returned 0, in persistent
  and partial contexts alike.

- _collectRelationUsages only registered explicit type:'direct' children,
  so shorthand logical operands ({ relation: 'owner' } inside union/
  intersection/exclusion) left the dependency index empty: writes to a
  base relation never invalidated cached logical decisions, and a check
  performed before an add kept serving its stale result forever.

New campaign rule-kind-partial-parity.test.js pins the full kind x
persistent/partial matrix (direct, chain, multi_hop, TTU out/in/reverse,
parent, computed, defeasible, union, exclusion, comparator, challenge,
binary) plus seeded differential properties for TTU, comparator, and
exclusion; artifact persistence disabled to avoid disk bloat.
2026-07-31 17:09:46 -07:00
John Dvorak 717ae1031e initial commit: @arbiter/core authorization engine with js-rigor hardening
Zanzibar-style authorization graph engine (direct/chain/TTU/defeasible/
binary modes, condensed snapshots, value relations) with 39 rigor test
campaigns. Includes fixes for snapshot binary writer/reader format
mismatch (snapshot-of-snapshot corruption), possibility write-boundary
validation, empty-graph snapshot serialization, relation lookup cache
direction collision, config-redefinition cache invalidation, binary
threshold semantics, defeasible compiled routing, and comparator
reason whitelisting.
2026-07-31 13:44:06 -07:00