Skip to content

Commit aacc34e

Browse files
committed
Tighten Instruqt assignments: tabs, admonitions, knowledge checks
This commit follows up on `ec8c183` (which introduced the Solution tabs) by working through a full audit of the eight chapter assignment files for consistency, attendee discoverability, and renderer behavior. Solution tabs. The six tabs added in the prior commit lacked `id:` fields and sat at the end of each chapter's tab list, after the Temporal UI service tab. Each now has a stable 12-character id (`cjoljjm4x5i1`, `ww0fsdf18zxw`, `azh4d9gf2did`, `lmldoarsfqyc`, `hhmx3u77tul9`, `mxlwpnohrz8r`) so subsequent pushes update the same artifact rather than racing against a fresh assigned id. The tabs also moved to index 1, immediately after Code Editor, on the theory that two code-viewing surfaces belong next to each other. Every `(tab-N)` button reference in chapters 3-7 was rewritten to absorb the index shift. Admonition syntax. The prior commit introduced two GitHub-flavored `> [!NOTE]` callouts in Chapter 2 alongside plain `>` blockquotes elsewhere. This commit completes that conversion: every blockquote in all eight chapters now opens with `[!NOTE]`, `[!TIP]`, `[!WARNING]`, or `[!IMPORTANT]`. Choices follow intent: `TIP` for the new "Stuck? See Solution" callouts, troubleshooting tips, and "where to go next"; `WARNING` for footguns (Ch 2 missing decorator, Ch 8 dev-server failure); `IMPORTANT` for Ch 7 production take-aways; `NOTE` for the rest. Solution-tab discoverability. Chapters 2-7 each gained a `[!TIP]` near the start of "What you will do" reminding attendees the **Solution** tab exists. Chapters 1 and 8 instead got a `[!NOTE]` explaining why their layout differs (Ch 1's Code Editor is the finished monolith; Ch 8's is the finished Java implementation), so the asymmetry between chapters does not look like a missing tab. Knowledge checks. Chapter 1 already ended with a knowledge-check blockquote; chapters 2-8 now have parallel three-question blocks at the end of each chapter's wrap-up, all under `> [!NOTE]`. The questions are calibrated to the chapter's central concept (sync vs async, error types, validator semantics, and so on) rather than trivia. Smaller fixes. Ch 3 Step 6 referenced the Web UI without a `[button label="Temporal UI"]` link; that link now points at the correct tab index. Ch 7 softened "~90 seconds total" and "~20 seconds" to ranges with explanations, since those numbers depend on retry timing. Every challenge frontmatter now sets `enhanced_loading: false` to match `track.yml` rather than `null`. No changes needed. The Ch 3 and Ch 5 worker startup-banner snippets were re-verified against the corresponding `compliance/worker.py` files in `workshop-nexus-intro-code` and match exactly. Chapter titles were already consistent in their casing.
1 parent ec8c183 commit aacc34e

10 files changed

Lines changed: 410 additions & 75 deletions

File tree

