fix/audit-findings #5
2 changed files with 41 additions and 15 deletions
docs: state resolution rules and limits as the code now implements them
The audit found README claims the code did not back: resolution was said to respect lexical namespace everywhere (Python/Swift matched a repo-wide unique name, Rust types their leaf name), "ambiguous targets stay external" (not for rival using-directives or #else stubs), Dart imports were said to resolve (no Dart symbol ever did across files), and "C/C++" hid that C went through the C++ grammar. The README now describes the fixed behaviour and its remaining limits: per-language visibility rules (Python imports, Swift module-wide names, Dart imported libraries without show/hide), Rust type identity by declaring file, preprocessor alternatives excluded from resolution, using-directive ambiguity, the C grammar for .c, Fold report validation and producer-gated symbolic lane, lossy UTF-8 decoding, diagnostic counts and empty-scan reporting, check recomputing metrics, low call-site coverage on large C++ code, no virtual-override fan-out, and unrecognized Catch2 TEST_CASE bodies. The research note lists the pinned C grammar.
commit
46698cd87d
53
README.md
53
README.md
|
|
@ -6,8 +6,8 @@ elements, and dependency edges show calls, imports, and inheritance. The same
|
|||
model is emitted as versioned JSON for other tools, including a future Fold
|
||||
integration.
|
||||
|
||||
The default extractor uses pinned Tree-sitter grammars for Rust, Dart, C/C++,
|
||||
JavaScript/JSX, and TypeScript/TSX. Python and Swift retain the lexical preview;
|
||||
The default extractor uses pinned Tree-sitter grammars for Rust, Dart, C
|
||||
(`.c`), C++ (including headers), JavaScript/JSX, and TypeScript/TSX. Python and Swift retain the lexical preview;
|
||||
P4_16 retains its separate lexical and optional pilot paths. Declarations are
|
||||
Syntactic evidence. Calls, imports, and inheritance retain Heuristic target
|
||||
resolution with backend, confidence, and source location, independently of
|
||||
|
|
@ -32,8 +32,16 @@ Layer Fold findings onto the building:
|
|||
--json fold.brick.json \
|
||||
--html fold.brick.html
|
||||
|
||||
A report must be a SARIF log or a Fold findings report; anything else is an
|
||||
error. Findings keep Fold's symbolic lane only when the report names Fold as its
|
||||
producer (`tool.name` / `tool.driver.name`); other producers' findings are
|
||||
imported, never symbolic. Findings without a file location are diagnosed, and
|
||||
SARIF `file://` URIs are decoded before matching.
|
||||
|
||||
Fold artifact paths are normalized lexically across `/`, `\\`, `.`, and `..`
|
||||
components before exact repository-relative matching. Absolute paths are
|
||||
components before exact repository-relative matching; a path with `..` that
|
||||
exists in this checkout follows the filesystem instead, so `link/..` resolves
|
||||
through the symlink. Absolute paths are
|
||||
accepted only beneath the model's scan root (including existing filesystem
|
||||
aliases whose canonical targets are beneath that root); leading traversal and unrelated
|
||||
suffix paths remain diagnostics. Findings for excluded, generated, or genuinely
|
||||
|
|
@ -152,26 +160,43 @@ Brick extracts syntax, without compiler type checking or build configuration.
|
|||
Macro expansion, overload resolution, dynamic dispatch, generated code, and
|
||||
full package/build-system resolution remain outside the default frontend.
|
||||
Malformed syntax produces diagnostics; recoverable sibling facts remain visible.
|
||||
A file with invalid UTF-8 is decoded lossily with a diagnostic; files with NUL
|
||||
bytes are skipped as binary. `build` prints diagnostic counts, and a scan that
|
||||
finds no supported source says so. `check` recomputes metrics from the graph
|
||||
(stored metrics are never trusted) and fails a model with no scanned source.
|
||||
Its score is not proof of correctness, maintainability,
|
||||
or security. Use the component metrics and evidence records; do not rank teams
|
||||
or repositories by the composite alone.
|
||||
|
||||
Resolution respects language, file, declaration ownership, and lexical namespace.
|
||||
Relative JS/TS and Dart imports resolve against the importing directory; missing
|
||||
paths never fall back to unrelated basenames. Explicit JS/TS named/default import
|
||||
bindings, module-scoped Rust grouped/aliased imports, and module-qualified Rust
|
||||
public calls can resolve across files.
|
||||
Grammar-based resolution respects language, file, declaration ownership, and
|
||||
lexical namespace. Relative JS/TS and Dart imports resolve against the importing
|
||||
directory (Dart `package:<own package>/` against `lib/`); missing paths never
|
||||
fall back to unrelated basenames. Explicit JS/TS named/default import bindings,
|
||||
module-scoped Rust grouped/aliased imports, module-qualified Rust public calls,
|
||||
and public top-level Dart names from imported libraries can resolve across files
|
||||
(Dart `show`/`hide` combinators are not modelled). The lexical preview resolves
|
||||
Python names in the calling file, then in files it imports; Swift names in the
|
||||
calling file, then by a module-wide unique name (Swift files of one module see
|
||||
each other without imports).
|
||||
C++ calls resolve through the include closure: a header prototype pairs with
|
||||
its definition in another translation unit, lookup walks class (including
|
||||
in-repository bases) and namespace scopes outward, and `static`/anonymous
|
||||
definitions stay file-local. C++ and Rust member calls resolve only through an
|
||||
explicitly declared receiver type (parameter, local, field, `this`/`self`,
|
||||
smart pointer, or `Self`-returning constructor) and carry
|
||||
`source.resolution`. Calls inside Rust expression macros (`assert!`, `format!`,
|
||||
definitions stay file-local. Declarations in `#elif`/`#else` branches stay in
|
||||
the graph (`source.preprocessor-branch: alternative`) but are never call
|
||||
targets, because Brick does not evaluate conditions; several `using`
|
||||
directives that nominate different declarations make a call ambiguous. C++ and
|
||||
Rust member calls resolve only through an explicitly declared receiver type
|
||||
(parameter, local, field, `this`/`self`, smart pointer, or `Self`-returning
|
||||
constructor) and carry `source.resolution`. Rust types are identified by their
|
||||
declaring file, so same-named types in different modules resolve through the
|
||||
caller's `use` binding or stay ambiguous. Calls inside Rust expression macros (`assert!`, `format!`,
|
||||
`vec!`, ...) are recovered by re-parsing and carry `source.extraction`.
|
||||
Every unresolved call edge records `source.unresolved-reason`, and
|
||||
`metrics.resolution` reports per-language call-site coverage. Ambiguous
|
||||
targets stay external. Bare package specifiers, tsconfig aliases, Rust
|
||||
`metrics.resolution` reports per-language call-site coverage; read the graph
|
||||
with that coverage in mind (on a large C++ repository only a minority of call
|
||||
sites resolve). Ambiguous targets stay external. Virtual calls resolve to the
|
||||
declared type's method only (overrides are not fanned out), and Catch2
|
||||
`TEST_CASE` bodies are not yet recognized as functions. Bare package specifiers, tsconfig aliases, Rust
|
||||
wildcard/block-local binding expansion, Cargo workspace module paths,
|
||||
`compile_commands.json` include paths, and compiler-grade dispatch need further
|
||||
adapters. File fan-out remains an observation rather
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ change cycle, isolation, and fan metrics; no health weights are changed.
|
|||
| Rust const/impl | Const function, distinct type-owned methods, stable IDs after unrelated insertions; unresolved impl cannot create cyclic ownership |
|
||||
| Fold absolute alias | `src/fold.rs` tests existing root aliases while rejecting outside and excluded files; original default-tempdir test passes |
|
||||
|
||||
The grammar versions are pinned in Cargo.toml and Cargo.lock: C++ 0.23.4,
|
||||
The grammar versions are pinned in Cargo.toml and Cargo.lock: C 0.24.2 (`.c`
|
||||
files), C++ 0.23.4,
|
||||
JavaScript 0.25.0, TypeScript/TSX 0.23.2, Dart 0.2.0, Rust 0.24.2, with the
|
||||
Tree-sitter Rust runtime at 0.26.13. Upstream API/grammar references:
|
||||
[C++](https://docs.rs/tree-sitter-cpp/0.23.4/tree_sitter_cpp/),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue