You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Decision] Where does logic shared between .mjs CI gate scripts and TypeScript tests live? — @object-ui/test-support is TS-source-only, so #5872's class (3) cannot use the class-(1) pattern #6923
Filed by the domain:ui execution seat (PM session session_013hfmP9hoMd3dJwTh85J4yB) out of #5872's 2026-08-31 round. ⛔ Not a scheduling detail — it is a decision this seat declined to make, and #5872's class (3) is blocked on it.
The wall, measured
#5872 consolidates hand-copied Zod-internals readers onto @object-ui/test-support, one reader-class at a time. Class (1) landed that way (PR #6047). Class (3) cannot.
Class (3) is one literal wrapper-key list — ['in', 'out', 'innerType', 'schema', 'left', 'right'] — walked to unwrap a Zod node. When #5872 was filed it lived in three TypeScript test files. It has since grown out of tests into .mjs CI gate scripts, so the copies now span a language boundary.
The class-(1) pattern is unavailable across it, for a mechanical reason:
packages/test-support is package.jsonprivate: true (v17.4.0, described "Internal, never-published"), and
its exports map points at ./src/index.ts — TypeScript source.
So a plain node scripts/check-*.mjscannot import it. There is no build artefact for a bare-node consumer to reach.
Why this is not the dev's call, and not the PM's
The three available shapes are not equivalent in cost, and two of them change how this repo shares logic:
B — give the wrapper-key list a JS-consumable home both sides can import, and have test-support re-export it, so tests and gate scripts read one list. This is the shape that actually removes the drift, but it is a real change to how this repo shares gate logic, not a mechanical consolidation — it means deciding whether a JS-consumable shared surface exists at all, where it lives, and what may depend on it.
C — defer class (3) until the shared-gate-logic question is settled on its own terms, since the question outlives this card.
The seat's recommendation is B, with the note that B is exactly why this needs a ruling rather than a dispatch: it establishes a new dependency shape for CI gates, which is above an execution seat's authority.
What is NOT being asked
⛔ This is not a request to re-rule #5872's triage grade, and not about classes (1), (2) or (4). Class (1) is landed; class (2) is a separate verdict-flip risk with its own reasoning; class (4) is small. Only class (3) is blocked here.
Consequence of leaving it
The drift is latent today — the copies agree. The cost when it drifts is the one spec-tombstones.ts already argues: a Zod internals rework moves one spelling and not the others, the copies that stop reading go quietly permissive, and the assertions built on them pass over nothing. ⭐ Measured on this exact family in PR #6047's ablation: on an empty vocabulary, the "spec accepts a name we do not implement" half of three of four parity gates stayed GREEN, because it filters an empty list. A gate script that silently stops matching is the same failure with CI's authority behind it.
Filed by the
domain:uiexecution seat (PM sessionsession_013hfmP9hoMd3dJwTh85J4yB) out of #5872's 2026-08-31 round. ⛔ Not a scheduling detail — it is a decision this seat declined to make, and #5872's class (3) is blocked on it.The wall, measured
#5872 consolidates hand-copied Zod-internals readers onto
@object-ui/test-support, one reader-class at a time. Class (1) landed that way (PR #6047). Class (3) cannot.Class (3) is one literal wrapper-key list —
['in', 'out', 'innerType', 'schema', 'left', 'right']— walked to unwrap a Zod node. When #5872 was filed it lived in three TypeScript test files. It has since grown out of tests into.mjsCI gate scripts, so the copies now span a language boundary.The class-(1) pattern is unavailable across it, for a mechanical reason:
packages/test-supportispackage.jsonprivate: true(v17.4.0, described "Internal, never-published"), andexportsmap points at./src/index.ts— TypeScript source.So a plain
node scripts/check-*.mjscannot import it. There is no build artefact for a bare-node consumer to reach.Why this is not the dev's call, and not the PM's
The three available shapes are not equivalent in cost, and two of them change how this repo shares logic:
.mjsgate scripts hand-copied. ⛔ This is the outcome the whole [finding] The tombstone judge converged, but the Zod-internals READERS around it are still hand-copied in ~10 test files — four of them verbatim #5872 family exists to prevent: two copies of one judgement that cannot move together — now with a language boundary guaranteeing they won't. It would also be the most misleading state, because the card would read as closed while the highest-drift-risk copies remain.test-supportre-export it, so tests and gate scripts read one list. This is the shape that actually removes the drift, but it is a real change to how this repo shares gate logic, not a mechanical consolidation — it means deciding whether a JS-consumable shared surface exists at all, where it lives, and what may depend on it.The seat's recommendation is B, with the note that B is exactly why this needs a ruling rather than a dispatch: it establishes a new dependency shape for CI gates, which is above an execution seat's authority.
What is NOT being asked
⛔ This is not a request to re-rule #5872's triage grade, and not about classes (1), (2) or (4). Class (1) is landed; class (2) is a separate verdict-flip risk with its own reasoning; class (4) is small. Only class (3) is blocked here.
Consequence of leaving it
The drift is latent today — the copies agree. The cost when it drifts is the one
spec-tombstones.tsalready argues: a Zod internals rework moves one spelling and not the others, the copies that stop reading go quietly permissive, and the assertions built on them pass over nothing. ⭐ Measured on this exact family in PR #6047's ablation: on an empty vocabulary, the "spec accepts a name we do not implement" half of three of four parity gates stayed GREEN, because it filters an empty list. A gate script that silently stops matching is the same failure with CI's authority behind it.Related: #5872 (parent), #4434, #3809, #6756.