Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions learn/output/Manage-The-User-And-Contact-Lifecycle/BRIEF.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Manage the User and Contact Lifecycle

- **Profile:** `unit-video` — Unit video (~4 min)
- **Target:** ~240s content (180–300s), word budget 435–726 (target 580) @ 2.42 w/s
- **Scenes:** aim ~10 (chrome 5 stamped + ~5-16 body)
- **Max static hold:** 5.0s · **Voice:** en-US-Ava:DragonHDLatestNeural
- **Source:** C:\learn-pr\learn-m365-pr\learn-m365-pr\wwl\provision-govern-identities-entra\includes\2-manage-user-contact-lifecycle.md

## Fill the placeholders

Every `__FILL__` below must be replaced before render (guarded by `tools/check_placeholders.py`).

- `opening.bumper` → [scenes/01-bumper.html](scenes/01-bumper.html)
- `opening.title` → [scenes/02-title.html](scenes/02-title.html)
- `opening.objectives` → [scenes/03-objectives.html](scenes/03-objectives.html)
- `closing.recap` → [scenes/90-recap.html](scenes/90-recap.html)
- `closing.cta` → [scenes/91-cta.html](scenes/91-cta.html)

## Next steps

1. Write the script + beat plan (script-writer) and fill the chrome placeholders above.
2. Author the teaching-body scenes into `scenes/` and insert them into `scenes.json` between the opening and closing chrome (see `scenes.json` → `body_slot`).
3. Run the gated pipeline (voice → fact-check QA → build → snapshot QA → render).
4. Guard: `py tools/check_placeholders.py --project .` must be clean before render.
18 changes: 18 additions & 0 deletions learn/output/Manage-The-User-And-Contact-Lifecycle/anchors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"_comment": "Cue name -> exact spoken phrase. word_anchors.py resolves each to real audio times against transcript.json. Phrases are unique contiguous token runs (case/punctuation-insensitive). Keys starting with _ are ignored.",
"_source": "script.md beat plan, unit 'Manage the user and contact lifecycle'",
"lifecycle_stages": "moves through a handful of stages",
"bulk_create": "Bulk create feature",
"two_surfaces": "each owns a different part of the job",
"predict_delete": "expect that account to be gone",
"soft_delete_30": "suspended state for 30 days",
"restore_props_licenses": "brings back the user's properties and the licenses",
"onprem_caveat": "the next sync cycle can recreate",
"mail_contact": "that's a mail contact, not a user",
"signin_decision": "does this person sign in",
"hybrid_tools": "Connect Sync is the classic sync server",
"opening_hook": "ReliCloud's directory never stops growing",
"objectives_stakes": "That question has a reassuring answer",
"thirty_days_recap": "you've got 30 days to bring it back",
"next_unit_cta": "Editing accounts one at a time works for a handful of people"
}
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Large diffs are not rendered by default.

