- Every function, class, and module should have one clear reason to change.
- Avoid "god functions" that handle multiple concerns.
- If you describe a function with "and", it likely violates SRP.
- Prefer composition over large multi-purpose units.
- Prefer readable code over "clever" abstractions.
- Avoid premature optimization.
- If a junior engineer can’t understand it in 30 seconds → simplify.
- Make dependencies visible.
- Avoid hidden state changes.
- Avoid "magic behavior" (implicit globals, side effects).
- Isolate I/O, network, and filesystem operations where possible.
Split logic into clear layers:
- UI / interface layer
- Business logic layer
- Data / persistence layer
- Utility/helpers (pure functions) Agent rule: Never mix data access with business logic unless explicitly justified.
- Prefer modular files over large monoliths.
- Keep file sizes reasonable (soft rule: <300–500 lines).
- Group by feature, not by type (often better for scaling systems).
- Prefer modular monolith over microservices unless scale demands it.
- Prioritize SASS: Use SASS (
.scss) for styling instead of standard CSS or inline styles. - Use
_projects: Leverage the modular project auto-registration system in the_projects/directory for new projects. - System Expansion: Work within the existing systems and expand them if needed, rather than creating completely new parallel architectures.
- Calendar pages: Keep layout and modal styling out of
navigation/calendar.md; use semantic classes and SCSS instead of utility-heavy inline markup. - Cross-origin APIs: Spring endpoints consumed from
pages.opencodingsociety.comshould explicitly allow credentialed cross-origin requests. - Documentation: Create detailed documentation for difficult or complex implementations as necessary.
- Commenting: Add comments for non-trivial logic, but keep them minimal and focused on why rather than what.
- Ask Questions: If system-level constraints, requirements, or patterns are unclear, pause and ask the user questions before proceeding.
- Treat Makefile as the single source of truth; common targets are
make/make serve-current,make dev,make stop,make convert, andmake convert-single(details in README.md). - Order matters: stop → build projects → convert notebooks/docx → split courses → jekyll serve (follow Makefile).
- Sources live in notebook sources and docx sources; converted Markdown is written to generated posts (generated, do not hand-edit).
- Course-split outputs (
*_csp.md/*_csa.md/*_csse.md/*_content.md) are generated; never edit them. See scripts/split_multi_course_files.py. - Conversion behavior is defined in scripts/convert_notebooks.py and scripts/convert_docx.py.
- New projects must follow _projects/REGISTRATION.md; architecture reference in _projects/ARCHITECTURE.md.
- Use SCSS-first styling; theme and styling conventions are in README.md.
- The backend service lives under node_backend/README.md and is separate from the site build pipeline; read it before making backend changes.
Names should:
- Explain intent, not implementation.
- Avoid abbreviations unless standard.
- Be consistent across the codebase.
- Example: Use
normalizeUserTransactionData()instead ofprocData2().
- Fail Fast: Validate inputs early, raise errors immediately with clear messages, and don't silently ignore failures.
- Defensive Programming: Assume inputs are invalid or malicious, add guards for edge cases, and never trust external data sources.
- Discipline: Never swallow exceptions silently. Always include context in errors and use typed/custom errors where appropriate.
- Log meaningful events, not noise.
- Logs should answer: what happened and why?
- Avoid logging sensitive data.
- Tests should describe behavior, not implementation.
- Every critical logic path should be testable.
- Prefer unit tests for logic, integration tests for flows.
- Agent rule: If code changes behavior, update or add tests.
- Ensure deterministic behavior (avoid randomness unless explicitly required, fix seeds when needed).
- For non-trivial tasks: write a short plan before coding.
- Break into steps before implementation.
- Prefer minimal diffs over refactors unless required.
- Don’t rewrite working code without reason.
- Match existing codebase style and structure.
- Don’t introduce new architecture unless necessary.
- Verify Assumptions: If unclear, infer cautiously and flag assumptions. Never silently guess critical requirements.
- Update this file: As you iterate, make mistakes, and learn new system patterns or constraints, actively update
AGENTS.md(and its optimized counterpart) with important notes so the system improves over time.
- Avoid functions that do too many things. Stick to SRP.
Hidden Side Effects
- Ensure predictability by keeping side effects explicit and well-documented.
- YAGNI (You Aren’t Gonna Need It): Don’t build features unless required now. Avoid speculative generalization.
- Optimize only after correctness is guaranteed (Profile before optimizing).