Synthèse automatique
Skill d'audit qui vérifie la compatibilité du moteur ByroRedux avec le contenu Fallout 4 en répartissant cinq dimensions d'analyse (precombines M49/CSG, BA2, matériaux BGSM, NIF BSVER, données ESM) entre des sous-agents.
Points forts
- Frontières de responsabilité explicites : chaque défaut est redirigé vers le skill propriétaire (audit-parsers, audit-nif, audit-esm, audit-physics, etc.) au lieu d'être traité ici
- Liste des fonctionnalités déjà livrées servant de garde-fou anti-régression, avec consigne de ne jamais les re-proposer comme travaux en attente
- Orchestration structurée par dimensions avec plafond de trois agents concurrents et chemins de fichiers précis pour chaque dimension
- Étapes de préparation concrètes : récupération des issues GitHub pour la déduplication et vérification de la présence des données de jeu locales
Limites
- Très fortement couplé à un dépôt privé unique (ByroRedux) avec des chemins codés en dur comme /mnt/data/SteamLibrary, donc non réutilisable tel quel ailleurs
- Le fichier fourni s'interrompt au milieu de la Dimension 1 : seules les premières instructions du premier des cinq axes sont réellement visibles
- Nécessite l'installation locale de Fallout 4 pour la validation sur données réelles ; sans elle, plusieurs dimensions perdent leur vérification concrète
- Aucun critère de sortie ni format de rapport final n'est spécifié dans la partie disponible
À utiliser lorsqu'un contributeur de ByroRedux veut vérifier qu'une modification récente n'a pas cassé le support du contenu Fallout 4.
À éviter sur un autre moteur ou dépôt, ou sans les données Fallout 4 installées et l'historique d'issues accessible.
Analyse de sécurité
PrudenceThe skill is a large read-mostly audit orchestrator: it inspects a Rust game engine, greps git history, runs existing test suites, optionally queries GitHub issues, and writes markdown reports. Nothing destructive, no curl|sh, no base64 payloads, no credential or token handling, no attempt to disable safety controls or to redirect the assessing agent's role. Risk comes only from ordinary power-tool usage - bash, network access through gh, reading host paths outside the repo, executing repo test code, and delegated subagents - so it rates caution rather than risky.
- •No declared allowed-tools, yet the workflow drives shell commands through orchestrator and subagent steps (mkdir -p /tmp/audit/fo4, git log, cargo test, gh issue list), so tool scope is implicit rather than declared.
- •Network egress to GitHub via `gh issue list --repo matiaszanolli/ByroRedux` - read-only, but it is an outbound call made without an explicit tool grant.
- •Reads absolute host paths outside the repository (`/mnt/data/SteamLibrary/steamapps/common/Fallout 4/Data/`) and an env-var-supplied data root (`BYROREDUX_FO4_DATA`), which pulls third-party game assets into the audit context.
- •Instructs running `cargo test -- --ignored` (including real-data integration tests) against the target repo, i.e. executing repository code and parsing untrusted binary game assets.
- •Spawns up to three concurrent Task subagents (`general-purpose`, `legacy-specialist`) whose tool permissions are inherited and not themselves constrained by this file.
- •Writes output into the working repo (`docs/audits/AUDIT_FO4_<TODAY>.md`, `/tmp/audit/fo4/dim_*.md`) and hands off to `/audit-publish`, which a reviewer should confirm before granting write access.
- •Minor, non-malicious: the text contains directives aimed at the reviewing agent ('do not re-file', 'never re-propose as pending', 'do not guess'). These are editorial policy statements, not an injection attempt, but they are instructions inside untrusted content and were not followed.
- •No allowed-tools declared, yet the workflow requires shell execution (`mkdir -p /tmp/audit/fo4`, `git log`, `cargo test`), network access (`gh issue list --repo matiaszanolli/ByroRedux`), reads from a local game install (`/mnt/data/SteamLibrary/.../Fallout 4/Data/`), and spawning up to 3 concurrent Task subagents — powerful capability is implicit rather than scoped.
- •Writes artifacts outside a stated sandbox (`/tmp/audit/fo4/dim_*.md` and `docs/audits/AUDIT_FO4_<TODAY>.md`), and one phase suggests a follow-on action (`/audit-publish`) that would commit/modify repository docs; side effects are legitimate for an audit but not bounded in the file.
- •Relies on `${ARGUMENTS}`-derived interpolation into shell commands in spirit (`--focus`, `--cell MedTekResearch01`, `BYROREDUX_FO4_DATA=…`) without quoting/validation guidance, so a crafted argument could alter invoked commands.
- •No destructive, exfiltrating, or obfuscated actions found: no `rm -rf`, no `curl|sh`, no base64 payloads, no secret/token handling, no safety-disabling instructions.
- •No prompt-injection or role-change attempt observed inside the skill body.
Exemples
Run the Fallout 4 compatibility audit across all five dimensions and report findings grouped by dimension.Audit FO4 Dimension 1 only — M49 precombined geometry decode and spawn paths — and flag any regressions against the shipped CSG pipeline.Check the FO4 BGSM/BGEM material merge path and the BSVER shader-flag band guards (130 typed vs 131 gap vs 132+ CRC) for regressions.description: "Per-game audit of Fallout 4 compatibility — BA2, half-float verts, BGSM materials, M49 precombines (CSG)" argument-hint: "--focus <dimensions>"
Fallout 4 Compatibility Audit
Deep audit of ByroRedux readiness for Fallout 4 content.
Architecture: Orchestrator. Each dimension runs as a Task agent (max 3 concurrent).
Read .claude/commands/_audit-common.md (layout, game data, dedup, finding format) and .claude/commands/_audit-severity.md. This file carries only FO4-specific context.
Scope: this skill owns FO4's data through the shared mechanisms. Defects in the mechanism itself go to the owner: BA2/CSG/BGSM/.uvd reader discipline → /audit-parsers; NIF block parsing → /audit-nif; ESM walker → /audit-esm; canonical-material invariants → /audit-nifal; Scaleform HUD (--hud, byroredux/src/scaleform_hud.rs, docs/smoke-tests/m48-7-fo4-hud.sh, AVM2/BGSCodeObj) → /audit-ui; ragdoll articulation incl. the FO4 bhkRagdollSystem decode (crates/nif/src/blocks/collision/np_ragdoll.rs) and docs/smoke-tests/fo4-ragdoll.sh → /audit-physics; the Havok 2014 behavior-graph reader (crates/hkx/) → /audit-parsers, its runtime (byroredux/src/asset_provider/{actor_graph,object_graph,archetype_idle}.rs, byroredux/src/systems/graph_locomotion.rs) → /audit-gameplay Dim 5; the LSCR loading model (FO4 TNAM → TRNS, byroredux/src/systems/loading_model.rs, docs/smoke-tests/p6-loading-model.sh) → /audit-gameplay Dim 6; terrain, ground cover (the Commonwealth is arid since 1a2330361) and WTHR → /audit-exterior; runtime telemetry (.claude/audit-baselines/runtime/fo4-InstituteBioScience.tsv) → /audit-runtime — run it after any precombine / SCOL / spawn change (#5484's skip-set fix, 777351ec1, moved its draw / entity / BLAS rows; that recapture is still owed).
Everything below is shipped — audit as regression guard, never re-propose as pending: NIF BSVER 130+ incl. Next-Gen, BA2 v1/v7/v8, the BGSM/BGEM parser, SCOL/PKIN expansion, M49 CSG precombines, BSConnectPoint attach graph.
Game Context
| Aspect | State |
|---|---|
| NIF | BSVER 130 + Next-Gen patches (FALLOUT4..FO4_DLC_UPPER = 130..=139 carries the DLC trailing fields, crates/nif/src/version.rs) |
| Shader flags | typed u32 pair at BSVER 130 only; BSVER 131 (FO4_SHADER_GAP) has neither; BSVER ≥ 132 uses CRC arrays. Guard: bsver_shader_flag_band_tests (version.rs), gates carries_typed_shader_flags / carries_crc_shader_flags |
| Materials | PBR params live in external .bgsm/.bgem; the NIF carries a path stub. crates/bgsm/ parses; merge_external_material folds into ImportedMesh.material before translate_material |
| Precombines | crates/bsa/src/csg.rs → crates/nif/src/import/precombine.rs → byroredux/src/cell_loader/precombined.rs; per-REFR skip set = the CELL XCRI pair tail, never XPRI (#5484). Spec docs/engine/fo4-csg-format.md |
| Data | /mnt/data/SteamLibrary/steamapps/common/Fallout 4/Data/; bench --cell MedTekResearch01 (ROADMAP) |
Parameters / Setup
--focus <dimensions> (comma-separated, default all 5). Setup: parse $ARGUMENTS; mkdir -p /tmp/audit/fo4; gh issue list --repo matiaszanolli/ByroRedux --limit 200 --json number,title,state,labels > /tmp/audit/issues.json; confirm Fallout 4/Data/ exists (else note dimensions losing real-data validation).
Dimensions
Dimension 1: M49 Precombined Geometry — Decode + Spawn (highest FO4 risk)
Subagent: general-purpose
Paths: crates/nif/src/import/precombine.rs, byroredux/src/cell_loader/precombined.rs, byroredux/src/cell_loader/load.rs + exterior.rs + partial.rs, byroredux/src/cell_loader/spawn/{mesh_instance,precombined}.rs, byroredux/src/streaming/pre_parse.rs (worker pre-parse), crates/plugin/src/esm/cell/helpers.rs (XCRI decode), crates/bsa/src/csg.rs, crates/bsa/src/uvd.rs
First step: git log --since=<last report> --format='%h %cs %s' -- crates/nif/src/import/precombine.rs byroredux/src/cell_loader/precombined.rs crates/bsa/src/csg.rs
Guards (confirm live, not #[ignore]d/vacuous): precombine.rs tests decode_keeps_every_lod_band + lod_bands_skip_empty_bands_and_bound_the_read (#4234); csg.rs oversized_read_len_is_rejected_before_it_is_reserved (#3758 — read_psg must bound its length before Vec::with_capacity; reader discipline is /audit-parsers); precombined.rs tests resolve_precombine_owner_follows_form_id_mod_index, csg_paths_index_every_plugin_in_the_load_order, dedup_requires_both_a_cache_key_and_a_matching_length (#3510), oc_nif_paths_are_already_canonical_cache_keys; finish_partial_tests.rs::finish_partial_import_builds_precombine_geometry_entry; blend restore on both routes (#5101): precombined.rs::merge_precombine_materials_restores_blend_but_keeps_bgsm_flags + finish_partial_tests.rs::finish_partial_import_precombine_route_applies_the_material_merge; zero origin (#5228): exterior_apply_advances_precombine_at_zero_origin; #[ignore]d real-data dlc_rebake_of_a_master_owned_cell_decodes_from_the_dlc_csg + exterior_precombine_instances_are_world_absolute. The runtime baseline is an interior, so no telemetry gate sees exterior placement.
Checklist (what the guards cannot see):
- Stride / transform —
psg_vertex_stride(vertex_desc)vs theBSPackedGeomObjectlayout (off-by-N shifts every vertex silently; cross-check the spec doc).into_imported_meshapplies Z-up→Y-up + instance transform once.cell_originmust beVec3::ZEROon both routes (#5228, fixed f3e1bba62): exterior_oc.nifinstance transforms are world-absolute (same frame as the exterior REFRDATApositions), so addingcell_grid_to_world_yupplaces every tile at ≈2× its world position — the "else precombines stack at origin" rationale was the disproved #1222 premise. - LOD bands (#4234) — the three bands are disjoint sub-meshes whose union is the model (12,096/12,096
BSMeshLODTriShape); every populated band is decoded. Picking one band deletes geometry (12.45% ofMeshesExtra.ba2's baked triangles) and is not z-fighting. Distance LOD may drop tail bands, never pick one. An empty band's offset is untrusted. - Which CSG blob — the
_oc.niffilename keys off the cell's owning plugin (form-id mod byte; DLC bakes under<plugin>.esm\), but the geometry blob is chosen by each object'sBSPackedGeomObject::filename_hash→csg_paths_by_name_hash(#2369: DLCs re-bake ~460 master-owned cells into their own blob). A blob no loaded plugin answers to, or a missing CSG, must fail closed to per-REFR (0 spawns), never read another plugin's PSG space or panic. Known open:resolve_precombine_ownerreads the FormID slot byte as a load-order position (#6088). - REFR de-dup gate (#1188 / #5484, fixed 777351ec1) — the skip set is the XCRI pair tail, (remapped REFR form id, bake hash) pairs on
CellData::absorbed_ref_bakes(crates/plugin/src/esm/cell/helpers.rs); XPRI is the disjoint previs participant list, validated and never stored. Pre-fix the two were inverted (every baked STAT/SCOL drawn twice, ~9.9k XPRI statics deleted); census 959,238 XCRI refs, 100% STAT/SCOL, XCRI ∩ XPRI = 0 — which also settles #2699's furniture question.effective_absorbed_refs(bakes, baked_hashes)(shared by interiorload.rs— whoseInteriorCellApplyJobnow drives both the sync and the budgeted load, #5589 / a4496c79b — and exteriorexterior.rs) suppresses a REFR only when its own bake drew geometry, so one missing_oc.nifun-skips only its refs (no holes, no double-draw with SCOL expansion). Guards:effective_absorbed_refs_un_skips_only_the_missing_bakes_refs;parse_cell_xcri_pairs_remap_and_keep_their_bake_hash+parse_wrld_exterior_cell_captures_precombined_xcri_xpri(XPRI populates nothing) incrates/plugin/src/esm/cell/tests/. - Texturing — each mesh takes its material from the owning shape's shader/alpha properties (
collect_precombine_geom_refs+precombine_material_from_shape), then the BGSM merge; no REFR overlay on this path (pre_merge_materialsempty by design, #4290). Regression = untextured/checker precombines. - Opaque-architecture blend guard — on this path only,
merge_precombine_materials(called by bothPrecombinedSpawnJoband the streaming drain inpartial.rs) keeps the BGSM merge's two_sided/decal/alpha_test/texture flags but restores the pre-merge alpha-blend triple (has_alpha,src/dst_blend_mode): FO4 authors the "Standard" blend identically on lab glass and opaque Institute metal, so forwarding the mergedhas_alphamakes wallsMATERIAL_KIND_GLASS(see-through, mirror-hazy). - Archive chain precedence (#3637) —
--bsa/--materials-ba2chains resolve last-listed-wins (a DLC's re-baked_oc.nifmust not be shadowed; 1,871 DLC mesh entries were shadowed pre-fix per the #3637 title). Provider rebuilds now share opened handles (#5288, 5402b2530:Archive::open_shared, a process-wide registry validated by file length + mtime) and skip the shadow-count walk for a reused handle — precedence is unchanged, only that diagnostic count is. LooseData\files (the--esmplugin's directory) are appended after every archive in the texture, mesh and material pools, so a loose override wins (#6200, 48e422a71; vanilla installs carry none, so no baseline moved). Guards:byroredux/src/asset_provider/tests/archive_precedence.rs(real-data,#[ignore]d — run it),byroredux/src/asset_provider/tests/loose_override.rs. - Upload once per object (#3510) —
CachedNifImport::geometry_dedupmaps every instance to its object's representative; keying the cache on the flattened sub-mesh index reintroduces one upload + BLAS per instance (1.37x VRAM, 4.6x worst tile). - Exterior streaming —
PrecombinedSpawnJobyields between hashes / meshes / BLAS batches, andPrecombinedPlacement(spawn/precombined.rs) between geometry groups, keeping the placement root + submesh numbering across yields; the synchronousspawn_precombined_mesheswrapper must stay behaviourally identical. The cell-stream worker pre-decodes each cell'sprecombine_oc_nif_pathsviadecode_precombine_csg(per-pluginCsgHandleCache) and the drain caches ageometry_only_cachedentry under the same key so the job only spawns — the two routes must agree on owner resolution, cache key, fail-closed fallback and the blend restore (divergence = different spawn counts per route). Regression guard (#5522, fixed 2ca9bc313):lookup_precombine_cacheseparates Hit /KnownFailure/ Unseen, so the worker's negative cache entry (Some(None): missing file, parse error, contained panic) is a terminal miss, never a main-thread re-parse outsidecatch_unwind; pinned bynegative_registry_entry_is_a_known_failure_not_unseen.NifImportRegistry's LRU evicts per-cell_oc.nifentries first and warns once on a shared-model eviction (6e1853d24); still open: the 2,048 cap is below the FO4 working set (#6114), one geometry copy per instance in precombine entries (#6116), and the worker pre-parses absorbed refs the main thread skips (#6097).effective_absorbed_refsis built once per apply job (67e724c3e, #6127), not per slice. .uvdprevis — envelope only (parse_uvd_header, incl.exterior_cell_grid; PVS payload uncracked, no occlusion consumer, #3810). Verify nothing pretends to consume the payload. Output:/tmp/audit/fo4/dim_1.md
Dimension 2: BGSM / BGEM → ImportedMaterial (merge + roles)
Subagent: general-purpose
Paths: crates/bgsm/src/, byroredux/src/asset_provider/material/{merge,mod,provider}.rs, byroredux/src/cell_loader/spawn/mesh_instance.rs (REFR overlay), byroredux/src/asset_provider/tests/{bgsm_merge,material_flags}.rs
First step: git log --since=<last report> --format='%h %cs %s' -- crates/bgsm byroredux/src/asset_provider/material
Guards: bgsm_merge.rs (bgsm_merge_forwards_alpha_blend_mode, bgsm_blend_to_gamebryo_is_identity_narrowing, the neutral-roughness pair, bgem_glass_forwards_authored_optics_and_overlay_roles); material_flags.rs::bgsm_metalness_*; crates/bgsm/src/template.rs resolve_breaks_*_cycle (#1148) + resolve_reports_per_file_parse_diagnostics (#5010, 746e0858e); crates/bgsm/tests/parse_all.rs real-data sweeps (hardened #5011, e8676b097) and asset_provider/tests/bgsm_diagnostics.rs. Parser discipline for crates/bgsm is /audit-parsers.
Checklist:
- Narrowed signature —
merge_external_materialtakes&mut ImportedMaterial, never&mut ImportedMesh, and is the only exported fn inmerge.rs(testmerge_external_material_is_the_only_exported_fn_in_this_file); a widened signature is a NIFAL boundary violation. It runs beforetranslate_material.merge_bgsm_armis split into group helpers (apply_bgsm_texture_slots/apply_bgsm_scalars/apply_bgsm_alpha_and_addressing, #5735 / a6cef30a5) and size-pinned bymerge_bgsm_arm_stays_within_its_size_pin; the helpers stay private. - Roles, not slots — BGSM texture paths and REFR/TXST overlays land in
MaterialTextureSet(22 named roles +decals: [T; 4],crates/nif/src/import/types.rs); FO4 wire-slot numbers must not survive past the import boundary. Overlay output is carried as named roles, not wire slots (#4434). Texture-set slot 7 is the_s.ddssmooth-spec map and routes to the smooth-spec role, not Specular (#4424: the BC5 map fed to the specular-colour multiply tinted every FO4 highlight warm); the gloss-sampler channel semantics are still an open question — do not guess. - Metalness from saturation, not luminance (#1476) — legacy spec-glossiness BGSMs (
pbr == false):bgsm_metalness=(max-min)/maxofspecular_color(white spec → 0). Luminance for the non-PBR branch makes vanilla concrete read chrome; luminance is correct only forpbr == true. - Authored enable bits gate their blocks —
specular_enabled == falsezeroes specular and derives no metalness / conductor tint in either branch (#4654, #4836;bgsm_specular_disabled_*); the envmap fill requires the chain'senvironment_mappingbit (#4428;*_skips_envmap_fill_when_env_mapping_disabled); a dead NIF texture path yields to a resolvable BGSM-chain path (#4636;dead_nif_texture_path_yields_to_resolvable_bgsm_chain_path). Reading a disabled block's values is the regression. - smoothness→roughness exactly once at the merge (
(1 - smoothness)clamped to the near-mirror floor); flag any downstream re-inversion. - Neutral-roughness fallback —
smoothness == 1.0with no resolvable gloss map → neutral 0.5 (NEAR_MIRROR_NEUTRAL_ROUGHNESS): #3639 at the merge (authored-nowhere; fires on thespecular_enabledarm only — a spec-off BGSM keeps the NIF-side roughness, #5012 / e80f7e854; must not fire when a template parent suppliessmooth_spec— pinned bybgsm_merge_keeps_the_floor_when_the_gloss_map_comes_from_the_template_parent, #5234 / 460c55a41), #3905 at spawn viamaterial_translate::resolve_unresolved_gloss_neutral_roughness(authored-but-unresolvable; gated on the shader'sglossMapIndex != 0u). The arms cover disjoint populations — collapsing them regresses. Regression guard (#5230, fixed 9f0a8a7cc): the spawn pass infers "hit the floor" fromroughness <= 0.04, which the glass classifier's forced mirror pane (0.04, metalness 1.0) also hits;classify_glass_into_material_with_provenancenow reports the forced mirror out throughtranslate_material_with_provenanceandresolve_unresolved_gloss_neutral_roughnessskips it (a_forced_mirror_pane_is_exempt_even_sitting_at_the_floor,a_bgsm_mirror_pane_keeps_its_mirror_through_the_spawn_pass_gateinmaterial_translate.rs). Both spawn sites must feed the provenance flag. - Blend factors pass through (#1823) — BGSM/BGEM
src_blend/dst_blendare already Gamebryo-native (Standard (6,7), Additive (6,0), Multiplicative (4,1)); any 0↔1 swap (or agl_to_gamebryo_blend) corrupts Additive/Multiplicative while leaving Standard untouched. - BGEM merge —
merge_bgem_armdeliberately leaves metalness/roughness as NaN soresolve_pbr's classifier runs; effect data merges into the NIF payload (#4425). Glass isglass_enabled-driven and must not misclassify opaque architecture with a stuck flag. - Lookup —
.bgsm/.bgem/.matdispatch on content magic, not extension (#758); last-listed-wins across--materials-ba2(#3637); template resolve is cycle-aware and depth-limited (DEPTH_LIMIT = 16) and surfaces parse diagnostics (lossy strings, unconsumed bytes, version past the ceiling) for every file in the chain throughTemplateResolver::parsed, not only the recovery arm (#5010). - MNAM-only landscape TXSTs — 32 of FO4's 128 LTEXs point at a TXST that authors only
MNAM; terrain resolves each layer throughLandscapeLayerTextures(byroredux/src/cell_loader/terrain.rs) andMaterialProvider::fill_texture_set_from_bgsmfills still-empty roles first-wins along the template chain, so authored TX slots keep precedence (#6199, e62e258bd). A layer reading only TX00/TX01/TX07 is the regression (untextured grass / rubble / cliffs). Output:/tmp/audit/fo4/dim_2.md
Dimension 3: NIF BSVER 130 Geometry, Shader Flags, Collision (FO4 slice)
Subagent: legacy-specialist
Paths: crates/nif/src/blocks/tri_shape/bs_tri_shape.rs, crates/nif/src/import/mesh/{bs_tri_shape,bs_geometry,skin}.rs, crates/nif/src/blocks/shader/lighting.rs, crates/nif/src/import/material/dedicated_shader.rs, crates/nif/src/import/collision/shape.rs
First step: git log --since=<last report> --format='%h %cs %s' -- crates/nif/src/import/material crates/nif/src/blocks/shader
Guards: fo4_shader_flag_tests.rs, alpha_flag_tests.rs (crates/nif/src/import/material/); bsver_shader_flag_band_tests; parse_rate_fo4_all_meshes (Dim 5). Parser mechanics are /audit-nif; the canonical handoff (single translate_material boundary, resolve-once metalness/roughness, glass classified after resolve_pbr) is /audit-nifal — file there.
Checklist:
VF_FULL_PRECISIONdefault-half unless set; binary16 decode incl. denormals/NaN.BSSubIndexTriShapesegments walked (actors lean on it); skinned indices/weights honour the packed layout. Regression guard (#5389, fixed cf9dec258): a per-vertex bone index>=the skin's own bone count declines the whole weight set (bind pose), never clamps —decline_unbounded_packed_indices(skin.rs) covers the inline arrays, the SSE global-buffer payload and classicNiSkinData; pinned bybs_tri_shape_skin_with_out_of_range_bone_index_declines/bs_tri_shape_skin_last_bone_index_is_in_range(bs_tri_shape_partition_remap_tests.rs). Vanilla census: 0 out-of-range over 23,099 FO4 skinned meshes (largest list 141/144). The FO4BsSkinInstancearm is pinned too (#5524, fixed 656e2bdc3):bs_skin_instance_out_of_range_bone_index_declines/bs_skin_instance_last_bone_index_is_in_range, and the decline warning is arm-neutral. Inline tangents whenVF_TANGENTS | VF_NORMALS(shared with Skyrim SE) — consolidating with theNiBinaryExtraDatapath is a regression of #795/#796.- Render-affecting flags consumed, not just parsed (#1592) —
dedicated_shader.rsORsModel_Space_Normals(F4SF1 bit 12) andAlpha_Test(F4SF2 bit 25) intoMaterialInfo, gated bycarries_typed_shader_flags(BSVER 130 only).Glow_Map(F4SF2 bit 6) is not gated: the(Fallout4, 2)arm inslot_role.rsroutes slot 2 to Emissive regardless — closed docs-only (#4430, 1a12670ae; routing unchanged on purpose — census: gating would strip 116 genuine_g.ddsglow maps, not gating masks 20 with a_d.dds; the BGSMglowmapbool is parsed, never read). The rule still needs an FO4 source; do not re-file or guess. These are lower priority than the BGSM merge (vanilla is BGSM-backed; only inline/loose/modded NIFs exercise them). - Skin/Hair tint
BSLightingShaderTypevariants sample different slots than the default path — the per-type map must match whattriangle.fragreads (#563). A BGSM material must never fall back to Lambert (FO4's inverse of the FNV regression); bareBSShaderPropertyBaseOnlystubs route throughMaterialInfo(#1244). - Parsed-then-dropped is FO4's recurring finding class (
texture_clamp_modeon 7.9% of lit materials #3507; the greyscale→palette enable bit): every decoded FO4 shader/BGSM field must reach anImportedMaterialsink and the canonicalMaterial, with one default across the three material tiers (#3515). The palette row ("Color Remapping Index") has two carriers (#5497): the precombine per-instancegrayscale_to_palette_scaleis stamped byapply_instance_palette_rowand restored across the BGSM merge inmerge_precombine_materials(guardsmerge_precombine_materials_keeps_the_instance_palette_row,apply_instance_palette_row_stamps_finite_rows_only); the REFR-side MSWPCNAM(color_remap_indexinmswp.rs) is applied as the palette row for a swapped placement, stamped on the raw-tierImportedMaterialbeforetranslate_material(0b2ffed89, #5497) — live only since f81e6e722 (#5755): both swap arms (per-shape, eager XATO) match throughmswp_source_matches(refr.rs:normalize_material_pathboth sides, case-insensitive, the CK*wildcard on 127 vanilla BNAMs), because a bare BNAM never equalled the NIF'sMaterials\…/ build-path /Data\materials\…spelling verbatim and no unbaked XMSP placement in Fallout4.esm swapped. MSWPFNAMis the CK tree folder (MaterialSwapRecord::tree_folder), never a path filter (#5756 — as one it rejected every swap of 806 records). Guards:mswp_source_matches_canonicalizes_and_honours_wildcards,build_overlay_xmsp_fnam_tree_folder_does_not_gate_the_swap(refr_texture_overlay_tests.rs),#[ignore]dfo4_mswp_canvas_swap_matches_the_picture_frame_nif. Starfield's REFRXLMS→ LMSW swaps (#5757,17bd40f4f;layered_material_swap_entries/canonical_swap_target) ride this same per-shapematerial_swapsarm, so an FO4 swap-path regression also breaks Starfield swaps (/audit-starfieldDim 4). - Collision —
BhkMultiSphereShapeandBhkConvexListShapetranslate toCollisionShapeinimport/collision/shape.rs(twodowncast_refarms); an arm reverting to "unsupported + drop" removes power-armor / settlement / debris collision. Packed-Havok (BhkSystemBinary) collision is blocked on thehknpCompressedMeshShapeDatadecode (PHYSAL,/audit-physics) — the skeletonbhkRagdollSystemblob is a different payload and is decoded (e1bd40bcf); FO4 architecture uses synthesized ghost trimesh colliders. The precombine collision sibling is<cell_formid:08x>_physics.nif(not_precomb.nif, which appears in no archive) — forward scope. Output:/tmp/audit/fo4/dim_3.md
Dimension 4: ESM Architecture Records + Cell Expansion
Scope split with /audit-esm: it owns the parser as a parser (GRUP walk, SubReader accounting, FormID remap); this dimension owns FO4's data through it. Shared-mechanism defects → /audit-esm.
Subagent: general-purpose
Paths: crates/plugin/src/esm/records/{scol,movs,pkin,mswp,parse}.rs, crates/plugin/src/esm/records/actor/npc.rs, crates/plugin/src/equip.rs, crates/plugin/src/esm/cell/{mod,support,walkers,wrld}.rs, byroredux/src/cell_loader/{refr,references/,spawn.rs,nif_import_registry.rs}
First step: git log --since=<last report> --format='%h %cs %s' -- crates/plugin/src/esm/records crates/plugin/src/esm/cell byroredux/src/cell_loader/refr.rs
Guards: cell_loader/scol_expansion_tests.rs, pkin_expansion_tests.rs, attach_points_spawn_tests.rs, refr_texture_overlay_tests.rs; the real-data ESM harness (#819) before any parse-rate claim.
Checklist:
- SCOL/PKIN expand into per-instance synthetic REFRs with composed (parent × child) transform; recursion bounded by
MAX_PKIN_DEPTH = 4(vanilla has zero nesting; the cap guards modded cross-recursion); SCOL-of-SCOL has its own gate. Regression guard (#5523, fixed a10b5d578):scol_cm_path(byroredux/src/cell_loader/refr.rs) answers which combined mesh a SCOL draws — the authoredMODLwhen it resolves, else the derived meshes\scol<owner>\cm<local id>.nif (114 DLCRobot SCOLs author dev-plugin MODLs) — andexpand_scol_placements_ifexpands the SCOL into its parts when it answersNone(13 vanilla placements name a CM that ships nowhere); the static spawn (byroredux/src/cell_loader/references/synth_child.rs) and the expansion gate inreferences/mod.rsread the same answer, so they cannot disagree. A SCOL nested under a PKIN keeps the emptiness-only gate. Pinned byscol_cm_path_prefers_the_authored_modl_then_the_derived_path+a_scol_with_an_absent_cm_expands_but_a_present_one_does_not(scol_expansion_tests.rs). Also: SCOL/PKINFLTRis the CK object-window filter path, a zstring decoded withread_zstringintofilter: Stringand never remapped (#5493, fixed 136048a95 — pre-fix 2,843 false malformed-FormID warns across the FO4 DLCs buried real remap failures; the*_expansion_tests.rspins use real string payloads plus a raw-under-remap test);NPC_.TPTAdecodes ontoNpcRecord::template_actors: [u32; 13](xEditwbTemplateFlagsorder, 0 = use theTPLTdefault) andwalk_inherited_records(crates/plugin/src/equip.rs) takes the per-flag entry for that flag's edge when non-zero (#5498, fixed 99c22a8db; 763 Fallout4.esm records resolved the wrong template before). MOVS is parse-only (physics runtime unwired). TheTXSTgroup arm is inrecords/parse.rsand its decode inesm/cell/support.rs— anunreachable_patternswarning there meansb"TXST"matches earlier than intended. The FO4-architecture maps must surface incategories()(records/index.rs). - TXST DODT (
DecalData) has zero consumers — 303 vanilla payloads parse ontoTextureSet.decal_dataand are never read (grep decal_datafinds only the parser and its tests); DNAM is consumed (TXST_FLAG_MODEL_SPACE_NORMALSinrefr.rs). Known and deferred — #3638 closed documentation-only (a decal-rendering feature build, not a parse bug); forward scope, don't re-file. - PKIN
CNAMis a template CELL, not a content base — fixed d63131c57 (#5231): every vanilla PKIN CNAM resolves to a CELL (the census spans Fallout4.esm + four DLCs) and vanilla FO4 places 0 PKIN REFRs (the CK bakes contents into ordinary REFRs) — an FO4-only premise: Starfield places 97,981 (fixed #5489: the expander now instances a CELL-typed CNAM's template-cell references under the outer transform, outer PKIN entry first, via the O(1)EsmCellIndex::cell_by_form_id) and returnsNoneonly when nothing was placeable so the outer REFR reaches the default miss accounting; base-record children remain the mod-authored shape. Guards:expand_pkin_empty_template_cell_places_nothing,expand_pkin_empty_template_leaves_the_base_children_fanning_out,expand_pkin_instances_its_template_cell_under_the_outer_transform, the#[ignore]dstarfield_cydonia_pack_ins_instance_their_template_cells,#[ignore]dfo4_pkin_cnam_targets_are_template_cells(crates/plugin/tests/parse_real_esm.rs). - Authored actor state — ACHR "Starts Unconscious" (
0x2000, FO4/FO76/SF only) decodes ontoPlacedRef::starts_unconsciousand spawns the actor dormant (#5017, 3c08cfe50);XRGDcorpse poses decode ontoPlacedRef::ragdoll_pose(260afc33f); the consumer isbyroredux/src/ragdoll_pose.rs, gated per rig by body-name set. FO4 (#5015 closed into follow-ups; e1bd40bcf + 28e1f413e): the skeleton'sbhkRagdollSystem(hknpRagdollData) blob decodes into the classic ragdoll/limited-hinge records, and XRGD entries map to bodies by each body'spose_bone_id, not entry order;is_fo4_posable_ragdolladmits the human, feral-ghoul and super-mutant sets (979 of 994 corpses resolve, per 28e1f413e) and refuses every other creature/robot rig (#6065 open). The layout is corpus-derived, not sourced — widen the gate only whenscripts/xrgd-fo4-rigs.pypasses a rig on both checks, never on a count match. Bodies take the blob's own material / motion-property rows by motion index, Skyrim's constants only as the no-rows fallback (#6066, fixed 019b087e3; pinned bya_body_reads_its_material_and_damping_rows_by_motion_indexinnp_ragdoll.rs+#[ignore]dcrates/nif/tests/np_ragdoll_corpus.rs). Convex/compound shapes and breakable joints decode (fc4a15104); the 67 bind-pose pivot disagreements are a recorded data property — the body-frame reading stays, the affected rigs hold live (#6067, closed 0d775dc61;docs/engine/physal.md). Live wiring (fc2b32d9e + 7c6e6c3e1, #6070 closed): FO4 RACEANAMskeleton paths are read,template_from_importedkeepspose_bone_id,spawn_skeleton_unitinstalls the one-body template only on a skeleton with no decoded one, and activation frees theFallbackActorColliderstand-in capsule (left behind it threw every limb; stand-up restores it). Regression guard:docs/smoke-tests/fo4-ragdoll.sh(all bodies/joints live, no recovery,BYRO_VALIDATION=1) +#[ignore]dbyroredux/src/ragdoll_installed_tests.rs(fo4_bind_pose_ragdoll_holds_together_in_free_fall, six rigs;fo4_xrgd_posed_ghoul_corpse_holds_together_in_free_fall). Not established, no tracking issue: a corpse whose REFR carries a large X/Y tilt (466 of 971 posed human/ghoul corpses) — the pose composition is unknown; the smoke covers only |X|,|Y| < 0.25 rad. Articulation defects →/audit-physics. - ARMA female→male biped fallback is Skyrim-only (open sourcing question, not a bug) —
resolve_armor_meshes(crates/plugin/src/equip.rs) falls back to the male biped model for a female wearer only whengame == GameKind::Skyrim(#5510, fixed d678dc578: the Skyrim CK documents the rule; 172 of Skyrim.esm's 766 addons are male-only). FO4 deliberately keeps the strict reading because the FO4 CK page documents no such rule and none is sourced locally — a FO4 male-only addon renders nothing on a female wearer. Needs an FO4 source (xEdit/CK/engine) before any change; do not extend the fallback by analogy and do not file it as a defect. - CELL
XCCMis game-dependent (#5463, 3b28dca71) — FO4 (like TES5) authors it as 'Sky/Weather from Region' [REGN] (xEditwbDefinitionsFO4.pas), decoded ontoCellData::sky_region; only TES4/FO3/FNV decode it ontoclimate_override(a CLMT). No consumer forsky_regionyet (forward scope). A FO4 cell readingclimate_overridefrom XCCM is the regression. - BSConnectPoint — the import lifts
BSConnectPoint::Parents/ChildrenintoAttachPoints/ChildAttachConnections(crates/core/src/ecs/components/attach_points.rs); spawn must materialise them (modular weapons / power-armor frames otherwise spawn base-receiver only). Output:/tmp/audit/fo4/dim_4.md
Dimension 5: Archives + Real-Data Validation + Forward Scope
Subagent: general-purpose
Paths: crates/bsa/src/ba2.rs, crates/nif/tests/parse_real_nifs.rs, crates/nif/examples/nif_stats.rs, ROADMAP.md, docs/feature-matrix.md
First step: BYROREDUX_FO4_DATA=… cargo test -p byroredux-nif --test parse_real_nifs -- --ignored fo4
Checklist:
- BA2 (FO4 slice; reader discipline is
/audit-parsers) — version dispatch is an exhaustivematch(v1/v7/v8 FO4 → zlib; v2/v3 Starfield →/audit-starfieldDim 1); unknown majors bail atopen()and a cascadingif v == 1 … elsewith a silent v1 fallback is the regression (#811). GNRL byte-exact; DX10 reconstructs the DDS header from width/height/dxgi_format/mips (BC1/BC3/BC5/BC7, mip0 → mip_last). - Parse rate —
parse_rate_fo4_all_meshescovers all 8 mesh-bearing archives (base pair + six DLCMain.ba2;DLCUltraHighResolutionis textures-only), 235,082 NIFs incl..bto/.btr(widened 2026-08-29 by #3466; re-measured 2026-10-09, 8/8 archives), 100.00% clean. Report the measured number, not ROADMAP's. Regression guard (#5232, fixed 3970c8d19):open_all_mesh_archives/open_ba2_by_name(crates/nif/tests/common/mod.rs) panic on a present-but-unopenable BA2 (Noneis reserved for an absent file) andrun_all_meshes_gateassertswalked > 0; a reversion turns the gates into green no-ops — still confirm the archive count actually walked, not just the pass. DX10 records withchunk_hdr_len != 24are now a hardInvalidData(#5008, cf2a36920; vanilla census: all 24). - Trace
import_nif_sceneon a workshop item, a creature (deathclaw / super mutant), a power-armor frame (heavy skinning + BSConnectPoint) and a modular weapon: mesh count,material_path, skinned vs rigid, connect points. - Forward scope (do not file as blockers): precombine
_physics.nifcollision and packed-Havok decode,.uvdPVS payload / occlusion consumer, MOVS physics runtime, DecalData consumer (above), XRGD poses for the unverified FO4 creature/robot rigs (#6065) and for tilted-reference corpses, FaceGen NIF truncation tail, deeper cell coverage (LIGH power state / CONT leveled items / NPC_ face morph). Output:/tmp/audit/fo4/dim_5.md
Phase 3: Merge
- Read
/tmp/audit/fo4/dim_*.md; combine intodocs/audits/AUDIT_FO4_<TODAY>.md:- Executive Summary — measured parse rate; what is shipped vs pending (above).
- Dimension Findings — grouped by severity per dimension.
- BGSM Consumption Table — BGSM field × merged-into-
ImportedMaterialbymerge_external_material/ surfaced-on-canonical-Material. Texture columns name theMaterialTextureSetrole, never an FO4 slot number. - Forward Scope Chain — precombine collision /
.uvdpayload → MOVS physics → DecalData → deeper REFR/LIGH/CONT/NPC_ coverage.
- Remove cross-dimension duplicates.
Suggest: /audit-publish docs/audits/AUDIT_FO4_<TODAY>.md
(label every finding game:fo4 + legacy-compat, plus its own domain label.)
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/fallout-4-compatibility-audit-mvj1ocr7/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/fallout-4-compatibility-audit-mvj1ocr7' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/fallout-4-compatibility-audit-mvj1ocr7/download' --output '.skill-downloads/fallout-4-compatibility-audit-mvj1ocr7/SKILL.md.part' && mv '.skill-downloads/fallout-4-compatibility-audit-mvj1ocr7/SKILL.md.part' '.skill-downloads/fallout-4-compatibility-audit-mvj1ocr7/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/fallout-4-compatibility-audit-mvj1ocr7/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.