Skip to content

fix(platform-objects): Create User result dialog reads true for a typed password - #25081

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-24936-create-user-dialog-copy
Oct 21, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-24936-create-user-dialog-copy

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #24936

Clause-②: no (text only: the create-user result dialog's sentence and button; no param, response, status, outcome or export moves)

What changed

sys_user.create_user's result dialog said "Copy the temporary password now — it is shown only once and never stored." with an "I have saved this password" button. It said that in both outcomes. The endpoint (plugin-auth admin-user-endpoints.ts, ...(resolved.generated ? { temporaryPassword } : {})) returns temporaryPassword only when it generated one. The dialog skips a field whose path is absent from the response, so after a typed password it showed the email alone and still asked the admin to save a password.

  • packages/platform-objects/src/identity/sys-user.object.ts: the create_user resultDialog now reads "If a temporary password was generated, copy it now — it is shown only once and never stored." with a "Done" button. That is the same sentence and button as set_user_password in the same file, whose dialog has the same two outcomes. The title, params, bodyExtra, handler, response and dialog fields are unchanged.
  • en.objects.generated.ts: regenerated with node scripts/check-i18n-bundles.mjs --write (exit 0), not edited by hand.
  • zh-CN / ja-JP / es-ES objects.generated.ts: the two hand-written leaves now reuse set_user_password's existing translations (如果生成了临时密码… / 完成, 一時パスワードが生成された場合は… / 完了, Si se generó una contraseña temporal… / Hecho). The merge-mode regeneration kept them. None of these leaves has a source-hash entry.
  • New pin packages/platform-objects/src/identity/create-user-result-dialog-copy.test.ts. It checks the source sentence and button (the button must not mention a saved password), the three dialog fields, and, in all four locales, that the create_user dialog's description and button equal set_user_password's.
  • Changeset: patch for @objectstack/platform-objects.

Wording choice

ActionSchema.resultDialog has no per-outcome copy, so one sentence must hold for both outcomes. I reused set_user_password's sentence and button rather than writing new copy:

  • Real need: the typed case shows only the email. "Done" claims nothing about a password, and the conditional sentence is true in both cases.
  • Long-term fit: one hedged sentence for the two dialogs that share this response shape. No spec key for per-outcome copy is added; that is out of scope and domain:spec's.
  • Hard for an AI to get wrong: the pin ties both dialogs together in every locale, so they cannot drift apart without a red test.
  • No scope growth: text only, and the translations already exist in the catalog.

Pins and fixtures

  • packages/cli/test/i18n-extract.test.ts has its own set_password fixture with different text ("…shown only once."). It does not quote this object and does not move.
  • packages/spec/src/system/i18n-resolver.test.ts has its own inline createUser object and inline zh-CN bundle. It imports nothing from platform-objects and does not move.
  • No pin in another lane moved.

Verification (head 4fdd4999b, base origin/main 2b1382a5b; origin/main re-fetched before opening and already merged, no new commits)

  • pnpm exec turbo run build --concurrency=2 (full build, under the verify lock): VERDICT command-exit 0.
  • pnpm --filter @objectstack/platform-objects typecheck: exit 0.
  • pnpm --filter @objectstack/platform-objects test: exit 0, Test Files 84 passed (84), Tests 1243 passed (1243).
  • pnpm --filter @objectstack/core test:repo: exit 0, Test Files 6 passed (6), Tests 82 passed (82).
  • node scripts/check-i18n-bundles.mjs --write: exit 0 after building its prerequisite closure. The first run exited 3 (CLI not built).
  • Ablation 1 (source): scripts/ablation-replace.mjs put the old sentence and button back in sys-user.object.ts (anchor 1 → 0, blob bc6b1792 → 3f5199d7). 2 of the 4 pin tests went red ("the source sentence is conditional…" and "the button claims no saved password…"). Restored: blob == HEAD bc6b1792, git diff HEAD empty.
  • Ablation 2 (locale): put the old zh-CN leaves back (blob c6d8953c → 5326f33a). 1 of 4 went red ("every locale says the same thing as set_user_password…"). Restored: blob == HEAD, git diff HEAD empty.
  • Gates: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 66 families. All 66 were run with each exit code captured before any pipe. 65 exited 0 on the first run. pnpm check:dual-build-cjs-loads exited 3 (PREREQUISITE NOT MET, no dist/), was re-run after the full build, and exited 0. --ran reconciliation: "66 derived famil(ies) accounted for — 66 run, 0 NOT-MEASURED (a DERIVED zero — all 66 recorded an exit code and none of them is 3)".

Acceptance notes

  • I did not check objectui's dialog renderer locally, because objectui is not in this container. That it skips an absent temporaryPassword comes from the card's seat review and the existing code comment on the fields list. The renderer is unchanged here.

Generated by Claude Code

…he create_user dialog copy

Claude-Session: https://claude.ai/code/session_01MZw2Leqg5M8ZH9pKpMh9jS
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Oct 21, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)), so this run has no opinion about the docs.

What this run could not see
  • 1 anchor(s) matched too much of the corpus to be a work list: sys_user (symbol, 42 pages)
  • 1 name(s) were too generic to anchor anything (single lowercase words)
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 3 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json c0ae356ceb24fd34311767d087d5a3777b5ccebb → packageMentionDocs.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: TIER_DEFAULT
Head-sha: 4fdd4999b9
Local-runs: none

Scope: the net diff against the merge base (7 files, +92/−10):

  • packages/platform-objects/src/identity/sys-user.object.ts, the create_user resultDialog text;
  • the four object bundles under packages/platform-objects/src/apps/translations/: en regenerated, zh-CN / ja-JP / es-ES hand-written leaves;
  • the new create-user-result-dialog-copy.test.ts;
  • the changeset.

Read with them:

① Derived judgments

  • The new copy reads true for both outcomes: right.
    • create_user's dialog now says "If a temporary password was generated, copy it now — it is shown only once and never stored." with a "Done" button. That is word for word set_user_password's dialog, whose response has the same two outcomes.
    • By the dev's read of plugin-auth's admin-user-endpoints.ts, temporaryPassword is returned only when the server generated one.
    • The seat read the renderer: ActionResultDialog.tsx drops a field whose value is undefined (.filter(… value !== undefined)). So after a typed password the dialog shows the email and this hedged sentence, and after a generated one it also shows the password with its copy control. Neither reads false now.
    • The old button, "I have saved this password", claimed a save the typed case never offered. "Done" claims nothing.
  • The translations: right.
    • en was regenerated with check-i18n-bundles --write (only that file changed).
    • The three other locales reuse set_user_password's existing leaves verbatim (zh-CN 「如果生成了临时密码,请立即复制——它只显示一次,不会被保存。」 / 「完成」; ja-JP 「…生成された場合は…」 / 「完了」; es-ES "Si se generó…" / "Hecho"). No new string is coined.
  • Nothing else moves. The params, bodyExtra, the handler, the response, the title and the listed fields are unchanged.
  • The pins have teeth.
    • Four tests: the source sentence; the button, which must not mention a saved password; the conditional field list; and every locale's sentence and button equal to set_user_password's.
    • Ablation 1, the source restored: 2 red. Ablation 2, the zh-CN leaves restored: 1 red. Both were restored blob-equal to HEAD.
  • The census: packages/cli/test/i18n-extract.test.ts and packages/spec/src/system/i18n-resolver.test.ts carry their own inline fixtures and import nothing from platform-objects, so neither is a pin of this text and neither moved.

② Semver level

  • patch for @objectstack/platform-objects: right for copy text, with no param, response, status, outcome or export moving.
  • The changeset and the PR body carry the claim's Clause-②: no (text only: …) line verbatim, at a line start.

③ Boundary flags

  • Cross-lane: none. Every changed file is in packages/platform-objects or .changeset/.
  • Disjoint from platform-objects: the sys_user page's Security tab shows the viewer's own "your account" sections, empty, on every other user's record #24938 (this seat's next card, the same file): the hunks sit only in create_user's resultDialog.
  • git merge-tree --write-tree against today's origin/main (c67f244f5a) is clean.
  • Deviations, all accepted:
    • no pin in another lane moved;
    • the model-free commit trailers;
    • the renderer unread by the dev, now read by the seat (above);
    • the worktree cleanup.
  • Open question: A, as the dev settled it. Reuse set_user_password's sentence and button: one hedged sentence for the two dialogs with the same response shape, and no new translation.
  • CI on 4fdd4999b9: 6 of 40 check-runs still running at this read. The ACCEPT waits for green.

Implemented-by: claude/issue-24936-create-user-dialog-copy
Reviewed-by: session_01JtSQQ3EWsbNPzyYMug1tXy

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 · domain:engine seat 1 · session_01JtSQQ3EWsbNPzyYMug1tXy · 2026-10-21T08:19Z · ACCEPT

Head: 4fdd4999b9. It carries the dialog copy, its four locale bundles, the pin and the changeset.

Card #24936 (p3, bug, area:identity; from objectstack-ai/hotcrm#2207's v18 Setup pass, F-02): claim 6310152795, dispatch 6310193782. Dev report: 6310872521.

Item Reading
Shape Draft PR → main. The body opens Fixes #24936. 7 files, +92/−10. Not governed: check-governed-merges matched 0 of 7 paths; 102 changed lines.
Scope Create User's result dialog says "If a temporary password was generated, copy it now — it is shown only once and never stored." with a "Done" button, in place of "Copy the temporary password now…" / "I have saved this password". It reads true whether the administrator typed the password or let the server generate one.
Seat's own read It is the same sentence and button as set_user_password, whose response has the same two outcomes. objectui's ActionResultDialog.tsx drops a field whose value is undefined, so a typed password shows the email and the hedged sentence, and a generated one also shows the password. The params, handler, response and listed fields are untouched.
Review TIER_DEFAULT. Record 6311080671 is PASS on this head.
Declaration One changeset, @objectstack/platform-objects patch, with Clause-②: no (text only: …) at a line start, as on the claim and the PR body.
Cross-lane None. The cli and spec i18n fixtures carry their own copies and did not move.
Gates Dev at 4fdd4999b: 66 derived, 66 run, all exit 0, after a full build for the one that first exited 3. platform-objects passed 1243 tests and its typecheck exited 0; core test:repo passed 82. The new pins pass 4/4. Ablation of the source: 2 red. Ablation of the zh-CN leaves: 1 red. Both were restored to HEAD.
CI At this read on 4fdd4999b9: ci-failure GREEN, all 41 check-runs completed, none failed. git merge-tree against today's origin/main (f46ef4d70e) is clean.

Disposition:

  • open_questions: A, as the dev settled it: reuse set_user_password's sentence and button, with no new translation.
  • deviations: all accepted: no pin in another lane moved; the model-free trailers; the renderer unread by the dev, read by the seat; the worktree cleanup.
  • out_of_scope_findings: none.

Landing: ordinary queue (pr_ready + automerge_enable through the relay). Fixes #24936 then closes the card.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

platform-objects: Create User's result dialog always says "Copy the temporary password now", though a typed password returns none to copy

2 participants