Observed 2026-09-05 on a fresh worktree of main at d701e657d7 while running the derived gate family for PR #15848 (dev seat, session session_019RfFHiRCSs3JXLK4cwcfox). Filed unassigned for triage; out of scope for that PR (a governed two-file prose change).
What happened
pnpm --filter @objectstack/lint run check:doc-formula-expressions on a freshly installed, unbuilt worktree:
- First run: exit 3,
PREREQUISITE NOT MET — the workspace package @objectstack/formula is not built, with Fix: pnpm exec turbo run build --filter=@objectstack/formula.
- After running exactly that fix (through the verify lock;
Tasks: 2 successful, 2 total): exit 3 again, PREREQUISITE NOT MET — the workspace package @objectstack/lint is not built.
- Only after
pnpm exec turbo run build --filter=@objectstack/lint (4 tasks, which includes formula) does the gate measure: ✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 428 files / 1370 TS blocks judged clean.
The refusal contract itself is right (exit 3, "Nothing was measured", the sibling convention that #15328 and #15835 hold other gates to). The gap is narrower: the printed fix is one build short on the tree the gate is most often run on cold, so a dev following the gate's own instruction gets a second refusal and pays a second lock round.
Where
packages/lint/scripts/check-doc-formula-expressions.mjs awaits requireDependency('@objectstack/formula', …) at line 15 and requireDependency('@objectstack/lint', …) at line 20, sequentially; scripts/import-prerequisite.mjs refuses on the first unmet call (Fix: ${verdict.fix} at line 691), so a gate with two compiled prerequisites can only ever name the first one.
Options
- A. Resolve both prerequisites before refusing, and print one fix that names the closure —
pnpm exec turbo run build --filter=@objectstack/lint builds formula as a dependency, so the closure fix is a single command.
- B. Keep the helper as is and have this gate order its two awaits so the outer package (
@objectstack/lint) is checked first; its turbo build carries formula, so the first printed fix is sufficient.
- C. Leave as is (two rounds on a cold tree; correct, just slow).
Recommendation: A if import-prerequisite.mjs has other multi-prerequisite callers (a helper-level fix closes the class); B if this gate is the only one. Either is a message change, not a verdict change — the self-test that pins the refusal wording is the place to pin the closure spelling.
Generated by Claude Code
Observed 2026-09-05 on a fresh worktree of
mainatd701e657d7while running the derived gate family for PR #15848 (dev seat, sessionsession_019RfFHiRCSs3JXLK4cwcfox). Filed unassigned for triage; out of scope for that PR (a governed two-file prose change).What happened
pnpm --filter @objectstack/lint run check:doc-formula-expressionson a freshly installed, unbuilt worktree:PREREQUISITE NOT MET — the workspace package @objectstack/formula is not built, withFix: pnpm exec turbo run build --filter=@objectstack/formula.Tasks: 2 successful, 2 total): exit 3 again,PREREQUISITE NOT MET — the workspace package @objectstack/lint is not built.pnpm exec turbo run build --filter=@objectstack/lint(4 tasks, which includes formula) does the gate measure:✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 428 files / 1370 TS blocks judged clean.The refusal contract itself is right (exit 3, "Nothing was measured", the sibling convention that #15328 and #15835 hold other gates to). The gap is narrower: the printed fix is one build short on the tree the gate is most often run on cold, so a dev following the gate's own instruction gets a second refusal and pays a second lock round.
Where
packages/lint/scripts/check-doc-formula-expressions.mjsawaitsrequireDependency('@objectstack/formula', …)at line 15 andrequireDependency('@objectstack/lint', …)at line 20, sequentially;scripts/import-prerequisite.mjsrefuses on the first unmet call (Fix: ${verdict.fix}at line 691), so a gate with two compiled prerequisites can only ever name the first one.Options
pnpm exec turbo run build --filter=@objectstack/lintbuilds formula as a dependency, so the closure fix is a single command.@objectstack/lint) is checked first; its turbo build carries formula, so the first printed fix is sufficient.Recommendation: A if
import-prerequisite.mjshas other multi-prerequisite callers (a helper-level fix closes the class); B if this gate is the only one. Either is a message change, not a verdict change — the self-test that pins the refusal wording is the place to pin the closure spelling.Generated by Claude Code