# Engineering Principles ## Purpose This document defines how the tutor platform should be implemented once coding begins. The product is expected to grow across web UI, API backend, workflow orchestration, learner memory, ontology processing, and generated learning assets. Without explicit constraints, those areas can easily collapse into large files and overbuilt abstractions. ## Core Rules ### 0. Backend language The backend is Go. This decision aligns the service with `agent-farm-go` so workflow orchestration can become an internal product capability rather than a loosely attached automation script. Keep the Go service modular and avoid turning the backend into one large workflow coordinator. ### 1. File size limit No source file should exceed 600 lines. When a file approaches the limit, split it by responsibility. Good split points: - route registration vs handler logic - handler logic vs service logic - service orchestration vs domain rules - domain rules vs persistence adapter - workflow contract definitions vs workflow execution - UI page shell vs reusable components Exemptions: - generated files - lockfiles - vendored files - external source snapshots - large fixture data ### 2. SOLID Apply SOLID pragmatically: - Single responsibility: learner memory, ontology, grading, progression, and asset generation should not live in one service. - Open/closed: add new interview tracks or asset types through data/config and narrow extension points where practical. - Liskov substitution: adapters should honor shared contracts without hidden behavior changes. - Interface segregation: avoid giant service interfaces. - Dependency inversion: domain logic should not depend directly on provider SDKs or database details. ### 3. KISS Prefer the simplest implementation that proves the current product loop: ```text question -> answer -> grading -> memory update -> next challenge ``` Do not introduce queues, distributed workers, plugin systems, or complex multi-agent orchestration until the MVP loop needs them. ### 4. YAGNI Do not build features only because they may be useful later. Examples to defer until proven necessary: - multi-school LMS administration - marketplace course publishing - company-specific interview packs - generalized ontology editor - multiple image providers - complex economy systems - social leaderboards ## Product Module Boundaries Initial implementation should keep these responsibilities distinct: - `auth`: users, sessions, identity providers. - `interview`: questions, rubrics, answers, grading records. - `learner_memory`: profiles, concept mastery, misconceptions, evidence. - `ontology`: concepts, prerequisites, source evidence, generated candidates. - `progression`: readiness maps, challenge ladders, boss questions, streaks. - `workflows`: typed contracts and calls into `agent-farm-go` / `third-one`. - `assets`: generated diagrams, lesson slices, prompt lineage, review state. The names can change with the chosen stack, but the responsibilities should stay separate. ## Workflow Contracts LLM workflow outputs should be typed and inspectable. Avoid relying on freeform assistant prose for product state changes. First contracts to define: - `DiagnosticResult` - `GradedAnswer` - `MemoryUpdateCandidate` - `NextChallenge` - `ReadinessUpdate` - `OntologyGap` - `TeachingAssetPrompt` ## Review Checklist Before considering an implementation slice complete: - No manually authored source file exceeds 600 lines. - New behavior maps to an OpenSpec requirement or updates OpenSpec. - The implementation keeps responsibilities separated. - The simplest useful design was chosen. - No future-only abstraction was added. - Tests or smoke checks prove the touched behavior.