red64-cli 0.3.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +194 -338
  2. package/dist/cli/parseArgs.d.ts.map +1 -1
  3. package/dist/cli/parseArgs.js +5 -13
  4. package/dist/cli/parseArgs.js.map +1 -1
  5. package/dist/components/init/types.d.ts +0 -2
  6. package/dist/components/init/types.d.ts.map +1 -1
  7. package/dist/components/screens/HelpScreen.d.ts.map +1 -1
  8. package/dist/components/screens/HelpScreen.js +0 -2
  9. package/dist/components/screens/HelpScreen.js.map +1 -1
  10. package/dist/components/screens/InitScreen.d.ts.map +1 -1
  11. package/dist/components/screens/InitScreen.js +5 -8
  12. package/dist/components/screens/InitScreen.js.map +1 -1
  13. package/dist/components/screens/StartScreen.d.ts.map +1 -1
  14. package/dist/components/screens/StartScreen.js +29 -8
  15. package/dist/components/screens/StartScreen.js.map +1 -1
  16. package/dist/components/screens/StatusScreen.d.ts.map +1 -1
  17. package/dist/components/screens/StatusScreen.js +16 -1
  18. package/dist/components/screens/StatusScreen.js.map +1 -1
  19. package/dist/services/AgentInvoker.d.ts.map +1 -1
  20. package/dist/services/AgentInvoker.js +76 -37
  21. package/dist/services/AgentInvoker.js.map +1 -1
  22. package/dist/services/ClaudeErrorDetector.d.ts +1 -1
  23. package/dist/services/ClaudeErrorDetector.d.ts.map +1 -1
  24. package/dist/services/ClaudeErrorDetector.js +1 -0
  25. package/dist/services/ClaudeErrorDetector.js.map +1 -1
  26. package/dist/services/ClaudeHealthCheck.d.ts +7 -0
  27. package/dist/services/ClaudeHealthCheck.d.ts.map +1 -1
  28. package/dist/services/ClaudeHealthCheck.js +76 -12
  29. package/dist/services/ClaudeHealthCheck.js.map +1 -1
  30. package/dist/services/ConfigService.d.ts +1 -0
  31. package/dist/services/ConfigService.d.ts.map +1 -1
  32. package/dist/services/ConfigService.js.map +1 -1
  33. package/dist/services/DockerRunner.js +1 -1
  34. package/dist/services/DockerRunner.js.map +1 -1
  35. package/dist/services/PhaseExecutor.d.ts.map +1 -1
  36. package/dist/services/PhaseExecutor.js +2 -1
  37. package/dist/services/PhaseExecutor.js.map +1 -1
  38. package/dist/services/TaskRunner.d.ts.map +1 -1
  39. package/dist/services/TaskRunner.js +2 -1
  40. package/dist/services/TaskRunner.js.map +1 -1
  41. package/dist/services/index.d.ts +1 -1
  42. package/dist/services/index.d.ts.map +1 -1
  43. package/dist/services/index.js +1 -1
  44. package/dist/services/index.js.map +1 -1
  45. package/dist/types/index.d.ts +4 -3
  46. package/dist/types/index.d.ts.map +1 -1
  47. package/dist/types/index.js.map +1 -1
  48. package/framework/stacks/c/code-quality.md +326 -0
  49. package/framework/stacks/c/coding-style.md +347 -0
  50. package/framework/stacks/c/conventions.md +513 -0
  51. package/framework/stacks/c/error-handling.md +350 -0
  52. package/framework/stacks/c/feedback.md +158 -0
  53. package/framework/stacks/c/memory-safety.md +408 -0
  54. package/framework/stacks/c/tech.md +122 -0
  55. package/framework/stacks/c/testing.md +472 -0
  56. package/framework/stacks/cpp/code-quality.md +282 -0
  57. package/framework/stacks/cpp/coding-style.md +363 -0
  58. package/framework/stacks/cpp/conventions.md +420 -0
  59. package/framework/stacks/cpp/error-handling.md +264 -0
  60. package/framework/stacks/cpp/feedback.md +104 -0
  61. package/framework/stacks/cpp/memory-safety.md +351 -0
  62. package/framework/stacks/cpp/tech.md +160 -0
  63. package/framework/stacks/cpp/testing.md +323 -0
  64. package/framework/stacks/java/code-quality.md +357 -0
  65. package/framework/stacks/java/coding-style.md +400 -0
  66. package/framework/stacks/java/conventions.md +437 -0
  67. package/framework/stacks/java/error-handling.md +408 -0
  68. package/framework/stacks/java/feedback.md +180 -0
  69. package/framework/stacks/java/tech.md +126 -0
  70. package/framework/stacks/java/testing.md +485 -0
  71. package/framework/stacks/javascript/async-patterns.md +216 -0
  72. package/framework/stacks/javascript/code-quality.md +182 -0
  73. package/framework/stacks/javascript/coding-style.md +293 -0
  74. package/framework/stacks/javascript/conventions.md +268 -0
  75. package/framework/stacks/javascript/error-handling.md +216 -0
  76. package/framework/stacks/javascript/feedback.md +80 -0
  77. package/framework/stacks/javascript/tech.md +114 -0
  78. package/framework/stacks/javascript/testing.md +209 -0
  79. package/framework/stacks/loco/code-quality.md +156 -0
  80. package/framework/stacks/loco/coding-style.md +247 -0
  81. package/framework/stacks/loco/error-handling.md +225 -0
  82. package/framework/stacks/loco/feedback.md +35 -0
  83. package/framework/stacks/loco/loco.md +342 -0
  84. package/framework/stacks/loco/structure.md +193 -0
  85. package/framework/stacks/loco/tech.md +129 -0
  86. package/framework/stacks/loco/testing.md +211 -0
  87. package/framework/stacks/rust/code-quality.md +370 -0
  88. package/framework/stacks/rust/coding-style.md +475 -0
  89. package/framework/stacks/rust/conventions.md +430 -0
  90. package/framework/stacks/rust/error-handling.md +399 -0
  91. package/framework/stacks/rust/feedback.md +152 -0
  92. package/framework/stacks/rust/memory-safety.md +398 -0
  93. package/framework/stacks/rust/tech.md +121 -0
  94. package/framework/stacks/rust/testing.md +528 -0
  95. package/package.json +14 -2
@@ -0,0 +1,326 @@
1
+ # Code Quality Standards
2
+
3
+ Project memory for code quality conventions: formatting, static analysis, sanitizers, and compiler warnings in modern C.
4
+
5
+ ---
6
+
7
+ ## Philosophy
8
+
9
+ - **Shift left**: Catch bugs at compile time, not runtime
10
+ - **Automate enforcement**: clang-format and clang-tidy in CI, not code review
11
+ - **Warnings are errors**: `-Werror` in CI ensures nothing slips through
12
+ - **Sanitizers in test**: Run ASan/UBSan on every test run in CI
13
+
14
+ ---
15
+
16
+ ## clang-format Configuration
17
+
18
+ ### `.clang-format`
19
+
20
+ ```yaml
21
+ BasedOnStyle: LLVM
22
+ Language: Cpp
23
+ Standard: c17
24
+ ColumnLimit: 100
25
+ IndentWidth: 4
26
+ UseTab: Never
27
+ BreakBeforeBraces: Attach
28
+ AllowShortFunctionsOnASingleLine: Empty
29
+ AllowShortIfStatementsOnASingleLine: Never
30
+ AllowShortLoopsOnASingleLine: false
31
+ PointerAlignment: Right
32
+ SpaceBeforeParens: ControlStatements
33
+ SortIncludes: CaseSensitive
34
+ IncludeBlocks: Regroup
35
+ IncludeCategories:
36
+ - Regex: '^".*"' # Project headers (corresponding header first)
37
+ Priority: 1
38
+ - Regex: '^<(assert|ctype|errno|float|limits|locale|math|setjmp|signal|stdarg|stddef|stdio|stdlib|string|time|stdbool|stdint|inttypes|stdalign|stdatomic|stdnoreturn|threads|uchar)\.h>'
39
+ Priority: 2 # C standard library
40
+ - Regex: '^<(sys|unistd|fcntl|pthread|netinet|arpa|dlfcn).*>'
41
+ Priority: 3 # POSIX / system
42
+ - Regex: '^<.+>' # Third-party
43
+ Priority: 4
44
+ ```
45
+
46
+ ```bash
47
+ # Format all source files
48
+ clang-format -i $(find src include -name '*.c' -o -name '*.h')
49
+
50
+ # Check formatting (CI)
51
+ clang-format --dry-run --Werror $(find src include -name '*.c' -o -name '*.h')
52
+ ```
53
+
54
+ ---
55
+
56
+ ## clang-tidy Configuration
57
+
58
+ ### `.clang-tidy`
59
+
60
+ ```yaml
61
+ Checks: >
62
+ -*,
63
+ bugprone-*,
64
+ cert-*,
65
+ misc-*,
66
+ readability-*,
67
+ performance-*,
68
+ clang-analyzer-*,
69
+ -readability-identifier-length,
70
+ -readability-magic-numbers,
71
+ -bugprone-easily-swappable-parameters,
72
+ -cert-err33-c
73
+
74
+ WarningsAsErrors: >
75
+ bugprone-*,
76
+ cert-str34-c,
77
+ cert-mem57-c,
78
+ clang-analyzer-security.*,
79
+ clang-analyzer-deadcode.*
80
+
81
+ CheckOptions:
82
+ - key: readability-identifier-naming.FunctionCase
83
+ value: lower_case
84
+ - key: readability-identifier-naming.VariableCase
85
+ value: lower_case
86
+ - key: readability-identifier-naming.MacroDefinitionCase
87
+ value: UPPER_CASE
88
+ - key: readability-identifier-naming.TypedefCase
89
+ value: lower_case
90
+ - key: readability-identifier-naming.TypedefSuffix
91
+ value: _t
92
+ ```
93
+
94
+ ### Key Check Categories
95
+
96
+ | Category | Purpose | Example Checks |
97
+ |---|---|---|
98
+ | `bugprone-*` | Common bug patterns | `sizeof-expression`, `narrowing-conversions`, `string-literal-with-embedded-nul` |
99
+ | `cert-*` | CERT C secure coding | `err34-c` (check return of `atoi`), `str34-c` (sign of `char`), `mem57-c` |
100
+ | `clang-analyzer-*` | Static analysis (deep) | `security.insecureAPI.strcpy`, `deadcode.DeadStores` |
101
+ | `performance-*` | Performance improvements | `type-promotion-in-math-fn` |
102
+ | `readability-*` | Code clarity | `identifier-naming`, `implicit-bool-conversion` |
103
+ | `misc-*` | Miscellaneous | `unused-parameters`, `redundant-expression` |
104
+
105
+ ```bash
106
+ # Run clang-tidy (requires compile_commands.json)
107
+ run-clang-tidy -p build
108
+
109
+ # Single file
110
+ clang-tidy -p build src/main.c
111
+
112
+ # With auto-fix
113
+ run-clang-tidy -p build -fix
114
+ ```
115
+
116
+ ---
117
+
118
+ ## cppcheck (Supplementary)
119
+
120
+ ```bash
121
+ # Run with compile database
122
+ cppcheck --project=build/compile_commands.json \
123
+ --std=c17 \
124
+ --enable=all \
125
+ --suppress=missingIncludeSystem \
126
+ --error-exitcode=1 \
127
+ --inline-suppr
128
+
129
+ # Without compile database
130
+ cppcheck --enable=all --std=c17 \
131
+ --suppress=missingInclude \
132
+ -I include/ \
133
+ src/
134
+ ```
135
+
136
+ ### cppcheck Key Checks
137
+
138
+ | Check | What It Finds |
139
+ |---|---|
140
+ | `nullPointer` | Null pointer dereference |
141
+ | `memleak` | Memory not freed on all paths |
142
+ | `bufferAccessOutOfBounds` | Array out-of-bounds access |
143
+ | `uninitvar` | Use of uninitialized variable |
144
+ | `resourceLeak` | File handle or socket not closed |
145
+ | `redundantAssignment` | Variable assigned then overwritten |
146
+
147
+ ---
148
+
149
+ ## Compiler Warnings
150
+
151
+ ### Recommended Flags
152
+
153
+ ```cmake
154
+ # CMakeLists.txt
155
+ target_compile_options(myapp PRIVATE
156
+ $<$<C_COMPILER_ID:GNU,Clang,AppleClang>:
157
+ -Wall
158
+ -Wextra
159
+ -Wpedantic
160
+ -Werror
161
+ -Wshadow
162
+ -Wconversion
163
+ -Wsign-conversion
164
+ -Wdouble-promotion
165
+ -Wformat=2
166
+ -Wformat-overflow=2
167
+ -Wformat-truncation=2
168
+ -Wimplicit-fallthrough
169
+ -Wnull-dereference
170
+ -Wunused
171
+ -Wstrict-prototypes
172
+ -Wold-style-definition
173
+ -Wmissing-prototypes
174
+ -Wmissing-declarations
175
+ -Wcast-align
176
+ -Wwrite-strings
177
+ -Wvla
178
+ >
179
+ $<$<C_COMPILER_ID:GNU>:
180
+ -Wlogical-op
181
+ -Wduplicated-cond
182
+ -Wduplicated-branches
183
+ -Wjump-misses-init
184
+ >
185
+ )
186
+ ```
187
+
188
+ | Flag | Purpose |
189
+ |---|---|
190
+ | `-Wall -Wextra` | Enable most warnings |
191
+ | `-Wpedantic` | Enforce strict ISO C compliance |
192
+ | `-Werror` | Treat warnings as errors (CI) |
193
+ | `-Wshadow` | Warn on variable shadowing |
194
+ | `-Wconversion` | Warn on implicit narrowing conversions |
195
+ | `-Wstrict-prototypes` | Require full prototypes (not empty parens) |
196
+ | `-Wmissing-prototypes` | Warn if global function has no prior prototype |
197
+ | `-Wvla` | Forbid variable-length arrays (stack overflow risk) |
198
+ | `-Wformat=2` | Extra format string checks |
199
+ | `-Wold-style-definition` | Forbid K&R style function definitions |
200
+
201
+ ---
202
+
203
+ ## Sanitizers
204
+
205
+ ### AddressSanitizer (ASan)
206
+
207
+ Detects: buffer overflows, use-after-free, use-after-scope, double-free, memory leaks.
208
+
209
+ ```cmake
210
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
211
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
212
+ ```
213
+
214
+ ### UndefinedBehaviorSanitizer (UBSan)
215
+
216
+ Detects: signed integer overflow, null pointer dereference, misaligned access, out-of-bounds shifts, type punning.
217
+
218
+ ```cmake
219
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
220
+ ```
221
+
222
+ ### MemorySanitizer (MSan) -- Clang Only
223
+
224
+ Detects: reads of uninitialized memory.
225
+
226
+ ```cmake
227
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory -fno-omit-frame-pointer")
228
+ ```
229
+
230
+ ### ThreadSanitizer (TSan)
231
+
232
+ Detects: data races, deadlocks.
233
+
234
+ ```cmake
235
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread")
236
+ ```
237
+
238
+ ### Sanitizer CMake Preset Pattern
239
+
240
+ ```json
241
+ {
242
+ "name": "asan",
243
+ "inherits": "debug",
244
+ "cacheVariables": {
245
+ "CMAKE_C_FLAGS": "-fsanitize=address,undefined -fno-omit-frame-pointer -fno-sanitize-recover=all"
246
+ }
247
+ }
248
+ ```
249
+
250
+ **Note**: ASan and TSan cannot be combined. Run them as separate CI jobs.
251
+
252
+ ---
253
+
254
+ ## CERT C Coding Standard References
255
+
256
+ Key CERT C rules to enforce via tooling and review:
257
+
258
+ | Rule | Description | Enforcement |
259
+ |---|---|---|
260
+ | **ERR33-C** | Detect and handle standard library errors | clang-tidy `cert-err33-c` |
261
+ | **STR31-C** | Guarantee null-terminated strings have sufficient space | Manual review, ASan |
262
+ | **MEM30-C** | Do not access freed memory | ASan, Valgrind |
263
+ | **MEM35-C** | Allocate sufficient memory for an object | ASan, cppcheck |
264
+ | **ARR38-C** | Guarantee array indices are within valid range | UBSan, ASan |
265
+ | **INT32-C** | Ensure signed integer operations do not overflow | UBSan |
266
+ | **FIO42-C** | Close files when they are no longer needed | cppcheck `resourceLeak` |
267
+ | **MSC24-C** | Do not use deprecated or obsolescent functions | clang-tidy, `-Wdeprecated` |
268
+
269
+ ---
270
+
271
+ ## Code Coverage
272
+
273
+ ### gcov / lcov
274
+
275
+ ```cmake
276
+ # Coverage build
277
+ target_compile_options(myapp_tests PRIVATE --coverage)
278
+ target_link_options(myapp_tests PRIVATE --coverage)
279
+ ```
280
+
281
+ ```bash
282
+ # Generate coverage report
283
+ cmake --build build-coverage
284
+ ctest --test-dir build-coverage
285
+ lcov --capture --directory build-coverage --output-file coverage.info
286
+ lcov --remove coverage.info '/usr/*' '*/test/*' --output-file coverage.info
287
+ genhtml coverage.info --output-directory coverage-report/
288
+
289
+ # Alternative: gcovr
290
+ gcovr --root . --html --html-details -o coverage/index.html
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Quality Commands Summary
296
+
297
+ ```bash
298
+ # Full quality check (CI pipeline)
299
+ clang-format --dry-run --Werror $(find src include -name '*.c' -o -name '*.h')
300
+ run-clang-tidy -p build
301
+ cppcheck --project=build/compile_commands.json --error-exitcode=1
302
+ cmake --build build-asan && ctest --test-dir build-asan --output-on-failure
303
+ cmake --build build-coverage && ctest --test-dir build-coverage
304
+
305
+ # Development workflow
306
+ clang-format -i src/**/*.c include/**/*.h # Quick format
307
+ cmake --build build && ctest --test-dir build # Fast feedback
308
+ clang-tidy -p build src/my_file.c # Focused analysis
309
+ ```
310
+
311
+ ---
312
+
313
+ ## Anti-Patterns
314
+
315
+ | Anti-Pattern | Problem | Correct Approach |
316
+ |---|---|---|
317
+ | No `-Werror` in CI | Warnings accumulate silently | `-Werror` in CI builds |
318
+ | Suppressing warnings globally | Hides real bugs | Suppress per-line with comments only when justified |
319
+ | No sanitizers in test | Memory bugs hide until production | ASan + UBSan on every CI test run |
320
+ | Manual code review for style | Inconsistent, wastes reviewer time | clang-format enforces automatically |
321
+ | No `compile_commands.json` | clang-tidy cannot find headers | `set(CMAKE_EXPORT_COMPILE_COMMANDS ON)` |
322
+ | Ignoring cppcheck findings | Misses bugs clang-tidy does not catch | Run both tools; they complement each other |
323
+
324
+ ---
325
+
326
+ _Focus on patterns over exhaustive rules. Code should be formatted, analyzed, and tested under sanitizers before it reaches review._
@@ -0,0 +1,347 @@
1
+ # C Coding Style
2
+
3
+ Coding style conventions for modern C projects. Opinionated patterns for readable, maintainable C17/C23 code beyond what clang-format enforces automatically.
4
+
5
+ ---
6
+
7
+ ## Philosophy
8
+
9
+ - **Explicit over implicit**: C gives you control; use it deliberately and visibly
10
+ - **Consistency above all**: snake_case everywhere, K&R braces, predictable structure
11
+ - **Const correctness**: If it does not change, mark it `const`
12
+ - **Minimal scope**: Static for internal linkage, block-scoped variables, small functions
13
+ - **Automate what you can**: Let clang-format handle layout; this doc covers judgment calls
14
+
15
+ ---
16
+
17
+ ## Naming Conventions
18
+
19
+ ### Standard C Naming
20
+
21
+ | Element | Convention | Example |
22
+ |---|---|---|
23
+ | Functions | `snake_case` | `parse_config`, `get_user_count` |
24
+ | Variables, parameters | `snake_case` | `user_count`, `max_retries` |
25
+ | Typedefs (structs, enums) | `snake_case_t` | `user_t`, `config_t`, `error_code_t` |
26
+ | Macros | `UPPER_CASE` | `MAX_BUFFER_SIZE`, `LOG_ERROR` |
27
+ | Constants (`#define`, `enum`) | `UPPER_CASE` | `MAX_RETRIES`, `STATUS_OK` |
28
+ | Enum values | `PREFIX_UPPER_CASE` | `ERR_NOT_FOUND`, `STATUS_ACTIVE` |
29
+ | Struct members | `snake_case` | `first_name`, `retry_count` |
30
+ | File-local (static) functions | `snake_case` (no prefix needed) | `validate_input` |
31
+ | Global variables (avoid) | `g_snake_case` | `g_config`, `g_logger` |
32
+ | Pointer variables | `*` attached to name | `int *ptr`, `char *name` |
33
+
34
+ ### Naming Rules
35
+
36
+ ```c
37
+ /* GOOD: Descriptive, reveals intent */
38
+ int active_user_count = get_active_users(db);
39
+ bool is_authenticated = token_validate(token);
40
+
41
+ #define MAX_RETRY_ATTEMPTS 3
42
+
43
+ typedef struct {
44
+ int id;
45
+ const char *name;
46
+ const char *email;
47
+ } user_t;
48
+
49
+ int user_find_by_email(const char *email, user_t *out_user);
50
+
51
+ /* BAD: Abbreviated, unclear, inconsistent */
52
+ int auc = getAU(db);
53
+ bool auth = tokVal(tok);
54
+ #define n 3
55
+ typedef struct { int Id; char *Name; } User;
56
+ ```
57
+
58
+ ### Boolean Naming
59
+
60
+ Prefix with `is_`, `has_`, `can_`, `should_`:
61
+
62
+ ```c
63
+ bool is_active = true;
64
+ bool has_permission = check_access(user, resource);
65
+ bool can_publish = (post->status == STATUS_DRAFT);
66
+ bool should_notify = user->preferences.notifications_enabled;
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Brace Style (K&R)
72
+
73
+ Opening brace on the same line as the statement. Functions may optionally place the brace on the next line (BSD/Allman variant), but K&R is preferred for consistency.
74
+
75
+ ```c
76
+ /* GOOD: K&R brace style */
77
+ if (count > 0) {
78
+ process_items(items, count);
79
+ } else {
80
+ log_warn("no items to process");
81
+ }
82
+
83
+ for (size_t i = 0; i < len; i++) {
84
+ buffer[i] = 0;
85
+ }
86
+
87
+ typedef struct {
88
+ int id;
89
+ char *name;
90
+ } user_t;
91
+
92
+ int parse_config(const char *path, config_t *out) {
93
+ FILE *fp = fopen(path, "r");
94
+ if (!fp) {
95
+ return -1;
96
+ }
97
+ /* ... */
98
+ fclose(fp);
99
+ return 0;
100
+ }
101
+
102
+ /* BAD: Allman/GNU style (inconsistent with project) */
103
+ if (count > 0)
104
+ {
105
+ process_items(items, count);
106
+ }
107
+ ```
108
+
109
+ ---
110
+
111
+ ## Function Design
112
+
113
+ ### Size and Parameter Limits
114
+
115
+ | Element | Guideline |
116
+ |---|---|
117
+ | Function body | Under 30 lines of logic, max 50 |
118
+ | Source file | Under 500 lines, max 800 |
119
+ | Header file | Under 200 lines, max 400 |
120
+ | Parameters | Max 5; use a struct/options for more |
121
+ | Nesting depth | Max 3 levels; extract helper functions |
122
+
123
+ ### Early Returns with Guard Clauses
124
+
125
+ ```c
126
+ /* GOOD: Guard clauses reduce nesting */
127
+ int user_create(const create_request_t *req, user_t *out) {
128
+ if (!req || !out) {
129
+ return ERR_NULL_PARAM;
130
+ }
131
+ if (strlen(req->email) == 0) {
132
+ return ERR_VALIDATION;
133
+ }
134
+ if (user_exists_by_email(req->email)) {
135
+ return ERR_ALREADY_EXISTS;
136
+ }
137
+
138
+ /* Main logic at base indentation */
139
+ out->id = next_id();
140
+ out->name = strdup(req->name);
141
+ out->email = strdup(req->email);
142
+ return 0;
143
+ }
144
+
145
+ /* BAD: Deeply nested conditional logic */
146
+ int user_create(const create_request_t *req, user_t *out) {
147
+ if (req && out) {
148
+ if (strlen(req->email) > 0) {
149
+ if (!user_exists_by_email(req->email)) {
150
+ out->id = next_id();
151
+ out->name = strdup(req->name);
152
+ out->email = strdup(req->email);
153
+ return 0;
154
+ }
155
+ return ERR_ALREADY_EXISTS;
156
+ }
157
+ return ERR_VALIDATION;
158
+ }
159
+ return ERR_NULL_PARAM;
160
+ }
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Header Guards
166
+
167
+ ### Preferred: `#pragma once`
168
+
169
+ ```c
170
+ /* GOOD: Simple, no name collisions */
171
+ #pragma once
172
+
173
+ #include <stddef.h>
174
+ #include <stdbool.h>
175
+
176
+ typedef struct {
177
+ int id;
178
+ char *name;
179
+ } user_t;
180
+
181
+ int user_create(const char *name, user_t *out);
182
+ ```
183
+
184
+ ### Alternative: Traditional Include Guards
185
+
186
+ ```c
187
+ /* ACCEPTABLE: Required for some compilers or coding standards */
188
+ #ifndef MYPROJECT_USER_H
189
+ #define MYPROJECT_USER_H
190
+
191
+ #include <stddef.h>
192
+
193
+ /* ... */
194
+
195
+ #endif /* MYPROJECT_USER_H */
196
+ ```
197
+
198
+ **Pattern**: `PROJECT_DIRECTORY_FILENAME_H` for traditional guards to avoid collisions.
199
+
200
+ ---
201
+
202
+ ## Include Order
203
+
204
+ ```c
205
+ /* 1. Corresponding header (for .c files) */
206
+ #include "myproject/user.h"
207
+
208
+ /* 2. C standard library */
209
+ #include <assert.h>
210
+ #include <stdbool.h>
211
+ #include <stddef.h>
212
+ #include <stdio.h>
213
+ #include <stdlib.h>
214
+ #include <string.h>
215
+
216
+ /* 3. POSIX / system headers */
217
+ #include <unistd.h>
218
+ #include <sys/types.h>
219
+
220
+ /* 4. Third-party libraries */
221
+ #include <cJSON.h>
222
+ #include <curl/curl.h>
223
+
224
+ /* 5. Project headers */
225
+ #include "myproject/config.h"
226
+ #include "myproject/error.h"
227
+ ```
228
+
229
+ **Rule**: Alphabetical within each group. Blank line between groups. The corresponding header is always first to verify it is self-contained.
230
+
231
+ ---
232
+
233
+ ## Const Correctness
234
+
235
+ ```c
236
+ /* GOOD: Const on pointers that should not be modified */
237
+ void print_user(const user_t *user) {
238
+ printf("Name: %s\n", user->name);
239
+ }
240
+
241
+ /* GOOD: Const on data that functions should not mutate */
242
+ int count_active(const user_t *users, size_t len) {
243
+ int count = 0;
244
+ for (size_t i = 0; i < len; i++) {
245
+ if (users[i].is_active) {
246
+ count++;
247
+ }
248
+ }
249
+ return count;
250
+ }
251
+
252
+ /* GOOD: Const for string parameters */
253
+ int parse_config(const char *path, config_t *out);
254
+
255
+ /* BAD: Missing const -- caller cannot trust function will not modify data */
256
+ int count_active(user_t *users, size_t len);
257
+ void print_user(user_t *user);
258
+ ```
259
+
260
+ ---
261
+
262
+ ## Static for Internal Linkage
263
+
264
+ ```c
265
+ /* GOOD: Static functions are file-private (internal linkage) */
266
+ static int validate_email(const char *email) {
267
+ if (!email || strlen(email) == 0) {
268
+ return -1;
269
+ }
270
+ return strchr(email, '@') ? 0 : -1;
271
+ }
272
+
273
+ /* GOOD: Static variables for file-scoped state */
274
+ static int s_initialized = 0;
275
+ static config_t s_config;
276
+
277
+ /* Public API function (declared in header) */
278
+ int config_init(const char *path) {
279
+ if (s_initialized) {
280
+ return ERR_ALREADY_INIT;
281
+ }
282
+ int rc = parse_config_file(path, &s_config);
283
+ if (rc == 0) {
284
+ s_initialized = 1;
285
+ }
286
+ return rc;
287
+ }
288
+
289
+ /* BAD: Non-static helper visible to linker -- potential name collision */
290
+ int validate_email(const char *email) { /* ... */ }
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Typedef Conventions
296
+
297
+ ```c
298
+ /* GOOD: Typedef structs with _t suffix */
299
+ typedef struct {
300
+ int id;
301
+ char *name;
302
+ char *email;
303
+ } user_t;
304
+
305
+ /* GOOD: Typedef enums */
306
+ typedef enum {
307
+ STATUS_OK = 0,
308
+ STATUS_ERROR = -1,
309
+ STATUS_TIMEOUT = -2,
310
+ } status_t;
311
+
312
+ /* GOOD: Opaque types for encapsulation */
313
+ /* In header: */
314
+ typedef struct database database_t;
315
+
316
+ /* In source: */
317
+ struct database {
318
+ void *handle;
319
+ char *connection_string;
320
+ };
321
+
322
+ /* BAD: No typedef, verbose usage everywhere */
323
+ struct user {
324
+ int id;
325
+ char *name;
326
+ };
327
+ void print(struct user *u); /* Requires 'struct' keyword each time */
328
+ ```
329
+
330
+ ---
331
+
332
+ ## Anti-Patterns
333
+
334
+ | Anti-Pattern | Problem | Correct Approach |
335
+ |---|---|---|
336
+ | camelCase or PascalCase for functions | Inconsistent with C ecosystem | `snake_case` for all functions and variables |
337
+ | Hungarian notation (`iCount`, `szName`) | Adds noise, types change | Descriptive `snake_case` names |
338
+ | Single-letter variable names | Unreadable outside tiny loops | Full descriptive names; `i`, `j`, `n` only for loop counters |
339
+ | Missing `const` on pointer parameters | Caller cannot trust immutability | Add `const` to all read-only pointer params |
340
+ | Non-static file-local functions | Pollutes global symbol table, name collisions | Mark all internal functions `static` |
341
+ | Macro constants for typed values | No type safety, no scope | Use `enum` or `static const` where possible |
342
+ | Functions over 50 lines | Hard to read, test, and maintain | Extract helper functions |
343
+ | Deep nesting (>3 levels) | Cognitive complexity | Guard clauses, early returns, extract functions |
344
+
345
+ ---
346
+
347
+ _Consistency is the highest virtue in C style. Write code that reads like well-organized prose: clear names, flat structure, explicit intent._