Skip to content

Console: an "App lock" entry on the profile page when the mobile shell exposes openAppLockSettings() #29748

Closed

Description

@objectstack-fleet

repo:mobile#1 · os-justin · session_01QSeKYnW1Xf6HDSWz1eGAqv

Filing category ③: a direct task from a maintainer ruling. The ruling is objectstack-ai/mobile#145 comment 6593856498: Ruling: batch #1 item 2 · letter A · maintainer 「同意」. Under option A, the lock is changed only on the shell's native settings screen. The Console reads it and opens that screen; it never writes the lock.

What the shell offers

The shell side is objectstack-ai/mobile#181; the contract is in mobile docs/HYBRID-SHELL.md, section "App lock".

  • getAppLock() resolves { enabled: boolean, timeoutSeconds: number }.
  • openAppLockSettings() opens the native settings screen. Changing the setting there asks for biometrics.
  • Feature-detect each with has('getAppLock') and has('openAppLockSettings'). Only pages on the configured server's origin may call them.
  • No event announces a change. Re-read getAppLock() when the profile page is shown.

Ask (Console, ui/)

  • On the user profile / personal settings page, when has('openAppLockSettings'), show an "App lock" row with its current state from getAppLock(). Tapping it calls openAppLockSettings().
  • In a plain browser or an older shell, show nothing.
  • ⛔ No Console-side toggle. The ruling keeps all writes native.

Business reason

  • Who benefits: phone users who expect the lock under their profile settings, where other apps put it.
  • If not done: the lock stays reachable only from the shell's connection switcher.

Who acts

The domain:ui seat. Triage decides the grade.

Duplicate check (2026-11-03)

is:issue openAppLockSettings in this repo returns 0 hits.

