# 预注册 —— **tsc 轴**：双写 JSX 增广在 DS 真发出的 d.ts 上跨 TypeScript 版本（`lab:B-tsc`）

🔴 **本文件先于任何取数代码写成并提交。取数开始后 ⛔ 一字不改**；
若发现控制缺口，**只能在取数之前补，并在 §3.2 留痕**（`AGENTS §3.9` 第六形态，L3 的 MH5 就是这么补的）。

owner 2026-09-03 在四条候选中选定 **B（tsc 版本维度）**。
上一格结算见 [`2026-09-02-open-items.md §16`](2026-09-02-open-items.md)，边界⑦ 逐字登记了本格要回答的那一问。

---

## 0. 起手重取（`AGENTS §2.13`）

| 项 | 交接给的 | 实取 | |
|---|---|---|---|
| lab `HEAD` / `origin/master` | `b248ded` | `b248dedf75cb503cf8f252c8163c7cd2ce7b909c`（两者相同）| 🟢 对上，dirty=0 |
| DS `HEAD` | `d1ba0505`（交接自标「别信」）| **`0cdee554`** | 🔴 **DRIFTED —— 连续第八轮** |

区间已核（`git diff --name-only d1ba0505 0cdee554`，用全路径，`AGENTS §22` 推论二）：
`docs/STATUS.md` · `docs/internal/STATUS-CHANGELOG.md` · `docs/internal/backlog.md` —— **3 个文件全在 docs 树**，
对本格引用的 DS 文件 **0 命中**。

---

## 1. 被测物与冻结（`AGENTS §2.12`）

| 项 | 值 |
|---|---|
| 路径 | `<DS>/dist-wc/tvu-web-components.d.ts` |
| `sha256` | `3e4d80cdf1a303b5d6fe1c824949b8db0fa3e9aef44d5881e1ccacc7ecd34680` |
| 规模 | 719 行 / 26,373 字节 |
| 观测于 | DS `0cdee554`（起手回读） |

🔴 它是 **gitignored 的 build 产物** ⇒ 冻结**只能**靠整文件 sha，
⛔ **光靠「DS HEAD 只动了 docs」推不出它没变**（L3 报告 §6 边界③ 逐字）。
🟢 起手回读与 L3 报告登记的 sha **逐字相同** ⇒ 本份与 L3 测的是同一份载体，两份读数可并排。

⛔ **本份不重建 `dist-wc`、不跑 DS 的 build、不写 DS 一个字节。**

---

## 2. 面与口径

### 2.0 口径名

> **`真载体口径 · tsc 轴 · moduleResolution=Bundler 不变`**

🔴 **口径与 L3 逐字相同的那部分 ⛔ 不许动**：`jsx=react-jsx` / `moduleResolution=Bundler` /
`types=[]` / `skipLibCheck=true` / `strict=true`，以及 `paths` 的两条 `react` 映射。
**唯一的新变量是 tsc 版本。** 动了口径里任何别的一项，读数就 ⛔ 不能与 L3 并排（`AGENTS §2.4`）。

### 2.1 tsc 轴 —— 12 条线（取数前钉死）

**入面规则**（可复核，⛔ 不是我挑的）：registry 上 **非预发布**的 `5.x` / `6.x` / `7.x` 线，
每条线取**该线最新 patch**。⛔ 不含 `6.0.0-beta` / `7.0.1-rc` / `7.1.0-dev.*` 这类预发布。

| # | 线 | 钉死版本 | |
|:-:|---|---|---|
| 1 | 5.0 | `5.0.4` | 口径下界（`moduleResolution: Bundler` 是 5.0 引入的）|
| 2 | 5.1 | `5.1.6` | |
| 3 | 5.2 | `5.2.2` | |
| 4 | 5.3 | `5.3.3` | |
| 5 | 5.4 | `5.4.5` | DS `devDependencies` 声明的 `^5.4.0` 的下界 |
| 6 | 5.5 | `5.5.4` | |
| 7 | 5.6 | `5.6.3` | |
| 8 | 5.7 | `5.7.3` | |
| 9 | 5.8 | `5.8.3` | |
| 10 | 5.9 | `5.9.3` | 🔴 **L3 唯一测过的那个** ⇒ 本份的比对基准线 |
| 11 | 6.0 | `6.0.3` | 🔴 **一格没测过** |
| 12 | 7.0 | `7.0.2` | 🔴 **一格没测过，且它是 registry 的 `latest`** |

🔴 **第 12 行是本格最值钱的一格**：`npm view typescript dist-tags` 实取 `latest = 7.0.2`
⇒ **今天 consumer 跑 `npm i -D typescript` 拿到的就是它**，而 DS 的 `devDependencies` 钉 `^5.4.0`
⇒ **DS 自己的 build 永远看不到 6/7**，`smoke:peer-floor` 也够不着（tsc ⛔ 不在 `peerDependencies` 里）。

### 2.2 `@types/react` 轴 —— 沿用 L3 那 5 个，⛔ 不换

`17.0.2` · `18.0.0` · `18.2.0` · `18.3.31` · `19.2.17`（处方 §2.6 原版本集）。
⛔ **不换、不增、不删** —— 换了就 ⛔ 不能与 L3 的 10 格逐格比对，而那个比对正是 C3 的判据。

⇒ **面 = 12 × 5 = 60 格**（每格再分正/反两向）。

### 2.3 判据（逐格，⛔ 不钉错误码）

- **正例** `fixtures/positive.tsx`（`size="M"`）：必须 `exit 0`。
- **反例** `fixtures/negative.tsx`（`size="XXL"`）：必须**非零退出 ∧ 诊断文本点到 `XXL`**。
  🔴 后半句防的是假绿：**增广若根本没生效，反例也会红** —— 红在「`tvu-button` 不存在」、⛔ 不含 `XXL`
  ⇒ **那种红 ⛔ 不算过**（L3 §1 逐字沿用）。
- ⛔ **错误码只作边界读数登记，⛔ 不作判据**（钉死码会让「写法失效」因换了个码而假绿/假红）。
  ⚠️ 本轮尤其要紧：**12 条线跨 3 个 major，其中 7.x 是重写过的实现，错误码/文案本就可能不同。**

### 2.4 🔴 出面外（`OUT_OF_FACE`）—— 它对分母的处置必须先写死

某格若 **MH2 红**（纯 React 基线都不过）或 **MH5 红**（被测入口没解析到），
⇒ 该格记 `OUT_OF_FACE`，**⛔ 不计入 C1 / C3 的分母，也 ⛔ 不算「过」**，且必须在报告里**逐格列出**。

🔴 理由：那两种红是**装置/环境**的失败，⛔ 不是被测对象的行为（`AGENTS §3.9`）。
把它算成红 ⇒ 报出假缺陷；算成绿 ⇒ 恒真项稀释分母（`AGENTS §2.9` 推论一）。**两种都错。**
⇒ 报告必须**并排报**：面内格数（有效分母）与总格数 60，⛔ 不许只报一个。

⚠️ 可预见的出面外来源（**⛔ 是预期，不是借口**）：老 `@types/react`（17 / 18.0 / 18.2）在
6.x / 7.x 上可能自己就编不过。真出现就如实记，⛔ 不得因此改判被测对象。

---

## 3. 地板 F · 承诺 C · 控制 MH/MN（取数前写死）

### 3.1 地板 F（不达 ⇒ 整份不可判读）

| # | 什么 | 线 |
|:-:|---|---|
| **F1** | 12 条线全部真装成功，且**回读**的 `version` 与 §2.1 钉死值逐字相同 | 12/12 |
| **F2** | 被测 d.ts 的 `sha256` 在**取数前 / 每格跑前 / 取数后**三次回读均等于 §1 的冻结值 | 全等 |
| **F3a** | 面内格数（MH2 ∧ MH5 皆绿）≥ **40** / 60 | ≥ 40 |
| **F3b** | **每条 tsc 线至少 1 格在面内** | 12/12 |

