Uh oh!
There was an error while loading. Please reload this page.
test(cli): pin the conversions-only exit-code cell of os validate --json --strict - #11609
Conversation
…json --strict`
The documented cell — a config whose ONLY advisories are ADR-0087 D2 load-time
conversion notices exits 1 with `{ valid: true, warnings: [], conversions: [...] }`
— had never been exercised: every existing fixture raises zero conversions, so a
regression narrowing the gate back to the payload's `warnings` field would have
left the whole suite green.
Adds a minimal pair built from one template, differing in a single key on one
`page:header` component: `description` (the live `page-header-subtitle-alias`
window) against the canonical `subtitle`. The pin therefore discriminates on the
conversion rather than on the presence of a page.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019siH5jDmk5hrayvfyojUqR📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 32708418190 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
Uh oh!
There was an error while loading. Please reload this page.
os-zhuang
commented
Aug 24, 2026
Queue-failure triage — not this PR's; re-queueing onceRun 32708418190, Checklist item 2 — the failing test is not in a package this diff touches. This PR is one file, What the assertion actually says. The scaffolder's Why the probe is fragile in the queue, and why it is a pre-existing condition. The test's own Consistent with the bot's own signature ledger: no other PR hit this test in the 24h window, and no Action: re-queueing once, per the "at most one re-run to confirm" rule. If it reddens again on the Generated by Claude Code |
Fixes#11301
Test-only. Pins the one documented exit-code cell of
os validate --json --strictthat no fixture exercised.The unpinned cell
--strictgates on the text face's warning list, which folds in the ADR-0087 D2 load-time conversion notices. The JSON payload carries those notices separately, underconversions, and its ownwarningsfield is the five-way spread without them. So a config whose only advisories are conversion notices exits 1 carrying{ valid: true, warnings: [], conversions: [...] }.That is deliberate, and
commands/validate.tsstates the reasoning at theemitJsoncall. It was also the one cell where the exit code is decided by a collection absent from the payload field a reader reaches for first — and every existing fixture raises zero conversions, so a regression narrowing the gate back topayload.warningswould have restored the original divergence with the whole suite green.The behaviour was not on trial here and was not touched: no production file is in this diff.
The fixture is a minimal pair, not a single input
Both members come from one template,
headerPageSource(key), and differ in a single key on onepage:headercomponent:--json--json --strict--strict(text)validwarningsconversionsdescription(the livepage-header-subtitle-aliaswindow)true[]subtitle(canonical spelling)true[][]So the pin discriminates on the conversion, not on "a page is present". Both rows were measured before the test was written.
The issue's suggested candidate,
object-compactLayout-to-highlightFields, turned out to be unusable and the test comment records why: it is alreadyretiredFromLoadPath, so the schema tombstones the key and it raises a validation error, not a notice.page-header-subtitle-aliaswas selected from the 17 entries that are still live on the load path, and measured to raise no other advisory.Anti-vacuity
conversionsis asserted non-empty.page-header-subtitle-aliasretires from the load path at protocol 18; on that day the fixture raises nothing, and without that assertion the file would keep passing while pinning an empty cell — exactly the failure this card exists to remove. It goes red instead, with a message naming the remedy.Discrimination ablation (trap-restored, mutation proven on disk by grepping both the injected and the removed text, prediction recorded before the run):
headerPageSource('description')→headerPageSource('subtitle')inbeforeAll, making the fixture byte-identical to its canonical twin. Removed-text hits 1 → 0, injected-text hits 0 → 1, sha7cde9871…→391ebbd5….expect(text.code).not.toBe(0)) rather than on theconversionsguard, since the floor is asserted first in the body.Tests 1 failed | 5 passed (6),AssertionError: text --strict must fail on the conversions-only config: expected +0 not to be +0. The canonical control stayed green.7cde9871…, grep counts back to 1/0,git statusclean.Verification — all at
32ecb986pnpm --filter @objectstack/cli exec vitest run src/commands/validate-json-strict-exit.e2e.test.ts→Test Files 1 passed (1)/Tests 6 passed (6)pnpm --filter @objectstack/cli typecheck→tsc --noEmit, exit 0node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, not a hand-built list. All 11 matched + convention-triggered families green, includingcheck-i18n-bundles: OK (9 package(s) — all bundles in sync…),check-i18n-coverage: OK (12 config(s), 602 baselined untranslated string(s), none new).andcheck-type-check-coverage --re-measure: OK — 32 ledger entr(ies) re-measured…, none above its recorded number.check:i18nandcheck:i18n-coveragefirst refused (PREREQUISITE NOT MET — the workspace CLI is not built, "Nothing was checked"). Recorded as not measured, then measured for real afterturbo run build.No changeset
Nothing user-visible ships: the diff is one
packages/cli/src/**/*.test.tsfile, whichtsconfig.build.jsonexcludes from the published output.skip-changesetapplied.Note on #11599
check:cli-test-child-envis not in this branch's base and does not reach this diff either way — the file lives inpackages/cli/src/commands/, notpackages/cli/test/**. No baseline entry was added and no existing violating file was touched.Generated by Claude Code