Repository navigation
Description
Filing gate ③, a maintainer-ruled duty: #22949 ruling E item 3 (6125775640) and #22998's test-budget rule, "a test file over 10 s of wall is a card for the owning lane". This is one lane's share of #23151, which asks triage to split its reading per owning lane.
Filed by the triage seat (seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U. ⛔ Not a claim. Part of #23151.
Reader who acts: the domain:devx seat. The packages below are this lane's in the pm-dispatch domain table.
The reading
From #23151, which takes it from the refresh run 38340176409 (measure-test-shard-timings --diff) over 20 hourly full-battery runs. Each row gives the file's slowest executed run in that window. Re-check: the next refresh PR's own list.
| package | files | slowest | file → seconds (run) |
|---|---|---|---|
@objectstack/example-showcase |
2 | 20.8 s | test/vitest-console-teardown-race.test.ts 20.8 s (38335967790)test/approval-resume-relation-expand.test.ts 10.2 s (38202645321) |
What done looks like
- Each file named above runs under 10 s of wall. The fix is to the test, or to what it waits on.
- ⛔ No deletion without a named duplicate (skills(ci): two-speed CI — fast set on PR and merge-queue runs, full battery hourly on main and before a release, main-red stops the lane, four required contexts plus the guard, timing gates report-only, test budgets not deletions #22998). ⛔ No timeout raise. ⛔ No move to a slower or skipped project to hide it.
- Pin: the next refresh PR's list no longer names the file.
- One PR per file or one per package, whichever the seat measures smaller. Each PR says which rows it closes.
Grade (triage)
tooling · priority:p3 · domain:devx · area:devpath, into pm:queue. It is maintainer-directed (#22949 ruling E), so the product-only queue rule's exemption applies.
- Lane:
examples/**test infrastructure isdomain:devxin the domain table.
Activity
objectstack-fleet commentedon Oct 13, 2026
Claim: PM loop round 11 ·
domain:devxseat 1 · 2026-10-13T12:00Z · triage-graded (priority:p3), part of #23151 under ruling E on #22949Session:
session_012zwsLMxQBwHUYJgPyrpEvxAccount:
zhuangjianguo(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-23185-showcase-slow-testsWorktree:
objectstack-issue-23185Domain:
domain:devxSeat:
domain:devx#1File surface:
examples/app-showcase/test/vitest-console-teardown-race.test.tsandexamples/app-showcase/test/approval-resume-relation-expand.test.ts, and what they wait on insideexamples/app-showcaseif the measured cause is there. ⛔ No deletion without a named duplicate, ⛔ no timeout raise, ⛔ no move to a slower or skipped project (the card's own bans)Container & model:
M,mode:subagent,model: opus(the default judgment tier)Clause-②: no (tests)
Responsibility: two showcase test files run 20.8 s and 10.2 s against a 10 s budget | no platform path covers it: the budget rule (#22998) names the owning lane | the hourly full battery pays the wall on every run
Thread-read: none
Serial constraints cleared: no open PR touches either test file (all open PRs' file lists read at this act).
objectstack-fleet commentedon Oct 13, 2026
os-dev-report
{
"issue": 23185,
"status": "done",
"branch": "claude/issue-23185-showcase-slow-tests",
"pr": "#23273",
"session": "session_012zwsLMxQBwHUYJgPyrpEvx — subagent run, so the parent's harness-stamped id (the Claude-Session trailer on every commit of the branch)",
"premise_still_valid": true,
"summary": "Both rows of the card, one PR for the package, with Fixes #23185. Both files now replace their clocks with sync points. (1) vitest-console-teardown-race: measured that the race has TWO vitest windows, (a) the worker's teardown sweep finding a pending console RPC and (b) the main process grading the worker's late rejection report before it arrives. A new harness reporter, test/fixtures/late-console-teardown/hold-console-acks.reporter.ts, holds (a) open deterministically: console log N is acked only when N+1 arrives, so the newest RPC is always pending at the sweep. It reads (b) instead of racing it: at child exit it writes the delivered rejection count beside the graded one to a verdict file passed via vitest's --outputFile option. Each leg now runs ONCE, where before it was up to 8 ablation attempts plus 4 guarded repetitions. The skip path is gone, and the premise probe gains a 6th marker (the cli-api console RPC handler awaits the reporters) with a matching control case. The fixture's first tick is now synchronous. (2) approval-resume-relation-expand: the stays-quiet watch ends on a settle point (the stranded run is failed and every sys_notification_delivery row is final) instead of waiting out the 5 s window, and asserts endedBy=settled. The fixed sleep(200) is gone, because decide() awaits the resume. Three clock-free contract cases were added. File walls are 2.2-3.2 s and 2.1-2.5 s even beside four concurrent vitest loops, against 6.3/7.3 s locally before and 20.8/10.2 s on CI. Every touched file is inside examples/app-showcase (the two tests, the fixture dir, and types/node-shim.d.ts gaining only the members imported). The PR body carries 'Clause-②: no' as the dispatch spelled it. The claim's '(tests)' suffix is not one of the declared arms, so it was not copied.",
"tests": "HEAD 5ea05a3 (the base was afbf960; main merged in, touching no file of this package). (a) cd examples/app-showcase && vitest run --maxWorkers=2 over the whole package: 'Test Files 33 passed (33) / Tests 412 passed (412)', 0 skipped. The box was loaded by the concurrent gate battery, and the two files read 2.95 s and 2.55 s in that run. (b) pnpm --filter @objectstack/example-showcase typecheck: exit 0, script name echoed; tsc --listFiles counts all 5 touched files. (c) The 39 families derived by node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 5ea05a3 were run, and --ran with recorded exit codes reads '39 derived, 38 run, 1 NOT-MEASURED, 0 UNRUN'. NOT MEASURED: pnpm check:dual-build-cjs-loads, reason: exit 3 PREREQUISITE NOT MET after its self-test passed (93 cases), because 8 packages outside the showcase closure (studio, client-react, embedder-openai, knowledge-memory, knowledge-ragflow, organizations, service-cluster-redis, service-knowledge) have no dist/ here and this diff changes no dist; CI reads it. Extra: node scripts/check-console-intercept-disarm.mjs OK (74 packages). (d) Lint as a proven narrowing: eslint --no-inline-config --format json over the 5 touched files reports 5 files, 0 errors, 0 warnings. eslint.config.mjs enables no type-aware linting (no parserOptions.project, no projectService), so untouched files' verdicts cannot move. (e) Before, at afbf960: the teardown pin took 6.34 s (ABLATION 2126 ms, GUARDED 4203 ms) and the approval file 7.30 s (its pre-fix case 5213 ms). After, at 53ed69f: the teardown pin took 2.2-2.5 s idle (5 runs) and 2.2-3.2 s beside four concurrent vitest loops (10 runs), green 15/15; the approval file took 2.19-2.30 s idle (3 runs) and 2.13-2.48 s under the same load (5 runs). (f) Ablations, all via node scripts/ablation-replace.mjs in wrap mode. Each showed anchor 1 to 0 and a changed blob; each restore showed the blob equal to HEAD and an empty git diff HEAD. Observed direction is red everywhere. A1, deleting disableConsoleIntercept: true from vitest.config.ts: GUARDED red 10/10 (5 idle, 5 loaded), verdict delivered=1. A2, the hold reporter returning Promise.resolve() (no hold), 12 loaded runs: ABLATION red 11/12, every one on the 'instrument' branch, never a skip. B1, the watch verdict read replaced by the pre-settle sample: 3 contract cases red. B2, the call site settling on completed instead of failed: the pre-fix case red on endedBy after paying the 5 s window (file 7.23 s). B3, inboxSettled dropping its outbox half: the 'both halves' contract red. (g) Prototype race measurements (a .mjs prototype of the same hold, one child per attempt): defaults without the hold reproduced 20/20 idle and 4/20 under 4 concurrent vitest loops; with the hold, rejections were 40/40 idle and 40/40 loaded (32/40 graded in time, which is window b); the app config with the hold gave 0/10; the guard re-armed via CLI with the hold gave 20/20. No build/dist ablation applies: the tests run source.",
"mcp_calls": "0 — no MCP GitHub tool called",
"api_writes": "3 — each a fleet-write relay stroke (POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): pr_create (POST /pulls draft, then POST /issues/23273/assignees zhuangjianguo; body read back byte-identical), labels_add skip-changeset (POST /issues/23273/labels; read back: size/l, tests, skip-changeset), and this report (POST /issues/23185/comments via post-stamped.mjs). 4 git pushes, which are not REST.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted, not filed — vitest's own window (b): a teardown rejection the worker reports after the pool settles is recorded but never graded (exit 0). This is upstream behaviour outside our contract, moot behind disableConsoleIntercept: true. It is in PR #23273's Acceptance notes.",
"carrier: none (承接者:无) · noted, not filed — examples/app-showcase/vitest.config.ts's disarm docblock and the scripts/check-console-intercept-disarm.mjs header still describe the race window as a single load-width span inside rpcDone(). The measured second window refines but does not contradict either prescription. It is in PR #23273's Acceptance notes."
]
}
objectstack-fleet commentedon Oct 13, 2026
Review: ACCEPT · PR #23273 (draft, head
5ea05a3201) ·domain:devxseat 1 ·session_012zwsLMxQBwHUYJgPyrpEvx· 2026-10-13T13:38ZChecked on GitHub, not on the report's say-so.
examples/app-showcase(+592 / −204):test/fixtures/late-console-teardown/hold-console-acks.reporter.ts;types/node-shim.d.ts, which only gains the members it imports.Fixes #23185. Labelssize/l,testsandskip-changeset, which is right for tests that ship in no dist. Not governed (0 of 5 paths), and no contract face is touched.--outputFile.disableConsoleIntercept: true, and the guard goes red 10/10, both idle and loaded.endedBy=settled. Ablations B1, B2 and B3 each go red on the case they should.check:dual-build-cjs-loads, because packages outside this closure have no dist here; CI reads it).5ea05a3201: 28 green, 10 skipped, 3 running, none red. The seat arms auto-merge.vitest.config.tsand thecheck-console-intercept-disarm.mjsheader still describe one race window, where two were measured. That refines them and does not contradict either.objectstack-fleet commentedon Oct 13, 2026
Landed: PR #23273 →
6c181625f9(Fixes #23185) ·domain:devxseat 1 ·session_012zwsLMxQBwHUYJgPyrpEvx· 2026-10-13T14:09Zmain, 5/5 files equal the PR head5ea05a3201.completedon the merge, andpm:dispatchedis removed with this record.main:vitest-console-teardown-race.test.tsandapproval-resume-relation-expand.test.tsreplace their clocks with sync points.