Commit graph

1560 commits

Author SHA1 Message Date
Gergő Magyar
c7701613ec
Merge branch 'main' into dependabot/npm_and_yarn/gitnexus/ladybugdb/core-0.18.2 2026-07-21 09:52:37 +01:00
Gergő Magyar
786e0d7841
Merge pull request #2597 from magyargergo/fix/2564-record-newexpr-callgraph
fix(java): record container node + new-expression chained call receiver typing (#2564)
2026-07-21 09:51:16 +01:00
Gergő Magyar
522d1ee62a
Merge branch 'main' into fix/2564-record-newexpr-callgraph 2026-07-21 09:29:45 +01:00
Gergő Magyar
8791e95ccc
Merge pull request #2598 from magyargergo/repro/issue-2589
fix(analyze): drop FTS indexes before the incremental DETACH DELETE
2026-07-21 09:29:34 +01:00
Gergo Magyar
dac2b770a0 fix(test): address gitnexus-review-agent findings on PR #2598
- Anchor isBenignDropFtsIndexError to the START of the message
  (startsWith, not includes) so a future genuine failure that merely
  mentions "Binder exception" or "Catalog exception" mid-message can't
  be misclassified as benign. New test proves the old substring match
  would have swallowed such a message.
- incremental-fts-drop-ordering.test.ts: probe FTS availability once in
  beforeAll and skip VISIBLY via ctx.skip() in beforeEach (matching the
  withTestLbugDB/lbug-vector-extension convention) instead of a silent
  console.warn+return inside the test body, which reported a false pass
  with zero coverage of the ordering invariant when FTS was unavailable.
  The post-first-run FTS-index-built check is now a hard assertion
  instead of a second soft skip, since the beforeEach gate already
  proved the extension loads.
2026-07-21 07:57:28 +00:00
Gergő Magyar
10545a52f0
Merge branch 'main' into dependabot/npm_and_yarn/gitnexus/ladybugdb/core-0.18.2 2026-07-21 08:40:14 +01:00
Gergo Magyar
993abbb7ea Merge branch 'main' auto-update (GitHub PR sync) into repro/issue-2589 2026-07-21 07:25:53 +00:00
Gergo Magyar
f460157470 style(test): fix prettier formatting in incremental-fts-drop-ordering.test.ts
CI's prettier --check flagged one over-long line; no behavior change.
2026-07-21 07:25:15 +00:00
Gergo Magyar
5099e8ff1e test(bench): rebaseline java scope-capture fingerprint for record support (#2564)
CI caught this: adding the record_declaration capture legitimately
changes the pinned java capture fingerprint, same as every prior
capture-behavior change to this language (#2550, #2555). Rebaselined
following the established _rebaselined_* precedent; scaling ratio
1.059 stays well within the 1.5 budget.
2026-07-21 07:18:38 +00:00
Gergő Magyar
bbd1c4cd47
Merge branch 'main' into repro/issue-2589 2026-07-21 08:12:59 +01:00
Gergő Magyar
1864309872
Merge branch 'main' into fix/2564-record-newexpr-callgraph 2026-07-21 08:06:15 +01:00
dependabot[bot]
b028cc0212
chore(deps)(deps): bump body-parser from 2.2.2 to 2.3.0 in /gitnexus (#2594)
Bumps [body-parser](https://github.com/expressjs/body-parser) from 2.2.2 to 2.3.0.
- [Release notes](https://github.com/expressjs/body-parser/releases)
- [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/body-parser/compare/v2.2.2...v2.3.0)

---
updated-dependencies:
- dependency-name: body-parser
  dependency-version: 2.3.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 08:05:49 +01:00
dependabot[bot]
cdd0ce9b8e
chore(deps)(deps): bump brace-expansion from 5.0.6 to 5.0.7 in /gitnexus (#2593)
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) from 5.0.6 to 5.0.7.
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v5.0.6...v5.0.7)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 5.0.7
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 08:05:33 +01:00
Gergő Magyar
2601506be3
Merge pull request #2592 from abhigyanpatwari/dependabot/npm_and_yarn/gitnexus/tar-7.5.20
chore(deps)(deps): bump tar from 7.5.16 to 7.5.20 in /gitnexus
2026-07-21 08:05:09 +01:00
Gergo Magyar
d7a4f47580 fix(analyze): drop FTS indexes before the incremental DETACH DELETE
Fixes #2589: incremental analyze intermittently crashed with "FTS
index 'file_fts' is inconsistent: term is missing during delete" after
markdown-only commits, and --repair-fts also failed in that state.

deleteNodesForFiles' batched DETACH DELETE ran against tables that
still carried the FTS index built at the end of the PREVIOUS analyze
run -- createSearchFTSIndexes only drops+rebuilds every index in Phase
3, well after that delete already ran. LadybugDB's FTS extension is
not proven to survive DML against an indexed table (its own docs never
demonstrate the sequence). Call the new dropSearchFTSIndexes() up front
in the non-escalated incremental branch, before deleteNodesForFiles --
Phase 3 still rebuilds every index from the final row set regardless.

New end-to-end test drives a real runFullAnalysis full+incremental
cycle and confirms it fails without this change (file_fts and 50
sibling indexes still present at delete time) and passes with it.
2026-07-21 07:04:50 +00:00
Gergo Magyar
c548652eca fix(lbug): stop dropFTSIndex from swallowing genuine engine failures
dropFTSIndex previously caught and discarded every DROP_FTS_INDEX error
unconditionally. Extract isBenignDropFtsIndexError, a pure classifier
for the two legitimate "nothing to drop" cases (Binder/Catalog
exceptions: index never created, or the FTS function isn't registered)
verified end-to-end against @ladybugdb/core 0.18.x's real conn.query()
error text. Anything else -- e.g. the Runtime exception "FTS index is
inconsistent" class from #2589 -- now rethrows instead of being masked,
so a corrupted index can no longer persist across analyze runs
undetected.
2026-07-21 07:04:50 +00:00
Gergo Magyar
1fd1f14cee refactor(search): extract dropSearchFTSIndexes from createSearchFTSIndexes
Pulls the existing per-index dropFTSIndex loop out into its own exported
function so the incremental writeback can drop FTS indexes up front,
before deleteNodesForFiles runs (#2589). No behavior change here —
createSearchFTSIndexes calls the new function and still rebuilds every
index afterward.
2026-07-21 07:04:49 +00:00
Gergo Magyar
1595a90a13 fix(storage): bump INCREMENTAL_SCHEMA_VERSION for the Java record fix (#2564)
Review finding: the record_declaration container-node fix (894110bf)
makes previously-uncaptured Record nodes and HAS_METHOD edges appear
for the first time, but the incremental write set only covers changed
files. Without this bump, an existing index would silently keep
omitting the Record node and its HAS_METHOD edges for unchanged
record files after an ordinary incremental analyze.

Same contract as v7 (#2437/#2522) and the two closest precedents, v8
(#2550) and v9 (#2555), which bumped this constant for the identical
"model X as first-class node" class of change.
2026-07-21 07:04:08 +00:00
Gergo Magyar
0b933aa43f fix(java): treat a new-expression as a typed receiver for its chained call (#2564)
new Local().inner() bound the whole object_creation_expression as
@reference.receiver, so its raw source text ("new Local()") became the
receiver name. That text can never match a scope binding, so the call
silently fell through to name-only fallback resolution and could
resolve to an unrelated same-named method on a collision.

Normalize the receiver to the constructed type's simple name (reusing
javaBaseSimpleNameOf, already used for the anonymous-class inheritance
edge) so Case 2 (class-name / static receiver) in
receiver-bound-calls.ts resolves it via its normal MRO walk. Mirrors
the existing normalizePhpReceiver precedent in php/captures.ts - a
language-local capture rewrite, no shared-pipeline change.
2026-07-21 07:04:07 +00:00
Gergo Magyar
1e190e6fdd fix(java): emit a graph node for record_declaration (#2564)
JAVA_QUERIES had no @definition.record capture, unlike its
class_declaration/interface_declaration/enum_declaration siblings and
unlike CSHARP_QUERIES' own record_declaration pattern. A Java record's
container node was never created, so its HAS_METHOD edges were dropped
at persistence even though ownership resolution computed a valid
ownerId for its methods.

Downstream label mapping, the class-extractor config, the dispatch
table, and ownership reconciliation already treated 'Record' correctly
- this was purely a missing structure-phase capture.
2026-07-21 07:04:07 +00:00
Gergo Magyar
a638867400 Merge branch 'dependabot/npm_and_yarn/gitnexus/ladybugdb/core-0.18.2' of origin into local 2026-07-21 06:16:48 +00:00
Gergo Magyar
30ec68fa7a fix(test): harden findInstalledFtsExtension for cross-OS filesystem quirks
Wrap the version-directory scan in try/catch so a transient FS error
(permission denial, an AV file lock on Windows, a directory vanishing
mid-scan) fails closed to null instead of throwing — matching the
original callers' contract, and safer across the Windows/macOS/Linux
CI matrix where these error modes differ.

Also drop the redundant USERPROFILE/HOME manual chain in
extension-binary-real.test.ts in favor of the repo's established
os.homedir() convention (already used ~15 other places here), which
Node resolves correctly per-OS and already honors env overrides.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-21 06:14:58 +00:00
dependabot[bot]
7c22975048
chore(deps)(deps): bump tar from 7.5.16 to 7.5.20 in /gitnexus
Bumps [tar](https://github.com/isaacs/node-tar) from 7.5.16 to 7.5.20.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.16...v7.5.20)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.20
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-21 06:13:22 +00:00
Gergő Magyar
cdeb9b59a5
Merge branch 'main' into dependabot/npm_and_yarn/gitnexus/ladybugdb/core-0.18.2 2026-07-21 07:10:13 +01:00
Gergő Magyar
281664eb0a
Revert "chore(deps)(deps): bump js-yaml from 4.3.0 to 5.0.0 in /gitnexus (#2586)" (#2596)
This reverts commit 3f93bf22d6.
2026-07-21 07:08:37 +01:00
Gergo Magyar
b751418985 fix(test): discover the installed FTS extension version dir instead of assuming it equals lbug.VERSION
resolveInstalledFtsExtension (extension-binary-real.test.ts) and
resolveSeedExtension (fts-extension-e2e.test.ts) both hardcoded the
on-disk FTS extension path as .lbdb/extension/<lbug.VERSION>/..., but
LadybugDB's native INSTALL/LOAD resolves its own extension-ABI version
directory, which does not always track the npm package version. Bumping
@ladybugdb/core from 0.18.1 to 0.18.2 in this PR still installs into a
0.18.1 directory, so both hardcoded lookups came up empty and failed
hard under GITNEXUS_REQUIRE_FTS=1 in CI (all platforms, shard 3).

Add findInstalledFtsExtension() to discover the real installed file by
scanning every version subdirectory, and use it from both test files.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-21 06:06:42 +00:00
dependabot[bot]
2dabdd391e
chore(deps)(deps-dev): bump tar (#2591)
Bumps the npm_and_yarn group with 1 update in the /gitnexus-web directory: [tar](https://github.com/isaacs/node-tar).


Updates `tar` from 7.5.16 to 7.5.20
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.16...v7.5.20)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.20
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 06:44:37 +01:00
ChunxueLi
84b4402cd1
fix: remove hardcoded 300-flows cap for large repositories (#2198)
* fix: remove hardcoded 300-flows cap for large repositories

The dynamicMaxProcesses was capped at 300 via Math.min(300, ...),
causing large repositories (280K+ nodes) to lose execution flows.

Change: Remove the Math.min(300, ...) cap, keep dynamic calculation.
Effect: 280K-node repo: 300 → 1617 flows.

* test: add regression for dynamic maxProcesses sizing (#2198)

Verify that processProcesses honours maxProcesses > 300 without truncation.
Addresses the optional follow-up suggested by @koriyoshi2041.

* test: exercise computeDynamicMaxProcesses at the phase layer (#2198)

Extract  from the inline
expression in  so the regression test can exercise the
function that actually contained the removed  cap.

The previous test called  directly with
, which passes regardless of whether the phase-level
cap is present —  never had the cap.

The new test suite covers:
  - floor (20) for tiny repos
  - linear scaling in the 0–3000 range
  - growth past 300 for large repos (the actual regression)
  - explicit assertion that reintroducing Math.min(300, …) would fail

Addresses review feedback from @azizur100389.

---------

Co-authored-by: Ubuntu <ubuntu@localhost.localdomain>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
2026-07-21 05:48:55 +01:00
ChamHerry
7534f53c27
feat(embeddings): control request-body dimensions via GITNEXUS_EMBEDDING_REQUEST_DIMS (#2574)
* feat(embeddings): support GITNEXUS_EMBEDDING_REQUEST_DIMS=omit

What: Honor GITNEXUS_EMBEDDING_REQUEST_DIMS=omit by suppressing the request-body
`dimensions` field sent to HTTP embedding backends.

Why: Strict OpenAI-compatible backends return vectors in the model's native size
but reject an unfamiliar `dimensions` field, breaking `analyze --embeddings`
against them. The var was parsed but never propagated, so `omit` was a no-op.

How: Add `requestDimensions` to HttpConfig, return it from readConfig, and forward
`config.requestDimensions` (not the validation-only `config.dimensions`) to
`httpEmbedBatch`. Local dimension checks still use `config.dimensions`.

Details: Coexists with the retry/pacing fields introduced upstream; both feature
sets are preserved. Default behavior unchanged when REQUEST_DIMS is unset.

Impact: gitnexus/src/core/embeddings/http-client.ts; README; unit tests.

* fix(embeddings): name GITNEXUS_EMBEDDING_REQUEST_DIMS in its own config error

Address the review findings on #2574.

What:
- A malformed GITNEXUS_EMBEDDING_REQUEST_DIMS now throws an error naming
  GITNEXUS_EMBEDDING_REQUEST_DIMS, not the sibling GITNEXUS_EMBEDDING_DIMS.
- isHttpEmbeddingDimsError recognizes both leads, so the CLI still classifies
  the REQUEST_DIMS config mistake as a clean config error, not a stack dump.
- Tests: numeric-override decoupling (DIMS=1024 validates the response while
  REQUEST_DIMS=512 is sent in the body), the omit aliases (none/off/false/0),
  and the malformed-value error path (which also pins the naming fix).
- README documents the full accepted values: omit-aliases and integer override.

Why: readConfig reused the DIMS error lead for the REQUEST_DIMS branch, so
REQUEST_DIMS=garbage misdirected the operator to edit the wrong variable. The
feature's actual decoupling and its non-omit inputs had no test coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: wangxc <wangxc_a_bj@si-tech.com.cn>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 05:46:20 +01:00
Gergő Magyar
2c4e0af64a
Merge branch 'main' into dependabot/npm_and_yarn/gitnexus/ladybugdb/core-0.18.2 2026-07-21 05:45:04 +01:00
dependabot[bot]
5935921079
chore(deps)(deps-dev): bump @types/node in /gitnexus (#2588)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.9.5 to 26.0.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 26.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 05:44:37 +01:00
dependabot[bot]
3f93bf22d6
chore(deps)(deps): bump js-yaml from 4.3.0 to 5.0.0 in /gitnexus (#2586)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.3.0 to 5.0.0.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.3.0...5.0.0)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-21 05:44:25 +01:00
Gergő Magyar
52b06b2642
fix(eval): stop using --bare for arms that need Skill or MCP tools (#2584)
Some checks failed
CodeQL / Analyze (python) (push) Waiting to run
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
Gitleaks / gitleaks (push) Waiting to run
Publish / Classify release event (push) Waiting to run
Publish / RC guard (marker + release-PR skip) (push) Blocked by required conditions
Publish / ci (push) Blocked by required conditions
Publish / Publish to npm (push) Blocked by required conditions
Publish / Build & Push RC Docker images (push) Blocked by required conditions
Scorecard / Scorecard analysis (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-cli) (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-web) (push) Waiting to run
Skill copy sync / shipped skills drift guard (push) Has been cancelled
--bare hard-disables the Skill tool and every mcp__* tool by Claude
Code design (confirmed against the pinned 2.1.214 binary; --allowedTools
cannot restore what --bare removes). Every workflow_bench arm except
baseline_nomcp needs Skill and/or GitNexus MCP tools, so every one of
those sessions has been silently unable to invoke gitnexus-plan/work/
review or the CE comparator skills -- the last skill-evolution run
(gen 0) scored 0/3 resolution on both arms across every task with
error_kind "skill-not-invoked", not because the candidate was bad but
because the harness could never invoke either arm's skill at all.

Only baseline_nomcp keeps --bare (it explicitly wants zero Skill/MCP
access anyway). The rest drop --bare and rely on ANTHROPIC_API_KEY
alone; the sandboxed HOME has no OAuth/keychain state to conflict
with it, and there's no committed .claude/settings.json in this repo
for dropping --bare to newly pick up.

Outside --bare the built-in toolset defaults to everything (WebFetch,
Task, subagents, ...), and --allowedTools only pre-approves within
whatever's available -- it doesn't narrow it. Added --tools for
non-bare sessions so the intended tool scope is still enforced instead
of silently widening.


Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 21:26:11 +01:00
dependabot[bot]
9c87030edf
chore(deps)(deps): bump @ladybugdb/core in /gitnexus
Bumps [@ladybugdb/core](https://github.com/LadybugDB/ladybug) from 0.18.1 to 0.18.2.
- [Release notes](https://github.com/LadybugDB/ladybug/releases)
- [Commits](https://github.com/LadybugDB/ladybug/compare/v0.18.1...v0.18.2)

---
updated-dependencies:
- dependency-name: "@ladybugdb/core"
  dependency-version: 0.18.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-20 20:15:31 +00:00
Gergő Magyar
8fd1f8a8d8
test(skills-e2e): give the Idempotency setup hook the 120s budget its siblings use (#2583)
The Idempotency beforeAll runs runSkillsCli (analyze --skills) twice, each
capped at 45s, under a 90s hook budget — exactly 2x the per-call timeout,
with no headroom for fixture creation and git init. On slow Windows CI
runners the two analyzes plus setup exceed 90s and the hook times out
('Hook timed out in 90000ms'), failing the shard before the test's own
status===null timeout tolerance can apply. Every other describe hook in
this file already uses 120s; align this one.

Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 19:54:54 +01:00
Gergő Magyar
ecf6a94a1e
Merge pull request #2582 from magyargergo/fix/buffer-pool-adaptive-sizing
perf(lbug): size the buffer pool to the repo (adaptive, COPY-safe)
2026-07-20 17:58:08 +01:00
Gergő Magyar
3dfe113179
Merge branch 'main' into fix/buffer-pool-adaptive-sizing 2026-07-20 17:29:56 +01:00
Claude
05dadb7950 fix(lbug): raise the adaptive pool floor to a COPY-safe 256 MiB
The 64 MiB floor was too small: LadybugDB's bulk COPY needs working
buffer-pool memory that scales with the repo, so a 64 MiB pool fails with
"buffer pool is full and no memory could be freed" on any non-trivial
repo (empirically: the 6-file skills-e2e idempotency fixture needs
>=128 MiB; the ~1800-file GitNexus checkout needs >=256 MiB). Introduce a
distinct ADAPTIVE_POOL_FLOOR (256 MiB) for the hint clamp, kept separate
from BUFFER_POOL_FLOOR (64 MiB), which still guards defaultBufferPoolSize
on tiny-RAM machines; the hint is still clamped up to the machine default
so it can never over-commit.

This keeps the change as what it actually is — a large-repo optimization:
GitNexus full analyze is 51s (2 GiB) -> 35s (adaptive ~414 MiB). Small
repos now open COPY-safely at 256 MiB instead of the 2 GiB default (same
wall time on Linux, where commit is lazy; the eager commit is far cheaper
than 2 GiB on Windows). The reframed comments drop the earlier
unrepresentative "3-file repo / 64 MiB fast" claim.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 16:29:17 +00:00
Claude
7f03a4ed2d docs(lbug): correct the POOL_BYTES_PER_ELEMENT tuning note
The factor is validated by timing a full `analyze --force` of a large
repo, not a build-free bench (the pool is a native eager allocation).
Benchmark (GitNexus self, 101k graph elements): adaptive 414MiB pool =
35.3s vs forced 2GiB = 50.8s vs forced 64MiB = 26.5s — the adaptive pool
is 31% faster than the old 2GiB default even on a large repo (the eager
commit dominates), with no under-sizing thrash. 4KiB/element kept.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 16:29:17 +00:00
Claude
087b44a865 feat(analyze): size the buffer pool to the graph before the DB open
runFullAnalysis now sets the buffer-pool size hint from the built graph's
node+relationship count (after the pipeline, before initLbug), and clears
it at the top of each run so a prior run's size can't leak into a
pre-pipeline open. A small repo opens with the fast 64MiB floor instead of
eagerly committing the full 2GiB pool.

Measured on a 3-file repo (this box): analyze drops 4.78s -> 1.9s for both
fresh and incremental, matching a forced 64MiB pool; the 2GiB path still
reproduces the old 4.78s. This roughly halves the skills-e2e Idempotency
hook (two analyze passes) that was timing out on Windows CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 16:29:17 +00:00
Claude
ad5ff42804 feat(lbug): add adaptive buffer-pool size hint
Adds the sizing lever without changing behavior yet: a module-scoped
buffer-pool size hint plus estimateBufferPool(graphElementCount), read by
resolveBufferManagerSize with precedence env-override > clamp(hint, 64MiB,
default) > default. The hint can only shrink the pool from the default
(clamped to [floor, default]), so the 2GiB/80%-RAM cap and the
GITNEXUS_LBUG_BUFFER_POOL_SIZE escape hatch (incl. 0) are preserved. With
no hint set, resolveBufferManagerSize returns exactly what it did before.

Motivation: LadybugDB eagerly commits the buffer pool at DB open, so the
fixed min(2GiB,80%RAM) pool adds a measured ~2.8s to every analyze even on
a 3-file repo (dominant on Windows). Sizing the pool to the graph lets
small repos use the fast 64MiB floor while large repos keep the cap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 16:29:17 +00:00
Gergő Magyar
8e95b58b49
Merge pull request #2581 from abhigyanpatwari/fix/evolution-sandbox-reflink-fallback-budget
fix(eval): size the buffered-fallback budget for the real graph index
2026-07-20 16:06:53 +01:00
Gergo Magyar
c723d420d5 fix(eval): size the buffered-fallback budget for the real graph index
trusted_gitnexus_runtime_mounts and sanitized_graph both hand the ~290 MiB
graph index through TaskAssetSnapshot.materialize(), which reflinks into
each arm clone or falls back to a buffered copy under a 16 MiB budget.
Neither ext4 (CI runners) nor 9p (this container) support FICLONE, so
every real materialization fell to the buffered path and blew the budget
instantly (CI run 29750271566).

Raises MAX_BUFFERED_FALLBACK_BYTES to 512 MiB - well above the real index
size, still a full 4x below MAX_TASK_ASSET_BYTES so a genuinely oversized
declaration still fails closed.
2026-07-20 14:42:50 +00:00
Gergő Magyar
e3ed82d162
Merge pull request #2580 from abhigyanpatwari/fix/evolution-sandbox-missing-hooks-mount
fix(eval): mount hooks/claude into the benchmark sandbox
2026-07-20 14:28:42 +01:00
Gergo Magyar
cd93b8da23 fix(eval): mount hooks/claude into the benchmark sandbox
resolve-invocation.ts requires hooks/claude/resolve-analyze-cmd.cjs at
module load time, reached whenever the analyze command loads. The
sandbox's curated mount list never exposed hooks/, so every
benchmark-arm session failed with MODULE_NOT_FOUND (CI run 29742191562).

Appends the new mount after the existing six so the function's
hardcoded mounts[0]/[1]/[2]/[5] validation reads stay correct. Extends
the real-bwrap canary to require analyze.js directly, since --version
alone never reaches the lazy import that broke.
2026-07-20 12:53:24 +00:00
Gergő Magyar
497f117075
fix(eval): drop tags from the benchmark's per-arm clone (#2579)
Every benchmark-arm session failed with "sanitized graph snapshot
preparation failed: clone has more than 1024 references; refusing
incomplete sanitization" (confirmed via a real workflow_dispatch run,
29738099937, after the prior activation fixes let the proposer succeed
end-to-end for the first time).

make_worktree() creates each arm's throwaway clone with a plain `git
clone`, which inherits every tag and branch from the source. This repo's
history has grown to 1144 tags (a v1.6.9-rc.N release-candidate series)
out of 1650 total refs, exceeding oracle_assets.MAX_CLONE_REFS=1024 -- a
fail-closed guard in sanitize_clone_for_hidden_oracles() that refuses to
proceed unless it can enumerate and delete every ref before handing a
sanitized snapshot to a benchmark session (so an agent can never discover
oracle answers via a ref the sanitization missed).

`ref` at every call site (evolve.py, runner.py, sanitized_graph.py) is
always a bare SHA or the literal "HEAD", never a branch name, so
`--single-branch --branch <ref>` isn't viable (git clone's --branch
requires a name). Tags are never used by the checkout fallback or by
sanitization's own delete-everything behavior, so dropping them via
--no-tags removes the 1144-ref majority without touching branch-fetch
behavior or the existing ref/origin-ref checkout fallback, and without
weakening MAX_CLONE_REFS itself.

Verified against the real repository (not just the test fixture): cloning
/workspace (1650 refs, 1144 tags) via the fixed make_worktree() now
produces a clone with 237 total refs and 0 tags.


Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 13:25:16 +01:00
Abhigyan Patwari
6b1c4d4540
fix(eval): surface stdout tail on session failure, not just stderr (#2577)
The proposer's second real-run failure (after the ENV_SCRUB permission fix
landed) exited 1 with subtype "success" and an EMPTY stderr_tail -- opaque:
the downloaded CI artifact showed num_turns:1, cost_usd:0, tokens:0,
duration_s:0.1, meaning the session terminated before any real model turn
completed (consistent with an early, pre-flight-style failure), but nothing
in the persisted record said why.

The actual JSON event stream (permission_denials, tool_use/tool_result,
is_error) lives in stdout, which run_managed already captures as
proc.stdout_tail -- it just never made it into the session's error_detail.
Add it there, bounded and truncated the same way stderr_tail already is.
It flows through evolve.py's existing whole-record redaction before being
written to disk / the uploaded artifact, so this closes the diagnostic gap
without a new blind CI dispatch: the next failure of this shape is
readable directly from the artifact.


Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ

Co-authored-by: Gergo Magyar <gergomagyar@icloud.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 12:06:02 +01:00
Abhigyan Patwari
f832239462
fix(eval): pre-approve proposer tools under Claude Code 2.1.214 ENV_SCRUB hardening (#2576)
The first real skill-evolution run got past task binding, then the proposer
session exited 1 with "Permission mode forced to default —
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB is set (allowed_non_write_users hardening)".

On 2.1.214 the permission resolver unconditionally forces permission mode to
"default" whenever CLAUDE_CODE_SUBPROCESS_ENV_SCRUB is set — `--permission-mode
dontAsk`, settings `permissions.defaultMode`, and `autoAllowBashIfSandboxed`
are all ignored for the mode decision. The proposer runs headless `-p --bare`
where Bash is its only writable tool (it writes the candidate overlay); under
forced "default" Bash was no longer auto-approved, so the session blocked.

We cannot set ENV_SCRUB=0 (it scrubs the Anthropic auth token from the
sandboxed proposer's Bash subprocesses). Instead, align with the forced mode:
pre-approve the proposer's exact tool surface via settings `permissions.allow`
(["Read","Grep","Glob","Bash"]) — under "default" a tool runs without a prompt
iff it matches an allow rule — and stop requesting a non-default mode so no
warning fires. ENV_SCRUB and the full sandbox filesystem/network lockdown are
unchanged. The real-binary containment canary is updated to the new invocation
(no --permission-mode) so the CI job is the authoritative empirical gate, and a
fast unit assertion pins the new permissions.allow / absent defaultMode.


Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ

Co-authored-by: Gergo Magyar <gergomagyar@icloud.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 11:25:49 +01:00
Abhigyan Patwari
2ea00a2b22
fix(ci): install root and shared node_modules for the evolution benchmark (#2575)
* fix(ci): install root and shared node_modules for the evolution benchmark

The first real workflow_dispatch of the skill-evolution loop failed at task
binding: capture_task_dependency_binding aborted with

  SandboxError: sandbox_copy path is unavailable: node_modules: No such
  file or directory

The benchmark tasks sandbox-copy node_modules from three locations
(tasks.scenarios.yaml) — the monorepo root, gitnexus-shared, and gitnexus —
mirroring a full dev checkout. The install step only ran `npm ci` in
gitnexus/, so the root and gitnexus-shared node_modules never existed and
the loop died before any agent ran. Install all three (root, then build
gitnexus-shared, then build gitnexus), matching the per-package install in
ci-tests.yml plus the root deps the tasks require.

A new contract test pins all three installs so this fails in CI rather than
on the next real run — the same guard the workflow's other two P1 fixes got.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ

* fix(ci): only add the missing root install; the subpackage steps already exist

The initial fix redundantly rebuilt gitnexus-shared and gitnexus inside the
gitnexus step — but the workflow already builds both in their own dedicated
steps. Only the monorepo root node_modules was missing. Add a single
"Install monorepo root dependencies" step and leave the two subpackage
build steps untouched, so the benchmark's root sandbox_copy resolves without
double-building.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Va5uu9Ar3e45QZ5xFsG4AZ

---------

Co-authored-by: Gergo Magyar <gergomagyar@icloud.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 09:56:54 +01:00
FAll
2cfbc4a259
feat(spring): build bean candidate inventory (#2494)
* feat(java): inventory Spring bean candidates

* fix(java): fail closed on Spring annotation shadowing

* fix(java): resolve Spring beans after imports

* fix(java): remove stale bean extraction path

* style: satisfy locked Prettier version

* fix(spring): address PR review findings

* feat(spring): share bean inventory across Java and Kotlin

* fix(spring): gate bean inventory analysis completeness

* fix(kotlin): avoid reloading cached scope source

* chore(autofix): apply prettier + eslint fixes via /autofix command

---------

Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-20 09:28:23 +01:00