210 changes: 210 additions & 0 deletions learn/output/Manage-The-User-And-Contact-Lifecycle/design-plan.md

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions learn/output/Manage-The-User-And-Contact-Lifecycle/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"title": "Manage the User and Contact Lifecycle",
"type": "unit-video",
"profile": "unit-video",
"status": "scaffolded",
"voice": "en-US-Ava:DragonHDLatestNeural",
"source": "C:\\learn-pr\\learn-m365-pr\\learn-m365-pr\\wwl\\provision-govern-identities-entra\\includes\\2-manage-user-contact-lifecycle.md",
"deliverables": {
"mp4": "Manage-The-User-And-Contact-Lifecycle.mp4",
"captions_vtt": "Manage-The-User-And-Contact-Lifecycle.vtt",
"thumbnail": "Manage-The-User-And-Contact-Lifecycle_thumbnail.png"
}
}
31 changes: 31 additions & 0 deletions learn/output/Manage-The-User-And-Contact-Lifecycle/narration.ssml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts" xml:lang="en-US">
<voice name="en-US-Vance:DragonHDLatestNeural">
<prosody rate="-3%">
<p>Relecloud's directory never stops growing. Every week brings a new hire, a contractor who only needs email, and someone whose last day means their account has to go. But here's what keeps admins up: what happens the moment you delete a user? Delete the wrong one this morning — is it already gone for good?</p>
<break time="400ms"/>
<p>That question has a reassuring answer — and it's one of several things worth getting right. In this unit, you'll move a user through its whole lifecycle, choose the admin center built for each task, recover a deletion before it's permanent, and tell a real user from a contact who never signs in.</p>
<break time="400ms"/>
<p>Start with the user itself. A cloud identity moves through a handful of stages, and you move it along: create it, edit its profile as a role changes, add and remove licenses as the job needs, block sign-in when access must stop now, and delete it when someone leaves for good.</p>
<break time="400ms"/>
<p>Creating one account at a time is fine for a single new hire. But when a batch arrives together, the Microsoft Entra admin center's <emphasis level="moderate">Bulk create</emphasis> feature takes a spreadsheet of display names, user principal names, and initial passwords, and builds every account in one pass.</p>
<break time="400ms"/>
<p>Two admin centers show you the same user, and each owns a different part of the job. You spend most of your day in the Microsoft 365 admin center — creating users, assigning licenses, blocking sign-in. You open the Microsoft Entra admin center for the identity object underneath, and to restore a deleted account.</p>
<break time="400ms"/>
<p>That last one is the surprise. Before I answer, picture it: you delete a user by mistake, and catch it five minutes later. Would you expect that account to be gone for good?</p>
<break time="400ms"/>
<p>It isn't — not right away. Deleting a user moves it into a suspended state for <emphasis level="moderate">thirty days</emphasis>, fully restorable, before Microsoft Entra ID removes it permanently. <break time="400ms"/> Only after those thirty days pass is restoring no longer possible.</p>
<break time="400ms"/>
<p>During that window, you find the account in the Microsoft Entra admin center under <emphasis level="moderate">Deleted users</emphasis>, select it, and restore it. Restoring brings back the user's properties and the licenses it held before deletion — you're not rebuilding the profile or reassigning every license.</p>
<break time="400ms"/>
<p>One caveat matters. If the account was synced from an on-premises directory instead of created in the cloud, deleting it in Microsoft Entra ID doesn't settle it. On-premises stays the master record, so the next sync cycle <emphasis level="moderate">can</emphasis> recreate the account you just deleted — and the fix belongs on-premises, not in a cloud portal.</p>
<break time="400ms"/>
<p>Not everyone in the address book signs in. A vendor's contact might only need to be emailed — that's a mail contact, not a user: a recipient with an external email address that never authenticates. You create one in the Exchange admin center, under <emphasis level="moderate">Recipients</emphasis>, then <emphasis level="moderate">Contacts</emphasis>. The deciding question is simple: does this person sign in? If yes, a user or a guest; if not, a contact.</p>
<break time="400ms"/>
<p>Finally, not every account started in the cloud — some sync from an on-premises Active Directory. Connect Sync is the classic sync server; Cloud Sync is a lighter, agent-based alternative that supports multiple disconnected forests; Connect Health watches the sync for failures; and IdFix scans on-premises directories for attribute errors before a clean first sync. You won't configure these — recognizing what each does is enough.</p>
<break time="400ms"/>
<p>So, the account you deleted by mistake this morning? You've got thirty days to bring it back — properties and licenses intact. You can move a user through its lifecycle, match each task to the right admin center, recover a deletion in time, and tell a user from a contact.</p>
<break time="400ms"/>
<p>Editing accounts one at a time works for a handful of people — but when your overseas office needs dozens before it opens, you'll want to provision at scale without over-granting your own permissions. That's the next unit. To go deeper, follow the <emphasis level="moderate">Learn more</emphasis> links in this module.</p>
</prosody>
</voice>
</speak>
25 changes: 25 additions & 0 deletions learn/output/Manage-The-User-And-Contact-Lifecycle/narration.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Relecloud's directory never stops growing. Every week brings a new hire, a contractor who only needs email, and someone whose last day means their account has to go. But here's what keeps admins up: what happens the moment you delete a user? Delete the wrong one this morning — is it already gone for good?

