Skip to content

Feat: hash result set in org vaultsts is order sensitive risking spurious change notifications on tied sort results - #1490

Merged
1nonlypiece merged 2 commits into
Disciplr-Org:mainfrom
obswrld:feat-hashResultSet-in-orgVaultsts-is-order-sensitive-risking-spurious-change-notifications-on-tied-sort-results
Jul 30, 2026
Merged

Feat: hash result set in org vaultsts is order sensitive risking spurious change notifications on tied sort results#1490
1nonlypiece merged 2 commits into
Disciplr-Org:mainfrom
obswrld:feat-hashResultSet-in-orgVaultsts-is-order-sensitive-risking-spurious-change-notifications-on-tied-sort-results

Conversation

@obswrld

@obswrld obswrld commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

closes #1385

Problem

hashResultSet in src/routes/orgVaults.ts computed a SHA-256 hash over the raw ids array via JSON.stringify(ids) . Since JSON.stringify preserves array element order, the resulting hash was order-sensitive.
When a saved search's sort_by field had duplicate values across rows (e.g., multiple vaults with the same created_at ), two evaluations of an otherwise-unchanged result set could produce different row orderings — even with the id DESC secondary sort. This caused saved-search.evaluate to detect a spurious "new results" notification purely from reordering rather than any real change in vault membership.

Fix
src/routes/orgVaults.ts — Sorted a copy of the IDs array before hashing:
// diff

  • return createHash("sha256").update(JSON.stringify(ids)).digest("hex");
  • return createHash("sha256").update(JSON.stringify([...ids].sort())).digest("hex");
    [...ids] creates a shallow copy to avoid mutating the original array, and .sort() normalizes the element order so the hash reflects set membership only, independent of row order.
    src/tests/orgVaults.savedSearches.test.ts — Updated the order-independence assertion:
    // diff
  • expect(hashResultSet(['a', 'b'])).not.toBe(hashResultSet(['b', 'a']))
  • expect(hashResultSet(['a', 'b'])).toBe(hashResultSet(['b', 'a']))
    Changes

File │ Change │

src/routes/orgVaults.ts:337 │ Sort IDs before hashing │
src/tests/orgVaults.savedSearches.test.ts:136 │ Assert order-independent hash │

Testing

  • ✅ Unit tests for hashResultSet pass (determinism, order-independence, empty input, hex format)
  • ✅ No database required — tests are pure unit tests

obswrld added 2 commits July 30, 2026 12:31
…parison

Sort IDs before computing the SHA-256 hash so the stored hash represents
set membership rather than row ordering. When a saved search's sort_by
field has duplicate values across rows, two evaluations of an otherwise-
unchanged result set can produce different orderings, causing spurious
'new results' notifications purely from reordering rather than any real
change in vault membership.

Sorting the IDs before hashing makes the comparison reflect set-membership
changes only, independent of row order.
@1nonlypiece
1nonlypiece merged commit e36aaba into Disciplr-Org:main Jul 30, 2026
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

hashResultSet in orgVaults.ts is order-sensitive, risking spurious change notifications on tied sort results

2 participants