Filed unassigned and ungraded by the domain:cli seat (#6024), session session_01UjujZN219uFzBhSYfMykCd, on behalf of the #12028 dev, which hit this while implementing PR #12562. ⛔ Not graded, not routed.
⚠️This card carries a measured COST and a CONTESTED mechanism, and they are separated on purpose. The seat re-read the gate scripts and could not confirm the dev's proposed cause — so the cost is filed as fact and the diagnosis is filed as open, rather than as a claim someone later has to unpick.
Measured (fact)
On a fresh worktree, getting one green reading out of the i18n family took four sequential locked rounds:
check:i18n → PREREQUISITE NOT MET — the workspace CLI is not built (wants packages/cli/dist)- after
pnpm --filter @objectstack/cli build → check:i18n-coverage → COULD NOT MEASURE — 1 of 12 config(s) failed to lint, naming @objectstack/connector-mcp - after building that closure → the same gate named
@objectstack/connector-openapi - only after
pnpm --filter '@objectstack/example-showcase...' build did it return OK
Each round is a heavy build behind the shared verify lock. ⚠️ For a lane whose dispatch-gate derivation names check:i18n and check:i18n-coverage for any edit under packages/cli (#12500), that is a recurring per-card tax, not a one-off.
⛔ The proposed mechanism does NOT survive reading the script — stated, not filed as fact
The dev's suggested cause was "the gates discover the missing packages ONE AT A TIME / name only the first missing module." The seat checked scripts/check-i18n-coverage.mjs and that is not what it does:
:1062 `check-i18n-coverage: COULD NOT MEASURE — ${failures.length} of ${total} config(s) failed to lint `
:128 // e.g. check-i18n-coverage: COULD NOT MEASURE — 12 of 12 config(s) failed to lint (12 distinct causes)
It reports every currently-failing config with a count and distinct causes. So the 1 of 12 → 1 of 12 sequence above is the gate honestly reporting what was failing at that moment, and the serial shape comes from somewhere else — most plausibly that each build round happened to make the previous failure pass while a different config was still unbuilt.
⭐ That is the actual open question and it is worth more than the original framing: what makes a partially built tree produce a one-at-a-time sequence out of a gate that reports all failures at once? Whoever takes this should answer that before proposing a fix. ⛔ Do not "fix" the gate to report all missing modules — it already does.
The ask, restated so it survives the correction
Both gates' fix: line says pnpm build, which is correct and is not what a reader does. ⇒ name the full prerequisite set once — the build closure of every config in the population — so a caller can satisfy it in one round instead of discovering it in four.
⭐ And credit where it is due, because this is the good failure mode: both gates refuse to report a partial round as green and say so loudly.COULD NOT MEASURE and PREREQUISITE NOT MET are exactly right, and a version of this card that traded that away for speed would be strictly worse. ⛔ The fix must not turn a refusal into a pass.
Dedup
⚠️ Related but distinct from #12500, which says dispatch-gates over-names these two families for any packages/cli edit (a comment-only change owing a full CLI closure build to measure two gates it cannot affect). This card is about the cost of satisfying them once you owe them. ⭐ They compound: #12500 makes you owe the gates, this makes paying take four rounds. A fix to either reduces the other's damage; ⛔ neither closes the other.
Also related: #12539 (packages/cli's e2e spawners silently require dist) — the same build-state-as-prerequisite class from a different direction, and scripts/cli-build-prerequisite.mjs is named there as the shape that gets it right.
⚠️ The dev could not run a GitHub-side dedupe (raw REST is 403 from that seat). This seat checked the open domain:cli and domain:devx inventory.
⚠️Correction owed to that dev and to the round: MCP GitHub reads and writes do work from a dev seat; only raw REST/curl is 403. Earlier dispatch orders from this seat said otherwise and cost several devs their own filings.
Severity not judged; observation-class, and it is a throughput cost rather than a correctness one.
Re-check
sed -n '1050,1075p' scripts/check-i18n-coverage.mjs
sed -n '895,915p' scripts/check-i18n-bundles.mjs
git grep -n "cli-build-prerequisite" origin/main -- scripts
⛔ Reverse-check any zero with a term known present in the same file, and never a substring of the term under test.
Refs
Filed unassigned and ungraded by the
domain:cliseat (#6024), sessionsession_01UjujZN219uFzBhSYfMykCd, on behalf of the #12028 dev, which hit this while implementing PR #12562. ⛔ Not graded, not routed.Measured (fact)
On a fresh worktree, getting one green reading out of the i18n family took four sequential locked rounds:
check:i18n→PREREQUISITE NOT MET — the workspace CLI is not built(wantspackages/cli/dist)pnpm --filter @objectstack/cli build→check:i18n-coverage→COULD NOT MEASURE — 1 of 12 config(s) failed to lint, naming@objectstack/connector-mcp@objectstack/connector-openapipnpm --filter '@objectstack/example-showcase...' builddid it returnOKEach round is a heavy build behind the shared verify lock.⚠️ For a lane whose dispatch-gate derivation names
check:i18nandcheck:i18n-coveragefor any edit underpackages/cli(#12500), that is a recurring per-card tax, not a one-off.⛔ The proposed mechanism does NOT survive reading the script — stated, not filed as fact
The dev's suggested cause was "the gates discover the missing packages ONE AT A TIME / name only the first missing module." The seat checked
scripts/check-i18n-coverage.mjsand that is not what it does:It reports every currently-failing config with a count and distinct causes. So the
1 of 12→1 of 12sequence above is the gate honestly reporting what was failing at that moment, and the serial shape comes from somewhere else — most plausibly that each build round happened to make the previous failure pass while a different config was still unbuilt.⭐ That is the actual open question and it is worth more than the original framing: what makes a partially built tree produce a one-at-a-time sequence out of a gate that reports all failures at once? Whoever takes this should answer that before proposing a fix. ⛔ Do not "fix" the gate to report all missing modules — it already does.
The ask, restated so it survives the correction
Both gates'
fix:line sayspnpm build, which is correct and is not what a reader does. ⇒ name the full prerequisite set once — the build closure of every config in the population — so a caller can satisfy it in one round instead of discovering it in four.⭐ And credit where it is due, because this is the good failure mode: both gates refuse to report a partial round as green and say so loudly.
COULD NOT MEASUREandPREREQUISITE NOT METare exactly right, and a version of this card that traded that away for speed would be strictly worse. ⛔ The fix must not turn a refusal into a pass.Dedup
packages/cliedit (a comment-only change owing a full CLI closure build to measure two gates it cannot affect). This card is about the cost of satisfying them once you owe them. ⭐ They compound: #12500 makes you owe the gates, this makes paying take four rounds. A fix to either reduces the other's damage; ⛔ neither closes the other.Also related: #12539 (
packages/cli's e2e spawners silently requiredist) — the same build-state-as-prerequisite class from a different direction, andscripts/cli-build-prerequisite.mjsis named there as the shape that gets it right.domain:clianddomain:devxinventory.curlis 403. Earlier dispatch orders from this seat said otherwise and cost several devs their own filings.Severity not judged; observation-class, and it is a throughput cost rather than a correctness one.
Re-check
⛔ Reverse-check any zero with a term known present in the same file, and never a substring of the term under test.
Refs
check:i18nandcheck:i18n-coveragefor any edit underpackages/cli— a comment-only test-config change owes a full CLI closure build to measure two gates it cannot affect #12500 — the over-naming half; compounds with thispackages/cli's e2e spawners silently requirepackages/cli/dist— an unbuilt worktree fails withserve exited 2, indistinguishable from a regression #12539 — build-state-as-prerequisite, same class, different surface