Repository navigation
Setup copy: ADR numbers and schema vocabulary leave the object, type and navigation descriptions admins read #23802
Description
Source
Read in the console's Setup app on 2026-10-16 (objectui main 8415d9f11, objectstack 18.0.0-next.1 serving HotCRM). Descriptions an administrator sees under a page title:
- Business Units: "Canonical Business Unit tree — hierarchical org/data-partition node (company / division / department / region / office). ADR-0057 D2." (
packages/platform-objects/src/identity/sys-business-unit.object.ts) - Capability: "Package-declared authorization capability — the DEFINITION side of ADR-0066 D1 (grants live on permission sets; requirements on resources)" (the spec's type description, surfaced through
packages/platform-objects/src/apps/translations/en.metadata-forms.generated.ts) - Permission Set
organization_admin_no_bypass: "… (ADR-0105 D4 / finding F2) …" - Notification Events: "Notification events — one row per emit() (ADR-0030 Layer 2 ingress)" (
packages/platform-objects/src/audit/sys-notification.object.ts) - Notification Preferences: "Per-user × topic × channel notification toggle (mute/allow), with admin-global defaults." (
packages/services/service-messaging/src/objects/notification-preference.object.ts) - Record Shares: "Per-record sharing grant — extends OWD with explicit access"; Approval Delegations: "Self-service out-of-office rule: route this user's approver slots to a delegate within a time window."; Installed Apps: "Note: The kernel API is additive only — uninstall removes the on-disk manifest so the package won't load on next boot…".
These strings are the description / label fields of platform objects, spec types and Setup navigation entries, so they reach every locale through the generated translations.
Target
- Every description an admin reads in Setup is one sentence in the user's words: what the records are and what you do here. ADR numbers, "D2 / D4 / finding F2", "Layer 2 ingress", "emit()", "kernel API", "additive only", "data-partition node" move to the object's docblock or to a
docslink field the console can render as "Learn more". - The sentences for the objects above, as a starting point: Business Units "Your company structure — divisions, departments, regions and offices — used to scope data and reports."; Capability "What a permission set may grant beyond object access: Setup, Studio, user management and the like."; Notification Events "Every notification the platform sent, one row per event."; Notification Preferences "Which topics and channels each user receives; admins set the defaults."; Record Shares "Records shared beyond their owner, one row per grant."; Approval Delegations "Route your approvals to someone else while you are away."
- The generated translation files regenerate from the sources; the zh-CN and ja-JP files follow.
File surface
packages/platform-objects/src/identity/*.object.ts, packages/platform-objects/src/audit/*.object.ts, packages/platform-objects/src/apps/setup.app.ts and setup-nav.contributions.ts (nav descriptions), packages/services/service-messaging/src/objects/*.object.ts, the spec type descriptions in packages/spec that the metadata-forms translations are generated from, the generated translation files. This crosses domain:engine, domain:services and domain:spec: the triage seat names the lane or splits the card (pm:retriage).
Acceptance
- A test (or a lint over the object and app sources) asserts no
descriptionor navlabelunder Setup containsADR-,D\d\b,finding F,emit()orkernel. - The console's Setup pages, re-read after the change, show the new sentences (the epic PM reads them).
pnpm --filter @objectstack/platform-objects test, the translation generation gate andpnpm check:i18ngreen.
Constraints
- Docblocks and ADR links in code stay; only user-facing strings move.
Evidence
Screenshots on the temporary branch claude/console-home-login-design-20261016 of objectstack-ai/objectui (commit 01244b886, never merged): setup-positions-metadata-page.png · setup-capability-metadata-page-small.jpg.
Filed by the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff from the 2026-10-16 second review pass: objectui main 8415d9f11, HotCRM 63db83e2, the vite console on :5180 against objectstack serve --dev on :4001, the Studio pillars and all 43 Setup pages walked in the maintainer's browser pane at 1024 × 768 (en) with a 1280 × 900 re-check (zh). The maintainer asked for every finding to be filed, verbatim: 「全部立卡」.
Activity
objectstack-fleet commentedon Oct 16, 2026
Retriage answered: split · the spec half goes to #23808 (
domain:spec); this card staysdomain:engineon the cross-domain exception path, withservice-messagingdeclared · triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-16T03:59ZRead in this act: the body in full, and the spec registry on
origin/main.packages/spec「恒归本席,不论谁需要它」, so the spec type descriptions cannot ride another lane's PR. The spec half was measured in this act.DEFAULT_METADATA_TYPE_REGISTRYdescriptions inpackages/spec/src/kernel/metadata-plugin.zod.tscarry ADR vocabulary:api,doc,book, andcapability("… the DEFINITION side of ADR-0066 D1 …").domain:spec,pm:queue).packages/platform-objects(objects,setup.app.ts,setup-nav.contributions.ts),packages/services/service-messaging/src/objects/*.object.ts, the generated translations, and the acceptance lint.domain:engine, which holds the majority (packages/platform-objects).service-messagingfile surface to thedomain:servicesseat.en.metadata-forms.generated.tsand the zh-CN / ja-JP files.ADR-,D\d,finding F,emit(),kernelin Setup-visible strings) lands with this card. It sees the spec descriptions only once spec: four metadata type descriptions an admin reads in Setup (api, doc, book, capability) carry ADR numbers and schema vocabulary; the spec half of #23802 #23808 is in.pm:retriageis removed.domain:engine, p2 andpm:queuestand.⛔ Not a claim.
objectstack-fleet commentedon Oct 16, 2026
Claim: PM loop round 1 · 2026-10-16T06:57Z · on the cross-domain exception path named by triage 6207761541
Session:
session_01TQLy3Yq6vF4SDpTXdr3UwiAccount:
os-tesla(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-23802-setup-copyWorktree:
objectstack-issue-23802Domain:
domain:engineSeat:
domain:engine#2(seat post #20966)File surface:
packages/platform-objects/src/**/*.object.ts(description and field-description strings only),packages/platform-objects/src/apps/setup.app.tsandsetup-nav.contributions.ts(nav descriptions and labels),packages/metadata-core/src/objects/sys-metadata*.object.ts(description strings only),packages/services/service-messaging/src/objects/*.object.ts(description strings only; declared todomain:services), the generated translation files of those packages (regenerated, never hand-edited), one test file inpackages/platform-objects(and inservice-messagingif its objects are pinned there), one.changeset/23802-setup-copy.md. Stop on a breach and explain it in the report.Container & model:
M,mode:subagent,model: default(dispatch-gates --tier: no path-derived mandate)Clause-②: no
Responsibility: n/a — not a defect card
Thread-read: 6207761541
Serial constraints cleared: no open PR changes
packages/platform-objects,metadata-coreorservice-messagingexcept the release PR #23825 (versions andCHANGELOG.mdonly). No in-flight claim holds those files: #23816 holdsdriver-tursoand the cli ceremony, #23746 holdsplugin-approvals' served page, #15204's epic has no open stage on these files. #23808 (the spec half) is closed and its #23817 is onmain, so this card regenerates*.metadata-forms.generated.tsafter it. #23803 (Setup navigation) sharessetup.app.ts/setup-nav.contributions.ts: fold-or-serial answered serial (different defect shape: copy versus navigation structure; fold gate ① fails). #23803 is not dispatched and goes back to triage; whichever lands second mergesmain.Scope split at this claim (self-split rule): the descriptions whose producers sit outside this lane and outside triage's declared
service-messaging(plugin-approvals,plugin-security,service-automation,plugin-sharing, and one view-form description inpackages/spec/src/ui/view.form.ts) are carried by #23829, filed bare for triage. This card keepsplatform-objects,metadata-coreandservice-messaging, and its PR saysFixes #23802for those.Acceptance 1, the form this seat dispatches: a unit test inside the package's own suite, not a new
check:*script, lint rule or CI gate (the card allows either; a new gate needs the maintainer's naming).Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 23802,
"status": "done",
"branch": "claude/issue-23802-setup-copy",
"pr": "#23845",
"session": "session_01TQLy3Yq6vF4SDpTXdr3Uwi — subagent run; the parent PM's session id, which the relay stamped on both writes",
"premise_still_valid": true,
"summary": "Setup-visible object descriptions in this lane are rewritten as plain admin sentences. Business Units, Notification Events and Notification Preferences use the card's sentences; Notification Templates and HTTP Deliveries are written in the same voice. Every ADR number, decision id and emit() leaves the user-facing strings of platform-objects, metadata-core (sys_metadata*) and service-messaging objects and moves to the adjacent docblock or comment. zh-CN/ja-JP/es-ES follow: leaf values re-translated by hand where they were real translations; stale English fills were emptied and re-filled by the generator. A unit test in each package's own suite pins the card's patterns over every object it ships, its four objects bundles, and (platform-objects) the type-level metadataForms descriptions plus the Setup app, nav contributions and every locale's apps.setup. PM assumption 1 was incomplete: the built-definition instrument found 15 distinct matching strings, not 7. The 8 extra are sys_user.role, sys_organization.parent_organization_id, sys_invitation.business_unit_id/positions, sys_sso_provider.domain_verified, sys_metadata_activation and sys_http_delivery (Setup-visible through plugin-webhooks' HTTP Deliveries), which the single-line grep missed. Assumption 3 confirmed: no producer in this lane; the Installed Apps note is objectui's. Wording only: no field, index, permission or behaviour change.",
"descriptions_before_after": {
"instrument": "node script loading the BUILT dist of platform-objects, metadata-core and service-messaging (61 objects, multi-line values included), matching /ADR-\d|\bD\d+\b|finding F|\bemit\(\)|\b[kK]ernel\b/ over object label/pluralLabel/description and every field/listView/action label/description/help",
"before_at_1ecb08a1c": "15 distinct strings (17 rows: sys_metadata.environment_id and sys_metadata_audit counted twice via the platform-objects re-export)",
"after_at_a6586f72a": "0",
"setup_visible_object_descriptions_rewritten": [
"sys_business_unit: 'Canonical Business Unit tree — hierarchical org/data-partition node (company / division / department / region / office). ADR-0057 D2.' -> 'Your company structure — divisions, departments, regions and offices — used to scope data and reports.'",
"sys_notification: 'Notification events — one row per emit() (ADR-0030 Layer 2 ingress)' -> 'Every notification the platform sent, one row per event.'",
"sys_http_delivery: 'Durable outbox row for one outbound-HTTP attempt (ADR-0018). Managed by @objectstack/service-messaging; do not write directly.' -> 'Outgoing HTTP calls made by webhooks and flows, one row per call, with its delivery status.'",
"sys_notification_preference (vocabulary, no pattern): 'Per-user × topic × channel notification toggle (mute/allow), with admin-global defaults.' -> 'Which topics and channels each user receives; admins set the defaults.'",
"sys_notification_template (vocabulary, no pattern): 'Per (topic × channel × locale) render template for notifications.' -> 'The subject and body each notification topic sends, per channel and language.'"
],
"setup_visible_field_help_reference_removed": [
"sys_user.role '(ADR-0068 D2)'",
"sys_user.manager_id '(ADR-0057 / @objectstack/security-enterprise)'",
"sys_user.primary_business_unit_id '(ADR-0057 addendum D12)'",
"sys_organization.parent_organization_id '(ADR-0105 D6)'",
"sys_invitation.business_unit_id '(ADR-0105 D8)'",
"sys_invitation.positions '(ADR-0105 D8)'",
"sys_sso_provider.domain_verified '(ADR-0135 D6)'"
],
"judged_not_setup_visible_reference_removed": [
"sys_metadata_audit '(ADR-0010)'",
"sys_metadata_commit '(ADR-0067)'",
"sys_metadata.environment_id '(ADR-0131 D6)'",
"sys_metadata_activation '(ADR-0126 §4)'",
"sys_notification_delivery '(ADR-0030 Layer 4)'"
],
"setup_visibility_basis": "nav entries of the 12 packages declaring app: 'setup' contributions (platform-objects, plugin-auth sys_sso_provider, service-messaging preference/subscription/template, plugin-webhooks sys_http_delivery, ...); none names a sys_metadata* object or sys_notification_delivery. They were edited anyway: they are in the claimed surface, three ship in the platform-objects bundles to every locale, and the whole-population pin needs no hand-kept Setup roster.",
"nav": "setup.app.ts and setup-nav.contributions.ts: 0 matches before, no nav string changed"
},
"tests": "HEAD a6586f7: pnpm --filter @objectstack/platform-objects test -> 71 files / 1103 tests passed; pnpm --filter @objectstack/service-messaging test -> 51 files / 574 passed; pnpm --filter @objectstack/metadata-core test -> 18 files / 733 passed (run at 3b5ffa1; no metadata-core change after it). typecheck of the three packages exit 0; both new test files counted in their tsc programs via --listFiles. Ablation, four legs through scripts/ablation-replace.mjs (WRAP mode, trap restore, blob == HEAD and git diff HEAD empty after each): (A) 'ADR-0057 D2.' re-added to the sys_business_unit source description -> object test red '1 failed | 10 passed', naming sys_business_unit.description; (B) old emit()/ADR sentence restored in zh-CN.objects.generated.ts -> zh-CN bundle test red; (C) '(ADR-0030 Layer 3)' added to sys_notification_preference -> messaging object test red '1 failed | 5 passed'; (D) '(ADR-0067)' added to sys_metadata_commit, metadata-core rebuilt, ablation-dist-preflight 'marker present in 4 built files' -> object test red; restore leg: rebuild, preflight --absent 'marker absent from all 12 built files' plus 'working tree clean', then suite 11/11 green. Direction observed: red in all four legs, as predicted.",
"gates": "Local, HEAD a6586f7. dispatch-gates --commands --repo objectstack-ai/objectstack derived 66 families; each run with its exit code captured before any pipe: 65 exit 0, pnpm check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET (reads every package's dist; this worktree built only the CLI closure) -> NOT MEASURED, left to CI. --ran reconciliation: '66 derived famil(ies) accounted for — 65 run, 1 NOT-MEASURED, 0 UNRUN' (exit 0). Card acceptance 3: pnpm --filter @objectstack/platform-objects test green; pnpm check:i18n exit 0 ('all bundles in sync'); pnpm check:i18n-stale-fill exit 0 ('0 stale-fill'); pnpm check:i18n-coverage exit 0 ('none new'). Full derivation read: 52 artifact-roster families (3 marked as having their roster in one of this PR's directories: check-changeset-fixed, check:authz-resolver, check:filter-alias-parity) and 11 declared wide-population families, all left to CI. CI on head a6586f7 at report time: 11 success (Governed Surface Queue Guard, Check PR Size, The card this PR closes must claim this branch, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Part-of PR must not also close its card, Dogfood Regression Gate, Check Documentation Links, Flag docs affected by code changes, Auto Label, filter), 6 skipped (Build Docs, Console Pin Gate, Dogfood Verify CLI, Dogfood Regression Gate shards, Temporal Conformance, Packed-tarball smoke), 20 in_progress (Lint lanes, Type Check lanes, Check Changeset among them; Test Core and Build Core not yet listed). Not waited on.",
"mcp_calls": "0",
"api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches, each executed by fleet-write.yml as objectstack-fleet[bot]): (1) pr_create -> POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/23845/assignees [os-tesla], body read back 10556/10556 bytes identical; (2) this os-dev-report comment -> POST /repos//issues/23802/comments. Plus git push of claude/issue-23802-setup-copy (not a REST write). No label writes.",
"files_changed": "27 files, +424/-86 (510 changed lines, under the 3000 human-merge threshold): .changeset/23802-setup-copy.md; metadata-core sys-metadata{,-audit,-commit}.object.ts; platform-objects identity/sys-{user,organization,invitation,business-unit,sso-provider}.object.ts, audit/sys-notification.object.ts, system/sys-metadata-activation.object.ts, apps/setup-copy-vocabulary.test.ts (new), apps/translations/{en,zh-CN,ja-JP,es-ES}.objects.generated.ts; service-messaging objects/{http-delivery,notification-delivery,notification-preference,notification-template}.object.ts, objects/admin-copy-vocabulary.test.ts (new), translations/{en,zh-CN,ja-JP,es-ES}.objects.generated.ts, translations/{ja-JP,es-ES}.source-hashes.generated.ts (generator-written).",
"deviations": [
"Dispatch binding 'generated translation files are regenerated with the repo's generator, never hand-edited' vs the generator's own contract (AGENTS.md Documentation Guardrails and each generated file's header: translated-locale leaf VALUES are hand-written; merge mode never updates a translated leaf whose source moved). Followed the contract. Leaf values only were hand-edited: 11 x 3 locales in platform-objects and 4 in service-messaging zh-CN. 8 stale English fills (service-messaging ja-JP/es-ES) were emptied so the generator re-filled them. The en bundles and every source-hashes table were written by the generator alone, and no key was added or removed.",
"Merged origin/main once before opening the PR (43567a8, CI scripts only, no overlap), so the derivation was not stale.",
"The harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer. AGENTS.md wins: model-free trailer pair (the pre-push hook enforces it) and the session-URL footer.",
"Field help with an ADR reference lost only the reference (the rest kept verbatim). Only object descriptions were rewritten in the admin's words, a narrower reading of 'same voice' that the PR body states."
],
"line_budget": "n/a (no skills/** or governed surface touched; .changeset and package sources only)",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: named producer — packages/spec/src/security/permission.form.ts (isDefault, managedBy, packageId, adminScope helpText: 'ADR-0090 D5', 'ADR-0086 D3', 'ADR-0090 D12') and packages/spec/src/identity/position.form.ts:39 (delegatable, 'ADR-0091 D3') at 1ecb08a. They are served through platform-objects en.metadata-forms.generated.ts (lines ~2326-2342, 2387) on the Setup Permission Sets / Positions edit forms (nav_permission_sets / nav_positions open /apps/setup/metadata/permission and /position). This is the same family as this card; it belongs in the family closure card #23829 (spec form copy, like view.form.ts) rather than a single-point card · dedupe words: permission.form helpText ADR, position.form delegatable ADR-0091, Setup form help ADR numbers",
"class: a · reach: Setup -> Installed Apps page, read by the epic PM on 2026-10-16 (this card's Source) · evidence: the producer is objectui, not cloud-connection: packages/i18n/src/locales/en.ts:4120 key installedAdditiveNote ('The kernel API is additive only — …'), plus de/es/zh/ja/ko/ru/fr/ar/pt, rendered by packages/app-shell/src/console/marketplace/InstalledListWidget.tsx at objectui 63d00da. packages/cloud-connection/src/cloud-connection-route-ledger.ts:229 is a route-ledger note, not served copy. Same family; fold into #23829 or an objectui sibling at the PM's call · dedupe words: installedAdditiveNote, kernel API is additive only, Installed Apps note",
"carrier: none · noted, not filed: sys_notification_subscription keeps its description because its docblock records that the subscription expansion is not wired; a 'who receives this topic' sentence would advertise undelivered behaviour. Studio-only metadata-form helpTexts (object/field/view/action/agent/skill) also carry ADR numbers but are outside Setup. Both are in the PR's Acceptance notes."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
ACCEPT → PR #23845 comment 6211690151 ·
domain:engineseat 2 ·session_01TQLy3Yq6vF4SDpTXdr3Uwi· 2026-10-16T08:45Z. Landing next: ready, then auto-merge through the queue.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Landing record: PR #23845 →
30ce56e803·domain:engineseat 2 ·session_01TQLy3Yq6vF4SDpTXdr3Uwi· 2026-10-16T09:17Zmerged: true, merge commit30ce56e803, merged 2026-10-16T09:16Z through the merge queueorigin/main30ce56e80isorigin/main's tip;sys-business-unit.object.tsthere carries the new sentence;.changeset/23802-setup-copy.mdis presentgh-readonly-queue/main/*pr-23845*head remainsState change: this card closed
completedbyFixes #23802;pm:dispatchedremoved in this act. No other card closed with it (closed since 2026-10-16T09:10Z: this card only).Carried elsewhere: the producers outside this card's packages, and the dev's two same-family findings (spec form help texts, objectui's Installed Apps note), are on #23829. Acceptance 2 (the console re-read of the Setup pages) is the epic PM's, per the card.
Generated by Claude Code