Commit graph

943 commits

Author SHA1 Message Date
Gergo Magyar
36141609a1 fix(scope): fail closed on namespace factory returns the lookup cannot prove
Review follow-up for the namespace factory return lookup (#3498). Each case
below either resolved to the wrong class or crashed; each now types the
receiver correctly or records a receiver-unresolved drop.

- Disk mode: the namespace-name set walked `scopeTree.byId`, which throws
  after the out-of-core seal, so an inline-only `rp.make().m()` partition
  aborted analyze under GITNEXUS_DISK_SCOPE_INDEX=1. It is now built from the
  finalized `scopes.imports` edges, resolved namespace edges only. This also
  removes the run-to-run edge/drop drift the lazy build caused.
- Hoisted method returns: TS and Dart hoist a method's return annotation to
  the module under the method name, and Go binds receiver methods at package
  scope, so `m.create()` could take `WidgetFactory.create(): Widget`. The
  return binding must now start where a module-local `Function` of that name
  is declared.
- `import pkg.sub` binds `pkg` but targets `pkg/sub.py`; such an edge only
  counts when its target file is the module the local name binds.
- A dotted return (`-> models.Order`) is not followed further: the next step
  would read `models` in the caller's namespace map, not the producer's.
- Zig: the `const x = rp.make()` binding decided namespace-vs-file-struct from
  the filename's case and lost `list.push`-style edges on lowercase
  file-structs. That binding form is reverted; the inline form is unaffected.
- Shared-position drops: a site's identity is now `receiver.member`, so
  `rp.untyped().untyped()` records its outer drop while a call and its own
  callee read still count once.

Tests: temp-repo regression rows for each case in the TypeScript, Go and
Python suites, a lowercase file-struct row in Zig, an awaited Dart row (an
awaited Future is not unwrapped yet, so it records a drop), and data-driven
unit cases for recordSiteMember.

Corpus A/B against origin/main: identical CALLS/ACCESSES edges outside the
new fixtures; the drop set outside them is unchanged from the previous head.
Receiver bench: +1 call drop (the awaited Dart row). Dart scope-capture
fingerprint moves for the same fixture row only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 08:45:32 +00:00
Abhigyan Patwari
04427e03c8
fix(ci): avoid RC tag collisions during npm processing (#3649)
Some checks failed
CodeQL / Analyze (python) (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 / Build & Push RC Docker images (push) Blocked by required conditions
Publish / Publish to npm (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
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
Devcontainer Smoke / Config-transform unit tests (push) Has been cancelled
Devcontainer Smoke / Build devcontainer image (default) (push) Has been cancelled
Devcontainer Smoke / Build devcontainer image (ui) (push) Has been cancelled
Publish Development Images / publish (core) (push) Has been cancelled
Publish Development Images / publish (ui) (push) Has been cancelled
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
2026-10-20 20:51:26 +01:00
azizur100389
163056af58
fix(staleness): point index hints to the CLI (#3641)
* fix(staleness): point index hints to the CLI

* fix(staleness): support npx-only installations

---------

Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
2026-10-20 19:11:15 +01:00
Abhigyan Patwari
9df1e98350
fix(routes): scope inline Express handlers and report api_impact lower bound (#3643)
* fix(routes): scope inline Express handlers and report api_impact lower bound

Inline Express handlers are anonymous Function nodes named by position, but
the route facts only recorded a handler name for bare identifiers. Routes
with inline handlers therefore had no handlerSymbolId: every route in a file
got the union of its handlers' response keys and every flow starting there.

Record the positional name for inline handlers, read response keys from the
resolved handler when a file registers several routes, and let processes
link exactly by handlerSymbolId as they already do for named handlers.

Count, per route, the files that pass its URL to a callee not proven to be
a fetch wrapper (excluding proven consumers and the route's own file). The
count is stored as Route.unverifiedConsumers; api_impact reports
epistemic: 'lower-bound' with that count when it is non-zero. Older indexes
without the column fall back to the previous query.

Closes #3488

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(routes): match unverified consumers once per URL

Memoize route matching per distinct fetch URL, skip the proven-consumer
scan when no unproven call matches a route, and build the Route query's
optional columns from a list instead of two booleans.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(group): keep inline handlers attributed to their registrar

Inline Express handlers now carry their positional Function name in the
route facts so ingestion can resolve a handlerSymbolId. Group HTTP
contracts read the same facts, but that name is a graph identity rather
than a symbol name the contract lookup can match, so the provider lost its
enclosing-registrar attribution. Ignore the name for inline handlers there.

Rebaseline the two bench guards the branch moved:
- emit-persistence: route.csv gains the header-only unverifiedConsumers
  field; stripping it restores the prior fingerprint exactly.
- receiver-resolution: the new fixture's req.query.path read on an untyped
  inline-handler parameter adds one receiver-unresolved read (191 -> 192).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
2026-10-20 17:44:08 +01:00
Abhigyan Patwari
faa453c528
fix: reduce MCP token overhead and correct cost comparisons (#3645)
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
2026-10-20 16:04:10 +01:00
Gergő Magyar
01af833875
fix(scope): preserve lexical bindings in HTTP wrapper detection (#3632)
* docs(scope): clarify lexical binding ownership and wrapper provenance

Checkpoint for #3630. Publishing the implemented source, regression tests, and benchmark harness as a draft PR; full-suite and final scaling validation remain in progress.

* fix(scope): publish #3630 docs/plans

* fix(scope): publish #3630 gitnexus/bench/lexical-binding-provenance

* fix(scope): publish #3630 gitnexus/bench/lexical-binding-provenance/fixtures

* fix(scope): publish #3630 gitnexus/bench/lexical-binding-provenance/results

* fix(scope): publish #3630 gitnexus/src/core/ingestion

* fix(scope): publish #3630 gitnexus/src/core/ingestion/languages/typescript

* fix(scope): publish #3630 gitnexus/src/core/ingestion/languages

* fix(scope): publish #3630 gitnexus/src/core/ingestion/pipeline-phases

* fix(scope): publish #3630 gitnexus/src/core/ingestion/route-extractors

* fix(scope): publish #3630 gitnexus/src/core/ingestion/workers

* fix(scope): publish #3630 gitnexus/test/fixtures/lang-resolution/fetch-wrapper-target-identity/lib

* fix(scope): publish #3630 gitnexus/test/fixtures/lang-resolution/fetch-wrapper-target-identity

* fix(scope): publish #3630 gitnexus/test/fixtures/lang-resolution/fetch-wrapper-target-identity/packages/http

* fix(scope): publish #3630 gitnexus/test/fixtures/lang-resolution/fetch-wrapper-target-identity/packages/http/src

* fix(scope): publish #3630 gitnexus/test/fixtures/lang-resolution/fetch-wrapper-target-identity/server

* fix(scope): publish #3630 gitnexus/test/fixtures/lang-resolution/fetch-wrapper-target-identity/web

* fix(scope): publish #3630 gitnexus/test/integration/resolvers

* fix(scope): publish #3630 gitnexus/test/unit

* fix(scope): publish #3630 gitnexus/test/unit/group

* fix(scope): publish #3630 gitnexus/test/unit/scope-resolution

* fix(scope): publish #3630 gitnexus/test/unit/scope-resolution/typescript

* fix(scope): publish #3630 gitnexus-shared/src/scope-resolution

* fix(scope): treat wrapped assignment targets as writes

`(app) = new Map()`, `(app as T) = x` and `app! = x` assign the same binding as
`app = x`, but route-fact invalidation and the shared pattern walker stopped at
the wrapper, so Express provenance survived the write and produced a false
route. Recurse through parenthesized, as/satisfies and non-null targets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(routes): resolve wrappers through overloads, declarator lists and barrels

Three wrapper shapes lost their identity:

- Bodyless overload signatures were indexed as separate definitions sharing
  the implementation's binding, so the binding looked ambiguous and both local
  and imported calls were rejected. Signatures now declare no callable.
- Facts for `const base = 0, request = (url) => fetch(url)` followed the first
  declarator. The captured name now selects its own declarator.
- An import resolved to a workspace barrel stopped at index.ts. Workers now
  record named, star and imported-then-exported re-exports, and resolution
  follows them to the declaring module: local and named exports shadow
  `export *`, star exports never carry `default`, and conflicting star exports
  block the name. No repository-wide name fallback is restored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(scope): assert closure ownership against the declaration

The closure-write assertion compared one lookup with itself, which also passes
when both are undefined. Compare it with the outer declaration and the shadowing
parameter, and keep the memoization check explicit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(routes): share lexical helpers and release per-file HTTP contexts

- Share binding keys, parameter patterns and transparent expression wrappers
  from lexical-bindings instead of four local copies; drop the unused
  moduleStem export; name the inferred-source predicates in lookup.
- Key the per-file HTTP context by its tree rather than its ParsedFile.
  Workers retain ParsedFiles for the whole chunk, which kept every file's AST
  and traversal maps alive until the chunk flushed.
- Index re-exports by name, memoize barrel walks per starting export, and keep
  facts without import targets as-is instead of copying them.
- Move TS-only wrapper cases into the TS describe.each instead of branching
  inside the per-language loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(routes): keep wrapper identity for HOCs, CommonJS, object keys and fetch packages

Four definition shapes that main linked by name lost their wrapper identity:

- `const load = useCallback((url) => fetch(url))` and curried HOCs produced no
  facts because definition lookup stopped at the call; it now follows the
  callable argument, as the structural definition capture does.
- `module.exports = { request }`, `exports.x = …` and `module.exports.x = …`
  were not exports, so destructured `require` callers missed the wrapper.
  CommonJS export assignments are recorded when `module`/`exports` are the
  unshadowed globals, including functions defined inline in the export object.
- An object-literal key or method name was resolved as a lexical binding and
  collided with a same-named module wrapper. Only binding identifiers now name
  a definition's binding.
- `import fetch from 'node-fetch'` no longer counted as fetch. Imports of known
  fetch implementations (node-fetch, cross-fetch, isomorphic-fetch, the fetch
  member of undici and whatwg-fetch) are fetch evidence again; parameters and
  other local names still are not.

Reference identifiers are also resolved only when their name is bound to a
callable or class region; other identifiers cannot add a reachability edge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(routes): drive the forwarding fallback case from data and cover re-export merges

Replace the boolean-switched forwarding fallback case with table rows instead
of branching inside the test, and assert that barrel re-export facts survive
worker sub-batch merges.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(bench): reject stale or dirty call-graph exports

The committed comparison named a candidate revision that is not on this branch,
and nothing stopped it. Comparison now requires both exports to come from clean
checkouts and the candidate export to come from the checkout running the
comparison.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(bench): regenerate the call-graph comparison on the reviewed head

Clean baseline 565e50276 and clean candidate 8a5f7b738 on the frozen 432-file
corpus (fingerprint 88be1faf...): exactly one CALLS target changes, the
annotated closure probe `declaredOwner.writeAndRead` now calls `Base.m`
instead of `Foo.m`. The other 431 CALLS and all 11 METHOD_OVERRIDES edges are
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(bench): emit export provenance and review notes from the comparison

The comparison report carried export provenance and the expected-change
explanation only as hand-added fields, which a regeneration dropped. Emit
both exports' revisions, dirty flags and fingerprints, the unchanged CALLS
and METHOD_OVERRIDES counts, and an optional `--note` explanation directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(bench): record calibrated scaling reports and the regenerated comparison

Duration-calibrated-v2 runs (5 warmups, 15 measured batches, 500 ms pilot
target) pinned to the same CPU, baseline then candidate back to back:

- Baseline 565e50276 exceeds the 1.8 normalized ceiling on six arms at 4x
  input: position-index 7.92, position-deep-completed 4.65, nested-helpers
  4.82, nested-helper-chain 14.05, reverse-chain 4.31, name-collisions 2.61
  (medians).
- Candidate 94f1a055b passes --check: every arm stays at or below 1.32 at 4x
  for both minimum and median, with correct semantic guards on every arm.

The comparison is regenerated from clean exports with its provenance and
review note emitted by the tool: one expected CALLS target change, 431 CALLS
and 11 METHOD_OVERRIDES unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(scope): replace recursion with explicit stacks in new traversals

The binding work added five recursive traversals whose depth follows input
shape: region summaries (callable nesting), barrel resolution (re-export
chain length), pattern binding names (destructuring depth), route-fact write
invalidation (pattern depth), and the position index's max-end tree. Each
now uses an explicit stack with the same visiting order and results.

Regression cases cover the inputs the recursive versions could not handle:
a 20,000-deep destructuring pattern and a 50,000-module re-export chain both
threw RangeError before this change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(routes): avoid a full-tree script walk when building lexical bindings

Route-fact extraction ran 1.78x slower than main on a 512-function file
(87 ms vs 49 ms) because createLexicalBindings walked every AST node in script
to detect collapsed parameter/body environments, which only functions with
parameter defaults or computed keys can have.

- Find functions with the native type search, skip plain parameter lists
  without any subtree search, and walk only the formals and bodies of the
  rest. Detection is unchanged, except that functions inside syntax-error
  regions are now also checked, which can only add fail-closed ambiguity.
- Read each node's id and start position once per lookup instead of
  repeatedly crossing into native getters.

The same extraction now takes about 56 ms against 51 ms on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(routes): walk wrapper evidence with a tree cursor

The wrapper context visited every node through namedChildren, which
materializes each child as a SyntaxNode and records a parent edge by node
id. A tree cursor reads node types and offsets natively, so only the node
types the handlers inspect become SyntaxNodes. Declared identifiers are
keyed by start offset, and the walk records the ancestor facts later
queries need (stored binding, default export, declarator of a name)
instead of a parent map.

On the 512-wrapper scaling input, context construction drops from about
58 ms to 48 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(bench): regenerate the call-graph comparison on the cursor walk

The candidate export at 6061ca71b has the same fingerprint as the previous
candidate: the traversal rewrite changes no edge. The one expected target
change and the 431 unchanged CALLS and 11 METHOD_OVERRIDES remain.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(bench): record final scaling reports on the cursor walk

Baseline 565e50276 and candidate 61de364ff ran back to back on CPU 23
with the duration-calibrated-v2 protocol. Every candidate check stays at
or below a 1.32 normalized factor against the 1.8 ceiling; the baseline
fails six of nine arms. Workload fingerprints agree except the documented
name-collision false positive in the baseline.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(plan): checkpoint the final review, scaling and suite results for #3630

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(routes): treat export aliases of one wrapper as one star-export target

Star-export candidates were deduplicated by the resolved export name, so
`export { request, request as send }` reached through two barrels counted
as two targets and blocked the import, dropping the consumer's FETCHES
edge. Candidates are now keyed by the declaration each export name names,
matching ECMAScript ResolveExport's binding comparison; distinct
declarations exported under the same name stay ambiguous.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(bench): regenerate scaling and call-graph reports on the alias fix

Baseline 565e50276 and candidate 4d62bd045 ran back to back on CPU 23.
Every candidate check stays at or below 1.22 against the 1.8 ceiling;
the baseline still fails six of nine arms. The CALLS/METHOD_OVERRIDES
export is unchanged (fingerprint 4db24f57), so the comparison only
records the new candidate revision.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(plan): record the export-alias fix and the regenerated reports for #3630

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(scope): keep the type a write gives an undeclared name

A constructor write to a name no scope declares (`client = new ApiClient()`
in sloppy JavaScript) declares nothing, so the lookup stays absent. The
carried constructor fact was dropped on that exit, which lost the receiver
type main had inferred for later reads in the writing scope. The absent
result now carries it, and findReceiverTypeBinding uses it before the
namespace fallbacks. Only complete-claim providers carry such a fact.

Tests pin the carried type per inferred source, the undeclared write, and
preservePosition across a module redirect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(routes): close the wrapper identity gaps found in review

- CommonJS wrappers captured as their assignment (`exports.x = function`,
  `module.exports.x = () =>`) produce facts again: findFunction follows the
  assignment's right side.
- Name-only fallback considers only definitions that can be the target: an
  unresolvable import names a module-level export, an undeclared global a
  top-level function. Nested and unexported helpers no longer erase a
  wrapper's edges.
- Only possible wrappers and module-level functions are emitted, and the
  routes phase builds the index only when routes and candidate calls exist.
- A rebound binding (later assignment, `var` initializer over a function
  declaration, reassigned export) proves no wrapper across files.
- `(<T>x) = ...` is a write; transparent wrappers skip type arguments.
- Calls inside recovered syntax are still collected; instance-field
  initializers resolve after the module body, so a later declaration is
  visible.
- Local exports are always recorded, so a star export conflicting with a
  non-callable export is ambiguous, and fully resolved barrel frames are
  shared across walks.
- HTTP hooks run per file under a guard; a failing file or one without a
  ParsedFile still records its function names so fallback declines.
- namesFetch is iterative, large patterns no longer spread into push, the
  facts cache is keyed by the name node, and the provider context cache
  checks its ParsedFile.

Tests cover each case; the behavior rows fail on the previous source.
The TS-only call cases no longer branch inside the test file, call targets
are asserted exactly, the function-type list is drift-checked, and the
persistence test joins the cross-platform worker list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(routes): describe wrapper fallback, barrel and recall boundaries

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(bench): count the new CommonJS fixture's dropped write site

`lib/cjs-member.js` in the fetch-wrapper target-identity fixture writes
`module.exports.arrowRequest`, a member write whose receiver is not typed.
That adds one `receiver-unresolved` write (190 -> 191 all-kind drops,
19 -> 20 writes). Call drops and shape-arm states are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(bench): regenerate scaling and call-graph reports on the review fixes

Baseline 565e50276 and candidate 528ea1478 ran back to back on CPU 23.
Every candidate check stays at or below 1.27 against the 1.8 ceiling; the
baseline still fails six of nine arms. The CALLS/METHOD_OVERRIDES export
is unchanged (fingerprint 4db24f57), so the comparison only records the
new candidate revision.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(plan): checkpoint the review fixes and regenerated reports for #3630

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(routes): share CommonJS checks and trim per-node work

- `isCommonJsGlobal`/`isModuleExports` in lexical-bindings replace the two
  copies in fetch-wrapper and framework-route-facts (both resolve the same
  scope from the same start position).
- LEXICAL_FUNCTION_TYPES is derived from the TypeScript FUNCTION_NODE_TYPES
  instead of a third hand-kept copy; the drift test still pins it.
- `unwrap` reads UNWRAPPED_TYPES, the set the cursor walk mirrors, and the
  class-body region is no longer shadowed under the name `deferred`.
- framework-route-facts reads each node's type once per loop iteration.
- The position index returns the latest-starting scope when it already
  contains the point, before the max-end tree search; that entry is the
  search's rightmost match.
- carried() returns a shared empty set for argument forms that cannot carry
  a value, the resolution file set is built without intermediate arrays,
  and the routes phase reads the call list once.

No behavior change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(bench): regenerate scaling and call-graph reports on the refactor

Baseline 565e50276 and candidate 3db8657ba ran back to back on CPU 23.
Every candidate check stays at or below 1.32 against the 1.8 ceiling; the
baseline still fails six of nine arms. The CALLS/METHOD_OVERRIDES export
is unchanged (fingerprint 4db24f57). The later main merge (e2a92dab8)
touches no measured file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(plan): checkpoint the simplification pass and its reports for #3630

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Address PR review feedback (#3632)

- Destructuring defaults (`{ fetch = globalThis.fetch } = {}`, renamed,
  array and local forms) are alias evidence for their leaf binding and
  no longer count a second initialization, which also invalidated
  bindings like `[send = other] = values`.
- `export default (request)` records the default export: the value is
  unwrapped before the identifier check.
- The HTTP fallback records and the collapsed-environment test row now
  say what they stand for.

Regression rows cover each form in JS, TS and TSX and fail on the
previous source; two fixture consumers cover imported wrappers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(bench): refresh lexical binding reports after review fixes

Regenerate clean baseline and candidate measurements at c263c4f72.
All candidate scaling checks pass, the semantic delta remains one CALLS
target, and receiver-resolution counts match the existing baseline.

* docs(plan): checkpoint refreshed review-fix measurements

Record c263c4f72 review fixes, the regenerated scaling and semantic
results, and the passing receiver and CI checks.

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 11:36:06 +01:00
gitnexus-release-bot[bot]
47d63a0601
chore(vendor): update tree-sitter-dart to 1.0.0-g0038280 (#3633)
* chore(vendor): update tree-sitter-dart to 1.0.0-g0038280

* chore(vendor): rebuild native prebuilds (tree-sitter-dart)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/39212887661

* fix(dart): use native extension type parsing

The upgraded grammar parses extension types directly. The compatibility
rewrite loses generic extension bodies and implements clauses, so capture
the native nodes and register their member ownership instead.

Refresh the Dart capture fingerprint after comparing the old grammar and
emitter over the same fixture corpus. Keep the scaling budget unchanged.

Refs #3633

* chore(vendor): rebuild native prebuilds (tree-sitter-dart)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/39239767139

* fix: repair Dart parity and checkpoint regressions

Remove Dart from the preprocessing fixture inventory after retiring its
hook. Use the parsed body boundary when reading extension-type heritage
so named-record representations retain their implements clauses.

Seed the WAL recovery fixture with the normal checkpoint threshold, then
force one-byte checkpoints only for the deliberately blocked write.
Require an actual error exit instead of accepting a subprocess timeout.

Refs #3633

* chore(vendor): rebuild native prebuilds (tree-sitter-dart)

Built by https://github.com/abhigyanpatwari/GitNexus/actions/runs/39248441688

---------

Co-authored-by: gitnexus-release-bot[bot] <gitnexus-release-bot[bot]@users.noreply.github.com>
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
2026-10-19 15:41:34 +01:00
Abhigyan Patwari
89602560d3
fix(group): read Python prefixed literals and f-string URLs as paths (#1675) (#3626)
Some checks failed
Skill copy sync / shipped skills drift guard (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
CodeQL / Analyze (python) (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
2026-10-19 07:10:29 +03:00
Abhigyan Patwari
565e50276d
fix(routes): resolve Express registrations made through helper parameters (#3629)
* fix(routes): resolve Express registrations made through helper parameters (#3487)

#3603 made Express receivers provenance-proven, which removed the receiver-
name false positives but also every registration on a function parameter:
a parameter has no binding value, so `app.get(...)` inside a helper never
resolved. On GitNexus's own server that dropped `* /api/mcp`
(`mountMCPEndpoints(app, ...)`) and `GET /` (`registerWebUI(app, ...)`),
and the two SSE progress routes registered by
`mountSSEProgress(app, '/api/.../progress', jobs)` were never found at all
(#3487, item a).

Named function values in the route facts now carry an identity and the
binding id of each parameter (a TypeScript `this` parameter takes no
position, and a parameter written anywhere in the body, nested closures
included, takes none either). Calls to plain functions and to namespace or
default import members are recorded as invocations, keeping only the
arguments that can carry an allocation or a literal path; arguments after a
spread have no position. The resolver resolves a registration whose
receiver, literal path or mounted child is a parameter through each call
site of its function, once per site and in the helper's file. This is one
hop only: a site argument that is itself a parameter does not resolve. When
no call site is recorded, the call is evaluated as written, so an unknown
mount path still suppresses its child router instead of exposing its paths
at the root.

Only calls whose callee is named like a function that registers on its
parameters are evaluated, which keeps resolution at its previous cost on
repositories with many helper calls. A function value's invalidation key now
includes its identity, so a property write on one function
(`Button.displayName = ...`) no longer disables every other. The group
layer shares the resolver, so it gets the same routes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(routes): forward mounted-child parameters and aliased helper imports

Review follow-ups for the helper-parameter forwarding:

- A helper that forwards only its mounted router (`function mountChild(child)
  { app.use('/api', child) }`) was never resolved, because the forwarded
  function was chosen from the receiver and path alone. Any parameter among
  the receiver and arguments now selects it, as long as all come from one
  function.
- A helper called through an aliased import (`{ mountSSEProgress as
  mountProgress }`) was filtered out before its call sites were recorded,
  since the filter compared only the local name. It now also accepts the
  imported name.
- A write to a same-named local declared in a nested block (`{ let app;
  app = other; }`) discarded the outer parameter. A write to a binding that
  a nested block, function or catch clause declares no longer counts.
- The fixture's `registerWebUI` uses its static directory.

The release tool-accuracy gate now passes `routes.helper-registration`, so
its known-gap allowance is removed. Its expected file moves from the caller
(`api.ts`) to the helper (`progress.ts`): an Express route belongs to the
file of its `app.get` call, which is also where its handler and response
keys are, as for every directly registered route.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(routes): treat destructuring reassignment as a parameter write

`[app] = [other]` reassigns `app`, but the write check compared the whole
target text (`[app]`) with the parameter name, so the parameter stayed
forwardable and later registrations used the call-site argument. A
destructuring target now writes each name it binds; a member target still
writes only a property. Also drops an unused local flagged by CodeQL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(routes): follow helpers exported under another name

`export { mountRoutes as setup }` records the export as a binding, so the
call-site filter knew the helper only as `mountRoutes` and skipped callers
importing `setup`. An export of a binding to a named function now adds its
exported name too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
2026-10-18 22:13:10 +01:00
Abhigyan Patwari
aa33a6e94c
fix(routes): link base-URL fetch calls made through wrapper chains (#3628)
* fix(routes): link base-URL fetch calls made through wrapper chains (#3488)

GitNexus's own web client calls `fetchWithTimeout(`${_backendUrl}/api/repos`)`,
which reaches fetch through `resilientFetch` and a local `fetchImpl` alias.
`api_impact` found none of those consumers, for three independent reasons:

- normalizeFetchURL rejected any URL that did not start with `/`, so a
  leading base-URL binding dropped the call. It now strips a leading
  `${...}` run followed by `/`, with the same rules as the group layer's
  consumer normalizer (#3111); the helper moves to route-path.ts so both
  layers share it. A path whose every segment is a param (`${base}/${id}`,
  `${base}/${id}.json`) is rejected, since it would match every route of
  that depth. Interpolations are collapsed brace-balanced before the query
  split, so `${repo ? `?repo=${repo}` : ''}` no longer ends the path, and
  one glued to the last static segment is treated as a query or suffix.
- The wrapper call collector required a `/`-leading literal, so the same
  template never became a wrapper candidate.
- Wrapper detection only looked five AST levels deep for a call to an
  identifier named `fetch`. Arrow-const wrappers sit deeper than that, and
  `resilientFetch` calls an alias of `globalThis.fetch`. Detection now walks
  the whole definition and accepts `globalThis`/`window`/`self.fetch` and
  aliases whose value names fetch (through `??`, `||`, `?:`), read from the
  AST rather than the text. It records whether the first parameter reaches
  fetch's URL argument and which callees receive that parameter. The routes
  phase closes the wrapper set over that forwarding: `fetchWithTimeout` is a
  wrapper because it forwards its URL to `resilientFetch`. A callee declared
  in the caller's file or imported from a relative module must carry a URL
  in exactly that module; a package-imported name is followed only when
  every recorded function of that name carries one. A fetch caller whose
  first parameter is not the URL (`track(event)`) or a same-named function
  elsewhere (an IPC `request(channel)`) lends nothing.

When `[param]` matches several sibling routes (`/api/analyze/upload` and
`/api/analyze/:jobId`), the fetch now links to the route whose segments
match by kind instead of the first one registered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(routes): match wrapper calls by declaring module and decline ambiguous fetch matches

Review follow-ups for #3488:

- A propagated wrapper's name went into a repo-wide set, so a literal call
  to an unrelated same-named function in another module was taken as a
  fetch. Wrapper call candidates now carry the module declaring a bare
  callee when the file declares or imports it relatively, and must reach a
  wrapper defined in exactly that module. Package and member callees keep
  the name match.
- An alias declared in a nested helper (`const fetchImpl = globalThis.fetch`)
  marked an outer call to a same-named parameter as a fetch. An alias now
  counts only where its declaring function encloses the call.
- A first parameter redeclared inside the function (`{ const url = ...;
  fetch(url) }`) was taken as the URL. A shadowed parameter is no longer
  followed.
- A fetch whose `[param]` ties between sibling static routes
  (`/api/kinds/foo`, `/api/kinds/bar`) linked to the first registered one.
  A tie now links none.
- The fixture's `resilientFetch` returns the last response instead of
  rejecting with `undefined`, and its client encodes the repo query value.

The release tool-accuracy gate now passes `api.template-wrapper`, so its
known-gap allowance is removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(routes): keep call-site wrapper names and ignore helpers that never run

- A wrapper call through a renamed relative import (`import { request as
  send }`) stored the exported name, so a configured `fetchWrappers` entry
  naming the call-site `send` no longer matched. The call keeps its
  call-site name and carries the declared name separately for the module
  lookup.
- A nested helper bound to a local that is never referenced again (`const
  later = () => resilientFetch(url)`) made its enclosing function forward
  its URL. Calls inside such a helper are ignored; a helper that is called
  or passed on, such as a retry callback, still counts.
- The fixture's `resilientFetch` no longer retries after a timeout or abort.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(routes): let a nested parameter shadow a fetch alias

A function parameter between a fetch alias and a call shadows the alias
there (`function send(fetchImpl) { return fetchImpl(event) }` beside an
outer `const fetchImpl = globalThis.fetch`), so that call no longer marks
the enclosing function as a fetch wrapper. The fixture's retry helper also
stops returning a stale 5xx response after a later attempt throws.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(routes): drop fetch aliases whose name is redeclared with another value

A block that redeclares an alias name with a non-fetch value (`{ const
fetchImpl = other; fetchImpl('/x') }`) let the inner call read as a fetch.
A name declared anywhere in the function with a value that does not name
fetch is no longer an alias, which covers every block-scoped shadow without
lexical scope tracking.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(routes): ignore uncalled nested declarations and shadowed global objects

- An uncalled nested `function helper() { fetch('/x') }` made its enclosing
  function a fetch wrapper. Nested function declarations that are never
  referenced are now ignored, as unused function-valued locals already were.
- `window.fetch(url)` through a parameter or local named `window` (or
  `self`, `globalThis`) was read as the platform fetch. Such a root is now
  that value's method. A bare `fetch` parameter is still taken as fetch,
  since injecting a fetch implementation is the common reason for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(bench): refresh the receiver-resolution baseline for the fetch fixture

The new `fetch-base-url-wrapper` fixture in `test/fixtures/lang-resolution`
adds one unresolved TypeScript chain-field call to the committed check
corpus (127 to 128 call drops). Regenerated with
`measure.mjs --update-baseline` after a fresh build and cleared parse caches;
no other counter moved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
2026-10-18 22:11:37 +01:00
Abhigyan Patwari
d4dc797054
fix(group): read net/http HandleFunc and Handle on proven routers as method-agnostic routes (#3627)
* fix(group): read net/http HandleFunc and Handle on proven routers as method-agnostic routes (#1668, #1670)

The Go provider query only matched the literal `http.HandleFunc(...)` with an
identifier or inline handler, so a local `http.NewServeMux()`, a gorilla or
chi router, `Handle(...)`, a method-value handler (`api.ListUsers`) and a raw
string path produced no provider at all (#1668).

It also hard-coded `GET`. A ServeMux registration serves every method unless
its pattern names one, so a POST consumer never paired with the route
(#1670). The provider is now method-agnostic (`*`), the convention Django,
Nest `@All` and Hono `.all` already use and the matcher already pairs with
consumers of every verb. A Go 1.22 pattern (`"POST /p"`,
`"GET host/p/{id}"`) gives its method and drops the host and the `{$}`
anchor, and a gorilla `.Methods(...)` on the route chain gives its verbs.

`HandleFunc`/`Handle` are common names outside HTTP (telebot's
`b.Handle("/start", fn)`), so the receiver must be a proven router: the
net/http package, a binding to `http.NewServeMux()`, gorilla
`mux.NewRouter()` or chi `chi.NewRouter()`, a gorilla
`PathPrefix("/p").Subrouter()` or chi `Route("/p", func(r chi.Router))`
(joining the prefix), or a parameter typed as one of those routers. A
router the file mounts under a stripped or prefixed path (`Mount`,
`StripPrefix`, gorilla `.Handler`) is declined, as is a struct field, since
their registered paths are not their URLs. Routers in `_test.go` files are
httptest mocks and are skipped. Handler naming is shared with the gin/echo
loop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(group): decline mounted router parameters and read HEAD routes as GET

A router parameter passed to `StripPrefix`/`Mount` was never marked mounted,
because the mount scan resolved identifiers through `findBinding`, which
returns nothing for a parameter, so its unprefixed paths were emitted. The
scan now records a parameter by its declaration and the router proof checks
it.

A `"HEAD /x"` pattern or gorilla `.Methods("HEAD")` produced an
`http::HEAD::` provider, while this plugin's `http.Head` consumers are keyed
as GET. Providers now follow the same HEAD-as-GET convention. The plugin
docstring no longer says any receiver is accepted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(group): read http.HandlerFunc conversions and hyphenated method tokens

`http.Handle("/x", http.HandlerFunc(h))` was dropped because the handler
argument is a conversion call; the converted function is now the handler.
A Go 1.22 pattern whose method token contains characters other than
letters (`"M-SEARCH /discover"`) produced no provider; the method now
accepts any HTTP token that starts with a letter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(group): keep HEAD-only Go routes apart from GET consumers

Reading a `"HEAD /x"` pattern or gorilla `.Methods("HEAD")` as GET let
every ordinary GET consumer pair with a route that does not serve GET. The
provider now stays HEAD. A HEAD consumer, which this plugin records as GET,
then misses a HEAD-only route; a missed link is preferred to a false one.
Repeated verbs still collapse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
2026-10-18 22:11:17 +01:00
Gergő Magyar
62f86ea068
feat(mcp): reduce response size and query overhead (#3621)
* docs(mcp): document focused response filters

* feat(mcp): add opt-in response section and relation filters

* test(mcp): verify response filters and compatibility

* test(mcp): add deterministic response-size benchmark

* docs(skills): teach focused MCP calls and safe filter use

* docs(skills): update debugging response-filter guidance

* docs(skills): update exploration response-filter guidance

* docs(skills): explain focused MCP response options

* docs(plugin): mirror focused debugging guidance

* docs(plugin): mirror focused exploration guidance

* docs(plugin): mirror focused MCP tool guide

* docs(cursor): mirror focused debugging guidance

* docs(cursor): mirror focused exploration guidance

* test(mcp): give filter cases unique identities

Use named cases to keep array inputs intact and let the CI execution audit distinguish every malformed-filter test.

* perf(mcp): batch BM25 symbol hydration

* test(mcp): serialize native hydration coverage

* test(eval): publish child PID atomically

* test(mcp): cover hydration on native platforms

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Abhigyan Patwari <126312502+abhigyanpatwari@users.noreply.github.com>
2026-10-18 17:32:09 +01:00
Abhigyan Patwari
39e0ced68d
test(server): make the opaque repo id assertion deterministic (#3625)
`publicRepoId` is an HMAC under a key drawn once per process
(`randomBytes(32)`), so the 22-character base64url id is effectively
random on every run. The test asserted `not.toContain('ws')` to show the
id does not leak the path, but any id contains "ws" by chance with
probability 21/4096 (~0.5%). CI hit it on #3624 with
`gt5f4oNtpcwsi6vep8lzQN`.

Across 20,000 fresh keys the old assertion failed 118 times and the new
one 0 times. The test now checks the base64url shape and that the full
path is absent; '/' is outside the alphabet, so a chance match cannot
happen.

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 13:43:33 +01:00
Gergő Magyar
5d1bc3dcea
feat(eval): request PR cost comparisons by label (#3622)
* feat(eval): measure PR cost before merge

Reuse authenticated historical MCP measurements for one pinned PR preview. Keep the protected main evaluator and publish separate evidence that cannot authorize a release.

* fix(eval): gate PR cost runs on a label

Require a repository writer label event and retain the opt-in label
and exact PR head before dispatch and paid sessions. Keep the
request handler on trusted base code and execute evaluation on main.

* ci: document trusted cost label trigger

* fix(eval): restrict previews to maintainer labels

Remove manual PR preview inputs and authorize Maintain/Admin roles before calling the protected reusable evaluator. Compare workflow measurement settings with historical evidence instead of exempting the entire workflow.

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
2026-10-18 11:00:08 +01:00
Gergő Magyar
bd20dde825
fix(taint): report inline and factory handler flows (#3612)
* fix(taint): cover inline and returned handlers (U8)

Join expression-handler CFG summaries to distinct graph functions without changing existing anonymous-owner identities. Keep named function expressions private to their lexical scope.

Related: #3489

* fix(ci): encode inline handler taint paths (U8)

Use codec-safe generated display names while preserving positional function identity. Verify persisted hop continuity and remove the repaired inline-flow accuracy allowance.

* fix: keep anonymous names unbound (U8)

* test: pin inline callback captures (U8)

* ci: run inline taint guard (U8)

* test: align inline handler contracts (U8)

Pin callback-owned call edges while preserving nested callable IDs and module-level HOC attribution. Assert repaired inline flows and the retained captured-closure limitation.

* ci: run native inline proofs on all OSes (U8)

Register real-worker identity/CFG and persisted explain cases on the existing Windows/macOS matrix. Charge explicit scheduling estimates without changing watchdogs or runtime behavior.

* test(taint): reject all enclosing factory sources

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
2026-10-17 20:22:58 +00:00
Gergő Magyar
30676685e0
fix(rename): apply the exact reviewed edit plan (#3617)
* fix(rename): bind apply to reviewed plans (U7)

Retain exact semantic edits behind single-use preview tokens and reject
source, target, inventory and graph drift before application. Preserve
explicit partial-write accounting and keep large unedited sources covered
with hashes instead of retained text.

Refs #2973

* fix(rename): cover unindexed sources (U7)

Address PR #3617 review by binding every supported source to streamed byte
hashes and canonical targets, including tracked and untracked files absent
from the graph. Keep the exact reviewed edits and bound evidence memory.

Use conventional even-sample medians and extend the existing CI benchmark
to capture and validate unindexed sources without relaxing timing gates.

Note: pre-existing packed Tree-sitter GLIBCXX_3.4.31 host failure in
parse-cache-identity-package.test.ts is not addressed by this PR.

* fix(rename): preserve lazy startup (U7)

Keep language providers off the MCP startup path; load their existing
classification only when rename inventory is requested. The existing
12 startup closure checks now pass.

Address PR #3617 review by including token validation in reviewed apply
timing and growing indexed evidence before preview, preserving the
20MiB controls under a 256MiB native pool. Migrate dispatch and retention
tests to the preview token contract, keeping write-failure oracles.

Note: pre-existing auto-sync /tmp fixture security and installed ARM64
grammar-header failures remain outside this PR; the packed Tree-sitter
GLIBCXX_3.4.31 host failure also reproduces on unchanged main.

* test(rename): always remove apply fixture (U7)

Own the temporary directory from creation in an outer finally so setup
and preview assertions cannot bypass cleanup. Keep spy restoration in
its inner finally and preserve all write-failure assertions.

Address PR #3617 cleanup feedback.

* fix(rename): retain targets and config evidence

* test(rename): verify approved physical output

* test(rename): cover native filesystem matrix

* test(rename): align preview contract fixtures

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
2026-10-17 19:38:01 +01:00
Gergő Magyar
9b04fbe627
fix(embeddings): budget generated inputs and isolate rejections (#3615)
* fix(embeddings): budget generated inputs and isolate rejections (U4)

* test(embeddings): require pending retry request

* fix(embeddings): preserve Unicode in context

* ci: run generated embedding input budget guard

* test(embeddings): run input isolation on native OSes

* fix: retain container identity after long prefixes

* test: distinguish generated input cases

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
2026-10-17 19:37:30 +01:00
Gergő Magyar
e6ae04ed84
fix(embeddings): reject corrupt identities before mutation (#3614)
* fix(embeddings): reject corrupt identities before mutation (U2)

* fix(embeddings): preserve exact Unicode keys (U2)

* fix(storage): validate identities before opening CSVs

* fix(embeddings): validate caches before mutation

* ci: gate native embedding identity benchmark

* test(embeddings): run identity proofs on native OSes

* docs: describe CSV identity validation pass

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
2026-10-17 18:45:28 +01:00
Gergő Magyar
c8629f1b6c
fix(storage): preserve published graph on rebuild failure (#3613)
* fix(storage): preserve published graph on rebuild failure (U1)

* test(storage): strengthen publication review coverage (U1)

* test(storage): align publication evidence (U1)

* fix(storage): retain completed recovery archives

* fix(storage): preserve quarantines before cache reads

* ci: run staged publication benchmark guard

* fix(ci): declare WAL replay probe determinism

Document that the bounded recovery read drains and discards its rows. Only WAL replay success is observed; row identity and query behavior are unchanged. The existing 21 query-determinism checks pass.

* test(storage): cover publication across platforms

* test(ci): exclude POSIX suite from Windows estimates

* test: allow native publication retry to finish

* test: verify Windows incremental recovery

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
2026-10-17 18:45:11 +01:00
Gergő Magyar
22a7608b7c
feat(cache): derive parser and PDG cache identities automatically (#3606) 2026-10-17 07:38:45 +03:00
Gergő Magyar
f8209df2e2
fix(routes): resolve Express receivers and router mount paths (#3603)
* fix(routes): resolve Express receiver provenance and mounted paths

Require statically proven framework receivers, compose Router mount paths,
and share the same provider resolution between ingestion and group routes.
Preserve worker and parse-cache parity with per-file facts.

* fix(review): apply review findings

Invalidate exported Routers through namespace property mutations and retain
uncertain incoming mounts so invalid parents cannot revive local paths.

* refactor(routes): reuse export checks and fixture writer

* fix(routes): evaluate fluent call receivers once

* fix(review): preserve provider paths and uncertain mounts

* fix(test): distinguish parameterized router mutation cases

* docs: remove Express route implementation plan
2026-10-16 18:25:40 +01:00
Gergő Magyar
faf05f2eb7
fix(install): restore Linux ARM64 npm installation (#3601)
* fix(install): validate and package Linux ARM64 parser replacements

* fix(install): add rebuilt ARM64 grammar binaries

* fix(install): place ARM64 binaries in versioned bundle paths

* refactor(install): share ARM64 prebuild validation

* fix(review): keep grammar rebuild provenance accurate

* test: pin audited ARM64 repair provenance (#3601)
2026-10-16 15:28:35 +01:00
azizur100389
94f167a90f
fix(routes): reject middleware and route metadata false positives (#3561)
* fix(routes): reject middleware and route metadata false positives

* fix(routes): invalidate cached phantom routes on upgrade

* test(routes): cover cache upgrades across merged schema versions

Verify that schemas 137 through 140 invalidate both parse stores after merging main into PR #3561 and advancing the schema to 141.

---------

Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
2026-10-16 08:02:41 +00:00
Richie Wee
b51f25606c
fix(routes): match configured fetch wrapper calls that pass type arguments (#3567)
Some checks failed
Devcontainer Smoke / Build devcontainer image (push) Has been cancelled
Devcontainer Smoke / Config-transform unit tests (push) Has been cancelled
Skill copy sync / shipped skills drift guard (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
Gitleaks / gitleaks (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-cli) (push) Waiting to run
CodeQL / Analyze (python) (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-web) (push) Waiting to run
2026-10-15 20:08:56 +03:00
Gergő Magyar
b37d4f246d
fix(group): release bridge database before publishing metadata (#3594) 2026-10-15 16:53:51 +03:00
Nguyễn Đăng Minh Lực
5c3961756b
fix(ingestion): preserve Go method ownership across files (#3559)
* fix(ingestion): re-point Go struct member edges when struct is declared in a sibling file (#3558)

findEnclosingClassInfo mints a Go method's owner id from the file
containing the method (Struct:<methodFile>:<Type>), while the Struct
node is keyed by the file declaring the struct (parse-worker uses
declFile). Same package, different file => the HAS_METHOD edge's
sourceId points at a node that does not exist and the edge is silently
dropped at COPY into LadybugDB.

Add reconcileGoStructOwnerEdges, run at the end of the parse phase
after ALL worker chunks are merged so every package's structs are
visible. It rewrites only edges that would otherwise dangle, and only
when exactly one Struct node shares the dangling id's package directory
and simple name; 0 or >=2 candidates keep the old drop behavior (a
wrong owner is worse than a dropped edge).

Index build is lazy: dangling Struct sources are rare (struct fields
never dangle — they live in the struct's own file), so the common
non-Go or fully-same-file case pays two per-type edge scans and no
whole-node pass.

Regression test: test/integration/go-cross-file-struct-owner.test.ts
(fails-before: 1 HAS_METHOD edge; passes-after: 3).

* fix(ingestion): scope Go struct-owner reconcile by language and package

Address PR #3559 review findings:

- Scope the pass to Go: dangling HAS_METHOD/HAS_PROPERTY owner ids whose
  Struct:<file>:<name> file is not Go source (Rust, Swift, ...) are never
  re-pointed, and only Struct nodes stamped language 'go' (the marker the
  worker sets on every declared symbol) are candidates. Negative test pins
  a Rust-shaped dangling edge staying untouched beside a same-name Go
  struct.

- Key candidate structs by (dir, declared package clause, name) instead of
  (dir, name): one directory can carry 'package pkg' and external-test
  'package pkg_test' files declaring the same type name, which the old key
  saw as ambiguous and dropped fail-closed. Clauses are read via the shared
  inferGoPackageName derivation with a call-scoped cache. Integration test
  covers the 3-file layout (pkg decl, pkg_test decl, pkg_test methods file)
  and asserts the edge lands on the pkg_test.Widget node.

- Keep the direct call in parse-impl with a TODO: the pass needs a
  graph-level post-merge hook, which no LanguageProvider/ScopeResolver hook
  provides today.

* refactor(ingestion): remove Go graph repair from shared parse phase

* fix(ingestion): resolve Go ownership during ingestion (language-provider.ts)

* Add resolveDetachedOwnerName function to Go config

* Refactor method owner population logic in Go

* Refactor receiver binding to handle unnamed receivers

* Enhance route handler method resolution logic

Refactor route handler to improve ownership resolution and method indexing.

* Add emitPostResolutionEdges to scope resolver

* fix(ingestion): resolve Go ownership during ingestion (ownership.ts)

* fix(ingestion): resolve Go ownership during ingestion (ast-helpers.ts)

* Add resolveDetachedOwnerName to provider methods

* Update SCHEMA_BUMP to 141

Increment schema version to 141 for new features and fixes.

* fix(ingestion): resolve Go ownership during ingestion (decl.go)

* fix(ingestion): resolve Go ownership during ingestion (external_decl_test.go)

* fix(ingestion): resolve Go ownership during ingestion (external_methods_test.go)

* fix(ingestion): resolve Go ownership during ingestion (foreign.rs)

* fix(ingestion): resolve Go ownership during ingestion (go.mod)

* fix(ingestion): resolve Go ownership during ingestion (local.go)

* fix(ingestion): resolve Go ownership during ingestion (methods.go)

* fix(ingestion): resolve Go ownership during ingestion (go-cross-file-struct-owner.test.ts)

* Refactor comments and method registration in tests

Updated comments for clarity and modified method registration to include qualified names and ownership.

* fix(ingestion): resolve Go ownership during ingestion (has-method.test.ts)

* Update SCHEMA_BUMP to 141 in tests

* refactor(ingestion): remove obsolete Go struct owner reconciliation

* fix(go): model build constraints for method ownership

* test(go): cover build constraint grammar and platform variants

* fix(go): resolve method owners across compatible build variants

* test(go): verify variant ownership through ingestion pipeline

This test verifies that build-variant owners are consistent across different workers, the semantic registry, and the graph. It sets up various scenarios to ensure that ownership is correctly resolved and that there are no dangling edges in the ownership graph.

* fix(go): reject impossible known constraints when peer is unknown

Address PR #3559 review feedback. Regression coverage follows in this update.

* feat(ingestion): allow providers to group incremental resolution files

Add the optional language-neutral hook used by the Go ownership writeback fix for PR #3559.

* fix(go): group sibling files for incremental ownership resolution

Use the existing Go package-directory key for the provider hook.

* fix(incremental): collect sibling resolution groups for changed paths

Keep group keys local to each provider and include current siblings of deleted files.

* fix(analyze): persist ownership changes in unchanged Go siblings

Expand changed and deleted resolution groups before importer traversal. Use the same effective file set for deletion and writeback so package-wide ownership changes reach the database.

* test(incremental): cover provider-local resolution groups

Cover changed, added, deleted and unrelated paths for the new sibling expansion helper.

* test(go): compare incremental ownership writes with cold rebuilds

Reproduce ownership changes after deleting and restoring a Windows declaration while the shared method file stays unchanged. Verify incremental writes and persisted ownership parity with forced rebuilds.

* test(go): exclude impossible owners with unknown method constraints

Use real parsing to cover impossible owner edges and valid owners hidden by impossible competitors.

* test(go): pin filename rules and unknown constraint overlap

Document Go first-dot filename behavior and verify impossible known constraints in both operand orders.

* test(go): register incremental ownership coverage across platforms

Include the new database-backed Go ownership suite in the cross-platform test list.

* test(go): schedule incremental ownership suite with native database tests

Complete PR #3559 review fixes. Local validation: 47 focused tests across five suites passed; build and source/test type checks passed. The full suite was interrupted without a result.

* refactor(ingestion): centralize worker owner hook forwarding

Pass the language provider into the private cached owner lookup instead of repeating four owner hooks at five call sites. Keep qualified-name selection explicit and preserve the exported helper signature.

Validation: CLI/shared build and test typecheck pass; repository lint has no errors; 591 tests pass with one skipped across 13 ownership and worker suites. Web typecheck is blocked by uninstalled web dependencies. Graph checks are unavailable because this checkout has no registered index.

* test(rename): add Go cross-file fixture module

Part of the cross-file method ownership regression for PR #3559. The completed fixture uses real indexing, public rename preview/apply, warm cache replay and post-rename reindexing. All 14 Go rename integration cases pass locally.

* test(rename): add cross-file fixture before/types.go

* test(rename): add cross-file fixture before/methods.go

* test(rename): add cross-file fixture before/callers.go

* test(rename): add cross-file fixture after/go.mod

* test(rename): add cross-file fixture after/types.go

* test(rename): add cross-file fixture after/methods.go

* test(rename): add cross-file fixture after/callers.go

* Add test case for renaming pointer receiver method

Complete the real persisted-index regression fixture for PR #3559. The type, pointer receiver method and callers are in separate Go files. Public rename preview/apply must make exactly four edits across the structural interface family while preserving an unrelated same-name method, comments and strings.

The fixture checks six exact ownership, interface and call edges before rename, after warm parse-cache replay and after reindexing the edited sources. All 14 Go rename integration cases pass. Formatting and the CLI typecheck pass. Graph impact/detect-changes could not run because this checkout has no registered index.

---------

Co-authored-by: System administrator <root@nixos-infra.home>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
2026-10-15 10:36:13 +00:00
Gergő Magyar
a665031c96
fix(lbug): diagnose staged-copy embedding failures, round max DB size (#3570)
* fix(lbug): round GITNEXUS_LBUG_MAX_DB_SIZE up to a power of two

The native buffer manager rejects any max DB size that is not a power of
two, but the env parser accepted any positive integer, so a value such as
300000000000 failed at open and was then reported with a misleading
"set a larger limit" hint.

Round a positive safe integer up to the next power of two and warn once
naming the raw and effective values. Values that are not safe integers
now fall back to the 16 GiB default.

Refs #3529

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* feat(lbug): add remedies for the address-space ceiling and past-EOF read

Add two pure classifiers beside bufferPoolExhaustionRemedy. They parse only
what the engine message states, label the byte count as the limit the engine
reported (not the configured value), and name GITNEXUS_ATOMIC_INCREMENTAL=0
only for runs that knob changes. Neither asserts why the failure occurred.

Refs #3529, #3530

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* feat(lbug): add size-evidence formatting for failure diagnostics

formatFileEvidence is a pure formatter over stat-shaped input (apparent
size, allocated blocks, raw statfs f_type), so sparse and regular cases are
testable without a real sparse file. describeFileEvidence wraps it, never
throws, and reports a missing file as unavailable.

Refs #3530

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(analyze): honor GITNEXUS_ATOMIC_INCREMENTAL=0 and classify staged failures

GITNEXUS_ATOMIC_INCREMENTAL was only read as === '1', so the documented =0
mitigation did nothing for watch and auto-sync, which pass atomicIncremental
as an option. An explicit =0 now beats the caller's request. Full rebuilds
and the escalation to staging still stage and are unaffected.

In the analyze catch block, snapshot the live and staging files before the
checkpoint driver stops and the database closes (closing can checkpoint the
staging file), classify the error once, then log the remedy and the held
evidence for a size-ceiling or past-EOF failure. The off-switch is named
only when the failed run was an atomic-incremental staged write. A max-size
message the classifiers do not recognise keeps the generic hint, and the
original error is rethrown unchanged. The atomic-incremental staging log
line now records the staged file size.

Refs #3529, #3530

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs: document max DB size rounding and GITNEXUS_ATOMIC_INCREMENTAL

Note that GITNEXUS_LBUG_MAX_DB_SIZE must be a power of two and is rounded
up, add GITNEXUS_ATOMIC_INCREMENTAL (1 and 0, and which builds 0 does not
affect) to both README env tables, and add a Troubleshooting entry for the
two intermittent embedding write-back failures and the evidence lines GitNexus
now logs for them.

Refs #3529, #3530

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(review): apply review findings

Review fixes:
- Label the GITNEXUS_LBUG_BUFFER_POOL_SIZE=0 sentinel in the failure
  evidence line instead of printing "buffer pool 0 B".
- Replace FailureRemedyContext {staged, offSwitchApplies} with a single
  StagedBuildMode ('in-place' | 'staged-rebuild' | 'staged-incremental'),
  removing the { staged: false, offSwitchApplies: true } illegal state.
- Re-attach the LBUG_MAX_DB_SIZE doc comment to the exported constant.
- Cover the in-place classified failure through runFullAnalysis, and the
  buffer-pool sentinel label, with new tests.

Also carries the simplification pass: failure evidence is collected only for
a classified failure, the staged-build flag is reused, the env var is read
once, and the evidence tests share one temp-dir helper.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(lbug): bound failure-evidence stats and record checkpoint activity

Review findings #1 and #3 on #3570.

describeFileEvidence raced nothing: a stat on a stalled 9p/NFS/virtiofs
mount hung the analyze failure handler before the driver stopped, the
database closed and the original error was rethrown. Each stat/statfs now
has a 2000 ms deadline and fails open; a missing file reads "absent"
instead of "unavailable", a stalled one reads "unavailable (timed out ...)".

collectFailureEvidence (new) is the single evidence collector: it reads
the checkpoint activity snapshot and dispatches every stat in one
Promise.all before its first await, covering the live index, the staging
copy and its .wal/.shadow/.wal.checkpoint sidecars. That is what lets a
#3530 report tell a short main file from pages pending in the sidecars or
from a CHECKPOINT GitNexus itself ran just before the failing DELETE.

runCheckpointWithRetry now records completed count, last completion time
and in-flight count. Both the periodic driver tick and checkpointOnce (the
staged window-start CHECKPOINT) go through it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(lbug): state the off-switch cost, pin the rounded max size, isolate ambient env

Review findings #5 (note), #6 (wiring) and #11 on #3570.

offSwitchNote now says that GITNEXUS_ATOMIC_INCREMENTAL=0 can leave the
live index partly written after a failed in-place write, and that the next
run then rebuilds it in full.

A new test stubs GITNEXUS_LBUG_MAX_DB_SIZE=300000000000, reloads
lbug-config and asserts the native Database constructor receives 2 ** 39
and that exactly one rounding warning is logged. The existing tests all
called the parsers directly and matched the constructor argument with
expect.any(Number), so reverting the wiring left the suite green.

vitest.config.ts sets GITNEXUS_ATOMIC_INCREMENTAL to the empty string
(neither '0' nor '1', i.e. unset) like GITNEXUS_MEMORY, so an exported =0
no longer switches off every staging test.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(analyze): carry the failure diagnosis in the error message and label escalated runs

Review findings #2, #4, #5, #7, #8 and the run-analyze half of #6 on #3570.

#4: the remedy and `Failure evidence` lines were only sent to onLog, which
`analyze --watch` wires only with GITNEXUS_VERBOSE=1 and the auto-sync
launcher drops - the only two callers that request atomic-incremental
staging. They are now appended to the rethrown error's message in place
(identity and prototype preserved, native text first so classifiers
anchored on it still match), which every caller prints. A thrown value
that is not an Error falls back to a log. Auto-sync truncated that message
to 240 characters before logging it; the log now allows 2000 while the
persisted summary stays short.

#8: remedy delivery is best effort, so a throwing onLog sink or an
unwritable message can no longer replace the native error.

#2: escalatedFullWrite is declared above the try, and an escalated
atomic-incremental run is classified as a rebuild. Its remedy no longer
points at GITNEXUS_ATOMIC_INCREMENTAL=0, which does not stop the
escalation from staging.

#5: when GITNEXUS_ATOMIC_INCREMENTAL=0 overrides a caller that requested
staging, the run logs one line saying so and what a failed write costs.

#7: the stage-time size line uses the same "staging copy" label as the
failure evidence.

#6: tests pin the evidence-before-driver-stop-before-close order, the exact
configured max DB size in the evidence, and the appended text against the
substring classifiers in the CLI and auto-sync.

The READMEs describe the new evidence lines, ask reporters to include the
stage-time line, and name GITNEXUS_WAL_MANUAL_CHECKPOINT=0 as the bisect
knob for the checkpoint hypothesis.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Address PR review feedback (#3570)

- wal-checkpoint-driver: count a checkpoint as completed only when
  tryFlushWAL actually ran one. It returns false when no connection is
  open, and the failure evidence renders the count as "N completed".
- auto-sync runner: an oversized native error now logs its head and tail
  (1000 characters each) so the appended failure diagnosis, which is always
  the tail, survives. The persisted 240-character summary is unchanged.
- lbug-config: the max-size remedy said GITNEXUS_LBUG_MAX_DB_SIZE "must be
  a power of 2", but non-powers are rounded up. It now says so, as do the
  matching lines in gitnexus/README.md.
- failure-evidence and file-evidence tests use the default registered
  temp-dir prefix, so the stale-sidecar sweep recognises their fixtures.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Address PR review feedback (#3570)

- run-analyze: stringify the thrown value through a helper that cannot
  throw, so an exotic throw (null-prototype object, throwing toString)
  cannot abort the failure handler before it stops the driver, closes the
  database and reclaims the staging copy.
- run-analyze: a classified non-Error throw is wrapped in an Error (original
  kept as `cause`) so the diagnosis travels in the message like every other
  case, instead of in a log that the auto-sync launcher drops. This removes
  the separate log fallback.
- auto-sync runner: the oversized-error log keeps head and tail within the
  2000-character cap; the separator no longer pushes it to 2003.
- lbug-config: the max-size rounding warning prints the operator's value as
  supplied (300000000000.9), not the integer it floored to.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Address PR review feedback (#3570)

- lbug-config: the max-size remedy's rounding example was itself a power of
  two. It now shows a value being rounded: 300000000000 becomes 549755813888.
- auto-sync-runner test: the comment said the whole log line is capped at
  2000 characters; the assertion covers the error payload after the prefix.
- extension-loader test: pin that the installer child is handed the rounded
  max DB size for a non-power-of-two override. The installer prefers that
  argument over the env var and has its own non-rounding parser, so this is
  what keeps a valid override working there.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Address PR review feedback (#3570)

- Keep the whole failure diagnosis in auto-sync's capped log line: the
  tail now reserves the remedy and evidence lines (with a 240-char floor
  for the native head) instead of an even head/tail split.
- Count only this run's checkpoints in the failure evidence: snapshot the
  process-global activity when the run begins and report the difference,
  so an earlier `analyze --watch` refresh no longer leaks in.
- Diagnose classified failures thrown while opening the staging copy, via
  helpers shared with the write-path catch.
- Halt checkpoint ticks before measuring failure evidence: start
  `walCheckpointDriver.stop()` (which clears its timer synchronously)
  before the stats, then await the drain before close.

Note: pre-existing timeouts in run-analyze-fts-repair ("fails repair mode
when no base meta exists", "abandons a pending set that fails
EMBEDDING_RESUME_MAX_ATTEMPTS times in a row") reproduce on the unchanged
PR head on this host and are not addressed by this commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-15 10:43:26 +01:00
Gergő Magyar
fa70fd8343
chore(deps): consolidate ten Dependabot updates and fix compatibility (#3592)
* chore(deps): consolidate Dependabot GitHub Actions updates

* chore(deps): consolidate web updates and secure transitive dependencies

* fix(web): preserve diagram appearance with Mermaid 12

* test(ci): align workflow security tests with updated action pins

* fix(ci): split coverage across eight shards to avoid job timeout

CI run 38693066214 cancelled Ubuntu coverage shard 1 after 25 minutes while tests were still passing. The missing coverage blob then caused the execution audit and CI gate to fail.

Increase only the coverage shard count from four to eight. Keep the timeout, full suite, coverage thresholds, and execution audit intact.

Validation: all 1,247 test files form a complete, disjoint eight-shard partition using the configured Vitest sequencer; 117 targeted tests passed (2 existing skips); workflow generator, Prettier, concurrency validation, and diff checks passed.

* fix(ci): leave headroom for Windows test shards

Run 38697469283 exhausted the 20-minute Windows watchdog. Use ten platform shards while retaining eight coverage shards and all existing timeouts, coverage gates, and execution audits. The accompanying timing refresh and recorded-profile regression keep all 145 platform-sensitive test files covered exactly once.

* fix(ci): refresh underestimated Windows suite timings

Refresh eight materially underestimated timing weights using Windows runs 38697469283 and 38693066214. The old partition placed native suites ahead of cli-e2e with insufficient time left under the watchdog. Keep every suite and the partitioning algorithm unchanged.

* test(ci): replay the Windows timeout workload

Add a deterministic regression from recorded Windows CI timings, independent of the scheduling table. It failed before the fix with a 1,426-second shard and now protects three minutes of watchdog headroom.

Validation: 118 targeted tests passed (2 existing skips); typecheck, formatting, workflow generation, concurrency and diff checks passed. Independent review found no actionable issues. All 145 platform test files are selected exactly once; replaying the complete observed profile gives a 973-second maximum across ten shards. Hosted CI remains the final elapsed-time check.
2026-10-15 10:43:04 +01:00
Gergő Magyar
cae60c2bd4
fix(mcp): reject corrupt query identities and refresh index metadata (#3571)
Some checks are pending
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
CodeQL / Analyze (python) (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
Trivy Image Scan / Trivy (gitnexus-cli) (push) Waiting to run
Scorecard / Scorecard analysis (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-web) (push) Waiting to run
* fix(mcp): reject corrupt query identities and refresh index metadata

* fix(mcp): preserve reader and search integrity

Keep replaced readers unknown until matching metadata is published.
Defer shared-handle refresh until other consumers release the old graph
to avoid rebuilding connections against the same stale generation.

Propagate identity corruption after both hybrid search lanes settle,
so the sibling cannot query after its database session is released.
Select the regressions for the OS matrix and retain Python coverage
without optional Swift grammars.

Validation: 393 focused tests, nine native generation tests and ten
race executions across five fresh processes pass. Build and source/test
typechecks pass. The early full run passed 26,096 tests and failed eight:
seven reproduce on baseline; the mixed-source publication case passes
in clean reruns. Windows/macOS native execution remains for CI.

Graph analysis maps all edited production symbols; coverage remains
partial for the anonymous FTS test callback, manually reviewed.

Refs #3571

* fix(lbug): bump @ladybugdb/core to 0.21.2 to stop doubled rows after delete and re-copy

LadybugDB 0.21.0 and 0.21.1 return every row of a table that spans more
than one native vector twice once the incremental writeback has DETACH
DELETEd it and a COPY into an earlier table has run. NodeGroup::scan let a
morsel that ended before the group's first live row wrap an unsigned
subtraction and rescan to the end of the group (LadybugDB #1085, fixed in
0.21.2). No primary key error fires. The identity guard from #3442 stops
the run with "unexpected or duplicate ID", so a Swift edit that pulls every
importer into the write set failed on repos with more than 2048 structs.
Only unreleased main was affected: 1.6.12 ships 0.18.3.

Pin 0.21.2 in package.json, update the six @ladybugdb/core entries in the
lockfile, and move coreVersion in the vendored FTS manifest. The FTS
extension stays at 0.21.0 because no v0.21.1 or v0.21.2 artifact is
published; the pairing assertion and its unit tests pass.

Add a regression to the delete-nodes-for-files suite: 2049 structs with
CONTAINS edges are loaded, every file is deleted, the graph is loaded
again, and each id and edge must appear exactly once.

Verification (Linux, Node 22.18):
- lbug-delete-nodes-for-files: 11/11 on 0.21.2. With the 0.21.1 native
  packages swapped in, the new test fails with 4098 rows instead of 2049.
- Reporter recipe end to end on the built CLI: incremental analyze exits 0
  with no duplicate ids on a Swift-heavy fixture and on a 70-file Python
  fixture, with and without FTS. On 0.21.1 the Swift fixture exits 1.
- A 0.21.1-written database opens and reads under 0.21.2.
- prettier, eslint and typecheck:tests are clean on the changed files.
- The full lbug-db project had not finished when this was committed.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* test(fts): say what the Windows warm-session branch covers

On Windows the repair step calls poolClose, which removes the pool entry
before the in-place writer opens. The step therefore checks the backend's
cached capability state, not a live pool connection. The comment now says so
instead of implying the pool stays warm. No behavior change.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* revert: take the @ladybugdb/core 0.21.2 bump out of this PR

Reverts 0cdc3dfe3. The bump fixes LadybugDB 0.21.0 and 0.21.1 returning every
row of a large table twice after a delete and re-copy, but on Windows it
crashes the vendored FTS extension, which is still the v0.21.0 build: four of
eight Windows shards failed with exit code 3221225477 (0xC0000005) in tests
that load libfts and build an FTS index. All eight passed on 9d79092ab with
core 0.21.1. A Windows extension is only published for v0.21.0, not for
v0.21.1 or v0.21.2.

The bump moves to its own draft PR (#3578) until a matching Windows
extension exists. This PR returns to its original query-integrity and
index-freshness scope.

Restores gitnexus/package.json, the six @ladybugdb/core entries in
package-lock.json, the coreVersion in vendor/lbug-fts/manifest.json, and
removes the regression test that belongs with the bump. All four files are
identical to origin/main (1b4e3f0a8) after this commit.

Verification:
- git diff origin/main for the four files is empty.
- fts-artifact-coverage and vendored-extension-path unit tests pass (31),
  and assert-publish-fts-coverage reports core 0.21.1 paired with extension
  0.21.0.
- The graph check on the staged revert was partial, because it only deletes
  test code. The forward change was gated clean: 4 files, 6 symbols, all in
  that test, no affected processes.
- Windows CI has not run on this commit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 15:06:26 +01:00
Parafee41
1b4e3f0a81
fix: use merge-base in regression review guidance (#3514) 2026-10-14 10:53:15 +03:00
Gergő Magyar
8fa8e64388
fix(rename): extend safe refactoring and flow coverage across languages (#3557) 2026-10-13 08:38:17 +03:00
Gergő Magyar
191a954bf6
fix(python): resolve calls through module-returning accessors (#3542)
Some checks failed
Trivy Image Scan / Trivy (gitnexus-cli) (push) Has been cancelled
Trivy Image Scan / Trivy (gitnexus-web) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Gitleaks / gitleaks (push) Has been cancelled
Publish / Classify release event (push) Has been cancelled
Scorecard / Scorecard analysis (push) Has been cancelled
Publish / RC guard (marker + release-PR skip) (push) Has been cancelled
Publish / ci (push) Has been cancelled
Publish / Publish to npm (push) Has been cancelled
Publish / Build & Push RC Docker images (push) Has been cancelled
* test(accuracy): retire repaired Python accessor gaps

* fix(python): connect module accessor resolution

* fix(python): resolve calls through module-returning accessors

Bind `_pc().target()` and `m = _pc(); m.target()` to the module's
function when a local accessor returns an imported module, and count
capped-out dropped names in the impact lower bound.

Closes #3497

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

* refactor(python): share module-accessor position key (#3542)

- Reuse the capture-side positionKey in the receiver namespace resolver
  instead of a second line:col helper plus an inline template.
- Note why the synthetic { moduleScope, scopes: [] } input is sufficient
  for createNamespaceTargetCache (sealed disk-backed ParsedFile shape).

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

* refactor(python): reuse subtype-dispatch positionKey (#3542)

- Export the existing line:col positionKey from subtype-dispatch instead of
  defining an identical copy in module-accessors, so both Python capture
  side channels key positions through one helper.
- Apply prettier to the Function-scope indexing line.

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

* fix(ci): unique test titles and rebaseline Python benches (#3542)

- impact-epistemic-lower-bound: `%j` rendered null, NaN and Infinity all as
  `null`, so the test-completeness audit rejected the duplicate identities.
  Use `%s` so every parameterized case has a distinct title.
- python-scope: capture fingerprint changes with the new module-accessor
  capture facts (golden captures were already updated).
- receiver-resolution: +4 Python call drops (125 -> 129). The two-step
  `x = f(); x.m()` form is now counted as an unresolved call instead of
  vanishing: fastapi-depends `router.get/post` (unknown, x3) and
  python-method-chain-binding `user.get_city()` (in-program; `User` has no
  `get_city`, so the site is genuinely unresolvable).

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

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 18:41:51 +01:00
Gergő Magyar
ecb444b4c8
chore(deps): consolidate ten Dependabot updates (#3554) 2026-10-10 16:16:16 +00:00
Gergő Magyar
a532e08ef9
fix(deps): make tree-sitter peer dependencies install cleanly (#3555)
* fix(deps): make tree-sitter peer installs clean

Keep the eight audited lockfile peer ranges consistent with the bundled tree-sitter 0.25.1 runtime and apply the existing manifest preparation during postinstall. Ordinary and strict npm installs resolve without peer warnings.

* docs: explain audited tree-sitter peer maintenance

* fix(deps): pin audited tree-sitter peers to 0.25.1

* fix(deps): normalize audited peers to the exact runtime

* docs: clarify exact tree-sitter runtime peer pins

* test(deps): cover exact peer pins and existing-install migration

Verify exact 0.25.1 peers, repeatable preparation, and migration from the previously widened peer metadata.

* fix(deps): support pnpm symlinks in bundle preparation (#3555)

Follow package symlinks and pnpm sibling dependency containers. Deduplicate real paths to avoid revisiting aliases or cycles while preserving the audited manifest and duplicate-instance checks.

Validated with strict npm ci, both typechecks, npm pack, a real pnpm layout, and a pnpm-installed tarball parsing all 19 grammars on main and worker threads.

* test(deps): cover pnpm layout and symlink cycles (#3555)

Exercise real package symlinks, transitive sibling dependencies, a self-cycle, metadata drift before writes, and rejection of distinct duplicate grammar instances.

The original script fails the pnpm regressions; the updated script passes all 10 bundle tests.

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

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-10-10 13:01:20 +00:00
Gergő Magyar
999cc9f913
fix(deps): upgrade native tree-sitter to 0.25.1 (#3531)
* fix(deps): upgrade native tree-sitter to 0.25.1

* fix(tree-sitter): preserve sync loading and update verified capture baselines

Route C# scope queries through the synchronous native grammar loader so the compiled analyze module remains require-compatible on Node 22.18. Refresh only the audited empty-Python-module and renamed-PHP-fixture captures, and pin the runtime assertion to 0.25.1.

Validated 479 targeted tests, all 16 scope-capture benchmark cases, Python capture/import guards, compiled C# worker parsing, build, typecheck and formatting. Performance budgets are unchanged.

* fix(tree-sitter): refresh upstream vendors and preserve parser semantics

* fix(ci): refresh prebuilds and support Windows ARM

Refresh macOS, Linux ARM, and Windows x64 grammar binaries from the successful native CI builds. Pin node-gyp 12.4.0 so the Windows ARM jobs recognize Visual Studio 2026.

Use local Git filtering for E2E to avoid PR-files API timeouts on generated parser diffs.

Validation: 143 focused tests, Actionlint, and all 16 scope-capture benchmark checks passed. Full npm test run started; native database suites still running.

* fix(ci): refresh Windows ARM grammar prebuilds

Import all seven Windows ARM grammar artifacts from successful native build run 37965761760. Artifact filenames and SHA-256 hashes verified; all 42 native build jobs passed.

Validation: 31 prebuild coverage tests passed.

* fix(bench): stabilize scope capture timing guard

Warm each input size seven times and use 21 median samples while retaining isolated timing blocks. Yield between languages so native finalizers release allocations outside the measured sections. Keep all fixture sizes, fingerprints, scaling formulas, and budgets unchanged.

Validation: all 16 language guards passed with a 2 GB heap limit (1.38 deep-chain ratio; 1518 MB peak RSS). Linear and quadratic controls passed their expected guard outcomes. Formatting and graph change analysis passed. Full npm test is running without failures so far.

* fix(parser): reduce TypeScript capture traversal cost

* fix(test): await parser worker readiness before teardown

* fix(parser): load C# synchronously in workers

* fix(grpc): resolve native proto detections against their own file

With the native proto grammar active, sibling .proto files that declare
the same short service name under different packages tied in the
directory-based resolveProtoConflict heuristic and both providers were
dropped. A proto-origin detection already knows its defining file, so
use that file's entry before falling back to the heuristic.

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

* ci(packaging): assert native grammars load from the installed tarball

The packaged-install smoke only ran `gitnexus --version`, so a grammar
that failed to load from the published package (bundled runtime, patched
peer manifests, vendored prebuilds, C# sync loader, Protobuf wrapper)
would ship silently; the dev-tree ABI smoke also accepts vendored
grammars that report unavailable. Parse a sample for every registered
grammar plus the native Protobuf plugin from the installed package, on
the main thread and in a worker thread.

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

* ci(tree-sitter): track compatibility workarounds instead of 0.25 readiness

The daily readiness report still targeted tree-sitter@0.25.0, so after the
upgrade it would keep reporting "Blocked" and never close its tracking issue.
Repurpose it to track what we carry for the bundled runtime: derive the target
from the package.json pin, list each pack-time peer patch from
prepare-tree-sitter-bundle.cjs with its drop condition (bump, wait for an
upstream release, transitive, or intentionally pinned), and reword the
buckets. The workflow adopts the issue opened under the old title.

Also update the grammar-update-monitor header and auto-PR text, which still
described the 0.21.1 runtime and a tree-sitter-c hold.

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

* test(dart): assert both nested labels target the loop; fix Zig call-shape doc

The nested-label CFG test only jumped to `outer` and checked reachability,
which still passes when a jump is retargeted to the inner loop (its exit
reaches the outer header). Jump to both labels and assert the exact
`continue` edges; dropping the inner label now fails the test.

Update the Zig callable-flow comment: call_expression now wraps actuals in a
required `arguments:` field.

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

---------

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 13:07:59 +03:00
Gergő Magyar
4756e8a820
fix(release): gate publication on accuracy and paired evaluation (#3503)
* test(release): add fixed-answer native tool accuracy

* fix(release): gate stable artifacts on pinned paired evaluations

Apply review findings #1-4: gate Docker publication, grade in-flight retries, preserve repository context, and execute negative controls in CI.

* fix(eval): verify native context and resolve harness security findings

Inspect Claude's first startup reminder for ordinary repository guidance.
Bound launcher-option matching and escape Markdown backslashes and pipes.
Exclude only the parsed synthetic accuracy corpus from CodeQL; keep the
benchmark harness and evaluator under security analysis.

Validated focused Python and TypeScript regressions plus core typecheck.

* fix(eval): wake the EC2 runner and prove paired evaluator execution

Bootstrap the existing dedicated instance from a protected hosted job, bound
native runner pickup, and stop only instances started by this run. Keep paid
sessions inside the fixed stop window and add a runner-only dispatch.

Require a contained six-cell prepare/session/oracle/report canary in CI,
including a failed repair that remains in the measured denominator.

* fix(ci): reuse existing configuration and disambiguate accuracy cases

Remove the new AWS credential/settings path and release opt-in variable. Bound native runner pickup with the existing GitHub token and retain private EventBridge startup until its existing mechanism can be reused. Reuse current workflow environment names and evolution schedule controls.

Name malformed-observation cases explicitly so the execution audit distinguishes null from missing and actually tests invalid arrays.

* fix(review): isolate release builds and preserve benchmark evidence

* fix(release): gate RC publication on paired quality and manage EC2 lifecycle

* fix(ci): clarify release shell redirects and build script

* fix(eval): remove temporary patch sinks after capture

* fix(bench): retire tool-accuracy allowances repaired on main

Main at 50aa4be3b repaired three #3487 route checks (#3505) and all four
#3499 Python scope checks (#3502, #3504). The ratchet correctly failed the
merged head with stale allowances, so remove them and keep the fixed answers
as release protection: 18/31 pass, 13 recorded gaps remain.

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

* fix(release): gate RCs on accuracy only and keep paid runs for stable

Follow the cost split proposed in discussion #3493: fixed-answer tool
accuracy on every RC, paired agent runs before stable releases and on a
weekly schedule against the latest RC.

RC publication no longer prepares a bundle, calls release-evaluation.yml
and waits for a paid run of up to 21 hours on the shared EC2 lock. Every
release attaches this run's accuracy report; stable npm publication still
requires exact-commit paired evidence. release-evaluation.yml drops its
workflow_call path and the now-unused candidate bundle module.

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

* fix(release): address PR #3503 review feedback

- Page through recent release-evaluation runs instead of reading only
  the newest 50, so valid stable evidence cannot be pushed off page one.
- Bound each runner-pickup jobs request by the remaining deadline.
- Replace non-finite floats at any depth in failure receipts so the
  incomplete report still serializes with allow_nan=False.
- Clarify that the summary.cap case has 501 names over 1001 sites.

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

* fix(review): harden candidate build and close review gaps

- Mount the candidate checkout's .git read-only inside the build sandbox,
  so lifecycle scripts cannot plant git config (e.g. core.fsmonitor) that
  host git later runs in that checkout during actions/checkout cleanup.
  The real-Bubblewrap canary now also attempts that write.
- Type tool-accuracy observations instead of using explicit any.
- Cover the fail-closed branches reviewers found untested: unsafe or
  missing evidence artifacts, mismatched task pins, malformed repo/SHA,
  an instance that stops again during bootstrap, and unbalanced GitNexus
  guidance markers.

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

* docs(release): describe RC accuracy gate and stable evidence step

- CONTRIBUTING now states that RCs are gated by CI (including the
  fixed-answer tool-accuracy check) without a paid run, and that stable
  publication needs a passing Release evaluation for the exact commit
  within seven days.
- The oracle-control fixture passes tarfile's data filter only where it
  exists (3.11.4+), matching the declared Python 3.11 floor.

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

* refactor(bench): pin tool-accuracy fixture line anchors in one place

run.ts bucketed rename edits and explain findings by line literals that
expectations.ts duplicated. Export FIXTURE_ANCHORS (file, line, pinned text)
from expectations.ts, build the fixed answers and run.ts classifiers from it,
and fail loudly (runner and unit test) when a fixture line no longer holds
the pinned text. Expected answers and observations are unchanged.

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

* fix(bench): fail closed when ripgrep is missing from the tool-accuracy run

rename's text-search pass shells out to rg and only logs a degraded warning
when it is absent, so a runner without ripgrep scored a degraded rename
(homonym.ts:1 missing) and still passed. Check rg --version before indexing,
record it in accuracy.json source.externalTools, and install ripgrep in the
ci-tests tool-accuracy job and the docker release-gate (same if: condition).

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

* refactor(eval): split baseline guidance, share bwrap preamble, drop dead bare option, harden patch cleanup

- Move the baseline (no-GitNexus) guidance scrubbing out of proposer_sandbox.py
  into baseline_guidance.py, with its unit tests.
- Expose real_directory, runtime_mount_args and bwrap_base_args publicly so
  release_build no longer imports private helpers or re-assembles the shared
  bubblewrap preamble; the candidate build command is byte-identical.
- Remove the unused run_claude `bare` parameter and its --bare/--tools branches.
- capture_patch: a failed temporary-directory removal no longer discards the
  read patch or replaces an earlier error; it is attached as a note, or warned
  on stderr when there was no earlier error.

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

* fix(ec2-runner): keep stop observing through transient describe failures

- stop() treats a failed or timed-out describe-instances call as unknown
  state and keeps observing until the stop deadline; a persistent failure
  is still raised at the deadline with the last command error. Unusable
  states and identity mismatches still fail at once (new CommandError
  subclass separates command failures from semantic ones).
- Readiness CLI has one paid mode: --job-name NAME. --evolve is removed;
  skill evolution passes its job name, and tests tie the watchdog command
  to the paid job's actual name in both EC2 workflows.
- Jobs-API requests never get a timeout larger than the remaining pickup
  budget (previously rounded up to 1s past the deadline).
- Document that the shared concurrency group keeps only one pending run,
  so a queued release evaluation can be replaced and must be confirmed.

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

* docs(eval): record verified EC2 lifecycle configuration

The README still described the AWS settings as assumed and unverified.
The OIDC role, environment settings and runner_only lifecycle were
configured and verified live on 2026-10-09.

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

* fix(release-eval): grade both runtimes against one pinned task toolchain

Candidate and stable each staged task dependencies (node_modules,
gitnexus-shared/dist) from their own runtime checkout, so the same v1.6.12
task source was graded with different TypeScript, Vitest and LadybugDB
versions and a per-task solve delta also measured dependency drift.

- Check out and build the pinned task commit once (tasks-base) and point
  every task's repo at it for both runtimes; the runtime under test reaches
  sessions only through --gitnexus-root. prepare requires --task-repo at the
  single pinned task commit (new task-sha subcommand resolves it).
- Retain sandbox_dependency_content_digest per measured row and make
  release_gate fail when any task's cells, across candidate and stable, do not
  share one recorded dependency digest.
- Move the task-pin comparison into validate_report(task_pins=...) and use
  it from release_report check and release_gate.
- Cover the gate CLI with a missing and a corrupt candidate report.

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

* docs(ci): warn that a pending release evaluation can be replaced

GitHub keeps one pending run per concurrency group, so a newer queued
EC2 run cancels a pending release evaluation. Operators must confirm the
startup job ran before relying on the evidence.

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

* test(eval): prove hidden oracles against the grading toolchain

Release evaluation now grades every task with dependencies built at the
pinned task commit (TypeScript 5.9.3, Vitest 4.1.11), but the oracle
controls still ran against the current checkout's toolchain. The Ubuntu
containment job now builds the pinned task toolchain and points the
controls at it. All seven controls pass locally against that build.

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

* test(ci): pin the duplicated EC2 lifecycle jobs together

Both EC2 workflows carry their own copy of the live-verified start,
check, readiness and stop jobs. A reusable workflow would change that
verified job structure, so instead a test requires the copies to stay
identical apart from the job display name and the paid-job dependency.

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

* fix(release-eval): accept stable evidence only from main's current evaluator

Stable publish validated downloaded agent evidence against the release
commit's eval/ tree and never tied a report to the run that produced it.
Evidence from an older evaluator stayed acceptable for seven days after
graders changed, while task changes on main made every fresh evaluation
mismatch the tag. The first invalid artifact also hid older valid runs.

The composite action now extracts eval/ from main's head and runs the
validator there with locked base dependencies only (no dev extras or
project build). A report counts only when its harness_sha is the head_sha
of its trusted main run and the compare API shows no change under eval/,
the release-evaluation workflow or the pinned agent CLI between that
harness and the evaluator; a missing, diverged or 300-file comparison
fails closed. Runs are tried newest first, rejected runs are skipped
with a bounded reason list, every gh call has a timeout, and task pins
use validate_report's task_pins check.

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

* fix(eval): break the sandbox import cycle and resolve code-scanning alerts

- baseline_guidance is now pure text handling with its own GuidanceError;
  the baseline mount builder lives in proposer_sandbox again and converts
  that error to SandboxError, so imports run one way only.
- task_assets uses the public real_directory name; the unused private
  alias is gone.
- The oracle-control fixture always extracts with tarfile's data filter
  and skips on Pythons that lack it, instead of extracting unfiltered.

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

* fix(release-eval): run candidate lifecycle scripts offline; reject smuggled report fields

- build_candidate now downloads locked dependencies with --ignore-scripts,
  then runs every lifecycle script (dependency installs, prepare, build)
  in a fresh network namespace, so candidate code cannot reach host-local
  services. Verified locally that the current head and the pinned task
  commit build this way; the real-Bubblewrap canary now asserts only
  loopback is visible to a lifecycle script.
- validate_report requires the evidence document to equal its
  field-whitelisted rebuild, so per-run or top-level fields outside the
  published schema are rejected before the publisher copies the file.
- The sandbox test suite also covers a no-GitNexus sandbox refusing
  unbalanced guidance markers.

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

* docs(eval): describe the offline candidate lifecycle

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

* fix(release-eval): pin downloads to the npm registry; require dependency binding

Address review feedback on PR #3503:
- The candidate's online install phase now refuses lockfile entries that
  resolve outside https://registry.npmjs.org/ (other than in-checkout
  workspace links) and refuses shipped .npmrc files, so a candidate
  cannot steer npm at loopback, private or metadata endpoints.
- Every measured row must carry a 64-hex task-dependency digest, so a
  single report cannot be accepted with its grading toolchain unbound.
- Oversized JSON integers mark a measurement untrustworthy instead of
  crashing report generation.
- Baseline guidance stripping recognises headings with up to three
  leading spaces (CommonMark).
- Remove a stale comment about the old private helper name.

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

* fix(eval): parse CommonMark ATX headings; compare evidence by exact JSON

- Baseline guidance stripping now parses headings as CommonMark ATX
  headings (0-3 leading spaces, optional closing # run, tabs), so a
  GitNexus section heading like '## GitNexus rules ##' is removed too.
- Evidence validation compares the serialized rebuild with the report,
  so a retyped value (true for 1, 2.0 for 2) no longer passes.

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

* fix(eval): drop continuations of every CommonMark list item in baseline guidance

A removed GitNexus instruction left its indented continuation behind when
the item used '+' or an ordered marker (1. / 1)). The scrubber now
recognises every CommonMark list-item marker.

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

* fix(eval): isolate candidate MCP from agent task writes (#3503)

Run MCP in a nested Bubblewrap boundary with read-only task, graph,
registry and runtime mounts, private state and isolated processes/network.
Keep task writes on the agent's built-in tools and remove mutating MCP grants.

Add startup/tool mutation canaries and preserve explicit unsafe diagnostics.

Validation: focused pytest 138 passed, 16 skipped. Full locked evaluator
996 passed, 29 skipped; real containment canaries require Ubuntu CI.
Note: eight pre-existing comparator-reuse failures reproduce on the
unchanged head due to missing os.supports_dir_fd support. One process-control
timeout failed in the full run and passed alone and on the unchanged head.

* fix(eval): close baseline mount overlap and test symlink evidence (#3503)

Reject supplied no-MCP mounts that cover forbidden GitNexus paths, including ancestor mounts and lexical aliases. Keep ordinary dependency mounts available.

Exercise evidence symlink rejection with a real valid-report target and retain dangling-link coverage.

Validation: 1026 evaluator tests passed, 29 skipped; targeted mount tests 36 passed and evidence tests 34 passed. Removing the symlink guard in memory makes the repaired regression fail. Ruff and diff checks passed.

Note: eight pre-existing comparator-reuse failures remain in this environment because os.supports_dir_fd lacks the required os.lstat support.

---------

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-10 08:26:08 +01:00
Gergő Magyar
82347f0f07
fix(scope): resolve local imports by lexical ownership (#3532) 2026-10-10 08:13:55 +03:00
azizur100389
50aa4be3b2
fix(routes): prefer production handlers and preserve app.all (#3505)
Some checks failed
Trivy Image Scan / Trivy (gitnexus-cli) (push) Has been cancelled
Trivy Image Scan / Trivy (gitnexus-web) (push) Has been cancelled
Gitleaks / gitleaks (push) Has been cancelled
Publish / Classify release event (push) Has been cancelled
Scorecard / Scorecard analysis (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Publish / Build & Push RC Docker images (push) Has been cancelled
Publish / RC guard (marker + release-PR skip) (push) Has been cancelled
Publish / ci (push) Has been cancelled
Publish / Publish to npm (push) Has been cancelled
2026-10-08 23:53:55 +03:00
azizur100389
ff922c0a3b
fix(python): resolve calls through aliased package re-exports (#3504) 2026-10-08 13:51:20 +03:00
Parafee41
4ccba12004
fix(scope): keep nested declarations out of module bindings (#3502) 2026-10-08 11:05:41 +03:00
Gergő Magyar
e230914189
chore(deps): consolidate eight dependabot updates (#3525) 2026-10-08 08:19:42 +03:00
Christian C. Berclaz
672fc72f56
fix(dart): capture package metadata portably during repository scan (#3465)
Some checks failed
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
CodeQL / Analyze (python) (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
2026-10-06 18:23:08 +03:00
Gergő Magyar
dd096e690c
chore(deps): consolidate open dependabot updates (#3496) 2026-10-06 07:23:35 +00:00
Younes Beriane
047354c3f0
fix(community): run Leiden in a worker so its timeout can fire (#3478) 2026-10-06 09:40:21 +03:00
Gergő Magyar
df49f90889
fix(ci): require every test to execute across the CI matrix (#3479) 2026-10-06 07:34:17 +03:00
Gergő Magyar
e8a09d067b
fix(search): reject incomplete FTS repairs and verify worktree lookup (#3475)
Some checks are pending
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
CodeQL / Analyze (python) (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
2026-10-05 13:19:10 +00:00
rgb-vgx
dbcfa63d40
fix(group): match Go framework imports exactly and follow bare-block group writes (#3473) 2026-10-05 13:14:03 +01:00
azizur100389
10947d4b52
fix(setup): preserve existing HTTP GitNexus MCP entries (#3460) 2026-10-05 06:19:46 +01:00
Gergő Magyar
c474a811ba
fix(test): align fixtures and mocks with current types (#3471) 2026-10-05 04:47:37 +01:00
rgb-vgx
504bff7102
fix(group): join gin/echo route-group prefixes and accept method-value handlers in Go HTTP providers (#3458)
Some checks are pending
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
CodeQL / Analyze (python) (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
2026-10-04 12:55:41 +01:00