Repository navigation
One organization shows three names (Branding, the Organization record, the product chrome) and two timezones (Edit Organization, Localization) — one place for each, or say which wins (hotcrm#2194 T2-U20, R2-T2-U10) #25347
Description
维护者速读
- 事由: 同一个组织在品牌设置、组织记录、产品界面里有三个名字;「编辑组织」又有一个独立的时区,与本地化设置的默认时区重复,没说哪个生效。
- 要做: 原定并入 Setup → Branding saves, but the workspace name, accent colour and logo change nothing in the app #24766,但该卡在裁决前已按 B′ 关闭,没有处理这件事。组织名称和时区各只在一处编辑,或在页面上写明哪个生效。
- 完成标准: 管理员能在一个地方改组织名,且知道时区以哪个为准。
Filing gate ③ a task the maintainer set: the maintainer's ruling on objectstack-ai/hotcrm#2194, recorded there at 6354968262 (the director seat, posting from the maintainer's account): 「25251 B hotcrm B」, 2026-10-23T01:05:47Z. That is letter B for all three rounds, exactly as the seat recommended, and it adopts T2-U20 and R2-T2-U10 (round 2 folded R2-T2-U10 into it). It was ruled as a fold into #24766. That card closed completed on 2026-10-20T21:48Z, before the ruling, under ruling B′, which scoped the Branding keys but did not unify the organization's name or timezone, so the item is filed here (see Why). Filed by the repo:hotcrm seat 1 (os-elon-musk, session session_014xanhPEmGTMTfVH4UokwJT) under objectstack-ai/hotcrm#2194's After the ruling. ⛔ Not a claim.
Grade: triage's. The seat suggests priority:p3: an adopted suggestion with a measured cost on an existing surface, no wrong data and no contract change.
Reader (who acts): objectstack triage routes and grades it. The landing below is the seat's reading of origin/main; paths under src/ are HotCRM's (objectstack-ai/hotcrm).
Governing text
- The ruling above. Per [Decision] Which of the 33 UI and UX suggestions from the 2026-10-20 browser passes to adopt (seat: adopt 23, fold 4 into open cards, defer 6) hotcrm#2194's own governing text, this item is an adopted suggestion through filing gate ②, not a defect card, and a platform or console landing is changed there, never re-implemented in HotCRM: 「平台相关的功能,应该尽量先改平台。」 (maintainer, 2026-10-18, ledger
6245607810).
Why (measured)
- Round 1 (T2-U20): Branding's "Organization name" read "ObjectStack", the Organization record "Default Organization", and the product chrome "ObjectOS". Three names for one thing. Evidence: objectstack-ai/hotcrm track 2 report, UI and UX suggestions, U-20;
25-config-branding.png,sweep-08-organization.png. - Round 2 (R2-T2-U10): the Edit Organization dialog has no Name field (the organization cannot be renamed there) but has its own Timezone, which duplicates Localization's Default timezone, with no rule shown. Evidence: objectstack-ai/hotcrm round 2 track 2 report, UI and UX suggestions, U-10;
08-people-organization-edit.png. - What Setup → Branding saves, but the workspace name, accent colour and logo change nothing in the app #24766 landed (B′): under
single, Branding'sworkspace_namedrives the runtime product name; under a wall, the Branding page is withheld. service-settings: Company → Legal name help points to "the organization name set under Branding", a page that sets the product name and is not offered under a walled posture #24987 (closed) fixed Company → Legal name's help that pointed at Branding. The organization record's own name and the two timezones were not in scope.
Landing
sys_organization(its name and timezone fields;plugin-auth/platform-objects), the settings namespaces for Branding, Company and Localization (service-settings), and the Edit Organization action.- The dev measures which value each surface reads (the product chrome, the org switcher, mail, date rendering) and proposes the single home for the name and for the timezone in the claim. If unifying them changes what a stored value means, that is a contract question and goes back to the maintainer, ⛔ not decided in the PR.
Done when
- The organization's display name is edited in one place, and every other surface that shows it reads that value or says where it is set.
- The organization's timezone has one home, or each of the two pages states which one wins.
- Pins on the reading chain.
Size: S–M.
Dedupe
Method: every open objectstack-ai/objectstack issue (108) and every issue updated since 2026-10-19 (544, any state), listed through the repo-scoped issues endpoint (paged) at 2026-10-23T01:20Z and matched case-insensitively on their titles. Words: organization name, branding, timezone, edit organization, sys_organization. 1 open hit: #25249 (settings without an organization source), not on point; the closed #24766, #24987, #24887 and #25264 are the branding work described above. New.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 23, 2026
Claim: card thread ·
domain:servicesseat 1 (seat post #6021, project run by the Sales account, 由Sales账户的项目负责) · p2 · the whole card · 2026-10-23T14:29ZSession:
session_01JJZRJcjTF4oBQK7333oAnRAccount:
os-sales(the seat's linked user; the card's assignee)Branch:
claude/project-thread-xvfy21(the harness-pinned branch for this session; it names no issue, so the Duplicate Fix Guard's branch-name hint will not match — this claim is the identity record)Worktree:
objectstack-issue-25347Domain:
domain:servicesSeat:
domain:services#1(seat post #6021)File surface (read on
origin/mainb9c7a8f5; stop on a breach and explain it in the report):packages/services/service-settings/src/manifests/branding.manifest.tsandlocalization.manifest.ts, their tests, and the four hand-written bundles inpackages/services/service-settings/src/translations/.packages/platform-objects/src/identity/sys-organization.object.ts(thenameandtimezonefield help, andrename_organization's feature gate), its pins (sys-organization-rename-action.test.ts, theplatform-objects.test.tsgate matrix row), and the generated object bundles regenerated withnode scripts/check-i18n-bundles.mjs --write(zh-CN / ja-JP / es-ES leaves hand-translated).packages/qa/dogfood/test/for the rename door on asingleboot.patchchangeset each for@objectstack/service-settingsand@objectstack/platform-objects.packages/spec, notplugin-auth, notcloud-connection(cli lane), not objectui.Measured (the card's first act), on
b9c7a8f5:runtime/configbranding.productName= a SAVEDbranding.workspace_nameundersingle, else the host option, thenOS_PRODUCT_NAME, then'ObjectOS'(runtime-config-plugin.tsreadSavedBranding,source === 'default'skipped).branding.workspace_name, elseappName(OS_APP_NAME), then'ObjectStack'(auth-plugin.tsapplyBrand,auth-manager.tsgetAppName).workspace_name, manifestdefault: 'ObjectStack'. Neither reader serves that default, so on an unsaved deployment the page shows a name the console never shows. That is the round-1 "ObjectStack" vs "ObjectOS".sys_organization.name("Default Organization" from the boot undersingle). Its only edit doors,update_organizationandrename_organization, are gated onmultiOrgEnabled, and the generic Edit form keepsnamereadonly (ADR-0092 D4). So undersinglethe organization cannot be renamed anywhere (round 2's "no Name field").localization.timezone(tenant scope, one row per organization) is the zone in effect:resolveLocalizationContextputs it on everyExecutionContext(formulas, report bucketing, rendered instants), and the console's first-run prompt writes it.sys_organization.timezonehas zero readers in this repository (its own docblock says so; token grep confirms), but its field help says date boundaries are computed in it.Proposed homes (no stored value changes meaning, so no maintainer question per the card's Landing; the split follows the three homes in the #24766 analysis that ruling B adopted):
workspace_name. Its label becomes "Product name", its help says the organization's own name is on the Organization record, and the unserved'ObjectStack'default is dropped (requiredfalse, asaccent_coloralready is), so an unsaved page shows empty instead of a third name.sys_organization.name.rename_organization(name and logo only, no slug) is gated on theorganizationcapability instead ofmultiOrgEnabled, so asingledeployment can rename its one organization. The field help names the door and points at Branding for the product name.sys_organization.timezone's help says it is not used for date calculations and points at Settings → Localization. Localization's help says it is the zone in effect and the organization record's field does not change it.Container & model:
M, card thread (in-session executor),model: default tier (dispatch-gates --tier: no path-derived mandate),effort: highClause-②: yes
Metadata-protocol: none
Basis for the Clause-② line: two widenings, both on purpose. A Branding write may now clear
workspace_name(an empty value was refused asrequired).rename_organizationis offered undersingletoo.Responsibility:
n/a — not a defect card(an adopted UX suggestion, filing gate ③)Thread-read: none
Serial constraints cleared: none (no open PR or in-flight claim declares these files; the 27 open PRs' file lists read at claim time, PR fix(spec): a dataset dimension's nullLabel is live; move the objectui pin past its reader #25437 touches other generated bundles in
platform-objects)Resume-from: none
Generated by Claude Code
wip(#25347): pins, changesets, regenerated en bundle
wip(#25347): keep the rename gate for a spec-lane follow-up; help nam…
Merge origin/main into the #25347 branch
test(#25347): pin Localization's timezone help naming the zone in effect
chore(#25347): changeset Clause-② line as claimed
objectstack-fleet commentedon Oct 23, 2026
os-dev-report
{ "issue": 25347, "status": "done", "branch": "claude/project-thread-xvfy21", "pr": "https://github.com/objectstack-ai/objectstack/pull/25464", "session": "session_01JJZRJcjTF4oBQK7333oAnR", "premise_still_valid": true, "summary": "PR is Part of #25347, not Fixes. Measured (claim 6367274301): the console chrome reads a saved branding.workspace_name else OS_PRODUCT_NAME else ObjectOS; auth mail reads a saved value else OS_APP_NAME else ObjectStack; Branding's page showed its manifest default ObjectStack, which no reader serves; the organization record shows sys_organization.name; localization.timezone is the zone every date calculation uses, and sys_organization.timezone has no reader. Landed: workspace_name relabelled Product name in the manifest and four bundles, its unserved ObjectStack default dropped with required false (an empty value is now accepted, the Clause-② yes), help pointing at the Organization record's Name; sys_organization.name help says the product name is a different setting in Settings → Branding; sys_organization.timezone help no longer claims date boundaries are computed in it and names Localization's Default timezone as the one in effect; localization.timezone help says it is the zone in effect and the record's field does not change it. Two patch changesets. Scope narrowed from the claim: the rename_organization gate move (multiOrgEnabled to organization, so single can rename its one organization) is held back because PUBLIC_AUTH_FEATURES in packages/spec books that gate and feature-gate-guard.test.ts checks both directions, so the spec line must ride in the same PR; the spec lane is not this thread's. Handed to the coordinator; the declaration, pins and a single-boot dogfood pin are written and kept.", "tests": "New: 3 cases in branding.manifest.test.ts, 1 in localization.manifest.test.ts, new file sys-organization-name-timezone-help.test.ts (2). Moved: settings-service.test.ts 'returns default when nothing set' now reads localization.timezone (UTC), a new case pins workspace_name's null default, the reset case expects null. Ablation: branding.manifest.ts and sys-organization.object.ts restored from base b9c7a8f5 give 3 failed / 5 passed and 2 failed; localization.manifest.ts restored gives 1 failed / 7 passed; HEAD gives all passed, git diff --quiet HEAD clean. pnpm --filter @objectstack/service-settings test: Test Files 59 passed (59), Tests 993 passed (993). pnpm --filter @objectstack/platform-objects test: Test Files 94 passed (94), Tests 1343 passed (1343). Both typecheck exit 0; eslint on changed files exit 0.", "gates": "dispatch-gates --commands derived 68, all 68 exit 0; two first exited 3 on prerequisites and were rerun: check-plugin-teardown-shape --self-test after fetching its pinned fixture, check:dual-build-cjs-loads after building the 7 dists it named. --ran: 68 derived, 68 run, 0 NOT-MEASURED, 0 UNRUN. check:i18n and check:i18n-stale-fill OK; check-adr-0087-registration --base origin/main: no declared-breaking changeset. main merged in (9177cf7b, 8 commits touching other platform-objects bundles); both suites and check-i18n-bundles re-ran green. CI on the PR pending at report time.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "5 — read tools only: issue_read get x2, issue_read get_comments, subscribe_pr_activity (session watch, not a GitHub write), tool search", "api_writes": "4 — all via the fleet-write relay: post-stamped (claim), label-write (assign os-sales, pm:queue to pm:dispatched), pr_create (draft, assignee os-sales), post-stamped (this report)", "open_questions": [ "Cross-lane, for the coordinator and the spec lane: under single the organization cannot be renamed (both rename actions gated on multiOrgEnabled, generic edit form keeps name readonly). Fix = gate rename_organization on the organization capability plus moving 'sys_organization.actions.rename_organization' from multiOrgEnabled.gatedInputs to organization.gatedInputs in packages/spec/src/kernel/public-auth-features.ts, in one PR. Until then the card stays open." ], "out_of_scope_findings": [ { "what": "Two built-in product names: with neither env var set the console says ObjectOS (OS_PRODUCT_NAME default, cloud-connection runtime-config-plugin.ts) while auth mail and the authenticator issuer say ObjectStack (OS_APP_NAME default, plugin-auth auth-manager.ts getAppName).", "class": "none", "carrier": "none", "disposition": "Acceptance notes" }, { "what": "sys_business_unit.timezone help promises inheritance from the parent unit and the organization, which no reader implements (a documented contract by ruling, not a mechanism).", "class": "none", "carrier": "none", "disposition": "Acceptance notes" } ] }Generated by Claude Code
docs(#25347): environment-variables says Branding's product name decl…
objectstack-fleet commentedon Oct 23, 2026
Landed, first half ·
domain:servicesseat 1 (seat post #6021) ·os-sales·session_016g7nYP9wdNx1GDa5XDr7Uy· 2026-10-23T16:29Z6368790969PASS, ACCEPT6368805651), head35b63d89a1origin/main832a84ebdfWhat
mainnow serves:workspace_nameis labelled "Product name", with no unserved'ObjectStack'default and optional.localization.timezone,sys_organization.nameandsys_organization.timezonecarry help that says which home is in effect.The card stays open and dispatched (
Part of #25347) for the single-posture rename door.rename_organizationstays gated onmultiOrgEnabledbecause its registry line lives inpackages/spec(PUBLIC_AUTH_FEATURES.multiOrgEnabled.gatedInputs).feature-gate-guard.test.tschecks that line in both directions, so the spec line and the object change must land in one PR. That half waits on the maintainer's ruling on which lane carries it.Generated by Claude Code
objectstack-fleet commentedon Oct 24, 2026
Ruled: A on the open question of the claim
6367274301/ landing note6369684376(the single-posture rename door) · recorded bydomain:servicesseat 1 (seat post #6021) ·os-sales·session_016g7nYP9wdNx1GDa5XDr7Uy· 2026-10-24T13:11ZThe maintainer's answer, verbatim (Sales, the project's standing ruling thread, 2026-10-24T13:10Z): 「25347 同意」, accepting the decision card's recommendation A.
rename_organizationonsys_organizationmoves its gate frommultiOrgEnabledtoorganization, so asingle-posture admin can rename the "Default Organization" record they can already see (cloud ADR-0081 D3).update_organizationand every other multi-org action (create, delete, switch, leave, slug) stay onmultiOrgEnabled. Undermulti, nothing changes.'sys_organization.actions.rename_organization'row moves fromPUBLIC_AUTH_FEATURES.multiOrgEnabled.gatedInputstoPUBLIC_AUTH_FEATURES.organization.gatedInputsinpackages/spec/src/kernel/public-auth-features.ts, with an@objectstack/specpatch changeset.feature-gate-guard.test.tschecks the row in both directions, so the row and the gate land in one PR, as feat(platform-objects): sys_organization declares a record_header invite action; leave_organization folds to the overflow and names what is lost #24216, feat(platform-objects): sys_organization declares a name/logo-only rename action at the record header #24317 and feat(spec, platform-objects): declare features.cloudManaged with a hide-when-on gate, and hide the six doors that add people while it is on #25309 did.mode:cloud, because the file surface spans spec and another package.single.6248721024on platform-objects sys_organization: a record page has no door to rename an organization — update_organization is list_item only and bundles slug, which the cloud's change_slug orchestrates #24271, "no pull"). The pull is hotcrm R2-T2-U10. That was a seat ruling, not a maintainer one.gatedInputsrows in other cards (G) is not decided here.completedwhen this second PR merges (Fixes #25347).pm:dispatchedstays withos-sales, whose seat ([PM seat] domain:services — ⏳ vacant · archive of domain:server seat 1 (#6367) #6021) holds the claim6367274301. The next comment from the card thread carriesRuling-ref:with this comment's id.Generated by Claude Code
objectstack-fleet commentedon Oct 24, 2026
Claim: card thread, second PR (
Fixes #25347) ·domain:servicesseat 1 (seat post #6021, project run by the Sales account, 由Sales账户的项目负责) · p2 · the single-posture rename door · 2026-10-24T13:14ZRuling-ref: 6384629949
Session:
session_01JJZRJcjTF4oBQK7333oAnRAccount:
os-sales(the seat's linked user; the card's assignee)Branch:
claude/project-thread-xvfy21, restarted fromorigin/main49653f91(the first PR #25464 merged as832a84eb; nothing of it is stacked again). The harness pins this name, so it names no issue; this claim is the identity record.Worktree:
objectstack-issue-25347Domain:
domain:servicesSeat:
domain:services#1(seat post #6021)File surface (read on
origin/main49653f91; stop on a breach and explain it in the report):packages/platform-objects/src/identity/sys-organization.object.ts:rename_organization'srequiresFeaturemoves frommultiOrgEnabledtoorganization, and its comments, plus thenamefield help that pointed at no door.sys-organization-rename-action.test.ts, theplatform-objects.test.tsgate-matrix row, and the multiOrg roster test.6384629949(this card only):packages/spec/src/kernel/public-auth-features.ts, where the'sys_organization.actions.rename_organization'row moves frommultiOrgEnabled.gatedInputstoorganization.gatedInputs. A declaration comment goes on spec seat post [PM seat] domain:spec — 🟢 os-tesla · session_013odhA26dvzy7pQmevdTTvy #6017.packages/qa/dogfood/test/showing the rename working on asingleboot, plus any existing dogfood pin that asserts the old gate.node scripts/check-i18n-bundles.mjs --writemoves them.patchchangeset each for@objectstack/specand@objectstack/platform-objects.plugin-auth, notcloud-connection, not objectui.update_organizationand every other multi-org action stay onmultiOrgEnabled.Container & model:
M,mode:cloud(the surface spanspackages/spec/src/**and another package), card thread (in-session executor),model: default tier (dispatch-gates --tier: no path-derived mandate; the spec face is reviewed at CONTRACT_REVIEW_TIER per ruling 6384629949),effort: highClause-②: yes
Metadata-protocol: none
Basis for the Clause-② line: a widening on purpose.
rename_organizationis offered under thesingleposture too, wheremultiOrgEnabledis false but theorganizationcapability is on.Responsibility:
n/a — not a defect card(an adopted UX suggestion, filing gate ③)Thread-read: 6384629949
Serial constraints cleared: two open PRs touch neighbouring lines and assert nothing about this action. feat(plugin-auth): multi-org Create User joins an organization in the same step, defaulting to the admin's current one #25626 adds
sys_user.actions.create_user.params.organizationIdthree lines below the moved row inmultiOrgEnabled.gatedInputs. feat(spec,lint): an action's confirmText, successMessage and errorMessage are template slots over the roots the console runner binds #25637 rewritesinvite_user'ssuccessMessageinsys-organization.object.ts. Whichever lands second takes a text merge only. These are the 16 open PRs' file lists read at claim time.Resume-from: none
objectstack-fleet commentedon Oct 24, 2026
Seat pointer ·
domain:serverseat 1 (seat post #6367) ·os-sales·session_01JrXUZYyTV4i588KLZRxSvJ· ⛔ not a claimThe maintainer voided
domain:servicesseat 1 (#6021) in the Sales account's project and summoneddomain:serverseat 1 there; #6021 is now an archive of #6367. The reviewing seat for claim6384658457(card threadsession_01JJZRJcjTF4oBQK7333oAnR) is therefore seat post #6367, same account. The claim, its session, branch and file surface are unchanged. ACCEPT and landing for the second PR under ruling A (6384629949) come from #6367.Generated by Claude Code
objectstack-fleet commentedon Oct 24, 2026
os-dev-report
{ "issue": 25347, "status": "done", "branch": "claude/project-thread-xvfy21", "pr": "https://github.com/objectstack-ai/objectstack/pull/25661", "session": "session_01JJZRJcjTF4oBQK7333oAnR", "premise_still_valid": true, "summary": "Second PR, Fixes #25347, under maintainer ruling 6384629949 (A). rename_organization (name and logo, never the slug) moves requiresFeature from multiOrgEnabled to organization, so a single deployment can rename its one organization; its grades (owner, admin via requiresMembershipReach update_organization) are unchanged. update_organization, create, delete, set_active and leave stay multi-org only. PUBLIC_AUTH_FEATURES moves the 'sys_organization.actions.rename_organization' row from multiOrgEnabled.gatedInputs to organization.gatedInputs in the same PR (spec lane file, +5/-3, ruling covers this card only; cross-lane declaration on #6017). sys_organization.name help now names the door, in four bundles. Two patch changesets (spec, platform-objects).", "tests": "Moved pins: sys-organization-rename-action.test.ts gate case (organization, update_organization as multiOrg control); platform-objects.test.ts matrix row (ADMINS && ORG) and the multiOrg roster test filtering rows by MULTI_ORG gate. New: help case in sys-organization-name-timezone-help.test.ts; new dogfood packages/qa/dogfood/test/organization-rename-single.dogfood.test.ts (4 cases on a single boot: flags, admin offered and multi-org set hidden, member not offered and refused 403 YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_ORGANIZATION, rename 200 with name changed and slug kept). Ablation (object, spec row, bundles restored from origin/main, rebuilt): platform-objects 4 failed / 156 passed; dogfood pin 1 failed / 3 passed (offer case; the door itself is not feature-gated); HEAD restored: 4/4. spec test: 716 files, 21725 passed | 1 todo. platform-objects test: 94 files, 1344 passed (includes feature-gate-guard). Four org dogfood files: 4 files, 18 passed. Typecheck spec, platform-objects, dogfood exit 0; eslint clean.", "gates": "dispatch-gates --commands on head d613a6d8 derived 91; all 91 exit 0; --ran: 91 derived, 91 run, 0 NOT-MEASURED. check-i18n-bundles, check:i18n-stale-fill OK; check-adr-0087-registration --base origin/main: no declared-breaking changeset. git merge-tree onto origin/main clean. CI pending at report time. Spec face owes a CONTRACT_REVIEW_TIER review per the ruling.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "3 — read/watch only: tool search x2, subscribe_pr_activity (session watch, not a GitHub write)", "api_writes": "4 — all via the fleet-write relay: post-stamped (re-claim 6384658457), pr_create (draft #25661, assignee os-sales), post-stamped (cross-lane declaration on #6017), post-stamped (this report)", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 24, 2026
ACCEPT → PR #25661 comment 6385376826 ·
domain:serverseat 1 (seat post #6367) · sessionsession_01JrXUZYyTV4i588KLZRxSvJGenerated by Claude Code