You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
i18n tests: the studio zh-only key families are listed twice (studio-namespace pin and the app-shell ZH_ONLY_REASONS pin) with nothing asserting they agree #27250
Filed by seat domain:ui#1 (seat post #25966, session_01JQwxbZeBv2y91towxasSUT) from the one should-fix in triage's contract review of PR #27136 (comment 6469007202, #25922 S7). It was left out of #27136 so the PASS stayed pinned to its head. ⛔ Not a claim. Triage grades and routes.
What is there (measured on origin/main after 9ff8154cf6)
ui/packages/i18n/src/__tests__/studio-namespace.test.ts:43 declares ZH_ONLY_FAMILIES = ['engine.flowNode.', 'engine.enum.type.', 'engine.packages.form.help.'] and reds on a zh-only key outside them.
ui/packages/app-shell/src/views/metadata-admin/inspectors/inspectorStrings.studioNamespace-25922.test.ts:156 declares ZH_ONLY_REASONS (prefix + reason + citation anchor), and :243 reds on a zh-only key outside its prefixes.
Before S7 the one list lived in check-i18n-designer-table-parity.mjs; S7 retired that gate and the list now has two homes.
Why it matters
Both pins fail closed, so no coverage is lost today. But a later slice can widen one list and not the other, and the two pins would then disagree about which zh-only keys are allowed.
Wanted
One home: derive one list from the other, or add a one-line equality assertion between them. Tests only, no runtime change.
Read fresh. After refactor(app-shell): retire the designer string table and its parity gate #27136 (S7) retired check-i18n-designer-table-parity.mjs, the studio zh-only key families live in two test pins: ZH_ONLY_FAMILIES in ui/packages/i18n and ZH_ONLY_REASONS in ui/packages/app-shell. Nothing checks that the two lists agree.
Both pins fail closed, so no coverage is lost today. It is tests only, with no runtime effect, so p3.
⛔ One home: one list is derived from the other, or a single equality assertion is added. No new gate script.
Dispatch order · domain:ui#1 · session_01JQwxbZeBv2y91towxasSUT · 2026-10-28T13:31Z
You are the os-dev developer agent for exactly ONE card: #27250, 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/NNNNN" -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-27250 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=27250 --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 grade (2026-10-28 13:15Z, triage#1): p3, domain:ui, area:i18n. The card is the one should-fix of triage's contract review of PR #27136 (6469007202): "a one-line equality assertion, or deriving one from the other, would keep them from drifting apart". No maintainer ruling needed.
PM mechanism assumptions (measure on origin/main after 1e8e5296; disproof welcome)
ui/packages/i18n/src/__tests__/studio-namespace.test.ts:43ZH_ONLY_FAMILIES (three prefixes) and ui/packages/app-shell/src/views/metadata-admin/inspectors/inspectorStrings.studioNamespace-25922.test.ts:156ZH_ONLY_REASONS (prefix + reason + citation anchor) hold the same family set.
The direction of the dependency matters: @object-ui/app-shell depends on @object-ui/i18n, never the reverse. So the one home is on the i18n side (export the family list from a test-support module the app-shell pin can import, or keep both and have the app-shell pin assert ZH_ONLY_REASONS prefixes equal the i18n list). ⛔ No runtime export added to @object-ui/i18n's public entry for a test-only list; if the only clean home would be a public export, take the equality-assertion route instead and say why.
Scope
File surface: the two test files (+ a test-support module if you take that route). Tests only, no runtime change. Ablation: add a fourth prefix to one list only ⇒ a pin goes red. Stay under 150 changed lines.
Tier
Quote dispatch-gates --tier on your surface. Expected none. TIER_DEFAULT, effort low. Clause-②: no, Metadata-protocol: none. Tests only: skip-changeset. Fixes #27250.
Claim: PM loop round 22 · 2026-10-28T13:34Z
Session: session_01JQwxbZeBv2y91towxasSUT (seat; implementation by card thread session session_01JQwxban7wCJnPiiSY4ULYz, mode:thread)
Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/project-thread-qipkqe (the card thread's harness push branch, self-reported — the measured platform exception to claude/issue-N-slug)
Worktree: objectstack-issue-27250 in the card thread's clone
Domain: domain:ui
Seat: domain:ui#1 (seat post #25966)
File surface: ui/packages/i18n/src/__tests__/studio-namespace.test.ts + ui/packages/app-shell/src/views/metadata-admin/inspectors/inspectorStrings.studioNamespace-25922.test.ts (+ an i18n-side test-support module if that route is taken); ⛔ any runtime export (stop on breach; explain in the report)
Container & model: S, mode:thread (the maintainer's word: 3 active card threads per seat, 2026-10-28 10:00Z / 12:11Z), model: TIER_DEFAULT (the dev quotes dispatch-gates --tier on the surface), effort: low
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — tests-only follow-up of contract review 6469007202 (PR #27136)
Thread-read: 6470346819
Premise: holds — on origin/main after 1e8e5296, ZH_ONLY_FAMILIES (i18n pin :43) and ZH_ONLY_REASONS (app-shell pin :156) hold the same three prefixes with no equality check.
Serial constraints cleared: #25922 is complete (S7 #27136 merged); no open PR edits either file.
Resume-from: none
{
"issue": 27250,
"status": "done",
"branch": "claude/project-thread-qipkqe",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27289",
"head": "37238cc1",
"session": "session_01JQwxban7wCJnPiiSY4ULYz",
"premise_still_valid": true,
"summary": "Premise held on origin/main 1e8e5296: ZH_ONLY_FAMILIES (i18n studio-namespace pin) and ZH_ONLY_REASONS (app-shell inspectorStrings.studioNamespace-25922 pin) held the same three prefixes with no equality check. The list now lives once in an i18n test-support module, ui/packages/i18n/src/__tests__/studio-zh-only-families.ts (STUDIO_ZH_ONLY_FAMILIES; under __tests__, excluded from the build, no exports-map change). The i18n pin reads it; the app-shell pin imports it by relative path (app-shell to i18n direction kept, precedent plugin-designer importing plugin-grid src/__tests__/explainDouble) and adds one case asserting the sorted ZH_ONLY_REASONS prefixes equal the sorted list. Tests only, no runtime change.",
"tests": "pnpm --dir ui exec vitest run on both pin files: Test Files 2 passed (2), Tests 201 passed (201). Ablation via scripts/ablation-replace.mjs, two legs, each anchor x1 to x0 and blob moved on disk: (a) fourth prefix in STUDIO_ZH_ONLY_FAMILIES only -> Tests 1 failed | 200 passed (201), failure = 'a reason is given for exactly the families the i18n pin allows'; (b) fourth entry in ZH_ONLY_REASONS only, valid anchor -> Tests 1 failed | 201 passed (202), same single failure. After both: git diff HEAD empty, both blobs equal HEAD blobs (dfe1a88f, 138a6f73). No dist leg: both pins import their subjects by relative path or the vitest src alias.",
"gates": "head 37238cc1, merge base 1e8e5296. dispatch-gates --commands derived 24; all 24 run, every one exit 0; dispatch-gates --ran: 24 run, 0 NOT-MEASURED, 0 UNRUN. Owed beyond the list: pnpm --filter @object-ui/i18n run type-check exit 0; pnpm --filter @object-ui/app-shell run type-check exit 0 (tsconfig.test.json compiles the cross-package import); pnpm --dir ui run check:new-line-citations exit 0 (0 new citations). CI check-runs: in_progress at report time. Tier: dispatch-gates --tier = no path-derived mandate (TIER_DEFAULT). Changed lines 34 (+26 / -8).",
"line_budget": "34 changed lines vs the 150 cap",
"files_changed": [
"ui/packages/i18n/src/__tests__/studio-zh-only-families.ts (new)",
"ui/packages/i18n/src/__tests__/studio-namespace.test.ts",
"ui/packages/app-shell/src/views/metadata-admin/inspectors/inspectorStrings.studioNamespace-25922.test.ts"
],
"deviations": [
"pnpm install --frozen-lockfile exited 1 twice: better-sqlite3 node-gyp rebuild aborted mid-download of the node headers through the proxy. Installed with --frozen-lockfile --ignore-scripts and ran the root prepare script (node scripts/setup-git-hooks.mjs) by hand; no test or gate in this card loads better-sqlite3.",
"PR template headings folded into the os-dev order (What changes / Why / Tests / Acceptance notes / Verification / Human Minimum), the os-dev exception.",
"Session-context MCP assignee/reviewer step skipped: the relay set the assignee; requested_reviewers read back empty."
],
"dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm",
"mcp_calls": "1: mcp__claude-code-remote__subscribe_pr_activity (PR 27289), not a GitHub MCP tool; 0 GitHub MCP calls",
"api_writes": "2 through the fleet-write relay: pr_create (POST pulls, PR 27289, with assignee os-warren and label skip-changeset); this os-dev-report comment (POST issues/27250/comments). git push is not a REST write.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed: ZH_ONLY_FLOOR in the app-shell pin keys a floor by 'engine.enum.' rather than 'engine.enum.type.'; it holds counts, not the allowed set, so it is outside the equality and was left as is (PR Acceptance notes)."
]
}
PR #27289 merged as bf01226b62 (seat record on the PR). The zh-only family list now lives once in ui/packages/i18n/src/__tests__/studio-zh-only-families.ts (STUDIO_ZH_ONLY_FAMILIES), and the app-shell pin asserts that the ZH_ONLY_REASONS prefixes equal it, so the two lists can no longer drift apart. Fixes #27250 closed this card. The claim is released: pm:dispatched comes off.
Activity
objectstack-fleet commentedon Oct 28, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Triage:
domain:ui, p3,area:i18n· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-28T13:15Z⛔ Not a claim.
check-i18n-designer-table-parity.mjs, the studio zh-only key families live in two test pins:ZH_ONLY_FAMILIESinui/packages/i18nandZH_ONLY_REASONSinui/packages/app-shell. Nothing checks that the two lists agree.tests,pm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Dispatch order ·
domain:ui#1·session_01JQwxbZeBv2y91towxasSUT· 2026-10-28T13:31ZYou are the os-dev developer agent for exactly ONE card: #27250, in your own card thread. Your role definition is
.claude/agents/os-dev.mdin 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-rootAGENTS.mdandui/AGENTS.mdbefore your first edit, and pm-dispatchreferences/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/NNNNN" -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; itsBranch:line names your thread's branch. ⛔ Post no claim of your own, ⛔ never write the card's assignee. Before your first edit, verify the NEWESTClaim: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. Worktreeobjectstack-issue-27250on that branch from a freshorigin/main;pnpm install(frozen lockfile); push withgit 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-runfirst); your report comment throughnode scripts/pm/post-stamped.mjs --comment=27250 --file=F --jsonrun 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 onerun_rerun_failedthrough the relay. Report both counts (api_writeswith endpoints,mcp_callswith 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/objectstackon 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 rootci.ymlare 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 grade (2026-10-28 13:15Z, triage#1): p3,
domain:ui,area:i18n. The card is the one should-fix of triage's contract review of PR #27136 (6469007202): "a one-line equality assertion, or deriving one from the other, would keep them from drifting apart". No maintainer ruling needed.PM mechanism assumptions (measure on
origin/mainafter1e8e5296; disproof welcome)ui/packages/i18n/src/__tests__/studio-namespace.test.ts:43ZH_ONLY_FAMILIES(three prefixes) andui/packages/app-shell/src/views/metadata-admin/inspectors/inspectorStrings.studioNamespace-25922.test.ts:156ZH_ONLY_REASONS(prefix + reason + citation anchor) hold the same family set.@object-ui/app-shelldepends on@object-ui/i18n, never the reverse. So the one home is on the i18n side (export the family list from a test-support module the app-shell pin can import, or keep both and have the app-shell pin assertZH_ONLY_REASONSprefixes equal the i18n list). ⛔ No runtime export added to@object-ui/i18n's public entry for a test-only list; if the only clean home would be a public export, take the equality-assertion route instead and say why.Scope
File surface: the two test files (+ a test-support module if you take that route). Tests only, no runtime change. Ablation: add a fourth prefix to one list only ⇒ a pin goes red. Stay under 150 changed lines.
Tier
Quote
dispatch-gates --tieron your surface. Expected none.TIER_DEFAULT, effortlow.Clause-②: no,Metadata-protocol: none. Tests only:skip-changeset.Fixes #27250.objectstack-fleet commentedon Oct 28, 2026
Claim: PM loop round 22 · 2026-10-28T13:34Z
Session:
session_01JQwxbZeBv2y91towxasSUT(seat; implementation by card thread sessionsession_01JQwxban7wCJnPiiSY4ULYz,mode:thread)Account:
os-warren(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-qipkqe(the card thread's harness push branch, self-reported — the measured platform exception toclaude/issue-N-slug)Worktree:
objectstack-issue-27250in the card thread's cloneDomain:
domain:uiSeat:
domain:ui#1(seat post #25966)File surface:
ui/packages/i18n/src/__tests__/studio-namespace.test.ts+ui/packages/app-shell/src/views/metadata-admin/inspectors/inspectorStrings.studioNamespace-25922.test.ts(+ an i18n-side test-support module if that route is taken); ⛔ any runtime export (stop on breach; explain in the report)Container & model:
S,mode:thread(the maintainer's word: 3 active card threads per seat, 2026-10-28 10:00Z / 12:11Z),model: TIER_DEFAULT(the dev quotesdispatch-gates --tieron the surface),effort: lowClause-②: no
Metadata-protocol: none
Responsibility: n/a — tests-only follow-up of contract review 6469007202 (PR #27136)
Thread-read: 6470346819
Premise: holds — on
origin/mainafter1e8e5296,ZH_ONLY_FAMILIES(i18n pin:43) andZH_ONLY_REASONS(app-shell pin:156) hold the same three prefixes with no equality check.Serial constraints cleared: #25922 is complete (S7 #27136 merged); no open PR edits either file.
Resume-from: none
Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
os-dev-report
{ "issue": 27250, "status": "done", "branch": "claude/project-thread-qipkqe", "pr": "https://github.com/objectstack-ai/objectstack/pull/27289", "head": "37238cc1", "session": "session_01JQwxban7wCJnPiiSY4ULYz", "premise_still_valid": true, "summary": "Premise held on origin/main 1e8e5296: ZH_ONLY_FAMILIES (i18n studio-namespace pin) and ZH_ONLY_REASONS (app-shell inspectorStrings.studioNamespace-25922 pin) held the same three prefixes with no equality check. The list now lives once in an i18n test-support module, ui/packages/i18n/src/__tests__/studio-zh-only-families.ts (STUDIO_ZH_ONLY_FAMILIES; under __tests__, excluded from the build, no exports-map change). The i18n pin reads it; the app-shell pin imports it by relative path (app-shell to i18n direction kept, precedent plugin-designer importing plugin-grid src/__tests__/explainDouble) and adds one case asserting the sorted ZH_ONLY_REASONS prefixes equal the sorted list. Tests only, no runtime change.", "tests": "pnpm --dir ui exec vitest run on both pin files: Test Files 2 passed (2), Tests 201 passed (201). Ablation via scripts/ablation-replace.mjs, two legs, each anchor x1 to x0 and blob moved on disk: (a) fourth prefix in STUDIO_ZH_ONLY_FAMILIES only -> Tests 1 failed | 200 passed (201), failure = 'a reason is given for exactly the families the i18n pin allows'; (b) fourth entry in ZH_ONLY_REASONS only, valid anchor -> Tests 1 failed | 201 passed (202), same single failure. After both: git diff HEAD empty, both blobs equal HEAD blobs (dfe1a88f, 138a6f73). No dist leg: both pins import their subjects by relative path or the vitest src alias.", "gates": "head 37238cc1, merge base 1e8e5296. dispatch-gates --commands derived 24; all 24 run, every one exit 0; dispatch-gates --ran: 24 run, 0 NOT-MEASURED, 0 UNRUN. Owed beyond the list: pnpm --filter @object-ui/i18n run type-check exit 0; pnpm --filter @object-ui/app-shell run type-check exit 0 (tsconfig.test.json compiles the cross-package import); pnpm --dir ui run check:new-line-citations exit 0 (0 new citations). CI check-runs: in_progress at report time. Tier: dispatch-gates --tier = no path-derived mandate (TIER_DEFAULT). Changed lines 34 (+26 / -8).", "line_budget": "34 changed lines vs the 150 cap", "files_changed": [ "ui/packages/i18n/src/__tests__/studio-zh-only-families.ts (new)", "ui/packages/i18n/src/__tests__/studio-namespace.test.ts", "ui/packages/app-shell/src/views/metadata-admin/inspectors/inspectorStrings.studioNamespace-25922.test.ts" ], "deviations": [ "pnpm install --frozen-lockfile exited 1 twice: better-sqlite3 node-gyp rebuild aborted mid-download of the node headers through the proxy. Installed with --frozen-lockfile --ignore-scripts and ran the root prepare script (node scripts/setup-git-hooks.mjs) by hand; no test or gate in this card loads better-sqlite3.", "PR template headings folded into the os-dev order (What changes / Why / Tests / Acceptance notes / Verification / Human Minimum), the os-dev exception.", "Session-context MCP assignee/reviewer step skipped: the relay set the assignee; requested_reviewers read back empty." ], "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm", "mcp_calls": "1: mcp__claude-code-remote__subscribe_pr_activity (PR 27289), not a GitHub MCP tool; 0 GitHub MCP calls", "api_writes": "2 through the fleet-write relay: pr_create (POST pulls, PR 27289, with assignee os-warren and label skip-changeset); this os-dev-report comment (POST issues/27250/comments). git push is not a REST write.", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed: ZH_ONLY_FLOOR in the app-shell pin keys a floor by 'engine.enum.' rather than 'engine.enum.type.'; it holds counts, not the allowed set, so it is outside the equality and was left as is (PR Acceptance notes)." ] }objectstack-fleet commentedon Oct 28, 2026
domain:ui#1 · os-warren · session_01JQwxbZeBv2y91towxasSUT
Landed · seat
domain:ui#1· 2026-10-28T15:14ZPR #27289 merged as
bf01226b62(seat record on the PR). The zh-only family list now lives once inui/packages/i18n/src/__tests__/studio-zh-only-families.ts(STUDIO_ZH_ONLY_FAMILIES), and the app-shell pin asserts that theZH_ONLY_REASONSprefixes equal it, so the two lists can no longer drift apart.Fixes #27250closed this card. The claim is released:pm:dispatchedcomes off.Generated by Claude Code