That question has a reassuring answer — and it's one of several things worth getting right. In this unit, you'll move a user through its whole lifecycle, choose the admin center built for each task, recover a deletion before it's permanent, and tell a real user from a contact who never signs in.

Start with the user itself. A cloud identity moves through a handful of stages, and you move it along: create it, edit its profile as a role changes, add and remove licenses as the job needs, block sign-in when access must stop now, and delete it when someone leaves for good.

Creating one account at a time is fine for a single new hire. But when a batch arrives together, the Microsoft Entra admin center's *Bulk create* feature takes a spreadsheet of display names, user principal names, and initial passwords, and builds every account in one pass.

Two admin centers show you the same user, and each owns a different part of the job. You spend most of your day in the Microsoft 365 admin center — creating users, assigning licenses, blocking sign-in. You open the Microsoft Entra admin center for the identity object underneath, and to restore a deleted account.

That last one is the surprise. Before I answer, picture it: you delete a user by mistake, and catch it five minutes later. Would you expect that account to be gone for good?

It isn't — not right away. Deleting a user moves it into a suspended state for *thirty days*, fully restorable, before Microsoft Entra ID removes it permanently. [[pause:400ms]] Only after those thirty days pass is restoring no longer possible.

During that window, you find the account in the Microsoft Entra admin center under *Deleted users*, select it, and restore it. Restoring brings back the user's properties and the licenses it held before deletion — you're not rebuilding the profile or reassigning every license.

One caveat matters. If the account was synced from an on-premises directory instead of created in the cloud, deleting it in Microsoft Entra ID doesn't settle it. On-premises stays the master record, so the next sync cycle *can* recreate the account you just deleted — and the fix belongs on-premises, not in a cloud portal.

Not everyone in the address book signs in. A vendor's contact might only need to be emailed — that's a mail contact, not a user: a recipient with an external email address that never authenticates. You create one in the Exchange admin center, under *Recipients*, then *Contacts*. The deciding question is simple: does this person sign in? If yes, a user or a guest; if not, a contact.

Finally, not every account started in the cloud — some sync from an on-premises Active Directory. Connect Sync is the classic sync server; Cloud Sync is a lighter, agent-based alternative that supports multiple disconnected forests; Connect Health watches the sync for failures; and IdFix scans on-premises directories for attribute errors before a clean first sync. You won't configure these — recognizing what each does is enough.

So, the account you deleted by mistake this morning? You've got thirty days to bring it back — properties and licenses intact. You can move a user through its lifecycle, match each task to the right admin center, recover a deletion in time, and tell a user from a contact.

