Add CLAUDE.md with mandatory docker build verification rule
ober
b4eefa8710317d39ade5913e8d39327267e88f9a
new file mode 100644 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,71 @@ +# CLAUDE.md — jerboa-secmon + +## MANDATORY: Verify Docker Build + +**ALWAYS run `make docker` after ANY change and verify the static binary works before committing.** + +This is non-negotiable. Never commit without confirming: +1. `make build` succeeds (all 33 modules compile) +2. `make docker` succeeds (static binary builds in Docker) +3. The resulting `secmon-agent` binary runs + +If the Docker build fails, fix it before doing anything else. + +## Build Commands + +```bash +make # Show help / list targets +make build # Compile all .sls → .so modules +make docker # Build fully static binary in Docker +make secmon-musl-local # Build static binary locally (needs musl) +make clean # Remove all build artifacts +``` + +## Project Overview + +Reimplementation of the Rust security monitoring agent (~/mine/secmon) in Scheme using the Jerboa framework (Gerbil-compatible Scheme on stock Chez Scheme). + +- Libraries: `.sls` files under `lib/secmon/` +- Entry points: `.ss` files under `bin/` +- Build system: `make docker` produces a fully static musl binary with zero dependencies +- Crypto: Uses `(std crypto native-rust)` — Rust `ring` library via FFI. **Never use `(std crypto digest)` — it shells out to `openssl`.** +- SQLite: Uses `(std db sqlite-native)` — Rust `rusqlite` via FFI +- Prelude: Always use `(jerboa prelude clean)`, never `(jerboa prelude)` (has a bug with `while` export) + +## Architecture + +``` +lib/secmon/ +├── crypto/ # ECIES encryption, PSK auth, key generation +├── monitor/ # 16 security monitors + events + suspicious patterns +├── platform/ # Linux /proc abstraction +├── buffer/ # Encrypted event ring buffer +├── server/ # TCP listener + wire protocol +├── storage/ # SQLite event store +├── config.sls # Configuration +└── stealth/ # Anti-debug, masquerade, integrity, env sanitize + +bin/ +├── agent.ss # Main agent (deployed to monitored hosts) +├── collector.ss # Remote event collector + decryption +├── keygen.ss # Key generation utility +└── analyze.ss # Offline analysis + detection rules +``` + +## Key Conventions + +- `(define (main . args)` — varargs for entry points (not `(define (main args)`) +- `sleep` with large ms: split into seconds + nanoseconds: `(make-time 'time-duration (* (mod ms 1000) 1000000) (quotient ms 1000))` +- Keyword args use quoted symbols: `'limit:`, `'host:` (not bare `limit:`) +- `(endianness little)` not `(endianness native)` — Chez only accepts `big`/`little` +- Record constructors: use `protocol` clause to customize, never define a separate `make-*` that conflicts + +## Static Build Pipeline + +The `make docker` target: +1. Builds glibc Chez Scheme (for compilation steps) +2. Builds musl Chez Scheme (for static libkernel.a) +3. Clones jerboa, builds libjerboa_native.a with musl target +4. Patches `load-shared-object` → `(void)` in staged jerboa copies +5. Compiles all modules, creates boot file, generates C with embedded data + FFI symbols +6. Links with musl-gcc → single static binary, zero dependencies