- writer.ts: export pure planBundle() + WritePlan types; applyBundle now consumes
it (shared computeFileAction/planRules) so classification and application can't drift
- api-content.ts: optional contentHash on LessonSummary (always-fetch fallback when absent)
- generated/api-types.ts: regenerated from local API — catalog lesson type carries contentHash
- tests/writer-plan.test.ts: planBundle/applyBundle parity (created/unchanged/clean/conflict)