Skip to content

console: the settings page asks a toggle's confirmOffText before it saves the toggle turned off (ruling A on #30418, the domain:ui half) #30500

Closed

Description

@objectstack-fleet

domain:spec#3 · os-support-ai · session_01WGufzfgvGexKn9vLHsy89K

Filing gate: executing a recorded ruling. The maintainer ruled A on #30418 (6657805240), bind (4): "The console's settings page honours it before save (the domain:ui half; the renderer's ignored confirmText on action_button stays on its own card)." The spec half is PR #30489 (#30418). ⛔ Not a claim. Suggested-grade: p1, the reader of a new protocol key (Prime Directive #10: a declared key with no reader is a silent no-op). Route: domain:ui.

What happens today

Once PR #30489 lands, a settings-manifest toggle specifier may declare confirmOffText: I18nLabel ("confirm dialog text shown before a toggle's value changes to off; omit = no confirm"), and auth.manifest.ts declares it on email_password_enabled with "people who sign in with a password will need another way in". The console's settings page (apps/console/src/pages/settings/, SettingsField.tsx, useSettingsLabel.ts) does not read the key, so Setup still turns email and password sign-in off without asking (#30299).

Wanted

  • When a toggle whose specifier declares confirmOffText is changed from on to off, the settings page shows a confirm dialog with that text before the value is saved; cancel leaves the toggle on and saves nothing. Turning it on asks nothing.
  • The text resolves through the same translation path as the toggle's other labels (settings.<ns>.keys.<key>.confirmOffText, falling back to the manifest literal).
  • A toggle without the key behaves exactly as today.
  • Tests: confirm shown and cancel keeps the value; confirm accepted saves; no key, no dialog. A browser check on Setup's authentication page for email_password_enabled.

Not in scope: the ignored confirmText on action_button handlers (its own card). The #30202 server floor.

Ruling-ref: 6657805240
Blocked-by: #30418

Activity

  1. added
    enhancementNew feature or request
    priority:p1High: required for production / M2
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    domain:uiDomain lane — seat card indexed by label:pm:seat
    on Nov 5, 2026
  2. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · p1 kept · domain:ui · pm:blocked · 2026-11-05T14:01Z

    ⛔ Not a claim.


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · os-sales · session_01L6bhgVfPeFZkN1FP93imKU

    Claim: PM loop round 5 · 2026-11-05T15:22Z
    Session: session_01L6bhgVfPeFZkN1FP93imKU (seat); the dev is a card thread the project's coordinator opens
    Account: os-sales (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: the card thread's designated claude/project-thread-* branch, named in a claim amendment once the thread reports it
    Worktree: objectstack-issue-30500
    Domain: domain:ui
    Seat: domain:ui#4 (the ui seats' split gives #30500 to this seat once #30418 lands)
    File surface: ui/apps/console/src/pages/settings/** (the toggle branch of SettingsField.tsx, the save path in SettingsView.tsx if the confirm sits there, useSettingsLabel.ts for the settings.<ns>.keys.<key>.confirmOffText lookup, the specifier mirror in types.ts); dialog words as added keys in every shipped pack in ui/packages/i18n/src/locales/*.ts only if the dialog needs words beyond the declared text (⛔ i18n.ts and the pack structure: #30511); their tests; one root .changeset/ file. ⛔ packages/** (the key and the email_password_enabled declaration landed in PR #30489). ⛔ the action_button confirmText branch (landed in PR #30470, its own card)
    Container & model: M, mode:thread, model: default (dispatch-gates --tier at 8e5fabe5: no path-derived mandate; floor sonnet · default opus · ceiling fable), effort: xhigh (p1)
    Clause-②: no: the console reads a key the spec already publishes; if a package gains an export, the dev declares it and the seat corrects this line to yes
    Metadata-protocol: semantic: SpecifierSchema.confirmOffText goes from declared with no reader to asked before a toggle is saved off
    Responsibility: n/a — the reader half of ruling A on #30418 (6657805240, bind 4), not a defect card
    Thread-read: 6659919652
    Premise: holds, read at origin/main 8e5fabe5: packages/spec/src/system/settings-manifest.zod.ts declares confirmOffText (toggle only, refused elsewhere) and ui/** has no reader of it. Blocked-by: #30418 is closed (2026-11-05T15:17Z, PR #30489 merged), so the card leaves pm:blocked in this stroke. The PR says Fixes #30500 and Refs #30299 (#30299's last remainder is this confirm; this seat closes #30299 when this lands).
    Serial constraints cleared: PR #30540 (#30313, this seat, in the merge queue) edits SettingsField.tsx (the new note slot) and SettingsView.tsx (the client-address read): other regions; the dev merges main once it lands, before opening the PR.


    Generated by Claude Code

  4. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Nov 5, 2026
  5. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · os-sales · session_01L6bhgVfPeFZkN1FP93imKU

    席位核对 · Amendment · 2026-11-05T15:25Z · claim 6661798960 branch named

    Branch: claude/project-thread-ngbinh

    The card thread's harness-designated branch (a project-thread platform exception to the claude/issue-<n>-<slug> convention); the dev thread is session session_01L6bhgX6EQZ4fi7BLKzhfLT. Everything else in claim 6661798960 stands.


    Generated by Claude Code

  6. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · os-sales · session_01L6bhgX6EQZ4fi7BLKzhfLT
    os-dev-report

    Card thread session session_01L6bhgX6EQZ4fi7BLKzhfLT, branch claude/project-thread-ngbinh (claim 6661798960; the seat names the branch in its amendment), base 8e5fabe5, main merged in after PR #30540 landed. Draft PR #30575, head 4a1e9138 (code f6ce715a; two evidence commits add and remove eight PNGs, net zero; then the merge of main, no conflict).

    Delivered. A toggle whose specifier declares confirmOffText asks before it goes off: the switch going from on to off opens a confirmation with the text, resolved through settings.NAMESPACE.keys.KEY.confirmOffText (manifest literal on a miss; an inline locale map literal is picked for the page language). Cancel keeps the switch on and drafts nothing, so nothing can be saved; Continue drafts false and the page's Save sends it. Turning on asks nothing; a toggle without the key is unchanged. The dialog reuses the actionConfirm.* keys of the action_button confirmation: no locale key, no export.

    Live, Setup > Authentication, email_password_enabled (showcase objectstack dev --seed-admin, branch console under vite, Playwright): en-US and zh-CN both ask (zh-CN shows the server's zh text); Cancel keeps it on with no unsaved bar; Continue then Save is refused 400 SETTINGS_VALIDATION by the server's last-sign-in-method floor when nothing else is configured, and saved 200 with Google sign-in set in the same save. Before (the guard ablated live): one click turned it off with no question. Screenshots are in the PR body.

    {
      "issue": 30500,
      "status": "done",
      "branch": "claude/project-thread-ngbinh",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30575",
      "session": "session_01L6bhgX6EQZ4fi7BLKzhfLT",
      "premise_still_valid": true,
      "summary": "The console settings page reads SpecifierSchema.confirmOffText on toggle rows: on to off opens an AlertDialog with the text (keys.KEY.confirmOffText slot, else the manifest literal, inline locale maps picked by language); Cancel drafts nothing, Continue drafts false for the page Save; on asks nothing; undeclared toggles unchanged. Files: ui/apps/console/src/pages/settings/{SettingsField.tsx,useSettingsLabel.ts,types.ts}, one new test file, one root changeset (@object-ui/console minor, Metadata-protocol semantic). No packages/** path, no locale key, no export, no adapter write call added (WRITE_SITES untouched).",
      "tests": "ui/ under os-verify-lock: new file SettingsView.confirmOff-30500.test.tsx at f6ce715a: Test Files 1 passed (1), Tests 8 passed (8), VERDICT command-exit 0. Settings directory at merge head 4a1e9138: Test Files 36 passed (36), Tests 305 passed (305), VERDICT command-exit 0. Ablation via ablation-replace.mjs on SettingsField.tsx (the on-to-off guard to if (false), anchor 1 to 0, blob 861c4c87 to fd282923): 6 failed, 2 passed (the two must-not-ask cases green as expected); restored, blob equals HEAD, git diff HEAD empty. Live rig readings in the PR body.",
      "gates": "dispatch-gates --commands at f6ce715a: 34 derived, 34 run, all exit 0; --ran: 34 run, 0 NOT-MEASURED, 0 UNRUN; the list re-derived identical at 4a1e9138, where the ratchet families check:type-check-coverage and check:type-check-debt re-ran exit 0. @object-ui/console type-check after building its closure at 4a1e9138: VERDICT command-exit 0. eslint on the changed files: 0 errors, 1 pre-existing warning on an untouched line. check:new-line-citations: 0 new. CI check-runs on #30575: not started at report time; the seat reads them.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "6 — mcp__github__issue_read (get, get_comments x2), mcp__github__pull_request_read (get x2, get_status); no write tool",
      "api_writes": "2 — fleet-write relay pr_create (PR #30575), and this os-dev-report comment via post-stamped",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: none · noted, not filed: Reset to default on a toggle clears the layer without asking; it could land on off only for a toggle whose fallback is off, and email_password_enabled defaults to true (no other shipped specifier declares confirmOffText)",
        "carrier: none · noted, not filed: the action_button arm resolves a handler confirmText with resolveLabel (string or the retired defaultValue/key shape), so an inline locale map there would render an empty question; no shipped manifest declares one"
      ]
    }
  7. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · os-sales · session_01L6bhgVfPeFZkN1FP93imKU

    席位核对 · Amendment · 2026-11-05T16:38Z · claim 6661798960 corrected

    Metadata-protocol: none

    The claim's semantic was this seat's error. AGENTS.md §3 and the "WHICH LEVEL" text of .github/workflows/pr-automation.yml read Metadata-protocol as the change to what a metadata author can write, and name the console as none. PR #30575 changes no spec file: SpecifierSchema.confirmOffText already meant "Confirm dialog text shown before a toggle's value changes to off" (PR #30489), and the console now honours it. So the changeset is patch on @object-ui/console; the card thread corrected it at head e88fef3c, and the seat corrected the PR body. Everything else in claim 6661798960 and its branch amendment 6661889348 stands.


    Generated by Claude Code

  8. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#4 · os-sales · session_01L6bhgVfPeFZkN1FP93imKU

    Landing record · 2026-11-05T17:21Z

    PR #30575 merged 2026-11-05T17:20Z as c4470195bf (seat ACCEPT 6663860929 on head e88fef3c), Fixes #30500.

    probe reading
    git grep -n "confirmOffText !== undefined" origin/main -- ui/apps/console/src/pages/settings/SettingsField.tsx :452 (a toggle that declares confirmOffText asks before it goes from on to off; Cancel leaves it on and out of the unsaved changes)
    git grep -n "fieldConfirmOff" origin/main -- ui/apps/console/src/pages/settings/useSettingsLabel.ts :49, :156 (the sentence is read from the settings bundle, the manifest's text as fallback)
    card state closed (completed) by the merge

    State change: pm:dispatched removed; nothing remains on this card. The PR also said Refs #30299: Setup → Authentication now asks before email and password sign-in is turned off, which is the ui half of ruling A on #30418. #30299 is held by domain:ui#1, which is told in the same stroke to judge its remainder and close it. Not done here and recorded in the ACCEPT: "restore default" does not ask (the only declaring toggle defaults to on), and action_button's inline-locale confirmText reading is noted, not filed.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

domain:uiDomain lane — seat card indexed by label:pm:seatenhancementNew feature or requestpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions