Synthèse automatique
Commande d'audit spécifique au dépôt ByroRedux, destinée à Claude Code, qui recherche la dette technique accumulée selon neuf dimensions : marqueurs obsolètes, code mort, duplication, nombres magiques, implémentations bouchon, documentation périmée et fichiers surdimensionnés.
Points forts
- Repose sur des recettes de découverte réexécutables et sur l'énumération du code actuel, plutôt que sur une liste de constats figée.
- Prévoit des règles explicites de promotion de sévérité et des métadonnées par constat (dimension, ancienneté, effort, identifiant).
- Déduplique les constats par rapport aux tickets GitHub tech-debt et aux rapports d'audit précédents, avec paramètres --focus et --depth.
- Utilise un script de comptage des lignes de production avec autotest pour distinguer la complexité du code de production des tests volumineux.
Limites
- Très liée au dépôt ByroRedux, à sa liste de crates Rust, à ses labels GitHub et à ses fichiers compagnons .claude/commands.
- L'audit ne corrige ni ne valide les problèmes : il produit uniquement des constats.
- Nécessite gh, cargo, l'historique git et les rapports antérieurs ; l'orchestration par agents peut être coûteuse sur de grands périmètres.
À utiliser pour un nettoyage périodique ou un audit avant refactorisation de ByroRedux, lorsqu'il faut dresser un inventaire structuré de la dette technique accumulée.
Ne pas l'utiliser pour rechercher des bugs de correction, de sécurité ou de performance, ni sur un autre dépôt que ByroRedux sans adapter les chemins, la liste des crates et les fichiers compagnons.
Analyse de sécurité
PrudenceThis 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.
- •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.
Exemples
Run /audit-tech-debt --focus 1,3,5 --depth shallow and report the worst offenders in those dimensions.Run a deep tech-debt audit of ByroRedux and prioritize crates that were not named in the last audit report.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. Defaultdeep.
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
- Parse
$ARGUMENTS. 2.mkdir -p /tmp/audit/tech-debt. - 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 - Scan
docs/audits/for priorAUDIT_TECH_DEBT_*.md(diff direction, not re-litigation). - 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:
prod_locsource .claude/commands/audit-tech-debt/prod_loc.sh prod_loc_self_test # must print "prod_loc self-test: ok"<file>reports 0 for pure-test files (tests.rs,*_tests.rs, anything undertests/— their#[cfg(test)] modgate 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). - Snapshot totals so the next audit can diff.
tools/is in scope (four workspace binaries);tools/nifskopeis vendored and pruned:Measured 2026-10-21 at 1be33af66 (diff direction only, re-run, never quote): markers 26 (18 are{ 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.txtXXXXfalse positives — three are the--type XXXXusage placeholder incrates/plugin/examples/dump_wths_refl.rs— 2 the FO4HACKFourCC, 3 quoted upstream FIXMEs, 1 documentedTBD— Dim 5; two real TODOs inbyroredux/src/loading_screen.rs, which cite the open #6194 since #6181, 51f97f708),allow(dead_code)41 (12 of them arecfg(test)TypeId-only markers incrates/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 tocrates+byroreduxread 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) andcrates/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.rsandcrates/plugin/src/esm/cell/mod.rsare now ~70–140-LOC hubs overvm/,effects/,condition/,save_io/andcell/directories, the largest child 1538 — as didbyroredux/src/components.rs(#5467) andcrates/scripting/src/fragment/effects.rs(#5468) before them. Split-hub hazard: a path-scopedgit log/grepon a hub file silently sees only the hub (git log -- byroredux/src/save_io.rsreturned 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 risercrates/renderer/src/vulkan/gpu_timers.rs(1874, +57 in a day, fc83608d3), thenbyroredux/src/inventory.rs(1863) andbyroredux/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) scanscrates,byroredux,tools,docs/engine,.claude/commandsand the top-level status docs for a stale byte count of every size-pinned struct —GpuMaterial,GpuLight,GpuTerrainTile,GpuInstance,GpuCamerasince #5203 (pinned_sizes(); plusbindings_glsl_states_the_real_struct_size). It CANNOT seeVertex::SIZE(a size written without the type name) orGpuWaterParams-class structs outsidepinned_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 fnclassify_pbr_keywordandMaterial::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-checkgit log/gh issue;docs/feature-matrix.mdrows 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.mdcommand examples whose flags or paths changed; per-game compat numbers indocs/engine/game-compatibility.mdvs ROADMAP.md's matrix (ROADMAP is the single home);docs/legacy/Gamebryo source paths that moved;crates/renderer/shaders/triangle.fragcomments quoting outdated struct sizes. docs/engine/*.mdare 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.mdPath-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-xDim 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.mdDeduplication) — 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 stateis 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/→ aNifVersionconstant. - Vulkan
MAX_*/MIN_*hardcoded inline →vk::PhysicalDeviceLimitsor a named constant. - Shader
#defineprovenance: every define is generated fromcrates/renderer/src/shader_constants_data.rs(include!d byshader_constants.rsandcrates/renderer/build.rs, which emitsshaders/include/shader_constants.glsl); source-scan tests inshader_constants.rspolice 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 dependenciesrunscargo machete --with-metadata(#3890;--with-metadatasince #5851, 251d491ef, so[dev-dependencies]workspace entries are seen too, plus aCargo.lockdrift 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 + Clippyrunscargo clippy --workspace --keep-going -- -D warningsplus a renderer-onlyundocumented_unsafe_blocksre-lint, #5121; the toolchain is pinned at 1.96.0 byrust-toolchain.tomlsince #5308 (b24cb46b6) after floatingstablelet 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-goinglints every crate that still compiles, but a crate red under clippy leaves its dependents unchecked (a redbyroredux-nifskips the bin). CI also runs--all-targets --keep-goingas 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 fortoo_many_arguments). - Each
#[allow(dead_code)]: called now or still dead? Delete if dead.pub fnin a private module nobody imports (cargo +nightly rustc -p <crate> -- -W unused);mod.rs/lib.rsre-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.tomlfeature 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) plusno_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 theclassify_pbrcheck (Dim 3). Confirm they are not themselves#[ignore]d. - Closed-HIGH real-data pins:
.github/real-data-pins.txtlists the#[ignore]d real-data tests guarding closed CRITICAL/HIGH fixes; no hosted runner executes them (scripts/run-real-data-pins.shis the local run). Since #6183 (9ee74b6e7)every_real_data_pin_names_an_ignored_test_in_its_lanechecks each row names a real ignoredfnits 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 thatprintln!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:coreinspect/saveandscriptingsavevia workspace unification,byroredux-spt --features recon,byroreduxwithoutdebug-server/ withtracing-tracy/ withdhat-heap,byroredux-nif --features dhat-heap). A feature orrequired-featurestarget 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.shadvisory 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
- Read all
/tmp/audit/tech-debt/dim_*.md. - Combine into
docs/audits/AUDIT_TECH_DEBT_<TODAY>.md: Executive Summary (findings by severity + delta vsbaseline.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). - 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 asdocumentation, notbug.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) staystech-debt+bug.
Du fichier au premier essai
Le téléchargement contient exactement le contenu affiché sur cette fiche. Cette copie peut différer de la dernière version du dépôt source.
Consulter la source et ses fichiers annexesCe téléchargement contient uniquement SKILL.md. Les scripts, références, modèles et dépendances éventuels ne sont pas inclus. Récupérez les fichiers nécessaires depuis la source en conservant leur arborescence avant de poursuivre.
1. Télécharger le fichier
Télécharger SKILL.mdDepuis la racine d’un projet de test, enregistrez le fichier sous .skill-downloads/technical-debt-audit-mvj1octe/SKILL.md, ou utilisez la commande suivante. Ce dossier sert à examiner la skill avant son installation.
Commande pour macOS/Linux ou WSL : un shell POSIX et curl sont nécessaires. Sous Windows sans WSL, utilisez le bouton de téléchargement et créez le dossier manuellement.
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. Vérifier les prérequis
Lisez SKILL.md avant de l’utiliser. Si le fichier cite des scripts ou services externes, examinez-les et préparez les accès nécessaires dans votre environnement de test.
Aucune section de prérequis reconnue dans ce fichier. Cela ne signifie pas qu’il est autonome : les bibliothèques, outils et accès peuvent être cités ailleurs dans le contenu ou dans le dépôt source.
Les plateformes de la fiche sont des indications du catalogue. Les chemins ci-dessous suivent la documentation des outils ; ils ne prouvent pas que cette skill y a été exécutée. Aucune version minimale de ces outils n’est attestée pour cette fiche.
3. Charger la skill
Le fichier ne fournit pas un en-tête name/description exploitable pour cette procédure native. Le téléchargement reste disponible pour lecture ; utilisez le mode manuel ci-dessous.
Mode manuel ou autre outil : joignez SKILL.md à une conversation, ou ouvrez-le dans un agent capable de lire les fichiers. Ajoutez les ressources annexes nécessaires. Il n’existe pas de dossier universel reconnu par tous les outils.
4. Faire un premier essai
Utilisez une entrée courte et fictive : un endpoint d’API, un petit document ou un brief d’interface. Dans une nouvelle conversation, joignez le fichier ou donnez son chemin à l’agent, puis adaptez cette demande :
Lis .skill-downloads/technical-debt-audit-mvj1octe/SKILL.md et applique ses instructions à cet exemple : [décrire une entrée de test]. Indique les fichiers, dépendances ou accès qui manquent. Produis le résultat demandé par la skill sans inventer de données ni exécuter de script non examiné.Résultat attendu : une sortie correspondant aux instructions de la skill, ou une liste précise des prérequis manquants. Une simple confirmation de lecture ne valide pas le premier usage. Si une ressource externe est indisponible, ce parcours reste à tester.
Bonnes pratiques React Hook Form
Developpement
Maîtrisez React Hook Form : évitez les anti-patterns, gérez les abonnements, et traitez correctement reset, dirty state et entrées contrôlées.
Migration Emotion vers Mantine
Developpement
Migrer les styled-components Emotion vers des composants Mantine avec style props et modules CSS. Pour convertir .styled.tsx ou supprimer les imports @emotion.
Détecteur de dérive de périmètre
Developpement
Analyse les diffs git par rapport à une intention pour détecter la dérive de périmètre, fichiers non liés et PR trop larges, puis suggère de garder, diviser ou justifier.