Skip to content

fix(scripts/dep-audit): correctness fixes from PR #6353 review, follow-up - #6358

Merged
senamakel merged 2 commits into
tinyhumansai:mainfrom
senamakel:dep-audit-report-fixes
Sep 19, 2026
Merged

senamakel merged 2 commits into
tinyhumansai:mainfrom
senamakel:dep-audit-report-fixes

Conversation

@senamakel

Copy link
Copy Markdown
Member

Summary

#6353 (the dep-audit tool itself) was merged before its CodeRabbit/tinysweeper review threads were fully addressed and pushed (a race with the merge). This PR carries the fixes I made in response to that review, rebased onto current main (post #6353/#6355/#6356). All 28 threads on #6353 were replied to and resolved citing this work; this is that work landing.

Fixes (scripts/dep-audit/report.mjs, run.sh, tinyanalyzer.toml, README.md)

  • compatKey no longer collapses distinct 0.0.z versions into one bucket (0.0.1 and 0.0.2 are semver-incompatible; only 0.x with x>0 collapses by minor).
  • driftAcross/summary.json: patch_only is now a real field ({ rows, patch_only }) instead of a property tacked onto an array, which JSON.stringify silently dropped.
  • Build-script + declared-target scanning: packageSourceDirs now includes a package's build = "..." script and tracks [[test]]/[[example]]/[[bench]]/[[bin]] targets as exact files rather than their parent directory, so a sibling file in a shared directory (e.g. the root crate's tests/) can no longer flip an unrelated package's unused-dependency verdict.
  • Renamed dependencies: added dependencyAliasMap so a dependency declared with package = "real-name" resolves its real crate name before graph lookups (previously reported a null version/graph-win).
  • packageDir: decodeURIComponents the path+file:// component (a checkout path with a space/percent-encoded character previously failed existence checks and forced a false remove).
  • heavyFor: excludes dependencies whose only edge kind is development — those never link into the shipped build and don't belong in a shipped-build weight ranking.
  • run.sh: fails loudly (instead of silently skipping) when a listed submodule is not initialized; rejects a symlinked/non-regular Cargo.lock before backing it up; tracks whether a lockfile existed before the run and restores that exact state (including removing a newly-created one) via an EXIT trap, so an interrupted run cannot leave edits behind.
  • tinyanalyzer.toml: removed the global ignore_unused = ["thiserror"] suppression — report.mjs's own textual re-check already handles the one false positive it existed for, and the global suppression was hiding genuinely-unused thiserror occurrences everywhere.
  • Docs: reworded the "how references are detected" prose (was literally crate::…, which is misleading — crate:: means something else in Rust; now describes the actual dep_name::… pattern), corrected the "every optional feature" claim (verified against tinyanalyzer's source: default cargo metadata, no --all-features), and documented the lockfile-absence/symlink behavior.
  • docs/dep-audit/2026-09-19.md is regenerated from the fixed generator against current main.

Validation

  • node --check scripts/dep-audit/report.mjs, bash -n scripts/dep-audit/run.sh.
  • bash scripts/dep-audit/run.sh --snapshot — full 24-target sweep, exit 0, lockfiles restored (verified git status clean afterward).
  • Spot-checked the regenerated report: several genuine new thiserror findings appear now that the global suppression is gone (e.g. tinyskillsremove), summary.json's drift.patch_only is present and non-zero.

Submission Checklist

  • Tests added or updated — N/A: maintainer tooling under scripts/, exercised by running the full sweep.
  • Diff coverage — N/A: no app/src or product Rust changes.
  • Coverage matrix updated — N/A.
  • All affected feature IDs listed under ## Related — N/A.
  • No new external network dependencies introduced.
  • Manual smoke checklist updated — N/A.
  • Linked issue closed — N/A.
  • pnpm --filter openhuman-app format:check — N/A, no app/ changes.
  • pnpm typecheck — N/A, no TypeScript changes.
  • Focused tests: see Validation above.
  • Rust fmt/check: N/A, no Rust changes.
  • Tauri fmt/check: N/A.

Related

Follow-up to #6353.

senamakel and others added 2 commits September 19, 2026 20:43
…reporting

The dependency audit scripts now handle lockfiles more carefully by recording whether each target's `Cargo.lock` existed before analysis and restoring that exact state, including removing newly created lockfiles and refusing to analyze targets with symlinked lockfiles. The unused dependency check now scans for the correct identifier (the manifest alias for renamed dependencies) and searches individual target files rather than entire directories to avoid false positives from unrelated sibling tests. The heavy dependency ranking excludes development-only dependencies from the shipped-build weight table, and the drift report now correctly serializes the patch-only count. The `tinyanalyzer.toml` configuration empties the `ignore_unused` list since the re-check already handles the attribute-based false positive that previously required global suppression.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Re-ran the dependency audit with the latest tinyanalyzer, which now detects additional unused dependencies and reports more accurate "name only" classifications. The updated report reflects changes in dependency counts, unused flags, and duplicate version tables across multiple targets, including the removal of several unused crates such as `tempfile` from root and `thiserror` from tinyskills.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@senamakel
senamakel requested a review from a team September 19, 2026 17:45
@coderabbitai

coderabbitai Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: aba89e00-aa97-4912-9e6c-e753d6e182cb

📥 Commits

Reviewing files that changed from the base of the PR and between 3669eac and 146756a.

📒 Files selected for processing (5)
  • docs/dep-audit/2026-09-19.md
  • scripts/dep-audit/README.md
  • scripts/dep-audit/report.mjs
  • scripts/dep-audit/run.sh
  • scripts/dep-audit/tinyanalyzer.toml
 _____________________________________________________________
< Return early? Yes. Return *something meaningful*? Also yes. >
 -------------------------------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ

Comment @coderabbitai help to get the list of available commands.

@senamakel
senamakel merged commit 7e31358 into tinyhumansai:main Sep 19, 2026
18 of 19 checks passed
@tinysweeper

tinysweeper Bot commented Sep 19, 2026

Copy link
Copy Markdown

Tiny Sweeper review

Tiny Sweeper reviewed this change across 6 lane(s) and found 7 active actionable finding(s). Detailed lane evidence and any incomplete work are listed below.

State: Reviewing pending checks
Priority: medium
Reviewed head: 146756a4c3ee
Updated: 1789842385 (Unix time)

Review snapshot

Change surface Files Review signal Count
Production 2 Active findings 7
Tests 0 Noted findings 0
Documentation 2 Resolved findings 15
Configuration 1 Pending checks/questions 4

Completeness: Complete
Test assessment: No supported feature-to-test mapping was available; this does not mean tests are absent or passed.

What changed

The review could not produce a supported behavioral summary; inspect the cited changed surface and lane details below.

Features

None identified with supported citations.

Tests

No supported feature-to-test mapping was produced. Test execution is not inferred.

Findings

  • medium · critique · Reserve built-in target names before discovery — `root` and `openhuman-app` are written to `targets.tsv` before this map is initialized, and neither name is inserted into it. If a recursive submodule directory is named `root` or (scripts/dep\-audit/run\.sh:99)
  • medium · critique · Exclude unrelated sibling files from source-use scans — `dirs` still contains the whole package directory, and `grepAny` recursively scans every `*.rs` file under it. Adding explicit target paths to `files` therefore does not prevent an (scripts/dep\-audit/report\.mjs:147)
  • medium · critique · Recognize renamed dependencies in target-specific tables — This only recognizes aliases in plain `[dependencies]`, `[dev-dependencies]`, and `[build-dependencies]` tables. A valid declaration such as `[target.'cfg(windows)'.dependencies]` (scripts/dep\-audit/report\.mjs:193)
  • medium · security · Handle renamed dependencies in target-specific tables — Cargo permits renamed dependencies under tables such as `[target.'cfg(unix)'.dependencies.foo]` and `[target.'cfg(unix)'.dependencies]`. This parser only recognizes top-level depen (scripts/dep\-audit/report\.mjs:190)
  • medium · security · Parse multiline renamed dependency declarations — This only recognizes inline dependency tables whose `package = "..."` attribute appears on the same line as the dependency key and closing brace. A valid multiline declaration such (scripts/dep\-audit/report\.mjs:203)
  • medium · tests · Add unit tests for the dependency alias map parser — `dependencyAliasMap` parses Cargo.toml to map manifest dependency aliases to real crate names. This mapping is used in the unused-dependency check; if it misparses a form (e.g., wo (scripts/dep\-audit/report\.mjs:181)
  • medium · e2e · End-to-end job `Rust Feature-Gate Smoke (gates off)` will not run on this change — `Rust Feature-Gate Smoke (gates off)` in `.github/workflows/ci-lite.yml` will not run for this pull request: the forge reports it as skipped, so a job condition was false for this (\.github/workflows/ci\-lite\.yml)

Resolved this pass

  • Exclude development dependencies from shipped-build cost claims
  • Scope the thiserror suppression to verified false positives
  • Exclude development dependencies from shipped-build cost claims
  • Scope the thiserror suppression to verified false positives
  • Exclude development dependencies from shipped-build cost claims
  • Scope the thiserror suppression to verified false positives
  • Describe external-crate reference detection correctly
  • Document the feature flags required for a full dependency graph
  • compatKey version collapse fix
  • driftAcross patch_only field fix
  • packageSourceDirs scanning exact files fix
  • dependencyAliasMap renamed resolution fix
  • packageDir decodeURIComponent fix
  • run.sh lockfile trap and symlink rejection fix
  • tinyanalyzer.toml ignore_unused removal

Pending checks: Rust E2E (mock backend), Build Playwright E2E Artifact, E2E (Playwright / web lane), Desktop E2E (full suite, 3 OS)

Before merge

  • Wait for Rust E2E (mock backend), Build Playwright E2E Artifact, E2E (Playwright / web lane), Desktop E2E (full suite, 3 OS).

How this fits together

flowchart LR
  n0["driftAcross<br/>changed<br/>5 findings"]:::flagged
  n1["packageDir<br/>changed<br/>5 findings"]:::flagged
  n2["packageSourceDirs<br/>changed<br/>5 findings"]:::flagged
  n3["renderMarkdown<br/>changed<br/>5 findings"]:::flagged
  n4["unusedFor<br/>changed<br/>5 findings"]:::flagged
  n5["data"]:::impacted
  n6["p"]:::impacted
  n7["summary"]:::impacted
  n8["a"]:::impacted
  n9["m"]:::impacted
  n10["pulledInVia"]:::impacted
  n0 -->|uses| n5
  n0 -->|uses| n6
  n0 -->|uses| n8
  n0 -->|uses| n9
  n1 -->|uses| n5
  n1 -->|uses| n9
  n2 -->|uses| n9
  n3 -->|uses| n7
  n4 -->|uses| n5
  n4 -->|uses| n8
  n7 -->|calls| n4
  n7 -->|uses| n5
  n7 -->|uses| n6
  n7 -->|uses| n8
  n7 -->|calls| n10
  n9 -->|uses| n6
  n10 -->|uses| n5
  n10 -->|uses| n6
  classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
  classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
  classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
  classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Loading
Agent review details

critique

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: Reviewed 5 files; 3 findings. _The code index is behind this pull request (indexed at `51f2de350b41`), so retrieved context may be out of date._ _3 memory call(s) failed (model: cortex: v1/answer answered 502 Bad Gateway), so this review saw part of what the engine holds._
  • Evidence: scripts/dep\-audit/run\.sh — Reserve built-in target names before discovery
  • Evidence: scripts/dep\-audit/report\.mjs — Exclude unrelated sibling files from source-use scans
  • Evidence: scripts/dep\-audit/report\.mjs — Recognize renamed dependencies in target-specific tables

security

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: Reviewed 3 files; 2 findings. 2 files were not security-reviewed: docs/dep-audit/2026-09-19.md (prose or tabular data), scripts/dep-audit/README.md (prose or tabular data). _The code index is behind this pull request (indexed at `51f2de350b41`), so retrieved context may be out of date._ _3 memory call(s) failed (model: cortex: v1/answer answered 502 Bad Gateway), so this review saw part of what the engine holds._
  • Evidence: scripts/dep\-audit/report\.mjs — Handle renamed dependencies in target-specific tables
  • Evidence: scripts/dep\-audit/report\.mjs — Parse multiline renamed dependency declarations

tests

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: Improves correctness of the dependency audit: decodes paths, handles crate aliases, filters dev-only deps from shipped-weight ranking, clears stale global suppression, and hardens lockfile restoration. The new `dependencyAliasMap` function lacks unit tests, but the changes are otherwise sound. _The code index is behind this pull request (indexed at `51f2de350b41`), so retrieved context may be out of date._ _3 memory call(s) failed (model: cortex: v1/answer answered 502 Bad Gateway), so this review saw part of what the engine holds._
  • Evidence: scripts/dep\-audit/report\.mjs — Add unit tests for the dependency alias map parser

commits

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: Nothing sensitive found in what this pull request commits.

description

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: All correctness issues from the initial dep-audit review (PR chore(scripts): add tinyanalyzer-driven dependency audit across core and vendor submodules #6353) have been addressed. The changes fix compatKey 0.0.z handling, driftAcross JSON output, package source scanning, dependency alias resolution, path decoding, heavyFor dev-only filtering, lockfile state restoration with interruption safety, and removal of the global thiserror suppression. No new problems are introduced. _The code index is behind this pull request (indexed at `51f2de350b41`), so retrieved context may be out of date._ _3 memory call(s) failed (model: cortex: v1/answer answered 502 Bad Gateway), so this review saw part of what the engine holds._

e2e

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: The pull request improves the robustness and accuracy of the internal dependency-audit scripts (lockfile backup/restore, source-file scanning, alias resolution). These changes affect a developer tool that is not exercised by any end-to-end test harness, and no external-facing behaviour (route, command, UI, persisted format, or message) is introduced. The modifications are internal and safe to merge without e2e coverage. Waiting on end-to-end jobs: `Rust E2E (mock backend)`, `Build Playwright E2E Artifact`, `E2E (Playwright / web lane)`, `Desktop E2E (full suite, 3 OS)`.
  • Unresolved questions/checks: Rust E2E (mock backend), Build Playwright E2E Artifact, E2E (Playwright / web lane), Desktop E2E (full suite, 3 OS)
  • Evidence: \.github/workflows/ci\-lite\.yml — End-to-end job `Rust Feature-Gate Smoke (gates off)` will not run on this change
Evidence and run details
  • Models: ladder/vectors, gpt-5.6-luna, deepseek-v4-flash
  • Spend: $0.034296
  • Tokens: 720043 input · 34528 output · 78034 cached · 1128 embedding
Head State Pass summary
146756a4c3ee pending 7 active finding(s), 15 resolved finding(s) (at 1789842385)

tinysweeper 0.1.0

@tinysweeper tinysweeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tinysweeper found nothing blocking. Approving.

             $0.0343 · 720,043 in / 34,528 out · 78,034 cached (11%) · ladder/vectors, gpt-5.6-luna, deepseek-v4-flash · 1,128 embedded
critique:    $0.0199 · 372,397 in / 15,728 out · 36,209 cached (10%) · gpt-5.6-luna, deepseek-v4-flash
security:    $0.0118 · 204,765 in / 6,885 out  · 11,105 cached (5%)  · gpt-5.6-luna
tests:       $0.0008 · 39,734 in  / 3,683 out  · 1,024 cached (3%)   · deepseek-v4-flash
description: $0.0007 · 31,272 in  / 4,358 out  · 1,024 cached (3%)   · deepseek-v4-flash
e2e:         $0.0008 · 44,030 in  / 839 out    · 1,024 cached (2%)   · deepseek-v4-flash

Comment thread scripts/dep-audit/run.sh
@@ -99,7 +99,12 @@ fi
declare -A seen_by_repo_sha=()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

priority medium critique confident

Reserve built-in target names before discovery

root and openhuman-app are written to targets.tsv before this map is initialized, and neither name is inserted into it. If a recursive submodule directory is named root or openhuman-app and contains a Cargo.toml, discovery emits a second target with the same name; its JSON and log paths then overwrite the built-in target's artifacts, so the final report can associate the wrong analysis with that target. Seed the collision-tracking map with the built-in names, or assign unique report names before writing each target.

[RULE] report-file-collision ·

* dependency to "keep".
*/
function packageSourceDirs(dir) {
const dirs = new Set([dir]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

priority medium critique confident

Exclude unrelated sibling files from source-use scans

dirs still contains the whole package directory, and grepAny recursively scans every *.rs file under it. Adding explicit target paths to files therefore does not prevent an unrelated sibling such as another integration test, example, or workspace Rust file from matching the dependency name and changing an actually-unused dependency to keep. The new documentation explicitly promises that each explicit target is scanned as an exact file; either stop recursively scanning files that are not package sources or otherwise exclude unrelated siblings from the directory targets.

[RULE] overbroad-source-scan ·

const head = /^\[([a-zA-Z0-9_.-]+)\]/.exec(line);
if (head) {
section = head[1];
const table = /^(dependencies|dev-dependencies|build-dependencies)\.([A-Za-z0-9_-]+)$/.exec(section);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

priority medium critique confident

Recognize renamed dependencies in target-specific tables

This only recognizes aliases in plain [dependencies], [dev-dependencies], and [build-dependencies] tables. A valid declaration such as [target.'cfg(windows)'.dependencies] with foo = { package = "bar", ... } is skipped, so dependencyAliasMap returns no foo -> bar mapping. The later graph lookups use foo even though the resolved package is named bar, producing incorrect graph-win and dependent information for target-specific dependencies. Match dependency table suffixes as well as top-level tables.

Suggested change
const table = /^(dependencies|dev-dependencies|build-dependencies)\.([A-Za-z0-9_-]+)$/.exec(section);
const table = /(?:^|\.)(dependencies|dev-dependencies|build-dependencies)\.([A-Za-z0-9_-]+)$/.exec(section);

[RULE] target-specific-dependency-alias ·

let tableDepKey = null;
for (const raw of toml.split("\n")) {
const line = raw.trim();
const head = /^\[([a-zA-Z0-9_.-]+)\]/.exec(line);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

priority medium security confident

Handle renamed dependencies in target-specific tables

Cargo permits renamed dependencies under tables such as [target.'cfg(unix)'.dependencies.foo] and [target.'cfg(unix)'.dependencies]. This parser only recognizes top-level dependency sections, so those aliases are absent from the map. The later graph lookup then uses the manifest alias instead of the resolved package name, causing valid dependencies to be reported with incorrect graph-win or unused results. Parse target-specific dependency tables, including quoted target expressions, or use a TOML parser.

[RULE] parse-target-specific-dependencies ·

continue;
}
if (!/^(dependencies|dev-dependencies|build-dependencies)$/.test(section)) continue;
const inline = /^([A-Za-z0-9_-]+)\s*=\s*\{([^}]*)\}/.exec(line);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

priority medium security confident

Parse multiline renamed dependency declarations

This only recognizes inline dependency tables whose package = "..." attribute appears on the same line as the dependency key and closing brace. A valid multiline declaration such as foo = { followed by package = "real-foo" is left unmapped, so resolvedDependency and otherDependents look up the alias instead of the resolved crate name and produce incorrect unused-dependency or graph-win results. Parse the TOML structure rather than matching one line at a time, or retain the current dependency table until its closing brace and inspect its fields.

[RULE] incomplete-manifest-parser ·

* imports), the latter is the real crate name (what the resolved package is
* called), so callers matching a dependency against the graph need this map.
*/
function dependencyAliasMap(dir) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

priority medium tests likely

Add unit tests for the dependency alias map parser

dependencyAliasMap parses Cargo.toml to map manifest dependency aliases to real crate names. This mapping is used in the unused-dependency check; if it misparses a form (e.g., workspace-level dependencies, dependencies.rename.workspace = true, or double-quoted inline tables), the verdict for renamed dependencies will be wrong. The function has no unit test. Add a test case under scripts/dep-audit/__tests__/ that exercises inline { package = ".." } and table-form [dependencies.alias] renames along with missing-file and empty-Cargo.toml paths.

[RULE] untested-function ·

@tinysweeper tinysweeper Bot added the priority: p2 Soon. Real but survivable — a rough edge, a gap, a thing that will bite later. label Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p2 Soon. Real but survivable — a rough edge, a gap, a thing that will bite later.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant