summaryrefslogtreecommitdiffhomepage
path: root/AGENTS.md
diff options
context:
space:
mode:
Diffstat (limited to 'AGENTS.md')
-rw-r--r--AGENTS.md83
1 files changed, 83 insertions, 0 deletions
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..9e9c600
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,83 @@
+# AGENTS.md — subagent constitution for C/Raylib project
+
+> **This is loaded by every agent.** It contains ONLY project-specific,
+> non-obvious rules. Never restate what a frontier model already knows about C
+> or raylib.
+
+---
+
+## 1. C dialect & build rules
+
+- **C99** (`-std=c99`). No C11/C17 features.
+- **Compile with `-Wall -Wextra`** — zero warnings. If you cannot silence a
+ warning without reducing correctness, flag it in your report.
+- **Raylib is the ONLY external library.** Include `raylib.h` for all platform
+ APIs (windowing, audio, input, font loading, drawing). Never include glfw,
+ miniaudio, or stb headers directly. For web: `emscripten.h` is allowed behind
+ `#ifdef PLATFORM_WEB`.
+- **`build/font_data.h`** (generated by `xxd` from `resources/`) is included
+ behind `#include "font_data.h"` guard its use with `#if FONT_EMBEDDED`.
+- **No dynamic allocation** unless paired with an explicit free in the same
+ module's cleanup. No leaks.
+- **No VLAs** (variable-length arrays on the stack). Use fixed-size buffers or
+ guard with `MAX_*` constants.
+
+## 2. Module boundaries (THE KEY RULE)
+
+- **Your `.h` file IS your contract.** It declares every public type, constant,
+ and function signature that other modules consume. Keep it minimal —
+ consumers should not see implementation details.
+- **Your `.c` file IS your implementation.** It is PRIVATE. Static functions
+ are module-internal. No other module includes your `.c` file — ever.
+- **Include guards:** Every `.h` file starts with `#pragma once`.
+- **Self-contained headers:** A `.h` file must `#include` all types it
+ references (directly or via forward declaration). Consuming agents should
+ need to include ONLY your `.h`, not hunt for transitive includes.
+- **Forward-declare when possible:** `typedef struct PlayerState PlayerState;`
+ in a header avoids pulling in the full `types.h` when only a pointer is
+ needed.
+
+## 3. State management
+
+- **No global mutable variables.** All shared state lives in `PlayerState` and
+ is passed by pointer.
+- **File-scope statics** are allowed ONLY for module-private data (e.g. cached
+ fonts, colors, layout constants in the UI module).
+- **Const correctness:** Mark pointers `const` when the function does not
+ mutate the data. Example: `const char *path` in functions that only read.
+
+## 4. Function naming
+
+- **Prefix public functions** with the module name or a clear namespace:
+ - `player_*` for player module
+ - `study_*` for study module
+ - `ui_*` for UI module
+- **Static helpers** (module-internal) may omit the prefix.
+- **Verb-first naming:** `player_load`, `player_seek`, `study_detect_silence`.
+
+## 5. Testing & verification
+
+- **Build is the primary test.** If `make` exits 0 with zero warnings, your
+ module compiles and links correctly.
+- **If you add a new `.c` file**, note it in your report — the orchestrator
+ updates the Makefile's `SRCS` list (this is orchestrator-owned build wiring,
+ NOT your responsibility).
+
+## 6. What you may read from other modules
+
+- **YES:** The `.h` header files of other modules (their contracts).
+- **NO:** The `.c` implementation files of ANY other module. If you think you
+ need to read a sibling's `.c` to understand its behavior, STOP — that means
+ the `.h` contract is underspecified. Report this to the orchestrator.
+
+## 7. Report format
+
+After completing your work, write `reports/<module>.md` with:
+1. **Files touched** (list paths)
+2. **What you implemented** (bullet list of functions/changes)
+3. **Build result** (`make` output — exit code + any warnings)
+4. **Issues or contract gaps** discovered
+5. **Any changes needed in other modules** (e.g. "study.h needs a new function
+ declaration")
+
+Keep the report concise — the orchestrator reads many of these per wave.