# EDU-001 — Provider-neutral safe question content - **Status:** done with recorded follow-up coverage - **Type:** implementation - **Phase:** 0 / core-loop prerequisite - **Blockers:** EDU-000 ## Student outcome A student cannot receive or restore an apparently valid question when its type, visibility, or options are malformed. Student-visible question content and practice snapshot JSON do not expose answer-bearing fields. ## Scope delivered - Shared question-type and option-shape contract. - Option-backed, optionless, unsupported composite, and unknown type handling. - Fail-closed single/page/collection safe projection. - Fail-closed practice creation for disabled/unavailable provider, invisible question, and unsafe options. - Strict practice snapshot restoration. - Answer-free option snapshot JSON. ## Relevant files - `docs/education/migration/11-question-content-safety-contract.md` - `yudao-module-education/CONTEXT.md` - `service/question/QuestionContentSafety.java` - `service/question/QuestionCatalogServiceImpl.java` - `service/practice/PracticeSessionServiceImpl.java` - `service/practice/SessionResponseAssembler.java` - corresponding focused tests ## Acceptance criteria - [x] Invalid option-backed content fails closed. - [x] Valid optionless content may have no options. - [x] `reading` and unknown types fail closed until modeled. - [x] Safe responses and option snapshot JSON exclude correctness and explanation fields. - [x] Malformed persisted snapshots do not become empty valid options. - [x] Disabled/unavailable providers and invisible questions cannot create sessions. - [x] Focused safety tests pass. - [x] Required compile and diff checks pass. ## Follow-up coverage - Add a clean JavaCatalogProvider public-seam/PostgreSQL contract test when the native catalog test harness is established. - Add explicit cross-tenant and `tenant_id=0` PUBLIC graph tests in the native catalog/graph-integrity slice. - Do not test private provider parsing through reflection. ## Verification recorded ```text Focused tests: 112 run, 0 failures, 0 errors git diff --check: passed yudao-server clean compile: BUILD SUCCESS PostgreSQL migration: not applicable and not executed ```