# Milestone 22: TypeScript 7 Goal: move the web toolchain from TypeScript 6.0.3 to TypeScript 7.0.x (the native compiler, GA 2026-07-08). One devDependency bump; every web gate and the release pipeline stay green. Design written 2026-08-12 against HEAD `91a0aa9`. TypeScript 7.0.2 is `typescript@latest` on npm at spec time; the milestone pins whatever 7.0.x is current when the session runs. ## Implementation contract (read first) - Read `AGENTS.md`, then this spec whole, before session work starts. - `web/src/lib/contractSamples.gen.ts` is generated; it is type-checked by `tsc -b` but never hand-edited. If TS7 rejects it, the fix goes in the generator (`AGENTS.md` regeneration procedure), not the file. - No license work: `typescript` is a devDependency, absent from both the runtime closure and the bundled set in `licenses/dependency-identity.txt`. The Zig drift guard (`src/licenses_drift_test.zig`) must still pass — it recomputes from `web/package-lock.json` and dev-only changes are invisible to it. ## Rulings (binding) ### 1. The bump is one line plus the lockfile `web/package.json:45` `"typescript": "6.0.3"` becomes the current 7.0.x, exact pin (repo convention: no ranges, milestone-14 ruling 12 pins by exact version everywhere). `npm install` updates `web/package-lock.json`. Nothing else in `dependencies` or `devDependencies` moves in this milestone. ### 2. The tsconfigs are already TS7-clean; verify, do not churn Checked against TS7's removed options (recorded here so the session does not re-derive it): `tsconfig.app.json` and `tsconfig.node.json` use `moduleResolution: "bundler"`, `module: "esnext"`, targets `es2022`/`es2023`, `paths` without `baseUrl`, `verbatimModuleSyntax`, `isolatedModules`, `noEmit`. None of TS7's removals (`target: es5`, `downlevelIteration`, `moduleResolution: node10`/`classic`, `module: amd/umd/system/none`, `baseUrl`-as-alias) are present. `tsconfig.json` is a two-entry project reference; TS7 supports `tsc -b` and project references. The session changes a tsconfig only if `tsc -b` errors demand it, and records any such change in `## Recorded (implementation)`. ### 3. Known TS7 edge: `skipLibCheck` no longer hides parse-level .d.ts errors Both tsconfigs set `skipLibCheck: true`. Under TS7 that still skips type checking of `.d.ts` files but not parse-level errors in them. If a dependency `.d.ts` fails to parse, the fix is a dependency patch bump or an upstream issue reference recorded in the spec — never a copied-and-edited local `.d.ts`. ### 4. Nothing else in the toolchain consumes the TS compiler Verified at spec time: `oxlint` (own parser), `vite`/`vitest` (esbuild transpile, no type checking), `prettier`, and `@vitejs/plugin-react` run no `tsc` and load no `typescript` API. The only consumer is the `typecheck` script (`web/package.json:12`, `tsc -b`), run in CI at `.gitea/workflows/gates.yml:113-114`. TS7 has no stable programmatic API until 7.1; nothing in this repo needs one. ## Sessions One session. ### Session S1: the bump Owns: `web/package.json`, `web/package-lock.json`, and — only if ruling 2 forces it — `web/tsconfig.app.json`, `web/tsconfig.node.json`, `web/tsconfig.json`. - S1.1 bump per ruling 1; `npm install`. - S1.2 run, in order: `npm run format:check`, `npm run lint`, `npm run typecheck`, `npm test`, `npm run build`, `npm run assert-bundled` (all from `web/`). - S1.3 `zig build test` (the licenses drift guard and the contract-samples guard run inside it). Acceptance (S1): - [ ] `web/node_modules/.bin/tsc --version` reports 7.0.x. - [ ] `npm run typecheck` exits 0 with no tsconfig change, or the change is recorded with the TS7 error text that forced it. - [ ] All six web gate commands exit 0. - [ ] `zig build test` exits 0. - [ ] `git diff` touches only the files S1 owns. ## Module layout New files: none. Deleted surface: none. ## Acceptance (milestone complete) - [ ] All S1 boxes. - [ ] `licenses/dependency-identity.txt` is byte-identical to HEAD. ## Anti-requirements - No other dependency bumps ride along — not oxlint, not vite, not vitest, not `@types/*`. - No tsconfig flag additions or "modernization" beyond what a TS7 error forces. - No typescript-eslint, ts-jest, or any tool needing the TS programmatic API (unavailable until 7.1, and unwanted regardless — oxlint is the linter). - No `tsgo` binary references anywhere: the binary is `tsc`, scripts stay as they are. - No edits to `web/src/**` — a source change to satisfy the new compiler is a finding to record and fix, not silently absorb, unless `tsc -b` fails without it; then it is recorded in `## Recorded (implementation)`.