|
| 1 | +# Automated Code Review Guidelines (DVYUKOV.md) |
| 2 | + |
| 3 | +This file contains curated recommendations extracted from automated pull request reviews. Ingest this file into your LLM pipeline to ensure compliance with repository style and best practices! |
| 4 | + |
| 5 | +## 1. Go Coding Style & Idioms |
| 6 | +- **Naming:** |
| 7 | + - Lowercase package names (no underscores or MixedCaps). |
| 8 | + - Use `NewFoo` or `MakeFoo` for constructors; return pointers if methods are defined on pointers. |
| 9 | + - Avoid repeating type names in method names (e.g., `linux.Foo()` not `linux.FooLinux()`). |
| 10 | + - Avoid "syz" prefixes for internal structs/fields (e.g., `exec_total` not `syz_exec_total`). |
| 11 | + - Use `i` for loop indices; use descriptive names for slice elements. |
| 12 | + - Favor positive boolean naming (`active` vs `not_inactive`). |
| 13 | +- **Declarations:** |
| 14 | + - Combine declaration and initialization (`x := foo()`). |
| 15 | + - Rely on zero-value defaults; do not manually initialize to 0, "", or `map[type]type{}`. |
| 16 | + - Unexport symbols (types, fields, constants, functions) not needed externally. |
| 17 | + - Use `iota` for enums and make `Invalid` the first value (0) to catch uninitialized fields. |
| 18 | + - Use `go:embed` for embedding static assets like HTML or text templates. |
| 19 | +- **Functions & Control Flow:** |
| 20 | + - Return early on errors (standard `if err != nil` check); avoid deep nesting. |
| 21 | + - Avoid naked or named returns unless they significantly simplify repetitive code. |
| 22 | + - Drop unnecessary `else` after `return`, `break`, or `continue`. |
| 23 | + - Prefer free/normal functions over closures if no context is captured from the outer scope. |
| 24 | + - Use closures to deduplicate scoped logic within a single function. |
| 25 | +- **Miscellaneous:** |
| 26 | + - Cap Go lines at 120 columns; use tabs for indentation. |
| 27 | + - Use `%s` for struct string conversion in `fmt` functions (idiomatic `v.String()` call). |
| 28 | + - Avoid unneeded parentheses in expressions and `()` to refer to functions in comments. |
| 29 | + |
| 30 | +## 2. Error Handling & Reliability |
| 31 | +- **Return Errors:** Never swallow errors or return `nil` on unexpected conditions. |
| 32 | +- **Fail Fast:** |
| 33 | + - Validate invariants early (e.g., during initialization or deserialization). |
| 34 | + - Panic on impossible internal logic corruption or broken engine invariants. |
| 35 | + - For external tools/plugins, use `SYZFAIL:` prefix for internal bugs to distinguish from target crashes. |
| 36 | +- **Error Context:** |
| 37 | + - Don't wrap errors without adding specific, helpful context (Syzkaller libs often add basic context). |
| 38 | + - Use `aflow.BadCallError` for invalid tool inputs in agent workflows. |
| 39 | +- **Validation:** |
| 40 | + - Always validate inputs at boundaries (datastores, APIs, CLI flags, regexes). |
| 41 | + - Guard against underflows/overflows in length checks and binary formats. |
| 42 | + |
| 43 | +## 3. Testing Best Practices |
| 44 | +- **Assertions:** Use `github.com/stretchr/testify/require` (or `assert`) for single-line, readable assertions. |
| 45 | +- **Structure:** |
| 46 | + - Use table-driven tests with `t.Run` for isolation and subtest selection. |
| 47 | + - Keep helper functions at the bottom of the test file; use `t.Cleanup` for teardown. |
| 48 | +- **Data Handling:** |
| 49 | + - Use backtick raw string literals (`` ` ``) for multi-line test data, regexes, and assembly. |
| 50 | + - Use `AUTO` in syzlang tests for auto-computing lengths and offsets. |
| 51 | + - Use `timeNow` over `time.Now` for deterministic test stubbing. |
| 52 | +- **Robustness:** |
| 53 | + - Run tests with `-race` to surface data races. |
| 54 | + - Check for goroutine leaks in tests using background concurrency. |
| 55 | + - Test boundary conditions (e.g., empty slices, index limits, or corrupted inputs). |
| 56 | + - Never just disable failing tests; fix them or document why they are disabled. |
| 57 | + - Include sample reports in `pkg/report/testdata` for new crash parsers. |
| 58 | + |
| 59 | +## 4. Architecture & Design |
| 60 | +- **YAGNI (You Ain't Gonna Need It):** |
| 61 | + - Don't add code "just in case"; remove unused types, fields, and dead code immediately. |
| 62 | + - Avoid unnecessary tunables/config flags; pick sensible defaults and scale timeouts. |
| 63 | +- **Decoupling:** |
| 64 | + - Keep logic uniform across different execution modes (e.g., fork-server vs no-fork-server). |
| 65 | + - Use standard interfaces (e.g., `io.Closer`) over custom cleanup methods. |
| 66 | + - Prefer specific, descriptive package names over generic ones like `util` or `generic`. |
| 67 | + - Prioritize larger, coherent packages over many micro-packages. |
| 68 | +- **State Management:** |
| 69 | + - Favor simple state tracking (single counter/slice) over complex nested maps. |
| 70 | + - Use Arch struct fields instead of logic-driven switches for architecture differences. |
| 71 | + - Pass objects/pointers early instead of passing IDs and doing repeated lookups. |
| 72 | + |
| 73 | +## 5. Performance & Resource Management |
| 74 | +- **Efficiency:** |
| 75 | + - Use map lookups (O(1)) instead of double loops (O(N^2)) for filtering. |
| 76 | + - Avoid casting large buffers to strings if only byte processing is needed. |
| 77 | + - Prefer direct slicing over `io.Reader` for byte processing to reduce garbage. |
| 78 | + - Avoid `bufio.Writer` when writing to `bytes.Buffer`. |
| 79 | +- **Resource Cleanup:** |
| 80 | + - Always `Wait()` on launched commands; use `defer` to close file descriptors and pipes. |
| 81 | + - Extract loop bodies into functions if they use `defer` to ensure per-iteration cleanup. |
| 82 | +- **Concurrency:** |
| 83 | + - Use channels for semaphores or async notifications; use capacity 1 to prevent blocking. |
| 84 | + - Use `nil` channels to disable `select` cases. |
| 85 | + - Ensure condition variables are checked in a loop to prevent race hangs. |
| 86 | + - Avoid infinite goroutine spawning in pools; track wait states. |
| 87 | + |
| 88 | +## 6. Logging & Observability |
| 89 | +- **Hygiene:** |
| 90 | + - Use the internal `log` package consistently; avoid mixing multiple logger libraries. |
| 91 | + - Log only actionable information at verbosity 0; use info logs for invalid user requests. |
| 92 | + - Don't suffix log messages with newlines (`\n`). |
| 93 | + - Format string safety: use `Logf(1, "%s", out)` instead of `Logf(1, out)`. |
| 94 | +- **Determinism:** Always sort map keys when serializing to persistent formats (configs, logs, coverage). |
| 95 | +- **Metrics:** Rename existing metrics rather than adding confusing duplicates when semantics change. |
| 96 | +- **Reporting:** Keep email prefixes short; explain *why* something was skipped in bisection logs. |
| 97 | + |
| 98 | +## 7. Syzkaller Specifics (Syzlang & Executor) |
| 99 | +- **Syzlang (.txt files):** |
| 100 | + - Use modern syscalls (e.g., `openat` with `AT_FDCWD` instead of `open`). |
| 101 | + - Use exact kernel field names; use descriptive prefixes to avoid collisions. |
| 102 | + - Use `const[0]` for reserved/unused fields to optimize mutation. |
| 103 | + - Inherited resources (from `fd`) get `read` and `close` automatically. |
| 104 | + - Use `ignore_return` for syscalls returning random system IDs or times. |
| 105 | +- **Executor (C++):** |
| 106 | + - Keep `executor.cc` free of OS-specific `#ifdefs`; use OS-specific headers. |
| 107 | + - Use `const std::string&` or `std::string_view` for immutable strings. |
| 108 | + - Check for short writes in output loops. |
| 109 | + - Avoid C89 start-of-block declarations; combine declaration and initialization. |
| 110 | + |
| 111 | +## 8. Tooling & Infrastructure |
| 112 | +- **CLI Tools:** |
| 113 | + - Standardize on `tool.Init()` and `tool.Failf()` from `pkg/tool`. |
| 114 | + - Declare CLI flags in `main()` to avoid global namespace pollution. |
| 115 | + - Use `runtime.NumCPU()` for default worker counts. |
| 116 | +- **OS Operations:** |
| 117 | + - Use `filepath.Join` for OS-agnostic paths; use `osutil.IsExist` for existence checks. |
| 118 | + - Combine multiple shell commands (e.g., `adb shell 'cmd1; cmd2'`) to reduce overhead. |
| 119 | +- **HTML/UI:** |
| 120 | + - Use standard `<details>` and `<summary>` for collapsibles. |
| 121 | + - Use tabs for HTML templates. |
| 122 | + |
| 123 | +> [!TIP] |
| 124 | +> This file is automatically updated by the workflow in `.github/workflows/update-review-guidelines.yml` to reflect new feedback as it occurs! |
0 commit comments