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
ui(studio): the dataset inspector stores currency: 'USD' when the currency format is picked with no currency — store nothing and inherit the field / tenant chain (#27119 Q2 X, G1) #27156
Filing gate ③ (maintainer-directed). Ruling 6464202770 on #27119 (batch #421 item 2, Q2 = X, maintainer 「其他同意」 2026-10-28): G1. Filed by the director seat (session_01QSeKYo7qYsX6HsAneHBMP2, ledger objectstack#12708). ⛔ Not a claim; triage sets the lane (domain:ui expected) and grade.
Ruling-ref: 6464202770
维护者速读
改了什么: Studio 数据集检查器里选「货币」格式但没选币种时,不再往度量上写 currency: 'USD';度量继承字段币种 → 组织默认币种这条既有链。
Dispatch order · domain:ui#1 · session_01JQwxbZeBv2y91towxasSUT · 2026-10-28T09:27Z
You are the os-dev developer agent for exactly ONE card: #27156, 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-27156 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=27156 --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)
Maintainer ruling 6464202770 on #27119 (batch #421 item 2, Q2 = X, maintainer 「其他同意」 2026-10-28): no surface guesses a currency. The card's own Ruling-ref: 6464202770 and Task list are binding: the Studio dataset inspector stops writing currency: 'USD' when no currency is picked; a measure then inherits through the existing chain (explicit measure currency → the source field's fixed currency → the tenant default). No further ruling.
PM mechanism assumptions (measure on origin/mainb8615afa; disproof welcome)
ui/packages/app-shell/src/views/metadata-admin/inspectors/DatasetDefaultInspector.tsx ≈L211–215: buildMeasureFormat('currency', …) returns currency: currency || 'USD'. With an empty pick it returns { format, currency: undefined }, and the saved measure carries no currency key at all (check the emit path drops an undefined key rather than writing currency: undefined or '').
The currency picker's empty state reads as "inherit" (an i18n string if a new label is needed, en + zh, plus what the i18n gates demand). Find whether the picker today pre-selects USD; if it does, the default becomes the empty/inherit state.
⛔ A stored currency: 'USD' the inspector wrote earlier stays as authored (it is explicit on the wire): no migration, no rewrite on load. The PR body says so.
Scan the same inspector (and its measure-format helpers) for any other 'USD' default on the write path; report each, fix only those that write a guessed currency on save.
Scope
File surface: DatasetDefaultInspector.tsx (and a measure-format helper if the guess lives there), i18n keys if any, tests. Tests: empty picker ⇒ saved measure has no currency key; a picked CNY ⇒ currency: 'CNY' (control); a loaded measure with currency: 'USD' round-trips unchanged. Ablation: restore || 'USD' ⇒ the first test goes red. Stay under 500 changed lines.
Serial: open PR #27163 (#27054) edits this file's imports and filter section (not buildMeasureFormat). Merge origin/main before your gates; if #27163 lands first, re-run the inspector tests.
Tier
Quote dispatch-gates --tier on your surface. Expected none. TIER_DEFAULT, effort low. Clause-②: no, Metadata-protocol: none. @object-ui/app-shell is private: skip-changeset unless you change a published package (then a patch changeset for it).
Claim: PM loop round 18 · 2026-10-28T09:29Z
Session: session_01JQwxbZeBv2y91towxasSUT (seat; implementation by card thread session session_01JQwxbakr3SQTyXX1NuZkt3, mode:thread)
Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/project-thread-0rmmxq (the card thread's harness push branch, self-reported — the measured platform exception to claude/issue-N-slug)
Worktree: objectstack-issue-27156 in the card thread's clone
Domain: domain:ui
Seat: domain:ui#1 (seat post #25966)
File surface: ui/packages/app-shell/src/views/metadata-admin/inspectors/DatasetDefaultInspector.tsx (and a measure-format helper if the guess lives there), i18n keys if any, + tests (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 (the dev quotes dispatch-gates --tier on the surface), effort: low
Clause-②: no
Metadata-protocol: none
Responsibility: the Studio dataset inspector (this lane's code) | the analytics currency chain and ruling 6464202770 on #27119 | a CNY organization's dashboard cells show $ with no error
Thread-read: none
Premise: holds — currency: currency || 'USD' is at DatasetDefaultInspector.tsx L215 on origin/mainb8615afa.
Serial constraints cleared: open PR #27163 (#27054) edits this file's imports and filter section, not buildMeasureFormat; the dev merges origin/main before the gates.
Resume-from: none
{
"issue": 27156,
"status": "done",
"branch": "claude/project-thread-0rmmxq",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27208",
"session": "session_01JQwxbakr3SQTyXX1NuZkt3 — card thread session, mode:thread",
"premise_still_valid": true,
"summary": "buildMeasureFormat no longer falls back to 'USD' and the currency picker no longer pre-selects USD; a new writeMeasureFormat drops unset format/currency keys so the saved measure carries no currency key. Over a currency-type field the picker defaults to an inherit row; over other fields it asks for a code (the runtime gives non-monetary measures no code, so inherit would resolve to nothing: mechanism assumption partly disproved, route chosen per the ruling's intent). parseMeasureFormat reads a code-less format over a currency field back as Currency · inherit; the picked kind is held in component state until a code is chosen. Stored currency 'USD' left as authored, no migration.",
"tests": "head 77475026: DatasetDefaultInspector.currencyNoGuess-27156.test.tsx 6/6 + DatasetDefaultInspector.test.tsx + ui scripts/ = 177 files passed, 5040 tests passed, 2 skipped (lock VERDICT command-exit 0). dcfac927: inspectors dir + packages/i18n = 286 files, 4116 passed, 14 skipped. type-check app-shell + i18n exit 0. Ablation on committed fix via ablation-replace.mjs (anchor 'currency: currency || undefined };' to 'currency: currency || 'USD' };'): 2 failed / 4 passed, the empty-pick case red; restore blob 10ecdd83 == HEAD, git diff HEAD empty. No dist leg: app-shell tests import the inspector by relative path.",
"gates": "dispatch-gates --commands on head 77475026: 34 families, every one exit 0 (exit captured before any pipe); --ran: 34 derived, 34 run, 0 NOT-MEASURED. Extra: ui check:new-line-citations 0 new, exit 0; eslint on 4 changed files 0 errors. --tier: no path-derived mandate, TIER_DEFAULT; 233 changed lines. CI check-runs: in_progress at report time.",
"line_budget": "233 changed lines (+223/-10) vs 500 order cap",
"files_changed": [
"ui/packages/app-shell/src/views/metadata-admin/inspectors/DatasetDefaultInspector.tsx",
"ui/packages/app-shell/src/views/metadata-admin/inspectors/DatasetDefaultInspector.currencyNoGuess-27156.test.tsx",
"ui/packages/i18n/src/namespaces/studio/en.ts",
"ui/packages/i18n/src/namespaces/studio/zh.ts",
".changeset/27156-dataset-inspector-no-currency-guess.md"
],
"deviations": [
"@object-ui/i18n is published, so a patch changeset ships instead of skip-changeset (the order expected skip-changeset only if no published package changed)",
"picker inherit row offered only over currency-type fields, not for every measure (measured runtime monetary predicate)",
"PR body folds .github/PULL_REQUEST_TEMPLATE.md headings (Why, Human Minimum) into the os-dev section order",
"PR body line 2 carries the platform requested-by line under the attribution comment"
],
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 — relay pr_create (POST pulls + assignee, run 40672905620); this report via post-stamped (POST issues/27156/comments). git push is not a REST write.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted in PR Acceptance notes, not filed: the format sample shows a plain number for an inherit measure; the formatKind.currency label shows a dollar example; Number over a currency field reads back as Currency (runtime always attaches a currency)"
]
}
PR #27208 merged as 48bffe389e (seat record: PR comment 6467000658, addendum 6467637918). The Studio dataset inspector no longer stores a guessed currency: 'USD', and its picker no longer pre-selects USD. Over a currency field the picker opens on "Inherit — field or organization default", and the saved measure carries no currency key, so it resolves the field's fixed currency and then the tenant default (ruling 6464202770 on #27119). Over any other field the picker asks for a code. A stored code, 'USD' included, is left as authored. The road to merge took one queue ejection, the foreseen conflict with #27163. pm:dispatched is removed with the close.
Activity
objectstack-fleet commentedon Oct 28, 2026
Dispatch order ·
domain:ui#1·session_01JQwxbZeBv2y91towxasSUT· 2026-10-28T09:27ZYou are the os-dev developer agent for exactly ONE card: #27156, 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-27156on 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=27156 --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)
Maintainer ruling 6464202770 on #27119 (batch #421 item 2, Q2 = X, maintainer 「其他同意」 2026-10-28): no surface guesses a currency. The card's own
Ruling-ref: 6464202770and Task list are binding: the Studio dataset inspector stops writingcurrency: 'USD'when no currency is picked; a measure then inherits through the existing chain (explicit measure currency → the source field's fixed currency → the tenant default). No further ruling.PM mechanism assumptions (measure on
origin/mainb8615afa; disproof welcome)ui/packages/app-shell/src/views/metadata-admin/inspectors/DatasetDefaultInspector.tsx≈L211–215:buildMeasureFormat('currency', …)returnscurrency: currency || 'USD'. With an empty pick it returns{ format, currency: undefined }, and the saved measure carries nocurrencykey at all (check the emit path drops anundefinedkey rather than writingcurrency: undefinedor'').currency: 'USD'the inspector wrote earlier stays as authored (it is explicit on the wire): no migration, no rewrite on load. The PR body says so.'USD'default on the write path; report each, fix only those that write a guessed currency on save.Scope
File surface:
DatasetDefaultInspector.tsx(and a measure-format helper if the guess lives there), i18n keys if any, tests. Tests: empty picker ⇒ saved measure has nocurrencykey; a pickedCNY⇒currency: 'CNY'(control); a loaded measure withcurrency: 'USD'round-trips unchanged. Ablation: restore|| 'USD'⇒ the first test goes red. Stay under 500 changed lines.Serial: open PR #27163 (#27054) edits this file's imports and filter section (not
buildMeasureFormat). Mergeorigin/mainbefore your gates; if #27163 lands first, re-run the inspector tests.Tier
Quote
dispatch-gates --tieron your surface. Expected none.TIER_DEFAULT, effortlow.Clause-②: no,Metadata-protocol: none.@object-ui/app-shellis private:skip-changesetunless you change a published package (then a patch changeset for it).objectstack-fleet commentedon Oct 28, 2026
Claim: PM loop round 18 · 2026-10-28T09:29Z
Session:
session_01JQwxbZeBv2y91towxasSUT(seat; implementation by card thread sessionsession_01JQwxbakr3SQTyXX1NuZkt3,mode:thread)Account:
os-warren(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-0rmmxq(the card thread's harness push branch, self-reported — the measured platform exception toclaude/issue-N-slug)Worktree:
objectstack-issue-27156in the card thread's cloneDomain:
domain:uiSeat:
domain:ui#1(seat post #25966)File surface:
ui/packages/app-shell/src/views/metadata-admin/inspectors/DatasetDefaultInspector.tsx(and a measure-format helper if the guess lives there), i18n keys if any, + tests (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(the dev quotesdispatch-gates --tieron the surface),effort: lowClause-②: no
Metadata-protocol: none
Responsibility: the Studio dataset inspector (this lane's code) | the analytics currency chain and ruling 6464202770 on #27119 | a CNY organization's dashboard cells show
$with no errorThread-read: none
Premise: holds —
currency: currency || 'USD'is atDatasetDefaultInspector.tsxL215 onorigin/mainb8615afa.Serial constraints cleared: open PR #27163 (#27054) edits this file's imports and filter section, not
buildMeasureFormat; the dev mergesorigin/mainbefore the gates.Resume-from: none
Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
os-dev-report
{ "issue": 27156, "status": "done", "branch": "claude/project-thread-0rmmxq", "pr": "https://github.com/objectstack-ai/objectstack/pull/27208", "session": "session_01JQwxbakr3SQTyXX1NuZkt3 — card thread session, mode:thread", "premise_still_valid": true, "summary": "buildMeasureFormat no longer falls back to 'USD' and the currency picker no longer pre-selects USD; a new writeMeasureFormat drops unset format/currency keys so the saved measure carries no currency key. Over a currency-type field the picker defaults to an inherit row; over other fields it asks for a code (the runtime gives non-monetary measures no code, so inherit would resolve to nothing: mechanism assumption partly disproved, route chosen per the ruling's intent). parseMeasureFormat reads a code-less format over a currency field back as Currency · inherit; the picked kind is held in component state until a code is chosen. Stored currency 'USD' left as authored, no migration.", "tests": "head 77475026: DatasetDefaultInspector.currencyNoGuess-27156.test.tsx 6/6 + DatasetDefaultInspector.test.tsx + ui scripts/ = 177 files passed, 5040 tests passed, 2 skipped (lock VERDICT command-exit 0). dcfac927: inspectors dir + packages/i18n = 286 files, 4116 passed, 14 skipped. type-check app-shell + i18n exit 0. Ablation on committed fix via ablation-replace.mjs (anchor 'currency: currency || undefined };' to 'currency: currency || 'USD' };'): 2 failed / 4 passed, the empty-pick case red; restore blob 10ecdd83 == HEAD, git diff HEAD empty. No dist leg: app-shell tests import the inspector by relative path.", "gates": "dispatch-gates --commands on head 77475026: 34 families, every one exit 0 (exit captured before any pipe); --ran: 34 derived, 34 run, 0 NOT-MEASURED. Extra: ui check:new-line-citations 0 new, exit 0; eslint on 4 changed files 0 errors. --tier: no path-derived mandate, TIER_DEFAULT; 233 changed lines. CI check-runs: in_progress at report time.", "line_budget": "233 changed lines (+223/-10) vs 500 order cap", "files_changed": [ "ui/packages/app-shell/src/views/metadata-admin/inspectors/DatasetDefaultInspector.tsx", "ui/packages/app-shell/src/views/metadata-admin/inspectors/DatasetDefaultInspector.currencyNoGuess-27156.test.tsx", "ui/packages/i18n/src/namespaces/studio/en.ts", "ui/packages/i18n/src/namespaces/studio/zh.ts", ".changeset/27156-dataset-inspector-no-currency-guess.md" ], "deviations": [ "@object-ui/i18n is published, so a patch changeset ships instead of skip-changeset (the order expected skip-changeset only if no published package changed)", "picker inherit row offered only over currency-type fields, not for every measure (measured runtime monetary predicate)", "PR body folds .github/PULL_REQUEST_TEMPLATE.md headings (Why, Human Minimum) into the os-dev section order", "PR body line 2 carries the platform requested-by line under the attribution comment" ], "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "2 — relay pr_create (POST pulls + assignee, run 40672905620); this report via post-stamped (POST issues/27156/comments). git push is not a REST write.", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted in PR Acceptance notes, not filed: the format sample shows a plain number for an inherit measure; the formatKind.currency label shows a dollar example; Number over a currency field reads back as Currency (runtime always attaches a currency)" ] }objectstack-fleet commentedon Oct 28, 2026
Landed · seat
domain:ui#1·session_01JQwxbZeBv2y91towxasSUT· 2026-10-28T11:45ZPR #27208 merged as
48bffe389e(seat record: PR comment 6467000658, addendum 6467637918). The Studio dataset inspector no longer stores a guessedcurrency: 'USD', and its picker no longer pre-selects USD. Over acurrencyfield the picker opens on "Inherit — field or organization default", and the saved measure carries nocurrencykey, so it resolves the field's fixed currency and then the tenant default (ruling 6464202770 on #27119). Over any other field the picker asks for a code. A stored code,'USD'included, is left as authored. The road to merge took one queue ejection, the foreseen conflict with #27163.pm:dispatchedis removed with the close.Generated by Claude Code