aha.md

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
# AhaSlides Integration Guide
2+
3+
Companion document to `course-plan.md`. Maps the AhaSlides deck (interactive layer) to the Slidev decks and Instruqt exercises (content + lab layers).
4+
5+
## Quick reference
6+
7+
| Field | Value |
8+
| :---- | :---- |
9+
| Presentation name | Introduction to Temporal Nexus, Replay Workshop |
10+
| Presentation ID | `9123470` |
11+
| Audience join code | `O8RSE` (ahaslides.com/O8RSE) |
12+
| Share code | `1777399099318-ytzrh18mal` |
13+
| Theme | Aurelia (id 30684), black background, white text |
14+
| Total slides | 38 |
15+
| Graded quiz slides | 21 |
16+
| Folder | Move into "Nexus Workshop" via UI (folder API not exposed) |
17+
18+
## Defaults applied to every quiz slide
19+
20+
- `maxPoint`: 100
21+
- `minPoint`: 0
22+
- `timeToAnswer`: 25 seconds
23+
- `fastAnswerGetMorePoint`: enabled
24+
25+
## How to use during the live workshop
26+
27+
The deck is the **interactive layer**. The presenter weaves between three surfaces:
28+
29+
1. **Slidev deck** for the lecture content (one deck per chapter).
30+
2. **AhaSlides** for warmups, knowledge checks, polls, and the final leaderboard.
31+
3. **Instruqt** for the hands-on coding exercises.
32+
33+
The AhaSlides deck advances slide by slide on the presenter's screen. Attendees join once at `ahaslides.com/O8RSE` (or scan the QR code) and stay on that browser tab for the full 3.5 hours. Their session persists across all 38 slides, so the **leaderboard at slide 19 (halftime)** and **slide 35 (final)** show cumulative scores from every graded item up to that point.
34+
35+
### Trigger pattern
36+
37+
For each chapter, the presenter:
38+
1. Opens the chapter's Slidev deck and frames the problem.
39+
2. Runs the **AhaSlides warmup** (poll, word cloud, or scale) before introducing the concept.
40+
3. Continues the Slidev lecture.
41+
4. Switches to Instruqt for the exercise.
42+
5. Returns to AhaSlides for the **chapter knowledge check** (graded quiz).
43+
6. Returns to Slidev for the chapter wrap.
44+
45+
## Slide-by-slide integration guide
46+
47+
### Welcome block (Slides 1 to 5), maps to course-plan Welcome (9:00 to 9:05)
48+
49+
| # | Type | Title / Prompt | When to trigger |
50+
| :- | :--- | :------------- | :-------------- |
51+
| 1 | Title | "Introduction to Temporal Nexus" | Open with this while attendees join. Show the QR code so people can scan to join. |
52+
| 2 | Word cloud | "One word for cross-team Temporal integration today." | First interactive moment. Sets the room. Read 3 to 5 responses out loud and riff. |
53+
| 3 | Scale (1 to 5) | "How comfortable are you with Temporal Workflows, Activities, and Updates?" | Lets the presenter calibrate pace. If average is below 3, slow down on the first chapter. |
54+
| 4 | Poll | "Have you ever wrapped a teammate's Workflow in an HTTP API?" | Run after the "why are we here" framing. The "yes, and it broke" responses are gold for the cross-team pain hook. |
55+
| 5 | Spinner wheel | "Pattern Roulette: 8 scenarios, defend your choice." | Optional crowd activity. Spin 2 or 3 times, ask volunteers to defend their pick. Pure energy moment, not graded. |
56+
57+
### Chapter 1 graded checkpoint (Slides 6 to 12), maps to course-plan Activity 1.4 (Comp 1 Performance Assessment)
58+
59+
Run this block **after** Slidev activities 1.1 (cross-team problem) and 1.2 (four building blocks). The original Instruqt-hosted quiz lives here now.
60+
61+
| # | Type | Question | LO covered |
62+
| :- | :--- | :------- | :--------- |
63+
| 6 | Pick answer | "Two teams, two namespaces, an audit boundary between them." (correct: Nexus) | 1.3, 1.4 |
64+
| 7 | Pick answer | "Same namespace, sibling workflow you control end-to-end." (correct: Child Workflow) | 1.3 |
65+
| 8 | Pick answer | "Third-party HTTP API from inside a workflow." (correct: Activity) | 1.3 |
66+
| 9 | Pick answer (multi) | "Which of these are Nexus building blocks?" (correct: Service, Operation, Endpoint, Registry) | 1.2 |
67+
| 10 | Match pairs | "Building-Block Bingo: match each primitive to its job." | 1.2 |
68+
| 11 | Short answer | "Maximum sync handler runtime, in seconds?" (10) | 1.5 |
69+
| 12 | Short answer | "Maximum async Schedule-to-Close on Cloud, in days?" (60) | 1.5 |
70+
71+
After slide 12, return to Slidev for the chapter recap. Do **not** show a leaderboard yet; the halftime board is at slide 19.
72+
73+
### Chapter 2: Service contract (Slides 13 to 14), maps to Slidev activity 2.1, 2.2
74+
75+
| # | Type | Prompt | When to trigger |
76+
| :- | :--- | :----- | :-------------- |
77+
| 13 | Word cloud | "What does 'service contract' mean to you?" | Run **before** the lecture. Anchors the new concept to prior models (gRPC, OpenAPI, Avro). |
78+
| 14 | Correct order (graded) | "Put the steps for defining a Nexus Service in the right order." | Run **after** the lecture, before the Instruqt exercise (TODO 1). |
79+
80+
### Chapter 3: Sync handler (Slides 15 to 16), maps to Slidev activity 3.1, 3.2
81+
82+
| # | Type | Prompt | When to trigger |
83+
| :- | :--- | :----- | :-------------- |
84+
| 15 | Pick answer multi (graded) | "When is a sync Nexus handler the right tool?" | Run after the "10s deadline" lecture beat. |
85+
| 16 | Pick answer (graded) | "Your sync handler routinely takes 9.8s. What's the safe move?" (Convert to async) | Sets up the natural transition to Chapter 5. |
86+
87+
### Chapter 4: Caller workflow and Event History (Slides 17 to 19), maps to Slidev activity 4.1, 4.2, then halftime leaderboard
88+
89+
| # | Type | Prompt | When to trigger |
90+
| :- | :--- | :----- | :-------------- |
91+
| 17 | Pick answer (graded) | "How many Nexus events on a sync call?" (2) | After the Slidev "two-event sync pattern" beat. |
92+
| 18 | Match pairs (graded) | "Match the Event History event to what it means." | After Instruqt exercise; reinforces the events they just witnessed. |
93+
| 19 | **Leaderboard** | Halftime standings | Last thing before the break. Celebrates top 3, builds tension for the second half. |
94+
95+
### Pre-break (Slides 20 to 21), maps to course-plan Break (10:40)
96+
97+
| # | Type | Prompt | When to trigger |
98+
| :- | :--- | :----- | :-------------- |
99+
| 20 | Word cloud | "What's clicking? One word." | Quick pulse check before the break. |
100+
| 21 | Q&A | "Drop your questions for after the break." | Leave this open during the break. Attendees submit; presenter triages and answers on return. |
101+
102+
### Chapter 5: Async operations (Slides 22 to 25), maps to Slidev activity 5.1, 5.2, 5.3, 5.4
103+
104+
| # | Type | Prompt | When to trigger |
105+
| :- | :--- | :----- | :-------------- |
106+
| 22 | Correct order (graded) | "Async Operation lifecycle: Scheduled, Started, Completed." | After Slidev 5.1 (three-event async lifecycle). |
107+
| 23 | Pick answer (graded) | "Which timeout governs total handler runtime?" (Schedule-to-Close) | After Slidev 5.3 (the three timeouts). |
108+
| 24 | Pick answer (graded) | "Why does WorkflowIDConflictPolicy.USE_EXISTING matter on retry?" | Same chapter, same beat as the timeouts. |
109+
| 25 | Scale (1 to 5) | "Could you pick the right timeout in production tomorrow?" | Self-assessment. If average is low, presenter spends extra time on the timeout decision tree. |
110+
111+
### Chapter 6: Updates through Nexus (Slides 26 to 28), maps to Slidev activity 6.1, 6.2, 6.3
112+
113+
| # | Type | Prompt | When to trigger |
114+
| :- | :--- | :----- | :-------------- |
115+
| 26 | Categorise (graded) | "Validator vs Handler: where does each action belong?" | Run after Slidev 6.1 (validator pattern). This is the topic with the highest confusion rate. |
116+
| 27 | Pick answer (graded) | "Which two events confirm an Update succeeded?" (UpdateAccepted + UpdateCompleted) | After the Instruqt exercise so attendees can match it to what they saw in Event History. |
117+
| 28 | Word cloud | "Name a human-in-the-loop scenario in your domain." | Anchors the pattern to attendees' real systems (refunds, KYC, fraud, escalations). |
118+
119+
### Chapter 7: Lifecycle control (Slides 29 to 32), maps to Slidev activity 7.1, 7.2, 7.3, 7.4
120+
121+
| # | Type | Prompt | When to trigger |
122+
| :- | :--- | :----- | :-------------- |
123+
| 29 | Match pairs (graded) | "Pick your Cancel: ABANDON, TRY_CANCEL, WAIT_REQUESTED, WAIT_COMPLETED." | After Slidev 7.1 (cancellation propagation). |
124+
| 30 | Pick answer (graded) | "OperationError vs HandlerError: which one triggers automatic retry?" (HandlerError) | After Slidev 7.2 (error types). |
125+
| 31 | Pick answer (graded) | "You see 'State: Blocked / The circuit breaker is open' in `temporal workflow describe`. What's happening?" | After Slidev 7.3 (circuit breaker). |
126+
| 32 | Pick answer (graded) | "After how many consecutive errors does the circuit breaker open?" (5) | Same beat. |
127+
128+
### Polyglot demo (Slides 33 to 34), maps to course-plan Activity 8.1
129+
130+
| # | Type | Prompt | When to trigger |
131+
| :- | :--- | :----- | :-------------- |
132+
| 33 | Poll | "Reaction to the Java handler running the same Service contract?" | Run **immediately after** the Java worker completes TXN-A. Captures the surprise in real time. |
133+
| 34 | Word cloud | "What language would YOU bridge to Temporal next?" | Sets up follow-up convos at the booth or in chat. |
134+
135+
### Wrap (Slides 35 to 38), maps to course-plan Wrap and Q&A (12:20 to 12:30)
136+
137+
| # | Type | Prompt | When to trigger |
138+
| :- | :--- | :----- | :-------------- |
139+
| 35 | **Leaderboard** | Final standings | Open the wrap with this. Top 3 win whatever swag is on offer. |
140+
| 36 | Brainstorm | "What will you try first when you get back to your team?" | Commitment device. Adult-learning research shows this dramatically improves retention. |
141+
| 37 | Scale (0 to 10) | "Likelihood to recommend Nexus to a colleague." | NPS-flavored. Useful signal for course iteration. |
142+
| 38 | Open-ended | "What still feels fuzzy?" | Final feedback. Drives next-iteration content priorities. |
143+
144+
## Manual UI tasks before going live
145+
146+
1. **Move presentation into the "Nexus Workshop" folder** in the AhaSlides UI (drag and drop in the dashboard).
147+
2. **Add hints + explanations** to each of the 21 graded quiz slides. Suggested template: hint nudges toward the right concept without giving the answer; explanation cites the exact Nexus doc page or Slidev slide for follow-up reading.
148+
3. **Tune time limits per slide if desired.** Defaults are 25s. Consider 15s for the simple short-answer numerics (slides 11, 12, 32) and 45 to 60s for the categorise (slide 26) and match-pairs (slides 10, 18, 29) which require more reading.
149+
4. **Confirm scoring is enabled** on graded slides via the side panel. Defaults look right but worth a sanity pass before the live event.
150+
5. **Optionally enable Team Play** (configured at presentation level) if you want to group attendees into teams of 3 for cooperative scoring. Currently disabled by default.
151+
6. **Print or share the QR / join code** for the welcome slide. Code: `O8RSE`.
152+
153+
## Mapping cheat sheet
154+
155+
```mermaid
156+
flowchart TD
157+
Welcome[Welcome 9:00 to 9:05] --> AhaW[AhaSlides 1 to 5]
158+
AhaW --> Slidev1[Slidev Ch 1 lecture]
159+
Slidev1 --> AhaQ1[AhaSlides 6 to 12: Comp 1 graded]
160+
AhaQ1 --> Inst1[Instruqt Ch 1 lab]
161+
162+
Inst1 --> Slidev2[Slidev Ch 2 lecture]
163+
Slidev2 --> AhaC2[AhaSlides 13 to 14]
164+
AhaC2 --> Inst2[Instruqt Ch 2 lab]
165+
166+
Inst2 --> Slidev3[Slidev Ch 3 to 4 lecture]
167+
Slidev3 --> AhaC34[AhaSlides 15 to 18]
168+
AhaC34 --> Inst34[Instruqt Ch 3 to 4 lab]
169+
Inst34 --> Half[AhaSlides 19: halftime board]
170+
171+
Half --> Break[BREAK]
172+
Break --> AhaPre[AhaSlides 20 to 21: pulse + Q&A parking lot]
173+
174+
AhaPre --> Slidev5[Slidev Ch 5 lecture]
175+
Slidev5 --> AhaC5[AhaSlides 22 to 25]
176+
AhaC5 --> Inst5[Instruqt Ch 5 lab]
177+
178+
Inst5 --> Slidev6[Slidev Ch 6 lecture]
179+
Slidev6 --> AhaC6[AhaSlides 26 to 28]
180+
AhaC6 --> Inst6[Instruqt Ch 6 lab]
181+
182+
Inst6 --> Slidev7[Slidev Ch 7 lecture]
183+
Slidev7 --> AhaC7[AhaSlides 29 to 32]
184+
AhaC7 --> Inst7[Instruqt Ch 7 lab]
185+
186+
Inst7 --> Polyglot[Polyglot demo]
187+
Polyglot --> AhaPG[AhaSlides 33 to 34]
188+
AhaPG --> AhaWrap[AhaSlides 35 to 38: leaderboard + reflection]
189+
```
190+
191+
## Known quirks discovered while building
192+
193+
1. **Slide creation interleaves across batches.** AhaSlides round-robins slides across batched `create_slides` calls in a way that scrambles intended order. Workaround: create everything in one batch, OR create then reorder with sequential `move_slide` calls anchoring slide N+1 after slide N.
194+
2. **`update_slide_properties_tool` has a schema bug.** It requires an `order` field that, when set, actually moves the slide rather than being metadata. The property fields (`minPoint`, `maxPoint`, `timeToAnswer`) are silently ignored. Use the AhaSlides UI for property edits.
195+
3. **Folder assignment is not exposed in the API.** Presentations land at root level and need to be dragged into folders via the dashboard.
196+
4. **Hints and explanations cannot be set via API.** UI only.
197+
198+
## Files referenced
199+
200+
- `course-plan.md` (this directory): the canonical course design with competencies, learning objectives, and timing.
201+
- `instruqt/`: the Lab definition, chapter scripts, and validation logic.
202+
- `edu-nexus-code/python/decouple-monolith/`: the exercise and solution code that the Slidev decks reference.

instruqt/01-run-monolith/assignment.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ tabs:
4545
port: 8233
4646
difficulty: basic
4747
timelimit: 600
48-
enhanced_loading: null
48+
enhanced_loading: false
4949
---
5050

5151
# Chapter 1: Run the Monolith
@@ -54,6 +54,12 @@ Before you decouple anything, run the application as it ships today and
5454
feel where the seams are. This chapter is observation only. There is no
5555
code to edit.
5656

57+
> [!NOTE]
58+
> This chapter has no separate **Solution** tab because there is
59+
> nothing to write. The **Code Editor** opens the finished monolith.
60+
> From Chapter 2 on, the **Code Editor** opens the exercise and a
61+
> separate **Solution** tab shows the finished file.
62+
5763
## Why this chapter exists
5864

5965
Every distributed-systems story has a "before" picture, and this is ours.
@@ -66,6 +72,7 @@ namespace, with one set of dependencies**. The compliance check is
6672
implemented as an Activity (`check_compliance`) imported into the
6773
Payments Worker.
6874

75+
> [!NOTE]
6976
> A note on framing: this monolith is the *most extreme* form of
7077
> coupling, where Compliance code is registered as an activity on the
7178
> Payments worker. In real production deployments most teams already
@@ -179,12 +186,14 @@ blocks should look something like this:
179186
Reason: Transaction amount exceeds $50,000 threshold. Requires enhanced due diligence review.
180187
```
181188

182-
> Note: TXN-B completing instead of waiting for human review is a
183-
> property of the rule-based checker we ship with: any MEDIUM-risk
184-
> transaction is auto-approved with a monitoring note. Chapter 6
185-
> introduces a real human-review path for MEDIUM transactions.
186-
>
187-
> Note: `Result: DECLINED_COMPLIANCE` is a *return value* from the
189+
> [!NOTE]
190+
> TXN-B completing instead of waiting for human review is a property
191+
> of the rule-based checker we ship with: any MEDIUM-risk transaction
192+
> is auto-approved with a monitoring note. Chapter 6 introduces a
193+
> real human-review path for MEDIUM transactions.
194+
195+
> [!NOTE]
196+
> `Result: DECLINED_COMPLIANCE` is a *return value* from the
188197
> Workflow, not a Workflow execution failure. The Temporal UI will
189198
> still show `payment-TXN-C` as `Completed`, because the Workflow
190199
> function returned cleanly. This distinction matters again in
@@ -251,6 +260,7 @@ the Nexus Endpoint that will route calls between them. The contract
251260
itself is small, and Chapter 2 is largely about what it means and where
252261
it lives. The actual decoupling happens across Chapters 3 and 4.
253262

263+
> [!NOTE]
254264
> Knowledge check (instructor-led in Live Event mode, self-check in
255265
> self-paced mode):
256266
>

instruqt/02-service-contract/assignment.md

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ tabs:
2929
type: code
3030
hostname: workshop
3131
path: /root/workshop/exercises/02_service_contract/exercise
32+
- id: mkyu8fxrz4kn
33+
title: Solution
34+
type: code
35+
hostname: workshop
36+
path: /root/workshop/exercises/02_service_contract/solution
3237
- id: ystkhevci7d2
3338
title: Terminal
3439
type: terminal
@@ -39,13 +44,9 @@ tabs:
3944
type: service
4045
hostname: workshop
4146
port: 8233
42-
- title: Solution
43-
type: code
44-
hostname: workshop
45-
path: /root/workshop/exercises/02_service_contract/solution
4647
difficulty: basic
4748
timelimit: 1200
48-
enhanced_loading: null
49+
enhanced_loading: false
4950
---
5051

5152
# Chapter 2: Define the Nexus Service Contract
@@ -102,6 +103,10 @@ reads first when they want to call your Service.
102103
CLI, attaching a Markdown description from `compliance-endpoint.md`.
103104
- Find the Endpoint in the Web UI and read its Markdown description.
104105

106+
> [!TIP]
107+
> Stuck on a TODO? The **Solution** tab shows the finished file. Try
108+
> the exercise first, then peek if you need to.
109+
105110
## Step 1: Apply TODO 1 in `shared/service.py`
106111

107112
Open `shared/service.py` in the
@@ -144,6 +149,7 @@ Both Operations belong in the contract from the start. Chapter 3 will
144149
implement `check_compliance` for real, and `submit_review` will be a
145150
stub until Chapter 6 turns it into a real Update sender.
146151

152+
> [!WARNING]
147153
> If you forget the `@nexusrpc.service` decorator, the file still
148154
> loads. The class is just an undecorated Python class with no Nexus
149155
> metadata. Nothing complains until a Worker tries to register a
@@ -162,7 +168,7 @@ environment with separate workflows, separate task queues, and separate
162168
access control. **Nexus is the only thing that crosses the boundary.**
163169

164170
Both namespaces were created for you when the track started. Verify
165-
they exist. In the [button label="Terminal" background="#444CE7"](tab-1):
171+
they exist. In the [button label="Terminal" background="#444CE7"](tab-2):
166172

167173
```bash,run
168174
temporal operator namespace list
@@ -208,7 +214,7 @@ The `get` output should include the Markdown description from
208214

