4.6 KiB
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.tsis generated; it is type-checked bytsc -bbut never hand-edited. If TS7 rejects it, the fix goes in the generator (AGENTS.mdregeneration procedure), not the file.- No license work:
typescriptis a devDependency, absent from both the runtime closure and the bundled set inlicenses/dependency-identity.txt. The Zig drift guard (src/licenses_drift_test.zig) must still pass — it recomputes fromweb/package-lock.jsonand 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 fromweb/). - S1.3
zig build test(the licenses drift guard and the contract-samples guard run inside it).
Acceptance (S1):
web/node_modules/.bin/tsc --versionreports 7.0.x.npm run typecheckexits 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 testexits 0.git difftouches only the files S1 owns.
Module layout
New files: none. Deleted surface: none.
Acceptance (milestone complete)
- All S1 boxes.
licenses/dependency-identity.txtis 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
tsgobinary references anywhere: the binary istsc, 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, unlesstsc -bfails without it; then it is recorded in## Recorded (implementation).