Commit graph

1166 commits

Author SHA1 Message Date
Mick Cooney
37efc888fc fix(r): flag an unreadable DESCRIPTION as truncated and tighten three R test assertions
An unreadable DESCRIPTION left RPackageConfig.truncated false, so a
qualifier naming the package it declares was classed external and its
call site dropped. The sibling hidesUndiscoveredPackage case already
treats an unreadable DESCRIPTION as unknown; do the same here and cover
it with a test.

Tighten three weak test assertions: the escaped-bracket export pattern
now asserts its exact match results, the S4 anchors test proves each
generic is defined exactly once, and the worker owner-absence test
fails on any defined ownerId, including an empty string.
2026-10-07 15:20:38 +01:00
Mick Cooney
3b478e4c46 fix(r): attach S4 slots to the Class argument instead of the first string argument
extractS4Fields and getRTopLevelPropertyOwnerName named the owner of a
setClass/setRefClass slot from the first string-valued argument, so
setClass(contains = "Base", Class = "A", representation(x = "numeric"))
attached slot x to Base. Select the owner with isRNamingArgument(arg, 'Class'),
the same choice the scope query and definition hook make.

Both owner paths share one helper so the field metadata and the ownerNameHint
agree.
2026-10-07 15:19:30 +01:00
Mick Cooney
257f9430dc Merge remote-tracking branch 'upstream/main' into g1/rehearsal-merge 2026-10-07 10:14:08 +01: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
Mick Cooney
084d4f158e Merge upstream/main into R language support 2026-10-06 14:45:53 +01: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
Parafee41
ced9660e77
fix(augment): recover symbols missed by FTS file ranking (#3422) 2026-10-05 08:27:59 +01:00
azizur100389
10947d4b52
fix(setup): preserve existing HTTP GitNexus MCP entries (#3460) 2026-10-05 06:19:46 +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
Gergő Magyar
1a5d88391c
fix(mcp): reject corrupt impact and context identities (#3466) 2026-10-04 10:52:01 +01:00
Gergő Magyar
16d7e9477b
fix(embeddings): reuse completed vectors after interrupted analyze (#3463) 2026-10-04 09:26:02 +01:00
Mick Cooney
7ce3ea6230 fix(r): bound total exportPattern matching work per package-config load
Each exportPattern matcher has its own work cap, but nothing bounded how many
patterns a repository may carry, so a NAMESPACE with 200 pathological patterns
cost about 77 s of analysis and one with tens of thousands of cheap patterns
cost minutes and gigabytes.

loadRPackageConfig now creates one SharedWorkBudget per call and a sub-budget
per package. Every matcher draws on its package's sub-budget and on the load's:
state visits spent matching (100M per load, 30M per package) and NFA states kept
by compiled patterns (500k per load, 100k per package). A pattern that does not
fit the state allowance is refused before its NFA is fully built, and the first
refusal closes the allowance so later patterns are refused without being parsed.
Once the matching budget is spent, refineRExportStatus and the R import resolver
stop calling the matchers. Refused and cut-short patterns take the existing
drop-and-warn path (export nothing), with at most 50 named per package and one
summary line for the rest. A hostile package can therefore not starve the
packages after it. Budgets count work units, so the outcome is deterministic.
Benign monorepos spend a negligible fraction of every budget.
2026-10-04 02:06:38 +01:00
Gergő Magyar
649be2c482
Merge branch 'main' into codex/embedding-checkpoint-3456 2026-10-03 17:55:00 +01:00
Gergő Magyar
c51bad71fa
docs(search): explain model-specific vector cutoff tuning (U1) (#3462) 2026-10-03 15:22:34 +00:00
azizur100389
07b5c27045 fix(embeddings): defer staged checkpoint count until publication 2026-10-03 12:09:27 +01:00
Abhishek B R
a47cd17f27
fix(config): honor nested .gitignore files during repository walks (#3440) 2026-10-03 09:55:47 +00:00
articultur
d1971cf953
fix(communities): omit memberships for filtered singleton communities (#3447) 2026-10-03 08:25:35 +00:00
Ankit Verma
4f298d0ac0
fix(staleness): detect rollback with one Git query (#3445) 2026-10-03 07:42:26 +00:00
articultur
668fac7635
fix(search): report partially missing FTS indexes in query results (#3448) 2026-10-03 07:36:27 +01:00
Gergő Magyar
f99dde8aa3
fix(mcp): discover positional SDK tool registrations (#3450)
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-02 22:57:23 +00:00
azizur100389
a8f18f00b9
fix(swift): avoid false calls for injected closure properties (#3434) 2026-10-02 23:31:14 +01:00
Gergő Magyar
dad3b8f6f2
fix(mcp): reject invalid symbol identities before graph reads (#3451) 2026-10-02 21:39:31 +01:00
Gergő Magyar
412446408d
fix(index): guard graph integrity and fail closed on incomplete risk (#3442) 2026-10-02 15:34:26 +01:00
Mick Cooney
684cdc12b2 fix(r): select the naming argument in the scope query's import and class declarations
The R scope query took the name of a setClass/setRefClass class and of a
source/library/require import from the call's first argument. A named first
argument was taken as the name (library(lib.loc = libO, pkgP) imported libO,
setClass(contains = "Base", Class = "A") declared Base), and a comment before
the first argument hid it (the import was lost, and a class declared after a
comment had no EXTENDS edge to VIRTUAL or to its base).

Capture every candidate argument and let the scope emitter keep only the one
that names the class or import: the argument spelled with the call's first
formal (Class, package, file), otherwise the first unnamed argument, with
comments and named arguments allowed before it. The selection is the one the
S4 definition captures already use, and reads each argument list once, so cost
stays linear in the argument count; a query-level prefix that skips leading
comments would be quadratic.

The parse-cache version bump already made for the unreleased S4 definition fix
covers the changed scope captures too, so no further bump is made.
2026-10-02 09:59:54 +01:00
Mick Cooney
1f1d0ff9aa fix(r): anchor S4/RefClass definition patterns to the first string argument
The setClass/setRefClass, setGeneric and setMethod definition patterns matched
any string-valued argument of the call, so every extra string minted a node:
contains = "VIRTUAL" a Class VIRTUAL, valueClass = "numeric" a Function numeric,
and the class in setMethod("show", "Foo", ...) a Method Foo (with a
HAS_METHOD Foo -> Foo edge).

Keep only the argument that names the definition, chosen by the R provider's
shouldSkipDefinitionCapture hook: the argument spelled with the call's first
formal in any position (Class for setClass and setRefClass, name for
setGeneric, f for setMethod), otherwise the first unnamed argument, which
comments and named arguments may precede. A named formal stops a later unnamed
string from also being taken.

The choice is made in code because a query-level prefix that skips leading
comments and named arguments is quadratic in the argument count on every call
in the file. The code reads each argument list once, so cost stays linear, and
a bounded-time test guards it. The slots/fields/representation pattern is keyed
on named arguments only and is unchanged. The EXTENDS edge to VIRTUAL never
depended on the spurious node: scope resolution mints the single placeholder
Class itself.

SCHEMA_BUMP is incremented because the definitions are parse-time captures
replayed from the warm cache. Characterisation tests that pinned the spurious
Method and HAS_METHOD edge are corrected.
2026-10-02 09:37:57 +01:00
Mick Cooney
a7ec43dbc6 refactor(r): remove five dead patterns from R_QUERIES
The S4/R5 contains= (single and c()), R6 inherit= (namespaced and bare)
and (comment) patterns capture @heritage*, @comment, which no code
reads: such a match has no @name and no @definition.*, so the worker
discards it. Inheritance edges come from the R scope query's
@reference.inherits.

Graph nodes, relationships, properties, resolution outcomes and the raw
worker output are byte-identical over the r-* fixtures and probe repos
before and after, so no re-analyse and no SCHEMA_BUMP are needed.

Also correct the R scope query header, which described the legacy table
as having proved the heritage shapes.
2026-10-01 13:37:58 +01:00
Mick Cooney
b03684cbde fix(r): scope a roxygen @param type to a formal of the documented function
The tag name was never checked against the function's formals and the type was
bound in the scope that contains the assignment, so a documented parameter
typed that name in every function of the file. The type is now bound per
formal, inside the function that owns it, and only for a formal of the
function the roxygen block documents.

Also pin the line-start anchor with a case that fails without it, and a tag
name that merely starts with `param`.
2026-10-01 13:37:58 +01:00
Mick Cooney
165cf12508 fix(r): bind a roxygen @param type only from an anchored form naming a local class
A @param description is free prose, but the first word of any capitalised
description was bound as the parameter's type (`@param df Data frame ...`
gave `df: Data`). A type is now bound only when the description is the type
alone or starts with it in braces, and the type names an R6, S4 or RefClass
class defined in the same file. Tags are read only at the start of a roxygen
line and a description runs to the next tag.

Remove the unwired extractReturnType, which took the first word of @return the
same way.
2026-10-01 13:37:58 +01:00
Mick Cooney
f5e0ea374d refactor(r): keep packageDirs for the locality fallback only
The packageDirs loop inside rOwningPackageDir could only matter when one
package directory sits inside another package's R/ directory, and no test
could observe it. NAMESPACE ownership now reads packages and NAMESPACE
directories only; rFileBelongsToDiscoveredPackage adds packageDirs for the
<name>/R/ locality fallback, where the same-name-copy test pins it. A new
test checks that discovery populates packageDirs.
2026-10-01 13:37:58 +01:00
Mick Cooney
c8823b566b fix(r): ignore the <name>/R/ locality fallback for files a discovered package owns
rQualifierLocality treated a qualifier as a local package when any parsed
file sat under a directory of that name followed by R/, even when discovery
had attributed the directory to a package with a different Package: name.
The directory name is now evidence only for files no discovered package owns.
2026-10-01 13:37:58 +01:00
Mick Cooney
2d3335927b fix(r): scope NAMESPACE export refinement to each package's R/ directory
refineRExportStatus matched a file against the package directory, so
functions in tests/, vignettes/ and inst/ were marked not exported although
R never loads them into the namespace, and a nested package without a
NAMESPACE inherited the enclosing package's. Ownership now comes from the
nearest discovered package whose R/ directory holds the file
(rOwningPackageDir), over every directory discovery read a DESCRIPTION in.

library() of a root-level package resolved to nothing because its directory
'' is falsy in resolveRImportInternal; it now resolves to the package's R/
files like a nested package.
2026-10-01 13:37:58 +01:00
Mick Cooney
98ac287601 fix(r): skip renv, packrat, revdep and .Rcheck trees in package discovery
Installed libraries and check output hold one DESCRIPTION per third-party
package. Discovery treated them as repository content: a renv project
library below the depth limit flagged discovery as truncated, which made
every pkg::fn() qualifier unknown, and a shallow copy became a local
package with no parsed files.

The main walk and the hidden-package scan now share one predicate that
skips a directory whose name is exactly renv, packrat or revdep, or ends in
.Rcheck after at least one character. Look-alike names are still searched.
2026-10-01 13:37:58 +01:00
Mick Cooney
fb6fbff036 fix(r): rank duplicate package directories by whole path
Among same-depth directories declaring one package name, the winner was
decided by breadth-first walk order, which compares path segment by
segment (a/x before a-b/x). Compare the whole relative path by code unit
instead (a-b/x before a/x), so the winner no longer depends on how the
walk happens to meet the directories, and update the comments to say so.
2026-10-01 13:37:58 +01:00
Mick Cooney
6f4f85bcc3 fix(r): make package discovery independent of readdir order
Package discovery used the filesystem's directory listing order, so the
200-directory cap visited different directories, and a package name
declared in several directories resolved to a different directory, on
different filesystems. Read every directory in code-unit name order and
keep the first package seen for a name: the shallowest directory, then the
path that sorts first. A root-level package is no longer replaced by a
nested copy of the same name.
2026-10-01 13:37:58 +01:00
Mick Cooney
12ba50217a fix(r): keep large exportPattern alternations and warn when a pattern is dropped
The linear-time exportPattern matcher refused anything over 1,024 states or
4,096 characters, so a legitimate `^(f1|...|f80)$` or `^[[:alpha:]]{1,2000}$`
compiled to nothing and every name in the package read as unexported, with no
diagnostic.

Raise the caps to 16,384 states and characters, and bound the hostile case by a
per-matcher work budget instead: a matcher counts the states it visits and, once
40 million are spent (about 0.4 s), answers false for names it has not decided
and reports itself exhausted. Alternations of literals are built as a trie so
alternatives sharing a prefix share states, the start closure is looked up by
code unit, closures are iterative, and verdicts are memoised per distinct name.

Every non-empty exportPattern that is dropped, and every matcher that runs out
of budget, now produces one warning per pattern per package naming the package
directory, the first 60 characters of the pattern and the reason. The dropped
patterns are also kept on RNamespaceInfo.droppedExportPatterns.
2026-10-01 13:37:58 +01:00
Mick Cooney
84d2a8be4a fix(r): match exportPattern in linear time
exportPattern() text comes from the analysed repository and was compiled
to a backtracking RegExp, so a pattern such as ^(a+)+$ took 1.6 s on a
27-character name and minutes on a slightly longer one, hanging analyze.
R itself evaluates these with the non-backtracking TRE.

Compile the pattern to a Thompson NFA and simulate it instead, so a match
costs O(name length x NFA size) for any pattern. Constructs with no
linear-time algorithm (back-references, look-around) and patterns that
expand beyond a fixed state cap are dropped like an uncompilable pattern.
Verdicts for ordinary patterns are unchanged, checked against the
previous RegExp on a generated corpus.
2026-10-01 13:37:58 +01:00
Mick Cooney
c885001568 chore(r): remove remaining label pointers from code and tests
Rewrite comment and describe-title text that pointed at labels defined
nowhere in the repository and history-narrative wording that referred to
earlier work, stating each rule directly. No behaviour change; test counts
are unchanged.
2026-10-01 13:37:58 +01:00
Mick Cooney
ce5041a64c chore(r): rewrite planning-note pointers in code and tests as self-contained text
Rewrite references to planning notes (section numbers, item labels, review
rounds, scenario/unit numbering) as self-contained statements of the rule or
trade-off. Comment, fixture comment and test-description text only; no
behaviour change.
2026-10-01 13:37:58 +01:00
Mick Cooney
3dbc46f00c chore(r): make comments, test names and docs self-contained
Replace issue-number references in comments, test names and descriptions with
self-contained wording, drop merge-coordination notes from the SCHEMA_BUMP
history, and rename a fixture file to qualified_use.R. Comment,
description and file-name changes only.
2026-10-01 13:37:58 +01:00
Mick Cooney
d18d24e408 style(r): format namespace-imports and parse-worker with the pinned prettier 2026-10-01 13:37:58 +01:00
Mick Cooney
4bdacd539e fix(r): treat a completed package scan with zero packages as proving pkg:: calls external
loadRPackageConfig returned null when discovery found no package, and
rQualifierLocality maps a null config to unknown, so in a repo with no
DESCRIPTION anywhere dplyr::filter() still bound to a local filter through
the name guess. Return an empty config instead: its truncated flag now
distinguishes a complete scan (external) from one that may have missed a
package (unknown, name guess kept).
2026-10-01 13:37:58 +01:00
Mick Cooney
d2b3c2497d docs(r): document qualifier-aware call resolution and its limits 2026-10-01 13:37:58 +01:00
Mick Cooney
463626572b fix(r): flag package discovery as truncated only when a skipped subtree hides an undiscovered package
Discovery set RPackageConfig.truncated whenever it skipped any directory
(depth-3 limit) or hit the 200-directory cap, so nearly every real repo
(tests/testthat/fixtures, inst/extdata, ...) counted as truncated. Qualified
calls to outside packages were then classified unknown and kept, leaving the
dplyr::filter() bound to a local filter() case unfixed.

Skipped directories and the cap leftover queue are now collected and scanned
by hidesUndiscoveredPackage (iterative DFS, global 5000-directory budget,
skipping node_modules, .git, .Rproj.user). truncated is set only when that
scan finds a DESCRIPTION whose Package: name is not already discovered,
exceeds the budget, or hits an unreadable path; an unreadable directory in
the main walk still truncates.
2026-10-01 13:37:58 +01:00
Mick Cooney
1b53efb12d feat(r): resolve pkg::fn to local package definitions and veto contradicting name guesses
The scope query now captures the qualifier of `pkg::fn()` / `pkg:::fn()`; use it.

- qualified-call.ts (new): parseRQualifier, a tri-state rQualifierLocality
  (local / external / unknown) and populateRQualifiedCalls, wired after the
  NAMESPACE import synthesis in R's populateWorkspaceReferences.
  * external package (discovery complete): the site is dropped, so no tier
    can guess an edge for it;
  * local package with exactly one top-level definition of the name: bound
    precisely (0.85) through resolveQualifiedFreeCall, keyed by file + start
    position;
  * local package with two or more definitions: the site is dropped;
  * local package with none (re-export) or unknown locality: unchanged.
- package-config.ts: RPackageConfig.truncated is set when the directory cap,
  the depth limit or an unreadable directory left discovery incomplete, so a
  package is only called external when the scan was complete.
- isRGlobalNameFallbackPlausible: a candidate inside the named local package
  is allowed, one elsewhere is vetoed when the package defines the name.
- Flip the tests that pinned the pre-fix name-only results and drop the
  temporary pins and it.fails markers of the step-1 tests.

No shared-core changes.
2026-10-01 13:37:58 +01:00
Mick Cooney
ed9d602e80 feat(r): capture the pkg:: qualifier on namespaced calls
Capture the whole namespace_operator of pkg::fn() and pkg:::fn() calls as
@reference.qualified-name so the qualifier reaches site.rawQualifiedName and
survives the parse cache. On its own this changes no graph output: no R
consumer reads the qualifier yet.

SCHEMA_BUMP is incremented because warm ParsedFiles lack the new capture.
2026-10-01 13:37:58 +01:00
Mick Cooney
d902526f6b refactor(ingestion): stop writing the R-only ownerId property onto every language's definition nodes
The node-property ownerId spread in the parse worker was added with R
support and is never read for non-R languages; upstream's worker never
wrote it onto definition nodes. R never had it either (its owner is
attached post-parse). Symbol ownerId and HAS_METHOD/HAS_PROPERTY edges
are unchanged.
2026-10-01 13:37:58 +01:00
Mick Cooney
c96fc05c1b refactor(r): compute ownerNameHint in definitionPropertiesExtractor; drop dead owner plumbing
Move R's deferred-owner hint out of the shared parse worker into R's
definitionPropertiesExtractor (rDefinitionProperties), and remove the
worker-side hint block, the node/symbol ownerNameHint spreads,
ParsedSymbol.ownerNameHint and the R extractor imports. Delete the dead
hasRoxygenExport branch from rExportChecker (both branches returned true).
2026-10-01 13:37:58 +01:00