Technical Debt Audit

VerifiedCaution

Orchestrated audit of accumulated technical debt in a Rust codebase: stale markers, dead code, duplication, magic numbers, stub implementations and doc rot, with triage and prioritization.

Sby Skills Guide Bot
DevelopmentAdvanced
11/9/2026
Claude Code
#technical-debt#code-audit#rust#code-quality#static-analysis

Recommended for

Automated summary

A repository-specific Claude Code audit command that scans ByroRedux for accumulated technical debt across nine dimensions, including stale markers, dead code, duplication, magic numbers, stub implementations, documentation rot, and oversized files.

Strengths

  • Uses reproducible discovery recipes and current-code enumeration instead of hardcoded finding lists, so audits can be rerun.
  • Defines explicit severity-promotion rules and per-finding metadata such as dimension, age, effort, and ID.
  • Deduplicates against GitHub tech-debt issues and prior audit reports, and supports --focus and --depth parameters.
  • Includes a production-LOC helper with a self-test that separates production complexity from bulk inline tests.

Limitations

  • Hard-wired to the ByroRedux repository, its Rust crate roster, GitHub issue labels, and companion .claude/commands files.
  • It audits and reports only; it does not remediate debt or verify fixes.
  • Requires gh, cargo, git history, and prior audit reports, and its agent orchestration can be expensive on large runs.
When to use it

Use it for a periodic cleanup or pre-refactor sweep of ByroRedux when you need a structured inventory of accumulated technical debt.

When not to use it

Do not use it to find correctness, security, or performance bugs, or on repositories other than ByroRedux unless paths, crate roster, and companion files are adapted.

Security analysis

Caution
Quality score85/100

This is a legitimate, repo-specific technical-debt audit skill: all commands are read-only inspection (grep, git, clippy, gh queries) plus temp-file bookkeeping. There is no curl|sh, no base64/obfuscated payload, no credential or secret exfiltration, and no instruction to disable safety controls. It lands in 'caution' rather than 'safe' because it relies on unrestricted Bash, sources a local shell script, makes authenticated network calls, and contains an rm -rf (bounded to /tmp). No prompt-injection or role-manipulation attempts were found in the content.

Findings
  • •No declared allowed-tools yet the skill drives extensive shell execution (bash loops, find, grep -R, git log/blame, wc/awk, mkdir) — the host must gate Bash or the agent gains broad filesystem read access across the whole repo.
  • •Sourcing a checked-in script: `source .claude/commands/audit-tech-debt/prod_loc.sh` executes repo-provided shell code in the agent's session; its safety depends entirely on the integrity of that file, which is not shown here.
  • •Includes `rm -rf /tmp/audit/tech-debt` — a destructive primitive, though scoped to a directory the skill itself created under /tmp, so impact is low.
  • •Authenticated network use via the `gh` CLI (`gh issue list --repo matiaszanolli/ByroRedux`, `gh issue view`) and `cargo clippy` / `cargo machete`; queries are read-only, but they require GitHub credentials and network egress.
  • •Writes artifacts outside /tmp (creates `docs/audits/AUDIT_TECH_DEBT_<date>.md` and later suggests a publish command), so the skill mutates the working tree.
  • •Sources a checked-in shell script into the agent's shell (`source .claude/commands/audit-tech-debt/prod_loc.sh`), so any modification to that file yields arbitrary code execution in the agent context.
  • •Runs `cargo clippy --workspace`, `cargo machete`, and workspace builds — compiling a Rust workspace executes `build.rs` scripts and proc macros from the repository, i.e. arbitrary code with the agent's privileges.
  • •Network/credentialed operations via `gh issue list` / `gh issue view` against the GitHub API (read-only, but relies on an authenticated token present in the environment).
  • •`rm -rf /tmp/audit/tech-debt` on cleanup — fixed, hardcoded path, low blast radius, not a real concern.
How this analysis is made

Examples

Focused shallow audit
Run /audit-tech-debt --focus 1,3,5 --depth shallow and report the worst offenders in those dimensions.
Young-crate sweep
Run a deep tech-debt audit of ByroRedux and prioritize crates that were not named in the last audit report.
Deduplicated cleanup pass
Audit accumulated technical debt since the last cleanup, deduplicate against existing tech-debt GitHub issues, and return findings with age and effort.

description: "Audit accumulated technical debt — stale markers, dead code, duplication, magic numbers, stub impls, doc rot, oversized files" argument-hint: "--focus <dimensions> --depth shallow|deep"

Tech-Debt Audit

Audit ByroRedux for accumulated technical debt: code that compiles, passes tests and ships, but raises the cost of every future change. Correctness bugs belong to other audits; this one hunts decay since the last cleanup pass.

Every dimension below is a DISCOVERY RECIPE, not a finding list. Instances churn between audits, so each dimension hands you a command that enumerates current instances plus a triage rule. There is no hardcoded instance list here on purpose — re-run the recipe and report what it surfaces today. Where a cargo test / CI gate already enforces an invariant, the dimension names the guard and aims at what it cannot see.

Architecture: Orchestrator. Each dimension runs as a Task agent (max 3 concurrent).

See .claude/commands/_audit-common.md for layout, crate roster, methodology, dedup, severity and finding format. Young code has had the fewest sweeps — find it with git log --diff-filter=A --since=<last-report-date> --name-only --format= -- 'crates/*/Cargo.toml' 'tools/*/Cargo.toml' plus the crates the last report never names (for c in crates/*/; do grep -q "$c" <last-report> || echo "$c"; done; the 2026-10-19 report still named none of bgsm, boot-request, debug-protocol, debug-ui, facegen, fsr3-sys, mod-runtime, papyrus, settings-io and the two placeholders — plus terrain-height, new on 2026-10-20 — nor three of the four tools/). File real findings there; do not just note the crate is young. crates/cxx-bridge and crates/platform are deliberate placeholders owned here: check they have not grown a second job or silent consumers, not that they are small.

Parameters (from $ARGUMENTS)

  • --focus <dimensions>: comma-separated dimension numbers (e.g. 1,3,5). Default: all 9.
  • --depth shallow|deep: shallow = surface counts + worst offenders; deep = per-instance triage with a concrete fix proposal. Default deep.

Extra Per-Finding Fields

  • Dimension: one of the 9 below.
  • Age (when relevant): commit hash + date the debt landed (git log -L / git blame).
  • Effort: trivial (≤30 min) | small (≤2 h) | medium (≤1 day) | large (>1 day, decompose first).
  • ID convention: TD<dim>-<date>-NN (e.g. TD3-2026-09-05-02 = Dim 3 Stale Documentation, finding 2 of that report).

Severity for Tech Debt

Tech-debt findings default to LOW (see _audit-severity.md). Promote only on amplification:

| Promotion Trigger | Floor | |-------------------|-------| | Duplicated logic with divergent bug-fix history (one branch fixed, the other regressed) | MEDIUM | | unimplemented!() / todo!() / panic!("not …") reachable from a shipped CLI flag or smoke test | MEDIUM | | #[ignore]d test that guards a fix from a closed CRITICAL/HIGH issue | MEDIUM | | Stale doc/audit baseline that misled an audit in the last 90 days | MEDIUM | | Magic number that would silently over/underflow under documented use | HIGH | | Stale GpuCamera/GpuInstance/GpuMaterial size in a doc comment (lockstep-drift bait) | MEDIUM |

Phase 1: Setup

  1. Parse $ARGUMENTS. 2. mkdir -p /tmp/audit/tech-debt.
  2. Dedup baseline: gh issue list --repo matiaszanolli/ByroRedux --limit 500 --state all --label tech-debt --json number,title,state > /tmp/audit/tech-debt/issues_all.json
  3. Scan docs/audits/ for prior AUDIT_TECH_DEBT_*.md (diff direction, not re-litigation).
  4. Production-LOC helper (Dim 1's subject is production complexity, not file length — a file long from bulk inline tests is not the debt this dimension hunts). Source the checked-in script and run its self-test first; a failure means no figure below it can be trusted:
    source .claude/commands/audit-tech-debt/prod_loc.sh
    prod_loc_self_test        # must print "prod_loc self-test: ok"
    
    prod_loc <file> reports 0 for pure-test files (tests.rs, *_tests.rs, anything under tests/ — their #[cfg(test)] mod gate lives in the parent) and otherwise total LOC minus every #[cfg(test)]-gated braced item, counting braces on code only (comments, strings, raw strings and char literals stripped, #4336).
  5. Snapshot totals so the next audit can diff. tools/ is in scope (four workspace binaries); tools/nifskope is vendored and pruned:
    {
      echo "markers (TODO/FIXME/HACK/XXX/TBD/WIP/KLUDGE): $(grep -RInE '(TODO|FIXME|HACK|XXX|TBD|WIP|KLUDGE)\b' crates byroredux tools --exclude-dir=nifskope | wc -l)"
      echo "allow(dead_code):      $(grep -RInE 'allow\(dead_code\)' crates byroredux tools --exclude-dir=nifskope | wc -l)"
      echo "unimplemented!/todo!(): $(grep -RInE 'unimplemented!|todo!\(\)' crates byroredux tools --exclude-dir=nifskope | wc -l)"
      echo "#[ignore] tests:        $(grep -RInE '^[[:space:]]*#\[ignore' --include='*.rs' crates byroredux tools --exclude-dir=nifskope | wc -l)"
      echo "files >2000 production LOC: $(for f in $(find crates byroredux tools -name '*.rs' -not -path 'tools/nifskope/*'); do echo "$(prod_loc "$f")"; done | awk '$1>2000' | wc -l)"
      echo "test files >2000 total LOC (lower priority, separate bucket): $(find crates byroredux tools -name '*.rs' -not -path 'tools/nifskope/*' -exec wc -l {} + | awk '$1>2000 && $2!="total"' | wc -l)"
    } > /tmp/audit/tech-debt/baseline.txt
    
    Measured 2026-10-21 at 1be33af66 (diff direction only, re-run, never quote): markers 26 (18 are XXXX false positives — three are the --type XXXX usage placeholder in crates/plugin/examples/dump_wths_refl.rs — 2 the FO4 HACK FourCC, 3 quoted upstream FIXMEs, 1 documented TBD — Dim 5; two real TODOs in byroredux/src/loading_screen.rs, which cite the open #6194 since #6181, 51f97f708), allow(dead_code) 41 (12 of them are cfg(test) TypeId-only markers in crates/core/src/ecs/lock_tracker.rs, c5113f0d9 — not debt), unimplemented!/todo!() 0 (a fresh hit is notable), #[ignore] 363 (352 on 2026-10-20, 322 on 2026-10-15; tools-inclusive — earlier reports scoped to crates+byroredux read lower; none runs on a hosted runner), production >2000 LOC: 4 — crates/renderer/src/shader_constants_data.rs (2949, a data table, Dim 1), crates/scripting/examples/mq101_conformance.rs (2157), crates/audio/src/lib.rs (2034) and crates/nif/src/import/types.rs (2011, +10 in a day). The five scripting/save/cell monoliths of 2026-10-15 left the list through real splits — crates/scripting/src/fragment/vm.rs, crates/scripting/src/translate/effects.rs, crates/scripting/src/condition.rs, byroredux/src/save_io.rs and crates/plugin/src/esm/cell/mod.rs are now ~70–140-LOC hubs over vm/, effects/, condition/, save_io/ and cell/ directories, the largest child 1538 — as did byroredux/src/components.rs (#5467) and crates/scripting/src/fragment/effects.rs (#5468) before them. Split-hub hazard: a path-scoped git log / grep on a hub file silently sees only the hub (git log -- byroredux/src/save_io.rs returned 0 commits where the directory returned 24); scope Dim 1 deltas to the <stem>/ directory and measure a split by its children, not by the parent shrinking. Watch-list within 5%: crates/debug-ui/src/panels.rs (1934), crates/renderer/src/vulkan/context/init.rs (1921), crates/plugin/src/esm/records/misc/world.rs (1912); fastest riser crates/renderer/src/vulkan/gpu_timers.rs (1874, +57 in a day, fc83608d3), then byroredux/src/inventory.rs (1863) and byroredux/src/asset_provider/material/merge.rs (1860); test-heavy >2000: 92. A raw whole-repo grep for #[ignore] also matches markdown prose — keep --include='*.rs'.

Phase 2: Dimension Agents

Ordered by debt impact: complexity and duplication compound across every edit; doc/audit rot misdirects the next audit; markers and dead code are cheap. Recent yield (grep -h '\*\*Dimension\*\*' docs/audits/AUDIT_TECH_DEBT_*.md): Dims 4, 3, 1, 8 dominate (then 2, 9); 5 and 6 rarely surface real debt. Each agent writes /tmp/audit/tech-debt/dim_<N>.md.

Dimension 1: File / Function / Module Complexity

Paths: all .rs under crates/, byroredux/, tools/ First step: the two-bucket command below

An oversized file taxes every edit, review and merge. Threshold is 2000 production LOC. Two buckets:

# Primary — the dimension's actual subject. File real findings from this.
for f in $(find crates byroredux tools -name '*.rs' -not -path 'tools/nifskope/*'); do
    p=$(prod_loc "$f"); [ "$p" -gt 2000 ] && echo -e "$p\t$f"
done | sort -rn
# Secondary — test-heavy files, report but do not auto-file: escalate one only if its OWN prod_loc also crosses 2000.
find crates byroredux tools -name '*.rs' -not -path 'tools/nifskope/*' -exec wc -l {} + | awk '$1>2000 && $2!="total"' | sort -rn

The recipe output is authoritative. A file that once split can re-cross (a previously-split file that grew back is a live finding); a file that dips under by incidental shrinkage is still a candidate — only an actual split removes one; and files within ~5% of the line (check the snapshot) are worth naming as watch-list rows. Function-level splits inside a file and file-level splits are independent signals — a register_*_systems / phase-helper extraction does not move its host file across the line.

Per file, propose a split AXIS by responsibility, chosen after reading the file's internal structure — never from a name or a tag. Precedent: a metadata enum tag (ExtenderFamily) touching 30 of 3759 lines was not the seam; the real axis was the four-layer service stack (routes → declarations → source aliases → runtime adapters) with one service holding over half the lines (#3851). Splits that worked: Vulkan context/ and volumetrics by construct-vs-record-vs-teardown; boot.rs into one file per registration stage; runtime.rs into one file per impl <wit>::Host block. Data tables (FourCC → id maps, shader_constants_data.rs) want a static table or generation, not a split. Vulkan-recording splits are render-pass-adjacent — read feedback_speculative_vulkan_fixes before proposing barrier/order changes.

Also flag: functions >200 LOC (propose extraction); match arms >50 cases (want a lookup table); nesting depth >5; a mod.rs / lib.rs with >20 pub use (two jobs). cargo +nightly clippy --all-targets -- -W clippy::cognitive_complexity if available, else inspect the worst offenders.

Dimension 2: Logic Duplication

Paths: sibling-file families under crates/nif/src/blocks/, crates/plugin/src/esm/records/, crates/renderer/src/vulkan/, byroredux/src/cell_loader/, byroredux/src/systems/ First step: ls crates/nif/src/blocks/*.rs crates/plugin/src/esm/records/*.rs crates/plugin/src/esm/records/*/*.rs crates/renderer/src/vulkan/*.rs byroredux/src/cell_loader/*.rs, then read two siblings side by side

CLAUDE.md global policy: improve existing code, never duplicate logic. Every finding names a concrete consolidation site (an existing helper to extend, or the new one and its callers). Look for: block-parser scaffolding (header → field → fixup) repeated across crates/nif/src/blocks/; texture-upload chains (BC1/BC3/BC5/RGBA) and image-layout barrier sequences repeated per pass in crates/renderer/src/vulkan/ (vulkan/image.rs GpuImage and the shared barrier helpers are the consolidation targets — a pass that still hand-rolls create/bind/destroy is a candidate); vk::WriteDescriptorSet / DescriptorSetLayoutBinding builder boilerplate (one home since #5593, c6d36b4e7: descriptors::{layout_binding,compute_binding,write_*}, vulkan/mod.rs's shared try_or_cleanup! and GpuBuffer::create_per_frame_uniforms, pinned by passes_build_layouts_writes_and_teardown_through_the_shared_helpers — a pass that re-spells the five-line binding chain or a local cleanup macro is a regression; the bindless texture layout is the one deliberate exception; since #5809, 31f4919d5, the same guard requires descriptors::clamp_sampler for clamp-to-edge samplers, with the genuinely different ones allowlisted); other single homes landed by the 2026-10-15 wave — the upload_ctx! macro for the GpuUploadCtx literal (#5823), with_extension_host for the extension dispatch tail (#5810), World::init_resource for insert-if-absent (#5806), byroredux_core::bytes for little-endian reads in the bin (#5818, no_production_code_reads_le_ints_by_hand) and the asset_provider layer for archive access (#5009, no_production_code_opens_archives_outside_the_provider_layer); ESM sub-record parse loops across crates/plugin/src/esm/records/; AI-procedure systems sharing scaffolding; near-identical per-game HUD/profile tables; source-scan helpers (production_text, production_text_or_whole, strip_test_modules, count_identifier) have ONE home, crates/core/src/source_scan.rs (#5100, 655b317c9; #5469, 334458b3f routed the ~40 surviving inline cuts through it) — a re-copied cut in a test module is a regression; no_source_scan_cuts_with_the_weak_cfg_test_needle (byroredux/src/workspace_hygiene_tests.rs) fails a new weak #[cfg(test)] find/split outside its allowlist. The Z-up→Y-up conversion has one home, crates/core/src/math/coord.rs (zup_to_yup_pos, zup_to_yup_quat_wxyz); re-exports elsewhere are not leaks — a genuine reimplementation would live outside that file.

Dimension 3: Stale Documentation & Comments

Paths: docs/, ROADMAP.md, HISTORY.md, README.md, CLAUDE.md, doc comments across the tree First step: .claude/commands/_audit-validate.sh

Doc rot misleads the next reader and the next audit. Run the gate first: _audit-validate.sh resolves every backticked path in the audit skills AND docs/engine/*.md against the tree (fatal on STALE) and lists backticked symbols found in no tracked .rs file (advisory — clear it, do not learn to scroll past it). STALE refs are auto-eligible findings (trivial). Guards that already police a class — aim at what they cannot see:

  • GPU-struct sizes: gpu_material_size_claims (crates/renderer/src/vulkan/material_tests.rs) scans crates, byroredux, tools, docs/engine, .claude/commands and the top-level status docs for a stale byte count of every size-pinned struct — GpuMaterial, GpuLight, GpuTerrainTile, GpuInstance, GpuCamera since #5203 (pinned_sizes(); plus bindings_glsl_states_the_real_struct_size). It CANNOT see Vertex::SIZE (a size written without the type name) or GpuWaterParams-class structs outside pinned_sizes() — cross-check those against the layout tests, never the prose: grep -rn "fn gpu_.*_is_[0-9]\+_bytes\|size_of::<Gpu" crates/renderer/src/vulkan/. A GPU-size claim found stale in prose is MEDIUM (severity table).
  • Deleted Material::classify_pbr: no_source_file_frames_the_deleted_classify_pbr_as_live (byroredux/src/workspace_hygiene_tests.rs) fails a doc that names it as live. The survivors are the free fn classify_pbr_keyword and Material::resolve_pbr.
  • Beyond the guards, sweep: doc comments naming renamed/deleted symbols (git log --diff-filter=D --since=<last> then grep each deleted name); ROADMAP.md milestones "in progress" whose issues are closed (or vice versa) — cross-check git log / gh issue; docs/feature-matrix.md rows against the crate that implements them (git log --grep M45, …) — it is a status floor, so flag any row contradicting shipped code; HISTORY.md entries referencing reverted work; README.md / CLAUDE.md command examples whose flags or paths changed; per-game compat numbers in docs/engine/game-compatibility.md vs ROADMAP.md's matrix (ROADMAP is the single home); docs/legacy/ Gamebryo source paths that moved; crates/renderer/shaders/triangle.frag comments quoting outdated struct sizes.
  • docs/engine/*.md are the "authoritative" references audits are told to believe (_audit-common.md): beyond the gate's path/symbol check, sample their numbers and lists against code — stage order and lock order (ecs.md), VRAM/pool figures (memory-budget.md), shader binding tables (shader-pipeline.md), dependency and crate lists — a doc that misled an audit in the last 90 days is MEDIUM.
  • Path convention: a backticked path or snake_case symbol in an audit skill asserts "exists right now"; deleted or forward-looking names go in italics or plain text (_audit-common.md Path-Reference Convention).

Dimension 4: Audit-Finding Rot

Paths: .claude/commands/, docs/audits/ First step: .claude/commands/_audit-validate.sh then ls .claude/commands/ docs/audits/ | tail -40

Stale baselines actively misdirect future audits.

  • STALE refs the gate prints in other audit skills → Dim 4 findings (trivial); advisory symbols in skills likewise.
  • Numeric claims in skills and _audit-common.md (LOC figures, struct sizes, counts, "all N dimensions") — the gate cannot see numbers: re-measure a sample (wc -l, prod_loc, grep -c) and flag any off by >20%. Layout-row LOC drift has been the single most repeated finding here.
  • "Existing: #NNN" / "open issue" callouts in skills where the issue is now CLOSED: gh issue view N --json state.
  • Dimension cross-references between skills ("/audit-x Dim N") that no longer name that dimension.
  • docs/audits/ reports older than 90 days whose CRITICAL/HIGH findings have no GitHub trace. Caveat: reports dated before 2026-06-07 predate /audit-publish, so a missing issue is not evidence a finding is open (#3875, _audit-common.md Deduplication) — verify against code and say which you checked.
  • Do NOT flag .claude/issues/<N>/ISSUE.md "Status: Open" drift: local issue files are immutable snapshots (TD10-001 / #1156); gh issue view <N> --json state is authoritative.

Dimension 5: Stale Markers (TODO / FIXME / HACK / XXX / TBD)

Paths: crates/, byroredux/, tools/ (not tools/nifskope), crates/renderer/shaders/ First step: the two greps below

grep -RInE '(TODO|FIXME|HACK|XXX|TBD|WIP|KLUDGE)\b' crates byroredux tools --exclude-dir=nifskope
grep -RInE '(TODO|FIXME|HACK|XXX|TBD|WIP|KLUDGE)\b' crates/renderer/shaders/

Keep the token list identical in both commands (an asymmetry once hid every shader FIXME, #3877); TBD is in it because the codebase uses it. tools/ (byro-dbg, byro-launcher, byro-detect, texture-upscale) is first-party and in scope. Triage each (skip markers <30 days old unless they name a closed issue): git blame for age — over 6 months gets reported; does it name an issue, and is that issue still open (closed issue + live marker = "marker outlived its driver"); does it name a milestone now complete per ROADMAP.md; a // TODO: implement on a path reachable from a shipped CLI flag promotes (severity table). False positives: XXXX, the ESM extended-size sub-record tag (key on comment content — "references the ESM XXXX escape" — not a file list; reader.rs, cell/wrld.rs, the b"XXXX" test sentinels in records/misc/magic.rs and the FourCC table doc in sdk/src/compatibility/storage_util/mod.rs all qualify); HACK, the FO4 terminal-record FourCC (crates/plugin/tests/parse_real_esm.rs); a // FIXME quoting a reference implementation's own FIXME (crates/bgsm/src/bgem.rs, bs_geometry.rs) documents upstream; a TBD that records an unresolved format semantic together with its own resolution (the FNV WEAP DNAM arm in crates/plugin/src/esm/records/items.rs) is a documented unknown, not a stale marker. Must-not-delete: the third-party attribution block atop crates/renderer/shaders/triangle.frag (GLSL-PathTracer MIT notice + Burley citation, ~first 30 lines). Flag any edit that strips it — MIT requires the notice to travel with the code.

Dimension 6: Stub & Placeholder Implementations

Paths: crates/, byroredux/, tools/ First step: the two greps below

grep -RInE 'unimplemented!|todo!\(\)|panic!\("not ' crates byroredux tools --exclude-dir=nifskope
grep -RInE '// *(stub|TODO: real|placeholder|not yet)' crates byroredux tools --exclude-dir=nifskope

The first command should return nothing — any hit is notable. For each: reachable from a shipped CLI flag or smoke test → MEDIUM; functions returning None / Vec::new() / Default::default() under a stub comment; trait impls with empty bodies the trait docs say should do work; console commands in byroredux/src/commands/ that no-op or print "TODO". Production-unreachable features are the yield here: a public builder/system with zero non-test callers whose docs or ROADMAP say it is wired (a ruleset builder that main never calls; a component nothing inserts). For a candidate name: grep -rnw name crates byroredux tools --include='*.rs' and drop test-only hits. Cross-check per-game ESM record coverage in crates/plugin/src/esm/records/ against the ROADMAP.md compat matrix (wired vs stubbed).

Dimension 7: Magic Numbers & Hardcoded Constants

Paths: crates/nif/src/blocks/, crates/renderer/, crates/plugin/src/esm/records/ First step: read the version-gate and budget sites; do not regex blindly (most literals are legitimate)

  • Bare numeric literals compared against version codes in crates/nif/src/blocks/ → a NifVersion constant.
  • Vulkan MAX_* / MIN_* hardcoded inline → vk::PhysicalDeviceLimits or a named constant.
  • Shader #define provenance: every define is generated from crates/renderer/src/shader_constants_data.rs (include!d by shader_constants.rs and crates/renderer/build.rs, which emits shaders/include/shader_constants.glsl); source-scan tests in shader_constants.rs police the generated header. The check is "every shader #define / loop bound / budget literal that bypasses that file" (lockstep risk HIGH — feedback_shader_struct_sync).
  • GPU #[repr(C)] size literals: reference the layout pins (Dim 3 has the recipe and the guards); an inline size literal that should reference them is a code finding here, a stale prose figure is Dim 3.
  • Frame/ray/cache budgets (MAX_TOTAL_BONES, MAX_MATERIALS, …) scattered vs one tunable module; ESM sub-record sizes hardcoded (if data.len() == 24) → a named constant on the record struct.
  • Do NOT flag protocol-defined magic: FourCC tags, BSA/NIF/BA2 magic, Vulkan format enums.

Dimension 8: Dead Code & Backwards-Compat Cruft

Paths: crates/, byroredux/, tools/, every Cargo.toml First step: cargo clippy --workspace --keep-going -- -D warnings (the CI gate) and the greps below

grep -RInE 'allow\(dead_code\)' crates byroredux tools --exclude-dir=nifskope
grep -RInE '#\[deprecated\]|// *removed:|_unused|fn .*_unused' crates byroredux
cargo machete --with-metadata 2>/dev/null || echo "cargo machete not installed — scan Cargo.toml deps vs use stmts"
  • Unused-dependency gate: CI job Unused dependencies runs cargo machete --with-metadata (#3890; --with-metadata since #5851, 251d491ef, so [dev-dependencies] workspace entries are seen too, plus a Cargo.lock drift check) — a red run is a finding. Its blind spots are macro-only and re-export-only use (the job comment says so); the hand scan earns its keep there and on deps used only under a non-default feature.
  • Clippy gate (CI job Test + Check + Clippy runs cargo clippy --workspace --keep-going -- -D warnings plus a renderer-only undocumented_unsafe_blocks re-lint, #5121; the toolchain is pinned at 1.96.0 by rust-toolchain.toml since #5308 (b24cb46b6) after floating stable let rustc 1.99's chunks_exact_to_as_chunks wave turn the gate red for four days — rustc 1.96 (800802516) and 1.98 (530c9e7aa) raised lints on untouched code too; a toolchain bump is now a deliberate commit, and the distro cargo ignores the pin; wasmtime 49's MSRV is exactly 1.96.0, 15a6b1d2d, so the pin can rise but not fall). A red gate is a finding: list each failing lint and file, plus the crates it left unlinted — --keep-going lints every crate that still compiles, but a crate red under clippy leaves its dependents unchecked (a red byroredux-nif skips the bin). CI also runs --all-targets --keep-going as a NON-blocking step (continue-on-error, #5621, a3ccd68fb: test/example-target lints re-accumulate on active days; both forms were re-zeroed in 9896b1cf7 / 8b0b922f5 and again by #5849 / #5850, 251d491ef) — a red non-blocking step is a lower-priority bucket, not a gate failure (the workspace example build itself went red once, the #3894 class, 530c9e7aa). Check every #[allow(clippy::…)] carries a reason comment (the house style for too_many_arguments).
  • Each #[allow(dead_code)]: called now or still dead? Delete if dead. pub fn in a private module nobody imports (cargo +nightly rustc -p <crate> -- -W unused); mod.rs/lib.rs re-exports with no consumer; _-prefixed params that survived a refactor (delete, do not rename); // removed: … breadcrumbs (delete completely); re-exports of deleted types "for compatibility" (no external consumers exist — pure rot); #[deprecated] items with no consumers; Cargo.toml feature flags with one branch always on/off.
  • Do NOT flag: cfg(test) / cfg(debug_assertions)-gated code, FFI boundary functions, or the public API of a workspace-internal crate a future binary will consume (note it rather than deleting).

Dimension 9: Test Hygiene

Paths: every #[test]/#[ignore] site, .github/workflows/ci.yml, byroredux/tests/ First step: the ignore-triage command below

# All ignores (matches BOTH `#[ignore]` and the reason form `#[ignore = "…"]` — do not tighten to a bare `]`)
grep -RInE '^[[:space:]]*#\[ignore' --include='*.rs' crates byroredux tools
# Ignores whose reason is NOT a data/hardware gate — the triage input
grep -RInE '^[[:space:]]*#\[ignore' --include='*.rs' crates byroredux tools | grep -viE 'game data|installed|\.(bsa|ba2|esm)|BSA|BA2|ESM|audio device|vulkan|gpu|rt-capable|display|opt-in|corpus|real (data|master)|steam|env'
  • Guards: workspace_hygiene_tests (byroredux/src/workspace_hygiene_tests.rs) — every_ignore_attribute_carries_a_reason (a bare #[ignore] fails; the reason text is the triage input), no_tmp_scratch_examples_are_committed (_tmp_* / tmp_* probes) plus no_committed_example_self_describes_as_disposable (module doc opening "throwaway / one-off / TEMP", #5114), no_test_attribute_is_stacked_on_another, example_targets_hold_their_per_crate_ceilings (per-crate example file/LOC ceilings, #5856 — a raised ceiling must come with a re-measure in the same commit), and the classify_pbr check (Dim 3). Confirm they are not themselves #[ignore]d.
  • Closed-HIGH real-data pins: .github/real-data-pins.txt lists the #[ignore]d real-data tests guarding closed CRITICAL/HIGH fixes; no hosted runner executes them (scripts/run-real-data-pins.sh is the local run). Since #6183 (9ee74b6e7) every_real_data_pin_names_an_ignored_test_in_its_lane checks each row names a real ignored fn its lane compiles. A closed-HIGH guard test that is #[ignore]d but absent from the list is the MEDIUM row above.
  • Most #[ignore]s gate Vulkan / game-data / audio tests — not debt. Triage the remainder: does a reason name an issue (gh issue view N), and if it guards a closed CRITICAL/HIGH fix → MEDIUM.
  • Tests with only smoke assertions (assert!(result.is_ok())); commented-out assertions in passing tests; tests that println! without an assert.
  • Feature gates vs CI lanes: enumerate [features] (grep -A6 '^\[features\]' crates/*/Cargo.toml byroredux/Cargo.toml) and compare with .github/workflows/ci.yml — non-default states run only where a lane names them (today: core inspect/save and scripting save via workspace unification, byroredux-spt --features recon, byroredux without debug-server / with tracing-tracy / with dhat-heap, byroredux-nif --features dhat-heap). A feature or required-features target with no lane can rot silently (the class #3894 / #4387 / #4390 closed).
  • byroredux/tests/golden_frames.rs (opts into --ignored) — still runnable, golden images current.
  • Cross-reference "must not regress" lines in other audit skills — each named regression test still exists and is not #[ignore]d (_audit-validate.sh advisory names symbols that are gone).

Cross-Dimension Dedup

A TODO inside a dead function reports under Dim 8, not also Dim 5. Material doc rot reports under Dim 3, not Dim 8. A stale GPU-size doc comment is Dim 3; a stale GPU-size code literal is Dim 7. NIFAL/material translation correctness is out of scope (/audit-nifal) — this audit owns only the debt around that tier.

Phase 3: Merge

  1. Read all /tmp/audit/tech-debt/dim_*.md.
  2. Combine into docs/audits/AUDIT_TECH_DEBT_<TODAY>.md: Executive Summary (findings by severity + delta vs baseline.txt), Baseline Snapshot (the Phase-1 counts), Top 10 Quick Wins (trivial/small effort), Top 5 Medium Investments (splits, consolidations), Findings (HIGH → MEDIUM → LOW, then by dimension), Deferred (gated on an in-progress milestone; name it).
  3. Remove cross-dimension duplicates per the rules above.

Phase 4: Cleanup

rm -rf /tmp/audit/tech-debt; tell the user the report is ready; suggest /audit-publish docs/audits/AUDIT_TECH_DEBT_<TODAY>.md.

GitHub Labels

Findings publish under tech-debt (plus the standard <severity> and <domain> labels; /audit-publish applies it for TECH_DEBT reports). Two sibling kind labels split the bucket — apply the one that matches:

  • doc-rot — documentation drifted from code (stale ROADMAP row, a SKILL naming a deleted symbol, a comment describing removed behaviour); publishes as documentation, not bug.
  • test-gap — missing, vacuous or non-asserting coverage (an #[ignore]d test with no data gate, an entry point with zero tests). Pure debt (dead code, duplication, magic numbers, oversized files, stale markers) stays tech-debt + bug.

From the file to a first result

The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.

View the source and supporting files

This download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.

1. Download the file

Download SKILL.md

From the root of a test project, save the file as .skill-downloads/technical-debt-audit-mvj1octe/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.

Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.

mkdir -p '.skill-downloads/technical-debt-audit-mvj1octe' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/technical-debt-audit-mvj1octe/download' --output '.skill-downloads/technical-debt-audit-mvj1octe/SKILL.md.part' && mv '.skill-downloads/technical-debt-audit-mvj1octe/SKILL.md.part' '.skill-downloads/technical-debt-audit-mvj1octe/SKILL.md'

2. Check prerequisites

Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.

No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.

The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.

3. Load the skill

This file does not provide a usable name/description header for this native procedure. It remains available to download and inspect; use the manual method below.

Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.

4. Try a first task

Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:

Read .skill-downloads/technical-debt-audit-mvj1octe/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.

Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.

Related skills