Commit e58689b
fix(surface): anchor the generated-module path on REPO_ROOT, not the first /src/
SIGNATURES-FRESH was red in CI while a local regen on the same commit was green:
the enumerator produced 1072274 bytes on this box and 1055946 in CI, 602 differing
leaves. The artifact cannot be simultaneously fresh and stale, and the committed
port_signatures.json is DRIFT's INPUT, so a non-reproducible enumerator makes every
parity claim a comparison against a fiction.
Root cause: three call sites derived the generated-module path by scanning the
ABSOLUTE source-file path with
const m = srcFile.match(/\/src\/(.+?)\.ts$/);
const modPath = m ? m[1].replace(/\//g, '.') : 'rest.namespaces';
The regex is unanchored at the start, so `.+?` being lazy does not help: it matches
the FIRST `/src/` segment anywhere in the path, including one belonging to a PARENT
directory rather than to this repo. The capture — and therefore every
`class:signalwire.<modPath>.<Name>` leaf built from it — depended on WHERE THE REPO
IS CHECKED OUT:
/home/runner/work/.../signalwire-typescript/src/rest/namespaces/x.types.generated.ts
-> 'rest.namespaces.x.types.generated' (correct)
/Users/<dev>/src/signalwire-typescript/src/rest/namespaces/x.types.generated.ts
-> 'signalwire-typescript.src.rest.namespaces.x.types.generated' (WRONG)
All 602 differing leaves are that one spurious `<repo-dir>.src.` prefix, in two
spellings (`signalwire-typescript.src.` from the raw dotted join, and
`signalwire_typescript.src.` where the value routes through fallbackModuleName,
which snake-cases the dash). CI was always right; the wrong output was the local
one, because the documented adjacency layout (porting-sdk/CLAUDE.md §7) puts every
checkout under a workspace directory literally named `src`.
Fix: one `srcRelStem()` helper resolves an absolute source path to its
`src/`-relative, extension-stripped stem via `path.relative(REPO_ROOT, ...)`, and
returns null for anything outside this repo's `src/`. Anchoring on REPO_ROOT means
exactly one `src/` can match and it is always this repo's. All three sites use it;
no other unanchored `/src/` path scan remains in the enumerator.
Also regenerates port_signatures.json off the fixed enumerator.
No surface moved. diff_port_signatures reports the identical
1620 reference symbols / 1914 port symbols / 560 excused divergences before and
after — the diff checker's generated-type leaf-name normalization was already
folding the bogus prefix away, which is exactly why DRIFT never saw this and only
SIGNATURES-FRESH caught it.
Environment-independence is measured, not argued: the fixed enumerator produces a
BYTE-IDENTICAL artifact (sha256 e28eadf6...) from three different checkout
locations — /Users/<dev>/src/signalwire-typescript (darwin-arm64),
/build/ts inside a linux/amd64 node:24 container, and CI's own
/home/runner/work/... path (whose pre-fix output this now matches exactly).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TSHZoWoxoPVK6FuNaNKWFh1 parent 4ceb69b commit e58689b
2 files changed
Lines changed: 647 additions & 612 deletions
0 commit comments