🔴 **F3b 比 F3a 更要紧**：某条线若一格都不在面内，那条线**根本没读到东西**
⇒ ⛔ 不得计入 C1「全绿」，必须单列为「未读到」。⛔ 不许用别的线的绿替它作答。

### 3.2 承诺 C

**C1 —— 双写在面内每格成立（⇒ 得出 tsc 下界/上界）**
面内每格：正例 `exit 0` **∧** 反例非零退出且诊断点到 `XXL`。
线 = **面内格数全绿**。
⇒ 产出：**`tsc 覆盖区间` = C1 全绿的线集**；若有红格，红在哪条线即是边界所在。

**C2 —— 阴性对照必须在每条线上各红一次**
剥掉被测 d.ts `declare global` 块的**临时副本**（⛔ 真源只读），
在**每条 tsc 线**上跑同一个正例：**每条线至少 1 格由绿转红**。线 = **12/12 条线各 ≥1 红**。
🔴 L3 只在 `17.0.2` 上证过一次；本份要求**逐线**证 ——
**⛔ 不许拿一条线的可失败性替另外 11 条线作答**（`AGENTS §22` 推论四：换一个口径结论可能反号）。
⚠️ 某条线若剥完仍全绿 ⇒ **该线的装置证不了自己能失败** ⇒ **该线的 C1 绿 ⛔ 不得单独引用**。

**C3 —— 🔴 本格主问：承重图是一维还是二维**
对面内每格取三列：**M**（只留 `declare module 'react'`）· **G**（只留 `declare global`）· **B**（双写 = 真源）。
与**基准线 `5.9.3`** 上同一个 `@types/react` 的 `(M, G)` 结论逐格比对：

- 判 **`承重图二维`**：存在 ≥ 1 个面内格，其 `(M, G)` 与基准线上同 `@types/react` 的 `(M, G)` **不同**。
- 判 **`承重图一维`**：面内**全部**格的 `(M, G)` 与基准线**逐格相同**。

🔴 **这条 ⛔ 不是「希望它绿」的承诺 —— 两个方向都有信息量，且 §6 已把两支各自的动作写死。**
🔴 立它的理由：DS 生成器头注释（`scripts/lib/react-binding-templates.mjs:421-426`）给的因果模型
**只有 `@types/react` 一维**（「18.3 把 JSX 搬进 react 模块、19 删掉了 global 的」），
而「`declare module 'react' { namespace JSX }` 到底会不会被查」是 **tsc 侧**的查找规则，⛔ 不在那句话里。

### 3.3 内建控制

