# Design Kickoff Packet — RPSV3-134 Power Control on RPS Link (New)

> ## ⛔ STALE — 历史快照，不是现行口径（2026-09-02 加注）
>
> **本文件是 2026-08-31 开建当天的认知快照。它记录的是「当时以为什么」，正文刻意一字未改**（owner
> 2026-09-02 决定：留作历史，不修）。下面至少 8 处结论已在 09-01 的四轮返工中被推翻。
>
> **现行口径的真源**（有冲突一律以它们为准，⛔ 别用本文件的取值去建任何东西）：
> - `RPS/docs/specs/2026-08-31-rpsv3-134-design-record.md` —— 交付实况 + 决策链
> - `RPS/docs/PRODUCT_INTRODUCTION.md` §3.3（文案）/ §3.6（Home 页可见视觉契约）/ §3.4（跨库图标）
>
> | 本文件写的 | 已被推翻成 |
> |---|---|
> | §4/§9 分区标题 `Power` 用 Roboto SemiBold 24，理由是「与 sibling `Ethernet Settings` (`6260:4289`) 一致」 | **该 sibling 根本不渲染**（所在 Content 卡 `visible=false`），全页**零个可见分区标题**。契约取自隐藏节点是本次最大返工的根因 —— design-record §10 / `PRODUCT_INTRODUCTION` §3.6 |
> | §9/§B 触发器用「Config T 式自画 icon-button（28×28 图标 + 12px 标签）」 | 改用 DS 库 `Button/dark M`（`icon=left, style=ghost, color=gray 1`），⛔ 不手搓 —— design-record §10.2 |
> | §B「按钮行 fill `#252525` ⚠️ adapt，建时再对 sibling 契约」 | **卡内所有子容器 fill 一律 `null`**，加底色块会读成嵌入式面板 —— `PRODUCT_INTRODUCTION` §3.6 |
> | §8 `All active transmissions will be interrupted.` | `all live transmissions will be temporarily disrupted`（重启）/ `... will be disrupted`（关机）。术语取 `live transmission`、`disrupted` —— design-record §11，Trevor Yao 定稿 |
> | §8 `The device will reconnect automatically.` | `Transmissions will be automatically restored after reboot.` **且 `reconnect` 一词被明令禁用**（歧义：分不清是传输恢复还是机器重连）—— `PRODUCT_INTRODUCTION` §3.3 |
> | §A 状态表「error（重启失败）= Deferred，未建」 | **已建**，第 ⑥ 态 `Reboot failed`（`6656:735`）—— design-record §13 / §14.2。且 owner 拍板 **Power Off 不做同等失败态** |
> | §5「in-progress 保留组件自带的 `OK` 页脚，换掉要 `detachInstance()`，属较小偏离」 | owner 拍板**就地切成绿色确认按钮** —— design-record §14.10 #3 |
> | §A/§10 五帧、单排布局 | **六帧、两行分支布局**（①分叉 → 重启支 ②④⑥ / 关机支 ③⑤），交付落在**新 page `6553:108` / Section `6554:1028`**，不是本文件 §1 写的基线页 —— design-record §8 / §14.1 |
>
> **仍然成立的两条**：§11 末行 `library-binding` could-not-run（至今如此，见 `PRODUCT_INTRODUCTION` §3.5）；
> §9 的两个 Config T 图标 key（owner 单次拍板的跨库依赖，promote 提案挂在 `design-review-queue.md` #13）。
>
> ⚠️ **`pnpm design:kickoff --check docs/internal/_design-kickoffs/rpsv3-134.md` 至今 exit 0** —— 那只证明
> **表格结构填满了**，证不了内容是对的。⛔ 别把它的绿读成「本文件仍准确」。

> Generated by `pnpm design:kickoff --name rpsv3-134`, filled 2026-08-31.
> Gate source: `docs/internal/design-process.md` M49 + M50/M51 working pattern.

## 1. Task Frame

| Field | Value |
|---|---|
| Request / Jira | [RPSV3-134](https://tvunetworks.atlassian.net/browse/RPSV3-134) "Add Reboot button to RPS (New) Setting UI" · Slack [thread](https://tvunetworks.slack.com/archives/C080LLVJ0S2/p1787952625306489) (Kalpesh Dave → Trevor Yao → Nancy Zeng) |
| Target Figma / URL | `pUE6UakxCpU6Dw9vUCtBBe` page `New RPS Link (New) 20260312` (`6259:4097`) → Section `New UX Design( 2026-03-12)` (`6260:4099`) → frame `RPS Link/Home` (`6260:4239`) |
| Scenario | **US-3** existing-product increment + **6-JIRA hard gate** (Jira-linked → full 8-step design-process) |
| Source version | `6260:4239` RPS Link/Home, 1920×900 (owner-specified baseline) |
| Reference input | Config T Local UI `5VVlCTtQ0WRcJdvwUA6bJ5` node `710:10848` "Power" section (M37 probe done, see §12) |
| Owner decision needed before start | None — all 6 resolved, see §2 |

## 2. Open Questions Gate

All answered by owner before PRD drafting (No-Open-Questions rule: nothing below leaks into deliverables as TBD).

| Question | Why it blocks design | Owner answer |
|---|---|---|
| Entry form: new top-level tab vs in-page section | Determines whether Top bar changes (M1) | **In-page Power section** (per Config T reference) |
| Which page hosts it | Determines which frame is edited | **Home page, bottom of content card** |
| Scope of Reboot/Shutdown: whole unit vs Master only vs per-PID | Determines whether a PID selector exists at all | **Whole unit (all PIDs together)** — no selector |
| Mobile frames in scope | Determines frame count (4 Mobile frames exist on the page) | **Web only (1920×900)** this round |
| State depth | Determines number of frames + UX cards | **Entry + confirm dialog + in-progress** |
| Icon source (DS library has no power glyph) | M32 library-first decision | **Import from Config T published library** |
| Does shutdown copy state "requires on-site power-on" | Determines dialog copy strength | **Yes, state it** — owner confirmed as fact: shutdown needs on-site power-on, **reboot does not** |

## 3. Baseline / Delta Contract

| Field | Items |
|---|---|
| Keep | Top bar instance (`6260:4240`, 1920×64) unchanged · System Info rows (Software / Version / PID ×4 / CPU Load / CPU Temp) unchanged in content, order and styling · `Content` card fill `#141414`, radius 4, padding 32/40 · Form Item metrics (h32, 48 pitch) · existing `Slice Line` divider pattern · page's existing annotation idiom (`Flow_text` / `Page_Title` / `Mark area` + `A --> B` vector connectors) |
| Change | `Content` card height 480 → taller (content needs ~194px, only 189px free below inner block) · add Power section inside the card below System Info, separated by a `Slice Line` · add 2 confirm-dialog state frames · add 2 in-progress state frames |
| Remove | None |
| Do not touch | `RPS Link/Ethernet Settings` (`6260:4352`) · `RPS Link/Modem Settings` (`6260:4404`) · `RPS Link/Login` + `/Entered` · all 4 Mobile frames · sub-sections `via HDMI output to Monitor` (`6260:5929`) and `UX Design of Mini Panel` (`6461:908`) · the `Release to QA` page itself is the read-only baseline — new work lands on a **new page** (M45.1) |

## 4. Semantic Pattern Contract

| semanticRole | instances | expectedPattern | exceptions |
|---|---|---|---|
| destructive device action (trigger) | Reboot button, Power Off button | Same visual vocabulary for both: icon-button form per Config T reference (28×28 icon + 12px label, vertical stack), imported icons from Config T library | None — owner rejected mixed icon/text form |
| destructive confirmation | Reboot confirm, Power Off confirm | `Notification` `theme=dark, form=pop confirm, type=danger` (`5908:7085`, 480×145) for **both**; only description copy differs | None |
| blocking progress feedback | Rebooting…, Powering off… | `Notification` `theme=dark, form=alert, type=info` (`5840:7089`, 480×153) + full-screen scrim for **both** | None |
| section heading inside content card | `Power` | Roboto SemiBold 24 `#f8f8f8` — same as `Ethernet Settings` heading (`6260:4289`) | Config T uses Helvetica Bold 22; **deviation is intentional** — local sibling contract (M21) beats reference styling |
| section divider | between System Info and Power | existing `Slice Line` library instance (key `30fc32b279c3e7d41c75026dbe5f780aec1e4bc8`) | None |

## 5. Feedback UI Inventory

| feedbackState | semanticClass | component | widthRule | paddingRule | iconRule | titleRule | bodyRule | actionPattern | exception |
|---|---|---|---|---|---|---|---|---|---|
| reboot confirm | modal notification | `Notification` pop confirm / danger `5908:7085` | 480 | component default | none | none | action + consequence + recovery, one sentence each | two-action | None |
| power-off confirm | modal notification | `Notification` pop confirm / danger `5908:7085` | 480 | component default | none | none | action + consequence + recovery, one sentence each | two-action | None |
| rebooting in progress | modal notification | `Notification` alert / info `5840:7089` + full-screen scrim | 480 | component default | blue info glyph | title layer used | recovery expectation, one sentence | one-action | Different component from the confirm rows in the same class: a progress state is not a decision, so it takes the single-action `alert` rather than `pop confirm`. `OK` is redundant for a progress state, but the footer is **not** a SLOT — replacing it needs `detachInstance()`, which breaks M32 library-first; keeping the stock footer is the lesser deviation. |
| powering off in progress | modal notification | `Notification` alert / info `5840:7089` + full-screen scrim | 480 | component default | blue info glyph | title layer used | recovery expectation, one sentence | one-action | Same exception as the row above. |

## 6. UX Principle Contract

| Principle | Evidence |
|---|---|
| Consistency | Both destructive triggers use one icon-button form; both confirms use the same `pop confirm / danger` variant; both progress states use the same `alert / info` variant. Section heading reuses the `Ethernet Settings` 24/SemiBold pattern already on the page. |
| Usability | Power lives on Home, the page users already open to read device identity (PID / CPU) — device-level info and device-level action co-located. Both actions are two-step (trigger → confirm), so neither is reachable by a single misclick. |
| Ease of use | No PID selector to reason about (owner locked scope to whole unit), so the user never has to decide "which module am I rebooting". |
| Accessibility / readability | Labels stay single words (`Reboot` / `Power Off`) at 12px per reference; consequence text lives in the dialog at component default size, not compressed into the button. Icon + text label pairing means the action is not carried by glyph alone. |

## 7. Simplicity Contract

| New module / state / note | User task it supports | Reuse / merge decision | Keep? |
|---|---|---|---|
| Power section in Home content card | Restart or shut down the unit without physical access | Reuses card, divider, heading pattern already on the page | Keep |
| Collapse chevron on the Power section | — | **Dropped.** Config T's reference has one, but Home has no collapsible section anywhere; adding one creates a single inconsistent affordance for a 2-button payload. M49 Consistency + Simplicity both point to omitting it. | **Drop** |
| Separate confirm variant per action | Distinguish reboot from shutdown risk | Merged — one variant, two copies (§4) | Merged |
| Disabled state of the two buttons | — | Not built: owner set no precondition for disabling (e.g. blocking during live transmission was not requested). Consequence is instead surfaced in dialog copy. | Defer |

## 8. Content Contract

Product UI copy is device-language **EN only** (M33). Annotation layer is bilingual (M23).

| Concept | Approved wording | Forbidden alternatives | Component text targets |
|---|---|---|---|
| the section | `Power` | ❌ Power Management, System Power, 电源设置 | section heading |
| restart action | `Reboot` | ❌ Restart, Reset, Power Cycle | trigger button label, dialog copy |
| shutdown action | `Power Off` | ❌ Shutdown, Turn Off, Halt — **sibling contract**: Config T already ships `Power Off`, and M49 requires reusing existing wording over new coinage | trigger button label, dialog copy |
| the unit being acted on | `the device` | ❌ the unit, the pack, the server, RPS Link | dialog copy |
| interruption consequence | `All active transmissions will be interrupted.` | ❌ streams will stop / you will go offline | both dialog bodies |
| reboot recovery | `The device will reconnect automatically.` | ❌ please wait / it will come back | reboot dialog + rebooting progress |
| power-off recovery | `The device can only be powered on again manually at its physical location.` | ❌ you must be on site / cannot be restarted remotely | power-off dialog + powering-off progress |

## 9. Component / Token / Icon Mapping

> Evidence = catalog grep / library search / live probe. No impression-based entries.

| Element / affordance | Source component / token / icon | Evidence |
|---|---|---|
| Top bar | library `Top bar` key `2f36c51ae9fcdfd450f3151c654c9931c9069d96` | ✅ already an instance on baseline frame, remote=true (M1 satisfied, untouched) |
| Section heading `Power` | text node, Roboto SemiBold 24 `#f8f8f8` | ✅ live probe of sibling heading `6260:4289` (`Ethernet Settings`) |
| Divider above Power section | library `Slice Line` key `30fc32b279c3e7d41c75026dbe5f780aec1e4bc8` | ✅ already used at `6260:4275` in the same card |
| Reboot icon | **Config T library** `Icon/Reboot` key `1e34b0e80bfeb85702f148e5e31c8b2664a775e8` | ✅ `search_design_system` hit; owner approved cross-library import. DS library has **no** power/reboot glyph — verified by grepping all 644 icons in `components.manifest.json` and rendering `icon/Setting/standby` (= moon+Z, sleep), `icon/others/electric 1` (= bolt), `electric 2` (= battery) |
| Power Off icon | **Config T library** `Icon/Power OFF` key `03daf29f9fd987ac16474a70c07976932d300d07` | same as above |
| Confirm dialog (both) | library `Notification` SET key `23535120dbdc93bf90af9a118b5091e58b590dc6` → variant `theme=dark, form=pop confirm, type=danger` (`5908:7085`, 480×145) | ✅ live probe of set `1408:17154`: **36 variants** (catalog said 32 — stale), type axis rename **already landed** (`danger` / `default` now real values). Rendered to confirm structure: no title layer, `Cancel` + red `Confirm`, X close |
| In-progress notice (both) | same SET → variant `theme=dark, form=alert, type=info` (`5840:7089`, 480×153) | ✅ live probe + render: blue info glyph, title layer, single green `OK` |
| Scrim behind dialogs | rect, fill `#000000` @ opacity **0.2** + `BACKGROUND_BLUR` radius **8** | M41 standard values (new design, retrofit exception does not apply — Home has no existing dialog) |
| Jira requirement annotation | file-local `Jira requirement` key `8fed268d84e7d08ebbcea20ce41bbd1e56e50a7c`; clone from instance `3877:2288` / `3877:2297` / `3877:2306` | project record `RPS/docs/specs/2026-06-15-fb-10040-design-record.md` §5; title font PingFang SC unloadable in MCP → set Inter after clone |
| Annotation layer fonts | EN `Roboto`, ZH `Noto Sans SC` | M23 §字体规范, locked at mapping time per M0 |
| Product-layer font | `Roboto` (web UI) | ✅ live probe: every text node on baseline frame is Roboto except Top bar avatar `T` (Helvetica Neue) and the clock (Digital Numbers) |
| Collapse chevron | **not used** — section is not collapsible | §7 decision; had it been needed: `icon/Arrow/Double up` key `2be13b82bf5bb8e32142e82d06bc20a14cfb79c2` |

### M35 affordance-category trace

| Affordance | Searched | Result |
|---|---|---|
| reboot / restart glyph | catalog grep (`power\|reboot\|restart\|shut\|refresh\|reload`) → `search_design_system` ×2 ("reboot icon", "restart refresh circular arrow icon") → manifest full enumeration of 644 icons → render check | DS: `icon/load/refresh` (correct shape, C+arrow) exists but owner chose Config T `Icon/Reboot` for 1:1 parity with reference |
| power-off glyph | same 4 routes + rendered `Setting/standby`, `others/electric 1`, `others/electric 2` | **DS true gap** — no ⏻ glyph anywhere in the library. → Config T library import (owner decision) + DS backlog proposal |
| destructive confirm surface | catalog `Notification` entry → live probe of set `1408:17154` | `form=pop confirm, type=danger` |
| blocking progress surface | catalog `Notification` + `Message` entries → live probe | `form=alert, type=info`; `Message` rejected (no theme axis, renders light on dark, owner ruled not to change its color) |

## Appendix A — M48 Startup Rule-Coverage Self-Check

### Locked spec (from owner answers + probes)

| Locked spec | How this task honors it |
|---|---|
| Whole-unit scope, no PID selector | Power section contains exactly 2 buttons, no target picker |
| Web only, 1920×900 | Only frames cloned from `6260:4239`; Mobile frames untouched |
| Shutdown requires on-site power-on; reboot does not | Two distinct dialog bodies; recovery sentence differs by action (§8) |
| Icons from Config T library | `importComponentByKeyAsync` for both keys; no self-drawn glyph |
| Baseline card metrics `#141414` / r4 / pad 32-40 / gap 20 / inner gap 16 / Form Item h32 pitch 48 | Power section built with the same metrics; card height grows rather than content compressing |
| Config T reference is **disabled-state** (`Button/Disable`, dash 6/6, `#666666`, label `#969696`) | Default state is built **enabled**; the reference's dashed/grey treatment is NOT copied as the default |
| **Card theme probe (M23.18 / M23.18.1 required line)** | Baseline frame fill `#1f1f1f` → luma 0.122 < 0.25 → **dark** ⇒ annotation cards use navy `#2B2D42` + cyan `#33A4FD`; page canvas set to `0.418`, not the Figma default white |

### Active M-rules hit (from mockup-conventions §AI 读取指引, ticked by trigger — not from memory)

| Rule | Landing plan |
|---|---|
| M0 | This §9 table, sent to owner for validation before building |
| M1 | Top bar stays a library instance, untouched |
| M-COLOR §C1/§C3/§C5/§C6/§C7 | File subscribes `TVU Design System` (verified via `teamLibrary.getAvailableLibraryVariableCollectionsAsync`); bind semantic tokens where available, else match probed sibling hex; annotation accent per §C4 must not reuse brand color |
| M-INTEGRITY §I1/§I2/§I3/§I4/§I6/§I7 | Card height change → re-measure container, sibling collision and overflow after every edit; probe target coordinates before create/move (Section-relative, see Q15) |
| §M-LIFECYCLE | before (I5/I6 probe) / after (conformance run) / walkthrough — all three |
| M21 | Local sibling contract beats reference styling (heading 24/SemiBold, not Helvetica 22) |
| M23 + M23.0 + M23.6 + M23.7 + M23.9 + M23.10 + M23.11 + M23.12 + M23.14 + M23.16 + M23.18 + M23.18.1 | UX delivery card (canonical 5 sections), state-preview frames placed **outside** product frame with connectors back to trigger, bilingual line-height tiers, theme auto-detected from canvas (dark → navy card), page canvas fill 0.418 |
| M23.8 + M23.8.1 | `Jira requirement` instance with real `setRangeHyperlink` to RPSV3-134 + Slack thread; PRD Source section lists every ticket, all clickable |
| M31 | Auto Layout by default for the Power section (VERTICAL heading + HORIZONTAL button row); absolute only for scrim/dialog overlay which needs viewport-centered placement |
| M32 + M32.1 + M32.4 + M32.5 + M32.6 | Library-first for every element; Config T import is an owner-approved exception recorded here; take probed values, don't invent |
| M33 | Product UI copy EN-only; bilingual only in annotation layer |
| M35 | Trace in §9 above |
| M37 | Reference probe done (§12); REFERENCE section to be placed left of the delivery section |
| M41 | scrim `#000` @0.2 + blur 8, single centered dialog, `Notification` instance, ≤720×320 ✅ (480×145) |
| M42 + M42.2 + M42.3 | Frame clones from baseline: probe paint bindings before mutate, structural audit after clone, land clones on the new page (not a side-by-side scratch copy) |
| M44 | No backend service names in labels |
| M45 + M45.1 | **New page** `< RPSV3-134 > Power Control on RPS Link 20260831`, inserted directly below `To be confirmed` separator (index 1) |
| M47 + M47.2 | Load each node's current fonts before edit; never `insertCharacters`; re-verify segments after text edits |
| M-FONT | Product text on the Roboto/text-style grid; annotation sizes per M23.14 |
| M-TXT-ICON-AUDIT | No Unicode glyph as icon in product area; `→ ▼ ▲ ①②③` in annotation must bind `Noto Sans SC` |
| M52 + M52.1 + M52.3 | Bind tokens not raw hex where the library provides them; feedback controls share one source (§5) |
| M53 | Dialog / progress copy: both actions are **user-initiated** — one wording family, no split into system-initiated phrasing |
| M49 | This packet |

### State completeness (first-class entity = the Power action)

| State | Covered |
|---|---|
| default / idle (both buttons available) | ✅ frame 1 |
| action-before → confirm (reboot) | ✅ frame 2 |
| action-before → confirm (power off) | ✅ frame 3 |
| action-during (rebooting) | ✅ frame 4 |
| action-during (powering off) | ✅ frame 5 |
| action-after | ⛔ N/A for reboot (device reconnects, page returns to default frame 1); for power off the web UI is unreachable — no renderable device state |
| cancel path | ✅ covered by `Cancel` in both confirms, returns to frame 1 |
| disabled / blocked | Deferred — owner set no precondition (§7); consequence surfaced in copy instead |
| error (reboot command fails) | Deferred — not requested; would reuse `Notification form=alert type=error` if added |

## 10. Ready Check

- [x] Open questions are answered or explicitly None.
- [x] Keep / Change / Remove / Do not touch are filled.
- [x] Every semanticRole has one expectedPattern.
- [x] Feedback UI inventory is filled or explicitly None.
- [x] New modules pass the Simplicity Contract.
- [x] Content terms are unique and reused.
- [x] Component / token / icon mapping has evidence.
- [x] If this is a later revision, Regression Snapshot is updated. — first revision, snapshot section initialized empty in §11.

## Appendix B — M37 Reference Probe (Config T `710:10848`)

| Item | Measured value |
|---|---|
| Container | `Content` 952×153, VERTICAL auto-layout, gap 16 |
| Heading | `Power`, Helvetica **Bold 22**, `#f1f1f1`; 24×24 `Icon/Arrow/right` at right edge (collapse affordance) |
| Button row | `Content` 950×110, HORIZONTAL, gap **40**, padding `24/0/24/20`, fill **`#252525`** |
| Buttons | 62 high (63w Reboot / 78w Power Off), VERTICAL gap 4, padding `8/12/8/12`, **stroke `#666666` w1 dash `[6,6]`**, layer name `Button/Disable` |
| Button icon | 28×28, vector fill `#ffffff` |
| Button label | Helvetica Regular **12**, `#969696` |
| Icon origin | `Icon/Reboot` / `Icon/Power OFF` — Config T library components |

### Reference adaptation decisions (M14)

| Reference trait | Adopted? | Rationale |
|---|---|---|
| Section layout: heading + button row | ✅ adopt | This is the shape the owner asked for |
| Icon-button form, 28×28 icon + 12px label | ✅ adopt | Owner decision |
| Icons themselves | ✅ adopt via library import | Owner decision |
| Dashed border + grey label | ❌ reject | That is the **disabled** state; default must read as enabled |
| Button row fill `#252525` | ⚠️ adapt | Home card is `#141414`; a raised `#252525` band is consistent with dark-layer hierarchy — verify against sibling contract at build time |
| Heading Helvetica Bold 22 | ❌ reject | Local page uses Roboto SemiBold 24 (M21) |
| Collapse chevron | ❌ reject | §7 Simplicity / Consistency |

## 11. Regression Snapshot

| Finding / change | Contract section updated | Regression result |
|---|---|---|
| None | N/A | N/A |
| Annotation text reported `fonts=Inter` on 89 nodes — `createText()` records an Inter **base style**, which range-level font setting does not replace | §9 mapping (annotation fonts) | Fixed by setting node-level `fontName` then re-applying the ZH range; `typography-icon` went 91 → 2, and the 2 remaining are outside this round's nodes |
| 117 newline characters carried the Inter base font | §9 mapping (annotation fonts) | Fixed in the same pass; `getStyledTextSegments` sweep returns 0 non-compliant families |
| `Power actions` padding 20 and state-label padding 20 were off the spacing scale | §4 Semantic Pattern (band metrics) | Pulled to 24 / 16 respectively across all five frames |
| Four scrims carried a raw `BACKGROUND_BLUR:8` instead of a bound effect style | §5 Feedback UI Inventory (scrim) | Bound to library effect style `Mask blur8` (`38f743fa…`); radius still 8, fill still 20% black per M41 |
| Dialogs stopped being vertically centered after copy wrapped (145 → 166 / 187 / 174) | §5 Feedback UI Inventory (widthRule/padding) | Re-centered against measured heights (y = 367 / 357 / 374 / 363) — an I7-class dependency |
| `Power` heading rendered centered | §4 Semantic Pattern (section heading) | Content card has `counterAxisAlignItems=CENTER`; heading switched to `FILL` + left-aligned text |
| Circled numbers `①-⑤` sat in a Roboto range (missing-glyph list) | §9 mapping (glyph discipline) | Rebound to Noto Sans SC — note the node-level font reset undoes this, so it must be re-applied after |
| `library-binding` rule could not run (offline cache absent) | §10 Ready Check | **Not passed, not waived** — recorded as un-run in the design record §7 |
