Skip to content

refactor(release): one source of truth for the platform table; delete the platforms-mirror check - #1105

Merged
thekevinbot merged 5 commits into
mainfrom
claude/1074-platform-table-single-source
Sep 5, 2026
Merged

thekevinbot merged 5 commits into
mainfrom
claude/1074-platform-table-single-source

Conversation

@thekevinbot

Copy link
Copy Markdown
Collaborator

Fixes #1074. Part of #1072.

The published-target table existed twice — a TypeScript literal in
packages/ts/src/platforms.ts and a hand-maintained Python subset in
internals/distcheck/.../node_flow/platforms.py — and a third component,
internals/checks/src/checks/platforms_mirror/, existed only to parse both and
prove they agreed. This collapses the duplicate and deletes the check.

The direction, and why

Canonical artifact: packages/ts/src/platforms.json. The rows move there
verbatim. platforms.ts imports it and types it; the distcheck flow reads the
same file with json.loads. Nothing is generated, nothing is committed twice,
and there is no derivation step to drift — the file is the table.

Three constraints picked that location, and each ruled out an alternative:

  • It has to ship to npm. loadNativeCore() calls libTriples() at runtime
    in the published package, so the data cannot live at the repo root or in
    putitoutthere.toml — neither is inside packages/ts, and npm files cannot
    reach a parent directory. Under src/ with resolveJsonModule, tsc copies
    the JSON into dist/ next to the compiled modules, and files: ["dist/", …]
    ships it. Verified, not assumed — see the manual run below.
  • It has to be read, not generated. A generated file that is committed can
    drift, which would need a check to police it — the exact thing being deleted
    here. A generated file that is not committed has to exist before any
    consumer builds, including tsx tools/stage-platform.ts and a Python process
    that never runs tsc. Reading one declarative file sidesteps both.
  • The subset stays a subset. The JSON carries every field; each reader takes
    what it needs. triple and libc remain TypeScript-only, as before.

Types at the boundary. JSON widens nodePlatform / nodeArch to string,
so PLATFORMS is a single as readonly Platform[] cast — one cast, in the one
place the JSON and node vocabularies meet. The Platform interface is
unchanged. On the Python side the only derivation is slug, stripped from
libName; existing assertions (p.slug, p.name, p.addon_name) pin it.

Public surface

Unaffected. packages/ts/src/index.ts exports only DirSQL and Table,
and package.json's exports map has a single "." entry — PLATFORMS,
libTriples() and librarySlug() were never reachable by a consumer and still
are not. librarySlug keeps its home in library-slug.ts and its behavior.
No SDK public API moved, so PARITY.md needs no update.

The one packaging-visible change: dist/platforms.json is now in the tarball
alongside the .js/.d.ts files.

Deleted

  • internals/checks/src/checks/platforms_mirror/ — 24 files (12 source, 12
    colocated tests), including everything refactor(checks): one function per file across attestation_guard and platforms_mirror #1102 split out of it.
  • internals/checks/tests/integration/platforms_mirror_test.py and
    internals/checks/tests/e2e/platforms_mirror_test.py.
  • Its import + add_command line in checks/cli.py, and the
    test_platforms_mirror_is_registered case in cli_test.py.
  • .github/workflows/platforms-mirror-check.yml.

Added in its place: packages/ts/src/platforms.json on
internals-distcheck-ci.yml's path filter, so a table edit still triggers the
lane whose lookup reads it.

Source-line delta

Measured with #1072's srcline.py (non-test, non-comment, non-blank), base
3a1e427 vs this branch. JSON is data, not source, and is outside the metric —
as are the Python and TypeScript comments.

scan root before after delta
packages/ts/src 544 502 −42
internals/checks/src 1,613 1,310 −303
internals/distcheck/src 354 361 +7
total (all 8 roots) 10,557 10,219 −338

24 fewer files. The issue estimated ~−276; the extra comes from platforms_mirror
having grown under #1020's extraction rungs since that estimate was taken.

Red/green

This is a refactor plus a removal, so neither arm of the rule demands a pushed
RED. The removal is exempt by AGENTS.md. The refactor introduces no new
observable behavior
: PLATFORMS holds byte-identical rows, libTriples()
returns the same map, and the Python Platform tuple is unchanged — all of it
already pinned by packages/ts/src/platforms.test.ts and
internals/distcheck/.../platforms_test.py, which are untouched. Not one
test assertion changed anywhere in this PR.
Every deleted test is a test of
deleted source.

Added assertions (not changed ones)

The colocated-test co-change gate requires a changed source file's test to
change with it, so each side gained one new case — a strengthening, never a
rewrite, and aimed at exactly the risk this PR introduces:

  • platforms.test.ts pins every ${nodePlatform}-${nodeArch} key. PLATFORMS
    is a cast, so no type stops a hand-edited row carrying a value node never
    reports.
  • platforms_test.py pins the full slug set. slug is the one field the
    Python side derives rather than carries, and a moved constant is a mutation
    survivor without a test on its literal.

Notes

  • tools/stage-platform.ts's "unsupported host" message pointed at
    src/platforms.ts; it now points at src/platforms.json. Not asserted by any
    test (stage-platform.test.ts matches /unsupported host/ only).
  • arch.py's "extend platforms.py" message was already pointing at the wrong
    file before this PR (the arch map lives in arch.py). Left alone — unrelated,
    and its own one-line fix.
  • one_function_per_file at threshold 1: internals/checks/src,
    packages/ts/src and internals/distcheck/src all still report zero
    violations. Measured with npx -y testing-conventions@latest, resolved
    version 0.0.116.

Manual verification

$ npx tsc -p tsconfig.build.json          # resolveJsonModule on
$ ls dist/platforms.json                  # → emitted, 1.0K
$ node -e "import('./dist/platforms.js')" # libTriples() → the same 5-entry map as main
$ npm pack --dry-run                      # "1.1kB dist/platforms.json" in the tarball
$ cd /tmp/demo && node .../dist/cli/dirsql.js "select * from './'"
[{"basename":"a.txt","ctime":…,"dir":"","ext":"txt","mtime":…,"path":"a.txt","size":6}]
$ uv run --project internals/distcheck python -c "from distcheck.node_flow.platforms import PLATFORMS; ..."
linux-x64-gnu   @dirsql/lib-linux-x64-gnu   dirsql.linux-x64-gnu.node   ['linux'] ['x64']
linux-arm64-gnu @dirsql/lib-linux-arm64-gnu dirsql.linux-arm64-gnu.node ['linux'] ['arm64']
darwin-x64      @dirsql/lib-darwin-x64      dirsql.darwin-x64.node      ['darwin'] ['x64']
darwin-arm64    @dirsql/lib-darwin-arm64    dirsql.darwin-arm64.node    ['darwin'] ['arm64']
win32-x64-msvc  @dirsql/lib-win32-x64-msvc  dirsql.win32-x64-msvc.node  ['win32'] ['x64']

Identical to the table on main, field for field.

E2E Verification

  • Ran e2e suites locally for every affected SDK
  • Python SDK e2e: N/A — packages/python untouched
  • TypeScript SDK e2e: pass (5 files, 16 tests)
  • Rust core e2e (if applicable): N/A — packages/rust untouched
  • packages/python/e2e-attestations/<branch>.json receipt written if packages/python changed (just e2e-attest-python) — N/A, unchanged
  • packages/ts/e2e-attestations/<branch>.json receipt written if packages/ts changed (just e2e-attest-ts)
  • internals/checks/e2e-attestations/<branch>.json receipt written (internals/checks/src changed)
  • Command(s) run:
    • pnpm test:e2e in packages/ts → 5 files, 16 tests, all pass
    • uv run python -m pytest tests/e2e -x -q in internals/checks → 25 pass
    • uvx testing-conventions@latest e2e attest '<above>' in each, receipts committed
    • just preflight → all pairs green (3 packaging SKIPs, which need a built artifact)
  • Result summary: green. Both receipts are pure additions — git show --stat on each
    attestation commit shows one file, 7 insertions, no sibling receipt pruned.

Changelog / Migrations

  • Changelog fragment added under <root>/<pkg>/changelog.d/ for each changed package — packages/ts/changelog.d/2026-09-05-platform-table-single-source.md. internals/** is outside changelog_gate's _ROOTS.
  • Migration fragment added under <root>/<pkg>/migrations.d/ (or: not required — additive/bugfix only) — not required: no public API breaks, no deprecated symbol removed, and no runtime behavior change. PLATFORMS and libTriples() return exactly what they returned before.

The published-target table lived twice -- as a TypeScript literal in
packages/ts/src/platforms.ts and as a hand-maintained Python subset in
internals/distcheck -- and `dirsql-checks platforms-mirror` existed only to
prove the copies agreed.

The rows now live in packages/ts/src/platforms.json. platforms.ts imports it
and casts the two node vocabularies (`NodeJS.Platform` / `NodeJS.Architecture`)
at that one boundary; the distcheck flow reads the same file. The JSON sits
under src/ so tsc emits it into dist/, which is what `loadNativeCore()` needs
at runtime in the published package.

With one copy there is nothing left to mirror, so the check, its colocated
unit tests, its integration and e2e suites, its registration in the
`dirsql-checks` group and its dedicated workflow are deleted.

No test assertion changed. Source lines: -338 across the scan roots.
The TypeScript view of the table is now a cast over platforms.json, so no
type stops a hand-edited row carrying a platform/arch node never reports;
the Python view derives `slug` from `libName` rather than carrying it.
Two new assertions pin both, one per side. No existing assertion changed.
…table-single-source

# Conflicts:
#	internals/checks/src/checks/cli.py
@thekevinbot
thekevinbot disabled auto-merge September 5, 2026 12:53
@thekevinbot
thekevinbot merged commit 35f34a2 into main Sep 5, 2026
48 checks passed
@thekevinbot
thekevinbot deleted the claude/1074-platform-table-single-source branch September 5, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

release: one source of truth for the platform table, and delete the platforms-mirror check

1 participant