Editing accounts one at a time works for a handful of people — but when your overseas office needs dozens before it opens, you'll want to provision at scale without over-granting your own permissions. That's the next unit. To go deeper, follow the *Learn more* links in this module.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[
{
"gate": 1,
"name": "Concept and source",
"status": "passed",
"artifact": null,
"note": "Source: C:\\learn-pr\\learn-m365-pr\\learn-m365-pr\\wwl\\provision-govern-identities-entra\\includes\\2-manage-user-contact-lifecycle.md",
"at": "2026-08-07T17:49:37"
},
{
"gate": 2,
"name": "Video type and profile",
"status": "passed",
"artifact": null,
"note": "Profile LOCKED: unit-video (~240s, 580 words, ~10 scenes, 5.0s static). Scaffolded by new_project.py.",
"at": "2026-08-07T17:49:37"
},
{
"gate": 6,
"name": "Fact-check QA",
"status": "passed",
"artifact": null,
"note": "SHIP 19/20; C5 headroom; design-plan B6 label fix applied",
"at": "2026-08-07T19:00:27"
}
]
101 changes: 101 additions & 0 deletions learn/output/Manage-The-User-And-Contact-Lifecycle/review/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<!doctype html>
<meta charset="utf-8">
<title>Review — Manage-The-User-And-Contact-Lifecycle</title>
<style>
body { font: 15px/1.55 "Segoe UI", system-ui, sans-serif; color: #091F2E; margin: 0;
padding: 44px 48px;
background: radial-gradient(120% 90% at 18% 8%, #FFFCFA, #FFF9F5 42%, #FFFAEF 68%, #F7F2F9 100%); }
h1 { font-size: 24px; font-weight: 600; margin: 0 0 2px; letter-spacing: -.01em; }
p.sub { color: #4a5b68; margin: 0 0 28px; }
table { border-collapse: collapse; width: 100%; max-width: 1100px;
background: rgba(255,255,255,.62); backdrop-filter: blur(20px);
border-radius: 10px; overflow: hidden; }
th { text-align: left; font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
color: #4a5b68; padding: 12px 16px; border-bottom: 1px solid #eadfd8; font-weight: 600; }
td { padding: 12px 16px; border-bottom: 1px solid #f0e7e1; vertical-align: top; }
td.g { font-variant-numeric: tabular-nums; color: #8891a0; width: 34px; }
td.note { color: #4a5b68; }
td.n { font-variant-numeric: tabular-nums; white-space: nowrap; }
.dim { color: #9aa5b1; }
.pill { display: inline-block; padding: 2px 10px; border-radius: 99px; font-size: 12px;
font-weight: 600; color: #fff; background: var(--c); }
a { color: #0078D4; }
</style>
<h1>Manage-The-User-And-Contact-Lifecycle</h1>
<p class="sub">3 of 9 gates passed &middot; newest attempt shown, full history in
<code>review/gates.json</code> &middot; <span class="dim">stage timing summary missing</span></p>
<table>
<tr><th>#</th><th>Gate</th><th>Status</th><th>Artifact</th><th>Note</th><th>When</th></tr>
<tr>
<td class="g">1</td>
<td>Concept and source</td>
<td><span class="pill" style="--c:#389A91">passed</span></td>
<td><span class=dim>—</span></td>
<td class="note">Source: C:\learn-pr\learn-m365-pr\learn-m365-pr\wwl\provision-govern-identities-entra\includes\2-manage-user-contact-lifecycle.md</td>
<td class="dim n">2026-08-07 17:49:37</td>
</tr>
<tr>
<td class="g">2</td>
<td>Video type and profile</td>
<td><span class="pill" style="--c:#389A91">passed</span></td>
<td><span class=dim>—</span></td>
<td class="note">Profile LOCKED: unit-video (~240s, 580 words, ~10 scenes, 5.0s static). Scaffolded by new_project.py.</td>
<td class="dim n">2026-08-07 17:49:37</td>
</tr>
<tr>
<td class="g">3</td>
<td>Look</td>
<td><span class="pill" style="--c:#8891a0">pending</span></td>
<td><span class=dim>—</span></td>
<td class="note"></td>
<td class="dim n"></td>
</tr>
<tr>
<td class="g">4</td>
<td>Voice</td>
<td><span class="pill" style="--c:#8891a0">pending</span></td>
<td><span class=dim>—</span></td>
<td class="note"></td>
<td class="dim n"></td>
</tr>
<tr>
<td class="g">5</td>
<td>Script</td>
<td><span class="pill" style="--c:#8891a0">pending</span></td>
<td><span class=dim>—</span></td>
<td class="note"></td>
<td class="dim n"></td>
</tr>
<tr>
<td class="g">6</td>
<td>Fact-check QA</td>
<td><span class="pill" style="--c:#389A91">passed</span></td>
<td><span class=dim>—</span></td>
<td class="note">SHIP 19/20; C5 headroom; design-plan B6 label fix applied</td>
<td class="dim n">2026-08-07 19:00:27</td>
</tr>
<tr>
<td class="g">7</td>
<td>Snapshot QA</td>
<td><span class="pill" style="--c:#8891a0">pending</span></td>
<td><span class=dim>—</span></td>
<td class="note"></td>
<td class="dim n"></td>
</tr>
<tr>
<td class="g">8</td>
<td>Render</td>
<td><span class="pill" style="--c:#8891a0">pending</span></td>
<td><span class=dim>—</span></td>
<td class="note"></td>
<td class="dim n"></td>
</tr>
<tr>
<td class="g">9</td>
<td>Delivery</td>
<td><span class="pill" style="--c:#8891a0">pending</span></td>
<td><span class=dim>—</span></td>
<td class="note"></td>
<td class="dim n"></td>
</tr>
</table>
133 changes: 133 additions & 0 deletions learn/output/Manage-The-User-And-Contact-Lifecycle/scenes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
{
"title": "Manage the User and Contact Lifecycle",
"composition_id": "root",
"width": 1920,
"height": 1080,
"root_background": "#fff8f3",
"gsap": "assets/vendor/gsap.min.js",
"narration": {
"src": "narration.wav",
"duration": 167.267,
"start": 0.0,
"track": 0
},
"fonts": [
{
"family": "Segoe UI",
"weight": 400,
"style": "normal",
"src": "fonts/segoeui-regular.woff2"
},
{
"family": "Segoe UI Semibold",
"weight": 600,
"style": "normal",
"src": "fonts/segoeui-semibold.woff2"
}
],
"endcard": {
"src": "assets/AI_End_Card.mp4",
"duration": 10.667,
"track": 11
},
"bookend": {
"intro": 0.5,
"outro": 0.7,
"color": "#000",
"outro_anchor": "next_unit_cta"
},
"scenes": [
{
"id": "01-bumper",
"src": "scenes/01-bumper.html",
"duration": 3.0,
"seam": "hard"
},
{
"id": "02-title",
"src": "scenes/02-title.html",
"duration": 24.0,
"seam": "hard"
},
{
"id": "03-objectives",
"src": "scenes/03-objectives.html",
"duration": 16.8,
"seam": "hard"
},
{
"id": "b1-lifecycle-spine",
"src": "scenes/b1-lifecycle-spine.html",
"duration": 8.0,
"seam": "hard"
},
{
"id": "b2-bulk-create",
"src": "scenes/b2-bulk-create.html",
"duration": 8.0,
"seam": "hard"
},
{
"id": "b3-right-surface",
"src": "scenes/b3-right-surface.html",
"duration": 8.0,
"seam": "hard"
},
{
"id": "b4-predict",
"src": "scenes/b4-predict.html",
"duration": 8.0,
"seam": "hard"
},
{
"id": "b5-soft-delete",
"src": "scenes/b5-soft-delete.html",
"duration": 8.0,
"seam": "hard"
},
{
"id": "b6-restore-returns",
"src": "scenes/b6-restore-returns.html",
"duration": 8.0,
"seam": "hard"
},
{
"id": "b7-onprem-caveat",
"src": "scenes/b7-onprem-caveat.html",
"duration": 8.0,
"seam": "hard"
},
{
"id": "b8-user-or-contact",
"src": "scenes/b8-user-or-contact.html",
"duration": 8.0,
"seam": "hard"
},
{
"id": "b9-hybrid-tools",
"src": "scenes/b9-hybrid-tools.html",
"duration": 8.0,
"seam": "hard"
},
{
"id": "90-recap",
"src": "scenes/90-recap.html",
"duration": 24.0,
"seam": "hard"
},
{
"id": "91-cta",
"src": "scenes/91-cta.html",
"duration": 16.8,
"seam": "hard"
}
],
"body_slot": {
"insert_after": "03-objectives",
"before": "90-recap",
"target_scene_count": 9,
"max_scene_count": 16,
"note": "Author the teaching-body scenes here (each on the kit foundation), then insert them into 'scenes' between the opening and closing chrome. The builder re-times all durations to real narration word anchors."
},
"anchors": "anchors.js"
}
Loading
Loading