Skip to content

fix(agent-tooling): search order, --lite umbrella breakage, Rust test false-positives, export-snapshot (closes #218) - #234

Merged
Wolfvin merged 6 commits into
mainfrom
fix/agent-tooling-audit-fixes
Jul 12, 2026
Merged

fix(agent-tooling): search order, --lite umbrella breakage, Rust test false-positives, export-snapshot (closes #218)#234
Wolfvin merged 6 commits into
mainfrom
fix/agent-tooling-audit-fixes

Conversation

@Wolfvin

@Wolfvin Wolfvin commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Summary

Direct verification pass driven by the goal "make CodeLens genuinely usable as an agent's primary tool, replacing manual grep, across js/css/html/react/py/rs/ts" — exercised every umbrella command end-to-end against a real 425-file polyglot workspace (Rust/TS/TSX/JS/CSS/HTML Tauri+React app) and CodeLens's own Python codebase, fixed everything broken directly (no worker per explicit directive), with before/after verification for each fix.

Fixes

  1. search --help example order was backwards — docs showed workspace before pattern, opposite of the real signature. Following it silently returns an empty result.
  2. graph mode truncated flag was meaningless — always True whenever a query had a LIMIT, regardless of whether results were cut off.
  3. --lite was completely broken for all 12 umbrella commands — reducer dispatch predates the refactor(commands): consolidate 78 commands → 12 focused commands #195 consolidation, keyed off old leaf command names that never match the new umbrella names. Every umbrella's --lite silently returned {"status": "ok"} with all data dropped.
  4. Rust inline #[test] functions false-flagged as dead code — measured 56%+ of all Rust registry_dead findings on a real workspace before the fix.
  5. deps --check import-snapshot permanently broken (closes chore(deps): import-snapshot permanently broken since export-snapshot was dropped #218)export-snapshot was dropped in refactor(commands): consolidate 78 commands → 12 focused commands #195 with no replacement; restored as deps --check export-snapshot, verified full round trip.
  6. summary/history --lite still returned bloated/empty output even after fix refactor: backend-focused cleanup — remove hardcoded paths, garbage files, frontend deps #3 (they're not umbrella-enveloped, hit the generic fallback which doesn't know their field names).
  7. Windows CRLF corruption in all CLI output_force_utf8_stdio() never set newline='', silently turning every \n into \r\n on Windows.

Test plan

  • pytest tests/ — all directly-touched test files pass (search, query_graph, deadcode_engine, export_snapshot [new], command_registry, codelens)
  • Full suite run — only pre-existing failures remain (Windows path-separator test debt + 2 pure timeouts on codelens scan . unrelated to these changes), documented in docs/agent-usage-guide.md
  • Manual CLI verification for every fix (before/after JSON diffs) — see commit messages and docs/agent-usage-guide.md "Fixed this session" section
  • sync_command_count.py --apply — docs stay in sync, count unchanged (export-snapshot is a deps sub-check, not a new top-level command)

🤖 Generated with Claude Code — direct fix session (no worker), full details in docs/agent-usage-guide.md

Wolfvin added 6 commits July 12, 2026 16:17
The --help epilog and module docstring showed `codelens search . "query"`
(workspace first), the opposite of the actual argparse signature
(pattern first, workspace second) — every other umbrella command takes
workspace first, so this is an easy trap. Following the wrong example
does not error: the workspace path silently becomes the search pattern
and returns an empty "ok" result with zero indication anything went
wrong. Found while exercising search end-to-end across a polyglot
workspace (rs/ts/tsx/js/css/html).
`graph` mode's `truncated` field was set to True whenever the query
merely contained a LIMIT clause, regardless of whether any rows were
actually cut off — a `LIMIT 50` query matching 1 row reported
`truncated: true`, misleading callers into thinking more results
existed. Now computed from the real row count vs. limit. Added a
regression test covering the under-filled-LIMIT case, which the
existing test_truncated_flag test never exercised (it only tested
LIMIT-with-enough-matches and no-LIMIT-at-all).
Rust unit tests live inline in the same file as production code inside
`#[cfg(test)] mod tests { #[test] fn ... }`, unlike JS/Python where
tests sit in a separate tests/ directory (already exempted by the
existing test-path patterns). Without this, every Rust test function
and every `mod tests` module false-positives as dead code, since the
test harness invokes them via attribute discovery, not a CALLS edge.
Measured on a real 192-file Rust workspace: this was 56%+ of all
Rust registry_dead findings in the top-100 window (100->69 after the
fix, with `mod tests` blocks also newly exempted). Detects #[test],
#[tokio::test], #[async_std::test] and other `#[x::test]` attribute
variants by checking the source lines immediately above the flagged
symbol.
…snapshot (closes #218)

export-snapshot was dropped entirely in the #195 umbrella consolidation
with no replacement, so import-snapshot could never find a snapshot
file to load ("Snapshot file not found" on every run) — the underlying
build_snapshot()/write_snapshot() logic in snapshot_io.py was never
deleted, just orphaned with no CLI entry point. Added
`deps --check export-snapshot` as a new sub-mode (mirroring
import-snapshot's own structure), and verified a full export->import
round trip preserves node/edge counts.

Also excluded both import-snapshot and export-snapshot from the bare
`codelens deps <workspace>` default: they are side-effecting/opt-in
actions that always failed with no --input/--output given, so every
default `deps` run showed a spurious unrelated error entry.

See docs/design/0218-export-snapshot.md for the full design rationale.
Two related bugs found while exercising every umbrella command's
--lite output on a real 425-file polyglot workspace:

1. _apply_lite's reducer dispatch table predates the #195 umbrella
   consolidation and keyed off the OLD leaf command names (smell,
   dead-code, query, ...). Since umbrella commands always pass their
   own name (context, audit, security, deps, ...), no branch ever
   matched, and every umbrella's --lite output silently collapsed to
   `{"status": "ok"}` with all data dropped. Fixed by unwrapping the
   `{"s","st","r":[{"_check":name,...}]}` envelope, applying the
   existing per-check reducers keyed by each item's own `_check` name,
   then re-wrapping.

2. summary/history are not umbrella-wrapped, so they hit the generic
   fallback instead — which doesn't know their real field names.
   summary's own job is "anti-overload prioritized findings" per its
   --help text, but --lite returned the same multi-thousand-token
   payload as non-lite (nested top_items/flow_chain per finding were
   never trimmed). history --lite collapsed to just
   `{"status", "workspace"}`, dropping snapshots/latest/trends/deltas
   entirely. Added dedicated reducers for both.

Also: _force_utf8_stdio() (the issue #179 Unicode-crash fix) rewraps
stdout/stderr with TextIOWrapper(encoding='utf-8') but never set
newline='', so every '\n' written on Windows silently became '\r\n'
(Python's default write-side os.linesep translation) — affecting every
line CodeLens prints on Windows. Fixed by adding newline=''. Caught by
an existing test that was failing before this fix.
Result of exercising every umbrella command (search/context/audit/
security/deps/impact/api-map/summary/history/doctor/graph) end-to-end
against a real 425-file polyglot workspace (Rust/TS/TSX/JS/CSS/HTML
Tauri+React app) plus CodeLens's own Python codebase. Documents: the
search pattern/workspace argument-order trap, which command to use for
which "replace grep" question, --lite reducer coverage per command,
per-language verified coverage (including the confirmed gap: no Rust
taint analysis), and a changelog of the 6 fixes made this session with
before/after verification evidence.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@sonarqubecloud

Copy link
Copy Markdown

@Wolfvin

Wolfvin commented Jul 12, 2026

Copy link
Copy Markdown
Owner Author

CI failures on this PR (`quality-gate` x4, `Test Suite`) are pre-existing on `main`, not caused by these changes — verified by checking `gh run list --branch main`: the merge commit for PR #233 (last merge before this PR) already shows both jobs failing.

Root causes filed separately as #235:

  1. `quality-gate`: workflow YAML still calls the dropped standalone `init` command (absorbed into `scan` since refactor(commands): consolidate 78 commands → 12 focused commands #195).
  2. `Test Suite`: segfault in `test_large_file_parsing.py` → `python_parser.py::_extract_references_impl`, aborts the whole pytest run (everything alphabetically after it, including `test_query_graph.py`/`test_codelens.py`, never executes in CI).

Locally verified (Windows, excluding the two known-flaky/segfaulting test files per the documented baseline methodology): all directly-touched test files pass — `test_export_snapshot.py` (new, 7/7), `test_query_graph.py`, `test_deadcode_engine.py`, `test_command_registry.py`, `test_codelens.py` (81/81), `test_issue195_consolidation.py`. Full command outputs and before/after CLI verification for every fix are in the commit messages and `docs/agent-usage-guide.md`.

@Wolfvin
Wolfvin merged commit c5ef0a4 into main Jul 12, 2026
6 of 12 checks passed
@Wolfvin
Wolfvin deleted the fix/agent-tooling-audit-fixes branch July 12, 2026 09:24
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.

chore(deps): import-snapshot permanently broken since export-snapshot was dropped

1 participant