Skip to content

Setup: show what people can really do and what really changed, using names rather than ids #30209

Closed

Description

@objectstack-fleet

epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff

From a real-user walkthrough of Setup, filed on the maintainer's word: 「以上都同意,立卡」 (2026-11-05). Measured on main b7075d9908, with the console in dev mode, unless a line says otherwise. Test app scaffolded with create-objectstack@18.3.0.

An administrator investigating a problem cannot get an answer from these screens today.

Items

# Where Observed Suggestion
1 User record, 权限集 tab Shows 0 and 暂无相关记录 for a user who has access through the default sets and positions Show effective access and where it comes from. POST /api/v1/security/explain already answers this
2 Sharing rule record 接收方 shows a raw id, _sGHMyWlqcx6t…; 条件 shows {"priority":"urgent"} The recipient's name, and the condition in words
3 审计日志 list The 记录 column is an id; object names like Platform Setting Audit Entry are English; one sign-in writes several rows Record label; localized names; a default view that hides the machinery
4 审计日志 config change detail Shows the key and a sha256: digest, so the new value cannot be read Show old and new values for non-secret settings. Secrets stay withheld
5 共享规则 new form The object picker lists 86 objects, mostly sys_*, with business objects buried Business objects first; hide objects where a rule makes no sense
6 Queue record No way to see or add members from the queue; they are on a separate nav entry A members list on the queue

Row 5 includes objects holding credentials and sessions, so the dev should confirm what a rule on those would do while deciding what to hide.

Activity

  1. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

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

    ⛔ Not a claim.

    • Read fresh. Setup's permission and change screens show ids and declared grants instead of effective access by name. A diagnostic-readability gap, so p3.

    Generated by Claude Code

  2. added
    domain:uiDomain lane — seat card indexed by label:pm:seat
    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 5, 2026
  3. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#6 · os-sales · session_01L6bhgUR8Nu4M7tbtgES7q2

    Claim: PM loop round 3 · 2026-11-05T12:21Z
    Session: session_01L6bhgUR8Nu4M7tbtgES7q2
    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-30209
    Domain: domain:ui
    Seat: domain:ui#6
    File surface: the rows whose fix lands in ui/**: row 1 (the user record's 权限集 tab shows effective access via the existing POST /api/v1/security/explain), row 2 (sharing-rule recipient by name, condition in words), row 3 (audit list record label / localized object names where ui/ draws them), row 6 (queue members list on the queue record), their tests, one root .changeset/ file. ⛔ row 4 (config-change values: what is secret is a server decision) and ⛔ row 5 (sharing-rule object picker over credential/session objects: security-sensitive, report the reading only). ⛔ packages/**. Rows not done are named in the report for the seat to split (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default (dispatch-gates --tier: no path-derived mandate; floor sonnet · default opus · ceiling fable), effort: high
    Clause-②: no (a new language-pack key, if a row needs one, is declared by the dev in the PR body and the seat re-reads this line at ACCEPT)
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6648534205
    Premise: holds as filed on b7075d99; the dev re-measures each row on origin/main first and may ship a subset
    Serial constraints cleared: none in flight on the user record tabs, sharing-rule or queue record pages (open PRs read 2026-11-05T12:18Z). No maintainer ruling beyond 「以上都同意,立卡」.

  4. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#6 · os-sales · session_01L6bhgUR8Nu4M7tbtgES7q2

    席位核对 · Amendment · 2026-11-05T12:24Z · claim 6657861397 branch named

    Branch: claude/project-thread-zr7jt1

    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_01L6bhgWs5eCv64CbCPwjWhV. Everything else in claim 6657861397 stands.

  5. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#6 · os-sales · session_01L6bhgWs5eCv64CbCPwjWhV
    os-dev-report

    {
      "issue": 30209,
      "status": "done",
      "branch": "claude/project-thread-zr7jt1",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30496",
      "session": "session_01L6bhgWs5eCv64CbCPwjWhV",
      "premise_still_valid": true,
      "summary": "Subset shipped (Refs, not Fixes). Row 2: a sharing rule's record page now names the recipient (record-page faces get the record as dependentValues, so recipient-picker reads recipient_type) and reads the condition in words (filter-condition gains a read face drawing the widget's words, 优先级 等于 紧急; unrepresentable criteria stay JSON). Row 3 (record-label half): RecordPointerCell expands the name field when it is a readable reference, so sys_session sign-in rows read the user's name. Rows 1, 3-rest, 4, 5 and 6 not shipped: rows_not_shipped below, each with its owning lane for the seat to split. No language-pack key added (words reuse filterBuilder.* rows): Clause-②: no.",
      "rows_not_shipped": [
        "row 1 · 林伟's 权限集 tab reads 0 / 暂无相关记录: the tab is page metadata (packages/platform-objects/src/pages/sys-user.page.ts, record:related_list over sys_user_permission_set); effective access needs a page-component vocabulary entry in packages/spec + the page edit in packages/platform-objects, then the ui block · lanes: spec + server, then ui",
        "row 3 rest · sys_platform_setting_audit (and others) have no zh-CN label rows in packages/platform-objects translations; 'one sign-in writes several rows' and a default view hiding them are the audit writer and the object's list views in packages/** · server lane",
        "row 4 · not measured (claim ⛔) · server lane",
        "row 5 · not measured (claim ⛔, reading only) · security lane",
        "row 6 · sys_queue_member.queue is a text field holding the queue name, not a lookup, so no related list is synthesized; needs a lookup or a sys_queue page with a members list in packages/plugins/plugin-sharing · server lane"
      ],
      "tests": "New: fields FilterConditionField.readWords-30209 (3), plugin-detail recordFace.siblingValues-30209 (2), plugin-grid ObjectGrid.recordPointerCell-12608 new describe (2). Positive control: sources restored to base c5800818 → 5 new assertions red, controls green. Ablations via scripts/ablation-replace.mjs, each restored (git diff HEAD empty): DetailSection dependentValues removed 1F/1P; words branch if(false) 2F/1P; $expand spread deleted 1F/4P. Suites fields+plugin-detail+plugin-grid+app-shell dirs: only reds were 4 renderer censuses, enrolled; rerun 36 files / 453 tests green. Type-check turbo --filter fields/plugin-detail/plugin-grid 55/55 (lock VERDICT 0). eslint changed files 0 errors.",
      "gates": "35 derived dispatch gates exit 0 (vitest run scripts/ SIGKILLed alongside type-check, rerun alone 171 passed VERDICT 0); ui check:spec-symbols, check:i18n-keys (after hook rename), check:unreferenced-sources, check:side-effects-array, check:phantom-deps, check:esm-specifiers, check:i18n-drift, check:new-line-citations, root check:doc-authoring all 0. CI on the PR: pending at report time.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "reads only — mcp__github__issue_read (card + comments); no write tool",
      "api_writes": "git push to claude/project-thread-zr7jt1 (harness branch); relay pr_create → #30496 (run 42036248962); relay issue comment (this report)",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: PR #30496 Acceptance notes · noted, not filed: Setup navigation and sys_queue labels (Queues, Queue, Display Label) read English under zh-CN — translation coverage in packages/**",
        "carrier: PR #30496 · noted, not filed: records named by a display_title formula over ids (sys_approval_approver/action/request, sys_user_position, sys_member) still read as ids in pointer cells — server metadata"
      ]
    }
  6. added
    domain:serverDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    and removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    domain:uiDomain lane — seat card indexed by label:pm:seat
    on Nov 5, 2026
  7. 27 remaining items

  8. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    State: rows 4–6 ruled → pm:queue · 2026-11-07T14:49Z

    ⛔ Not a claim.


    Generated by Claude Code

  9. added
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    pm:queueReady for the PM dispatch loop
    on Nov 7, 2026
  10. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · marchtian · session_017ihL2dFb2QdZEHEJ83cR2B

    Claim: PM loop round 2 · rows 5 B (server half), with rows 1 and 2 measured · 2026-11-07T15:40Z
    Session: session_017ihL2dFb2QdZEHEJ83cR2B
    Account: marchtian
    Branch: claude/project-thread-txk3tb
    Worktree: objectstack-issue-30209 (the card thread's own checkout)
    Domain: domain:server
    Seat: domain:server#3
    File surface: packages/plugins/plugin-sharing/** (row 5 B server half: a read-only shareable-objects route + the sys_sharing_rule object field widget hint, tests, translations), the route-ledger / envelope-guard / live-mount-parity wiring lines the gates name, .changeset/**; rows 1 and 2 are measured and reported only. ⛔ packages/spec/**, ui/** (stop on breach; explain in the report)
    Container & model: M, mode:thread (card thread cmsg_01VmuUhXU9SSUzqJYyXSmYSiFMQNAUTGWk1GeD14KvBfaa of this account's project), model: TIER_DEFAULT — dispatch-gates --tier: no path-derived mandate, effort: session default — card-thread effort is set by the maintainer only; the seat's reading is high (M; a new read route on the sharing admin surface)
    Clause-②: no (provisional) — an additive read route and a widget hint on the existing free widget string; the dev states the arm from the diff
    Metadata-protocol: none
    Responsibility: n/a — enhancement card (Setup walkthrough, epic #26676)
    Thread-read: 6708449661
    Premise: holds — rows 3, 4 B, 5 C, 6 B landed (PRs #30620, #30728, #30621) and row 2 + the record-name half of row 3 in PR #30496; triage 6708449661 re-queued rows 1, 2 and 5 B under ruling 6670358877. describeFilterGroup is on main 8ef4d3090, so row 2 is measured first and may already be done
    Serial constraints cleared: no open PR touches packages/plugins/plugin-sharing/** (open PR list read now); #30621 (row 5 C, the save-time refusal this route must share its predicate with) is closed

    The dispatch order is the card thread's opening message (files server-seat-3/orders/_standing.md + server-seat-3/orders/30209.md in this account's project); slot granted by the project coordinator.

  11. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · marchtian · session_017ihL2f62c1GYk6XzbdtCa4
    os-dev-report

    {
      "issue": 30209,
      "status": "done",
      "branch": "claude/project-thread-txk3tb",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/31207",
      "head": "59c76e787e7b21dd493272fdd133042ed846a902",
      "session": "session_017ihL2f62c1GYk6XzbdtCa4",
      "premise_still_valid": true,
      "summary": "Row 5 B server half: plugin-sharing mounts GET /api/v1/sharing/shareable-objects on IHttpServer at kernel:ready, listing every registered object for which SharingService.sharingRuleObjectRefusal (the #30621 save-time check, passed in as a function, never copied) answers null, business objects before platform objects, each group by label then name. Admission is SharingRuleService.assertCanManageRules through a new SharingRuleService.listShareableObjects; the door's refusal order follows #31004 (caller, held sign-in 403, anonymous 401, any query 400, non-admin 403; 501 with no rule service, 500 when the engine cannot enumerate). Row 2 is done on main 8ef4d309 (PR #30496, both halves pinned); row 1 measured: the page widget needs no spec, the missing piece is a per-user effective-access read with origins (server arm).",
      "tests": "pnpm --filter @objectstack/plugin-sharing test :: exit 0 (70 files, 1464 tests) on 59c76e787e; shareable-objects.test.ts 16/16; sharing-route-ledger.conformance.test.ts 3/3; typecheck :: exit 0. Ablations via scripts/ablation-replace.mjs, each restored with blob == HEAD: verdict filter removed 4F/12P; admission removed 3F/13P (first attempt refused by the tool as a no-op, rerun); anonymous branch disabled 1F; query refusal disabled 1F; business-before-platform comparison removed 3F.",
      "gates": "node scripts/pm/dispatch-gates.mjs --commands derived 89 families on head 59c76e787e: all 89 :: exit 0 (list in the PR's Derived gates block); --ran reconciliation :: exit 0 (89 derived, 89 run, 0 NOT-MEASURED, 0 UNRUN). eslint --no-inline-config over the 11 touched .ts/.mjs files :: exit 0 (the package has no lint script). Dogfood route-ledger-live-mount-parity :: exit 0 (8/8). Extra, not derived: pnpm --filter @objectstack/spec run check:generated :: exit 1 under the default 2 GB heap (tsc -p tsconfig.test.json OOM, exit 134, 'failed without diagnostics'), :: exit 0 with NODE_OPTIONS=--max-old-space-size=8192; no packages/spec file in this diff. CI check-runs: not yet read, PR just opened.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "line_budget": "no budget in the order; 13 files, +950/-4: source 436 (routes 199, list 112, ledger 55, plugin wiring 50, rule service 22, sharing-service +11/-4), tests 471 (410 + 61), one-line wirings 12 (dogfood 3, envelope guard 6, cross-package inputs 2, turbo 1), changeset 18",
      "files_changed": [
        ".changeset/30209-sharing-shareable-objects.md",
        "packages/plugins/plugin-sharing/src/shareable-objects-routes.ts",
        "packages/plugins/plugin-sharing/src/shareable-objects.test.ts",
        "packages/plugins/plugin-sharing/src/shareable-objects.ts",
        "packages/plugins/plugin-sharing/src/sharing-plugin.ts",
        "packages/plugins/plugin-sharing/src/sharing-route-ledger.conformance.test.ts",
        "packages/plugins/plugin-sharing/src/sharing-route-ledger.ts",
        "packages/plugins/plugin-sharing/src/sharing-rule-service.ts",
        "packages/plugins/plugin-sharing/src/sharing-service.ts",
        "packages/qa/dogfood/test/route-ledger-live-mount-parity.dogfood.test.ts",
        "scripts/check-route-envelope.mjs",
        "scripts/cross-package-test-inputs.mjs",
        "turbo.json"
      ],
      "deviations": [
        "No widget hint on sys_sharing_rule.object_name: the field already declares widget 'object-ref'; an unregistered hint degrades to a text input, so flipping it before the console registers the widget would regress today's picker. See open_questions.",
        "Clause-② line in the PR body and changeset reads 'yes (widening)' where the claim's provisional line reads 'no': the diff adds a public HTTP read, as #31004 declared for its sibling door. Metadata-protocol: none, as claimed.",
        "PR-body attribution line 2 links this card thread (cmsg_01VmuUhXU9SSUzqJYyXSmYSiFMQNAUTGWk1GeD14KvBfaa), not the seat thread the standing order spells: the session's own attribution instruction wins.",
        "PR body says 'Refs #30209', not 'Fixes #30209', per the seat's go message: the card stays open for row 1 and the console picker.",
        "Small refactor outside the route: isPlatformObjectSchema extracted in sharing-service.ts from effectiveSharingModel's own test and reused for the list's system flag, so the system-context census reads one ledgered spelling; no behaviour change.",
        "Files outside packages/plugins/plugin-sharing: only the four one-line wirings the order names (dogfood parity import, envelope guard MODULES, cross-package-test-inputs, turbo.json)."
      ],
      "mcp_calls": "5 — read only: mcp__github__issue_read x3, ToolSearch x1 (loader), mcp__claude-code-remote__subscribe_pr_activity x1 (PR #31207). No GitHub write tool.",
      "api_writes": "3 — git push origin claude/project-thread-txk3tb (several pushes, last 59c76e787e); pr_create via scripts/pm/fleet-write/dispatch.mjs (request fw-20261107T173119Z-fea8a7, run 42396719674, POST /repos/objectstack-ai/objectstack/pulls draft + POST /issues/31207/assignees [marchtian], read-back identical); this report via scripts/pm/post-stamped.mjs --comment=30209 (POST /issues/30209/comments)",
      "open_questions": [
        {
          "question": "When and where does sys_sharing_rule.object_name get its widget hint for the new picker?",
          "options": [
            "A: the ui card that registers the console widget also flips the hint (one line in plugin-sharing's object file), so the field never shows a text box",
            "B: flip it now in this PR and accept a text input until the ui card lands"
          ],
          "recommendation": "A, because the field already has a working object-ref picker and an unregistered hint degrades to a text input"
        }
      ],
      "security_findings": "withheld",
      "out_of_scope_findings": [
        "carrier: seat (#30209 row 1) · row 1 split proposal, not filed: (1) server card: per-user effective-access read with origins (default binding / position / direct), e.g. GET /api/v1/security/users/:id/effective-access on plugin-security IHttpServer, built on resolveUserAuthzGrants plus the catalog's position bindings; no spec arm unless served by @objectstack/rest over a spec contract; (2) ui card: a security:effective-access widget (unclaimed namespace, precedent mcp:authorized-assistants) plus a one-line edit in packages/platform-objects/src/pages/sys-user.page.ts; the same ui card can carry row 5's widget hint (open question). Evidence in PR #31207 'Rows 1 and 2'. Dedupe words: effective access, permission set origin, position binding, sys_user page."
      ]
    }

    Generated by Claude Code

  12. added
    pm:queueReady for the PM dispatch loop
    and removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Nov 7, 2026
  13. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · marchtian · session_017ihL2dFb2QdZEHEJ83cR2B

    Landed · 2026-11-07T18:58Z

    reading value
    PR #31207 MERGED 2026-11-07T18:57:11Z through the merge queue as 6f017e24a4, head 59c76e787e (second queue run; the first went red on the plugin-auth one-hour boundary test, #31175 / #31212)
    row 5, server half done: GET /api/v1/sharing/shareable-objects lists only objects a rule can take effect on, business objects first; credential and session objects never listed
    row 5, console half #31217 (picker reads the new endpoint; flips the sys_sharing_rule.object_name widget hint in the same PR)
    row 1 #31215 (server: per-user effective-access read with origins), #31216 (ui: user-page widget, Blocked-by #31215)
    row 2 already done on main 8ef4d309 by #30496
    rows 3, 4, 6 not part of this claim; untouched

    State: this claim ends here. pm:dispatched and the assignee removed and pm:queue restored, so rows 3, 4 and 6 can be claimed or split by their lanes (row 3/4 audit list and config-change detail: server services/audit face plus ui; row 6 queue members: ui).

  14. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · marchtian · session_017ihL2dFb2QdZEHEJ83cR2B

    Closed · 2026-11-07T19:00Z · correction of landing comment 6711667957

    That comment's last row was wrong: rows 3, 4 and 6 are not open. Row 3 landed as PR #30620, rows 4 B and 6 B as PR #30728, row 5 C as #30621 (triage 6708449661 recorded this). Every row is now either done on main or carried by its own card:

    row where
    1 #31215 (server effective-access read), #31216 (ui user-page widget)
    2 done, PR #30496
    3 done, PR #30620
    4 B done, PR #30728
    5 C done, #30621
    5 B server half done, PR #31207; console half #31217
    6 B done, PR #30728

    So this card closes as completed instead of going back to pm:queue. Follow-up work lives on #31215, #31216 and #31217.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:serverDomain 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