| # | 控制 | red 时本该意味着 |
|:-:|---|---|
| **MH1** | 剥 `declare global` 的副本，正例必须**红**（= C2 的装置）| 装置根本没在测 JSX 增广 ⇒ 该线读数作废 |
| **MH2** | 每格：**不 import DS 包**的纯 React 基线必须 `exit 0` | 我的 tsconfig / `react` 那半边 `paths` 在该 tsc 上坏了 ⇒ 该格 `OUT_OF_FACE` |
| **MH3** | 每格：回读 `@types/react/package.json` 的 `version` | 5 个 env 串味 |
| **MH4** | 每格：回读被测 d.ts 的 `sha256` | 载体在取数中变了 |
| **MH5** | 每格：从入口 `import type { ButtonSize }` 并用掉，必须 `exit 0` | `paths` 对 **DS 那半边**映射坏了 ⇒ 该格 `OUT_OF_FACE`，⛔ 不是「双写失效」 |
| 🔴 **MH6**（新增）| 每格：回读**这一格实际调用的那个 tsc** 自己的 `version`，并记录解析到的入口文件路径 | **12 条线串味** —— 「以为在跑 7.0.2、实际跑的 5.9.3」。⚠️ 入口 ⛔ 不许假设成 `lib/tsc.js`，必须从该包 `package.json` 的 `bin` 解析（7.x 是重写过的实现，入口形态可能不同）|
| 🔴 **MH7**（新增）| 每格：`--showConfig` 回读实际生效的 `moduleResolution` / `jsx`，必须逐字 `bundler` / `react-jsx` | **口径在不同 tsc 上被静默改写/忽略** ⇒ 12 条线量的不是同一个东西、读数不可并排（`AGENTS §2.4`）|
| **MN1** | 退出码一律 `spawnSync(...).status`，⛔ 不经 shell、⛔ 不接管道 | 读到管道末端那一节的码（`lab:N47`）|
| **MN2** | 正/反/M/G/基线/解析各自独立 fixture + 独立 `tsc` 进程 | 同一次编译里一个错掩盖另一个 |
| ~~**PH-MH1**~~ | ~~承重图 **B** 列 = 主判据 positive 格~~ | ⚠️ **在本份退化成构造保证** —— 同一个进程、同一个函数算出来的，⛔ 不是独立实证 ⇒ **由下面的 MH8 取代** |
| 🔴 **MH8**（新增）| **基准线 `5.9.3`** 上的 B / M / G 逐格结论，必须与 **L3 已发表读数**（`runs/wc-types-jsx-matrix/l3.json` 10 格 + `l3-post-hoc-blocks.json` 15 格）**逐格相同** | 🔴 **新量具与旧量具在同一条线上分岔** ⇒ 12 条线的读数 ⛔ 不可与 L3 并排，C3 的比对基准就没了 |

⚠️ **MH7 若在某条线上 `--showConfig` 不可用** ⇒ 该线记 `MH7=unavailable`，
且该线读数标「**口径未回读**」，⛔ **不得与已回读的线并排下结论**。⛔ 不许默认它一样。

### 3.4 取数前的补写留痕（`AGENTS §3.9` 第六形态）

- **2026-09-03，零读数**：本文件初版即含 MH6 / MH7。二者 ⛔ 不是 L3 那套的一部分，
  是本轮扩到 12 条线（跨 3 个 major）时**当场识别出的新控制缺口**，写在任何取数代码之前。
- 🔴 **2026-09-03，第二次补写，⛔ 仍是零读数**（补于**任何取数代码之前**，与 L3 的 MH5 同一处理）：
  **加 MH8，并把 PH-MH1 降级。** 起因是照 L3 抄控制表时当场发现：L3 的 PH-MH1 之所以是**实证**，
  是因为承重图与主判据由**两个脚本、两条管线**算出；而本份把两者合进**同一个进程同一个函数**
  ⇒ 「B 列 = positive 格」变成**构造保证，⛔ 不再能失败**（`AGENTS §2.15`：先问这个控制会不会根本不能失败）。
  ⇒ 直接抄过来会得到一条**恒真控制**，读起来却像一条过了的等价控制。
  ⇒ 换成 MH8：拿基准线去**逐格复现 L3 已发表的 25 格读数** —— 这条能真红，且红了正好否掉「可并排」这个前提。

---

## 4. 判读规则（🔴 取数后逐字执行，⛔ 不改）

```
若 F1 / F2 / F3a / F3b 任一不达        ⇒ 「不可判读（地板不达）」
否则若 C2 有任何一条线不红              ⇒ 该线「不可判读（阴性对照不红）」，其余线照常判
否则若 C1 面内有红格                    ⇒ 「有洞」＋ 逐格列出红在哪条线/哪个 @types/react
否则若 C3 = 二维                        ⇒ 「双写覆盖面内全部线 · 承重图二维」
否则                                    ⇒ 「双写覆盖面内全部线 · 承重图一维」
```

⇒ 记为 **`TSCAXIS_VERDICT`**。

---

## 5. 覆盖边界（⛔ 是边界，不是 TODO）

1. **口径固定 `moduleResolution=Bundler`** ⇒ ⛔ **够不到 tsc 4.x**（该选项 5.0 才有）。
   换掉它去够 4.x = **换口径** ⇒ 读数 ⛔ 不可与本份/L3 并排（`AGENTS §2.4` / `§22` 推论四）。
2. **每条线只取最新 patch** ⇒ patch 间 ⛔ 不可插值；**线间同样 ⛔ 不可插值**
   （L3 已在 `@types/react` 轴上实证分界不连续：`18.2.0` 红 / `18.3.31` 绿）。
3. ⛔ **不含预发布**（`6.0.0-beta` / `7.0.1-rc` / `7.1.0-dev.*`）。
4. **被测物是 build 产物**：读数绑的是「那一份 `sha256 3e4d80cd…` 的文件」，
   ⛔ **不是**「DS `0cdee554` 必然构建出的那一份」——⛔ 本份未重建。
5. **单次读数**：一个载体上的一次取数，⛔ 不是重复实验。
6. **射程 = JSX 增广这一条**（`JSX.IntrinsicElements` 上的自定义元素与其 props）。
   ⛔ 不测该 d.ts 的其它任何契约（事件 / slot / 导出面 / props 语义）。
7. ⛔ **不覆盖非 React consumer**（处方 §2.6 那三格 Vue 对照）。
8. ⛔ **不覆盖 `react-pilot/src/wrappers/jsx.d.ts`**（逐字 `Not shipped`，L3 §5②）。
9. ⛔ **不写 DS 一个字节、不跑任何 DS 闸、不重建 `dist-wc`。**

---

## 6. 🔴 结论驱动什么动作（两支都写死，取数后 ⛔ 不改）

| `TSCAXIS_VERDICT` | 驱动 |
|---|---|
| **有洞**（C1 面内有红格）| 🔴 **真缺陷** ⇒ 出处方给 DS：双写在那条 tsc 线上不成立，指明线与 `@types/react` |
| **承重图二维** | 🔴 出处方给 DS：`react-binding-templates.mjs` 头注释的因果模型只有 `@types/react` 一维，实测是二维 ⇒ **改那段理由**（⛔ 不改模板、⛔ 不改代码、⛔ 不动 `dist-wc`）|
| **承重图一维** | 建议 DS 为 `./web-components` 出口**声明一个它现在没有的 tsc 下界**（现 `peerDependencies` 只有 `vue`，`typescript` 在 `devDependencies` ⇒ 对 consumer 零声明），下界 = C1 全绿的最低线 |
| 任何一支 | ⛔ 不写 DS 一个字节 · ⛔ 不重建 `dist-wc` · ⛔ 不改 DS 模板 · 回改 `open-items` 清单**正文**（`AGENTS §22` 推论一）|

⚠️ **⛔ 不驱动的**：本份**没发现洞**时 ⛔ 不出处方、⛔ 不改 DS 模板 —— 与 L3 §7 同一条纪律。

---

## 7. ⛔ 本轮不许改的东西

- 🔴 [`probes/wc-types-jsx-matrix/run-matrix.mjs`](../probes/wc-types-jsx-matrix/run-matrix.mjs) 与
  [`post-hoc-blocks.mjs`](../probes/wc-types-jsx-matrix/post-hoc-blocks.mjs)：**⛔ 不改一个字节。**
  它们钉着 **L3 已发表读数**，动它们会让那份读数不可复核 ——
  与 §15.4 判否「改 `scan-real-surface.mjs` 的 label」**同一条理由**。
- ⇒ 本轮**只加**：`probes/wc-types-jsx-matrix/run-tsc-axis.mjs`。
- ⚠️ **代价如实登记**：控制逻辑会与 `run-matrix.mjs` 重复。
  ⛔ **不抽公共库** —— 抽取就等于改原文件。这是**刻意付的**重复代价，⛔ 不是疏忽。
- `fixtures/` 四份 **原样复用，⛔ 不改**（改了就 ⛔ 不能与 L3 逐格比对）。

---

## 8. 读数落点

- 主量具读数：`runs/wc-types-jsx-matrix/tsc-axis.json`
- 报告：`reports/2026-09-03-tsc-axis.md`
