Commit Graph

4 Commits

Author SHA1 Message Date
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 8f863275c2 js-rigor: fix binary mode dropping partial graphs; binary-partial parity campaign
The binary branch of AuthorizationChecker.check rebuilt its options with a
fixed six-field object, silently discarding partialGraphContext (and any
other caller option) — binary checks denied grants the normal path
allowed. Now spreads all caller options through. binary-partial-parity
pins: partial grants above the threshold allow, below deny, persistent
wins over partial, and binary decisions agree with normal decisions on
the same overlay.
2026-07-31 15:31:34 -07:00
John Dvorak 7ffa5045e6 js-rigor: batch cache staleness, tx-batch crash, TTL bypass; value freshness campaigns
Engine fixes:
- RelationUpdates.updateRelationsBatch: invalidate arbiter-level caches
  (rule result cache, ChainRule caches, direct-check cache) per affected
  relation — batch updates bypassed Arbiter.addRelation and served stale
  decisions after batch modify/swap with warm caches
- updateRelationsBatchTransactional rollback: new Map(Set) crashed with
  'Iterator value is not an entry object' — fixed to new Set
- RelationalComparatorRule: value extraction (direct-list and cached
  direct paths) now gates on valueManager._isValueExpired — TTL-expired
  values no longer feed comparator decisions

Campaigns:
- value-freshness-parity.test.js: batch modify/swap/tx rollback freshness
  with comparator mirror (batch MODIFY of a missing relation is a silent
  no-op — pinned)
- ttl-expiry-parity.test.js: injected-clock TTL expiry through the
  comparator path (exact parity with caching off; bounded staleness with
  caching on), faithful changed_last_at mirror semantics
2026-07-31 14:21:22 -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