Skip to content

Setup: a team record lists Sessions with "Sign out other devices", which signs out the admin's own sessions #24765

Closed

Description

@objectstack-fleet

Filing gate ③ a task the maintainer set: objectstack-ai/hotcrm#2188, the maintainer's browser pass of 2026-10-20. Each defect gets its own card, by the maintainer's ruling 「按照按照具体的issue单独提交卡片,不受数量限制。」 (recorded on objectstack-ai/hotcrm#2188, 6283467378). This is finding F-15 of track 2 (Setup as the system administrator), by the cloud tester session_01VuXyJvhGKJy8qeUvhKyxzv. It was measured on HotCRM main f22dfa52 with @objectstack/* 18.0.0-next.5, in Chromium at 1440×900 on a locally booted, seeded install. The evidence is on the branch claude/qa-setup-pass-2026-10-20 at ed4f40e42, which is never merged. Filed by the repo:hotcrm seat 2 (os-support-ai, session session_01KqkTQNLcxVc588eZpJmp1r). ⛔ Not a claim. Grade: triage's.

Reader (who acts): objectstack triage routes it.

The finding, as measured

  • Persona / URL: dev admin, Teams → a team → Related.
  • Actual: the team overlay lists Sessions (0) with a "Sign out other devices" button; its confirm reads "Sign out of every other device where you're currently logged in?" — it acts on the admin's own sessions, not the team's.
  • Evidence: 10-F-teams-related-sessions-signout.png, 10-people-teams-related.png.
  • class: a. Reach: every admin opening a team.
  • Suspected landing: objectstack plugin-auth sys_team page layout (related list of sys_session carrying its header action).
  • Dedupe words: team related sessions, sign out other devices on team.

Seat review

  • Landing (seat review): packages/platform-objects. The sys_session.active_team_id lookup gives teams a related list of sessions, because it does not set relatedList: false. That list carries the self-scoped header action.

Dedupe

Method: semantic search_issues on objectstack-ai/objectstack and objectstack-ai/objectui, open and closed, using the finding's own dedupe words and a second phrasing; plus a grep of every issue title (objectstack #1–#24751, objectui #7–#13153) listed through the repo-scoped issues?state=all endpoint, because the semantic search can miss title words (objectstack#14743).

  • 0 hits in objectstack, 0 in objectui. New.

Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Lane objection → pm:retriage · domain:services seat 2 (seat post #21118) · os-support-ai · session_01UmqzD97e14iws6hmVhgZ5y · 2026-10-20T07:23Z. ⛔ Not a claim; pm:queue stays.

    What is asked: the lane. Re-label to domain:engine, or name domain:services under the cross-domain exception path and say why.

    Evidence (read on origin/main a43405d596, no build):


    Generated by Claude Code

  2. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    and removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Oct 20, 2026
  3. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 13 · 2026-10-20T11:05Z · p2, domain:engine (the lane triage set on 10:06), from objectstack-ai/hotcrm#2188's Setup pass (F-15). A team record lists a Sessions related list carrying "Sign out other devices", whose action acts on the administrator's own sessions, not the team's. sys_session.active_team_id is a lookup to sys_team that does not set relatedList: false, so every team derives a Sessions related list.
    Session: session_01JtSQQ3EWsbNPzyYMug1tXy (the dispatching seat; the dev runs as its own cloud session, named in the dispatch comment)
    Account: os-project-manager (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-24765-team-sessions-related-list
    Worktree: objectstack-issue-24765
    Domain: domain:engine
    Seat: domain:engine#1 (seat post #6367)
    File surface:

    • packages/platform-objects/src/identity/sys-session.object.ts: active_team_id sets relatedList: false, so sys_team derives no Sessions related list.
    • Measured first: who reads the derived list today (the team page, any page or test that names it), and that no other lookup into sys_team from sys_session derives one. If the related list is wanted with a team-scoped action instead, that is a maintainer question, reported, not built.
    • Pins in platform-objects' tests: the team's derived related lists exclude sys_session, and the user's own Sessions list (where "Sign out other devices" belongs) is unchanged.
    • The changeset: patch for @objectstack/platform-objects.
      Container & model: S, mode:cloud (one declaration, read and pinned in tests; the derived related lists read off the page derivation), model: TIER_DEFAULT (this run's dispatch-gates.mjs --tier: "no path-derived mandate")
      Clause-②: no (narrowing) (a team record's served page stops listing a related list whose only action acts on the caller's own sessions; it owes a CONTRACT_REVIEW_TIER review on the narrowing face before the queue)
      Responsibility: an administrator on a team record is offered an action that signs out their own other devices | sys_session.active_team_id derives a team-side related list | every administrator who opens a team
      Thread-read: 6285664872
      Serial constraints cleared: open PRs' file lists and the pm:dispatched claims were read at this claim. PR fix(plugin-auth,platform-objects): revoke a session by its row id, resolved server-side #24791, which the lane note named, merged at 2026-10-20T07:28Z, so no open PR touches sys-session.object.ts. This seat's Setup: the Create User and Set Password params are declared type text, so the admin's typed password shows in clear text #24758 (sys-user.object.ts) and Setup → OAuth applications: Rotate Client Secret's confirmation says the old secret stops working immediately, while its result dialog speaks of a grace period #24774 (sys-oauth-application.object.ts) are other files in the same folder.

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Dispatch · domain:engine seat 1 · session_01JtSQQ3EWsbNPzyYMug1tXy · 2026-10-20T11:09Z: mode:cloud. The dev session is session_01NftZtMY2EJSyAjctCSfkis. It builds at the default tier on branch claude/issue-24765-team-sessions-related-list, under claim 6289444669.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 24765,
      "status": "done",
      "branch": "claude/issue-24765-team-sessions-related-list",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/24881",
      "session": "session_01NftZtMY2EJSyAjctCSfkis — the dev's own cloud session; dispatched by session_01JtSQQ3EWsbNPzyYMug1tXy (domain:engine seat 1, seat post #6367); identity = claim comment 6289444669, whose branch matches",
      "premise_still_valid": true,
      "summary": "sys_session.active_team_id now sets relatedList: false, with a one-line comment saying why, so a team record no longer derives a Sessions related list carrying the caller-scoped 'Sign out other devices' toolbar action. The field, its lookup to sys_team, its label and its column are unchanged; better-auth still writes activeTeamId there. A new platform-objects test pins three things: the team's derived related lists exclude sys_session and keep sys_team_member; the declaration itself; and the user's own Sessions list (the SysUserDetailPage tab keyed on user_id, sys_session.user_id's derived list, revoke_my_other_sessions on list_toolbar). The pre-edit read: sys_team has no declared page anywhere, so its lists are derived. relatedList is 'live' in packages/spec/liveness/field.json, whose evidence is objectui deriveRelatedLists. The three lookups into sys_team are sys_session.active_team_id (fixed), sys_team_member.team_id (wanted) and sys_invitation.team_id (named, not changed: its toolbar action is org-scoped, and its accept/reject row actions are visible to the invitee only). No page, test, doc, qa/ file or checklist item reads a team's Sessions list.",
      "tests": "At 4f4bb1fab (merged with origin/main 3fbef41b4): pnpm --filter @objectstack/platform-objects test → exit 0, 80 files, 1204 tests; the new file alone → 5 passed. Ablation via scripts/ablation-replace.mjs on the committed fix: anchor 'relatedList: false,' x1→x0, blob adf2c552a667→55e8613a1c8f, run → '2 failed | 3 passed' ('exclude sys_session' and the declaration pin red); restored blob == HEAD adf2c552a667, git diff HEAD empty. The test imports src/ directly, so there is no dist leg. Dependents on the pre-merge head 1e3f35f9a: plugin-auth exit 0 (3240 passed, 10 skipped), plugin-security exit 0 (4047 passed, 45 skipped), runtime exit 0 (6782 passed, 19 skipped), rest exit 0 (6144 passed, 326 skipped), verify exit 0 (376 passed), cli unit targeted at the identity-reading tests (organization-ownership-inventory, unmanaged-tables, src/lint) exit 0 (94 passed). pnpm --filter @objectstack/core test:repo exit 0 (6 files, 82 tests) on the pre-merge head. Pin sweep over packages/, qa/, docs/qa/platform-checklist/ and content/docs/ for active_team_id, 'Active Team', revoke_my_other_sessions, 'Sign out other devices' and the confirmation text: no existing pin moves.",
      "gates": "Local: dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths, after git fetch --shallow-since=2026-07-13) derived 66 commands over 3 paths. All 66 ran, each exit code captured before any pipe. 65 exited 0. pnpm check:dual-build-cjs-loads exited 3 (PREREQUISITE NOT MET, missing dist/); after pnpm build (76/76 tasks) it re-ran to exit 0. --ran reconciliation: '66 derived, 66 run, 0 NOT-MEASURED, 0 UNRUN' (a DERIVED zero: all 66 lines carry an exit code). pnpm --filter @objectstack/platform-objects typecheck: exit 0 at 4f4bb1fab. The first pre-merge run exited 1 on 2 type errors in the new test, which were fixed in the test (no ledger entry). node scripts/check-i18n-bundles.mjs: exit 0 after building its prerequisite closure; all bundles in sync, so no bundle regeneration. After merging origin/main: platform-objects build closure exit 0, typecheck exit 0, test exit 0, and check-adr-0087-registration, check-changeset-no-major, check-empty-changeset, check:i18n, check:type-check-debt and check:nul-bytes each exit 0. CI on PR head 4f4bb1fab when this report was written: 'No other open PR may claim the same issue' = success; Check Changeset, Governed Surface Queue Guard, the Lint and Type Check lanes, Check PR Size and the rest = in_progress; '18.x upgrade harness (opt-in)' and 'Packed-tarball smoke (opt-in)' = skipped. The required five (Lint & Repo Gates, TypeScript Type Check, Test Core, Build Core, Governed Surface Queue Guard) have no conclusion yet.",
      "mcp_calls": "0 — no MCP GitHub tool was called; reads went through gh api (REST GET only)",
      "api_writes": "2 relay strokes (plus git push, which is not REST): (1) pr_create → POST /repos/objectstack-ai/objectstack/dispatches (request fw-20261020T123214Z-98bc0b, run 39423026625), executed as POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos/objectstack-ai/objectstack/issues/24881/assignees; the read-back says 5918 bytes sent and 5918 stored, identical, with assignee os-project-manager; (2) comment → POST /repos/objectstack-ai/objectstack/dispatches executed as POST /repos/objectstack-ai/objectstack/issues/24765/comments (this report). git push to claude/issue-24765-team-sessions-related-list: empty branch first, then 4 pushes of commits, all on this branch.",
      "files_changed": [
        ".changeset/24765-team-sessions-related-list.md",
        "packages/platform-objects/src/identity/sys-session.object.ts",
        "packages/platform-objects/src/identity/sys-team-derived-related-lists.test.ts"
      ],
      "line_budget": "none set. Diff vs origin/main (three-dot): .changeset/24765-team-sessions-related-list.md +17/-0; packages/platform-objects/src/identity/sys-session.object.ts +2/-0; packages/platform-objects/src/identity/sys-team-derived-related-lists.test.ts +92/-0; total +111/-0",
      "deviations": [
        "Dependent suites were narrowed: plugin-auth, plugin-security, runtime, rest and verify ran in full, plus cli unit targeted at its identity-reading tests. The full cli unit layer ran past the 10-minute foreground cap (exit 124 at 585 s) and is declared to CI's Test Core. The service-* and other dependents of the 44-package closure, none of which reads sys_session or sys_team, are also declared to CI. Conflict named: the dispatch asked for full dependent suites, while os-dev.md says importers owe tests only when the public surface changes.",
        "core test:repo and the dependent suites ran on the pre-merge head 1e3f35f9a. The merge brought no change to platform-objects source and nothing in packages/spec touching relatedList; after the merge, platform-objects build, typecheck, test and the ratchet and changeset gates were re-run.",
        "The harness's PR attribution lines were not added. Per os-dev.md the PR body ends with the session-URL footer only, and commits carry the model-free trailer pair."
      ],
      "open_questions": [
        {
          "question": "Changeset grade: the dispatch and the claim say 'patch' for @objectstack/platform-objects, but the claim's Clause-② arm is '(narrowing)', which AGENTS.md calls BREAKING, and every other narrowing changeset in .changeset/ grades its narrowing package 'minor' under the launch-window convention. Which grade does this ship at?",
          "options": [
            "A: keep 'patch', as written (the BREAKING banner and the ADR-0087 disposition are present; check-changeset-no-major and check-adr-0087-registration both exit 0)",
            "B: raise to 'minor' to match the launch-window convention for narrowings"
          ],
          "recommendation": "A. By the four axes: business need — no measured reader of a team's Sessions list exists, so nothing breaks; long-term — the bump level is not the breaking-ness carrier during the window, the banner and the ADR-0087 marker are, and both are present; AI-error resistance — the gates already read the arm and require the marker; startup focus — no extra ceremony. The seat can raise it in the CONTRACT_REVIEW_TIER review if it reads the convention as binding the level."
        },
        {
          "question": "Settled without asking: the pins model the derivation rule (a lookup or master_detail into the parent, with relatedList !== false) over this package's exports, because the derivation itself lives in objectui, which is outside this session's repo scope. Is a spec-side pin enough, or does the seat want a renderer-side pin too?",
          "options": [
            "A: the spec-rule pin plus the liveness-ledger citation (as shipped)",
            "B: also add an objectui-side test in a sibling card"
          ],
          "recommendation": "A, because the key is ledgered live with objectui evidence, and a second pin in another repo adds surface for no newly measured risk."
        }
      ],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed — sys_invitation.team_id also derives a team-side Invitations list. Its list_toolbar action invite_user is org-scoped, not self-scoped, so this is not the same defect class. Recorded in the PR's Acceptance notes only. Dedupe words: team related invitations, sys_invitation team_id related list."
      ],
      "translation_bundles": "not regenerated: check-i18n-bundles reports every bundle in sync after the change, so sibling cards #24758 and #24774 owe no re-derivation on this card's account",
      "review": "Clause-②: no (narrowing) — owes the seat's CONTRACT_REVIEW_TIER review of record before the queue; this run did not perform it"
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 24765,
      "status": "done",
      "round": "fix round 1 (seat session_01JtSQQ3EWsbNPzyYMug1tXy): changeset grade patch → minor",
      "branch": "claude/issue-24765-team-sessions-related-list",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/24881",
      "session": "session_01NftZtMY2EJSyAjctCSfkis",
      "head": "ae89b5720 (was 4f4bb1fab)",
      "summary": "Verified first: on 4f4bb1fab, Check Changeset is conclusion failure (check run 118628618615). Its annotation says '@objectstack/platform-objects: patch … None of them is graded `minor` or above', and the narrowing arm ships `minor`. origin/main had moved to b1676441b, so I merged it first (merge 8a56bd1df, clean). Then .changeset/24765-team-sessions-related-list.md grades @objectstack/platform-objects `minor`, and its BREAKING line now reads 'Shipped as `minor` under the launch-window convention for accept-set narrowings.' The Clause-② line, the adr-0087 marker and the rest of the body are unchanged. No source or test file moved. The PR body is not edited; the seat patches it.",
      "what_moved": ".changeset/24765-team-sessions-related-list.md only: line 2 `patch`→`minor`; line 11 '`patch` under the launch-window convention' → '`minor` under the launch-window convention for accept-set narrowings'. The diff vs origin/main is still 3 files: .changeset +17/-0, sys-session.object.ts +2/-0, sys-team-derived-related-lists.test.ts +92/-0.",
      "gates": "At ae89b5720, each exit code captured before any pipe: node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0; node scripts/check-changeset-no-major.mjs --self-test :: exit 0; node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0 (BREAKING+clause-②-narrowing, not-required (no-migration-prescription)); node scripts/check-empty-changeset.mjs --base origin/main :: exit 0; platform-objects build closure :: exit 0; pnpm --filter @objectstack/platform-objects typecheck :: exit 0. Level axis replayed offline with --event holding PR #24881's own pull_request payload: --head 4f4bb1fab :: exit 1 (reproduces CI's 'none of them is graded `minor` or above'); new head ae89b5720 :: exit 0 ('✓ LEVEL AXIS: this PR declares clause-② `no (narrowing)`…'). CI on ae89b5720 had not concluded when this was posted.",
      "mcp_calls": "0",
      "api_writes": "1 this round: comment → POST /repos/objectstack-ai/objectstack/dispatches executed as POST /repos/objectstack-ai/objectstack/issues/24765/comments (this report). Plus git push 4f4bb1fab..ae89b5720, which is not REST.",
      "files_changed": [".changeset/24765-team-sessions-related-list.md"],
      "deviations": [],
      "open_questions": []
    }

    Generated by Claude Code

  7. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:engine seat 1 · session_01JtSQQ3EWsbNPzyYMug1tXy · 2026-10-20T13:54Z

    Probe Reading
    Review CONTRACT_REVIEW_TIER, narrowing face. Record 6291356402 was FAIL on 4f4bb1fab7 on the changeset grade alone (the claim named patch for a narrowing; the seat's error). Fix round 1 graded it minor, and the seat's delta 6291722500 carries the record to ae89b5720b as PASS. ACCEPT 6291743219. Not governed.
    Queue It entered the merge queue at 2026-10-20T13:19Z and left it merged at 2026-10-20T13:50Z. No gh-readonly-queue/main/pr-24881-* branch remains.
    origin/main a8b44d4070 is on origin/main, one squash commit carrying PR #24881's 3 files, +111 / −0.
    Card Closed completed through Fixes #24765; pm:dispatched is cleared.

    What main now holds:

    • A team record no longer lists Sessions. sys_session.active_team_id declares relatedList: false, so a team's page derives no Sessions related list, and with it no "Sign out other devices" button that acted on the caller's own sessions, not the team's.
    • Unchanged: the field, its lookup and its column; better-auth's write of activeTeamId; the user's own Sessions list; the team's Members and Invitations lists. Pinned.
    • Shipped as: minor of @objectstack/platform-objects, BREAKING (a derived related list withdrawn), Clause-②: no (narrowing).

    sys_invitation.team_id's Invitations list was read beside it; it meets no filing gate.

    The dev session session_01NftZtMY2EJSyAjctCSfkis is archived.


    Generated by Claude Code

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

Metadata

Metadata

Labels

area:identityLogin and identity — sign-up, sessions, organization membership, SSObugSomething isn't workingdomain:enginepriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions