Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
6d02597
Correct en-GB-oxendict spellings in code symbols and prose
leynos Aug 28, 2026
f692353
Document installer dependency module layout
leynos Sep 4, 2026
c9639a2
Document 0.3.0 API migration
leynos Sep 4, 2026
9222b5e
Fix lint-hardening review findings
leynos Sep 4, 2026
37d230f
Regenerate lockfile after rebase
leynos Sep 4, 2026
bfa2899
Parameterize executable permission tests
leynos Sep 4, 2026
06faa31
Pin SARIF wire keys and harden PATH discovery
leynos Sep 5, 2026
f1994ff
Ignore agent memory scratch directory
leynos Sep 8, 2026
284371b
Complete spelling migration contracts (#397-401)
Sep 26, 2026
82d1633
Preserve deliberate spelling contract terms
Sep 27, 2026
5538276
Document changed lint callbacks (#398)
Sep 27, 2026
3c2b61d
Bound compile-contract tests for CI (#401)
Sep 27, 2026
f51112c
Complete spelling review coverage
Sep 27, 2026
16e118b
Improve installer PATH diagnostics
Sep 27, 2026
87f3839
Consolidate PATH scan tests
Sep 27, 2026
7a52fe2
Refine spelling, tracing, and test helpers
Oct 14, 2026
05a4a47
Address PR #363 review findings
Oct 15, 2026
4fef0a4
Simplify tracing test structure
Oct 15, 2026
a1fcacc
Refresh lockfile and gate Unix tracing probe
Oct 15, 2026
233f60f
Test installer tracing through the real CLI (#363)
Oct 15, 2026
98ffa18
Clarify compile-contract test inventory
Oct 15, 2026
ac625ae
Reduce coverage build disk usage
Oct 15, 2026
8de12b2
Document PATH scan helper results
Oct 15, 2026
97750e5
Bound coverage profiles during nextest
Oct 15, 2026
d4571f2
Harden dependency checks and compile-contract tests
Oct 16, 2026
f3a457b
Resolve installer maintainability findings
Oct 16, 2026
5a78b24
Adopt directory-based module structure
leynos Aug 28, 2026
67dc727
Restore rustfmt-canonical layout in the extracted downloader tests
Sep 27, 2026
16ff229
Keep the deps test modules within the line budget
Oct 12, 2026
75957e4
Document the module layout and test placement rules
Oct 15, 2026
ea560b3
Add ADR 006 and correct a false enforcement claim
Oct 15, 2026
37ac0f4
Correct a false claim about workspace lint tables
Oct 15, 2026
0ee10b8
Correct two false module-layout claims
Oct 16, 2026
7ec1640
Drop a #[path] anchor broken by the rename
Oct 16, 2026
8d8c6e9
Fix workspace-lint violations across support crates
leynos Aug 28, 2026
fe2634a
Isolate lint declarations and clear remaining support-crate findings
leynos Aug 30, 2026
ef96f20
Fix UI harness and attribute parser findings
Oct 12, 2026
dc39990
Fix workspace-lint violations across support crates
leynos Aug 28, 2026
c5e8c02
Isolate lint declarations and clear remaining support-crate findings
leynos Aug 30, 2026
c1cd7e3
Fix UI harness and attribute parser findings
Oct 12, 2026
c598262
Bound Kani proofs and split AST properties
Oct 18, 2026
17bd339
Record bounded AST proof results
Oct 18, 2026
d325581
Split and bound Kani proof obligations
Oct 18, 2026
c0ef8c2
Use production MinHash lane in Kani proof
Oct 18, 2026
d3e62ec
Bound AST lowering and parser pins
Oct 19, 2026
eabfe1b
Correct proof coverage documentation
Oct 19, 2026
a20569e
Record exception and current CI evidence
Oct 19, 2026
6f57fc3
Clarify bounded Kani proof scope
Oct 19, 2026
e34f07a
Correct focused Kani run measurements
Oct 19, 2026
4f7b739
Size nested Cargo budgets and re-entrant test locking
Oct 19, 2026
15a29bc
Merge updated support-lint candidate
Oct 19, 2026
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
36 changes: 26 additions & 10 deletions .config/nextest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ default-filter = "not (binary(behaviour_toolchain) | binary(behaviour_cli) | kin
# cancels the run and discards the log that would have named the test.
slow-timeout = { period = "300s", terminate-after = 1, grace-period = "5s" }
# The whole run's budget. It sits above the largest per-test allowance below,
# so a test may spend its budget in full. The previous 75-minute run reached
# 1,840 of 1,842 tests before the nested SARIF API contract was still compiling.
# Ten more minutes give that remaining trybuild work room to finish.
# so a test may spend its budget in full. The previous 85-minute run reached
# 1,843 of 1,860 tests before the nested no-unwrap example build was cancelled;
# 17 tests remained unrun. The 120-minute budget gives that cold build and the
# rest of the suite room to finish after shared Cargo and compiler queues.
# See "Test timeouts: four tiers, outermost last" in the developers' guide.
global-timeout = "85m"
global-timeout = "120m"

# CI profile — run the full suite including slow installer tests.
[profile.ci]
Expand All @@ -32,7 +33,7 @@ default-filter = "not kind(example)"
# budgets that govern CI belong where a reader of this profile finds
# them.
slow-timeout = { period = "300s", terminate-after = 1, grace-period = "5s" }
global-timeout = "85m"
global-timeout = "120m"

[[profile.ci.overrides]]
# The toolchain auto-install behavioural tests may download and install a
Expand All @@ -44,11 +45,12 @@ test-group = "serial-toolchain-installs"
[[profile.ci.overrides]]
# Dylint UI harnesses build lint libraries; the default profile gives them
# the same allowance below. Compile-contract tests use the dedicated
# 45-minute override below.
# 60-minute override below.
# `whitaker-installer`'s binary is
# named `ui` but its test is not, so the `(binary(ui) & test(=ui))`
# clause does not reach it; it measured 235 s and timed out at 300 s on
# the Windows lane under the base allowance. A full workspace run also
# reached 9m56 in the trybuild harness while compiler admission queued.
# Keep that nested build bounded while leaving room to finish under contention.
filter = "test(driver::ui::) | test(tests::ui::) | test(ui::ui) | (binary(ui) & test(=ui))"
slow-timeout = { period = "20m", terminate-after = 1, grace-period = "5s" }
Expand All @@ -58,15 +60,15 @@ test-group = "serial-dylint-ui"
# Every discovered trybuild test builds fixtures through nested Cargo. Keep
# them under one build-sized allowance and avoid retries that repeat the work.
filter = "test(dependency_check_result_contract_is_public) | test(fixture_expansion_lint_attribute_contract) | test(normalize_settings_is_public_and_the_legacy_name_stays_removed) | test(renamed_common_apis_are_public_and_legacy_names_stay_removed) | test(renamed_sarif_api_is_public_and_legacy_names_stay_removed) | test(sha2_0_11_pre_migration_patterns_fail_to_compile) | test(trybuild_fixtures_compile_without_diagnostics)"
slow-timeout = { period = "45m", terminate-after = 1, grace-period = "5s" }
slow-timeout = { period = "60m", terminate-after = 1, grace-period = "5s" }
test-group = "serial-dylint-ui"
retries = 0

[[profile.ci.overrides]]
# The parser-pin fixtures run nested Cargo builds with isolated targets. Their
# longer allowance reflects a full interval spent queued for compiler slots.
filter = "binary(build_script_integration)"
slow-timeout = { period = "45m", terminate-after = 1, grace-period = "5s" }
slow-timeout = { period = "60m", terminate-after = 1, grace-period = "5s" }
test-group = "serial-nested-cargo-builds"

[[profile.ci.overrides]]
Expand All @@ -76,6 +78,13 @@ filter = "binary(no_default_features_build)"
slow-timeout = { period = "20m", terminate-after = 1, grace-period = "5s" }
test-group = "serial-nested-cargo-builds"

[[profile.ci.overrides]]
# Package-isolated checks can queue for shared cache and compiler resources;
# serialize them with the other nested builds.
filter = "test(crate_builds_without_dylint_driver_feature) | test(fluent_bundles_are_included_in_the_package_tarball)"
slow-timeout = { period = "30m", terminate-after = 1, grace-period = "5s" }
test-group = "serial-nested-cargo-builds"

# Serialize dylint UI tests that build lint libraries and use
# `#[serial]`. nextest runs each test in its own process, so the
# `serial_test` crate's in-process mutex has no effect. A test-group
Expand Down Expand Up @@ -129,22 +138,29 @@ slow-timeout = { period = "20m", terminate-after = 1, grace-period = "5s" }
# Every discovered trybuild test builds fixtures through nested Cargo. Keep
# them under one build-sized allowance and avoid retries that repeat the work.
filter = "test(dependency_check_result_contract_is_public) | test(fixture_expansion_lint_attribute_contract) | test(normalize_settings_is_public_and_the_legacy_name_stays_removed) | test(renamed_common_apis_are_public_and_legacy_names_stay_removed) | test(renamed_sarif_api_is_public_and_legacy_names_stay_removed) | test(sha2_0_11_pre_migration_patterns_fail_to_compile) | test(trybuild_fixtures_compile_without_diagnostics)"
slow-timeout = { period = "45m", terminate-after = 1, grace-period = "5s" }
slow-timeout = { period = "60m", terminate-after = 1, grace-period = "5s" }
test-group = "serial-dylint-ui"
retries = 0

[[profile.default.overrides]]
# These parser-pin and no-default-feature cases run nested Cargo builds in
# isolated targets; a cold build may queue behind admitted compiler work.
filter = "binary(build_script_integration)"
slow-timeout = { period = "45m", terminate-after = 1, grace-period = "5s" }
slow-timeout = { period = "60m", terminate-after = 1, grace-period = "5s" }
test-group = "serial-nested-cargo-builds"

[[profile.default.overrides]]
filter = "binary(no_default_features_build)"
slow-timeout = { period = "20m", terminate-after = 1, grace-period = "5s" }
test-group = "serial-nested-cargo-builds"

[[profile.default.overrides]]
# These isolated Cargo checks also wait for shared cache and compiler
# resources; serialize them with the other nested builds.
filter = "test(crate_builds_without_dylint_driver_feature) | test(fluent_bundles_are_included_in_the_package_tarball)"
slow-timeout = { period = "30m", terminate-after = 1, grace-period = "5s" }
test-group = "serial-nested-cargo-builds"

[[profile.default.overrides]]
# Serialize ignored exclusion integration tests when they are explicitly run.
# They build and stage the lint library before invoking `cargo dylint`, so they
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ jobs:
coverage-check:
if: github.event_name == 'pull_request'
runs-on: ubicloud-standard-2-ubuntu-2404
# Above the 85 m nextest global timeout plus a cold build and the work
# Above the 120 m nextest global timeout plus a cold build and the work
# either side of the suite. A ceiling merely above the suite's budget
# cancels the job before nextest can report the overrun, and a
# cancellation discards the log that would have explained it.
timeout-minutes: 120
timeout-minutes: 180
defaults:
run:
shell: bash
Expand Down Expand Up @@ -523,8 +523,8 @@ jobs:
# when the `ci` profile is selected, so the named toolchain and UI
# tests were bounded; what nothing bounded was every other test, the
# `ci` profile having declared no base `slow-timeout` of its own.
# The 120 m job ceiling includes the 85 m suite budget and cold setup.
timeout-minutes: 120
# The 180 m job ceiling includes the 120 m suite budget and cold setup.
timeout-minutes: 180
env:
# `windows-latest` is a 4 vCPU GitHub-hosted shape, so it does not share
# the Ubicloud constant used by the Linux lanes.
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/coverage-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ jobs:
# admits `main` alone; the codescene environment contract holds it to
# this job.
environment: codescene
# Above the 85 m nextest global timeout plus a cold build and the work
# Above the 120 m nextest global timeout plus a cold build and the work
# either side of the suite; kept in step with ci.yml's coverage lane.
timeout-minutes: 120
timeout-minutes: 180
defaults:
run:
shell: bash
Expand Down
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ thiserror = "2"
trybuild = "1.0.116"
log = "0.4.28"
sha2 = "0.11.0"
semver = "1.0.28"
tar = "0.4.44"
ureq = "3.2.0"
zstd = "0.14.0"
Expand Down
1 change: 1 addition & 0 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ glob = "0.3.3"
log = { workspace = true }
once_cell = { workspace = true }
parking_lot = { workspace = true }
temp-env = { workspace = true }
tempfile = "3.14.0"
thiserror = { workspace = true }
unic-langid = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions common/src/attributes/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl Attribute {
/// assert!(attribute.is_outer());
/// ```
#[must_use]
pub fn new(path: AttributePath, kind: AttributeKind) -> Self {
pub const fn new(path: AttributePath, kind: AttributeKind) -> Self {
Self {
path,
kind,
Expand Down Expand Up @@ -87,7 +87,7 @@ impl Attribute {
/// assert!(attribute.path().is_doc());
/// ```
#[must_use]
pub fn path(&self) -> &AttributePath {
pub const fn path(&self) -> &AttributePath {
&self.path
}

Expand Down
4 changes: 2 additions & 2 deletions common/src/attributes/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use rstest::rstest;

#[rstest]
#[case::empty(Vec::<String>::new())]
#[case::single(vec!["dead_code".to_string()])]
#[case::complex(vec!["cfg(feature = \"test\")".to_string(), "path(\"std::io\")".to_string()])]
#[case::single(vec!["dead_code".to_owned()])]
#[case::complex(vec!["cfg(feature = \"test\")".to_owned(), "path(\"std::io\")".to_owned()])]
fn attribute_with_arguments_preserves_inputs(#[case] arguments: Vec<String>) {
let attribute = Attribute::with_arguments(
AttributePath::from("allow"),
Expand Down
14 changes: 7 additions & 7 deletions common/src/brain_trait_metrics/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,44 +72,44 @@ impl BrainTraitDiagnostic {

/// Returns the evaluation disposition.
#[must_use]
pub fn disposition(&self) -> BrainTraitDisposition {
pub const fn disposition(&self) -> BrainTraitDisposition {
self.disposition
}

/// Returns the number of required methods.
#[must_use]
pub fn required_method_count(&self) -> usize {
pub const fn required_method_count(&self) -> usize {
self.required_method_count
}

/// Returns the number of default methods.
#[must_use]
pub fn default_method_count(&self) -> usize {
pub const fn default_method_count(&self) -> usize {
self.default_method_count
}

/// Returns the total method count (required + default).
#[must_use]
pub fn total_method_count(&self) -> usize {
pub const fn total_method_count(&self) -> usize {
self.required_method_count + self.default_method_count
}

/// Returns the sum of default method cognitive complexity values.
#[must_use]
pub fn default_method_cc_sum(&self) -> usize {
pub const fn default_method_cc_sum(&self) -> usize {
self.default_method_cc_sum
}

/// Returns the total number of trait items (methods + associated
/// types + associated consts).
#[must_use]
pub fn total_item_count(&self) -> usize {
pub const fn total_item_count(&self) -> usize {
self.total_item_count
}

/// Returns implementor burden (required method count).
#[must_use]
pub fn implementor_burden(&self) -> usize {
pub const fn implementor_burden(&self) -> usize {
self.implementor_burden
}
}
Expand Down
24 changes: 12 additions & 12 deletions common/src/brain_trait_metrics/evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,20 +84,20 @@ impl BrainTraitThresholds {
/// Total method count at or above which the warn rule's method
/// condition is met.
#[must_use]
pub fn methods_warn(&self) -> usize {
pub const fn methods_warn(&self) -> usize {
self.methods_warn
}

/// Total method count at or above which the deny rule triggers.
#[must_use]
pub fn methods_deny(&self) -> usize {
pub const fn methods_deny(&self) -> usize {
self.methods_deny
}

/// Default method CC sum at or above which the warn rule's
/// complexity condition is met.
#[must_use]
pub fn default_cc_warn(&self) -> usize {
pub const fn default_cc_warn(&self) -> usize {
self.default_cc_warn
}
}
Expand Down Expand Up @@ -138,7 +138,7 @@ pub struct BrainTraitThresholdsBuilder {
impl BrainTraitThresholdsBuilder {
/// Creates a builder with all thresholds set to their defaults.
#[must_use]
pub fn new() -> Self {
pub const fn new() -> Self {
Self {
methods_warn: DEFAULT_METHODS_WARN,
methods_deny: DEFAULT_METHODS_DENY,
Expand All @@ -148,28 +148,28 @@ impl BrainTraitThresholdsBuilder {

/// Sets the method count warn threshold.
#[must_use]
pub fn methods_warn(mut self, value: usize) -> Self {
pub const fn methods_warn(mut self, value: usize) -> Self {
self.methods_warn = value;
self
}

/// Sets the method count deny threshold.
#[must_use]
pub fn methods_deny(mut self, value: usize) -> Self {
pub const fn methods_deny(mut self, value: usize) -> Self {
self.methods_deny = value;
self
}

/// Sets the default method CC sum warn threshold.
#[must_use]
pub fn default_cc_warn(mut self, value: usize) -> Self {
pub const fn default_cc_warn(mut self, value: usize) -> Self {
self.default_cc_warn = value;
self
}

/// Consumes the builder and returns the completed thresholds.
#[must_use]
pub fn build(self) -> BrainTraitThresholds {
pub const fn build(self) -> BrainTraitThresholds {
BrainTraitThresholds {
methods_warn: self.methods_warn,
methods_deny: self.methods_deny,
Expand All @@ -190,19 +190,19 @@ impl Default for BrainTraitThresholdsBuilder {

/// Computes total method count (required + default), excluding
/// associated types and consts.
fn total_method_count(metrics: &TraitMetrics) -> usize {
const fn total_method_count(metrics: &TraitMetrics) -> usize {
metrics.required_method_count() + metrics.default_method_count()
}

/// Returns `true` when the deny condition holds (OR-based).
#[must_use]
fn is_deny_triggered(metrics: &TraitMetrics, thresholds: &BrainTraitThresholds) -> bool {
const fn is_deny_triggered(metrics: &TraitMetrics, thresholds: &BrainTraitThresholds) -> bool {
total_method_count(metrics) >= thresholds.methods_deny
}

/// Returns `true` when all warn conditions hold simultaneously (AND-based).
#[must_use]
fn is_warn_triggered(metrics: &TraitMetrics, thresholds: &BrainTraitThresholds) -> bool {
const fn is_warn_triggered(metrics: &TraitMetrics, thresholds: &BrainTraitThresholds) -> bool {
total_method_count(metrics) >= thresholds.methods_warn
&& metrics.default_method_cc_sum() >= thresholds.default_cc_warn
}
Expand Down Expand Up @@ -233,7 +233,7 @@ fn is_warn_triggered(metrics: &TraitMetrics, thresholds: &BrainTraitThresholds)
/// );
/// ```
#[must_use]
pub fn evaluate_brain_trait(
pub const fn evaluate_brain_trait(
metrics: &TraitMetrics,
thresholds: &BrainTraitThresholds,
) -> BrainTraitDisposition {
Expand Down
6 changes: 3 additions & 3 deletions common/src/brain_trait_metrics/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ impl TraitItemMetrics {
/// assert_eq!(item.kind(), TraitItemKind::RequiredMethod);
/// ```
#[must_use]
pub fn kind(&self) -> TraitItemKind {
pub const fn kind(&self) -> TraitItemKind {
self.kind
}

Expand All @@ -162,7 +162,7 @@ impl TraitItemMetrics {
/// assert_eq!(item.default_method_cc(), Some(9));
/// ```
#[must_use]
pub fn default_method_cc(&self) -> Option<usize> {
pub const fn default_method_cc(&self) -> Option<usize> {
self.default_method_cc
}

Expand Down Expand Up @@ -211,7 +211,7 @@ impl TraitItemMetrics {
/// assert_eq!(trait_item_count(&items), 2);
/// ```
#[must_use]
pub fn trait_item_count(items: &[TraitItemMetrics]) -> usize {
pub const fn trait_item_count(items: &[TraitItemMetrics]) -> usize {
items.len()
}

Expand Down
Loading
Loading