Activity

  1. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p3 · domain:ui · pm:queue · 2026-11-03T03:58Z

    ⛔ Not a claim.

    • Read fresh. An "App lock" row on the profile page when the shell exposes openAppLockSettings(). The Console reads the lock and never writes it. Maintainer-ruled A (mobile#145). The lock itself already works in the shell, so this is discoverability: p3.

    Generated by Claude Code

  2. added
    domain:uiDomain lane — seat card indexed by label:pm:seat
    enhancementNew feature or request
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 3, 2026
  3. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Claim: PM loop round 19 · 2026-11-03T04:16Z
    Session: session_01QsR2jSM2R4osc3dyaqPHY1 (card thread, os-dev); dispatched by seat session session_01QsR2jUJ19MstFvFhjgiYTu
    Account: zhuangjianguo
    Branch: claude/project-thread-y37yg8 (platform-assigned to the card thread; it can push only this branch)
    Worktree: objectstack-issue-29748
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: ui/packages/mobile/src/nativeHost.ts (two capability union members, optional getAppLock? / openAppLockSettings? on the host interface, a NativeAppLock type, nativeGetAppLock, nativeOpenAppLockSettings), ui/packages/mobile/src/index.ts (their exports), ui/packages/mobile/src/__tests__/nativeHost.test.tsx, ui/packages/mobile/README.md, ui/apps/console/src/pages/system/ProfilePage.tsx (an App lock card only when nativeHostCan(host, 'openAppLockSettings'): read on mount, on visibilitychange to visible and on window focus; tap calls nativeOpenAppLockSettings; no toggle), new ui/apps/console/src/pages/system/__tests__/ProfilePage.appLock-29748.test.tsx, the keys profile.appLock.{title,off,onImmediately,onAfter} in all ten packs under ui/packages/i18n/src/locales/, and a root .changeset (patch). Any other file is declared by a claim amendment before code (stop on breach; explain in the report)
    Container & model: S, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: medium
    Clause-②: yes (widening): new optional host members and exports in @object-ui/mobile and four new i18n keys; nothing removed or narrowed
    Metadata-protocol: none
    Responsibility: the Console App lock row (read-only, opens the native screen); every lock write stays in the shell per mobile#145 ruling A
    Thread-read: 6595074906
    Premise: holds (at origin/main 7ba8b11f: the bridge reader is @object-ui/mobile nativeHost.ts (nativeHostCan + native* wrappers) with no app-lock members yet; the profile page is console ProfilePage.tsx; the contract is mobile PR #181 HYBRID-SHELL.md "App lock", not yet on mobile main)
    Serial constraints cleared: none blocking. Seat 3 #29735 (claim 6595193307) edits the same nativeHost.ts union, host interface, index.ts and test fake: whichever lands second merges main and keeps both sets of members. No open PR touches these files at claim time.

  4. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jSM2R4osc3dyaqPHY1
    os-dev-report

    {
      "issue": 29748,
      "status": "done",
      "branch": "claude/project-thread-y37yg8",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29798",
      "session": "session_01QsR2jSM2R4osc3dyaqPHY1",
      "premise_still_valid": true,
      "summary": "Profile page (/system/profile and account:profile_card) gains an App lock card, drawn only when nativeHostCan(useNativeHost(), 'openAppLockSettings'). It shows Off, On (immediately) or On with an Intl-named duration from getAppLock(), re-read on mount, visibilitychange to visible and window focus; a tap calls nativeOpenAppLockSettings(); no toggle and no write. @object-ui/mobile adds the two optional host members, NativeAppLock and the nativeGetAppLock / nativeOpenAppLockSettings wrappers (README updated); profile.appLock.{title,off,onImmediately,onAfter} in all ten packs. Contract read at objectstack-ai/mobile#181 head 77ded7bb (not on mobile main). One in-surface correction after the first run: the duration fell back to the machine locale (machineLocaleCensus-9909 red), now UI language then useDisplayLocale() (commit 75f435ad).",
      "tests": "Head 75f435ad. New ProfilePage.appLock-29748.test.tsx: 9 passed; on main's ProfilePage.tsx (7ba8b11f, tree-only restore, git diff HEAD empty after) 6 failed / 3 passed (every shell case red, 3 controls green). Ablation via ablation-replace --delete of the visibilitychange + focus listener lines: 1 failed / 8 passed (the re-read case), restored blob == HEAD. vitest packages/i18n/ packages/mobile/ + five ProfilePage suites: Test Files 109 passed, Tests 1633 passed, 13 skipped. turbo type-check console+mobile+i18n: 73/73. eslint on five changed code files: 0 errors, 1 pre-existing warning (ProfilePage name-sync set-state-in-effect).",
      "gates": "dispatch-gates --commands at 75f435ad: 35 families. 34 non-vitest run with exit captured before pipes, GITHUB_EVENT_PATH = the PR body: all exit 0. pnpm --dir ui exec vitest run scripts/: 170 files passed, 2 skipped, exit 0. check:new-line-citations (ui/): 0 new. Body gates before pr_create: check-changeset-no-major, check-adr-0087-registration, check-closing-keyword-parity, check-partof-closing-keyword all exit 0. CI check-runs: in_progress at report time. Not merged with main: 18 commits behind, git merge-tree clean.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "9 — GitHub MCP issue_read x5 (29748 get + comments, 29735, 29750), get_session, add_repo (read-only, mobile public); no MCP write tool",
      "api_writes": "2 — git push (branch); fleet-write pr_create (run 41582956881, PR #29798, body read back byte-identical). Plus this os-dev-report comment via post-stamped.",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "class: b · reach: named producer — objectstack-ai/mobile app/console.tsx openAppLockSettings: () => router.push('/app-lock-settings') pushes a native screen inside the same activity; HYBRID-SHELL.md 'Reading the app lock' says no event announces a change, and an Android WebView fires no visibilitychange for an in-activity push, so a Console that re-reads on visibility/focus can show the old state after the user returns from the settings screen until it remounts. Contract text: 'No bridge method changes the lock' / card: 'No event announces a change. Re-read getAppLock() when the profile page is shown.' Seam: shell:openAppLockSettings → renderer:console ProfilePage AppLockCard. Not reproduced on a device (no device here); measured only as the absence of any shell event in the contract. · dedupe words: appLockChanged, app lock event, getAppLock stale, visibilitychange WebView",
        "carrier: #29735 · serial merge on nativeHost.ts union/interface/index.ts/test fake, noted, not filed"
      ],
      "deviations": "Clause-② line copied as the seat's handshake reply spelled it ('Clause-②: yes (widening)'), not with the claim line's trailing explanation. PR has no assignees/reviewers (os-dev: none at pr_create; the harness's assignee/reviewer MCP step skipped as an MCP write). No PR subscription: re-runs and landing are the seat's."
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu

    Landed · 2026-11-03T05:55Z · PR #29798 merged through the merge queue as b62463f1 at 2026-11-03T05:54Z (GitHub's clock). ACCEPT 6596343019 and contract review 6596159679 (PASS) at head 75f435ad.

    probe before (b62463f1~1) now (origin/main)
    export function nativeGetAppLock in ui/packages/mobile/src/nativeHost.ts 0 1
    function AppLockCard in ui/apps/console/src/pages/system/ProfilePage.tsx 0 1

    Fixes #29748 closed this card. pm:dispatched comes off in the same stroke as this note. Serial: seat 3's #29803 (#29735) now merges main and keeps both member sets in NativeHostMethod, ObjectStackNative and index.ts. The follow-up is #29800, for the repo:mobile seat: the shell sends no app-lock change event, so the row can show the old state after an in-activity Android push.

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:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions