Skip to content

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

Open

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. 12 remaining items

  8. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-bill · session_01Utp6Cbvcmv8YWFhFJwzjKL

    Ruling confirmed: rows 4 · 5 · 6 = 4B · 5C · 6B · recorded by domain:server#2; not dispatched (the maintainer ended the server lane's shift); back in pm:queue for the next server seat.

    Maintainer: 「同意」 to the presentation, in the decision thread, 2026-11-05T21:41Z (project files decisions/30209-审计日志第4至6行-呈批-fable.md).

    State change: needs-user-decision removed, pm:queue added.

  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 5, 2026
  10. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

    Claim: PM loop round 2 · 2026-11-05T22:46Z — rows 4 and 6 as ruled (row 5 C is #30621, row 5 B a later card; rows 1–3 as recorded)
    Session: session_016WV4cyvF7SP65frVFAYLv7
    Account: os-elon-musk (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:server
    Seat: domain:server#5
    File surface: row 4 B: packages/services/service-settings/src/** (upsertRow returns the row id; the config_change audit row writes record_id), packages/plugins/plugin-audit/src/** (a sys_audit_log record page with an "other changes to the same record" related list), config-change-audit.test.ts and the #24611 comment in sys-audit-log.object.ts; row 6 B: packages/plugins/plugin-sharing/src/** (a sys_queue record page whose member list uses relationshipField: 'queue' + relationshipValueField: 'name', "New" prefilling the queue name), their translation bundles and tests, one changeset. ⛔ packages/spec/**, ⛔ ui/** (if the ui limits a self-referencing related list, fall back as the ruling says and report), ⛔ sys_queue_member.queue's field type (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: default, effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the audit list's config change shows only a digest, and a queue cannot list its members | none | every administrator tracing a settings change or managing a queue
    Thread-read: 6670358877
    Premise: holds per the ruling record 6670358877; the dev first measures whether the global sys_platform_setting mirror row carries plain text (the ruling's measure-first item)
    Serial constraints cleared: open PR #30448 (settings-service.ts, #30385) shares service-settings; the dev reads its diff and merges origin/main after it lands. #30630 (this seat) touches service-settings copy tables only, a different region

    Ruling (6670358877, the maintainer 「同意」 to the presentation, 2026-11-05T21:41Z): Row 4 B, Row 5 C (#30621), Row 6 B, details as recorded there. Row 4's changeset records the audit row's shape change (not BREAKING). Row 6: pin both the related-list filter and the "New" prefill; the PR body says declared queues are out. This PR writes Refs #30209; the card closes when rows 1 and 5 B are carried.

  11. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

    Claim amendment to 6671520435 · 2026-11-05T22:48Z
    Branch: claude/project-thread-v92xw9
    Dev session: session_016WV4cyf254wVgypzQ5Uj1a (the card thread, mode:thread), dispatched by this seat; the claim's other lines stand.

  12. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

    Claim amendment to 6671520435 · 2026-11-05T22:54Z
    File surface: adds, as forced test edits only, packages/qa/dogfood/test/audit-log-parent-read-gate.dogfood.test.ts (its run-level "about no record" row moves to another producer, and a pin that a config_change row now follows the parent-record gate) and packages/qa/dogfood/test/settings-config-change-audit.dogfood.test.ts (an end-to-end record_id pin). packages/qa is domain:devx; these are tests the row-4 change makes false, no product code there. The claim's other lines stand.

    Seat reading on the visibility consequence the dev measured: once a config_change row carries record_id = the settings row id, plugin-audit's parent-record read gate serves it only to a reader who can read that settings row or holds the ledger audit capability (the admin default) — the rule the CRUD mirror rows of the same settings row already follow. A reader holding only the ledger object grant stops seeing config_change rows. The seat takes this as the ruling's own consequence (Row 4 B, 6670358877): it narrows who reads, widens nothing, and makes one settings row's audit rows follow one rule. The PR names it in ## 维护者速读 and the changeset; the maintainer can veto at the PR.

  13. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7
    os-dev-report

    {
      "issue": 30209,
      "status": "done",
      "branch": "claude/project-thread-v92xw9",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/30728",
      "session": "session_016WV4cyf254wVgypzQ5Uj1a",
      "premise_still_valid": true,
      "summary": "Rows 4 B and 6 B as ruled (6670358877). service-settings upsertRow returns the stored row id and the config_change row writes it as record_id (metadata unchanged); plugin-audit ships a default sys_audit_log record page whose related list keys record_id on both sides (no New), and plugin-sharing ships a default sys_queue record page whose members list keys queue on the queue's name with New kept. Measure-first answer: the global sys_platform_setting mirror row carries the non-secret value in plain text, old and new; a secret's mirror row carries neither value nor handle. No ui self-reference limit was found, so no ui fallback; declared queues are out (PR body says so).",
      "tests": "service-settings config-change-audit.test.ts 18/18 (global + tenant re-pins, new overwrite case); plugin-audit sys-audit-log-page.test.ts 10/10 and sys-audit-log-same-record.integration.test.ts 6/6; plugin-sharing sys-queue-page.test.ts 8/8 (filter + New prefill on ObjectQL+SqlDriver, agreement with OwnershipQueueService). Full suites: service-settings 69 files/1179 tests, plugin-audit 75/1161, plugin-sharing 67/1417, all pass; tsc --noEmit exit 0 in each. Dogfood (built closure for the three packages first): audit-log-parent-read-gate.dogfood.test.ts 9/9 and settings-config-change-audit.dogfood.test.ts 5/5, Test Files 2 passed (2), Tests 14 passed (14). Ablations via scripts/ablation-replace.mjs: config-change-audit.ts `record_id: entry.recordId ?? null` -> `record_id: null` => 3 failed | 15 passed; sys-queue.page.ts `relationshipValueField: 'name'` -> `'id'` => 4 failed | 4 passed; both restored, blob == HEAD, git diff HEAD empty.",
      "gates": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 69 commands on head f6c2de44 (origin/main merged); each run with exit captured before any pipe: 69 exit 0 (check-plugin-teardown-shape --self-test exited 3 first on the shallow clone, 0 after fetching 621a4876). --ran: '69 derived famil(ies) accounted for — 69 run, 0 NOT-MEASURED (a DERIVED zero — all 69 recorded an exit code and none of them is 3)'. pnpm lint exit 0. CI check-runs on the PR not yet concluded at report time.",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm; the two amended dogfood files were run (14/14), see tests",
      "mcp_calls": "4 — mcp__github__issue_read x2, mcp__github__pull_request_read x2 (read #30448, read back #30728); no write tools",
      "api_writes": "2 — fleet-write relay POST /repos/objectstack-ai/objectstack/dispatches: pr_create (#30728, 8772 bytes read back identical); post-stamped issue comment on #30209 (this report)",
      "open_questions": [
        {
          "question": "New config_change rows now fall under the parent-record read gate, so a ledger-only reader loses them. The claim's line is `Clause-②: no`; does that narrowing call for the `(narrowing)` arm (BREAKING) instead?",
          "options": [
            "A keep `Clause-②: no`: no API or stored shape is removed, the gate is unchanged and old rows keep their visibility",
            "B re-declare `Clause-②: no (narrowing)` with a BREAKING banner and run the full dogfood"
          ],
          "recommendation": "A, because the seat accepted the narrowing as the ruling's consequence and it is named plainly in 风险 and the changeset for a maintainer veto; the seat decides"
        }
      ],
      "security_findings": "none",
      "out_of_scope_findings": [
        "class: b · reach: Setup → Audit Logs opens the ui `audit:log` browser drawer, which does not open the new sys_audit_log record page, so the same-record list is reached only from the object list or record links · evidence: nav_audit_logs points at the drawer component · dedupe words: audit drawer record page link",
        "carrier: PR #30728 acceptance notes · noted, not filed"
      ]
    }

    Generated by Claude Code

  14. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

    Landed · 2026-11-06T00:29Z · PR #30728 (rows 4 B and 6 B)

    Probe Reading
    PR #30728 merged, merge commit 05a30e6e, through the merge queue (seat ACCEPT 6672516987 on head f6c2de44; not governed, 1201 lines)
    #30209 stays open: the PR wrote Refs #30209

    Shipped: row 4 B (a config_change row names its settings row as record_id; sys_audit_log_detail lists the other changes to the same record) and row 6 B (sys_queue_detail lists the queue's members by name, "New" prefills it). Named consequence, in the changeset: a reader holding only the ledger's read grant who cannot read the settings store no longer sees new config_change rows.

    Still open on this card: row 1 (effective access on the user record's 权限集 tab: domain:spec first, then server, then ui, per the ui report above) and row 5 B (the read-only "objects under record sharing" route + picker, a p3 follow-up the ruling 6670358877 left undispatched). Row 5 C is #30621.

    Follow-up filed: #30748 (Setup → Audit Logs drawer reaches the new record page).

    State change: pm:dispatched removed, assignee cleared; the remaining rows are for triage to route.

  15. added
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Nov 6, 2026
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 requestneeds-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PRpriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions