Automated summary
Turns the findings of a finished Markdown audit report into one GitHub issue per finding, with status filtering, code re-verification and deduplication against open issues.
Strengths
- Clear staged process with a path-validation gate that runs before any finding is judged.
- Processes only NEW findings and records Existing / Regression ones instead of re-filing them.
- Requires reading the code at the symbol via grep rather than the line, and re-mapping moved files before declaring a finding STALE.
- Mandatory deduplication against open issues through gh issue list, plus a closed-issue search to catch regressions.
Limitations
- Hardcoded to the matiaszanolli/ByroRedux repo and its file layout (crates/bsa, byroredux/src, etc.), so it is not portable as-is.
- Depends on external shared files (_audit-common.md, _audit-severity.md, _audit-validate.sh) that are not included in this definition.
- The provided text cuts off mid-sentence in the regression-handling step, leaving the end of the workflow underspecified.
Use it when an audit report is complete and its confirmed findings need to become tracked GitHub issues.
Avoid it on a repo or layout other than the hardcoded one, or when issues are created by different tooling.
Security analysis
CautionThe skill is a well-intentioned publishing workflow, but it drives bash and the authenticated `gh` CLI to create issues in a live repository with no declared allowed-tools and no pre-action confirmation, and it shells out to an external validator script and shared protocol files that are not included in the package and therefore cannot be reviewed. None of the content is malicious or destructive, so it lands at caution rather than risky.
- •Executes shell commands (`.claude/commands/_audit-validate.sh`, `mkdir`, `gh ...`) despite declaring no allowed-tools; the agent grants itself bash/git-hub network access implicitly.
- •Performs unconfirmed write actions against a live GitHub repository (`gh issue create` / `gh issue list`), creating externally visible artifacts. No explicit human-approval gate before filing; step 10 is only a post-hoc count check.
- •Depends on external, non-bundled content that cannot be audited here: `.claude/commands/_audit-common.md`, `.claude/commands/_audit-severity.md`, and the executable `_audit-validate.sh`. The validator script is run blindly (`exit 1 on stale paths`) and its behavior is unverifiable from this file.
- •Writes to shared temp paths (`/tmp/audit/issues.json`, `/tmp/audit/labels.txt`) without unique suffixes; low risk but enables collision/clobbering in multi-tenant environments.
- •Hard-codes a specific repository owner/name (`matiaszanolli/ByroRedux`), which is legitimate scoping but means the skill is only safe to run in that context; running it elsewhere would still target the hard-coded repo.
- •No destructive, exfiltration, obfuscation, or safety-disabling instructions were found; the shell usage is confined to reading reports, validating paths, and managing issues.
- •Executes a local helper script `.claude/commands/_audit-validate.sh` whose contents are not included in the skill — the auditor cannot see what that script does (it is described as a path-validation gate that exits 1 on stale paths, which sounds benign, but it is opaque execution).
- •Report-derived text is interpolated into double-quoted shell arguments (`--title "<ID>: <title>"`, `--body "<description + evidence + ...>"`); backticks or `$( )` appearing in an audit finding's title/description/evidence would be shell-expanded when the command runs. Safer to write the body to a temp file and use `gh issue create --body-file`.
- •Hardcoded target repo (`matiaszanolli/ByroRedux`) and hardcoded local paths (`.claude/issues/...`, `/tmp/audit`) — scope is fixed, but nothing destructive or exfiltrating is performed.
- •Skill instructs reading sibling protocol files (`_audit-common.md`, `_audit-severity.md`) that are not shipped, so part of the effective instruction set is unvalidated.
Examples
Publish docs/audits/AUDIT_RENDERER_2026-04-04.md to GitHub issues.Turn docs/audits/AUDIT_NIF_IMPORT_2026-03-30.md into issues, but skip anything already open and summarize the ones you dropped.File the NEW findings from docs/audits/AUDIT_COLLISION_2026-04-02.md, and flag any that look like a regression of a previously closed issue.description: "Convert an audit report's findings into GitHub issues with completeness checks" argument-hint: "<path-to-audit-report>"
Audit → GitHub Issues Publisher
Turn a finished audit report (docs/audits/AUDIT_<TYPE>_<DATE>.md) into one GitHub
issue per actionable finding, with dedup, label reconciliation, and a completeness
gate so nothing silently slips through.
Shared protocol (read, do not restate): .claude/commands/_audit-common.md —
the Base Per-Finding Format (the exact field set this skill parses) and the
Deduplication (MANDATORY) flow. Severity scale: .claude/commands/_audit-severity.md.
This skill is the only place issues are created. Audit skills stop at writing the
report; they never call gh issue create.
Process
1. Load + parse the report
Read $ARGUMENTS (e.g. docs/audits/AUDIT_RENDERER_2026-04-04.md). Each finding block
follows _audit-common's Base Per-Finding Format: ### <ID>: <Title> then Severity,
Dimension, Location, Status, Description, Evidence, Impact, Related,
Suggested Fix. Extract those fields per finding; ID + Severity + Location + Status
are required, the rest carry into the issue body.
2. Path-validation gate (run first, before judging any finding)
.claude/commands/_audit-validate.sh # exit 1 on any STALE backticked path
This is the #1114 / TD7-050 gate. It fails fast when a report was written against
pre-split paths — a Location: pointing at a file that is now a directory. Common
splits to expect (old single file → current dir; the old paths are
deliberately un-backticked since they no longer exist): archive.rs →
crates/bsa/src/archive/, render.rs → byroredux/src/render/,
import/walk.rs → crates/nif/src/import/walk/, blocks/collision.rs →
crates/nif/src/blocks/collision/, blocks/tri_shape.rs →
crates/nif/src/blocks/tri_shape/.
byroredux/src/systems.rs and byroredux/src/cell_loader.rs survive as thin re-export
shims beside their systems/ and cell_loader/ dirs — re-point a Location there
to the owning submodule (e.g. byroredux/src/systems/particle.rs).
3. Filter by status
Process only findings with status NEW. Existing: #NNN and Regression of #NNN
are already tracked upstream — record them in the summary, do not re-file.
4. Validate each NEW finding against current code
- Read the referenced file at the symbol (not the line — line numbers drift; trust
grep -rn <fn/struct>). - Re-map before judging. If the
Location:file no longer exists but the code does (a split, not a fix), resolve to the current submodule and update the finding's path before filing. Do NOT mark a path move as STALE. Examples: material logic lives atbyroredux/src/material_translate.rs(translate_material) +crates/core/src/ecs/components/material.rs(Material::resolve_pbr); the per-frame particle system isbyroredux/src/systems/particle.rs(apply_emitter_params), fed bycrates/nif/src/import/walk/emitter.rs(extract_emitter_params/extract_emitter_rate). - Classify: CONFIRMED (bug still present) → file it; STALE (already fixed) → skip, record in summary; UNVERIFIABLE (cannot confirm against code) → skip, record in summary.
5. Deduplicate against open issues
Follow _audit-common's Deduplication flow:
mkdir -p /tmp/audit
gh issue list --repo matiaszanolli/ByroRedux --limit 400 --json number,title,state,labels \
> /tmp/audit/issues.json
Match each CONFIRMED finding's keywords against existing open issue titles.
On a match, skip and record Existing #NNN in the summary. The list above is open-only
(gh issue list defaults to --state open), so check closed issues per finding with
gh issue list --repo matiaszanolli/ByroRedux --state closed --search "<keywords>" --json number,title;
if a closed issue matches and the bug is back, file it but title/note it as a regression of #NNN.
6. Reconcile labels against the live repo (do this once, before any create)
The set of labels that exist in the repo is authoritative — gh issue create rejects an
unknown label. Pull the live set first:
gh label list --repo matiaszanolli/ByroRedux --limit 200 --json name --jq '.[].name' \
> /tmp/audit/labels.txt
Every label this skill applies MUST appear in that file. The four axes are defined in _audit-common's Issue Labels section — do not restate them; the summary below is the publish-time mapping only.
Severity (always exactly one): critical · high · medium · low · info.
Type (always exactly one): bug · enhancement · documentation. There is no
maintenance label — tech-debt findings use the tech-debt domain label plus bug;
doc-rot findings use documentation + doc-rot.
Domain (one or more) — as of 2026-08-21 nearly every audited subsystem has its own label. Map the finding's subsystem directly:
| Finding subsystem | Domain label(s) |
|-------------------|-----------------|
| NIF parser / block dispatch | nif-parser (primary) + nif (format tag) |
| NIFAL canonical translation | nifal + the subsystem it lands in (nif-parser / renderer) |
| ESM / CELL / WRLD / plugin loading | esm-plugin |
| BSA / BA2 / CSG archive readers | import-pipeline (no bsa label — flag the gap) |
| Vulkan renderer / RT / denoiser | renderer (+ vulkan / pipeline / memory) |
| GLSL / SPIR-V sources, shader contract | shaders (+ renderer) |
| Water — WATAL translation, buoyancy, waterline | water |
| Terrain / LOD / sky / weather / ground cover / worldspace (EXAL, SKYAL) | terrain-exterior (+ renderer / shaders for the GPU half) |
| Inventory / containers / loot / consumables / combat / AI packages / locomotion | gameplay + the narrower tag (inventory / combat / ai / quests / dialogue) |
| BGSM / CDB / HKX / FaceGen / MenuXml / game-detect readers | import-pipeline (no own label — flag the gap) |
| SDK, debug server / protocol / byro-dbg, launcher, settings-io | tech-debt (no own label — flag the gap) |
| Physics — Havok→Rapier, colliders, ragdoll (PHYSAL) | physics |
| SpeedTree (.spt) | speedtree |
| Character rulesets — ActorValues, perks, leveling (CHARAL) | character |
| Audio (M44) | audio |
| Scaleform / SWF UI (R4 + M48) | ui |
| Save/load (M45) | save-load |
| Papyrus / ObScript / scripting runtime | scripting |
| ECS storage / queries / scheduler | ecs |
| Animation runtime / KF import / clip sampling | animation (+ ecs / nif-parser for the side it lands in) |
| Cargo dependency drift, pins, MSRV | dependencies (+ tech-debt) |
| GPU sync (semaphores, fences, barriers) | sync |
| CPU lock ordering / races / access declarations | concurrency |
| Platform / windowing, audit infrastructure | tech-debt (no own label — flag the gap) |
Game (zero or more) — apply whenever the finding is specific to a title, in addition
to the domain label. A per-game audit report labels every finding with its game; a
cross-cutting audit labels only the findings that name a specific title's data:
game:fnv · game:fo3 · game:fo4 · game:fo76 · game:skyrim · game:oblivion ·
game:starfield.
Cross-cutting kind tags (zero or more, alongside the domain):
doc-rot— the defect is documentation drifted from code (stale ROADMAP row, SKILL doc naming a deleted symbol, a comment describing removed behaviour). Pair withdocumentationas the type.test-gap— the defect is missing/vacuous/non-asserting coverage. Pair with the domain of the code left untested.tech-debt— dead code, duplication, stale markers, magic numbers, oversized files.
If a finding genuinely has no reasonable existing label, file it with severity + bug
only and flag the missing-label gap in the summary. Do not gh label create ad hoc —
new labels are a deliberate repo decision, not a per-publish side effect.
Report-family defaults — the AUDIT_<TYPE>_<DATE>.md filename selects a default
domain/type; a per-finding Dimension/domain always overrides it:
| Report (AUDIT_<TYPE>_*.md) | Default domain | Type | Extra |
|------------------------------|----------------|------|-------|
| AUDIT_RENDERER_* | renderer | bug | — |
| AUDIT_ECS_* | ecs | bug | — |
| AUDIT_CONCURRENCY_* | concurrency | bug | sync on GPU-side findings |
| AUDIT_NIF_* | nif-parser | bug | nif |
| AUDIT_NIFAL_* | nifal | bug | + the landing subsystem |
| AUDIT_ESM_* | esm-plugin | bug | — |
| AUDIT_PHYSICS_* | physics | bug | water on the WATAL buoyancy sink |
| AUDIT_CHARACTER_* | character | bug | — |
| AUDIT_UI_* | ui | bug | — |
| AUDIT_SAVE_* | save-load | bug | — |
| AUDIT_AUDIO_* | audio | bug | — |
| AUDIT_SPEEDTREE_* | speedtree | bug | terrain-exterior |
| AUDIT_SCRIPTING_* | scripting | bug | — |
| AUDIT_PAPYRUS_* | scripting | bug | — |
| AUDIT_PERFORMANCE_* | performance | bug | + the landing subsystem |
| AUDIT_SAFETY_* | safety | bug | + the landing subsystem |
| AUDIT_RUNTIME_* | (per finding) | bug | performance on fps/draw-call drift |
| AUDIT_EXTERIOR_* | terrain-exterior | bug | water / shaders / renderer per finding |
| AUDIT_GAMEPLAY_* | gameplay | bug | inventory / combat / ai / quests / dialogue per finding |
| AUDIT_PARSERS_* | import-pipeline | bug | game:* where title-specific |
| AUDIT_TOOLING_* | tech-debt | bug | — |
| AUDIT_FNV_* / AUDIT_FO3_* / AUDIT_FO4_* / AUDIT_SKYRIM_* / AUDIT_OBLIVION_* / AUDIT_STARFIELD_* | (per finding) | bug | the matching game:* on every finding + legacy-compat |
| AUDIT_LEGACY_COMPAT_* | legacy-compat | bug | game:* where title-specific |
| AUDIT_TECH_DEBT_* | (per finding) | bug | tech-debt |
| AUDIT_INCREMENTAL_* / AUDIT_REGRESSION_* | (per finding) | bug | — |
For AUDIT_TECH_DEBT_* the final set is <severity>,<domain?>,tech-debt,bug. Doc-rot
findings — in any report family — swap bug → documentation and add doc-rot;
coverage findings add test-gap. For everything else: <severity>,<domain>,bug,
plus game:<title> whenever the finding is specific to one game's data.
7. Build the completeness checklist (per CONFIRMED finding)
Append to each issue body. Drop rows that can't apply (e.g. omit FFI if the fix is NIF-only):
## Completeness Checks
- [ ] **UNSAFE**: If the fix adds `unsafe`, a safety comment states the upheld invariant
- [ ] **SIBLING**: Same pattern checked in related files (other shader types, other block parsers)
- [ ] **DROP**: If Vulkan objects change, the Drop impl is still reverse-order correct
- [ ] **LOCK_ORDER**: If a RwLock scope changes, TypeId-sorted acquisition is preserved
- [ ] **FFI**: If the cxx bridge is touched, pointer lifetimes across the boundary are sound
- [ ] **CANONICAL-BOUNDARY**: If the fix touches `byroredux/src/material_translate.rs` (`translate_material`), `Material::resolve_pbr` (`crates/core/src/ecs/components/material.rs`), or the emitter params in `crates/nif/src/import/walk/emitter.rs` (`extract_emitter_params` / `extract_emitter_rate`), per-game logic stays at the NIFAL parser→`Material` boundary — never pushed into shaders/renderer, never re-derived at render time. See `/audit-nifal`.
- [ ] **TESTS**: A regression test pins this specific fix
8. Create the issue
gh issue create --repo matiaszanolli/ByroRedux \
--title "<ID>: <title>" \
--body "<description + evidence + impact + suggested fix + completeness checks>" \
--label "<severity>,<domain>,<type>"
--label takes a comma-separated list. Every token must be in /tmp/audit/labels.txt
(step 6). If gh rejects a label, the reconciliation missed one — fix the mapping, do not
drop the finding silently.
9. Snapshot to local tracking
mkdir -p .claude/issues/<NUMBER>
Write .claude/issues/<NUMBER>/ISSUE.md with the finding details.
Immutable-snapshot convention (TD10-001 / #1156): this file is the issue as filed,
not a live mirror. GitHub is authoritative for current state — query
gh issue view <N> --json state when live state is needed. Do not write a
State:/Status: field. The convention applies symmetrically to INVESTIGATION.md and
any sibling created by /fix-issue.
10. Completeness summary (the gate)
Every NEW finding must reach a terminal action — created, skipped-as-duplicate, or skipped-with-reason. Print the table and assert the count matches: NEW findings parsed == (Created + Skipped). A NEW finding that is neither created nor consciously skipped is a publish bug.
| Finding | Action | Reason |
|---------|--------|--------|
| REN-001 | Created #42 | NEW, CONFIRMED |
| REN-002 | Skipped | Existing #38 |
| REN-003 | Skipped | STALE (fixed in composite.rs) |
| BSA-004 | Created #43 | NEW, CONFIRMED — labeled import-pipeline (no bsa label) |
Flag any subsystem-without-a-label mappings (step 6) here so the gap is visible.
11. Suggest next step
For each created issue:
Fix with: /fix-issue <number>
From the file to a first result
The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.
View the source and supporting filesThis download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.
1. Download the file
Download SKILL.mdFrom the root of a test project, save the file as .skill-downloads/audit-report-to-github-issues-publisher-mvg6ty4b/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.
Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.
mkdir -p '.skill-downloads/audit-report-to-github-issues-publisher-mvg6ty4b' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/audit-report-to-github-issues-publisher-mvg6ty4b/download' --output '.skill-downloads/audit-report-to-github-issues-publisher-mvg6ty4b/SKILL.md.part' && mv '.skill-downloads/audit-report-to-github-issues-publisher-mvg6ty4b/SKILL.md.part' '.skill-downloads/audit-report-to-github-issues-publisher-mvg6ty4b/SKILL.md'2. Check prerequisites
Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.
No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.
The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.
3. Load the skill
This file does not provide a usable name/description header for this native procedure. It remains available to download and inspect; use the manual method below.
Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.
4. Try a first task
Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:
Read .skill-downloads/audit-report-to-github-issues-publisher-mvg6ty4b/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.
Configure a Chat Channel with SecretRefs
DevOps
Set up chat channels using non-interactive commands, with secrets only as SecretRefs. Covers gather, mutate, repair, and prove steps for reliable delivery.
Investigate ClickHouse CI Failures
DevOps
Investigate a ClickHouse CI failure end-to-end from a PR or S3 report URL. Fetches failed tests, classifies flaky vs real regression, and checks for existing issues/fixes.
Ansible PR Review
DevOps
Reviews an Ansible PR following the project's standardized process, including changelog checks, test coverage validation, and feedback tracking.