209215
## Step 4: Find the Endpoint in the Web UI
210216

211-
Click the [button label="Temporal UI" background="#444CE7"](tab-2)
217+
Click the [button label="Temporal UI" background="#444CE7"](tab-3)
212218
tab. In the left navigation, click **Nexus Endpoints** (or browse to
213219
`/nexus/endpoints` directly).
214220

@@ -233,9 +239,20 @@ In Chapter 3 you will write the **handler** that fulfills the
233239
`check_compliance` Operation, and you will register it on a brand new
234240
Compliance Worker that polls the `compliance-risk` task queue.
235241

242+
> [!NOTE]
236243
> Take-away: the contract is ordinary Python. The Nexus runtime reads
237244
> the type annotations on a `@nexusrpc.service` class to figure out
238245
> what operations exist and what shape their requests and responses
239246
> take. The contract has no UI surface; it lives only in the Python
240247
> files both teams import. The Endpoint is the matching server-side
241248
> artifact, plus a description that documents what the contract does.
249+
250+
> [!NOTE]
251+
> Knowledge check (instructor-led in Live Event mode, self-check in
252+
> self-paced mode):
253+
>
254+
> - Where does the Service contract live, and which packages import it?
255+
> - Which artifact does the Web UI show: the Service class, the
256+
> Endpoint, or both?
257+
> - If you change the contract, do you need to restart the dev server
258+
> or just the Workers that import it?

0 commit comments

Comments
 (0)