Skip to content

Commit 92eabf4

Browse files
hyperpolymathclaude
andcommitted
docs(language-policy): codify TS→AffineScript migration state + carve-outs
TS→AffineScript migration is in-flight, not complete (unlike V→Zig which closed 2026-05-28). Doc state had drifted: TS row in LANGUAGE-POLICY.adoc listed replacement as ReScript (itself banned 2026-04-30), Migration Priority §2 said "Convert TS to ReScript", and the standards/.claude exemption table only listed avow-telegram-bot — missing the structural carve-outs (.d.ts, */bindings/{deno,ts,typescript}/, tooling configs, upstream forks, archives). Mirrors the V→Zig sweep structure (standards#227): codifies five carve-out classes, references the hypatia detection rule (cicd_rules/typescript_detected) with path_allow_prefixes parallel to :vlang_detected, adds v1.3.0 amendment, extends language-policy.yml workflow to block new TS outside carve-outs. Inventory recorded in project tracker project_estate_ts_to_affinescript_2026_05_28.md: 909 total TS files, ~288 estate-authored after carve-out, top targets idaptik (52) + wordpress-tools (43) + developer-ecosystem (18). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent b3493a6 commit 92eabf4

3 files changed

Lines changed: 91 additions & 9 deletions

File tree

.claude/CLAUDE.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,18 @@ Both are FOSS with independent governance (no Big Tech).
128128

129129
### TypeScript Exemptions (Approved)
130130

131-
The hyperpolymath "no new TypeScript" policy has the following approved exemptions in this repo. These are *not* policy violations — they are documented carve-outs.
131+
The hyperpolymath "no new TypeScript" policy has the following approved exemptions, encoded as `path_allow_prefixes` on the hypatia rule `cicd_rules/typescript_detected` (matches `*.ts`). These are *not* policy violations — they are documented carve-outs.
132132

133-
| Path | Files | Rationale | Unblock condition |
134-
|---|---|---|---|
135-
| `avow-protocol/telegram-bot/avow-telegram-bot/**` | 4 | Telegram bot — Telegraf / node-telegram-bot-api are the canonical TS-native libraries for the Bot API; no AffineScript binding planned. | AffineScript Telegram-bot bindings (no scheduled issue). |
133+
Existing pre-2026-04-30 `.ts`/`.tsx` outside these carve-outs is grandfathered while in-flight migration proceeds (~288 estate-authored files across ~40 repos as of 2026-05-28; see project tracker `project_estate_ts_to_affinescript_2026_05_28.md`). New TS files in non-carve-out paths are blocked.
136134

137-
Adding to this list requires explicit user approval and an unblock condition. New TypeScript files outside this list are blocked by the RSR antipattern check.
135+
| Path / Pattern | Class | Rationale | Unblock condition |
136+
|---|---|---|---|
137+
| `**/*.d.ts` | declaration | FFI/library type definitions (headers, not implementation). | Never — declaration files are the boundary, not the code. |
138+
| `**/bindings/deno/**`, `**/bindings/typescript/**`, `**/bindings/ts/**` | interop target | We expose work to TS/Deno consumers without authoring TS as primary code path. Exemplar: `proven/bindings/deno/` (72 files — Idris2 ABI exposed as Deno-native module). Parallel to V-lang `v-cartridge`/`v-adapter`/`v-bindings`/`v-client` carve-out. | Never — these are consumer-facing bindings. |
139+
| `avow-protocol/telegram-bot/avow-telegram-bot/**` | PERMANENT | Telegraf / node-telegram-bot-api are the canonical TS-native libraries for the Bot API; no AffineScript binding planned. | AffineScript Telegram-bot bindings (no scheduled issue). |
140+
| `**/vite.config.ts`, `**/vitest.config.ts`, `**/tsup.config.ts`, `**/tsconfig.json` | tooling | Build orchestration, not application code. | When AffineScript ships native equivalents. |
141+
| `affinescript-deno-test/**`, `affinescript-cli/**` | bootstrap shim | TS/JS shims used to bootstrap the AffineScript test runner / CLI. | When AffineScript self-hosts these. |
142+
| `rescript/**`, `servers/**`, `repos-monorepo/**` | upstream fork | Not estate-authored — vendored upstream code (ReScript compiler, third-party MCP servers, mass aggregator). | Never — upstream fork. |
143+
| `hyperpolymath-archive/**` | archived | GitHub-archived repos cannot accept PRs; TS is dormant. | Never — archived. |
144+
145+
Adding to this list requires explicit user approval and an unblock condition (except the structural classes above, which are estate-wide policy). The detection rule and its `path_allow_prefixes` field are the single source of truth; this table mirrors that for human readability.

rhodium-standard-repositories/.github/workflows/language-policy.yml

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,34 @@ jobs:
4444
exit 1
4545
fi
4646
fi
47-
47+
48+
# Block new TypeScript files (banned 2026-04-30, replacement: AffineScript).
49+
# Carve-outs (parallel to hypatia cicd_rules/typescript_detected path_allow_prefixes):
50+
# *.d.ts declaration files (headers, not impl)
51+
# */bindings/{deno,ts,typescript}/ interop targets (consumers of our work)
52+
# avow-protocol/telegram-bot/avow-telegram-bot/ Telegraf PERMANENT exemption
53+
# *.config.ts / vite.config.ts / vitest.config.ts / tsup.config.ts tooling
54+
# affinescript-deno-test/ + affinescript-cli/ bootstrap shims
55+
# rescript/ + servers/ + repos-monorepo/ upstream forks
56+
# hyperpolymath-archive/ archived repos
57+
NEW_TS=$(git diff --name-only --diff-filter=A HEAD~1 2>/dev/null \
58+
| grep -E '\.tsx?$' \
59+
| grep -vE '\.d\.ts$' \
60+
| grep -vE '/bindings/(deno|typescript|ts)/' \
61+
| grep -vE '^avow-protocol/telegram-bot/avow-telegram-bot/' \
62+
| grep -vE '(^|/)(vite|vitest|tsup)\.config\.ts$' \
63+
| grep -vE '\.config\.ts$' \
64+
| grep -vE '^(affinescript-deno-test|affinescript-cli)/' \
65+
| grep -vE '^(rescript|servers|repos-monorepo|hyperpolymath-archive)/' \
66+
|| true)
67+
if [ -n "$NEW_TS" ]; then
68+
echo "❌ New TypeScript files detected (banned 2026-04-30). Use AffineScript instead."
69+
echo "$NEW_TS"
70+
echo ""
71+
echo "If this file genuinely belongs to a carve-out class, add it via"
72+
echo "the hypatia rule's path_allow_prefixes — see standards/.claude/CLAUDE.md"
73+
echo "§TypeScript Exemptions (Approved)."
74+
exit 1
75+
fi
76+
4877
echo "✅ Language policy check passed"

rhodium-standard-repositories/spec/LANGUAGE-POLICY.adoc

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,29 @@ NOTE: For full rationale and migration guides, see the link:{source-repo}[CCCP r
122122
| Banned | Replacement | Rationale
123123

124124
| *TypeScript*
125-
| ReScript
126-
| Unsound gradual typing
125+
| AffineScript
126+
| Banned in NEW code 2026-04-30 (estate-language-policy refresh
127+
`feedback_estate_lang_policy_2026_05_25.md`). Existing `.ts`/`.tsx`
128+
is grandfathered while in-flight migration to AffineScript proceeds
129+
(see project tracker
130+
`project_estate_ts_to_affinescript_2026_05_28.md`). Detection is
131+
the hypatia rule `cicd_rules/typescript_detected` (matches `*.ts`)
132+
with `path_allow_prefixes` covering five carve-out classes:
133+
(1) `*.d.ts` declaration files (FFI/library type definitions —
134+
these are headers, not implementation); (2) `*/bindings/deno/`,
135+
`*/bindings/typescript/`, `*/bindings/ts/` interop targets where
136+
we expose work to TS/Deno consumers without authoring TS as our
137+
primary code path (exemplar: `proven/bindings/deno/`);
138+
(3) `avow-protocol/telegram-bot/avow-telegram-bot/**` — Telegraf
139+
is the canonical TS-native Bot-API library, no AffineScript
140+
binding planned (PERMANENT exemption); (4) tooling configs
141+
(`vite.config.ts`, `vitest.config.ts`, `tsup.config.ts`,
142+
`tsconfig.json`) — these are build orchestration, not application
143+
code; (5) upstream forks not estate-authored (`rescript/`,
144+
`servers/`, `repos-monorepo/`) and `hyperpolymath-archive/**`
145+
(archived repos with dormant TS). Unsound gradual typing is the
146+
underlying technical objection; AffineScript provides affine/linear
147+
types plus typed-wasm output.
127148

128149
| *Node.js*
129150
| Deno
@@ -235,7 +256,16 @@ everywhere" rule.
235256
When encountering banned languages:
236257

237258
1. *Immediate*: Block new code in banned languages
238-
2. *Short-term*: Convert TypeScript to ReScript (now AffineScript) → typed-wasm
259+
2. *In-flight 2026-04-30 → ongoing*: Convert existing TypeScript/ReScript/JS
260+
→ AffineScript → typed-wasm. ReScript is also banned in new code as of
261+
2026-04-30; existing `.res` migrates to `.affine` directly (do NOT pass
262+
through ReScript). Tracker:
263+
`project_estate_ts_to_affinescript_2026_05_28.md` records inventory
264+
(~288 estate-authored `.ts`/`.tsx` files post-carve-out across ~40
265+
repos), carve-out classes, and per-repo migration order. New TS files
266+
are blocked by hypatia `cicd_rules/typescript_detected` (with
267+
`path_allow_prefixes` for documented carve-outs) and the
268+
`language-policy.yml` reusable.
239269
3. *Medium-term*: Replace Node/npm with Deno
240270
4. ✅ *Done 2026-05-28*: V-lang → Zig migration complete across the estate
241271
(16 admin-merged PRs; hypatia detection rule armed)
@@ -411,6 +441,21 @@ not prose alone.
411441

412442
== Amendments
413443

444+
=== v1.3.0 — 2026-05-28 (Jonathan D.A. Jewell)
445+
446+
Codified the *TypeScript → AffineScript migration state*: in-flight, not
447+
complete. Existing `.ts`/`.tsx` is grandfathered while migration to
448+
AffineScript proceeds; new TS in non-carve-out paths is blocked.
449+
Documented five carve-out classes (`.d.ts`, `*/bindings/{deno,ts,typescript}/`,
450+
`avow-protocol/telegram-bot/avow-telegram-bot/**`, tooling configs,
451+
upstream forks + archives). Detection rule: hypatia
452+
`cicd_rules/typescript_detected` extended with `path_allow_prefixes`
453+
mirroring the V-lang rule's structure (hypatia#372/#373 precedent).
454+
Tracker: `project_estate_ts_to_affinescript_2026_05_28.md`. This
455+
amendment closes the doc-vs-policy drift where TS was listed with
456+
replacement "ReScript" rather than "AffineScript" (post-2026-04-30
457+
ReScript is itself banned in new code).
458+
414459
=== v1.2.2 — 2026-05-16 (Jonathan D.A. Jewell)
415460

416461
Generalised the scoped convention override into the *Explicit-Escape

0 commit comments

Comments
 (0)