Skip to content

Commit bfef9ad

Browse files
feat(scripts): AffineScript port of check-ts-allowlist (TS->AS campaign STEP 2 seed) (#284)
## Summary Adds `scripts/check-ts-allowlist.affine` as the AffineScript port of the existing `scripts/check-ts-allowlist.ts`, filed under the estate TS->AffineScript migration campaign (#239 umbrella, STEP 2 — tail-batch-1 per standards#241). **Self-referential**: the script that enforces the no-new-TypeScript policy is itself one of the TS files that policy applies to. Landing the AffineScript version is a symbolic milestone for the meta-tool. **Pattern**: phronesis#19 seed style. Add `.affine` alongside the live `.ts`. No workflow change in this PR; CI keeps invoking the `.ts` via `deno run --allow-read .standards-checkout/scripts/check-ts-allowlist.ts`. Workflow cutover (compile `.affine` to `.deno.js`, wire wrapper, retire `.ts`) is a follow-up issue. ## Behaviour equivalence The regression suite at `scripts/tests/check-ts-allowlist-test.sh` exercises 13 cases (builtin allowlist classes + Layer-2 CLAUDE.md exemptions + Layer-2.5 governance-allowlist + dotted-dir skip + multi-heading-table parsing). - **All 13 PASS** against the AffineScript-emitted `.deno.js` (verified locally with a sibling harness using the same fixtures) - **All 13 PASS** against the original `.ts` (no regression) Both implementations are behaviour-equivalent on the substring assertions the suite makes. Cosmetic difference: the `.affine` port uses ASCII `[FAIL]` / `[OK]` sentinels instead of the original emoji (see "Seam findings" below). ## Stdlib surface used All externs already shipped in `stdlib/Deno.affine` via affinescript#445: - `walkRecursive` (recursive file enumeration) - `regexMatch` (JS RegExp.test wrapper) - `readTextFile` (synchronous file read; throws on missing — wrapped in `try`/`catch`) - `args`, `exit`, `consoleError` Plus AffineScript builtins: `string_get`, `string_sub`, `string_find`, `char_to_int`, `int_to_string`, `len`. ## AffineScript seam findings surfaced by this port (Each would be a separate affinescript-repo PR — out of scope for this per-standards-repo PR per the campaign's ownership gate.) - **String less-than lex-compare**: not built-in. Implemented inline via byte-wise `str_lt` (calls `char_to_int(string_get(...))`). Bare `a < b` on `String` produces `TypeMismatch (String, Int)`. - **`break`/`continue` in `while`**: `BREAK`/`CONTINUE` tokens are reserved in `lib/parser.mly` but no production rule uses them yet. Refactored two natural occurrences (`s_trim` inner loops + `strip_leading_dot_slash`) to combined-guard / sentinel-boolean forms. - **Non-ASCII string literals**: lower to octal escape sequences (e.g. `"\\226\\157\\140"`) in `--deno-esm` output. Strict-mode ESM rejects octal escapes with `SyntaxError: Octal escape sequences are not allowed in strict mode.` Worked around with ASCII `[FAIL]` / `[OK]` sentinels. - **Stale installed binary**: the `affinescript` at `~/.local/bin/` predated PR #445 and silently emitted bare `walkRecursive(".")` calls (no `__as_walkRecursive` shim in the prelude). A trunk rebuild surfaces the new shims correctly. ## Sequencing follow-ups (NOT part of this PR) - [ ] Compile-time wiring: build `.affine` -> `.deno.js` in CI; commit `.deno.js` as a generated artefact OR add a precompile step. - [ ] Workflow cutover: update `.github/workflows/governance-reusable.yml` to invoke the `.deno.js` (with the existing `--allow-read` scope). - [ ] Retire `.ts`: delete `scripts/check-ts-allowlist.ts` and update `docs/EXEMPTION-MECHANISMS.adoc` references. - [ ] Upstream affinescript fixes for the 3 seam findings above (file as separate affinescript-repo issues). ## Test plan - [x] `affinescript check` type-checks the `.affine` - [x] `affinescript compile --deno-esm` emits `.deno.js` with no octal-escape errors - [x] 13/13 regression tests pass against the AffineScript-emitted `.deno.js` - [x] 13/13 regression tests pass against the original `.ts` (no regression) - [x] GPG-signed commits ## Refs - Refs #239 (campaign umbrella) - Refs #241 (STEP 2 — TAIL BATCH 1) - Pattern: hyperpolymath/phronesis#19 (STEP 1 seed) - Unblocked by: hyperpolymath/affinescript#445 (STEP 3 first-cut) 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent 9c33dec commit bfef9ad

0 file changed

File tree

    0 commit comments

    Comments
     (0)