# The "golden rules" of programming for BMLibrarian

1. **Never trust input from users, external data, network or file data**: Always validate and sanitize input. Never trust that it will be in the expected format or contain the expected data.
2. **No magic numbers**: Always use constants or configuration for numbers. Never hardcode numbers. Always use named constants for numbers that are used in multiple places.
3. **No hardcoded paths**: Always use constants or configuration for paths. Never hardcode paths. Always use named constants for paths that are used in multiple places.
4. **All model communication happens through the LLM abstraction layer**: Use `bmlibrarian_lite.llm` for all LLM interactions. 
5. **All modules need to be documented in markdown format** in doc/users for the end user, and doc/developers for developers. Important information for the AI assistant goes into doc/llm.
6. **All parameters must have type hints**: No exceptions.
7. **All functions, methods, and classes must have docstrings**: No exceptions.
8. **All errors must be handled, logged, and reported to the user**: No exceptions.
9. **No inline style sheets**: All stylesheets must be generated by the stylesheet generator / centralised styling system (stylesheet_generator.py).
10. **No hardcoded pixel values**: All dimensions must be calculated from font metrics or relative to other elements, generally using our dpi font scaling system (dpi_scale.py).
11. **We prefer reusable pure functions over more complex larger structures.** Where possible, such pure functions should be factored out into generally useful libraries.
12. **All tests must be written**: No exceptions.
13. **No truncation of data**: Never truncate data unless explicitly specified by the user. NEVER introduce truncation before consulting with the team and getting approval.
14. **No secrets in code or configuration files**: Use environment variables or secrets management tools like `python-dotenv` to store secrets.
15. **Configuration files must have restricted permissions (600)**: Use `os.chmod(path, 0o600)` after writing configuration files containing sensitive data. Use constants from `bmlibrarian.lite.constants` for permission values.
16. **Use thread-safe implementations for concurrent access**: The `MetricsCollector` class uses `threading.RLock()` for thread safety. When creating shared state that may be accessed from multiple threads, always protect it with appropriate locking.
17. **Use retry_with_backoff() for network operations**: Use `retry_with_backoff()` from `bmlibrarian.lite.utils` for all network operations.
