Repository navigation
fix(setup-copy): approval, security, automation and sharing descriptions read as admin copy; ADR numbers move to comments - #23917
Conversation
…ons carry no ADR numbers Object and field descriptions an administrator reads in Setup are rewritten in the admin's words; ADR numbers and decision ids move to comments beside the strings. Wording only. Claude-Session: https://claude.ai/code/session_018VqJPGA1NDNSCZsnecsChP Co-authored-by: Claude <noreply@anthropic.com>
…rom the new descriptions Translated leaves whose source moved are re-translated in place (leaf values only); English fills with recorded provenance were emptied and refilled by `check-i18n-bundles --write`, which also refreshed their source hashes. Claude-Session: https://claude.ai/code/session_018VqJPGA1NDNSCZsnecsChP Co-authored-by: Claude <noreply@anthropic.com>
… vocabulary One unit test per package (approvals, security, sharing, automation), in the form the service-messaging pin landed: every object the package ships, the security permission sets, and every leaf of the package's objects bundles. Claude-Session: https://claude.ai/code/session_018VqJPGA1NDNSCZsnecsChP Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018VqJPGA1NDNSCZsnecsChP Co-authored-by: Claude <noreply@anthropic.com>
…tup-copy-services
📓 Docs Drift CheckThis PR changes 4 package(s): 17 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 12 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 20 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 8f0ffd74b306d4238d496b7a3ac788d979276373 && git checkout 8f0ffd74b306d4238d496b7a3ac788d979276373
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin d5666be8769a18c5c8d7695b3ac9100af2394620 85fb81cfd1db2eebc634ef41eb7e3e49e11c45c8 && git checkout -B drift-repro d5666be8769a18c5c8d7695b3ac9100af2394620 && git merge --no-ff 85fb81cfd1db2eebc634ef41eb7e3e49e11c45c8
node scripts/docs-audit/affected-docs.mjs --json d5666be8769a18c5c8d7695b3ac9100af2394620
|
席位核对 · review ·
|
席位核对 · ACCEPT ·
|
Fixes #23829
Clause-②: no
What changed
The sentence an administrator reads under a Setup page title is the object's
description; a field's help tooltip is the field'sdescription; the Permission Sets page lists each shipped set with itsdescription. This PR rewrites those strings in the fourdomain:servicespackages the card names (plugin-approvals,plugin-security,service-automation,plugin-sharing) and moves every ADR number, decision id and review-finding id out of the strings into a comment beside each one or the docblock that already cites it. Docblocks and ADR links in code stay. Wording only: no field, index, permission or behaviour change.Form copied from #23845 (the parent #23802's landed PR): field help keeps its operational text and loses only the design-record reference; object descriptions are rewritten as one sentence.
Before / after
Measured by loading every object each package exports from
src(13 objects, every string leaf at any depth, multi-line values included) plusplugin-security's 8 shipped permission sets, against the card's patterns (ADR-followed by a digit, a decision id such as D2,finding F,emit(),kernel). Before, at base94114c1f26: 26 object strings and 3 permission-set descriptions matched. After: 0 and 0. The card's own reading (single-line values only) had found 9 of the 29.Object descriptions, rewritten:
sys_approval_delegation(Approvals, Delegations (OOO))sys_record_share(Access Control, Record Shares)sys_user_position(a user's Positions list, View all)sys_audience_binding_suggestion(no Setup page)sys_automation_run(no Setup page)The Approval Delegations sentence departs from the card's starting sentence ("Route your approvals to someone else while you are away.") on purpose:
ApprovalService.expandApproversreroutes only individually-routed approvers (user/field/manager); team, department, position and membership-level approvers are not rerouted, so "your approvals" would promise more than the runtime does. The comment beside the string says so.Field help and other strings, the design-record reference removed and the rest unchanged:
sys_approval_request:flow_run_id,flow_node_id,node_config_json("(ADR-0019)"; the section comment already cites it).sys_approval_delegation.valid_from("(ADR-0091 D2 predicate)").sys_audience_binding_suggestion:package_id("ADR-0086 D3 provenance"),anchor("ADR-0090 D9").sys_user_position:business_unit_id,valid_from,valid_until,reason,delegated_from,last_certified_at,certified_by(the "[ADR-0091 Dn]" / "[ADR-0090 Addendum]" prefixes and the "(D2)", "(D3)", "(D4)", "(D12)" ids), and thereserved_identity_positionvalidation's description ("ADR-0068 D2").organization_admin_no_bypass: "(ADR-0105 D4 / finding F2)". Its producer isderiveWallLessOrgAdmininpackages/plugins/plugin-security/src/objects/default-permission-sets.ts; the card's reading missed it because the description is a multi-line concatenation.Beyond the card's list, in the same packages
These sit in the four packages but not in the card's list. Each is the same defect (design-record vocabulary in admin copy), the fix is the same mechanical removal, no open PR touches the file, and each is covered by the same pin and bundle family, so it is fixed here rather than reported. Without them, each package's pin over every object it ships would be red.
sys_user_permission_set(plugin-security; a user's Permission Sets list and its grant form):permission_set,valid_from,valid_until,reason,last_certified_at,certified_byhelp and thevalidity_window_ordervalidation's description. These are the byte-identical "[ADR-0091 Dn]" phrases of the siblingsys_user_position, in the same bundle.mcp_agent_data_readandmcp_agent_data_write(same producer file asorganization_admin_no_bypass): "via the ADR-0090 D10 intersection" became "by the delegating user's own permissions".reservedIdentityNameMessage(plugin-securityobjects/reserved-identity-names.ts): the refusal a Setup assignment form shows read "These names are ADR-0068 built-in identities"; it now reads "These names are built-in identities". It is a leaf of every locale's security bundle. The tests compare against the function, so none changed.sys_flow_dispatch(service-automation; no Setup page): "a rebuilt kernel" became "a reload or restart".Setup reachability
sys_approval_request,sys_approval_action,sys_approval_delegation(approvals-plugin.ts),sys_record_share,sys_sharing_rule(sharing-plugin.ts).sys_user_positionandsys_user_permission_set(the Positions and Permission Sets related lists inplatform-objects/src/pages/sys-user.page.ts; New opens each object's form, View all opens its list page)./apps/setup/metadata/permission).sys_audience_binding_suggestion(objectui reads its rows through a dedicated suggested-bindings API and renders its own copy) andsys_automation_run. Both are cleaned because the card names them.Translations
node scripts/check-i18n-bundles.mjs --write --filter=approvals|security|sharingregenerated theenbundles from source.service-automationgenerates no bundle. Merge mode keeps every non-empty translated-locale value, so the order was the one #23845 used:sys_user_positiondescription re-translated); plugin-sharing zh-CN, ja-JP and es-ES (thesys_record_sharedescription); plugin-approvals zh-CN (the delegation description andvalid_fromhelp).flow_*help texts in all three approvals locales, the delegation description andvalid_fromhelp in approvals ja-JP and es-ES, and the reserved-position refusal in all three security locales.Pins (acceptance 2)
One unit test per package, in the form #23845 landed (
service-messaging/src/objects/admin-copy-vocabulary.test.ts). That pin restates its matcher rather than importing a shared helper, so these do the same. No newcheck:*script, lint rule or CI wiring.packages/plugins/plugin-approvals/src/admin-copy-vocabulary.test.ts: every object the package exports plussys_approval_token(registered by the plugin, not exported); every leaf of the fourobjectsbundles.packages/plugins/plugin-security/src/objects/admin-copy-vocabulary.test.ts: every objectobjects/index.tsexports; the label and description of every shipped permission set; every leaf of the four bundles.packages/plugins/plugin-sharing/src/objects/admin-copy-vocabulary.test.ts: every objectobjects/index.tsexports; every leaf of the four bundles.packages/services/service-automation/src/admin-copy-vocabulary.test.ts: every object the package exports (no bundle exists).Each has a positive control showing the matcher recognises every kind of vocabulary, and a minimum roster so the population cannot quietly shrink.
Ablation, through
scripts/ablation-replace.mjs(WRAP mode, trap-armed restore): " (ADR-0057 D4)" put back into thesys_user_positiondescription (anchor 1 to 0, marker 0 to 1, blobfbd17436adffto7ea8a4913087). The security pin went red on exactly one test, namingsys_user_position.description (an ADR number, a decision id); 6 others stayed green. Restore: blob equal to HEAD (fbd17436adff),git diff HEADempty. No build was involved, because the pin imports the object through relativesrcpaths, not through adistexport.Local verification (HEAD
85fb81cfd1)Built first:
turbo run build --filter=@objectstack/cli...(62 packages, the CLI closure the i18n generator needs, which contains all four packages), exit 0, after mergingorigin/mainat497518c3f6.pnpm --filter @objectstack/plugin-approvals test: 79 files, 1088 tests passed.typecheck: exit 0.pnpm --filter @objectstack/plugin-security test: 187 files, 3721 passed, 45 skipped.typecheck: exit 0.pnpm --filter @objectstack/plugin-sharing test: 47 files, 1073 passed.typecheck: exit 0.pnpm --filter @objectstack/service-automation test: 187 files, 2503 passed.typecheck: exit 0.tsc -p tsconfig.test.json --listFilesOnly: 1 hit each), whichcheck:test-typecheckcompiles.dispatch-gates --commands --repo objectstack-ai/objectstack, 65 families): 64 exit 0, among themcheck:i18n("10 package(s) — all bundles in sync"),check:i18n-stale-fill("no new stale fills, 0 baselined"),check:cross-package-test-inputsandcheck:nul-bytes.check:dual-build-cjs-loadsprinted PREREQUISITE NOT MET (exit 3): it reads every package'sdist, and this worktree built only the CLI closure. That one is NOT MEASURED locally and left to CI.--ranreconciliation: 65 derived, 64 run, 1 NOT-MEASURED, 0 UNRUN.pnpm check:i18n-coverage, exit 0 ("621 baselined untranslated string(s), none new").test:repoand the rest of the farm, which belong to CI.Acceptance notes
dist/index.d.tscarry each object'sdescriptionas a string literal type (readonly description: "Records shared beyond their owner, one row per grant."), so the declaration files change byte-wise in those literals only. No export, type shape or accept set moved.everyoneandguestbuilt-in positions' descriptions inplugin-security/src/builtin-positions.tscarry "(ADR-0090 D5)" and "(ADR-0090 D9)" on Setup's Positions page. That file is outside this card's surface, andbuiltin-positions.boot.test.tspins the same text as the stored legacy rows the retired seeder wrote, so a change there also moves a stored-row fixture and needs its own reading. Reported to the PM for the family's closing card; the security pin does not judge the positions population.sys_approval_request's other descriptions and the excludedsys-approval-request.page.tswere not touched (PR feat(plugin-approvals): the request page's Details tab ends with the request snapshot's raw JSON, gated on studio.access #23837 holds the page).Generated by Claude Code