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
|
model is emitted as versioned JSON for other tools, including a future Fold
|
||||||
integration.
|
integration.
|
||||||
|
|
||||||
The default extractor uses pinned Tree-sitter grammars for Rust, Dart, C/C++,
|
The default extractor uses pinned Tree-sitter grammars for Rust, Dart, C
|
||||||
JavaScript/JSX, and TypeScript/TSX. Python and Swift retain the lexical preview;
|
(`.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
|
P4_16 retains its separate lexical and optional pilot paths. Declarations are
|
||||||
Syntactic evidence. Calls, imports, and inheritance retain Heuristic target
|
Syntactic evidence. Calls, imports, and inheritance retain Heuristic target
|
||||||
resolution with backend, confidence, and source location, independently of
|
resolution with backend, confidence, and source location, independently of
|
||||||
|
|
@ -32,8 +32,16 @@ Layer Fold findings onto the building:
|
||||||
--json fold.brick.json \
|
--json fold.brick.json \
|
||||||
--html fold.brick.html
|
--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 `..`
|
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
|
accepted only beneath the model's scan root (including existing filesystem
|
||||||
aliases whose canonical targets are beneath that root); leading traversal and unrelated
|
aliases whose canonical targets are beneath that root); leading traversal and unrelated
|
||||||
suffix paths remain diagnostics. Findings for excluded, generated, or genuinely
|
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
|
Macro expansion, overload resolution, dynamic dispatch, generated code, and
|
||||||
full package/build-system resolution remain outside the default frontend.
|
full package/build-system resolution remain outside the default frontend.
|
||||||
Malformed syntax produces diagnostics; recoverable sibling facts remain visible.
|
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,
|
Its score is not proof of correctness, maintainability,
|
||||||
or security. Use the component metrics and evidence records; do not rank teams
|
or security. Use the component metrics and evidence records; do not rank teams
|
||||||
or repositories by the composite alone.
|
or repositories by the composite alone.
|
||||||
|
|
||||||
Resolution respects language, file, declaration ownership, and lexical namespace.
|
Grammar-based resolution respects language, file, declaration ownership, and
|
||||||
Relative JS/TS and Dart imports resolve against the importing directory; missing
|
lexical namespace. Relative JS/TS and Dart imports resolve against the importing
|
||||||
paths never fall back to unrelated basenames. Explicit JS/TS named/default import
|
directory (Dart `package:<own package>/` against `lib/`); missing paths never
|
||||||
bindings, module-scoped Rust grouped/aliased imports, and module-qualified Rust
|
fall back to unrelated basenames. Explicit JS/TS named/default import bindings,
|
||||||
public calls can resolve across files.
|
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
|
C++ calls resolve through the include closure: a header prototype pairs with
|
||||||
its definition in another translation unit, lookup walks class (including
|
its definition in another translation unit, lookup walks class (including
|
||||||
in-repository bases) and namespace scopes outward, and `static`/anonymous
|
in-repository bases) and namespace scopes outward, and `static`/anonymous
|
||||||
definitions stay file-local. C++ and Rust member calls resolve only through an
|
definitions stay file-local. Declarations in `#elif`/`#else` branches stay in
|
||||||
explicitly declared receiver type (parameter, local, field, `this`/`self`,
|
the graph (`source.preprocessor-branch: alternative`) but are never call
|
||||||
smart pointer, or `Self`-returning constructor) and carry
|
targets, because Brick does not evaluate conditions; several `using`
|
||||||
`source.resolution`. Calls inside Rust expression macros (`assert!`, `format!`,
|
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`.
|
`vec!`, ...) are recovered by re-parsing and carry `source.extraction`.
|
||||||
Every unresolved call edge records `source.unresolved-reason`, and
|
Every unresolved call edge records `source.unresolved-reason`, and
|
||||||
`metrics.resolution` reports per-language call-site coverage. Ambiguous
|
`metrics.resolution` reports per-language call-site coverage; read the graph
|
||||||
targets stay external. Bare package specifiers, tsconfig aliases, Rust
|
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,
|
wildcard/block-local binding expansion, Cargo workspace module paths,
|
||||||
`compile_commands.json` include paths, and compiler-grade dispatch need further
|
`compile_commands.json` include paths, and compiler-grade dispatch need further
|
||||||
adapters. File fan-out remains an observation rather
|
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 |
|
| 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 |
|
| 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
|
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:
|
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/),
|
[C++](https://docs.rs/tree-sitter-cpp/0.23.4/tree_sitter_cpp/),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue