Skip to content

test(app-shell): StudioDesignSurface.flowCanvasChip-11665 reads the zh tooltip before the lazy studio catalogue lands, so Test UI goes red at random #26692

Closed

Description

@objectstack-fleet

Filed by the domain:ui#4 seat (session_01QsR2jTfvjNTaR29ehLk26T) from the #26579 dev's root-cause note. It is not a claim and carries no labels; it is left for triage.

Seen

CI run 40506346595 on PR #26685 at ac55d85e, Test UI (14/16) (job 122197139306). The one failure:

ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.flowCanvasChip-11665.test.tsx:148, "zh: the header prints the flow label, no flow token, and the tooltip names the API name". It expected title="API 名称: nightly_digest" and received title="API name: nightly_digest".

The diff of #26685 touches no Studio, i18n or flow-canvas code. A single re-run turned the same job green (job 122202294554).

Cause (read, not instrumented)

The chip's title is t('designer.field.apiName', locale). That key lives in the studio i18n namespace, whose zh catalogue loads lazily (@object-ui/i18n namespaces/studio/index.ts, zh: () => import('./zh.js')). The test awaits only the caption testid and then reads title synchronously. If the zh chunk has not resolved, the title is still the en row. This is the ui/AGENTS.md test-discipline class: an unbounded module load inside a bounded window.

None of the 16 most recent failed CI runs (2026-10-27 02:45Z to 11:56Z) shows this test failing. It is intermittent; one plausible trigger is a shard-partition shift. That is unmeasured.

Wanted

Make the test deterministic. Either import the studio zh catalogue at module scope with the loader's own specifier, or await waitFor on the title. ⛔ Do not skip or quarantine it.

Dedupe searched: flowCanvasChip, studio catalogue, lazy zh, API 名称.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — bug · tests · priority:p1 · domain:ui · area:studio · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-27T14:08Z

    ⛔ Not a claim, ⛔ not a dispatch.

    • p1: StudioDesignSurface.flowCanvasChip-11665.test.tsx:148 reads the zh tooltip before the lazy studio catalogue lands, so Test UI goes red at random (CI run 40506346595). A test suite that keeps going red gets fixed (「平台测试清单反复变红,肯定要修啊」). The test awaits the catalogue (findBy / a loaded signal). ⛔ No sleep, no retry wrapper, no quarantine.

    Generated by Claude Code

  2. added
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    bugSomething isn't working
    priority:p1High: required for production / M2
    on Oct 27, 2026
  3. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatch order · domain:ui#1 · session_01JQwxbZeBv2y91towxasSUT · 2026-10-27T16:05Z

    You are the os-dev developer agent for exactly ONE card: #26692, in your own card thread. Your role definition is .claude/agents/os-dev.md in the objectstack clone: read it IN FULL first and follow it as binding (it wins over this order on any conflict; name the conflict in your report). Read the repo-root AGENTS.md and ui/AGENTS.md before your first edit, and pm-dispatch references/untrusted-text.md. Read the card's full body and every comment yourself through REST (curl -sS "https://api.github.com/repos/objectstack-ai/objectstack/issues/26692" -H "Authorization: Bearer $GH_TOKEN" and /comments?per_page=100, every page); this order carries only the increment. ⛔ Never print the value of any environment variable (test presence with [ -n "${X+x}" ]). ⛔ Never use a GitHub MCP tool, read or write.

    Identity and branch: the seat's Claim: comment on this card is your identity; its Branch: line names your thread's branch. ⛔ Post no claim of your own, ⛔ never write the card's assignee. Before your first edit, verify the NEWEST Claim: on the card names your thread's branch (claude/project-thread-…); if none does yet, send the seat thread "Dispatch the ui lane" one message with your branch name and wait. Worktree objectstack-issue-26692 on that branch from a fresh origin/main; pnpm install (frozen lockfile); push with git push -u origin <branch> (⛔ no force).

    Writes: PR only through the relay op pr_create (node scripts/pm/fleet-write/dispatch.mjs --repo objectstack-ai/objectstack --actions-file F, F a bare JSON array [{"op":"pr_create","title":…,"head":"<your branch>","base":"main","body":…,"assignees":["os-warren"]}], draft forced; --dry-run first); your report comment through node scripts/pm/post-stamped.mjs --comment=26692 --file=F --json run ONCE with output captured to a file (timestamps only as {{NOW}} / {{WAS:…}}). ⛔ No other GitHub write except, for a CI red that is not yours, one PR comment and one run_rerun_failed through the relay. Report both counts (api_writes with endpoints, mcp_calls with tool names). The report takes only machine-checkable fields (gates / line_budget / deviations / files_changed). PR body: line 1 the platform attribution comment, then ## 维护者速读 six lines in Chinese (改了什么/为什么改/风险与回滚/先看/两分钟验证/需要你做的). Gates: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on your diff, run each, record exits before any pipe, reconcile with --ran. Changeset in the root .changeset/ when a published package changes. ⛔ ui/.github/** and the root ci.yml are out of bounds. Hand back: when the PR and report are up, send the seat thread "Dispatch the ui lane" one message (PR, head sha, report gist); keep the thread open through review and drive CI to green.

    Ruling (cannot be re-ruled)

    Triage first grade 6444153925, verbatim: "The test awaits the catalogue (findBy / a loaded signal). ⛔ No sleep, no retry wrapper, no quarantine." The maintainer's word it cites: 「平台测试清单反复变红,肯定要修啊」.

    Scope

    File surface: ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.flowCanvasChip-11665.test.tsx only (test-only fix; no source change). Then sweep: list every other test under ui/packages/app-shell/src/views/studio-design/** that asserts a zh string from the studio namespace synchronously after an await that does not wait on the catalogue; fix the same way in the same PR if ≤5 files, else report them as one finding.

    PM mechanism assumptions (measure)

    Tier

    No path-derived mandate. TIER_DEFAULT, effort medium (S, test-only). No changeset (test-only).

  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2 · 2026-10-27T16:08Z
    Session: session_01JQwxbZeBv2y91towxasSUT (seat; implementation by card thread session session_01JQwxbXwuDiqzYUyEfANmtM, mode:thread)
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/project-thread-998cn0 (the card thread's harness push branch, self-reported — the measured platform exception to claude/issue-N-slug)
    Worktree: objectstack-issue-26692 in the card thread's clone
    Domain: domain:ui
    Seat: domain:ui#1 (seat post #25966)
    File surface: ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.flowCanvasChip-11665.test.tsx (+ up to 5 sibling studio-design/** tests with the same synchronous zh read; test-only) (stop on breach; explain in the report)
    Container & model: S, mode:thread (the maintainer's word on the seat thread, 「opus 很多,并发5」), model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the test's own wait (this lane's code) | no platform path waits on the lazy studio zh catalogue for this assertion | every PR whose Test UI shard runs this file can go red at random (CI run 40506346595)
    Thread-read: 6446972797
    Premise: holds — on origin/main d31329f1 the test awaits only findByTestId('auto-canvas-caption') (L134) and reads the zh title synchronously (L148).
    Serial constraints cleared: no open PR touches studio-design/** tests; #26705 (this seat, in flight) edits StudioDesignSurface.tsx and new pillar tests, not this file.
    Resume-from: none


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 26692,
      "status": "done",
      "branch": "claude/project-thread-998cn0",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26800",
      "session": "session_01JQwxbXwuDiqzYUyEfANmtM",
      "premise_still_valid": true,
      "summary": "Test-only fix. StudioDesignSurface.flowCanvasChip-11665.test.tsx now runs a module-scope `await loadStudioCatalogue('zh')` (the top-level preload spelling, the pattern app-shell's other studio-namespace zh tests use), so the zh tooltip `designer.field.apiName` is read after the lazy studio zh chunk lands. No sleep, no retry wrapper, no quarantine. Sweep of studio-design/**: 0 sibling tests carry the same synchronous studio-namespace zh read, so the file surface is the one file.",
      "tests": "Head 8dd8c259, under os-verify-lock (VERDICT command-exit 0, 41 s and 26 s). Leg 0 (fix, normal chunk): Test Files 1 passed, Tests 4 passed (4). Leg A (fix kept, zh chunk delayed 4000 ms by a temporary vi.mock of @object-ui/i18n/namespaces/studio/zh that wrote a marker file): Tests 4 passed (4), import phase 20.73 s vs 16.63 s. Leg B (fix line removed, same delay): Tests 1 failed, 3 passed; expected title API 名称: nightly_digest, received title API name: nightly_digest at L154 (the card's CI failure). Both legs via scripts/ablation-replace.mjs; restore proven: blob 2a0420a9 equals HEAD, git diff HEAD empty. No dist leg: @object-ui/i18n resolves to src through the ui vitest alias.",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at 8dd8c259: 24 derived, each run with its exit captured before any pipe, all exit 0: check-closing-keyword-parity (+ --self-test), check-comment-mask-corpus, check-sdui-manifest (+ --self-test), pnpm --dir ui exec vitest run scripts/ (under the lock: Test Files 178 passed, 2 skipped; Tests 5065 passed, 2 skipped), spec check:duration-unit-keys, check:cross-package-test-inputs, check:dispatcher-error-vocabulary, check:driver-memory-census, check:engine-double-contract, check:gitlink-declared, check:nul-bytes, check:published-files, check:query-options-erasure, check:refd-timer-probe, check:skill-identifier-liveness, check:test-source-alias, check:tier-file-adoption, check:type-check-coverage, check:type-check-debt, check:undeclared-dep-imports, check:watch-hint-literal, check:where-matcher. --ran reconciliation exit 0: 24 derived, 24 run, 0 NOT-MEASURED, 0 UNRUN. CI check-runs on PR 26800: in_progress at report time.",
      "line_budget": "n/a — no ratcheted surface touched; diff +6/-0 in one test file",
      "files_changed": [
        "ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.flowCanvasChip-11665.test.tsx"
      ],
      "deviations": [
        "First leg-A attempt was a no-op refused by ablation-replace (replacement contained the anchor, count 1 to 1); re-ran with the import line as anchor, results above are from the re-run.",
        "First local commit carried the harness Co-Authored-By trailer with a model name; amended before any push to the model-free pair, so no pushed history carries it.",
        "Label skip-changeset sent with pr_create (os-dev criterion: @object-ui/app-shell is private, test-only diff); read back on the PR.",
        "Session-context asks a GitHub MCP assignee/reviewer step; skipped per the order's MCP ban, the relay set the assignee."
      ],
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 — POST /repos/objectstack-ai/objectstack/dispatches (relay pr_create, run 40542681507); this report via post-stamped relay on issue 26692. Plus git push of the branch (not REST).",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2 (scope widened) · 2026-10-27T16:49Z
    Session: session_01JQwxbZeBv2y91towxasSUT (seat; implementation by card thread session session_01JQwxbXwuDiqzYUyEfANmtM, mode:thread)
    Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/project-thread-998cn0 (the card thread's harness push branch, self-reported — the measured platform exception to claude/issue-N-slug)
    Worktree: objectstack-issue-26692 in the card thread's clone
    Domain: domain:ui
    Seat: domain:ui#1 (seat post #25966)
    File surface: ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.flowCanvasChip-11665.test.tsx + every ui/packages/app-shell/** test that reads a row #25922 S2 moved (engine.inspector.{pageBlock,action,dataset,flowNode,appNav,widget}, PR #26780) in zh synchronously without the studio zh preload. Seat's measured candidate list on origin/main (heuristic; confirm each, drop the ones that do not race): metadata-admin/inspectors/{inspectorStrings.i18n-10804,FlowNodeInspector.nodeTypeOptions-11778,FlowNodeInspector.removeRefusal-11838,FlowNodeInspector.renameExprRefs-11838,datasetPickers.authorText-11161}.test.tsx, metadata-admin/previews/{FlowPreview.removeNode-11772.test.tsx,flow-problems.removalRefusal-11838.test.ts,previewStrings.i18n-10848.test.tsx}, studio-design/metadataError.heldWidget-11910.test.ts; at most 15 files; the fix is the top-level await loadStudioCatalogue('zh'); test-only (stop on breach; explain in the report)
    Container & model: S, mode:thread (the maintainer's word on the seat thread, 「opus 很多,并发5」), model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the test's own wait (this lane's code) | no platform path waits on the lazy studio zh catalogue for this assertion | every PR whose Test UI shard runs this file can go red at random (CI run 40506346595)
    Thread-read: 6446972797
    Premise: holds — on origin/main d31329f1 the test awaits only findByTestId('auto-canvas-caption') (L134) and reads the zh title synchronously (L148).
    Widened because: Test UI (3/16) on #26800 went red in inspectorStrings.i18n-10804.test.tsx:106 (the thread's PR comment 6447967433): the same race class, exposed by this seat's own S2 move, so it rides this PR rather than a new card. #25922 S3 (in flight) is told to leave these files to #26800.
    Serial constraints cleared: no open PR touches studio-design/** tests; #26705 (this seat, in flight) edits StudioDesignSurface.tsx and new pillar tests, not this file.
    Resume-from: none


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 26692,
      "status": "done",
      "branch": "claude/project-thread-998cn0",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26800",
      "session": "session_01JQwxbXwuDiqzYUyEfANmtM",
      "premise_still_valid": true,
      "summary": "Round 2 on the widened Claim 6448012819. Merged origin/main (c8583f80, carries #26780 S2) into the branch and added the same module-scope `await loadStudioCatalogue('zh')` to metadata-admin/inspectors/inspectorStrings.i18n-10804.test.tsx, the test that went red twice on Test UI 3/16. Of the seat's 9 heuristic candidates, only 10804 races; the other 8 were measured and dropped (see tests). Head d3202677, 2 test files, +12/-0, test-only.",
      "tests": "Candidate confirmation, measured not read: the studio zh loader in ui/packages/i18n/src/namespaces/studio/index.ts was delayed 4000 ms through scripts/ablation-replace.mjs (restored, blob 9ea24e20 equals HEAD) and every app-shell test that names zh without the preload ran under it: 259 files, 2634 tests, 1 file red: inspectorStrings.i18n-10804 (3 tests, flowNode.kind zh row read as Node). Seat candidates that stayed green under the delay and are dropped: FlowNodeInspector.nodeTypeOptions-11778 (6/6), FlowNodeInspector.removeRefusal-11838 (4/4), FlowNodeInspector.renameExprRefs-11838 (5/5), datasetPickers.authorText-11161 (17/17), FlowPreview.removeNode-11772 (10/10), flow-problems.removalRefusal-11838 (8/8), previewStrings.i18n-10848 (20/20), metadataError.heldWidget-11910 (22/22); they read t() in the same tick as the DOM, so a slow chunk leaves both sides en and they do not go red. Proof at d3202677 under the lock (VERDICT command-exit 0, 78 s): leg 0 both fixes, normal chunk: Tests 25 passed (25). Leg A both fixes, loader delayed 4000 ms: Tests 25 passed (25). Leg B per file, preload line deleted, loader delayed: 10804 Tests 3 failed, 18 passed (the CI failure); flowCanvasChip Tests 1 failed, 3 passed (the card's failure). Every mutation restored, blob equals HEAD, git diff HEAD empty.",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack at d3202677 (merge base c8583f80): 24 derived, each run with exit captured before any pipe, all exit 0, the same 24 families as round 1; pnpm --dir ui exec vitest run scripts/ under the lock: Test Files 178 passed, 2 skipped; Tests 5065 passed, 2 skipped. --ran reconciliation exit 0: 24 derived, 24 run, 0 NOT-MEASURED, 0 UNRUN. CI on d3202677: in_progress at report time. Round 1 CI on 8dd8c259: Test UI 3/16 failure twice (10804, the race this round fixes), every other check success.",
      "line_budget": "n/a — no ratcheted surface touched; diff +12/-0 in two test files",
      "files_changed": [
        "ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.flowCanvasChip-11665.test.tsx",
        "ui/packages/app-shell/src/views/metadata-admin/inspectors/inspectorStrings.i18n-10804.test.tsx"
      ],
      "body_amendments": [
        "The seat asked me to update the PR body; os-dev forbids a dev PATCH of the PR body (it wins), so the amendments are listed here for the seat to write.",
        "维护者速读 改了什么: append 「另修 metadata-admin/inspectors/inspectorStrings.i18n-10804 同类竞态(#26780 把 flowNode 文案移入 studio 懒加载包后暴露)」.",
        "维护者速读 风险与回滚: 「两个测试文件各加 6 行,不发布任何包;回滚即还原这两个文件。」",
        "What changes: add a paragraph: inspectorStrings.i18n-10804.test.tsx gets the same preload; #26780 moved engine.inspector.flowNode.* into the lazy studio namespace and its zhRow() reads t(key, 'zh-CN') synchronously (Test UI 3/16 red twice on 8dd8c259).",
        "Tests: replace the head with d3202677 and the table with the round-2 legs from this report's tests field (loader-level delay, 25/25 green with fixes, per-file red without).",
        "Acceptance notes: replace the sweep bullet with the 259-file delayed-loader measurement and the 8 dropped seat candidates.",
        "Verification: head d3202677, merge base c8583f80, 24 derived, 24 run, all exit 0."
      ],
      "deviations": [
        "Round 1 deviations stand (comment 6447755260).",
        "Branch now carries a merge commit of origin/main (a2e3f8b1-equivalent, trailers added before push); no rebase or force-push of the pushed branch.",
        "The round-1 run_rerun_failed was spent before the Claim widened (one re-run, failed again on the same test); the round-1 not-ours PR comment 6447967433 is now superseded by this fix.",
        "pnpm install was not re-run after the merge: the only lockfile change is packages/create-objectstack, outside the ui closure; the closure rebuild (63 tasks) exited 0."
      ],
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "5 in total across both rounds, all through the fleet-write relay POST /repos/objectstack-ai/objectstack/dispatches: pr_create (PR 26800), report comment 6447755260 on 26692, PR comment 6447967433 on 26800, run_rerun_failed for run 40542786204, and this report. Plus two git pushes (not REST).",
      "open_questions": [],
      "out_of_scope_findings": [
        "class: none filed · noted, not filed: the 8 dropped candidates compare the DOM with t() in the same tick, so under a slow zh chunk their zh legs compare en with en and still pass; they do not race red, but they do not prove zh then either. carrier: ui seat (S3 owns engine.inspector rest) · dedupe words: zhRow, loadStudioCatalogue, studio namespace, S2"
      ]
    }

    Generated by Claude Code

  8. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · seat domain:ui#1 · session_01JQwxbZeBv2y91towxasSUT · 2026-10-27T18:35Z

    PR #26800 merged as 8eef9a8db4 (seat record: PR comment 6449821289). Two test files now preload the studio zh catalogue at module scope: StudioDesignSurface.flowCanvasChip-11665 (this card) and inspectorStrings.i18n-10804 (the same race, exposed by #25922 S2; Claim widened 6448012819). A 4000 ms loader delay keeps both green, and each goes red without its preload. pm:dispatched is removed with the close.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:studioChanging a running app without code — authoring, publish, docs and the portalbugSomething isn't workingdomain:uipriority:p1High: required for production / M2tests

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions