# Notes

## Learner profile
- Frontend engineer; sibling tracks complete: SSE, Web Workers, IndexedDB, Cache API, OPFS, Service Workers, Session Storage, BroadcastChannel, Structured Clone, Monorepos
- **Motivation:** general FE toolkit depth — design-review judgment for browser platform APIs
- **Prior knowledge:** dedicated/shared worker `postMessage` + transfer (Workers lessons 3–5); BroadcastChannel as same-origin pub/sub with **no** `targetOrigin` / transfer list; structured clone type matrix + transfer detachment (issue #13). **Handles:** lesson 2 quiz all correct (2026-08-17) — can name `contentWindow` / `parent` / `top` / `opener`. See LR-0005. Before that, had not used those APIs in work (2026-08-16). **Ready:** lesson 4 quiz all correct (2026-08-19). See LR-0007. **Close / trust:** lesson 7 completed (2026-08-19). See LR-0010. **Review:** lesson 8 passed (2026-08-19). See LR-0011. Lessons 1–8 are a floor.
- **Depth:** decisions + light hands-on
- **Why this topic:** GitHub issue [#15](https://github.com/ayv4zyan/teach/issues/15); owns window/iframe, origin stamps, MessageChannel/ports — not another worker/BC tutorial

## Teaching preferences
- Decision frameworks, tradeoffs, deal-breakers
- ADHD-friendly: one win up front, short numbered sections, bullets over long prose, tight quizzes
- Cite high-trust sources; don’t invent origin/`targetOrigin` behavior
- Build on Workers + Structured Clone + BroadcastChannel — do not re-teach clone types or BC fan-out
- Prefer modern Chromium + Firefox + Safari
- **Framework examples: React.** Workspace-wide: see `/AGENTS.md`
- **Do not clone the “when X fits → API → deal-breakers → playbook” shape just because other topics did.** This topic’s click is the *boundary* (WindowProxy, two stamps, then the port as a capability). Start there. User asked (2026-08-14) for better realization even if the track looks different.
- **Open lessons as files.** Do not start a local server. The workspace is static HTML; `open path/to/lesson.html` is enough. `file://` origin quirks belong in the lesson, not as a reason to stand up `http.server`.

## Pedagogical bet (this track)
Lesson 1 is a **live lab**, not a spectrum quiz. First draft used a mailbox metaphor. Learner read it and did not understand (2026-08-16). Rewrite is ASD-STE100 + `CONTEXT.md` words only. Do not bring the metaphor back.

## Session log
- 2026-08-14: Mission established from [ayv4zyan/teach#15](https://github.com/ayv4zyan/teach/issues/15); lesson 1 + live lab. Learner said: close the server, open the HTML directly.
- 2026-08-16: Learner passed lesson 1 to the quiz without a quiz attempt; prose did not land. Applied wait-what: CONTEXT.md + STE rewrite of lesson 1, glossary, and rules sheet.
- 2026-08-16: Learner has not used iframe/parent/opener/`window.open`. Do not start a new topic. Insert a short “other windows / how you get a handle” lesson before postMessage.
- 2026-08-17: Lesson 1 quiz — A, B, C, E correct; D wrong (silent discard vs throw). See LR-0004.
- 2026-08-17: Lesson 2 = how you get a handle (contentWindow / parent / top / opener). No new postMessage rules. Live nested-iframe + popup lab.
- 2026-08-17: Lesson 2 quiz all correct. Lesson 3 = event.source as the reply handle.
- 2026-08-18: Lesson 3 quiz — A, B, C, E correct; D wrong (`event.origin` is send-time, not “who lives there now”). Same time-split as LR-0004. See LR-0006.
- 2026-08-18: Lesson 4 = wait for ready. Do not send at once. load ≠ ready. Reload clears ready.
- 2026-08-19: Lesson 4 quiz all correct. Lesson 5 = MessageChannel: keep port1, transfer port2.
- 2026-08-19: Lesson 5 quiz — A, C, E correct; B and D wrong (transfer drops port2; port `event.origin` is empty). See LR-0008.
- 2026-08-19: Lesson 6 = who can hear. Window send vs port. Reuses B/D from lesson 5.
- 2026-08-19: Lesson 6 quiz — A, C, D, E correct; B wrong (same window → call the function). See LR-0009.
- 2026-08-19: Lesson 7 = close the port; event.data is not server truth.
- 2026-08-19: Lesson 7 completed. See LR-0010. Offer a design-review drill; rules sheet is the review.
- 2026-08-19: Lesson 8 = design-review drill (same window, who hears, *, ready, untrusted data).
- 2026-08-19: Lesson 8 passed. See LR-0011. Track complete unless a real product case does not fit.
- 2026-08-19: Closed [ayv4zyan/teach#15](https://github.com/ayv4zyan/teach/issues/15) as completed.

## Accuracy watch-outs
- Options-form `postMessage(message)` defaults `targetOrigin` to `"/"` (same-origin only), **not** `"*"`. HTML Standard + MDN (Apr 2026).
- Wrong `targetOrigin` is a **silent drop**, not a throw. `SyntaxError` only if the string is not `"/"` / `"*"` and fails URL parse (`"null"` is not a valid target).
- Opaque origins (`data:`, `sandbox` without `allow-same-origin`, often `file:`) serialize as `"null"`. To *send* to them you must use `"*"` — you cannot name them with `targetOrigin: "null"`.
- `event.origin` is the sender’s origin **at send time**. The window may have navigated since.
- Any window that has obtained your `Window` can post to it. A listener without an origin check is an XSS hole (MDN, HTML §9.3.2.1).
- MessageEvent is shared with SSE / WS / BC / workers — `origin` / `source` matter on the *window* surface; ports are how MessageChannel arrives.
- Firefox: `about:srcdoc` documents inherit the parent origin (peek works; `event.origin` is the parent tuple) but `location.origin` inside the child is `"null"`. The lab chip uses `event.origin`. Verified 2026-08-14 on Firefox.
- `MessagePort.close()` disentangles both ends; the other port fires `close`. Spec: a later `postMessage` with no entangled target returns without delivering (HTML message port post message steps). Some browsers throw. Teach “does not arrive,” not a specific exception.
