Uh oh!
There was an error while loading. Please reload this page.
test(spec): end the publish-smoke collision harness with exit 0 - #10916
Merged
Conversation
The harness had `set +e +o pipefail` after sourcing publish-smoke.sh but no trailing `exit 0`, so its exit status was whatever the last command returned — and every case ends by killing its stubs. Reaping a stub that has already exited returns 1, execFileSync then throws, and the failure arrives as a bare `Command failed` with the vacuity guard that would have named the problem never reached. This is the second half of the reporting fix PR #10456 landed for the sdui sibling; this file had only the first. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B4h3medzvhB9rpfoja9jcw
Contributor
📓 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. |
This was referenced Aug 21, 2026
os-elon
marked this pull request as ready for review
August 21, 2026 17:37
Uh oh!
There was an error while loading. Please reload this page.
Contributor
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 32509184310 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#10671
Finishes the reporting fix PR #10456 landed for the sdui sibling. That PR shipped
set +eand a trailingexit 0; this file has carried only the former since it was written. PR #10684 (this file's THIEF fix) is where the missing half was measured and filed.What changed
runHarnessbuilds the harness body and hands it toexecFileSync, so the harness's exit status decides whether the test body gets to run its assertions at all. Every case in this file ends by killing its stubs:Reaping a stub that has already exited returns 1. The
set +e +o pipefailat:184stops that from aborting the harness mid-line — which is all it buys — but it does not stop it from becoming the harness's exit status.execFileSyncthen throws in the test body and the failure arrives as a bareCommand failed, pre-empting the vacuity guard written to name the real problem.One line, at the end of the harness body:
'exit 0'. The harness's exit status is not a measurement; every measurement is a printedKEY=VALUEline and the assertions grade those.The
exit 0sits after the body but thetrap … EXITat:189still runs, and a trap that does not itself exit leaves the status alone — so the stubs are still reaped and 0 is still whatexecFileSyncsees. Measured, not assumed: it is what makes the after-fix leg below report an assertion rather thanCommand failed.Positive control — the card's two shapes, reproduced on one rig
Mutation: the HOLDER stub in "picks a per-run port and skips one that is already held" exits early, so the vacuity guard has an empty value to name and the cleanup
killreaps a dead pid. Same mutation both legs; the only difference is whether the harness endsexit 0.Before the fix — the card's captured shape, assertion never reached:
After the fix — the report the file's guards were written to produce:
Firing first is the point. With no holder,
smoke_pick_free_portlegitimately returns the same port andexpect(r.SECOND).not.toBe(r.FIRST)at:261would fail too — which reads as "the picker hands back busy ports", the misdiagnosis this file's header warns about. The guard names the real problem instead.Both legs confirmed on disk by grepping for the injected and the removed spelling — never by the editor's exit code: mutation leg
injected=1 removed=0, restore legmutated=0 original=1, restore driven bytrap … EXIT INT TERMso a mid-run kill could not leave a mutated tree behind for later measurements. No rebuild leg is involved, re-derived rather than inherited from the sibling PR: the file's whole import list isvitestplusnode:child_process/node:fs/node:os/node:path/node:url— no@objectstack/*specifier resolving through a packageexports/dist—pnpm --filter '@objectstack/spec^...' buildreportsNo projects matched the filters, andpackages/specdeclares no workspace dependency at all.The
HTTP_STUBerror guard — judged, and deliberately NOT takenThe card raised this as a separate judgement: give the four fixed-port
HTTP_STUBusers thes.once("error", …)guardOWNED_HTTP_STUBalready carries. Measured, and left out — it changes nothing the harness can observe.Every one of
HTTP_STUB's four call sites (:229,:266,:269,:296) spells>/dev/null 2>&1. Against that spelling, with a squatter forcing the stub to lose its bind:killrcThe two forms are indistinguishable to the harness. The only difference is a stack trace on a stream nothing reads, and neither form changes the exit status or the dead-pid
killthat was making the failure illegible. What made a lost bind report asCommand failedwas never the trace — it was the missingexit 0, which is what this PR fixes; four inert guards on top would not have reported it.Not unsafe, then — inert, so the card's stated condition for inclusion ("changes the failure shape the right way") is not met, and adding it would be speculative surface. The measurement is recorded in
HTTP_STUB's docblock rather than only here, because the file now visibly raises the question: a reader comparing the two stubs would otherwise close the asymmetry on symmetry grounds alone.Fences, each checked
scripts/publish-smoke.shnorscripts/gen-sdui-manifest.shis in this diff.git diff --name-onlyreturns exactly one path. Both shell scripts were read only.127.0.0.1probe asymmetry is untouched. This diff adds nolistenhost argument and no probe change; Two port-reservation registries now run the same protocol in different directories — convergesdui_pick_free_portandsmoke_pick_free_portonto one helper #10261 stays as recorded.expect(line is added or removed anywhere in the diff — the change is one'exit 0'string plus comments.set +e +o pipefailwas not touched, and remains at:184with its original comment.Changeset
None owed, re-derived rather than assumed.
@objectstack/specpublishesfiles: ["dist","json-schema","liveness","prompts","llms.txt","README.md","src/**/*.zod.ts","CHANGELOG.md","api-surface","spec-changes.json"]—scripts/is not among them, so this file reaches no published surface. Tests-only goes through theskip-changesetlabel in this repo, applied to this PR (the label is a real mechanism here, per PR #10684).Evidence
All at HEAD
374697959e, clean tree:Gates
Re-derived against the real diff with
node scripts/pm/dispatch-gates.mjs(it took the change set from the merge base itself,7e75dc701), all run at374697959e. 12 path-matched + 5 convention-triggered, quoting each gate's own verdict line rather than a bare$?:Each
pnpm --filtergate was checked for the zero-match trap — a filter matching no script exits 0 having run nothing — by confirming the> @objectstack/spec@17.1.0 …banner is present in its log. All four show it.Three narrowings, declared:
check:type-check-debtandcheck-dev-prereqswere NOT MEASURED, not "not applicable". Both refuse outright on an unbuilt worktree —--re-measure cannot run: 55 workspace dependenc(ies) … have no built type entry point on disk, andcheck-dev-prereqsendsFix: pnpm build. That refusal is the gates working as designed (measuring from an unbuilt closure would record a different world), not a verdict about this diff. CI runs both against a built tree. The ratchet half of the former is the same ledgercheck:test-typecheckreported unchanged above.pnpm lintis CI's run. Narrowed to the changed file, and the narrowing is measured rather than asserted: the file is in ESLint's own population (isPathIgnored→false, config resolved with 4 rules);lintFilesreports 1 file linted, 0 errors, 0 warnings, 0 suppressed; and the diff cannot move any untouched file's verdict because type-aware linting is not enabled anywhere here —calculateConfigForFilereportsparserOptions.project: nullandprojectService: null.Generated by Claude Code