Updated June 26, 2026
With recurring course assignment, admins can manage recurring training cycles within a single Learning Program (LP). Each certification cycle is a Course added to the LP, and an Active/Inactive toggle controls which cycles are current.
Today, when a customer needs to reassign training annually (e.g., compliance recertification), admins must manually recreate content and manage new assignments. There is no easy way to track completion across different cycles together.
With this feature, admins manage recurring training by adding new Courses to an existing LP and toggling previous cycles to Inactive. A "Use for next cycle" action deep-copies a Course and its content for the next certification period, giving the admin a content review touchpoint each cycle. Learners see their LP status reflect reality — it reverts to In Progress when a new cycle is due, and new hires only receive current (Active) cycles.
These capabilities deliver the annual compliance workflow and establish the foundational primitive for automated scheduling in future versions.
LP components can be Courses, Flash Drills, or Channels. V1 applies Active/Inactive state to Course components only. Flash Drills and Channels are out of scope for this release — they behave exactly as they do in default-mode LPs (always assigned; Flash Drills count toward progress, Channels do not as they are open-ended).
Recurring course assignment is one of the most frequently requested capabilities. Admins who manage compliance and certification programs are often key voices in vendor selection and renewal decisions — delivering this feature directly improves their satisfaction and strengthens the case for renewal. Beyond satisfaction, recurring assignment embeds Allego into essential internal processes like annual compliance workflows and certification renewal cycles. Once these processes run on Allego, the platform becomes stickier and harder to replace.
Recurring assignment is a frequently asked question in RFPs, and native support for it is rare among direct SE competitors. A well-designed solution gives prospects another reason to choose Allego and strengthens the platform consolidation argument by addressing a key advantage that LMS vendors have held. This becomes increasingly important as Allego targets larger enterprise customers with more stringent compliance requirements — recurring assignment is table stakes for that segment.
Organizations with compliance, regulatory, or skills-maintenance requirements need learners to repeat training on a regular cadence. Common scenarios:
V1 targets the first scenario (annual compliance / fixed calendar schedule). The capabilities introduced generalize to individual-timing scenarios in future versions.
The admin manages recurring training as a sequence of Courses within a single LP. Each Course represents one certification cycle. An Active/Inactive toggle controls which cycles are current for assignment and progress calculation.
Deep copy is required because content-item completion is global in the system. If the new cycle's Course references the same Quiz entity as the previous cycle, the system considers it already complete. "Use for next cycle" creates new content-item entities with their own IDs and empty completion records.
Today, admins manage recertification using standalone Courses — one per cycle, completely independent of each other.
| Before (standalone Courses) | After (Courses in LP with Active/Inactive) | |
|---|---|---|
| Creating next cycle | Admin creates a brand new Course with duplicated content. No connection to previous cycles. | Admin clicks "Use for next cycle" — system deep-copies Course + content, adds to the same LP |
| Managing audiences | Admin recreates audiences from scratch for each new Course | Audiences are on the LP — existing members automatically get the new Active component |
| Tracking cycles together | No system connection between cycles. Admin relies on naming conventions and tags to correlate | All cycles live in one LP. Each cycle is a Course within it — naturally grouped |
| Completion status | Admin must check each standalone Course separately to understand a learner's certification history | LP status reflects current-cycle completion. Per-Course data shows cycle-by-cycle history |
| New hire experience | Admin must ensure new hires are added to the current Course only, not outdated ones | New hires only receive Active components. Past cycles (Inactive) are automatically skipped |
Active/Inactive is not a stopgap for v1 — it's the primitive that all future automation builds on. The v2 scheduling rules are automated triggers for the same state transition the admin performs manually in v1. Even in v1, task generation executes per-assignment (per individual audience member), so the execution path for per-learner scheduling in v2 is already built and tested.
See the Workflow Illustration for visual walkthroughs of admin setup, learner timelines, and cycle transitions.
Scope TBD with PM for Analytics — see Reporting Considerations section
This section captures topics for discussion with the PM for Analytics. Solutions are not prescribed — these are awareness items and conversation starters.
Learning Programs have been "one and done" — current reporting is built around that assumption. The team should consider how the dynamic nature of LP status (reverting from Finished to In Progress each cycle) affects each dashboard widget and determine whether it's acceptable to leave as-is. A key starting question: do the dashboard widgets take the application's value for progress status, or do they compute their own? Showing the data as-is is one thing, but breaking widget logic because of changed system behavior is another.
(Note: from past experience, this review can be time-consuming for the team. AI-assisted code review could significantly accelerate it.)
Per-cycle completion status is already visible at the component level (each Course shows its own status in the Assignee Progress Details table). The question is about the Program Status column — this likely shows the current value, which will now change dynamically. We need a way to show previous instances of completion. One option: when the user hovers over the Program Status value, also show previous completion records. Determine the best approach with the PM for Analytics.
LP-level records are not sent in the ADF today, so the dynamic LP status change may not have a direct impact. Each time a new Active cycle is assigned, Task Activity will include a "received" record; when the learner completes, a "completed" record. This is incremental and consistent with existing behavior. However, new ADF data sets are being designed or implemented — the PM for Analytics should confirm whether any of those would be affected.
Assignment Stats provides good visuals on aggregate-level data across LPs and Courses. The dynamic nature of LP status (reverting from Finished to In Progress each cycle) will affect these visuals for LPs. May not require changes, but we need to understand the current behavior so we can prepare users and have a clear starting point for future enhancements.
Assignment Stats currently cannot report on individual LP components. This means we can't use the existing visuals to show, for example, "Completion over time for the 2025 cycle" (which is a Course within the LP). This is a future enhancement need. The PM for Analytics should be aware so it can be planned alongside or after the recurring course assignment feature.
Active/Inactive controls whether a component is assigned. Existing LP settings control when, how, and to whom. This section documents how Active/Inactive interacts with each existing setting.
Guiding principle: Inactive overrides assignment. If a component is Inactive, no new tasks are generated regardless of other settings. Existing tasks for Inactive components remain intact.
LP mode requirement: Active/Inactive state and dynamic LP progress are only available on LPs created in the new recurring mode. Existing "one and done" LPs are unaffected — they retain today's sticky completion behavior and do not expose the Active/Inactive toggle.
Configured per audience in the "Sharing and task assignment" panel.
| Audience mode | Active component | Inactive component |
|---|---|---|
| Subscribe/enroll | Tasks generated for audience members | No new tasks generated. Existing tasks remain. |
| Share only | No tasks generated (existing behavior) | No tasks generated (same as today) |
No interaction. "Share only" already prevents task generation; Inactive does the same for individual components within a "Subscribe/enroll" audience. These are independent controls at different levels.
The audience-level start date controls when the LP assignment begins for the audience. Active/Inactive operates after enrollment — a component's state is evaluated when tasks are generated for audience members, not when the audience is created.
No interaction. The audience start date determines when the LP becomes available; Active/Inactive determines which components within it generate tasks.
| Enrollment option | Active component | Inactive component |
|---|---|---|
| Align start/due dates to others | Task generated at current timeline position | Skipped — no task generated, even though alignment would normally "catch up" to past components |
| Shift start/due dates relative to enrollment | Task generated with shifted offsets | Skipped — no task generated. Gap stays in the shifted timeline. |
Key scenario — late enrollee + past cycles: A late enrollee joins an LP where the current cycle is Active and past cycles are Inactive. Under "Align to others," they would normally receive tasks for all components available as of today. With Active/Inactive, they skip Inactive components entirely — this is the core "newcomer skip" behavior.
Timeline gap under "Shift relative": Inactive components are excluded from task generation, but their day offsets are not removed from the timeline. Example: if an Inactive component occupied Day 7 and the next Active component is at Day 14, the enrollee's schedule has a gap at Day 7. The admin can adjust offsets manually if tighter spacing is desired.
The audience-level due date applies to the LP as a whole, not individual components. Active/Inactive operates at the component level.
No interaction. The LP due date is unaffected by component-level Active/Inactive state.
When a component is set to Active and tasks are auto-assigned to existing audience members, those members should receive notifications per the audience's notification settings.
When a component is set to Inactive, no notification is needed — no assignment action is occurring.
Configured per component row on the Manage Collections page.
| Start value | Active | Inactive |
|---|---|---|
| "When assigned" (Day 0) | Task generated immediately upon enrollment or activation | No task generated |
| "Day 1" through "Week 51" | Task generated after the specified delay | No task generated. Offset preserved — if set back to Active, original offset resumes. |
| "After: [component]" (gating) | Task generated after gating component is completed | Constraint applies — see below |
Gating constraint: If a component is used as a gating item (another component's Start is set to "After: [this component]"), it cannot be set to Inactive. The toggle is disabled with an explanatory message. This prevents broken dependency chains. In a chain A → B → C, only C (the tail) can be set to Inactive. To make B inactive, the admin must first change C's Start to something other than "After: B."
The component-level End value is a due date that shows an "overdue" label on learner tasks. It has no system enforcement — does not cancel or revoke access.
| Active | Inactive | |
|---|---|---|
| End value set | Due date applies to generated tasks | No task generated, due date not applicable. Value preserved on component. |
| No end value | No due date on tasks | No task generated |
For existing tasks on a component that becomes Inactive, the due date remains in effect — those tasks are not modified.
The component-level toggle determines whether a task is auto-generated (Enroll) or the learner can self-enroll (Subscribe).
| Active | Inactive | |
|---|---|---|
| Enroll | Task auto-generated | No task generated (Inactive overrides) |
| Subscribe | Learner can self-enroll | Self-enrollment blocked |
Inactive prevents self-enrollment. The analogous behavior on individual Courses is the "Do not assign to members of this audience after [date]" setting (not available on LPs, but the same mechanism). When that date passes, the assignment is excluded from the subscription pipeline — self-enrollment is effectively blocked. Following this precedent, Inactive also prevents self-enrollment. Existing subscriptions remain intact.
| Active | Inactive | |
|---|---|---|
| Notify on | Notification sent when task is generated | No task generated, no notification |
| Notify off | Task generated silently | No task generated |
No interaction. Notifications are a consequence of task generation. If no task is generated (Inactive), no notification is sent.
May need to be broken down further during grooming.