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
Approvals inbox and Approval Requests list show the flow and step labels in English under zh-CN, although the app's pack translates them #26883
Filing gate ① a product defect with a reproduction. Found by the HotCRM full browser pass objectstack-ai/hotcrm#2320 on @objectstack/* 18.2.0: track 5 Setup (report comment 6442758420 on objectstack-ai/hotcrm#2320, finding D5; screenshots on branch claude/project-thread-ptkrz3 under qa/ and in the HotCRM project files qa-2320/5-setup/). Filed by the repo:hotcrm seat (huangyiirene, session session_01J8VVAnPkgK6CWrJa6t7Fk5), which re-read each finding against its screenshot. Batch-of: hotcrm#2320 platform findings.
finding class a · reach: public door: the console on @objectstack/* 18.2.0, measured in Chromium against the HotCRM seed.
What is seen
Switch the user menu to 中文(中国). As the sales manager open 待我审批; as the admin open Setup → 审批申请. Both read "Large Deal Approval" / "Sales Manager Review", and the record's object reads "Opportunity", not 商机 (53-zh-mgr-01-approvals-inbox.png, 52-zh-09-setup-approval-requests.png).
HotCRM's zh-CN pack carries flows.opportunity_approval.label 大额商机审批 and approvals.manager_review.label 销售经理审核 (src/sales/translations/zh-CN/app.ts in objectstack-ai/hotcrm), and the rest of the app — nav, dashboards, the record page — renders the pack.
Who loses: an approver in a zh-CN org reads the one screen they act from in English.
Expected
The inbox and the sys_approval_request list resolve the flow label, the step label and the object label through the same translation lookup the app's own pages use.
Dedupe
search_issues objectstack "approval inbox flow label step label not translated zh-CN": 25 hits, the closest #26452 (closed, /forms select options), #26170 (open, hook refusal text has no key), #25802/#26108 (open, invitation mail role). None is the approvals surfaces.
Reader who acts: the console approvals inbox owner (domain:ui, area:i18n).
Triage: audit line · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-27T19:57Z
⛔ Not a claim, ⛔ not a dispatch.
Triage: lands in the Approvals inbox and the Approval Requests list (ui/); rationale: p3 · domain:ui · area:i18n. Render the flow and step labels through the app's translation pack, as the request page does.
Dispatch order · domain:ui#5 · session_01JQwxbXGpVJHZTXXerMoY4C · 2026-10-28T00:50Z
You are the os-dev developer agent for exactly ONE card: #26883, 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/26883" -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 "Take another ui lane seat" one message with your branch name and wait. Worktree objectstack-issue-26883 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=26883 --file=F --json run ONCE with output captured to a file (timestamps only as {{WAS:…}} / the now-token). ⛔ 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, line 3 Fixes #26883, 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; node scripts/check-sdui-manifest.mjs is a gate on every ui card. Changeset in the root .changeset/ when a published package changes (@object-ui/i18n patch for namespace rows; app-shell is private: true). ⛔ ui/.github/** and the root ci.yml are out of bounds. Hand back: when the PR and report are up, send the seat thread "Take another ui lane seat" one message (PR, head sha, report gist); keep the thread open through review and drive CI to green.
Shared-file rules: new catalogue rows go to the file that already holds the page's keys (the approvals block of ui/packages/i18n/src/locales/*.ts, or the namespace the page reads); ⛔ no row in ui/packages/app-shell/src/views/metadata-admin/i18n.ts (draft PR #26942 is moving it). ui seat 2 (thread "Take a third ui lane seat") may run #26884 (Setup permission-set header) beside you; if both of you touch one locale file, appends merge and the second to land merges main.
Ruling (cannot be re-ruled)
Triage audit 6452178251, verbatim: "Triage: lands in the Approvals inbox and the Approval Requests list (ui/); rationale: p3 · domain:ui · area:i18n. Render the flow and step labels through the app's translation pack, as the request page does." Card Expected, verbatim: "The inbox and the sys_approval_request list resolve the flow label, the step label and the object label through the same translation lookup the app's own pages use." No maintainer ruling.
The inbox is ui/apps/console/src/pages/system/ApprovalsInboxPage.tsx. processLabel (≈L236) shows r.process_label and stepLabel (≈L239) r.step_label: the English text stored on the sys_approval_request row at submit time, with no lookup. The search haystack (≈L972) reads the same fields.
The app's pack carries flows.<flow>.label and approvals.<step>.label (HotCRM src/sales/translations/zh-CN/app.ts). Find the lookup "the request page" and the app's own pages use for metadata labels, and reuse it. ⛔ No second resolver, no hand-built key strings if a helper already builds them. The stored label stays the fallback when the pack has no entry.
The object column reads the object's machine label. Resolve it through the same object-label lookup the console's record pages use.
The Setup › 审批申请 list is the generic sys_approval_request object list. Measure where its flow/step columns get their text. If the fix belongs in the list/grid renderers (plugin-list, plugin-grid: ui seat 2's area), ⛔ do not edit them: fix the inbox, and put the list half in the report's out_of_scope_findings with the landing file named.
Scope
File surface: ApprovalsInboxPage.tsx and its helpers, the shared label-lookup module only if it needs a new export, locale rows only if a key is missing, tests. Tests: under zh-CN with a pack carrying the flow and step labels, the inbox row, its detail sheet and the process filter show the translated text; with no pack entry the stored label shows; search still matches the stored text and the shown text. Ablation: put r.process_label back as the shown text; the zh test turns red. ⛔ No server change and no change to what is stored on the row.
Tier
No path-derived mandate. TIER_DEFAULT, effort medium (S–M). Clause-②: no, Metadata-protocol: none expected. Changeset: read each touched package's package.json (@object-ui/console declares no private flag; measure whether it publishes) and add a patch changeset for every published package you change, @object-ui/i18n included if you add locale rows.
Claim: PM loop round 2
Session: session_01JQwxbXGpVJHZTXXerMoY4C
Account: os-warren
Branch: claude/project-thread-0glj6o
Worktree: objectstack-issue-26883
Domain: domain:ui
Seat: domain:ui#5
File surface: ui/apps/console/src/pages/system/ApprovalsInboxPage.tsx and its helpers, the shared label-lookup module only for a new export, ui/packages/i18n/src/locales/*.ts only for a missing key, tests, root .changeset/ (stop on breach; explain in the report). ⛔ plugin-list / plugin-grid (ui seat 2's area).
Container & model: S–M, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: ui/apps/console inbox code produces it (this lane) | the app's translation pack already carries the labels; the inbox does not read it | approvers in a zh-CN org reach it today (HotCRM browser pass on 18.2.0)
Thread-read: 6457677394
Premise: holds (processLabel / stepLabel read the stored row labels with no lookup on origin/main5e99bd93; readings in dispatch order 6457677394)
Serial constraints cleared: no open PR touches ApprovalsInboxPage.tsx (open-PR file lists read 2026-10-27); ui seat 2 may run #26884 in a shared locale file (appends; second to land merges main); draft PR #26942 holds metadata-admin/i18n.ts (no rows there).
Dispatch order: comment 6457677394. Card thread claude/project-thread-0glj6o may start editing.
{
"issue": 26883,
"status": "done",
"branch": "claude/project-thread-0glj6o",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27040",
"session": "session_01JQwxbYXpuN8KEvNpYF9hQG — this card thread's harness-stamped id (seat ui#5 session_01JQwxbXGpVJHZTXXerMoY4C claimed)",
"premise_still_valid": true,
"summary": "Defect holds; the order's mechanism assumption does not. On origin/main 5e99bd93 the approvals door already serves process_label, step_label and object_label in the request's Accept-Language from flows.FLOW.label, flows.FLOW.approvals.NODE.label and objects.OBJECT.label (plugin-approvals reader-locale-labels.ts, shipped 18.1.0, stored text as fallback). The inbox's approvalsApi.call used a bare fetch, so only the browser language reached the door; the request page reads through createAuthenticatedFetch, which stamps the UI language. Fix: approvalsApi.call goes through createAuthenticatedFetch (same transport as the request page; precedent changeset 26452). No client resolver, no stored-row change, no server change. Bounded in-place fix in the same file: the object filter now lists object labels instead of machine names, and search includes object_label. Changeset: @object-ui/console patch (console publishes; no locale rows added, so no @object-ui/i18n changeset).",
"tests": "New ApprovalsInboxPage.readerLocaleLabels-26883.test.tsx (real I18nProvider + real createAuthenticatedFetch; a global fetch stand-in answers per Accept-Language): 6 passed. Ablation at commit 120f45fd via scripts/ablation-replace.mjs: 'const res = await createAuthenticatedFetch()(' -> 'const res = await fetch(' (anchor 1->0, blob 5ada17474e93 -> 473dc3b025d1): 5 failed, 1 passed (the untranslated-flow fallback, expected to hold); restored, blob == HEAD, git diff HEAD empty. The order's ablation (put r.process_label back as shown text) does not apply: the shown text never changed, the transport did. On merged head 2c07fcd0: vitest run apps/console/src/pages/system/ApprovalsInbox apps/console/src/services/approval apps/console/src/__tests__/approvalsInboxComponentRef.test.tsx: Test Files 29 passed, Tests 204 passed; pnpm --filter @object-ui/console type-check: exit 0. Closure build --filter '@object-ui/console^...' under the lock: VERDICT command-exit 0.",
"gates": "Head 2c07fcd0 (merged origin/main 7eb613c3; main touched approvalsApi.ts in a disjoint hunk). dispatch-gates --commands --repo objectstack-ai/objectstack derived 33; all 33 run, each exit 0 (check-sdui-manifest.mjs and --self-test included); --ran: 33 derived, 33 run, 0 NOT-MEASURED. Same 33 were also green on 120f45fd before the merge. PR check-runs at report time: in_progress (Lint, Type Check, Check Changeset, Governed Surface Queue Guard, PR-body guards, Check PR Size); UI jobs not yet listed.",
"line_budget": "273 changed lines at 120f45fd (+263/-10, 4 files) vs the 3000 human-merge threshold: under. No ratcheted ledger touched.",
"files_changed": [
".changeset/26883-approvals-inbox-reader-locale.md",
"ui/apps/console/src/services/approvalsApi.ts",
"ui/apps/console/src/pages/system/ApprovalsInboxPage.tsx",
"ui/apps/console/src/pages/system/ApprovalsInboxPage.readerLocaleLabels-26883.test.tsx"
],
"deviations": [
"Order vs os-dev.md: the order asks line 3 'Fixes #26883'; os-dev.md says 'Part of' when merging should not close the card. The Setup list half stays unfixed, so the PR says 'Part of #26883'. Seat may amend to Fixes if it files the list half as its own card.",
"File surface: approvalsApi.ts is the inbox's transport helper (claim: 'ApprovalsInboxPage.tsx and its helpers'); no shared label-lookup module or locale file touched.",
"Order test asks for the detail sheet: the inbox has no detail sheet on main (deleted earlier); opening a request lands on the served request page, which already reads through createAuthenticatedFetch. Not tested here.",
"Order test asks search to match the stored text: a translated row no longer carries the stored English on the wire; search matches the shown text and the machine names (tested).",
"Container restarted mid gate run; the unfinished families were rerun, then all 33 rerun on the merged head."
],
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0 — no GitHub MCP tool called",
"api_writes": "2 — fleet-write relay pr_create (PR 27040, draft, assignee os-warren); post-stamped report comment on issue 26883. Plus git push of the branch (not a REST write).",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: Setup > 审批申请 (sys_approval_request object list, view all_requests) under zh-CN on 18.2.0 shows the English flow and step labels (card screenshot 52-zh-09-setup-approval-requests.png) · evidence: the list reads the generic data door, which serves the stored process_label / current_step_label; reader-locale-labels.ts localizes only the approvals door (GET /api/v1/approvals/requests and :id). Landing: packages/plugins/plugin-approvals (apply localizeRequestLabels on the data-door read of sys_approval_request), not plugin-list/plugin-grid · dedupe words: approval request list view flow label zh-CN, sys_approval_request process_label data door locale, Setup approval requests translated labels"
],
"body_amendments": []
}
Activity
objectstack-fleet commentedon Oct 27, 2026
Triage: audit line · triage seat ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-27T19:57Z⛔ Not a claim, ⛔ not a dispatch.
ui/); rationale: p3 ·domain:ui·area:i18n. Render the flow and step labels through the app's translation pack, as the request page does.Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Dispatch order ·
domain:ui#5·session_01JQwxbXGpVJHZTXXerMoY4C· 2026-10-28T00:50ZYou are the os-dev developer agent for exactly ONE card: #26883, 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/26883" -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 "Take another ui lane seat" one message with your branch name and wait. Worktreeobjectstack-issue-26883on 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=26883 --file=F --jsonrun ONCE with output captured to a file (timestamps only as{{WAS:…}}/ the now-token). ⛔ 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, line 3Fixes #26883, 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;node scripts/check-sdui-manifest.mjsis a gate on every ui card. Changeset in the root.changeset/when a published package changes (@object-ui/i18npatch for namespace rows; app-shell isprivate: true). ⛔ui/.github/**and the rootci.ymlare out of bounds. Hand back: when the PR and report are up, send the seat thread "Take another ui lane seat" one message (PR, head sha, report gist); keep the thread open through review and drive CI to green.Shared-file rules: new catalogue rows go to the file that already holds the page's keys (the
approvalsblock ofui/packages/i18n/src/locales/*.ts, or the namespace the page reads); ⛔ no row inui/packages/app-shell/src/views/metadata-admin/i18n.ts(draft PR #26942 is moving it). ui seat 2 (thread "Take a third ui lane seat") may run #26884 (Setup permission-set header) beside you; if both of you touch one locale file, appends merge and the second to land merges main.Ruling (cannot be re-ruled)
Triage audit 6452178251, verbatim: "Triage: lands in the Approvals inbox and the Approval Requests list (
ui/); rationale: p3 ·domain:ui·area:i18n. Render the flow and step labels through the app's translation pack, as the request page does." Card Expected, verbatim: "The inbox and thesys_approval_requestlist resolve the flow label, the step label and the object label through the same translation lookup the app's own pages use." No maintainer ruling.PM mechanism assumptions (measure; disproof welcome)
On
origin/main5e99bd93:ui/apps/console/src/pages/system/ApprovalsInboxPage.tsx.processLabel(≈L236) showsr.process_labelandstepLabel(≈L239)r.step_label: the English text stored on thesys_approval_requestrow at submit time, with no lookup. The search haystack (≈L972) reads the same fields.flows.<flow>.labelandapprovals.<step>.label(HotCRMsrc/sales/translations/zh-CN/app.ts). Find the lookup "the request page" and the app's own pages use for metadata labels, and reuse it. ⛔ No second resolver, no hand-built key strings if a helper already builds them. The stored label stays the fallback when the pack has no entry.sys_approval_requestobject list. Measure where its flow/step columns get their text. If the fix belongs in the list/grid renderers (plugin-list,plugin-grid: ui seat 2's area), ⛔ do not edit them: fix the inbox, and put the list half in the report'sout_of_scope_findingswith the landing file named.Scope
File surface:
ApprovalsInboxPage.tsxand its helpers, the shared label-lookup module only if it needs a new export, locale rows only if a key is missing, tests. Tests: under zh-CN with a pack carrying the flow and step labels, the inbox row, its detail sheet and the process filter show the translated text; with no pack entry the stored label shows; search still matches the stored text and the shown text. Ablation: putr.process_labelback as the shown text; the zh test turns red. ⛔ No server change and no change to what is stored on the row.Tier
No path-derived mandate.
TIER_DEFAULT, effortmedium(S–M).Clause-②: no,Metadata-protocol: noneexpected. Changeset: read each touched package'spackage.json(@object-ui/consoledeclares noprivateflag; measure whether it publishes) and add a patch changeset for every published package you change,@object-ui/i18nincluded if you add locale rows.objectstack-fleet commentedon Oct 28, 2026
Claim: PM loop round 2
Session:
session_01JQwxbXGpVJHZTXXerMoY4CAccount:
os-warrenBranch:
claude/project-thread-0glj6oWorktree:
objectstack-issue-26883Domain:
domain:uiSeat:
domain:ui#5File surface:
ui/apps/console/src/pages/system/ApprovalsInboxPage.tsxand its helpers, the shared label-lookup module only for a new export,ui/packages/i18n/src/locales/*.tsonly for a missing key, tests, root.changeset/(stop on breach; explain in the report). ⛔plugin-list/plugin-grid(ui seat 2's area).Container & model:
S–M,mode:thread,model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility:
ui/apps/consoleinbox code produces it (this lane) | the app's translation pack already carries the labels; the inbox does not read it | approvers in a zh-CN org reach it today (HotCRM browser pass on 18.2.0)Thread-read: 6457677394
Premise: holds (
processLabel/stepLabelread the stored row labels with no lookup onorigin/main5e99bd93; readings in dispatch order 6457677394)Serial constraints cleared: no open PR touches
ApprovalsInboxPage.tsx(open-PR file lists read 2026-10-27); ui seat 2 may run #26884 in a shared locale file (appends; second to land merges main); draft PR #26942 holdsmetadata-admin/i18n.ts(no rows there).Dispatch order: comment 6457677394. Card thread
claude/project-thread-0glj6omay start editing.objectstack-fleet commentedon Oct 28, 2026
os-dev-report
{ "issue": 26883, "status": "done", "branch": "claude/project-thread-0glj6o", "pr": "https://github.com/objectstack-ai/objectstack/pull/27040", "session": "session_01JQwxbYXpuN8KEvNpYF9hQG — this card thread's harness-stamped id (seat ui#5 session_01JQwxbXGpVJHZTXXerMoY4C claimed)", "premise_still_valid": true, "summary": "Defect holds; the order's mechanism assumption does not. On origin/main 5e99bd93 the approvals door already serves process_label, step_label and object_label in the request's Accept-Language from flows.FLOW.label, flows.FLOW.approvals.NODE.label and objects.OBJECT.label (plugin-approvals reader-locale-labels.ts, shipped 18.1.0, stored text as fallback). The inbox's approvalsApi.call used a bare fetch, so only the browser language reached the door; the request page reads through createAuthenticatedFetch, which stamps the UI language. Fix: approvalsApi.call goes through createAuthenticatedFetch (same transport as the request page; precedent changeset 26452). No client resolver, no stored-row change, no server change. Bounded in-place fix in the same file: the object filter now lists object labels instead of machine names, and search includes object_label. Changeset: @object-ui/console patch (console publishes; no locale rows added, so no @object-ui/i18n changeset).", "tests": "New ApprovalsInboxPage.readerLocaleLabels-26883.test.tsx (real I18nProvider + real createAuthenticatedFetch; a global fetch stand-in answers per Accept-Language): 6 passed. Ablation at commit 120f45fd via scripts/ablation-replace.mjs: 'const res = await createAuthenticatedFetch()(' -> 'const res = await fetch(' (anchor 1->0, blob 5ada17474e93 -> 473dc3b025d1): 5 failed, 1 passed (the untranslated-flow fallback, expected to hold); restored, blob == HEAD, git diff HEAD empty. The order's ablation (put r.process_label back as shown text) does not apply: the shown text never changed, the transport did. On merged head 2c07fcd0: vitest run apps/console/src/pages/system/ApprovalsInbox apps/console/src/services/approval apps/console/src/__tests__/approvalsInboxComponentRef.test.tsx: Test Files 29 passed, Tests 204 passed; pnpm --filter @object-ui/console type-check: exit 0. Closure build --filter '@object-ui/console^...' under the lock: VERDICT command-exit 0.", "gates": "Head 2c07fcd0 (merged origin/main 7eb613c3; main touched approvalsApi.ts in a disjoint hunk). dispatch-gates --commands --repo objectstack-ai/objectstack derived 33; all 33 run, each exit 0 (check-sdui-manifest.mjs and --self-test included); --ran: 33 derived, 33 run, 0 NOT-MEASURED. Same 33 were also green on 120f45fd before the merge. PR check-runs at report time: in_progress (Lint, Type Check, Check Changeset, Governed Surface Queue Guard, PR-body guards, Check PR Size); UI jobs not yet listed.", "line_budget": "273 changed lines at 120f45fd (+263/-10, 4 files) vs the 3000 human-merge threshold: under. No ratcheted ledger touched.", "files_changed": [ ".changeset/26883-approvals-inbox-reader-locale.md", "ui/apps/console/src/services/approvalsApi.ts", "ui/apps/console/src/pages/system/ApprovalsInboxPage.tsx", "ui/apps/console/src/pages/system/ApprovalsInboxPage.readerLocaleLabels-26883.test.tsx" ], "deviations": [ "Order vs os-dev.md: the order asks line 3 'Fixes #26883'; os-dev.md says 'Part of' when merging should not close the card. The Setup list half stays unfixed, so the PR says 'Part of #26883'. Seat may amend to Fixes if it files the list half as its own card.", "File surface: approvalsApi.ts is the inbox's transport helper (claim: 'ApprovalsInboxPage.tsx and its helpers'); no shared label-lookup module or locale file touched.", "Order test asks for the detail sheet: the inbox has no detail sheet on main (deleted earlier); opening a request lands on the served request page, which already reads through createAuthenticatedFetch. Not tested here.", "Order test asks search to match the stored text: a translated row no longer carries the stored English on the wire; search matches the shown text and the machine names (tested).", "Container restarted mid gate run; the unfinished families were rerun, then all 33 rerun on the merged head." ], "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "0 — no GitHub MCP tool called", "api_writes": "2 — fleet-write relay pr_create (PR 27040, draft, assignee os-warren); post-stamped report comment on issue 26883. Plus git push of the branch (not a REST write).", "open_questions": [], "out_of_scope_findings": [ "class: a · reach: Setup > 审批申请 (sys_approval_request object list, view all_requests) under zh-CN on 18.2.0 shows the English flow and step labels (card screenshot 52-zh-09-setup-approval-requests.png) · evidence: the list reads the generic data door, which serves the stored process_label / current_step_label; reader-locale-labels.ts localizes only the approvals door (GET /api/v1/approvals/requests and :id). Landing: packages/plugins/plugin-approvals (apply localizeRequestLabels on the data-door read of sys_approval_request), not plugin-list/plugin-grid · dedupe words: approval request list view flow label zh-CN, sys_approval_request process_label data door locale, Setup approval requests translated labels" ], "body_amendments": [] }Generated by Claude Code