- 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.
87 lines
3.5 KiB
Markdown
87 lines
3.5 KiB
Markdown
# 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. Lifecycle `draft → active →
|
||
superseded`; exactly one `active`. The `schedule` JSON is an array of 26 week
|
||
objects: `{ week_number (1–26), theme, topic_ids[], estimated_duration (15–45),
|
||
week_rationale }`. `coverage_stats` records theme/topic coverage.
|
||
- **`topics`** — supply `theme`, `complexity_weight` (1–5), and `difficulty` as
|
||
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)`:
|
||
1. Group learning topics by `theme` (`buildThemeTopicMap`), sorted by
|
||
`complexity_weight` ascending.
|
||
2. 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.
|
||
3. `callLLM` (standard tier, `maxTokens: 8192`, temp 0) with forced
|
||
`emit_curriculum_schedule`. Up to 2 attempts; on validation failure the errors
|
||
are fed back into the retry prompt.
|
||
4. Validate (`validateSchedule`): exactly 26 weeks, correct `week_number` sequence,
|
||
durations 15–45, every `topic_id` exists, ≥1 topic per week. Unscheduled themes
|
||
are warnings, not hard errors.
|
||
5. Supersede any existing draft and store the new `draft` version 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:
|
||
|
||
```js
|
||
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) is `0` until 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 its `topic_ids`, and returns `{ cycle, weekNumber, theme, topics,
|
||
estimatedDuration, rationale }`.
|
||
- `getAssignedTopic(userId, week)` returns the week's primary topic, falling back to
|
||
a deterministic hash of `userId:week` when 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_week` setting.
|
||
- Regeneration produces a new version; activating it changes future weeks for all
|
||
users. Completion history (`micro_learning_completions`) is append-only and never
|
||
rewritten.
|