Artifact A — PM leadership + dev handoff
We have a gap in reassignment and recertification. Customers need to reassign training on recurring schedules — annual compliance renewals, certification expirations, regulatory recertification on fixed clocks. Today, admins handle these manually because the system doesn't support them natively.
To close this gap, the solution that makes sense is to extend our Learning Programs. Currently, LPs are missing:
With these additions, LPs can be extended to cover the reassignment/recertification use cases:
Fixed calendar schedule, all learners on the same cycle
| Name | Scenario | Date | Event | LP Status | Notes |
|---|---|---|---|---|---|
| Sam | Normal enrollee | Mar 15 2026 | Enrolls in LP | In Progress | 2026 Course is active (start passed, end not reached) |
| Jun 10 2026 | Completes 2026 | Finished | Completion record retained | ||
| Jan 1 2027 | 2027 Course becomes active | In Progress | New active Course to complete | ||
| Feb 20 2027 | Completes 2027 | Finished | Both completion records retained | ||
| Joe | Late enrollee | Feb 10 2027 | Enrolls in LP | In Progress | 2026 end date passed → Skipped. Starts with 2027. |
| Mar 5 2027 | Completes 2027 | Finished | |||
| Alex | Non-completer | Mar 15 2026 | Enrolls in LP | In Progress | 2026 Course is active |
| Dec 31 2026 | End date reached, not completed | Cancelled | Access revoked. Partial progress retained in record. | ||
| Jan 1 2027 | 2027 Course becomes active | In Progress | Fresh start on 2027 |
Learner-initiated, completion-triggered chain, no fixed clock
| Name | Scenario | Date | Event | LP Status | Notes |
|---|---|---|---|---|---|
| Lisa | Fast completer | Jan 1 2026 | Enrolls in LP | In Progress | Original Cert immediately active |
| Jan 15 2026 | Completes Original | Finished | Completion record retained. 365-day wait begins. | ||
| Jan 15 2027 | Renewal 1 unlocks | In Progress | 365 days after completion. New active Course. | ||
| Jan 25 2027 | Completes Renewal 1 | Finished | Record retained. Next 365-day wait begins. | ||
| Jan 25 2028 | Renewal 2 unlocks | In Progress | Cycle continues indefinitely | ||
| Dan | Slow completer | Jan 1 2026 | Enrolls in LP | In Progress | Original Cert immediately active |
| Jul 15 2026 | Completes Original | Finished | Takes 6 months. 365-day wait starts from here. | ||
| Jul 15 2027 | Renewal 1 unlocks | In Progress | Dan's renewal is 6 months later than Lisa's | ||
| Aug 1 2027 | Completes Renewal 1 | Finished | Chain continues from Dan's own pace | ||
| Amy | Late enrollee | Jun 15 2026 | Enrolls in LP | In Progress | Enrolls 6 months after Lisa. Original Cert active. |
| Jun 30 2026 | Completes Original | Finished | 365-day wait starts from Jun 30. | ||
| Jun 30 2027 | Renewal 1 unlocks | In Progress | Amy's entire chain is shifted to her enrollment/completion dates |
Completion-triggered renewal with a limited window to complete each Course
| Name | Scenario | Date | Event | LP Status | Notes |
|---|---|---|---|---|---|
| Lisa | Completes within windows | Jan 1 2026 | Enrolls in LP | In Progress | Original Cert active. Window: Jan 1–Jan 31. |
| Jan 15 2026 | Completes Original | Finished | Within 30d window. 365-day wait begins. | ||
| Jan 15 2027 | Renewal 1 unlocks | In Progress | Window: Jan 15–Feb 14 2027. | ||
| Jan 25 2027 | Completes Renewal 1 | Finished | Within 30d window. Chain continues. | ||
| Jan 25 2028 | Renewal 2 unlocks | In Progress | Window: Jan 25–Feb 24 2028. | ||
| Mark | Misses original window | Jan 1 2026 | Enrolls in LP | In Progress | Original Cert active. Window: Jan 1–Jan 31. |
| Jan 31 2026 | Window expires, not completed | Lapsed | Original cancelled. Access revoked. Chain never starts. | ||
| Kim | Misses renewal window | Jan 1 2026 | Enrolls in LP | In Progress | Original Cert active. Window: Jan 1–Jan 31. |
| Jan 20 2026 | Completes Original | Finished | Within window. 365-day wait begins. | ||
| Jan 20 2027 | Renewal 1 unlocks | In Progress | Window: Jan 20–Feb 19 2027. | ||
| Feb 19 2027 | Window expires, not completed | Lapsed | Renewal 1 cancelled. Chain stops. Original completion retained. | ||
| Amy | Late enrollee | Jun 15 2026 | Enrolls in LP | In Progress | Enrolls 6 months late. Window: Jun 15–Jul 15. |
| Jun 27 2026 | Completes Original | Finished | Within window. 365-day wait starts from Jun 27. | ||
| Jun 27 2027 | Renewal 1 unlocks | In Progress | Amy's entire chain shifted. Window: Jun 27–Jul 27 2027. |
Fixed clock anchored to enrollment date — doesn't wait for learner
| Name | Scenario | Date | Event | LP Status | Notes |
|---|---|---|---|---|---|
| Sara | Completes on time | Jan 1 2026 | Enrolls in LP | In Progress | Original active. Window: Jan 1 2026–Dec 31 2026. |
| Mar 1 2026 | Completes Original | Finished | Done early. LP stays Finished until next cycle. | ||
| Jan 1 2027 | Renewal 1 becomes active | In Progress | 365 days after enrollment. Window: Jan 1–Dec 31 2027. | ||
| Feb 15 2027 | Completes Renewal 1 | Finished | Done early again. Waits for next cycle. | ||
| Jan 1 2028 | Renewal 2 becomes active | In Progress | 730 days after enrollment. Cycle continues. | ||
| Tom | Non-completer | Jan 1 2026 | Enrolls in LP | In Progress | Original active. Window: Jan 1 2026–Dec 31 2026. |
| Dec 31 2026 | Original end date reached, not completed | Cancelled | Access revoked. Record retained. | ||
| Jan 1 2027 | Renewal 1 becomes active | In Progress | Clock doesn't wait. Renewal starts regardless. | ||
| Dec 31 2027 | Renewal 1 end date reached, not completed | Cancelled | Consecutive cancellations accumulate. No special treatment in v1. | ||
| Nia | Late enrollee | Jun 15 2026 | Enrolls in LP | In Progress | Original active. Window: Jun 15 2026–Jun 14 2027. |
| Aug 1 2026 | Completes Original | Finished | Done. Waits for next cycle based on her enrollment. | ||
| Jun 15 2027 | Renewal 1 becomes active | In Progress | 365 days after Nia's enrollment. Window: Jun 15 2027–Jun 14 2028. | ||
| Jul 20 2027 | Completes Renewal 1 | Finished | Nia's entire clock is shifted to her enrollment date. |
Building blocks required to support reassignment/recertification
| # | Component | Definition |
|---|---|---|
| 1 | Course end date | A Course can have an expiration date. Scoped to LP Courses in v1; could apply to Courses in general in the future. |
| 2 | Active Course state | A Course is "active" when: start date is in the past AND end date is in the future (or none). This is the window during which the learner has access. |
| # | Component | Definition |
|---|---|---|
| 3 | LP mode flag | A flag on the LP that enables Course-level scheduling. When on, each Course gets its own start/end dates and lifecycle. |
| # | Component | Status | Definition |
|---|---|---|---|
| 4 | Cancellation | New | When end date is reached and Course is incomplete: set status to "Cancelled", revoke access to the Course. Completion record retained if previously earned. |
| 5 | Skip logic | New | Automatic. If learner's enrollment date > Course end date, the Course is skipped. No admin toggle. |
| 6 | Completion-chain enforcement | Exists | Next Course waits for previous to complete before unlocking. |
| 7 | Dynamic LP progress | New | LP status = Finished when all active Courses are complete. Reverts to In Progress when new active Courses appear. Completion records retained permanently. |
| # | Component | Status | Definition |
|---|---|---|---|
| 8 | Absolute start date | New | Course becomes available on a fixed calendar date. |
| 9 | Enrollment-relative start | New | Course becomes available X days after LP enrollment. |
| 10 | Completion-triggered delay | Extend existing | Adds "N days after" delay to existing immediate completion trigger. |
| 11 | Absolute end date | New | Course expires on a fixed calendar date. |
| 12 | Relative end date | New | Course expires X days after it starts. |
| # | Component | Definition |
|---|---|---|
| 13 | Use for next cycle | Copies a Course (+ underlying content items) as a shortcut for creating the next cycle. Admin then adjusts dates. |
Which components are required for each use case
| Component | Status | UC1 | UC2 | UC2+Window | UC3 |
|---|---|---|---|---|---|
| Foundational | |||||
| 1. Course end date | New | ✓ | ✓ | ✓ | |
| 2. Active Course state | New | ✓ | ✓ | ✓ | ✓ |
| LP Mode | |||||
| 3. LP mode flag | New | ✓ | ✓ | ✓ | ✓ |
| Behaviors | |||||
| 4. Cancellation | New | ✓ | ✓ | ✓ | |
| 5. Skip logic | New | ✓ | |||
| 6. Completion-chain | Exists | ✓ | ✓ | ||
| 7. Dynamic LP progress | New | ✓ | ✓ | ✓ | ✓ |
| Scheduling | |||||
| 8. Absolute start | New | ✓ | |||
| 9. Enrollment-relative start | New | ✓ | ✓ | ✓ | |
| 10. Completion-triggered delay | Extend | ✓ | ✓ | ||
| 11. Absolute end | New | ✓ | |||
| 12. Relative end | New | ✓ | ✓ | ||
| Admin Tools | |||||
| 13. Use for next cycle | New | ✓ | ✓ | ✓ | ✓ |
Proposed stories and sequencing rationale
| Story | Components | What it delivers |
|---|---|---|
| S1 | LP mode flag, Absolute start, Absolute end | Basic scheduled Courses with fixed calendar dates |
| S2 | Course end date, Active Course state, Skip logic | Late enrollees handled correctly; system understands "active" vs "expired" |
| S3 | Cancellation | End date reached → cancel assignment, revoke access, retain completion record |
| S4 | Dynamic LP progress | LP status reacts to active Courses (Finished ↔ In Progress) |
| S5 | Use for next cycle | Admin can copy Course + content for next cycle |
S1 → S2 → S3 → S4 → S5
| Step | Rationale |
|---|---|
| S1 first | Establishes the foundation (mode flag + date fields) |
| S2 after S1 | Requires end dates from S1 to define "active" and "expired" |
| S3 after S2 | Requires active state from S2 to know when to cancel |
| S4 after S3 | Requires cancellation from S3 to correctly recalculate LP progress |
| S5 last | Independent but most useful after the others exist |
What's covered in v1 and what's explicitly out of scope
Cadence-driven reassignment — recurring training triggered by time (calendar dates, enrollment-relative dates, completion-triggered delays).
| Category | Example | Why out of scope |
|---|---|---|
| Event/incident-triggered | Safety incident → reassign training to team | Requires external trigger integration, not time-based |
| Content version change | Policy v2 published → auto-reassign everyone on v1 | Requires content-change detection + auto-assignment |
| Performance/assessment-triggered | Fails phishing test → reassign awareness training | Requires conditional branching (pass/fail logic) |
| Role/transfer-triggered | Role change → redo compliance for new role | Blurs new assignment vs. reassignment |
| Grant extension | Admin extends window for individual learner | Known v1 limitation — no mechanism exists |
| Admin recovery (re-audience) | Lapsed learner re-added via different audience | Behavior unknown — needs investigation |