Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ A patch for one regression and two reports from downstream projects.
- **The HTML export is reproducible** and no longer embeds the builder's
workspace path (#1104).
- **Robot Framework suites count as evidence** (#1105).
- **Marker attribution and ignore-file scope tightened** (REQ-405, REQ-407).

### Upgrade note

Markers inside gitignored or symlinked directories no longer count as
evidence. List such paths in a `.rivetignore` negation (`!path`) or move them,
and run `rivet coverage --tests` before and after upgrading to compare.

### Security
- **wasmtime 48.0.6 → 48.0.7** (RUSTSEC-2026-0378, RUSTSEC-2026-0379) — a
Expand Down Expand Up @@ -46,6 +53,16 @@ A patch for one regression and two reports from downstream projects.
Artifact pages also wrote `data-source-file` as an absolute path of the
building machine; a static export now writes it relative to the project root,
while `rivet serve` and the VS Code webview keep the real path they open.
- **Marker attribution and ignore-file scope tightened** (REQ-405, REQ-407) —
a Robot marker is named after a test case only inside `Test Cases`, `Tasks`
or `Keywords` sections (any case, singular or plural, any number of `*`);
under `Settings` or `Variables` it falls back to `file:line` instead of
taking the neighbouring setting as its name. The marker walk reads ignore
files from the project root down to each scanned directory and no longer
reads any above the project root, so a stray `.gitignore` in a home
directory cannot hide evidence. `.ignore`, `.git/info/exclude`, the
global-ignore opt-out and the symlink-loop guard now have tests that fail
when the behaviour is reverted.

### Added

Expand Down
4 changes: 2 additions & 2 deletions artifacts/requirements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10283,7 +10283,7 @@ artifacts:
title: marker scanning walks the whole tree, follows symlinks and ignores .gitignore, so validate takes hours on a repo with symlinks to large external trees (#1097)
status: verified
release: v0.41.1
description: "Since v0.41.0 every command that computes coverage or verification (validate, coverage, context, MCP reload) scans source files for rivet: verifies markers (REQ-389 A1). test_scanner::scan_directory used Path::is_dir, which follows symlinks, consulted no ignore file and had no cycle guard; on WSL2 a project with symlinks into the Windows drive (376k files) did not finish validate in minutes to hours. ACCEPTANCE: the marker walk does not enter symlinked directories (no cycles), honours .gitignore, .ignore, .git/info/exclude and a project .rivetignore, keeps the existing skips, and finds exactly the same markers on a tree without symlinks; tests in the module cover each case with a negative control."
description: "Since v0.41.0 every command that computes coverage or verification (validate, coverage, context, MCP reload) scans source files for rivet: verifies markers (REQ-389 A1). test_scanner::scan_directory used Path::is_dir, which follows symlinks, consulted no ignore file and had no cycle guard; on WSL2 a project with symlinks into the Windows drive (376k files) did not finish validate in minutes to hours. ACCEPTANCE: the marker walk does not enter symlinked directories (no cycles), honours .gitignore, .ignore, .git/info/exclude and a project .rivetignore, keeps the existing skips, and finds exactly the same markers on a tree without symlinks; tests in the module cover each case with a negative control. Ignore files above the project root are not read."
tags: [scanning, performance, regression]
fields:
category: functional
Expand Down Expand Up @@ -10313,7 +10313,7 @@ artifacts:
title: "rivet: verifies markers in Robot Framework files (.robot, .resource) are not scanned (#1105)"
status: verified
release: v0.41.1
description: "The marker scanner mapped only Rust, Python, C/C++, JS/TS, Go and shell files to comment styles, so a project whose tests are Robot Framework suites got no verification credit and a higher warning count. ACCEPTANCE: .robot and .resource files are scanned with # comments; a marker before or inside a Robot test case or keyword is attributed to that case; a module test with Robot fixtures fails when the extension mapping is removed."
description: "The marker scanner mapped only Rust, Python, C/C++, JS/TS, Go and shell files to comment styles, so a project whose tests are Robot Framework suites got no verification credit and a higher warning count. ACCEPTANCE: .robot and .resource files are scanned with # comments; a marker before or inside a Robot test case or keyword is attributed to that case; a module test with Robot fixtures fails when the extension mapping is removed. Markers outside Test Cases/Tasks/Keywords sections fall back to file:line."
tags: [scanning, testing]
fields:
category: functional
Expand Down
19 changes: 13 additions & 6 deletions rivet-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8361,7 +8361,8 @@ impl ReadinessCtx {
// Source markers are `verifies` evidence by another route (REQ-329);
// without them a marker-verified requirement would read as missing
// its verification rule.
let markers = rivet_core::test_scanner::scan_source_files(
let markers = rivet_core::test_scanner::scan_source_files_in_project(
&cli.project,
&default_marker_scan_paths(&cli.project),
&rivet_core::test_scanner::default_patterns(),
);
Expand Down Expand Up @@ -9882,7 +9883,8 @@ fn cmd_stats_qualification(cli: &Cli) -> Result<bool> {
/// Scanning takes seconds on a large tree, so only commands that compute
/// coverage or verification call this, not every project load.
fn marker_verified_ids(project: &std::path::Path) -> std::collections::BTreeSet<String> {
rivet_core::test_scanner::scan_source_files(
rivet_core::test_scanner::scan_source_files_in_project(
project,
&default_marker_scan_paths(project),
&rivet_core::test_scanner::default_patterns(),
)
Expand Down Expand Up @@ -10281,7 +10283,11 @@ fn cmd_verify(cli: &Cli, id: &str, scan: &[std::path::PathBuf], dry_run: bool) -
} else {
scan.to_vec()
};
let markers = test_scanner::scan_source_files(&paths, &test_scanner::default_patterns());
let markers = test_scanner::scan_source_files_in_project(
&cli.project,
&paths,
&test_scanner::default_patterns(),
);
let marker_hits: Vec<&test_scanner::TestMarker> = markers
.iter()
.filter(|m| m.target_id == id && m.link_type == "verifies")
Expand Down Expand Up @@ -10719,7 +10725,8 @@ fn cmd_coverage(
.collect();
if !uncovered.is_empty() {
let paths = default_marker_scan_paths(&cli.project);
let markers = rivet_core::test_scanner::scan_source_files(
let markers = rivet_core::test_scanner::scan_source_files_in_project(
&cli.project,
&paths,
&rivet_core::test_scanner::default_patterns(),
);
Expand Down Expand Up @@ -11327,7 +11334,7 @@ fn cmd_coverage_tests(cli: &Cli, format: &str, scan_paths: &[PathBuf]) -> Result
};

let patterns = test_scanner::default_patterns();
let markers = test_scanner::scan_source_files(&paths, &patterns);
let markers = test_scanner::scan_source_files_in_project(&cli.project, &paths, &patterns);
let coverage = test_scanner::compute_test_coverage(&markers, &store, Some(&schema));

if format == "json" {
Expand Down Expand Up @@ -19006,7 +19013,7 @@ fn cmd_import_results_junit(
defaults
};
let patterns = test_scanner::default_patterns();
let markers = test_scanner::scan_source_files(&scan_paths, &patterns);
let markers = test_scanner::scan_source_files_in_project(&cli.project, &scan_paths, &patterns);

let runs = parse_junit_xml_with_markers(&xml, &markers)
.with_context(|| format!("failed to parse JUnit XML from {}", file.display()))?;
Expand Down
2 changes: 1 addition & 1 deletion rivet-core/src/links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ mod tests {
assert!(from_c.is_empty(), "leaf has no reachables, got {from_c:?}");
}

// Verifies: REQ-406
// rivet: verifies REQ-406
// Backlinks were collected in store (HashMap) order, so the incoming-link
// table differed from run to run (#1104). They are now ordered by link
// type, then source id, whatever order the store yields.
Expand Down
Loading
Loading