fix(engine) #5615: keep vectors the graph build leaves unreachable searchable via the delta scan - #5633
Conversation
…archable via the delta scan
|
Tick the box to add this pull request to the merge queue (same as
|
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 0 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
|
Review: fix(engine) #5615 - keep graph-unreachable vectors searchable via the delta scan Reviewed A few points worth considering, none blocking. Correctness / design - looks right
Points to consider
Tests
Overall: solid fix, strong diagnostics, good coverage. My only genuine ask is a quick look at point (1); the rest are notes. |
|
Review: fix(engine) issue 5615 - keep graph-unreachable vectors searchable via the delta scan Overall this is a strong, well-reasoned PR. The root-cause writeup is excellent, the fix sits at the right layer (an ArcadeDB-side safety net that restores the "every committed vector is findable" guarantee without pretending to fix the upstream JVector builder), and the design choices are sound:
A few things worth considering: 1. Exception-driven control flow in the level loop (performance) - findUnreachableOrdinals, ~line 1427. The BFS iterates every level 2. Transient boolean[upper] + int[upper] on every rebuild (performance). Both arrays are allocated on every rebuild including the common zero-orphan case. For a multi-million-vector index rebuilt frequently, that is tens of MB of transient allocation per rebuild. The doc acknowledges this and argues the build dominates, which is fair; just flagging it since GC pressure is a stated project concern. A pooled/reused buffer is a possible future optimization if profiling ever points here. 3. view.entryNode() null-safety (robustness) - line 1418. 4. Reachability model note (minor). The walk unions edges across all levels, whereas beam search descends top-to-0 then beam-searches level 0. Union-reachability is a superset of beam-reachable, so this can never produce a false orphan (safe direction), but in principle a node reachable only via a higher-level in-edge could still be beam-unreachable and go undetected. Given the observed defect is in-degree-0 at all levels this is fine; a one-line comment that this detects graph-unreachable rather than strictly beam-unreachable would set expectations. Tests. Good coverage. The deterministic Nits. The None of these are blockers. Item 1 is the one I would most want addressed before merge, since it runs on every rebuild on the hot path. |
…nd empty-iterator semantics
|
Thanks - addressed 3 of the 4 in 1. Exception-driven control flow - the premise does not hold, so there is no exception storm.
Both the out-of-range level and the unmapped node return the shared Guarding with What was genuinely wrong was my comment, which asserted absence was signalled by an exception and is what pointed you at this. Corrected to state that absence yields an empty iterator and that the 3. 4. Reachability model - documented on the method. The walk unions all levels, which is a superset of beam-reachable, so it can never invent a false orphan; a node reachable only via a higher-level in-edge is not reported, which suits the observed defect (no in-edges at any level). Noted that conservative is the right direction here, since a false orphan costs a duplicate delta entry on every search. 2. Transient arrays - agreed and left as-is; noted in the tracking doc as a future optimization if profiling points here. Nits: the
|
|
Review of PR 5633 - keep unreachable vectors searchable via the delta scan Reviewed the engine change (LSMVectorIndex, ArcadePageVectorValues), both tests, and the surrounding rebuild/delta machinery. This is a high-quality, unusually well-diagnosed PR. The root-cause writeup and the theories-eliminated section are exemplary, and the design choices are sound. What is good
Points worth considering (none blocking)
Verification Followed the reasoning through mergeWithDeltaScan (RID dedup against graph results + loc.deleted recheck), the deltaSnapshotId skip (prevents double-scoring against the trim), and the ordinal-to-finalActiveVectorIds mapping (bounds-guarded). All consistent. The provided/test scope rules and the no-new-dependency rule are not touched. LGTM once the restart-gap limitation is noted somewhere durable. |
…ard a null neighbor iterator
|
Addressed in 1. Restart gap - real, and narrower than "the delta is lost". Verified the exact mechanism: on load, 2. Idle index / inactivity timer - confirmed intended. You are right that the decrement can take 3. Null iterator - guarded. Added an explicit 4. Double
|
|
Review: keep graph-build orphans searchable via the delta scan (issue 5615) Thorough, well-diagnosed fix. The root-cause writeup and the "theories eliminated" section make this reviewable in a way most concurrency bugs never are, and the mechanism (walk-from-entry, re-queue into Correctness - verified good
Points worth surfacing (mostly already documented)
Nits
Tests Overall: solid, safe, and unusually well-documented. My only substantive ask is to make sure the restart gap and the idle-scan cost are visible to users of the guarantee (they are in the doc/comments; consider echoing in the issue/upstream report). Not blocking. |
|
Review: PR #5633 - keep graph-orphaned vectors searchable via the delta scan Reviewed the full diff, the surrounding Correctness - the fix hangs together. Traced the integration and it is internally consistent:
Test coverage - one gap worth noting. The deterministic Performance - transient allocation on every rebuild. Minor notes.
Docs. Overall: sound fix, correctly scoped as an ArcadeDB-layer safety net, thoroughly documented. Main ask is a deterministic test over the re-queue path; the allocation note is a nice-to-have. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5633 +/- ##
============================================
- Coverage 67.20% 66.49% -0.71%
- Complexity 0 1115 +1115
============================================
Files 1771 1771
Lines 149642 149745 +103
Branches 31738 31764 +26
============================================
- Hits 100560 99576 -984
- Misses 35942 37172 +1230
+ Partials 13140 12997 -143 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Filed the searcher-pool race found during this investigation as #5648 - |
|
Review of #5633 - keep graph-build-orphaned vectors searchable via the delta scan I reviewed the change ( What is solid
Things worth keeping on the radar (all acknowledged in the code/PR body; flagging for visibility)
Upstream Agree the root cause is in the JVector Overall: clear root-cause analysis, a fail-safe implementation, and tests that actually pin the behavior. Nice work. Automated review - the PR is already merged; posting for the record. |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 0 |
🟢 Coverage 81.43% diff coverage · -7.51% coverage variation
Metric Results Coverage variation ✅ -7.51% coverage variation Diff coverage ✅ 81.43% diff coverage Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (8a4cf19) 149642 113740 76.01% Head commit (84fde7a) 181737 (+32095) 124491 (+10751) 68.50% (-7.51%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#5633) 70 57 81.43% Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Bumps [undici](https://github.com/nodejs/undici) from 8.5.0 to 8.10.0. Release notes *Sourced from [undici's releases](https://github.com/nodejs/undici/releases).* > v8.10.0 > ------- > > What's Changed > -------------- > > * feat: namespace h2 options by [`@metcoder95`](https://github.com/metcoder95) in [nodejs/undici#5498](https://redirect.github.com/nodejs/undici/pull/5498) > * test: update WPT expectations by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5587](https://redirect.github.com/nodejs/undici/pull/5587) > * test: add cache/dedupe + dns re-dispatch integration tests by [`@GiHoon1123`](https://github.com/GiHoon1123) in [nodejs/undici#5535](https://redirect.github.com/nodejs/undici/pull/5535) > * fix(websocket): support process.unref by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5578](https://redirect.github.com/nodejs/undici/pull/5578) > * fix(h2): ensure every request settles by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5603](https://redirect.github.com/nodejs/undici/pull/5603) > * fix(readable): consume a body whose end has already been emitted by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5617](https://redirect.github.com/nodejs/undici/pull/5617) > * fix(retry): skip the content-length checkpoint for HEAD and for a 206 without content-range by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5610](https://redirect.github.com/nodejs/undici/pull/5610) > * fix: revert idle socket validation to setTimeout(0) to prevent stall on idle event loop by [`@marceli1404`](https://github.com/marceli1404) in [nodejs/undici#5606](https://redirect.github.com/nodejs/undici/pull/5606) > * fix(env-http-proxy-agent): match bare IPv6 addresses in no\_proxy by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5623](https://redirect.github.com/nodejs/undici/pull/5623) > * test: handle aggregate balanced pool errors by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5377](https://redirect.github.com/nodejs/undici/pull/5377) > * fix(readable): keep body bytes that arrive after setEncoding() by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5620](https://redirect.github.com/nodejs/undici/pull/5620) > * fix(socks5): evict unused origin pools by [`@Kkartik14`](https://github.com/Kkartik14) in [nodejs/undici#5595](https://redirect.github.com/nodejs/undici/pull/5595) > * fix: skip deduplication for upgrade requests by [`@Ram-blip`](https://github.com/Ram-blip) in [nodejs/undici#5593](https://redirect.github.com/nodejs/undici/pull/5593) > * fix(retry): forward informational responses by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5625](https://redirect.github.com/nodejs/undici/pull/5625) > * fix(mock): non-string path matchers under ignoreTrailingSlash, and DataView reply bodies by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5619](https://redirect.github.com/nodejs/undici/pull/5619) > * fix(interceptors): cache() and deduplicate() silently inert on Client/Pool without opts.origin by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5628](https://redirect.github.com/nodejs/undici/pull/5628) > * build(deps): bump ossf/scorecard-action from 2.4.3 to 2.4.4 by [`@dependabot`](https://github.com/dependabot)[bot] in [nodejs/undici#5633](https://redirect.github.com/nodejs/undici/pull/5633) > * build(deps): bump github/codeql-action/init from 4.36.2 to 4.37.3 by [`@dependabot`](https://github.com/dependabot)[bot] in [nodejs/undici#5634](https://redirect.github.com/nodejs/undici/pull/5634) > * build(deps): bump actions/setup-node from 6.4.0 to 7.0.0 by [`@dependabot`](https://github.com/dependabot)[bot] in [nodejs/undici#5636](https://redirect.github.com/nodejs/undici/pull/5636) > * fix(mock): emit request body lifecycle hooks by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5367](https://redirect.github.com/nodejs/undici/pull/5367) > * fix(h2): detach upgrade close handler after GOAWAY by [`@pacocartones`](https://github.com/pacocartones) in [nodejs/undici#5641](https://redirect.github.com/nodejs/undici/pull/5641) > * fix: retry refused HTTP/2 streams by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5598](https://redirect.github.com/nodejs/undici/pull/5598) > * fix: preserve DNS origin hostname on sockets by [`@cyphercodes`](https://github.com/cyphercodes) in [nodejs/undici#5577](https://redirect.github.com/nodejs/undici/pull/5577) > > New Contributors > ---------------- > > * [`@marceli1404`](https://github.com/marceli1404) made their first contribution in [nodejs/undici#5606](https://redirect.github.com/nodejs/undici/pull/5606) > * [`@Kkartik14`](https://github.com/Kkartik14) made their first contribution in [nodejs/undici#5595](https://redirect.github.com/nodejs/undici/pull/5595) > * [`@pacocartones`](https://github.com/pacocartones) made their first contribution in [nodejs/undici#5641](https://redirect.github.com/nodejs/undici/pull/5641) > * [`@cyphercodes`](https://github.com/cyphercodes) made their first contribution in [nodejs/undici#5577](https://redirect.github.com/nodejs/undici/pull/5577) > > **Full Changelog**: <nodejs/undici@v8.9.0...v8.10.0> > > v8.9.0 > ------ > >⚠️ Security fixes > ----------------- > > ### High severity > > * [GHSA-4cwx-7wf7-3272](GHSA-4cwx-7wf7-3272): malformed qualified `private` Cache-Control directives could cause cross-user information disclosure in shared caches or a parse-time crash. The cache parser now treats empty qualified directives conservatively and safely handles mixed qualified and unqualified directives. Fixed by [4fe5bc5f](nodejs/undici@4fe5bc5) with regression coverage in [9f09b49a](nodejs/undici@9f09b49). > > ### Medium severity > > * [GHSA-m8rv-5g2x-5cg5](GHSA-m8rv-5g2x-5cg5): a malicious `type` property on a duck-typed blob-like HTTP/1.1 request body could inject CRLF sequences into the generated `content-type` header. Undici now coerces and validates the value before adding it to the request. Fixed by [7d3cf924](nodejs/undici@7d3cf92). > * [GHSA-jr45-8vmc-qm54](GHSA-jr45-8vmc-qm54): optional whitespace around `=` in qualified `no-cache` and `private` directives could bypass shared-cache restrictions and disclose authenticated data across users. Cache-Control parsing now normalizes these forms and applies conservative cache decisions. Fixed by [c601fff1](nodejs/undici@c601fff). > * [GHSA-8xcm-r25x-g524](GHSA-8xcm-r25x-g524): the retry interceptor could expose a stale `Content-Length` after resuming a partial response, potentially causing downstream response desynchronization, hangs, or corruption. Undici now rejects partial responses whose `Content-Length` is inconsistent with `Content-Range`. Fixed by [e11a68ed](nodejs/undici@e11a68e), with corrected fixtures in [2b3f7493](nodejs/undici@2b3f749). > * [GHSA-v3r7-h72x-cjcm](GHSA-v3r7-h72x-cjcm): unsanitized `domain` and `unparsed` values passed to `setCookie()` could inject cookie attributes. Undici now validates cookie domains, paths, and unparsed attributes more strictly. Fixed by [10d93fc3](nodejs/undici@10d93fc). > > Additional hardening > -------------------- ... (truncated) Commits * [`c8d80e6`](nodejs/undici@c8d80e6) Bumped v8.10.0 ([#5644](https://redirect.github.com/nodejs/undici/issues/5644)) * [`66923b4`](nodejs/undici@66923b4) fix: preserve DNS origin hostname on sockets ([#5577](https://redirect.github.com/nodejs/undici/issues/5577)) * [`3926499`](nodejs/undici@3926499) fix: retry refused HTTP/2 streams ([#5598](https://redirect.github.com/nodejs/undici/issues/5598)) * [`73d6e9e`](nodejs/undici@73d6e9e) fix(h2): detach upgrade close handler after GOAWAY ([#5641](https://redirect.github.com/nodejs/undici/issues/5641)) * [`b111adb`](nodejs/undici@b111adb) fix(mock): emit request body lifecycle hooks ([#5367](https://redirect.github.com/nodejs/undici/issues/5367)) * [`ae4a3e3`](nodejs/undici@ae4a3e3) build(deps): bump actions/setup-node from 6.4.0 to 7.0.0 ([#5636](https://redirect.github.com/nodejs/undici/issues/5636)) * [`ec3fbf1`](nodejs/undici@ec3fbf1) build(deps): bump github/codeql-action/init from 4.36.2 to 4.37.3 ([#5634](https://redirect.github.com/nodejs/undici/issues/5634)) * [`2151720`](nodejs/undici@2151720) build(deps): bump ossf/scorecard-action from 2.4.3 to 2.4.4 ([#5633](https://redirect.github.com/nodejs/undici/issues/5633)) * [`b96a116`](nodejs/undici@b96a116) fix(interceptors): allow interceptors without opts.origin ([#5628](https://redirect.github.com/nodejs/undici/issues/5628)) * [`a18ef2d`](nodejs/undici@a18ef2d) fix(mock): non-string path matchers under ignoreTrailingSlash, and DataView r... * Additional commits viewable in [compare view](nodejs/undici@v8.5.0...v8.10.0) [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- Dependabot commands and options You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/ArcadeData/arcadedb/network/alerts).
…p ci] Bumps [undici](https://github.com/nodejs/undici) from 8.5.0 to 8.10.0. Release notes *Sourced from [undici's releases](https://github.com/nodejs/undici/releases).* > v8.10.0 > ------- > > What's Changed > -------------- > > * feat: namespace h2 options by [`@metcoder95`](https://github.com/metcoder95) in [nodejs/undici#5498](https://redirect.github.com/nodejs/undici/pull/5498) > * test: update WPT expectations by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5587](https://redirect.github.com/nodejs/undici/pull/5587) > * test: add cache/dedupe + dns re-dispatch integration tests by [`@GiHoon1123`](https://github.com/GiHoon1123) in [nodejs/undici#5535](https://redirect.github.com/nodejs/undici/pull/5535) > * fix(websocket): support process.unref by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5578](https://redirect.github.com/nodejs/undici/pull/5578) > * fix(h2): ensure every request settles by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5603](https://redirect.github.com/nodejs/undici/pull/5603) > * fix(readable): consume a body whose end has already been emitted by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5617](https://redirect.github.com/nodejs/undici/pull/5617) > * fix(retry): skip the content-length checkpoint for HEAD and for a 206 without content-range by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5610](https://redirect.github.com/nodejs/undici/pull/5610) > * fix: revert idle socket validation to setTimeout(0) to prevent stall on idle event loop by [`@marceli1404`](https://github.com/marceli1404) in [nodejs/undici#5606](https://redirect.github.com/nodejs/undici/pull/5606) > * fix(env-http-proxy-agent): match bare IPv6 addresses in no\_proxy by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5623](https://redirect.github.com/nodejs/undici/pull/5623) > * test: handle aggregate balanced pool errors by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5377](https://redirect.github.com/nodejs/undici/pull/5377) > * fix(readable): keep body bytes that arrive after setEncoding() by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5620](https://redirect.github.com/nodejs/undici/pull/5620) > * fix(socks5): evict unused origin pools by [`@Kkartik14`](https://github.com/Kkartik14) in [nodejs/undici#5595](https://redirect.github.com/nodejs/undici/pull/5595) > * fix: skip deduplication for upgrade requests by [`@Ram-blip`](https://github.com/Ram-blip) in [nodejs/undici#5593](https://redirect.github.com/nodejs/undici/pull/5593) > * fix(retry): forward informational responses by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5625](https://redirect.github.com/nodejs/undici/pull/5625) > * fix(mock): non-string path matchers under ignoreTrailingSlash, and DataView reply bodies by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5619](https://redirect.github.com/nodejs/undici/pull/5619) > * fix(interceptors): cache() and deduplicate() silently inert on Client/Pool without opts.origin by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5628](https://redirect.github.com/nodejs/undici/pull/5628) > * build(deps): bump ossf/scorecard-action from 2.4.3 to 2.4.4 by [`@dependabot`](https://github.com/dependabot)[bot] in [nodejs/undici#5633](https://redirect.github.com/nodejs/undici/pull/5633) > * build(deps): bump github/codeql-action/init from 4.36.2 to 4.37.3 by [`@dependabot`](https://github.com/dependabot)[bot] in [nodejs/undici#5634](https://redirect.github.com/nodejs/undici/pull/5634) > * build(deps): bump actions/setup-node from 6.4.0 to 7.0.0 by [`@dependabot`](https://github.com/dependabot)[bot] in [nodejs/undici#5636](https://redirect.github.com/nodejs/undici/pull/5636) > * fix(mock): emit request body lifecycle hooks by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5367](https://redirect.github.com/nodejs/undici/pull/5367) > * fix(h2): detach upgrade close handler after GOAWAY by [`@pacocartones`](https://github.com/pacocartones) in [nodejs/undici#5641](https://redirect.github.com/nodejs/undici/pull/5641) > * fix: retry refused HTTP/2 streams by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5598](https://redirect.github.com/nodejs/undici/pull/5598) > * fix: preserve DNS origin hostname on sockets by [`@cyphercodes`](https://github.com/cyphercodes) in [nodejs/undici#5577](https://redirect.github.com/nodejs/undici/pull/5577) > > New Contributors > ---------------- > > * [`@marceli1404`](https://github.com/marceli1404) made their first contribution in [nodejs/undici#5606](https://redirect.github.com/nodejs/undici/pull/5606) > * [`@Kkartik14`](https://github.com/Kkartik14) made their first contribution in [nodejs/undici#5595](https://redirect.github.com/nodejs/undici/pull/5595) > * [`@pacocartones`](https://github.com/pacocartones) made their first contribution in [nodejs/undici#5641](https://redirect.github.com/nodejs/undici/pull/5641) > * [`@cyphercodes`](https://github.com/cyphercodes) made their first contribution in [nodejs/undici#5577](https://redirect.github.com/nodejs/undici/pull/5577) > > **Full Changelog**: <nodejs/undici@v8.9.0...v8.10.0> > > v8.9.0 > ------ > >⚠️ Security fixes > ----------------- > > ### High severity > > * [GHSA-4cwx-7wf7-3272](GHSA-4cwx-7wf7-3272): malformed qualified `private` Cache-Control directives could cause cross-user information disclosure in shared caches or a parse-time crash. The cache parser now treats empty qualified directives conservatively and safely handles mixed qualified and unqualified directives. Fixed by [4fe5bc5f](nodejs/undici@4fe5bc5) with regression coverage in [9f09b49a](nodejs/undici@9f09b49). > > ### Medium severity > > * [GHSA-m8rv-5g2x-5cg5](GHSA-m8rv-5g2x-5cg5): a malicious `type` property on a duck-typed blob-like HTTP/1.1 request body could inject CRLF sequences into the generated `content-type` header. Undici now coerces and validates the value before adding it to the request. Fixed by [7d3cf924](nodejs/undici@7d3cf92). > * [GHSA-jr45-8vmc-qm54](GHSA-jr45-8vmc-qm54): optional whitespace around `=` in qualified `no-cache` and `private` directives could bypass shared-cache restrictions and disclose authenticated data across users. Cache-Control parsing now normalizes these forms and applies conservative cache decisions. Fixed by [c601fff1](nodejs/undici@c601fff). > * [GHSA-8xcm-r25x-g524](GHSA-8xcm-r25x-g524): the retry interceptor could expose a stale `Content-Length` after resuming a partial response, potentially causing downstream response desynchronization, hangs, or corruption. Undici now rejects partial responses whose `Content-Length` is inconsistent with `Content-Range`. Fixed by [e11a68ed](nodejs/undici@e11a68e), with corrected fixtures in [2b3f7493](nodejs/undici@2b3f749). > * [GHSA-v3r7-h72x-cjcm](GHSA-v3r7-h72x-cjcm): unsanitized `domain` and `unparsed` values passed to `setCookie()` could inject cookie attributes. Undici now validates cookie domains, paths, and unparsed attributes more strictly. Fixed by [10d93fc3](nodejs/undici@10d93fc). > > Additional hardening > -------------------- ... (truncated) Commits * [`c8d80e6`](nodejs/undici@c8d80e6) Bumped v8.10.0 ([#5644](https://redirect.github.com/nodejs/undici/issues/5644)) * [`66923b4`](nodejs/undici@66923b4) fix: preserve DNS origin hostname on sockets ([#5577](https://redirect.github.com/nodejs/undici/issues/5577)) * [`3926499`](nodejs/undici@3926499) fix: retry refused HTTP/2 streams ([#5598](https://redirect.github.com/nodejs/undici/issues/5598)) * [`73d6e9e`](nodejs/undici@73d6e9e) fix(h2): detach upgrade close handler after GOAWAY ([#5641](https://redirect.github.com/nodejs/undici/issues/5641)) * [`b111adb`](nodejs/undici@b111adb) fix(mock): emit request body lifecycle hooks ([#5367](https://redirect.github.com/nodejs/undici/issues/5367)) * [`ae4a3e3`](nodejs/undici@ae4a3e3) build(deps): bump actions/setup-node from 6.4.0 to 7.0.0 ([#5636](https://redirect.github.com/nodejs/undici/issues/5636)) * [`ec3fbf1`](nodejs/undici@ec3fbf1) build(deps): bump github/codeql-action/init from 4.36.2 to 4.37.3 ([#5634](https://redirect.github.com/nodejs/undici/issues/5634)) * [`2151720`](nodejs/undici@2151720) build(deps): bump ossf/scorecard-action from 2.4.3 to 2.4.4 ([#5633](https://redirect.github.com/nodejs/undici/issues/5633)) * [`b96a116`](nodejs/undici@b96a116) fix(interceptors): allow interceptors without opts.origin ([#5628](https://redirect.github.com/nodejs/undici/issues/5628)) * [`a18ef2d`](nodejs/undici@a18ef2d) fix(mock): non-string path matchers under ignoreTrailingSlash, and DataView r... * Additional commits viewable in [compare view](nodejs/undici@v8.5.0...v8.10.0) [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- Dependabot commands and options You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/ArcadeData/arcadedb/network/alerts).
Closes #5615
Root cause
A graph rebuild occasionally emits an orphan node: present in the graph and carrying a full set of outgoing edges, but with zero incoming edges. Beam search starts at the entry node and only ever follows edges forward, so an orphan can never be visited - at any
efSearch, however good its score. The vector, the location index, the ordinal map and the scoring path are all correct, which is why the symptom looked like a delta-retention or publication race for so long and why nine earlier theories all failed.Instrumenting the reproducer to walk the graph at the moment of a miss:
The missing vector is the globally best-scoring node (
betterScoring=0), graph and ordinal map agree on size, and a BFS from the entry node reaches 1599 of 1600 nodes - every one except this.retryHit=falseandwideEfHit=false(efSearch=2000 against a 1600-node graph) show the miss is stable rather than a transient read-path race.A second probe placed directly after
builder.build(vectors)closed the chain: on a failing run the build reportedORPHANS count=3 sample=252(deg=32) 257(deg=32) 258(deg=32)and the search then missed ordinal 258, one of those three. Passing runs reported zero orphan builds.GraphIndexBuilder.build()does callcleanup()(verified in the 4.0.0-rc.7 bytecode:submit(addNodes) -> join -> cleanup), and cleanup has connectivity machinery. It nonetheless leaves these nodes unreferenced under concurrent rebuild pressure.The change
findUnreachableOrdinalswalks every edge from the graph entry node after a build and returns the ordinals nothing reaches.buildGraphFromScratchExclusivelyre-queues those vectors into the delta buffer, wheremergeWithDeltaScan- an exhaustive linear scan - keeps them searchable until the next rebuild wires them into the graph.deltaSnapshotIdare skipped: the existing trim already carries them over, and re-adding them would score the same vector twice in the delta scan.This is a safety net at the ArcadeDB layer that restores the "every committed vector is findable" guarantee. It does not address why the builder produces the orphan, which is worth reporting upstream.
Test plan
LSMVectorIndexGraphConnectivityTest- 5 deterministic cases against graphs whose shape is fixed by the test: a connected chain, a node with out-edges and no in-edges, several orphans at once, a disconnected cycle, and an empty graph. StubbingfindUnreachableOrdinalsto a no-op fails 3 of the 5, confirming they bind.LSMVectorIndexConcurrentRebuildVisibilityTest- the end-to-end reproducer, which on a miss now reports whether the vector is reachable from the entry node at all.mvn -pl engine test -Dtest='com.arcadedb.index.vector.*Test'- 245 tests, 0 failures, 0 errors.Note the concurrency reproducer is inherently probabilistic: its flake rate on unfixed code swung between 1 run in 1 and 1 run in 10, so a single clean run of it proves little on its own. The deterministic test is what pins the fix.