- Introduced "Pension Scheme & Benefits" detailing secondary employment benefits and pension specifics. - Created "Roles & Accountabilities" outlining the Holacracy role structure and responsibilities within Respellion. - Added "Security" section covering GDPR compliance and workplace safety protocols. - Established "Spending and Contracting" policy detailing expense categories and submission processes. - Documented "Who We Are" to define Respellion's identity, services, and operational model under Holacracy and ISO 9001.
3.5 KiB
Curriculum spec: 26-week per-user cycle
The curriculum sequences the knowledge base into a 26-week schedule. Every
employee runs their own cycle, starting when they enroll. Implemented in
src/lib/curriculumService.js; admin UI in
src/components/admin/CurriculumManager.jsx.
Data
curriculum_versions— generated schedules. Lifecycledraft → active → superseded; exactly oneactive. ThescheduleJSON is an array of 26 week objects:{ week_number (1–26), theme, topic_ids[], estimated_duration (15–45), week_rationale }.coverage_statsrecords theme/topic coverage.topics— supplytheme,complexity_weight(1–5), anddifficultyas generation input.
Topic enrichment (prerequisite)
Generation needs themed, weighted topics. enrichTopicsForCurriculum() finds
topics missing a theme (excluding type='fact' and learning_relevance='exclude')
and, in batches of 20, calls Claude with emit_topic_enrichment to assign
theme, complexity_weight, and difficulty. Triggered from the Curriculum tab.
Generation
generateCurriculumDraft(reason):
- Group learning topics by
theme(buildThemeTopicMap), sorted bycomplexity_weightascending. - Build a prompt describing themes and their topic ids. If there are more than 26 themes, the model is instructed to merge closely related themes.
callLLM(standard tier,maxTokens: 8192, temp 0) with forcedemit_curriculum_schedule. Up to 2 attempts; on validation failure the errors are fed back into the retry prompt.- Validate (
validateSchedule): exactly 26 weeks, correctweek_numbersequence, durations 15–45, everytopic_idexists, ≥1 topic per week. Unscheduled themes are warnings, not hard errors. - Supersede any existing draft and store the new
draftversion with coverage stats.
confirmVersion(versionId, adminUserId) activates a draft (and supersedes the old
active version); rejectVersion discards a draft.
Per-user scheduling (the cycle)
The cycle is detached from the calendar. Enrollment sets
team_members.curriculum_started_at (see docs/frontend-spec.md for onboarding).
AppContext derives the user's position:
getPersonalWeekNumber(startedAt) // floor(daysSinceStart / 7) + 1, ≥1 (0 if not enrolled)
getCurriculumWeek(personalWeek) // ((n - 1) % 26) + 1 → 1..26 slot
getCurriculumCycle(personalWeek) // floor((n - 1) / 26) + 1 → 1, 2, 3, ...
- Week 1 begins the day the employee enrolls.
- After week 26 the cycle restarts at week 1 with the same content.
state.weekNumber(the absolute counter) is0until the user enrolls; pages are gated behind onboarding so they never render with week 0.
Content & progress for a week
getCurrentWeekContent(personalWeek)reads the active version's schedule, maps the 26-week slot to itstopic_ids, and returns{ cycle, weekNumber, theme, topics, estimatedDuration, rationale }.getAssignedTopic(userId, week)returns the week's primary topic, falling back to a deterministic hash ofuserId:weekwhen no curriculum is active. Keep the fallback.getYearProgress(userId, personalWeek)computes completion for the current cycle.
Notes
- There is no shared "current week" and no
admin:current_weeksetting. - Regeneration produces a new version; activating it changes future weeks for all
users. Completion history (
micro_learning_completions) is append-only and never rewritten.