EPIC — Recurring Course Assignment

Interaction with Existing LP Settings

How Active/Inactive behaves alongside every existing audience-level and component-level setting on Learning Programs.

Guiding principle: Active/Inactive controls whether a component is assigned. Existing LP settings control when, how, and to whom. 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. Without this mode gate, enabling dynamic progress on all existing LPs could generate unexpected new tasks for learners who completed their LP long ago.

V1 scope: Active/Inactive applies to Course components only. Flash Drills and Channels behave as they do in default-mode LPs.

LP audience-level settings

Configured per audience in the "Sharing and task assignment" panel.

Subscribe/enroll vs. Share only No interaction
Values: "Subscribe/enroll" · "Share only, do not subscribe/enroll"
Audience modeActive componentInactive 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)

"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.

Starting date No interaction
Values: "Starting now" · "Starting on [date]"

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.

The audience start date determines when the LP becomes available; Active/Inactive determines which components within it generate tasks.

Late enrollee handling (enrollment option)
Values: "Align start/due dates to others" · "Shift start/due dates relative to enrollment"
Enrollment optionActive componentInactive component
Align to others Task generated at current timeline position Skipped — no task generated, even though alignment would normally "catch up" to past components
Shift relative 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.
Due date No interaction
Values: "Ending on [date]" · "Ending never"

The audience-level due date applies to the LP as a whole, not individual components. Active/Inactive operates at the component level. The LP due date is unaffected by component-level Active/Inactive state.

Notifications and reminders
Values: "Notify users" (with optional email, push, reminders) · "Don't notify"

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.

LP component-level settings

Configured per component row on the Manage Collections page.

Start
Values: "When assigned" · "Day 1" through "Week 51" · "After: [component]"
Start valueActiveInactive
When assigned Task generated immediately upon enrollment or activation No task generated
Day 1 – Week 51 Task generated after the specified delay No task generated. Offset preserved — if set back to Active, original offset resumes.
After: [component] 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."

End (due date) No interaction
Values: "X days after enrollment" · "X weeks after enrollment" · none

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.

ActiveInactive
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.

Subscribe/Enroll toggle (per component) Decision needed
Values: "Enroll" · "Subscribe" (per component row)

The component-level toggle determines whether a task is auto-generated (Enroll) or the learner can self-enroll (Subscribe).

ActiveInactive
Enroll Task auto-generated No task generated (Inactive overrides)
Subscribe Learner can self-enroll Self-enrollment blocked (recommended)

Decision: should learners self-enroll in an Inactive component?

Recommendation: no. 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 should also prevent self-enrollment. Existing subscriptions remain intact.

Notify Users (per component) No interaction
Values: on · off
ActiveInactive
Notify on Notification sent when task is generated No task generated, no notification
Notify off Task generated silently No task generated

Notifications are a consequence of task generation. If no task is generated (Inactive), no notification is sent.

Story Breakdown

Cloud stories
Cloud Story 1: Data model for new LP mode and Active status

New LP mode flag on the LP entity (name TBD). Active/Inactive field on LearningProgramItem. Schema changes and API support.

Cloud Story 2: System behavior for Active vs. Inactive components

Dynamic LP progress — LP "Finished" computed from Active components only, reverts to "In Progress" when an Active component is incomplete. Existing audience members — create tasks for Active components (auto-assign on activation, even if LP was previously Finished). New audience members — skip Inactive components (do not assign).

May need to be broken down further during grooming.

Cloud Story 3: "Use for next cycle" support

Deep copy Course + all content items with new entity IDs. New component added to LP as Inactive by default. Backend API for the action.

Web stories
Web Story 1: LP Properties — mode designation

Add the new mode option to the LP creation/properties screen.

Web Story 2: Component-level Active status

Active/Inactive indication on component rows in Manage Collections. Toggle affordance for changing status. Gating constraint — disable toggle with explanatory message if component is a gating item.

Web Story 3: "Use for next cycle" UX

New option in the three-dot menu on a component row. Creates a placeholder row named "Copy of [Source]" with all options except "Remove" disabled. Admin saves changes → system performs the deep copy. Full editing (rename, content review, toggle Active) available only after copy completes.

Web Story 4: LP index page — learner Active status

Differentiate Active vs. Inactive components for learners on the webapp LP index page.

Cloud/Mobile stories
Cloud/Mobile: LP index page — learner Active status

Differentiate Active vs. Inactive components for learners on the mobile app's equivalent LP view.