Synthèse automatique
Commande d'audit pour ByroRedux qui répartit l'analyse des courses de données, deadlocks, ordres de verrouillage et synchronisations Vulkan sur sept dimensions exécutées en parallèle.
Points forts
- Classe les dimensions selon leur rayon d'impact concurrent (files Vulkan et AS d'abord, puis ECS, ordonnanceur, cycle de vie), ce qui concentre l'effort sur les défauts critiques.
- Fournit un barème de sévérité minimal explicite (course sur file Vulkan ou violation de durée de vie FFI = CRITIQUE) qui rend le tri des constats reproductible.
- Impose un garde-fou anti-correctif-spéculatif : toute anomalie de barrière ou d'étage doit être confirmée par la couche de validation ou RenderDoc avant d'être promue au-delà d'une hypothèse.
- Prévoit une déduplication via la liste des issues GitHub existantes et un plafond de trois agents simultanés pour maîtriser le coût d'exécution.
Limites
- Fortement couplé à un dépôt précis (ByroRedux, chemins .claude/commands, label gh, variables BYRO_VALIDATION) : inutilisable tel quel sur un autre projet.
- Les défauts de synchronisation Vulkan échappent largement à cargo test ; sans exécution avec la validation de synchronisation ou RenderDoc, beaucoup de constats resteront à l'état d'hypothèses.
- Suppose un environnement outillé (gh CLI, accès réseau au dépôt, écriture dans /tmp) et un extrait de commande fourni ici est tronqué, donc l'étape de récupération du référentiel de déduplication doit être reconstituée.
À lancer avant une livraison ou une refonte majeure du moteur Vulkan/Rust ByroRedux, lorsqu'on veut un inventaire priorisé des risques de concurrence et d'ordre de verrouillage.
À éviter sur un projet qui n'est pas ByroRedux, ou si aucun moyen de validation Vulkan (couche de synchronisation, GPU-Assisted Validation, RenderDoc) n'est disponible pour confirmer les constats.
Analyse de sécurité
PrudenceThe skill is a read-only code-audit orchestrator: it reads first-party source files, shells out to create scratch directories, queries GitHub for a dedup baseline, and writes findings into /tmp and docs. There is no deletion, no curl|sh, no credential handling, and no outbound transfer of repository data. Risk is moderate only because it exercises bash/Task/network privileges that it never declares, and because it consumes two unreviewed companion instruction files and appends a further publishing command — so the effective permission surface exceeds what is visible here.
- •Declares no allowed-tools, yet the workflow requires shell execution (mkdir, file reads/writes), spawning Task agents, and network access via `gh issue list --repo matiaszanolli/ByroRedux` — the declared tool surface does not match the operations the skill performs.
- •Writes audit artifacts into the repository (`docs/audits/AUDIT_CONCURRENCY_<TODAY>.md`) and `/tmp/audit/...`, and then chains into additional commands (`/audit-publish`) that are not defined inside the reviewed content, so the full effect of the pipeline cannot be verified from this file alone.
- •Depends on two external instruction files (`.claude/commands/_audit-common.md`, `.claude/commands/_audit-severity.md`) whose contents are not included; those files are incorporated as instructions and could alter behavior in ways this review cannot see.
- •Network call to GitHub CLI requires an authenticated token in the environment; the skill only reads issue metadata, but the token context is an implicit privilege the listing should be aware of.
- •No destructive, obfuscated, or exfiltration behavior found; no attempts to alter reviewer role or override instructions were present in the skill text.
- •Instructs shell/network operations (`mkdir -p`, `gh issue list --repo ...`) and writes audit files under `/tmp` and `docs/audits` without declaring allowed tools; these are legitimate audit workflow steps but require bash/network access if executed.
Exemples
Run the concurrency and synchronization audit with --focus 1,3 --depth deep and report any Vulkan queue data races or ECS RwLock ordering violations with their trigger conditions.Do a shallow pass over all seven concurrency dimensions: check barrier and lock presence only, and flag anything at HIGH or CRITICAL severity.Audit the compute → acceleration structure → fragment chain for missing AS barriers, and tell me which findings need a BYRO_VALIDATION sync-validation run to confirm.description: "Audit Vulkan queue/AS sync, ECS lock ordering, scheduler access declarations, RwLock patterns, deadlock potential" argument-hint: "--focus <dimensions> --depth shallow|deep"
Concurrency and Synchronization Audit
Audit ByroRedux for data races, deadlocks, incorrect lock ordering, missing Vulkan synchronization, and thread-safety violations.
Architecture: Orchestrator. Each dimension runs as a Task agent (max 3 concurrent).
See .claude/commands/_audit-common.md for project layout, methodology,
deduplication, context rules, finding format, and the path-reference convention.
See .claude/commands/_audit-severity.md for the severity scale — the rows that
matter here:
| Condition | Minimum Severity | |-----------|-----------------| | Data race on Vulkan queue / use-after-free / AS built at wrong address | CRITICAL | | Vulkan spec violation (missing barrier, fence misuse) | HIGH | | Missing AS barrier (build → shader read) | HIGH | | Resource / descriptor / command-buffer leak per frame | HIGH | | Missing cleanup on swapchain recreate | HIGH | | ECS deadlock potential (RwLock ordering violation) | HIGH | | FFI lifetime violation across the cxx bridge | CRITICAL |
Dimensions below are ordered by concurrency blast radius: GPU queue / AS data races (CRITICAL) first, then ECS deadlock surfaces, then the already-closed scheduler/access machinery (now regression guards), then the slower-moving lifecycle / worker / chain dimensions.
Parameters (from $ARGUMENTS)
--focus <dimensions>: Comma-separated dimension numbers (e.g.,1,3). Default: all 7.--depth shallow|deep:shallow= check barrier/lock presence;deep= trace concurrent paths and timing windows. Default:deep.
Extra Per-Finding Fields
- Dimension: Vulkan Queue & AS Sync | Compute → AS → Fragment Chains | ECS Lock Ordering | Scheduler Access Declarations | RwLock Patterns (Resource↔Storage, Physics) | Resource Lifecycle | Worker Threads (Streaming, Debug)
- Trigger Conditions: Exact timing/concurrency window needed to reproduce
- Verification Path: For Vulkan-sync findings — whether the failure is observable in
cargo test, the validation layer, or only RenderDoc (see "Speculative-fix guardrail" below)
Speculative-fix guardrail (read before reporting any Vulkan-sync finding)
Vulkan render-pass / pipeline-barrier / semaphore / fence bugs are largely
invisible to cargo test — there is no headless device assertion that
catches a missing image barrier or a wrong stage mask. Per the project's
standing rule, do not propose shipping a barrier/stage/layout change on
reasoning alone. Frame each such finding as "needs validation-layer or
RenderDoc confirmation" and state the concrete signal that would confirm it
(a specific VUID-* validation message, a RenderDoc resource-state mismatch,
or a visible artifact class). A finding whose only evidence is "this barrier
looks wrong" is a HYPOTHESIS row, not a fix.
The cheapest evidence channel is now sync-validation in release (#ec81f233).
BYRO_VALIDATION=<v> (instance.rs::validation_enabled) turns on the Khronos
validation layer + Synchronization Validation in a release build — debug
builds are too slow to stream into the dense cells that fault. BYRO_VALIDATION=gpuav
additionally enables GPU-Assisted Validation (shader OOB / descriptor checks).
The debug messenger routes layer messages into the Rust log whenever validation
is enabled. A sync-validation RAW/WAR hazard count (e.g. the ~40/frame the
--cornell harness reported pre-#507945d8) is the confirmed-bug signal — prefer
it over "looks wrong." Confirm any AS-build-input / barrier finding against a
captured validation run before escalating past HYPOTHESIS.
Phase 1: Setup
- Parse
$ARGUMENTS mkdir -p /tmp/audit/concurrency- Fetch dedup baseline:
gh issue list --repo matiaszanolli/ByroRedux --limit 200 --json number,title,state,labels > /tmp/audit/concurrency/issues.json
Phase 2: Launch Dimension Agents
Dimension 1: Vulkan Queue & Acceleration-Structure Sync (CRITICAL surface)
Entry points: crates/renderer/src/vulkan/context/draw.rs (draw_frame), crates/renderer/src/vulkan/sync.rs, crates/renderer/src/vulkan/acceleration/ (blas_static.rs, blas_skinned.rs, tlas.rs), crates/renderer/src/vulkan/context/resize.rs
Checklist:
- Queue submission is single-Mutex.
graphics_queueandpresent_queueare bothArc<Mutex<vk::Queue>>(context/mod.rs);present_queueis anArc::cloneofgraphics_queue, so one Mutex serialises all submits + presents.vk::QueueisCopy, so the canonical pattern is "lock → copy the handle out → drop the guard →queue_submit": confirm the guard is not held acrossqueue_submit/queue_present(a held guard during a blocking submit would serialise every other queue user; a copied-out handle used after a second thread re-submits is a data race). Cross-check the.lock()sites indraw.rs(main submit ~queue_submit, and the secondary one-time-command submit) against this rule. - Frame-in-flight discipline. The
in_flight[frame]fence must be waited on before its command buffer / per-frame resources are reused;image_available[frame]semaphore must not be reused while a prior acquire is still pending (the draw.rs comment block around the acquire→submit window documents the ordering — verify it still holds). - Acquire → render → present semaphore chain is correct and uses per-image (not per-frame) signal semaphores where required by the swapchain image index.
- AS build → read barrier. Every BLAS/TLAS build or refit that a later ray query reads must be followed by an
ACCELERATION_STRUCTURE_WRITE_KHR → ACCELERATION_STRUCTURE_READ_KHRbarrier before the fragment-stage ray-query consumer. Static BLAS:blas_static.rs(memory_barrier, WRITE→READ). Skinned BLAS refit:blas_skinned.rs(regression guard, #1790:record_scratch_serialize_barrier's dst mask is WRITE|READ, not WRITE-only — it must cover a first-sight frame's same-command-buffer BUILD-then-UPDATE-refit adjacency, where the UPDATE readssrcAccelerationStructure). TLAS:tlas.rs(cmd_pipeline_barrier). A missing or wrong-stage barrier here is HIGH (CRITICAL if the AS is built at a wrong/stale device address — wrong geometry in shadows/reflections/GI). - Deferred BLAS-scratch destruction (regression guard, #1782).
blas_scratch_bufferretirement on grow/shrink routes throughpending_destroy_scratch(deferred) instead of an immediate free — same use-after-free class as #a476b256 below, but for the scratch allocation rather than aBlasEntry.build_skinned_blas_batched_on_cmd's own grow-destroy is deliberately immediate (safe: runs after that frame's own fence wait) — don't flag it as a missed instance. - AS build INPUT barrier access flag (regression guard, #507945d8). Distinct from the build→read barrier above: the inputs to a build (instance-buffer copy → TLAS build in
tlas.rs; skinned-vertex compute write → BLAS build indraw.rs) must be made visible withSHADER_READat theACCELERATION_STRUCTURE_BUILDstage, NOTACCELERATION_STRUCTURE_READ_KHR(that flag reads an AS structure, not build inputs). The wrong flag is a copy/compute → build RAW hazard sync-validation catches — confirm via aBYRO_VALIDATIONrun, don't escalate on reasoning alone. - Deferred AS destruction vs in-flight reads (#a476b256). BLAS eviction/drop routes the AS handle + buffers through
pending_destroy_blas(deferred countdown), so an unload/eviction can't free an AS the in-flight frame's ray queries still read. Verify no path re-introduces an immediatedestroy_acceleration_structureat the eviction site (use-after-free = CRITICAL) and that shutdown drains the queue. - Swapchain recreate sync.
recreate_swapchain(context/resize.rs) must cover all in-flight work withdevice_wait_idle(or equivalent fence drain) before destroying/rebuilding swapchain-dependent resources — no use-after-destroy across the recreate. - One-time command buffers (BLAS initial build, staging copies) block the main thread on a fence — flag if any such blocking submit runs inside the per-frame hot path rather than at load time.
Output:
/tmp/audit/concurrency/dim_1.md
Dimension 2: Compute → AS → Fragment Chains
Entry points: crates/renderer/src/vulkan/skin_compute.rs, crates/renderer/src/vulkan/acceleration/blas_skinned.rs (refit path), crates/renderer/src/vulkan/svgf.rs, crates/renderer/src/vulkan/taa.rs, crates/renderer/src/vulkan/caustic.rs, crates/renderer/src/vulkan/water_caustic.rs, crates/renderer/src/vulkan/volumetrics.rs, crates/renderer/src/vulkan/bloom.rs, crates/renderer/src/vulkan/material.rs, crates/renderer/src/vulkan/context/draw.rs (master ordering)
Checklist:
- Skin chain (M29). Palette build (
skin_compute.rs) →COMPUTE_WRITE→SHADER_READ→ per-mesh skin output → BLAS refit (blas_skinned.rs) reads it → fragment ray query hits the refit BLAS. The full palette→skin→refit→ray-query chain must be intact; a drift = stale geometry in shadows/reflections/GI. The live raster path uses inline skinning intriangle.vert(not the SSBO output), so aVERTEX_INPUTbarrier is not currently required — flag only if a raster-from-skinned-SSBO path is added without one. - Cross-frame ping-pong (no slot N reads slot N's in-flight write). SVGF history, TAA history, caustic accumulator, water-caustic per-FIF
R32_UINTaccumulator, and volumetrics (lighting_volumes→integrated_volumes) all read the previous frame's slot. Verify the per-frame-in-flight indexing. - Volumetrics gate (#1105). Injection writes
lighting_volumes(COMPUTE) → integration reads it, writesintegrated_volumes(COMPUTE→COMPUTE) →composite.fragsamples it (COMPUTE_WRITE→FRAGMENT_READ).write_tlasmust run beforedispatcheach gated frame —volumetrics.rskeeps atlas_written: [bool; MAX_FRAMES_IN_FLIGHT]latch thatdispatchdebug_assert!s and then resets. Verify the latch set/reset symmetry. - Bloom within-frame RAW chain (#931). Down-pyramid and up-pyramid each need a per-mip
COMPUTE_WRITE(SHADER_WRITE)→COMPUTE_READ(SHADER_READ)image barrier so mip[i+1] sees mip[i]'s write;up_mips[0]must complete before composite samples it. Confirm the "post-barrier on the just-written mip only" accounting leaves no missing publish on the final up-mip. - Caustic CLEAR → COMPUTE → FRAGMENT. Accumulator cleared before compute writes; compute completes before composite reads.
- MaterialBuffer SSBO (R1).
material.rsupload isHOST_WRITE → VERTEX/FRAGMENT_READ; today it lands before draw recording so the frame fence already covers it — flag only if the upload moves into a compute path mid-frame. Output:/tmp/audit/concurrency/dim_2.md
Dimension 3: ECS Lock Ordering & Deadlock
Entry points: crates/core/src/ecs/world.rs (query_2_mut, query_2_mut_mut, the resource-pair queries), crates/core/src/ecs/query.rs, crates/core/src/ecs/lock_tracker.rs, all system functions under byroredux/src/systems/ (animation.rs, audio.rs, billboard.rs, bounds.rs, camera.rs, character.rs, debug.rs, light_anim.rs, metrics.rs, particle.rs, water.rs, weather.rs)
Checklist:
- TypeId-sorted acquisition is the deadlock-prevention invariant.
world.rsmulti-component queries acquire storage locks inTypeId-ascending order regardless of the generic-parameter order the caller spells (theif id_a < id_b { … } else { … }branches inquery_2_mut). Thelock_trackerscope guards are set up in the same order so the lock-order graph never sees a spurious ABBA edge when the caller writes<B, A>withTypeId(A) < TypeId(B)(#313). Verify any new multi-lock accessor follows this and that same-type access still hits theassert_ne!panic. lock_trackercoverage. Same-thread re-entrant conflict detection is always-on in debug builds (track_read/track_writepanic on a conflicting held lock). The cross-thread global lock-order graph is opt-in viaBYRO_LOCK_ORDER_CHECK=1(global_ordermodule) — so an ABBA risk between two parallel systems is only caught when that env var is set. Flag any CI/test path that should run with it but doesn't (seedocs/contributing.mdlock-order-checkjob).- Guard lifetime in system bodies. No
query_mut/resource_mutguard held across a call that re-enters the same storage/resource; nested query patterns (e.g. animation querying Player then Transform) must drop the first guard or use the pairedquery_N_mutaccessor; noWorld::insert(structural mutation,&mut self) during system execution (systems hold&World). - Poisoning. Storage
RwLocks poison on panic; every acquisition resolvesPoisonErrorthroughstorage_lock_poisoned::<T>()(re-panics with a diagnostic). Confirm no acquisition path silentlyunwrap()s a poisoned guard into torn state. Output:/tmp/audit/concurrency/dim_3.md
Dimension 4: Scheduler Access Declarations (regression guard — M27 closed)
Entry points: crates/core/src/ecs/scheduler.rs, crates/core/src/ecs/access.rs, byroredux/src/commands/world_info.rs (sys.accesses)
Status: M27 (parallel dispatch) and R7 (access declarations) are closed
(ROADMAP.md). The parallel-scheduler feature is on by default; the
post-migration sys.accesses report is 0 unknown / 0 conflicts. This
dimension is therefore a regression guard, not migration tracking.
Checklist:
- The conflict model is sound and matches the enum.
AccessConflicthas exactly three variants —None,Unknown { left_undeclared, right_undeclared },Conflict { pairs }(access.rs); there is noParallelvariant.analyze_pairreturnsUnknownwhenever either side is undeclared (the pessimistic fallback, not "no conflict"),Conflicton a write/read or write/write overlap on the same component or resource,Noneotherwise. Verify any new variant or analyzer change preserves the "undeclared ⇒ Unknown ⇒ assume serialise" semantics. - Migration KPIs.
AccessReport::undeclared_parallel_count()is the migration KPI (the population the analyzer can reason about);undeclared_count()= parallel + exclusive split viaundeclared_parallel_count()+undeclared_exclusive_count()(#1237).known_conflict_count()andunknown_pair_count()must stay 0 on the engine binary — a regression here means a parallel-stage system was added without anadd_to_with_accessdeclaration (closures/bare-fns can't overrideSystem::access, so they need the registration-site channel; #1236). - Exclusive phase. Exclusive systems run serially after the parallel batch (
StageData.exclusive) — they're listed in the report but never paired; the four runtime-mutually-exclusive systems re-staged in M27 Phase 3 (audio, spin, character-mode dispatcher,player_controller_system) must stay exclusive. Flag any move back to parallel. - Re-entry & panic policy.
Scheduleris owned byApp, never aResource— re-entry from a system body is structurally impossible (#868). Panic-in-system is fail-fast by design (#1412); do not report "missing catch_unwind" as a bug. Output:/tmp/audit/concurrency/dim_4.md
Dimension 5: RwLock Patterns — Resource↔Storage & Physics Step
Entry points: crates/physics/src/sync.rs (physics_sync_system, set_linear_velocity, set_kinematic_translation), crates/physics/src/world.rs (PhysicsWorld), crates/physics/src/components.rs (RapierHandles), crates/physics/src/config.rs (ContactConfig), byroredux/src/cell_loader/unload.rs (release_victim_rapier_bodies), byroredux/src/systems/character.rs
Checklist:
- TypeId-sorting does NOT cover the Resource↔Storage pair. The deadlock-prevention sort in
query_N_mutorders storage locks; a Resource lock (resource_mut) and a storage lock (query/query_mut) are an unordered pair. So noresource_mut::<PhysicsWorld>()guard may be held across aquery/query_mutiteration and vice-versa.physics_sync_systemis a 4-phase system (collect newcomers → register → step → pull dynamic). Verify Phase 1collect_newcomerscollects to aVecunder read guards and drops them beforeregister_newcomerstakes thePhysicsWorld+RapierHandleswrite guards. - Helper lock order.
set_linear_velocity/set_kinematic_translationreadRapierHandlesviaworld.query::<RapierHandles>()...copied()(the read guard drops at the end of thematch/letexpression because the handle isCopy), then takeresource_mut::<PhysicsWorld>(). Confirm the read guard is genuinely dropped before the write guard, and that callers (e.g.character_controller_system) don't already hold aPhysicsWorldguard when they call these. ContactConfigis read viatry_resource(optional) and snapshotted once per batch inregister_newcomers— confirm it is not re-locked inside the per-newcomer loop.- Cell-unload teardown (#1520).
release_victim_rapier_bodies(unload.rs) collects each victim'sRapierHandlesinto a scratchVecunder the storage read guard, drops it, then removes bodies/colliders fromPhysicsWorld— same release-reads-before-write discipline; verify it runs before the despawn loop drops the handles. - Single-threaded placement.
physics_sync_systemruns inStage::Physicsafter transform propagation and must not be co-scheduled (parallel) with any other system that touchesPhysicsWorld/RapierHandles/Transform. Output:/tmp/audit/concurrency/dim_5.md
Dimension 6: Resource Lifecycle (GPU teardown ordering)
Entry points: crates/renderer/src/vulkan/context/mod.rs (Drop impl), all destroy() methods, crates/renderer/src/vulkan/buffer.rs, crates/renderer/src/vulkan/acceleration/, crates/renderer/src/vulkan/context/resize.rs, crates/renderer/src/vulkan/egui_pass.rs, crates/renderer/src/vulkan/scene_buffer/, crates/renderer/src/vulkan/material.rs
Checklist:
- Reverse-order destruction (Vulkan requirement); Drop reached for all GPU resources; allocator freed last. Note #1483 hoisted allocator-independent destroys out of the allocator-guard scope in Drop — verify no resource that needs the allocator is destroyed after the guard is dropped.
- No use-after-destroy across swapchain recreate. G-buffer / SVGF / TAA / caustic / water-caustic / volumetrics (
lighting_volumes+integrated_volumes) / bloom (down_mips+up_mips) / composite resources rebuilt on recreate; per-FIF history/accumulator images freed for every in-flight slot; egui framebuffers rebuilt (resize.rs). - AS cleanup on shutdown. All
BlasEntrybuffers +TlasStatebuffers + scratch released; per-skinned-entity skin output buffers retained until the owning entity is destroyed. - Other GPU SSBO/descriptor cleanup.
scene_buffercleanup,MaterialBufferSSBO (R1), texture registry,EguiPass::destroy()(releases egui-ash-renderer resources + framebuffers;egui_pass: Option<EguiPass>taken/dropped in reverse order incontext/mod.rsDrop). - Per-frame leaks. Any descriptor / command-buffer / staging allocation created per frame but not freed/reset is HIGH (compounds).
Output:
/tmp/audit/concurrency/dim_6.md
Dimension 7: Worker Threads (Streaming, Debug Server) & Thread-Safety Bounds
Entry points: byroredux/src/streaming.rs (M40 async pre-parse worker), crates/debug-server/src/listener.rs (per-client TCP threads), crates/debug-server/src/system.rs (DebugDrainSystem), crates/debug-ui/src/lib.rs, all types with Send + Sync bounds (Component, Resource), crates/renderer/src/vulkan/allocator.rs (SharedAllocator)
Checklist:
- Streaming Drop ordering (#1167).
WorldStreamingState::request_txisOption<mpsc::Sender<LoadCellRequest>>andworkerisOption<JoinHandle<()>>. TheDropimpl musttake()+ drop the Sender BEFORE the worker handle is dropped (declaration-order field drop would otherwise detach the worker before the channel closes, defeating the join).shutdown(&mut self, timeout)takes the worker handle so the laterDropsafety-net observesworker: Noneand short-circuits. Verify the field-drop /take()ordering and the join-with-timeout path. - Worker ↔ main data flow. Parsed cell payload moves to the main thread via channel — no shared
&mut Worldfrom the worker. Off-thread NIF/texture extract goes throughArc<TextureProvider>whose innerBsaArchive/Ba2ArchiveserialiseFileaccess via Mutex (concurrent extracts safe). BGSM resolution (&mut,MaterialProvider::merge_bgsm_into_mesh) stays main-thread-only — confirm the worker doesn't touch it. NIF import cache (Resource) accessed from the worker must use a read-only fast path with write-back deferred to main. - Debug server. Per-client TCP threads do not touch the World directly — all mutations route through
DebugDrainSystemon the main thread (Late-stage exclusive). The command queue between listener and main thread must be bounded (no unbounded buffering on a slow main loop). Screenshot readback completes on a fence wait — verify no race between the drain system and present. - Allocator sharing.
SharedAllocator = Arc<Mutex<vulkan::Allocator>>(allocator.rs) is held byVulkanContextand cloned intoEguiPass(egui_pass.rs), volumetrics, ssao, scene_buffer, etc. All dispatch runs single-threaded insidedraw_frame; the only correctness concern is that no holder keeps the Mutex locked across a queue submit. The egui overlay dispatch runs after composite on the main loop. Send + Syncbounds. Component/Resource storage reached only through World query/resource guards; no raw pointer shared across threads; cxx-bridge pointer lifetimes bounded; Ruffle/wgpu (UI) device isSendbut notSync— confirm it stays on one thread.- Out of scope: parse-time
Materialtranslation (byroredux/src/material_translate.rs::translate_material,Material::resolve_pbr) is single-threaded with no Mutex/RwLock/resource_mut — see/audit-nifalfor that boundary. Output:/tmp/audit/concurrency/dim_7.md
Phase 3: Merge
- Read all
/tmp/audit/concurrency/dim_*.mdfiles - Combine into
docs/audits/AUDIT_CONCURRENCY_<TODAY>.md - Remove cross-dimension duplicates
Suggest: /audit-publish docs/audits/AUDIT_CONCURRENCY_<TODAY>.md
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/concurrency-and-synchronization-audit-mryiqiqp/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/concurrency-and-synchronization-audit-mryiqiqp' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/concurrency-and-synchronization-audit-mryiqiqp/download' --output '.skill-downloads/concurrency-and-synchronization-audit-mryiqiqp/SKILL.md.part' && mv '.skill-downloads/concurrency-and-synchronization-audit-mryiqiqp/SKILL.md.part' '.skill-downloads/concurrency-and-synchronization-audit-mryiqiqp/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/concurrency-and-synchronization-audit-mryiqiqp/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.