opencode-audit #17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: opencode-audit | |
| on: | |
| schedule: | |
| - cron: '0 6 * * *' | |
| - cron: '0 18 * * *' | |
| workflow_dispatch: | |
| inputs: | |
| module: | |
| description: 'Module to scan (e.g. engine/graphics, world/worldgen)' | |
| required: false | |
| type: string | |
| jobs: | |
| audit: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| permissions: | |
| id-token: write | |
| contents: write | |
| issues: write | |
| pull-requests: write | |
| steps: | |
| - name: Select module to scan | |
| id: select-module | |
| env: | |
| INPUT_MODULE: ${{ inputs.module }} | |
| run: | | |
| MODULES=( | |
| "engine/graphics" | |
| "engine/core" | |
| "engine/math" | |
| "engine/input" | |
| "engine/ui" | |
| "engine/atmosphere" | |
| "engine/audio" | |
| "engine/ecs" | |
| "engine/physics" | |
| "world" | |
| "world/meshing" | |
| "world/worldgen" | |
| "game" | |
| ) | |
| COUNT=${#MODULES[@]} | |
| if [ -n "$INPUT_MODULE" ]; then | |
| if ! echo "$INPUT_MODULE" | grep -qE '^[a-zA-Z0-9_ /-]+$'; then | |
| echo "ERROR: Invalid module input: '$INPUT_MODULE'" >&2 | |
| exit 1 | |
| fi | |
| SELECTED="$INPUT_MODULE" | |
| echo "Manual dispatch: scanning ${SELECTED}" | |
| else | |
| DAY=$((10#$(date +%j))) | |
| INDEX=$((DAY % COUNT)) | |
| SELECTED="${MODULES[${INDEX}]}" | |
| echo "Scheduled run: day=${DAY} index=${INDEX} → ${SELECTED}" | |
| fi | |
| echo "module=${SELECTED}" >> "$GITHUB_OUTPUT" | |
| echo "module_path=src/${SELECTED}" >> "$GITHUB_OUTPUT" | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Ensure audit label exists | |
| run: | | |
| if ! gh label list --json name --jq '.[].name' | grep -q '^automated-audit$'; then | |
| gh label create "automated-audit" \ | |
| --description "Issues found by automated opencode audit scans" \ | |
| --color "1D76DB" | |
| fi | |
| env: | |
| GH_TOKEN: ${{ secrets.OPENCODE_PAT }} | |
| - name: Setup Nix | |
| uses: ./.github/actions/setup-nix | |
| - name: Ensure opencode cache dir exists | |
| run: | | |
| # Nix installer may restrict ~/.cache permissions; restore and use /tmp for non-persistent cache | |
| sudo chmod u+w ~/.cache 2>/dev/null || true | |
| mkdir -p /tmp/opencode-cache ~/.local/share/opencode | |
| - name: Run opencode audit | |
| uses: anomalyco/opencode/github@v1.3.3 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.OPENCODE_PAT }} | |
| GH_TOKEN: ${{ secrets.OPENCODE_PAT }} | |
| KIMI_API_KEY: ${{ secrets.KIMI_API_KEY }} | |
| XDG_CACHE_HOME: /tmp/opencode-cache | |
| with: | |
| model: kimi-for-coding/k2p5 | |
| prompt: | | |
| You are a senior Zig systems programming auditor performing a deep code audit. | |
| ## YOUR TASK | |
| Perform a thorough audit of the `${{ steps.select-module.outputs.module_path }}/` directory in this codebase. Your goal is to find the single most impactful issue or improvement opportunity and file a GitHub issue with full details. | |
| ## ⛔ ABSOLUTE RULES — READ THESE FIRST | |
| **YOU MUST NOT:** | |
| - Create branches (`git checkout -b`, `git branch`, `git push`) | |
| - Create pull requests (`gh pr create`) | |
| - Modify or create any files (no `git commit`, no file writes) | |
| - Run any `git push` command for any reason | |
| **YOU MUST ONLY:** | |
| - Read source code files to understand the codebase | |
| - Run read-only commands (`ls`, `cat`, `gh issue list`, `gh pr list`, `nix develop --command zig build test`) | |
| - Create EXACTLY ONE GitHub issue using `gh issue create` | |
| If you violate these rules, your output will be automatically reverted. No exceptions. | |
| **Additional constraints:** | |
| 1. You may ONLY create a single GitHub issue. Do NOT create branches, pull requests, or modify any files. | |
| 2. If you find nothing meaningful, file NO issue. Silence is better than noise. | |
| 3. Before filing, run `gh issue list --label "automated-audit" --state open --limit 50` and verify no existing issue already covers the same finding. If one exists, do NOT file a duplicate. | |
| 4. Before filing, run `gh pr list --state open --limit 50` and check if any open PR already addresses the same problem (e.g., PR title or description mentions the bug/area). If one exists, post a comment on that PR instead of filing a duplicate issue. | |
| ## CODEBASE CONTEXT | |
| ZigCraft is a high-performance Minecraft-style voxel engine built with: | |
| - **Zig 0.14+** with strict memory management (explicit allocators, defer/errdefer) | |
| - **SDL3** for windowing and input | |
| - **Vulkan** for rendering (only backend, via RHI abstraction) | |
| - **Nix** for reproducible builds (`nix develop --command zig build`) | |
| - **GLSL shaders** validated via glslangValidator | |
| - **Custom job system** for multithreaded world generation and meshing | |
| Build commands available: | |
| - `nix develop --command zig build test` — unit tests + shader validation | |
| - `nix develop --command zig fmt src/` — format code | |
| - `nix develop --command zig build -Doptimize=ReleaseFast` — release build | |
| ## MODULE-SPECIFIC FOCUS | |
| Tailor your audit depth based on which module you're scanning: | |
| **engine/graphics** → Vulkan resource lifecycle, buffer/texture handle leaks, pipeline state correctness, memory barriers, synchronization primitives, double-buffering with MAX_FRAMES_IN_FLIGHT, shader uniform naming mismatches, GPU data layout (packed struct alignment) | |
| **engine/core** → Job system correctness (work stealing, deadlock potential), mutex usage patterns, logging edge cases, time precision issues | |
| **engine/math** → Float precision edge cases, vector/matrix operation correctness, AABB/Frustum corner cases, SIMD opportunity gaps | |
| **engine/input** → Event handling completeness, input state consistency across frames, edge cases in key/mouse binding | |
| **engine/ui** → Immediate-mode UI performance, text rendering edge cases, widget state management, font glyph coverage | |
| **engine/atmosphere** → Atmospheric scattering correctness, gradient banding, LOD transitions for sky rendering | |
| **engine/audio** → Backend abstraction correctness, buffer management, audio thread synchronization, resource cleanup | |
| **engine/ecs** → Component storage efficiency, archetype fragmentation, query performance, system dependency ordering | |
| **engine/physics** → Collision detection edge cases, numerical stability, broad-phase efficiency, penetration resolution | |
| **world** (core) → Chunk data structure correctness, worldToChunk/worldToLocal coordinate transforms, chunk pin/unpin lifecycle, chunk storage efficiency, streaming boundary conditions | |
| **world/meshing** → Greedy meshing correctness, AO calculation artifacts, lighting sampler accuracy, boundary mesh stitching, allocation patterns in hot paths | |
| **world/worldgen** → Noise algorithm correctness, biome selection edge cases, cave generation artifacts, terrain continuity at chunk boundaries, allocator usage in generation hot paths, decoration placement bugs, schematic loading safety | |
| **game** → Screen state machine correctness, settings persistence, game loop timing, UI/game state synchronization | |
| ## WHAT TO LOOK FOR (Broad Scan) | |
| Prioritize by impact. Check for: | |
| 1. **Memory Safety** — Leaks (missing defer), double-free potential, dangling pointers, allocator misuse, ArrayListUnmanaged without proper deinit | |
| 2. **Concurrency Bugs** — Unprotected shared state, race conditions, deadlock potential, missing mutex, chunk pin/unpin mismatches across threads | |
| 3. **Error Handling** — Swallowed errors (catching and ignoring), missing `try`, error sets that are too broad or too narrow | |
| 4. **Performance** — Unnecessary allocations in hot paths (especially worldgen/meshing), cache-unfriendly data layouts, redundant computation, missing bounds on loops | |
| 5. **Correctness** — Off-by-one errors, wrong integer types (signed vs unsigned for coordinates), integer overflow potential, incorrect coordinate system usage | |
| 6. **Dead Code / Unused Variables** — Functions never called, variables assigned but unused, imported but unused modules | |
| 7. **Missing Tests** — Critical logic paths with no test coverage, especially math operations and coordinate transforms | |
| 8. **API Misuse** — Vulkan calls with wrong parameters, incorrect RHI usage, mismatched create/destroy patterns | |
| ## HOW TO AUDIT | |
| 1. First, read the directory listing of `${{ steps.select-module.outputs.module_path }}/` to understand the scope | |
| 2. Read each source file in the module, starting with the most critical ones (those dealing with GPU resources, memory, or concurrency) | |
| 3. For each file, trace the data flow: how are resources created, used, and destroyed? | |
| 4. Cross-reference with other modules if needed (e.g., check if callers of a function handle errors correctly) | |
| 5. If possible, run `nix develop --command zig build test` to check if existing tests pass | |
| 6. If you find a concrete issue, verify it by reading surrounding code to confirm it's a real problem, not a false positive | |
| ## ISSUE FORMAT | |
| If you find a meaningful issue, create it using this EXACT structure: | |
| **Title:** `[Audit][{PRIORITY}] {concise description}` | |
| - Priority is one of: Critical, High, Medium, Low | |
| **Labels:** `automated-audit` | |
| **Body must follow this template exactly:** | |
| ``` | |
| ## 🔍 Module Scanned | |
| `src/{module}/` (automated audit scan) | |
| ## 📝 Summary | |
| 2-3 sentences describing the issue clearly. | |
| ## 📍 Location | |
| - **File:** `src/path/to/file.zig:{line_number}` | |
| - **Function/Scope:** `{function_name}` or `{struct_name}` | |
| ## 🔴 Severity: {Critical|High|Medium|Low} | |
| - **Critical:** Crashes, data corruption, security vulnerabilities, GPU device loss | |
| - **High:** Memory leaks, race conditions, incorrect rendering, broken features | |
| - **Medium:** Performance degradation, missing error handling, suboptimal patterns | |
| - **Low:** Code style, dead code, minor improvements | |
| ## 💥 Impact | |
| What happens if this is not addressed? Be specific about user-visible symptoms or system behavior. | |
| ## 🔎 Evidence | |
| Include the relevant code snippet (5-15 lines) that demonstrates the problem. Use a code block with `zig` syntax highlighting. Point out exactly which lines are problematic and why. | |
| ## 🛠️ Proposed Fix | |
| Provide specific, actionable steps to fix the issue. Include code snippets where helpful. Reference specific function names, types, or patterns to use. | |
| ## ✅ Acceptance Criteria | |
| - [ ] {specific testable criterion 1} | |
| - [ ] {specific testable criterion 2} | |
| - [ ] {specific testable criterion 3} | |
| Example criteria: | |
| - "All unit tests in `src/tests.zig` pass" | |
| - "No memory leaks detected when running with `zig build test`" | |
| - "The function returns correct results for edge cases: empty input, max values, negative values" | |
| - "The fix has been verified with `nix develop --command zig build test`" | |
| ## 📚 References | |
| - Link to any related issues, docs, or Zig standard library patterns that are relevant. | |
| ``` | |
| ## FINAL REMINDERS | |
| - **One issue maximum.** If you find multiple problems, file the one with the highest impact. | |
| - **Check for duplicates first.** Run `gh issue list --label "automated-audit" --state open --limit 50` and compare before filing. Also run `gh pr list --state open --limit 50` to check if a fix is already in progress. | |
| - **No false positives.** If you're not confident an issue is real, don't file it. Verify by reading surrounding code. | |
| - **No action is valid.** If the module looks clean, that's a good outcome. Don't manufacture issues. | |
| - **Be specific.** Every claim must reference a specific file, line number, and code pattern. No vague statements. | |
| ## ⛔ REMINDER: ABSOLUTE RULES (REPEATED) | |
| - Do NOT create branches. Do NOT push code. Do NOT create pull requests. | |
| - Do NOT modify or create any files. | |
| - ONLY use `gh issue create` to file your finding. | |
| - If you feel tempted to create a PR or branch, STOP. Create an issue instead. | |
| - name: Compliance guard — enforce issue-only output | |
| if: always() | |
| run: | | |
| echo "=== Checking for audit compliance violations ===" | |
| BOT_LOGIN="opencode-agent[bot]" | |
| VIOLATIONS=0 | |
| CUTOFF=$(date -u -d '30 minutes ago' +%Y-%m-%dT%H:%M:%SZ) | |
| NEW_PRS=$(gh pr list --author "$BOT_LOGIN" --state open --limit 10 \ | |
| --json number,title,headRefName,createdAt,body \ | |
| --jq '.[] | select(.createdAt >= "'"$CUTOFF"'")') | |
| if [ -n "$NEW_PRS" ]; then | |
| echo "::error::Compliance violation detected: agent created pull request(s) instead of issue(s)" | |
| echo "$NEW_PRS" | jq -c '.number' | while read -r PR_NUM; do | |
| PR_NUM=$(echo "$PR_NUM" | tr -d '"') | |
| echo " ❌ Closing rogue PR #$PR_NUM" | |
| PR_BODY=$(gh pr view "$PR_NUM" --json body --jq '.body') | |
| PR_TITLE=$(gh pr view "$PR_NUM" --json title --jq '.title') | |
| BRANCH=$(gh pr view "$PR_NUM" --json headRefName --jq '.headRefName') | |
| ISSUE_TITLE="[Audit] ${PR_TITLE}" | |
| ISSUE_BODY=$(cat <<ISSUE_EOF | |
| ## ⚠️ Auto-converted from rogue PR #$PR_NUM | |
| The audit agent incorrectly created a pull request instead of a GitHub issue. | |
| The finding has been automatically converted below. | |
| --- | |
| $PR_BODY | |
| ISSUE_EOF | |
| ) | |
| echo " 📝 Creating issue from PR content..." | |
| gh issue create \ | |
| --label "automated-audit" \ | |
| --title "$ISSUE_TITLE" \ | |
| --body "$ISSUE_BODY" || echo " ⚠️ Failed to create issue from PR" | |
| gh pr close "$PR_NUM" --comment "Auto-closed by compliance guard: audit workflow must create issues, not PRs." --delete-branch | |
| VIOLATIONS=$((VIOLATIONS + 1)) | |
| done | |
| fi | |
| BOT_BRANCHES=$(gh api "repos/${{ github.repository }}/branches" \ | |
| --jq ".[] | select(.name | startswith(\"opencode/\")) | .name" 2>/dev/null || echo "") | |
| if [ -n "$BOT_BRANCHES" ]; then | |
| echo "::warning::Found opencode/ branches that may be audit violations:" | |
| echo "$BOT_BRANCHES" | while read -r BRANCH; do | |
| echo " ⚠️ Branch: $BRANCH" | |
| done | |
| fi | |
| if [ "$VIOLATIONS" -gt 0 ]; then | |
| echo "::error::Compliance guard corrected $VIOLATIONS violation(s). PR(s) closed and converted to issue(s)." | |
| else | |
| echo "✅ No compliance violations detected." | |
| fi | |
| env: | |
| GH_TOKEN: ${{ secrets.OPENCODE_PAT }} |