You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
console list view: a view with sharing.lockedBy and no sharing.type shows no lock indicator, because ListView reads the raw type and ignores the spec default "collaborative" #29009
Filing gate: ① a product defect, a QA run clause fail (studio-authoring.no-entry-property-matrix acceptance[1]).
Business reason: #26844 made a list view show "Locked by USER" when sharing.lockedBy is set. An author who writes only sharing: {lockedBy: 'admin@objectos.ai'} (the spec defaults type to collaborative) gets a saved, published view that shows no lock at all, so other readers do not learn that the view is locked.
Reader who acts: the triage seat, then a domain:ui implementer in ui/packages/plugin-list/src/ListView.tsx. QA suggestion only: p3.
Duplicate search: lockedBy → 6 hits; #26844 (closed, fixed by PR #27013) added the indicator, and this is the case it does not reach. sharing type default collaborative → 2 hits (#26844, #22611), neither about the default.
Batch-of: release-18.3.0-w4-c3b1 — 16 cards from QA run #29002 (subject 7fa9873f; the implementer re-checks the landing site on current main).
Reproduction
On a writable package: PUT /api/v1/meta/view/qar8_vl.v_sharing?mode=draft&package=PKG with {object:'qar8_vl', viewKind:'list', label:'R8 sharing', config:{type:'grid', …, sharing:{lockedBy:'admin@objectos.ai'}}}, then publish. The live read carries sharing.lockedBy.
Open /_console/apps/APP/qar8_vl, pick "R8 sharing" in the view switcher.
Expected: the lock indicator ("Locked by admin@objectos.ai"). Actual: no lock text, icon or user anywhere; the toolbar matches the other views. Reproduced 3 times on fresh browsers.
Mechanism (found by reading source at the subject)
ListView.tsx (about L6358) renders the sharing span only inside schema.sharing?.type && (…). ViewSharingSchema (packages/spec/src/ui/view.zod.ts about L1840) declares type: z.enum(['personal','collaborative']).default('collaborative'), and the served view carries the authored body, so a view with only lockedBy never draws the indicator. Not driven: the same view with type set (by the code it renders).
Claim: PM loop round 11 · 2026-11-02T10:52Z
Session: cse_01QsR2jSSoRjvEqsGsZZLPC9 (card thread, os-dev); dispatched by seat session session_01QsR2jV4dWohojjbTJTQq5m
Account: zhuangjianguo
Branch: claude/project-thread-cet2if (platform-assigned to the card thread; it can push only this branch)
Worktree: objectstack-issue-29009
Domain: domain:ui
Seat: domain:ui#3
File surface: ui/packages/plugin-list/src/ListView.tsx (the sharing block only), its tests, and a changeset (stop on breach; explain in the report). No spec edit.
Container & model: XS, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: open — recorded at review
Thread-read: 6571556837
Premise: holds (at origin/maineed73a39: ListView.tsx:6458 renders the sharing span only under schema.sharing?.type &&, and :6511hasLeftSideItems also keys on type, while ViewSharingSchema defaults type to collaborative and the served view carries the authored body). Triage 6571556837 graded p2 and asks to sequence with #29037 (domain:spec, open, unclaimed); the fix keys the lock on lockedBy, so #29037 retiring personal cannot hide it again.
Serial constraints cleared: NOT cleared for pr_create: seat 1's PR #29273 (#29074) and PR #29266 (#28950) also edit ListView.tsx and are open drafts. This card builds now, keeps its hunk to the sharing block, and merges origin/main over whichever has landed right before pr_create.
{
"issue": 29009,
"status": "done",
"branch": "claude/project-thread-cet2if",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29312",
"head": "57e2c4d1",
"session": "session_01QsR2jSSoRjvEqsGsZZLPC9",
"premise_still_valid": true,
"summary": "ListView's read-only sharing indicator now renders when sharing declares a type or a lockedBy (hasSharingIndicator), so a view authored as sharing: { lockedBy } with no type shows 'Locked by USER'; the lock keys on lockedBy alone. An absent type shows the spec default label, read once from ViewSharingSchema.parse({}).type (collaborative, 'Shared view'), the same read ListView makes for PaginationConfigSchema; the toolbar separator's hasLeftSideItems uses the same predicate. A sharing block with neither key shows nothing; type-set views render as before. Premise held at origin/main 8a8a03d3 (guard on schema.sharing?.type in the sharing block and in hasLeftSideItems).",
"files_changed": [
"ui/packages/plugin-list/src/ListView.tsx (+26 -6: spec/ui import line, SPEC_DEFAULT_SHARING_TYPE + hasSharingIndicator after DEFAULT_LIST_DISPLAY_PAGE_SIZE, the sharing block, the separator's hasLeftSideItems line)",
"ui/packages/plugin-list/src/__tests__/ListView.test.tsx (+35: it.each over no type / collaborative / personal with lockedBy admin@objectos.ai, plus sharing: {} shows nothing)",
".changeset/29009-list-lock-without-type.md (new, @object-ui/plugin-list patch, Clause-② no, Metadata-protocol none)"
],
"line_budget": "XS-S card; 74 additions, 6 deletions, 3 files; production diff 32 lines in one file",
"tests": "On b6269b70 (code identical at head 57e2c4d1): vitest ListView.test.tsx 158/158 passed. Whole packages/plugin-list suite, locked, --maxWorkers=2, two batches: 93 files/660 tests + 92 files/1107 tests, all passed (185 files, 1767 tests). turbo type-check --filter=@object-ui/plugin-list 50/50, exit 0 (tsc --noEmit && tsc -p tsconfig.test.json). eslint on the two touched files: 0 errors. Ablation (scripts/ablation-replace.mjs) guard back to the type form, anchor 1->0, blob ccc95a10->9518d23b: 1 failed / 157 passed, the failing case being the no-type lockedBy row; restored, blob == HEAD, git diff HEAD empty.",
"gates": "dispatch-gates --commands --repo objectstack-ai/objectstack on b6269b70: 34 derived families, every one exit 0 (incl. node scripts/check-sdui-manifest.mjs exit 0 and its --self-test exit 0, pnpm --dir ui exec vitest run scripts/ exit 0 with 169 files passed / 2 skipped). dispatch-gates --ran: 34 derived, 34 run, 0 NOT-MEASURED, exit 0. Extra: pnpm check:new-line-citations (ui) 0 new; body gates on the PR body (check-changeset-no-major, check-adr-0087-registration, check-closing-keyword-parity, check-partof-closing-keyword) all exit 0. CI check-runs on #29312: in_progress at report time.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"serial": "Merged origin/main f2bf2938 right before pr_create; neither PR #29273 (draft) nor PR #29266 (open, non-draft) had landed, so it merged over neither. Their ListView.tsx hunks (read from the PR files API) do not overlap this diff's lines. The merge touched no file under ui/packages/plugin-list or packages/spec/src/ui. No parallel same fix on main or in open PRs (searched 29009 and lockedBy).",
"deviations": [
"Claim surface reads 'the sharing block only': besides the sharing block and the separator line the brief names, the diff adds ViewSharingSchema to the existing @objectstack/spec/ui import line and one module-level block (SPEC_DEFAULT_SHARING_TYPE, hasSharingIndicator) after DEFAULT_LIST_DISPLAY_PAGE_SIZE. Both are needed to read the spec default at module scope as the brief prefers; same file, no other component.",
"PR body opens with the harness project-attribution block (an HTML comment line and a Requested-by line), then Fixes #29009, per the os-dev exception for the harness-written first line.",
"The harness asked to set the PR assignee and request a reviewer after pr_create; not done, per the seat's common rule 10 and os-dev (no assignees, no MCP writes).",
"Verification runs were taken on b6269b70; head 57e2c4d1 only adds a merge of origin/main that touches no plugin-list or spec ui file, so they were not rerun.",
"No real-browser run: one render condition, covered by tests that render the real ListView."
],
"mcp_calls": "3 — mcp__github__issue_read x3 (get #29009, get_comments #29009, get #29037); all reads, no write tool",
"api_writes": "2 — fleet-write relay pr_create (objectstack-ai/objectstack#29312, run 41438458947); post-stamped comment on #29009 (this report). git push is not counted.",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": []
}
Landed: PR #29312 merged at 2026-11-02T12:37Z as cfe5d499. Fixes #29009 closed this card; pm:dispatched removed. Delivered: a list view whose sharing sets lockedBy without type now shows its lock indicator beside the spec's default type label; the lock keys on lockedBy alone, so #29037 retiring personal cannot hide it. Nothing left on this card.
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: studio-authoring.no-entry-property-matrix
Triage:
domain:ui· p2 ·pm:queue· 2026-11-02T07:27Z⛔ Not a claim.
Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m
Claim: PM loop round 11 · 2026-11-02T10:52Z
Session:
cse_01QsR2jSSoRjvEqsGsZZLPC9(card thread, os-dev); dispatched by seat sessionsession_01QsR2jV4dWohojjbTJTQq5mAccount:
zhuangjianguoBranch:
claude/project-thread-cet2if(platform-assigned to the card thread; it can push only this branch)Worktree:
objectstack-issue-29009Domain:
domain:uiSeat:
domain:ui#3File surface:
ui/packages/plugin-list/src/ListView.tsx(the sharing block only), its tests, and a changeset (stop on breach; explain in the report). No spec edit.Container & model: XS,
mode:thread,model: default tier (dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility:
open — recorded at reviewThread-read: 6571556837
Premise: holds (at
origin/maineed73a39:ListView.tsx:6458renders the sharing span only underschema.sharing?.type &&, and:6511hasLeftSideItemsalso keys ontype, whileViewSharingSchemadefaultstypetocollaborativeand the served view carries the authored body). Triage 6571556837 graded p2 and asks to sequence with #29037 (domain:spec, open, unclaimed); the fix keys the lock onlockedBy, so #29037 retiringpersonalcannot hide it again.Serial constraints cleared: NOT cleared for
pr_create: seat 1's PR #29273 (#29074) and PR #29266 (#28950) also editListView.tsxand are open drafts. This card builds now, keeps its hunk to the sharing block, and mergesorigin/mainover whichever has landed right beforepr_create.objectstack-fleet commentedon Nov 2, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jSSoRjvEqsGsZZLPC9
os-dev-report
{ "issue": 29009, "status": "done", "branch": "claude/project-thread-cet2if", "pr": "https://github.com/objectstack-ai/objectstack/pull/29312", "head": "57e2c4d1", "session": "session_01QsR2jSSoRjvEqsGsZZLPC9", "premise_still_valid": true, "summary": "ListView's read-only sharing indicator now renders when sharing declares a type or a lockedBy (hasSharingIndicator), so a view authored as sharing: { lockedBy } with no type shows 'Locked by USER'; the lock keys on lockedBy alone. An absent type shows the spec default label, read once from ViewSharingSchema.parse({}).type (collaborative, 'Shared view'), the same read ListView makes for PaginationConfigSchema; the toolbar separator's hasLeftSideItems uses the same predicate. A sharing block with neither key shows nothing; type-set views render as before. Premise held at origin/main 8a8a03d3 (guard on schema.sharing?.type in the sharing block and in hasLeftSideItems).", "files_changed": [ "ui/packages/plugin-list/src/ListView.tsx (+26 -6: spec/ui import line, SPEC_DEFAULT_SHARING_TYPE + hasSharingIndicator after DEFAULT_LIST_DISPLAY_PAGE_SIZE, the sharing block, the separator's hasLeftSideItems line)", "ui/packages/plugin-list/src/__tests__/ListView.test.tsx (+35: it.each over no type / collaborative / personal with lockedBy admin@objectos.ai, plus sharing: {} shows nothing)", ".changeset/29009-list-lock-without-type.md (new, @object-ui/plugin-list patch, Clause-② no, Metadata-protocol none)" ], "line_budget": "XS-S card; 74 additions, 6 deletions, 3 files; production diff 32 lines in one file", "tests": "On b6269b70 (code identical at head 57e2c4d1): vitest ListView.test.tsx 158/158 passed. Whole packages/plugin-list suite, locked, --maxWorkers=2, two batches: 93 files/660 tests + 92 files/1107 tests, all passed (185 files, 1767 tests). turbo type-check --filter=@object-ui/plugin-list 50/50, exit 0 (tsc --noEmit && tsc -p tsconfig.test.json). eslint on the two touched files: 0 errors. Ablation (scripts/ablation-replace.mjs) guard back to the type form, anchor 1->0, blob ccc95a10->9518d23b: 1 failed / 157 passed, the failing case being the no-type lockedBy row; restored, blob == HEAD, git diff HEAD empty.", "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack on b6269b70: 34 derived families, every one exit 0 (incl. node scripts/check-sdui-manifest.mjs exit 0 and its --self-test exit 0, pnpm --dir ui exec vitest run scripts/ exit 0 with 169 files passed / 2 skipped). dispatch-gates --ran: 34 derived, 34 run, 0 NOT-MEASURED, exit 0. Extra: pnpm check:new-line-citations (ui) 0 new; body gates on the PR body (check-changeset-no-major, check-adr-0087-registration, check-closing-keyword-parity, check-partof-closing-keyword) all exit 0. CI check-runs on #29312: in_progress at report time.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "serial": "Merged origin/main f2bf2938 right before pr_create; neither PR #29273 (draft) nor PR #29266 (open, non-draft) had landed, so it merged over neither. Their ListView.tsx hunks (read from the PR files API) do not overlap this diff's lines. The merge touched no file under ui/packages/plugin-list or packages/spec/src/ui. No parallel same fix on main or in open PRs (searched 29009 and lockedBy).", "deviations": [ "Claim surface reads 'the sharing block only': besides the sharing block and the separator line the brief names, the diff adds ViewSharingSchema to the existing @objectstack/spec/ui import line and one module-level block (SPEC_DEFAULT_SHARING_TYPE, hasSharingIndicator) after DEFAULT_LIST_DISPLAY_PAGE_SIZE. Both are needed to read the spec default at module scope as the brief prefers; same file, no other component.", "PR body opens with the harness project-attribution block (an HTML comment line and a Requested-by line), then Fixes #29009, per the os-dev exception for the harness-written first line.", "The harness asked to set the PR assignee and request a reviewer after pr_create; not done, per the seat's common rule 10 and os-dev (no assignees, no MCP writes).", "Verification runs were taken on b6269b70; head 57e2c4d1 only adds a merge of origin/main that touches no plugin-list or spec ui file, so they were not rerun.", "No real-browser run: one render condition, covered by tests that render the real ListView." ], "mcp_calls": "3 — mcp__github__issue_read x3 (get #29009, get_comments #29009, get #29037); all reads, no write tool", "api_writes": "2 — fleet-write relay pr_create (objectstack-ai/objectstack#29312, run 41438458947); post-stamped comment on #29009 (this report). git push is not counted.", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [] }objectstack-fleet commentedon Nov 2, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m
Landed: PR #29312 merged at 2026-11-02T12:37Z as
cfe5d499.Fixes #29009closed this card;pm:dispatchedremoved. Delivered: a list view whosesharingsetslockedBywithouttypenow shows its lock indicator beside the spec's default type label; the lock keys onlockedByalone, so #29037 retiringpersonalcannot hide it. Nothing left on this card.