Skip to content

chore(tvc): lint against inline absolute paths + AGENTS.md guidance#166

Open
daniilrrr wants to merge 1 commit into
mainfrom
daniil/lint-absolute-paths
Open

chore(tvc): lint against inline absolute paths + AGENTS.md guidance#166
daniilrrr wants to merge 1 commit into
mainfrom
daniil/lint-absolute-paths

Conversation

@daniilrrr

@daniilrrr daniilrrr commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Motivation

In the review of #158, reviewers asked contributors to prefer a short use import over inline fully-qualified absolute paths at call sites — e.g. replace

let app_status = crate::commands::app_status::sanitize_app_status(response)?;

with

use crate::commands::app_status::sanitize_app_status;
// ...
let app_status = sanitize_app_status(response)?;

This PR makes that convention easier to uphold, via two complementary mechanisms scoped to the tvc crate:

  1. a mechanical Clippy lint (clippy::absolute_paths), and
  2. an AGENTS.md instruction for AI agents / humans.

Scope note: This is intentionally tvc-only. It does not touch the rest of the workspace or generated code. No [workspace.lints] plumbing, no per-crate [lints] workspace = true edits, no generated-code #[allow] (tvc consumes generated types via use imports and doesn't include! generated source, so nothing there is tripped).

What changed (3 files)

  1. tvc/Cargo.toml — crate-local lint, no workspace wiring:

    [lints.clippy]
    absolute_paths = "warn"
  2. clippy.toml (repo root) — tuning for the lint:

    absolute-paths-max-segments = 2
    absolute-paths-allowed-crates = ["std", "core", "alloc"]
    • clippy.toml is global by nature (one per repo), but its settings only take effect for lints that are actually enabled — currently only in tvc. So in practice these knobs scope to tvc today.
    • max-segments = 2 is Clippy's default; it still flags 3+ segment inline paths such as crate::commands::app_status::sanitize_app_status(...) (the Add visibility for egress #158 antipattern).
    • allowed-crates = ["std", "core", "alloc"] keeps fully-qualified std-family references (e.g. std::collections::HashMap) from being flagged.
  3. AGENTS.md (new) — guidance file (none existed in the repo). See the exact wording below.

AGENTS.md instruction (the wording used)

Imports: prefer short use imports over inline absolute paths

When you reference an item (function, type, trait, macro) from another module, bring it into scope with a use import and call it by its short name. Do not write out a fully-qualified absolute path inline at the call site.

This keeps call sites readable, makes dependencies explicit at the top of the file, and matches the convention requested in code review (see PR #158).

Avoid — inline fully-qualified absolute path:

let app_status = crate::commands::app_status::sanitize_app_status(response)?;
println!("{}", crate::commands::display::format_egress_enabled(app.enable_egress));

Prefer — short use import + bare call:

use crate::commands::app_status::sanitize_app_status;
use crate::commands::display::format_egress_enabled;
// ...
let app_status = sanitize_app_status(response)?;
println!("{}", format_egress_enabled(app.enable_egress));

Notes and exceptions: applies to crate::/self::/super::/external paths; short idiomatic FQ paths like std::collections::HashMap are fine and not flagged; keep a path inline to disambiguate a real name collision; in tvc this is mechanically enforced by clippy::absolute_paths, elsewhere it's a guideline; generated code under client/src/generated/ is exempt and must not be hand-edited.

⚠️ warn vs. deny under make lint (unchanged finding, now tvc-scoped)

The lint is set to warn, not deny. However, make lint runs:

cargo clippy --all-targets --all-features -- -D warnings

-D warnings promotes all warnings to hard errors, so under make lint/CI this lint effectively behaves as deny — it will FAIL while any tvc absolute_paths violation remains. Verified empirically on this branch: cargo clippy -p tvc --all-targets --all-features -- -D warnings exits 101 (44 violations promoted to errors in the lib-test build).

The Makefile was intentionally not changed. Options to decide before/at merge:

  • (a) Accept deny-under-CI — merge config + AGENTS.md, then fix the tvc violations so make lint goes green. Cleanest end state.
  • (b) Fix all tvc violations first — convert the 47 sites to short use imports, then merge; CI stays green immediately.
  • (c) Adjust make lint — not done here, to avoid silently weakening -D warnings.

The AGENTS.md guidance carries zero CI risk regardless of which option is chosen — it's advisory, so it can land immediately even if the lint cleanup is deferred.

Blast radius (tvc-focused, pinned toolchain 1.88)

Unique file:line:col violation sites from cargo clippy --all-targets --all-features, deduped across targets, with this PR's config:

Scope Violations
tvc (total) 47
tvc/src/ 45
tvc/tests/ 2
Everywhere else in the workspace 0 (lint not enabled there)

Verified that no absolute_paths warning appears outside tvc after removing the workspace plumbing.

For context (workspace-wide, had this been global): the lint would have produced ~1646 sites, of which 1586 are in generated code (client/src/generated/) and only ~60 non-generated — which is exactly why scoping to tvc (and skipping generated entirely) keeps this small and meaningful.

max-segments sensitivity within tvc: at max-segments = 2 (shipped) → 47 sites; bumping to 3 would shrink it to a handful but would stop flagging the 3-segment #158-style internal-helper calls, so 2 is the right threshold to actually enforce the convention.

Lint vs. AGENTS.md — assessment

clippy::absolute_paths lint AGENTS.md instruction
Enforcement Mechanical, every build Advisory; relies on agent/human compliance
CI behavior Becomes hard error under make lint (-D warnings) Zero CI impact
Coverage Only what the lint models (segment-count heuristic; tunable) Any nuance you can describe in prose
False positives Possible (heuristic), needs #[allow] escape hatches None — humans/agents apply judgment
Applies to Compiled Rust in enabled crates Agents/humans editing anything

Recommendation: keep both. The lint gives a hard floor inside tvc; AGENTS.md gives broader, judgment-friendly guidance (and reaches code/cases the lint can't model) without any CI risk. The lint's one sharp edge is the -D warnings interaction above — that's the only thing to decide before merge.

Verification

  • cargo metadata parses — config is syntactically valid.
  • cargo clippy --all-targets --all-features shows the lint active only in tvc (47 sites; 0 elsewhere), purely from tvc/Cargo.toml.
  • The Add visibility for egress #158 antipattern is flagged on real in-tree tvc code, e.g. crate::commands::app_status::sanitize_app_status(...).
  • cargo clippy -p tvc ... -- -D warnings → exit 101 (confirms the deny-under-CI behavior).

Pre-existing finding (not introduced here)

make lint already does not pass clean on main with the pinned 1.88 toolchain: cargo fmt -- --check fails on two tvc files (tvc/src/client.rs, tvc/src/commands/display.rs) due to edition-2024 formatting drift. Worth a separate cargo fmt commit; flagged here for transparency. No file changed in this PR introduces a new fmt diff.

Push the tvc CLI toward short `use` imports over inline fully-qualified
absolute paths at call sites (e.g. prefer
`use crate::commands::display::format_egress_enabled;` + `format_egress_enabled(x)`
over `crate::commands::display::format_egress_enabled(x)`), as requested in the
PR #158 review.

Two complementary mechanisms, scoped to tvc only:

- Mechanical: enable the `clippy::absolute_paths` restriction lint at warn,
  crate-locally via `[lints.clippy]` in tvc/Cargo.toml (no workspace plumbing).
  Tuning lives in a repo-root clippy.toml (absolute-paths-max-segments = 2,
  absolute-paths-allowed-crates = ["std", "core", "alloc"]). clippy.toml is
  global by nature but only takes effect where the lint is enabled (tvc).

- Guidance: add AGENTS.md with an "Imports" section instructing AI agents and
  humans to prefer short `use` imports, with a concrete before/after example.

Other workspace crates and generated code are intentionally untouched.
@daniilrrr daniilrrr force-pushed the daniil/lint-absolute-paths branch from 5b0718b to 43abeb5 Compare June 17, 2026 04:29
@daniilrrr daniilrrr changed the title chore: lint against inline absolute paths (clippy::absolute_paths) chore(tvc): lint against inline absolute paths + AGENTS.md guidance Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant