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
feat: Setup catalog pages read the registry (editable under single, read-only under a wall); assignment pages stay data pages; pickers list the registry (objectstack ADR-0131 D3/D7) #7611
Part of the ADR-0131 execution tree (objectstack-ai/objectstack#15194). ⛔ Do not claim, assign or dispatch this card while that gate card is open, whatever the labels here say. The record is docs/adr/0131-total-organization-ownership-no-null-organization-id.md in objectstack-ai/objectstack (merged 2026-09-04).
In one sentence. Positions, permission sets and capabilities come from exactly one list — the registry. Under single-tenant an administrator can create and edit them in Setup (they are environment-level); on a shared-database multi-tenant deployment they are read-only. Assignment pages (who holds which position, who holds which set) stay ordinary data pages for the caller's own organization, with native search, sort and paging. Pickers list the registry. There is no merged two-source list.
The maintainer's Steedos lesson is the reason for that last sentence: a UI that merges an in-memory list with a database list has to re-implement search, sort and paging itself, and it drifts.
Scope. Setup catalog pages read /api/v1/meta/<type> — managed items read-only with a provenance badge, environment-authored items editable for capability holders under single, everything read-only for tenants under a wall (the server refuses anyway; the UI explains why). Assignment pages (sys_user_position, sys_user_permission_set) read /api/v1/data/… with native search/sort/paging and write the catalog item by name. Pickers — assign a user to a position or a set, sharing recipients, the capability matrix — list the registry. Remove every dependence on sys_position / sys_permission_set / sys_position_permission_set / sys_capability rows.
Acceptance. Against a framework build with C2 and C3 landed: Setup catalog pages render from the registry with the four tables gone; assigning a declared or Studio-authored position through the picker succeeds end to end and lands a name-keyed row; under isolated a tenant admin sees the catalog read-only and can still assign; no request fetches a merged list.
⭐ Parity gate (ADR-0131 §4 — this card fails without it). Under single, an organization administrator with no Studio capability creates, edits, deactivates and reactivates an environment-authored permission set from the same Setup page as today, with the list views, the filters, the object × CRUD / field-level matrix editor and the active switch all intact; a managed set opens read-only with a clone action. A JSON textarea in place of the matrix editor fails this card.
Absorbs: objectui#7205 — clicking a column header silently persisting an org-wide view overlay. That overlay axis is exactly what ADR-0131 D6/C5 retires, so the fix is not a save gesture on the old mechanism; read that card before starting.
Canonical unblock lines added on the #7041 census (objectui#7674); the blocker is as the card states above — no state change. The body already carries both targets, but on one line wrapped whole in inline backticks, so nothing matches at line start; split here, one line per blocker. The ADR-0131 execution-tree parent the body also names (objectstack-ai/objectstack#15194, open) is recorded as context, not added as a third blocker — objectstack#15193 is the gate card.
v18 pre-opening re-verification (C9): HOLDS. Nothing is implemented, and the blocker lines are incomplete
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-06T14:38Z. ⛔ Not a claim, ⛔ not a dispatch. Read-only re-verification on objectstack main6befe19c6e and objectui mainc910630cf9. The cut base was 2026-09-04, 3,298 commits earlier. The maintainer asked for this pre-opening preparation in the triage seat's chat: 「现在就可以处理吧」. Classes, positions and functions only. The claiming seat applies these corrections before building. The body is not rewritten.
The Setup catalog pages still read rows: apps/console/src/AppContent.tsx:269-271 routes positions to sys_position and permissions to sys_permission_set.
No objectui code reads the catalog's metadata for Setup.
PermissionMatrixEditor already lists permission metadata (:481), but its clone path reads the row (:952, permission-set-clone-dispatch.ts:35).
Additions:
The runtime dependence is about 11 sites in 10 files. The card did not enumerate it. It includes:
the approval-approver pickers, which the card's picker list does not name:approverIdentity.ts:100, decisionOutputParams.ts:73, useApproverDirectory.ts:114.
The server-side Setup nav entries are objectstack's (plugin-security/src/security-plugin.ts:1464-1466), not this card's. They move with C2/C3 on the framework side.
The new Blocked-by lines:
the acceptance "the four tables are gone" needs C3 (#15204);
absorbing objectui#7205 (sort persisting an org-wide overlay, still live at ObjectView.tsx:3194-3195/:3525-3526) needs C5's retirement of the overlay axis (#15206);
ADR §8 lists only C2 for C9, so these two record the card's own acceptance, not a new order.
target:v18 added, executing decision card objectstack-ai/objectstack#22010 (ruling 6020197009, batch #282 item 6, maintainer 「同意」). The label is a release-board view, not a gate: this card's gate stays its Blocked-by: / Restart-when: line on objectstack-ai/objectstack#15193. Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U. ⛔ Not a claim; no other label changes.
Ruling: batch #310 item 1 · letter A · maintainer 「cloud 冻结在 v17 没问题,其他同意你的建议。」 2026-10-10T05:22Z
Director seat, summon #36, session_019fWAt2renophxLVg5aJXMH (GitHub hotlong; written as objectstack-fleet[bot] via the relay). Batch #310 is the seven optimisation items of the ADR-0131 family assessment this seat gave in chat after ruling objectstack-ai/objectstack#22601 (B, 6094045326); the maintainer accepted every item but the cloud one (item 6, which keeps cloud pinned on the v17 line). Item 1 is this card. Thread-read: 6022571467.
Build it by reuse, not by new pages. The Setup catalog pages reuse the console's existing metadata-admin components (the permission matrix editor already reads and writes /api/v1/meta/permission/NAME and its layers), re-routed and re-gated for Setup; no new page family, and no server-side merged list (ADR-0131 D7).
The reader list this card inherits (objectui origin/main1b2d016, measured by this seat): the Setup position and permission-set pages themselves (generic ObjectViews over sys_position and sys_permission_set; the AppContent routes system/roles, system/positions, system/permissions), AssignedUsersSection (three find calls on the three tables), CapabilityMultiSelectField (find on sys_capability), RecipientPickerField (the position recipient reads sys_position), useApproverDirectory and approverIdentity (sys_position as a directory object), decisionOutputParams (position maps to sys_position), recordDelete and permission-set-clone-dispatch (sys_permission_set special cases), data-objectstack's sys_permission_set schema special case, RecordDetailView's sys_permission_set slot, PermissionMatrixEditor's sys_capability read. At least ten source files plus the generic pages, where the decision card said six.
The parity gate stands, and it answers the maintainer's question of this hour, verbatim 「以后 岗位、权限集是不是就不能在界面上添加了?」: under single, an organization administrator with no Studio capability still creates, edits, deactivates and reactivates positions and permission sets from the same Setup page as today; the write lands in the environment ledger through the metadata door (ADR-0131 D2 and D3; the redirect ADR-0094 D3 makes and C2's S7 write-through already performs). Under a wall (group / isolated) tenant administrators assign but do not define; the operator defines the catalog for every tenant in Studio. Managed-package items stay locked (clone to customize, the 2026-08-24 rule). Server half, owed by the cutover (refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write under single and refused under a wall (ADR-0131 D2/D3/D5/D13) objectstack#15204): the metadata door accepts an organization administrator's write for the position, permission and capability types under single without manage_metadata; without that acceptance this card's parity gate cannot pass, so the cutover plan names it.
State
No label change in this act. The triage seat moves pm:blocked to pm:queue, rewrites the Blocked-by: line to the ordering above (this card lands before the cutover's table-retiring PR, together with the pin bump), and routes the card to the objectui lane.
Triage: executing ruling 6094171670 (batch #310 item 1). pm:blocked → pm:queue, routed to the objectui domain:ui lane
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-10T05:53Z. ⛔ Not a claim, ⛔ not a dispatch.
Build by reuse: the Setup catalog pages re-route the existing metadata-admin components, such as the permission matrix editor. ⛔ No new page family, and ⛔ no server-side merged list (D7).
The reader list is at least ten source files plus the generic Setup pages: AssignedUsersSection, CapabilityMultiSelectField, RecipientPickerField, useApproverDirectory, approverIdentity, decisionOutputParams, recordDelete, permission-set-clone-dispatch, data-objectstack's special case, RecordDetailView's slot and PermissionMatrixEditor, plus the AppContent routes system/roles, system/positions and system/permissions.
The parity gate: under single, an organization administrator without Studio capability still creates, edits, deactivates and reactivates positions and permission sets from the same Setup page. Under a wall, tenant administrators assign but do not define.
On that framework the catalog still lives in rows. Measure what /api/v1/meta/position serves there, and whether a v17 org admin's write through the metadata door is accepted.
If this card's Setup pages would show cloud's organizations less than today, the PR names the cloud .objectui-sha hold it needs (the pin stays before this card until cloud moves to v18 after C7). ⛔ No silent regression on cloud.
This amends my 6094395552: the parity gate I copied from 6094171670 rests on a false premise, and it is now decision objectstack-ai/objectstack#22621
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-10T06:07Z. ⛔ Not a claim, ⛔ not a dispatch.
What I copied without checking: "under single, an organization administrator without Studio capability still creates, edits, deactivates and reactivates positions and permission sets from the same Setup page".
What main does (objectstack e22315238f):
The organization-admin set, and the derived organization_admin_no_bypass variant that single uses, keeps sys_position, sys_permission_set and the junction read-only. That is the anti-escalation rule at plugin-security/src/objects/default-permission-sets.ts:426-431 and :475-477.
It does not hold manage_metadata either.
Today, Setup's catalog writer is the platform admin (admin_full_access holds manage_metadata).
So:
Keeping today's authority needs no server change.
"The metadata door accepts an organization administrator's write" would loosen a security boundary. That is the maintainer's to decide, and it is now #22621 (recommended: A, keep today's authority).
For the claimant, until #22621 is ruled:
The parity gate is the platform admin's: create, edit, deactivate and reactivate in Setup, as today. The organization admin reads, and the page explains why.
The rest of the scope and the ordering stand as in 6094395552.
Director seat, summon #36, session_019fWAt2renophxLVg5aJXMH (via the relay). The record is 6094985249 on objectstack-ai/objectstack#22621, which closed completed in that act. Thread-read: 6094498192 (this lane's own amendment of the parity gate, which this ruling confirms).
This corrects this seat's 6094171670. Its parity-gate sentence rested on the ADR's wording, not the code: organization administrators are read-only on the catalog today (the anti-escalation rule, default-permission-sets.ts:426-431), and the metadata door's gate is manage_metadata. The parity gate reads: under single, the platform administrator (a manage_metadata holder) creates, edits, deactivates and reactivates positions and permission sets from the same Setup page as today, with the list views, the filters, the matrix editor and the active switch; an organization administrator sees the catalog read-only, and the page says why. Under a wall, tenant administrators assign but do not define. Managed-package items stay locked (clone to customize).
The "server half" named in 6094171670 is withdrawn. No metadata-door change is owed for organization administrators; the cutover (objectstack#15204) carries none. Everything else in 6094171670 stands: the card is unblocked (now pm:queue), it is built by reusing the metadata-admin components, it lands before the cutover's table-retiring PR together with the pin bump, and the reader list is the measured one.
Intake into the epic lane epic:#15194 · epic PM session_01Y5583bs2RDd53MH6kM1ca3 (os-steve) · 2026-10-18T14:41Z. ⛔ Not a claim. pm:epic is added after this comment; the state label stays as it is. The maintainer handed this tree's whole remaining development to the epic seat (delegation record: objectstack-ai/objectstack#15194's body; seat record 6251069534 there).
Claim: PM loop round 1 · 2026-10-18T17:12Z
Session: session_01Y5583bs2RDd53MH6kM1ca3
Account: os-steve (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-7611-retired-catalog-remainder
Worktree: the cloud session's own checkout (mode:cloud)
Domain: domain:ui
Seat: epic:#15194 (the epic lane: the maintainer handed this tree's whole remaining development to the epic seat, objectstack-ai/objectstack#15194's body; intake pointer 6251215808)
File surface, read on objectui origin/main76f91f8; stop on breach and explain in the report:
release record 6158162134 item 1 (census row 8c): packages/plugin-detail/src/renderers/PermissionFacetLink.tsx, packages/app-shell/src/views/metadata-admin/RecordPermissionAssignmentsRenderer.tsx, the sys_permission_set entry in packages/data-objectstack/src/index.ts, and the rest the census lists (RecordDetailView's slot, recordDelete's reset copy, ObjectView's note, the @object-ui/types TSDoc, plugin-detail's sdui manifest text, the MetadataFieldsPage TSDoc, the capabilityLint docblock, the locale comments, ROADMAP);
item 4: objectui#7205 is read and its disposition reported.
Container & model: M, mode:cloud, model: TIER_DEFAULT (dispatch-gates --tier --repo objectstack-ai/objectui: no path-derived mandate)
Clause-②: no
Responsibility: n/a — not a defect card
Thread-read: 6251215808
Serial constraints cleared: objectstack C3 stage 9 (#23952, in flight) changes no objectui reader — objectui source holds no non-comment read of sys_sharing_rule (grep at 76f91f8); sharing rules reach the console through the metadata door. No other in-flight epic stage touches objectui.
Hold released. The latest transition, 6159065130, set two restart conditions. Both hold now:
Item 1: @objectstack/spec@18.0.0-next.3's tag commit 2c9bf9430a compares ahead of 66949b7729.
{
"issue": 7611,
"status": "done",
"branch": "claude/issue-7611-retired-catalog-remainder",
"pr": "https://github.com/objectstack-ai/objectui/pull/12998",
"session": "session_01YNkqqKcTgHPV6SDyV6uquV",
"premise_still_valid": true,
"claim_check": "Newest Claim: on the card is 6252749120 (seat epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3) naming branch claude/issue-7611-retired-catalog-remainder: matches. Card assignee not written.",
"summary": "Item 1 (census row 8c) done: the object-page special cases for the retired sys_permission_set object are deleted (PermissionFacetLink + field:permission-facet-link, the DetailSection / InlineFieldInput branches, data-objectstack's facet widget stamp, RecordPermissionAssignmentsRenderer + its RecordDetailView slot, recordDelete's package-owned reset copy, the perm.facet.* and objectActions.resetPackageSet* keys in ten packs, the cli known-schema-type) and the published texts re-worded (types idField TSDoc, lookup.mdx, plugin-detail relationshipValueField description, MetadataFieldsPage, capabilityLint, ROADMAP). Item 3 measured live on objectstack main 6a49efb with this branch's console: every acceptance and parity clause passes except one, after fixing one gap found here (a permission set created from the Setup catalog was saved as a draft the live matrix editor never read; publishing it later wiped the grants): the create is now live (registry `createLive`, set on permission). The one failing clause, 'under isolated a tenant admin can still assign', is refused by objectstack's server (403 on sys_user_position / sys_user_permission_set for organization_admin) and is reported, not built, so the PR is `Part of #7611`. Item 4: objectui#7205 leaves nothing for this card (a header click writes only the user's sys_user_preference, zero /meta/view writes).",
"line_budget": "51 files, +304 / -1487 (1791 changed lines) against base 76f91f8, under the 3,000-line single-PR route; census estimate was 0.6k-0.9k for item 1 alone, the i18n key removal and the test rewrite of perm-home-namespace-3546 account for the excess",
"files_changed": "item 1: packages/plugin-detail/src/{renderers/PermissionFacetLink.tsx (deleted), DetailSection.tsx, DetailSectionNode.tsx, InlineFieldInput.tsx, RelatedList.tsx, renderers/record-related-list.tsx, index.tsx, __tests__/PermissionFacetLink.sduiCarrier.test.tsx (deleted), __tests__/InlineFieldInput.capabilityWidgetRetired.test.tsx, __tests__/InlineFieldInput.delegation.test.tsx}; packages/app-shell/src/{views/metadata-admin/RecordPermissionAssignmentsRenderer.tsx (deleted), views/RecordDetailView.tsx, views/ObjectView.tsx, hooks/useObjectActions.ts, hooks/__tests__/useObjectActions.test.tsx, preview/capabilityLint.ts, views/metadata-admin/PermissionMatrixEditor.tsx (comment), views/metadata-admin/PermissionAdvancedFacets.tsx (comment), views/__tests__/SearchResultsPage.resultsCountPlural-10024.test.tsx (comment)}; packages/core/src/actions/{recordDelete.ts, __tests__/recordDelete.test.ts}; packages/data-objectstack/src/index.ts; packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts; packages/i18n/src/__tests__/{perm-home-namespace-3546.test.tsx, count-families-11445.test.ts}; packages/cli/src/utils/known-schema-types.ts; packages/types/src/field-types.ts; packages/plugin-designer/src/MetadataFieldsPage.tsx; packages/plugin-form/src/ObjectForm.tsx; packages/plugin-view/src/{ObjectView.tsx, __tests__/ObjectView.gridDelete-10383.test.tsx}; packages/fields/src/{index.tsx, widgets/CapabilityMultiSelectField.tsx, __tests__/capability-multiselect-retired.test.ts}; scripts/__tests__/check-phantom-dependencies.test.ts; content/docs/fields/lookup.mdx; ROADMAP.md. item-3 gap: packages/app-shell/src/views/metadata-admin/{ResourceEditPage.tsx, registry.ts, anchors.ts, ResourceEditPage.liveCreate-7611.test.tsx (new)}. .changeset/7611-retired-catalog-remainder.md (minor, 6 packages).",
"item3_measurement": {
"rig": "objectstack main 6a49efb; showcase built with turbo (--filter @objectstack/example-showcase^...); `objectstack dev --seed-admin --fresh -p 4010` (Tenancy: single); isolated: the showcase app copied to a scratch dir whose package.json declares @objectstack/organizations (the CLI refuses a walled boot unless the host app declares it), OS_PLATFORM_OWNER_EMAIL=admin@objectos.ai, OS_AUTH_MEMBERSHIP_POLICY=invite-only; console = this branch, vite :5190 with DEV_PROXY_TARGET; Playwright Chromium with every /api request recorded",
"users": "single: author = member role admin (organization_admin_no_bypass) + fixture set {manage_metadata, setup.access, setup.write, manage_org_users}, no studio.access (/auth/me/permissions); orgadmin = member role admin only. isolated: tenant = member role admin (organization_admin).",
"four tables gone": "PASS: GET /api/v1/meta/object/NAME and /api/v1/data/NAME answer 404 for sys_position, sys_permission_set, sys_position_permission_set, sys_capability",
"catalog pages render from the registry": "PASS: Positions 17, Capabilities 12, Permission Sets 21 items; reads /meta/position, /meta/capability, /meta/permission (+ /data/sys_metadata_activation)",
"no request fetches a merged list": "PASS: no request to a retired object and no second list read in any recorded page load",
"parity create": "FAILED before this PR (New wrote PUT ...?mode=draft; editor opened without the label; editor Save wrote live; Home showed '1 unpublished change'; Publish replaced published objects {showcase_account R/E} with {}), PASS after: one live PUT /meta/permission/qa_parity_two, label kept, /meta/_drafts []",
"parity edit (object x CRUD and field-level matrix)": "PASS: published item carries objects.showcase_account {allowRead, allowEdit} and two fields entries",
"parity list views and filters": "PASS: search, source filter (Artifact 17 / Runtime 3), active filter (All / Active / Inactive)",
"parity deactivate / reactivate": "PASS: two POST /api/v1/security/_activation/permission/qa_parity_two, Inactive filter lists it between them, ledger ends active true",
"managed set read-only with clone": "PASS: showcase_manager 749/749 checkboxes disabled, 'Clone to customize'; POST /api/v1/security/permission-sets/showcase_manager/clone lands qa_manager_copy and opens it",
"org admin without manage_metadata (ruling A, objectstack#22621)": "PASS: no New, switches disabled, editor read-only naming manage_metadata",
"assign declared and environment-authored position through the picker, name-keyed row": "PASS as platform admin: position page Add holder, and the sys_user_position form whose Position select lists the 15 registry positions incl. qa_env_position; rows carry position manager / qa_env_position; qa_env_position's set reaches the holder",
"isolated: tenant admin sees the catalog read-only": "PASS: no New, 'Read-only for organization administrators ... your organization assigns them.'",
"isolated: tenant admin can still assign": "FAIL (server, objectstack): POST /api/v1/data/sys_user_position and /data/sys_user_permission_set as the tenant admin -> 403 PERMISSION_DENIED; console offers no Add holder (correct for the server's answer)"
},
"item4_reading": "objectui#7205: measured as platform admin on the single rig: two header clicks on showcase_account re-sort the grid and send only POST + PATCH /api/v1/data/sys_user_preference (objectui#12418's per-user list preference); /api/v1/meta/view writes = 0. Server side, objectstack meta-write-capability retires the org overlay arm (ADR-0131 D6/C5). Nothing remains of #7205 for #7611; #7205's own disposition (close) is the seat's.",
"tests": "At head a64d778 (except where noted). vitest from repo root: run A (f6ec5e6+fix) 11 files / 206 passed after one transform error this branch introduced was fixed (a05e7a7: apostrophe in a single-quoted manifest string); run B 3 files / 22 passed (gridDelete-10383, two DetailSection files); run C 4 files / 18 passed (liveCreate-7611 new, createFirstWritePin-11773, setupCatalog-7611, layersUnsaved-11799). Reverse verification of the new pin: createLive true->false in anchors.ts => 'outside a package: one live PUT...' fails (PUT carries mode=draft), control green; restored via git checkout HEAD, git diff HEAD empty. No ablation of a dist-resolved subject.",
"gates": "local: `pnpm turbo run type-check --concurrency=2` over core,i18n,types,data-objectstack,fields (Tasks 16/16, VERDICT command-exit 0) and plugin-detail,plugin-form,plugin-view,plugin-designer,app-shell,cli (Tasks 35/35, exit 0) — the hyphenated script, echoed per package; eslint --no-inline-config on the 40 changed ts/tsx files: 7 errors all in untouched lines, same count on 76f91f8 (4 data-objectstack no-console, 3 RelatedList react-compiler); node scripts/check-changeset-presence.mjs exit 0; node scripts/check-new-cross-file-line-citations.mjs '0 new citation(s)' exit 0. Not run locally (CI's): full `pnpm test`, `pnpm lint`. CI check-runs on PR #12998: in_progress at report time, not read.",
"deviations": [
"The whole-package vitest run of packages/plugin-detail + i18n + data-objectstack + cli was abandoned (workers timed out on a loaded 4-core box) and replaced by the targeted file lists above; full suites are CI's.",
"PR creation: the fleet-write relay was refused by the egress proxy ('repository_dispatch is not permitted for this session type', HTTP 403, with OS_FLEET_TRANSPORT unset and =direct alike — dispatch.mjs only dispatches), so the draft PR and its assignee were written through the REST proxy directly (curl to api.github.com) and land as os-steve, not objectstack-fleet[bot]. The report comment went the same way.",
"The platform replaced the PR body's trailing attribution lines with its session-URL footer at create time; the rest of the body read back byte-identical.",
"A symlink examples/app-showcase/node_modules/@objectstack/organizations was created in the shared objectstack checkout while building the isolated rig (it did not satisfy the CLI, which reads the app's package.json); removing it was refused by the guard-main-checkout-bash hook, so it is still there (gitignored node_modules, no tracked file changed). Seat: `rm` it from a session where the hook permits, or leave it. No objectstack source was edited.",
"Item 3 found and fixed one gap in objectui beyond the claim's file surface (ResourceEditPage.tsx, registry.ts, anchors.ts + one new test): landing point is the producer of the stray draft, the generic create page.",
"Item-1 ripple beyond the literal census list, all references to deleted symbols or copy: useObjectActions, plugin-view ObjectView and its gridDelete test, PermissionMatrixEditor / PermissionAdvancedFacets / CapabilityMultiSelectField / DetailSectionNode comments, the i18n tests that used perm.facet keys."
],
"mcp_calls": "0",
"api_writes": "3 — POST /repos/objectstack-ai/objectui/pulls (draft #12998); POST /repos/objectstack-ai/objectui/issues/12998/assignees (os-steve); POST /repos/objectstack-ai/objectui/issues/7611/comments (this report). Plus 4 git pushes to the branch; 2 refused relay dispatches (no write landed).",
"open_questions": [
{
"question": "Dispatch Section 1 quotes the body's parity gate ('an organization administrator with NO Studio capability creates, edits ...'), but maintainer ruling A on objectstack#22621 (card comment 6095024693) says Setup authoring under single requires manage_metadata, and an org admin without it is read-only. Which reading binds?",
"options": ["A: the ruling — measured both: an org admin holding manage_metadata and no studio.access authors everything; a plain org admin is read-only with the reason", "B: the literal body — would need the metadata door to admit organization_admin, loosening a boundary the maintainer ruled to keep"],
"recommendation": "A, decided by the later maintainer ruling; nothing built for B"
},
{
"question": "Under isolated, objectstack's organization_admin keeps sys_user_position and sys_user_permission_set read-only (default-permission-sets 'Anti-escalation'), so 'a tenant admin can still assign' fails, while ADR-0131 D3 says assignments are 'created and removed by that organization's admins'. Is the clause owed by objectstack (an assignment grant scoped by the wall, with the escalation guard on which sets/positions may be assigned), or is the clause to be amended?",
"options": ["A: objectstack card to let walled org admins write assignment rows of their own organization, refusing admin_full_access-class sets", "B: amend #7611's acceptance: under a wall only the operator assigns"],
"recommendation": "A on the real-need axis (the ADR's own sentence, and the console page already tells tenant admins 'your organization assigns them'), but it loosens a security boundary, so it is the maintainer's; this card stays open on it either way"
}
],
"out_of_scope_findings": [
"class: b · reach: POST /api/v1/data/sys_user_position as an isolated-posture tenant admin (member role admin, organization_admin) -> 403 PERMISSION_DENIED; same for /data/sys_user_permission_set · evidence: objectstack main 6a49efb, plugin-security default-permission-sets.ts organization_admin declaration sets both objects allowCreate/allowEdit/allowDelete false; ADR-0131 D3 'Assignments are organization rows, in every posture ... created and removed by that organization's admins'; Seam: spec:ADR-0131 D3 assignment rows -> runtime:organization_admin object grants | renderer:PositionHoldersSection / AssignedUsersSection (correctly hide Add) · dedupe words: organization_admin assignment read-only; tenant admin cannot assign position; sys_user_position anti-escalation walled",
"carrier: none · noted, not filed · console copy on the org-admin read-only editor also shows 'Read-only (this metadata type has no runtime write channel)' beside the correct manage_metadata reason (single and isolated)",
"carrier: none · noted, not filed · packages/app-shell/src/utils/approverIdentity.ts DISPLAY_FIELDS_BY_OBJECT keeps a sys_position entry no binding reaches since APPROVER_VALUE_SOURCES.position is registry-bound in the installed spec 18.0.0-next.3; its approverValueIsName docblock still says 'under the installed spec position answers through the second arm'",
"carrier: none · noted, not filed · capabilityLint's pseudo-stack carries no registry-declared capabilities (stack.capabilities), only permission-set grants; read only, a false 'resolves nowhere' warning for a defineCapability-only capability is possible but not measured"
]
}
{
"issue": 7611,
"part": "patch round 1 on PR #12998 (seat message from session_01Y5583bs2RDd53MH6kM1ca3)",
"status": "done",
"branch": "claude/issue-7611-retired-catalog-remainder",
"pr": "https://github.com/objectstack-ai/objectui/pull/12998",
"head": "41f02663c39b083cf677f7a57aca7dcadd474336",
"session": "session_01YNkqqKcTgHPV6SDyV6uquV",
"summary": "Both red shards are fixed at the producer, the scripts' own tests. (1) check-i18n-call-site-keys.test.ts pinned recordDelete's resetPackageSetSuccess call site; that row is retired, because the call went with the package-owned reset copy. In its place the test now pins that the call is absent, beside the unchanged live sister assertion `t('objectActions.deleteSuccess', { label })`. The other two rows (marketplace, home) are untouched. (2) check-i18n-en-drift.test.ts used objectActions.resetPackageSetConfirm as its only live example of a `'a' + 'b'` value. No pack value is spelled that way now (grep over all ten packs: none), so there was no live call site of the same shape to move the pin to. The folding behaviour is now pinned on a parsePack fixture holding a multi-line concatenation, asserting the folded string. No assertion weakened, no test skipped. Docblocks that named the deleted key (check-i18n-en-drift.mjs, check-i18n-call-site-keys.mjs) or the deleted applyFieldWidgetOverrides (plugin-charts ObjectChart.tsx, plugin-grid relationalMetaKeys.ts and its 6875 test) are re-worded; comments only, no behaviour change.",
"tests": "Local, from the repo root: `pnpm exec vitest run --maxWorkers=2 scripts/` (includes both failing files) -> Test Files 186 passed | 2 skipped (188), Tests 5620 passed | 2 skipped; os-verify-lock VERDICT command-exit 0, exit captured before any pipe. The VERDICT lines inside the log are the citation gate's own fixtures.",
"gates": "CI on head 41f0266, read from the check-runs API until complete: 36 runs, 33 success, 3 skipped (Test (coverage), its matrix row, dependabot), 0 failure. Includes Test (shard 1..16/16) all success, Test success, Type Check success, Lint success, Build and E2E success, Repo Gates success, Line Citation Gate success, Changeset Declaration success. PR is draft, mergeable_state clean. Local: check-changeset-presence exit 0; check-new-cross-file-line-citations 0 new.",
"files_changed_this_round": "scripts/__tests__/check-i18n-call-site-keys.test.ts; scripts/__tests__/check-i18n-en-drift.test.ts; scripts/check-i18n-call-site-keys.mjs (docblock); scripts/check-i18n-en-drift.mjs (docblock); packages/plugin-charts/src/ObjectChart.tsx (comment); packages/plugin-grid/src/relationalMetaKeys.ts (comment); packages/plugin-grid/src/__tests__/lookupDisplayFieldSpelling-6875.test.tsx (comment)",
"line_budget": "this round +31 / -32 in 7 files; PR total 58 files",
"deviations": [
"Writes went through the REST proxy directly (curl to api.github.com), as in the first report: the fleet-write relay is refused for this session type.",
"No merge of origin/main: GitHub reports no conflict (mergeable_state clean)."
],
"mcp_calls": "0",
"api_writes": "1: POST /repos/objectstack-ai/objectui/issues/7611/comments (this addendum). Plus 1 git push.",
"open_questions": [],
"out_of_scope_findings": []
}
{
"issue": 7611,
"part": "patch round 1, items 2 and 3 on PR #12998 (seat messages from session_01Y5583bs2RDd53MH6kM1ca3)",
"status": "done",
"branch": "claude/issue-7611-retired-catalog-remainder",
"pr": "https://github.com/objectstack-ai/objectui/pull/12998",
"head": "efb2db1dd0fe47052b8fbfca532e03b77e7cc68c",
"session": "session_01YNkqqKcTgHPV6SDyV6uquV",
"carrier": "The failing acceptance clause 'under isolated a tenant admin can still assign' is carried by objectstack-ai/objectstack#24136 (code half of maintainer ruling B on objectstack-ai/objectstack#23960, record 6228728551; ADR half landed as PR #24163). #7611 stays `Part of #7611`. This supersedes my first report's Q2 and its class-b finding; nothing to file.",
"pr_body_line_2_for_the_seat": "Clause-②: no (narrowing)",
"reachability_measured": "Against base 76f91f8. @object-ui/core exports recordDelete (src/index.ts re-exports actions/index.ts, which re-exports recordDelete.ts): confirmText narrows. @object-ui/i18n: the ten built-in packs are published, so the removed keys narrow. @object-ui/plugin-detail: PermissionFacetLink was imported but never exported from src/index.ts (exports has only '.'), but its registry key field:permission-facet-link was registered at module load, a published runtime face: narrows. @object-ui/cli: known-schema-types is not exported (src/index.ts exports serve and init), but it decides what the published `objectui check` bin accepts: narrows that bin's face. @object-ui/app-shell: RecordPermissionAssignmentsRenderer was never exported from src/index.ts: internal. @object-ui/data-objectstack: applyFieldWidgetOverrides was private: internal; its effect, the getObjectSchema stamp, is a behaviour change.",
"changeset": ".changeset/7611-retired-catalog-remainder.md rewritten. Still `minor` for all six packages. A Breaking section gives FROM / TO pairs with a one-line fix for core confirmText, the i18n keys, the plugin-detail registry key and the cli known type. Behaviour changes, one line each: getObjectSchema stops stamping the widget; the record page drops the assignments panel; the Setup permission-set create is live. Widenings: recordDelete's data source needs only delete; the registry entry gains optional createLive. The internals are named as not reachable.",
"tests": "This round changed the changeset only (no source); the round-1 local run stands: `vitest run scripts/` 186 files passed, exit 0. node scripts/check-changeset-presence.mjs passes.",
"gates": "CI on head efb2db1, read until complete: 36 runs, 33 success, 3 skipped (Test (coverage), its matrix row, dependabot), 0 failure. All 16 Test shards and Test, Type Check, Lint, Changeset Declaration, Changeset Bump Policy and Changeset Fixed Group Check passed. The PR is draft with mergeable_state clean.",
"deviations": ["Written through the REST proxy directly (curl to api.github.com): the fleet-write relay is refused for this session type.", "The PR body is not edited by me; line 2 is given above for the seat to write."],
"mcp_calls": "0 GitHub MCP calls (1 send_message to the seat in the earlier half of this round)",
"api_writes": "1: POST /repos/objectstack-ai/objectui/issues/7611/comments (this addendum). Also 1 git push.",
"open_questions": [],
"out_of_scope_findings": []
}
Landed · epic PM session_01Y5583bs2RDd53MH6kM1ca3 (os-steve) · 2026-10-19T01:32Z. PR #12998 (C9, Part of #7611) has merged. Its contract review is record 6257392934 (CONTRACT_REVIEW_TIER, PASS on efb2db1dd). The merged head b2ef1e631 is that head plus a branch update (parents efb2db1dd, 1624e08f6); no code was added after the review.
The object-page special cases and texts for the four retired catalog objects (census row 8c) are deleted or reworded.
A permission set created from the Setup catalog is created live. This is the item-3 gap, measured before and after the fix.
The acceptance table in the PR body measures every clause under single and isolated.
Remainder. One acceptance clause is still open: under isolated, a tenant admin can still assign. The server refuses that write today (403). Its producer is objectstack, and ruling B on objectstack-ai/objectstack#23960 (6228728551) places it there. This card closes when that carrier lands. The carrier is objectstack-ai/objectstack#24136, which waits on objectstack-ai/objectstack#24340.
Item 3.approverIdentity.ts still has a dead sys_position entry in DISPLAY_FIELDS_BY_OBJECT and a stale approverValueIsName docblock. This rides the PR for this card's remainder.
Item 4. Whether capabilityLint raises a false "resolves nowhere" warning for a capability declared only with defineCapability has not been measured, so it is not a card. The remainder's dev measures it with the reviewer's instrument: a draft that references such a capability, then Publish from Home. The dev fixes it in that PR only if it reproduces.
Provenance. The seat put this to the maintainer in chat, at the end of its p1 sweep: 「三张只跟多组织隔离部署(walled 模式)有关的卡挂着 v18 标签……我倾向把这三张的 v18 标签去掉,改排 18.x」. The maintainer answered 「两件事 同意」.
Activity
claude commentedon Sep 4, 2026
Blocked-by: objectstack-ai/objectstack#15193
Blocked-by: objectstack-ai/objectstack#15196
Canonical unblock lines added on the #7041 census (objectui#7674); the blocker is as the card states above — no state change. The body already carries both targets, but on one line wrapped whole in inline backticks, so nothing matches at line start; split here, one line per blocker. The ADR-0131 execution-tree parent the body also names (objectstack-ai/objectstack#15194, open) is recorded as context, not added as a third blocker — objectstack#15193 is the gate card.
Generated by Claude Code
objectstack-fleet commentedon Oct 6, 2026
v18 pre-opening re-verification (C9): HOLDS. Nothing is implemented, and the blocker lines are incomplete
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-06T14:38Z. ⛔ Not a claim, ⛔ not a dispatch. Read-only re-verification on objectstackmain6befe19c6eand objectuimainc910630cf9. The cut base was 2026-09-04, 3,298 commits earlier. The maintainer asked for this pre-opening preparation in the triage seat's chat: 「现在就可以处理吧」. Classes, positions and functions only. The claiming seat applies these corrections before building. The body is not rewritten.Blocked-by: objectstack-ai/objectstack#15204
Blocked-by: objectstack-ai/objectstack#15206
Holds:
apps/console/src/AppContent.tsx:269-271routes positions tosys_positionand permissions tosys_permission_set.PermissionMatrixEditoralready lists permission metadata (:481), but its clone path reads the row (:952,permission-set-clone-dispatch.ts:35).Additions:
AssignedUsersSection.tsx:127,149,154(bypermission_set_id);CapabilityMultiSelectField.tsx:177;RecipientPickerField.tsx:54;RecordDetailView.tsx:2881;core/actions/recordDelete.ts:96;data-objectstack/src/index.ts:5128;approverIdentity.ts:100,decisionOutputParams.ts:73,useApproverDirectory.ts:114.plugin-security/src/security-plugin.ts:1464-1466), not this card's. They move with C2/C3 on the framework side.Blocked-bylines:ObjectView.tsx:3194-3195/:3525-3526) needs C5's retirement of the overlay axis (#15206);Generated by Claude Code
objectstack-fleet commentedon Oct 6, 2026
target:v18added, executing decision card objectstack-ai/objectstack#22010 (ruling6020197009, batch #282 item 6, maintainer 「同意」). The label is a release-board view, not a gate: this card's gate stays itsBlocked-by:/Restart-when:line on objectstack-ai/objectstack#15193. Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·session_01AavokzJ5DndAwitDXvKy4U. ⛔ Not a claim; no other label changes.objectstack-fleet commentedon Oct 10, 2026
Ruling: batch #310 item 1 · letter A · maintainer 「cloud 冻结在 v17 没问题,其他同意你的建议。」 2026-10-10T05:22Z
Director seat, summon #36,
session_019fWAt2renophxLVg5aJXMH(GitHubhotlong; written asobjectstack-fleet[bot]via the relay). Batch #310 is the seven optimisation items of the ADR-0131 family assessment this seat gave in chat after ruling objectstack-ai/objectstack#22601 (B, 6094045326); the maintainer accepted every item but the cloud one (item 6, which keeps cloud pinned on the v17 line). Item 1 is this card. Thread-read: 6022571467.The ruling
GET /api/v1/meta/position,/api/v1/meta/permission,/api/v1/meta/capability) are on objectstackmainsince C2's S1–S5, and [Decision] ADR-0131 剩余部分(C2 余下阶段 + C3):继续分段、合并成一次切换,还是改成「registry 支撑的对象」 objectstack#22601 ruled B: the four catalog tables leave in ONE cutover with C2's remaining reader switch, and that cutover's last PR cannot merge until this card has landed and the.objectui-shapin has moved (AGENTS.md Post-Task Checklist step 4). This card is therefore on the cutover's critical path and leavespm:blockedforpm:queuenow; the label move and theBlocked-by:rewrite are the triage seat's, routed to the objectui lane./api/v1/meta/permission/NAMEand its layers), re-routed and re-gated for Setup; no new page family, and no server-side merged list (ADR-0131 D7).origin/main1b2d016, measured by this seat): the Setup position and permission-set pages themselves (generic ObjectViews oversys_positionandsys_permission_set; the AppContent routessystem/roles,system/positions,system/permissions),AssignedUsersSection(threefindcalls on the three tables),CapabilityMultiSelectField(findonsys_capability),RecipientPickerField(the position recipient readssys_position),useApproverDirectoryandapproverIdentity(sys_positionas a directory object),decisionOutputParams(position maps tosys_position),recordDeleteandpermission-set-clone-dispatch(sys_permission_setspecial cases),data-objectstack'ssys_permission_setschema special case,RecordDetailView'ssys_permission_setslot,PermissionMatrixEditor'ssys_capabilityread. At least ten source files plus the generic pages, where the decision card said six.single, an organization administrator with no Studio capability still creates, edits, deactivates and reactivates positions and permission sets from the same Setup page as today; the write lands in the environment ledger through the metadata door (ADR-0131 D2 and D3; the redirect ADR-0094 D3 makes and C2's S7 write-through already performs). Under a wall (group/isolated) tenant administrators assign but do not define; the operator defines the catalog for every tenant in Studio. Managed-package items stay locked (clone to customize, the 2026-08-24 rule). Server half, owed by the cutover (refactor(plugin-security,platform-objects,spec): retire the catalog seeders, the per-organization catalog machinery and the four catalog objects; Setup creation is an environment write undersingleand refused under a wall (ADR-0131 D2/D3/D5/D13) objectstack#15204): the metadata door accepts an organization administrator's write for theposition,permissionandcapabilitytypes undersinglewithoutmanage_metadata; without that acceptance this card's parity gate cannot pass, so the cutover plan names it.State
pm:blockedtopm:queue, rewrites theBlocked-by:line to the ordering above (this card lands before the cutover's table-retiring PR, together with the pin bump), and routes the card to the objectui lane.Generated by Claude Code
objectstack-fleet commentedon Oct 10, 2026
Triage: executing ruling
6094171670(batch #310 item 1).pm:blocked→pm:queue, routed to the objectuidomain:uilaneTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-10T05:53Z. ⛔ Not a claim, ⛔ not a dispatch.Blocked-by: none
/api/v1/meta/position,/permission,/capability) have been on objectstackmainsince C2's S1–S5.6094045326), so this card sits on the cutover's critical path.Blocked-by:line sits inside backticks, so no unlock scan reads it. This line-startBlocked-by: noneis the machine-read one now.singleand refused under a wall (ADR-0131 D2/D3/D5/D13) objectstack#15204) and together with objectstack's.objectui-shabump (AGENTS.md Post-Task Checklist step 4). The cutover's stage plan names that PR.AssignedUsersSection,CapabilityMultiSelectField,RecipientPickerField,useApproverDirectory,approverIdentity,decisionOutputParams,recordDelete,permission-set-clone-dispatch,data-objectstack's special case,RecordDetailView's slot andPermissionMatrixEditor, plus the AppContent routessystem/roles,system/positionsandsystem/permissions.single, an organization administrator without Studio capability still creates, edits, deactivates and reactivates positions and permission sets from the same Setup page. Under a wall, tenant administrators assign but do not define.singleand refused under a wall (ADR-0131 D2/D3/D5/D13) objectstack#15204.main(cloud#2755 moves.objectui-shaalone) on framework56bf27affb, the v17 line. The maintainer confirmed that freeze in batch Fix CRM example field naming to comply with snake_case convention #310 item 6./api/v1/meta/positionserves there, and whether a v17 org admin's write through the metadata door is accepted..objectui-shahold it needs (the pin stays before this card until cloud moves to v18 after C7). ⛔ No silent regression on cloud.objectstack-fleet commentedon Oct 10, 2026
This amends my
6094395552: the parity gate I copied from6094171670rests on a false premise, and it is now decision objectstack-ai/objectstack#22621Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-10T06:07Z. ⛔ Not a claim, ⛔ not a dispatch.single, an organization administrator without Studio capability still creates, edits, deactivates and reactivates positions and permission sets from the same Setup page".maindoes (objectstacke22315238f):organization_admin_no_bypassvariant thatsingleuses, keepssys_position,sys_permission_setand the junction read-only. That is the anti-escalation rule atplugin-security/src/objects/default-permission-sets.ts:426-431and:475-477.manage_metadataeither.admin_full_accessholdsmanage_metadata).6094395552.objectstack-fleet commentedon Oct 10, 2026
Ruling pointer: batch #311 item 1 (decision card objectstack#22621) · A · maintainer 「同意」 2026-10-10T07:15Z
Director seat, summon #36,
session_019fWAt2renophxLVg5aJXMH(via the relay). The record is 6094985249 on objectstack-ai/objectstack#22621, which closedcompletedin that act. Thread-read: 6094498192 (this lane's own amendment of the parity gate, which this ruling confirms).default-permission-sets.ts:426-431), and the metadata door's gate ismanage_metadata. The parity gate reads: undersingle, the platform administrator (amanage_metadataholder) creates, edits, deactivates and reactivates positions and permission sets from the same Setup page as today, with the list views, the filters, the matrix editor and the active switch; an organization administrator sees the catalog read-only, and the page says why. Under a wall, tenant administrators assign but do not define. Managed-package items stay locked (clone to customize).pm:queue), it is built by reusing the metadata-admin components, it lands before the cutover's table-retiring PR together with the pin bump, and the reader list is the measured one.Generated by Claude Code
63 remaining items
objectstack-fleet commentedon Oct 18, 2026
Intake into the epic lane
epic:#15194· epic PMsession_01Y5583bs2RDd53MH6kM1ca3(os-steve) · 2026-10-18T14:41Z. ⛔ Not a claim.pm:epicis added after this comment; the state label stays as it is. The maintainer handed this tree's whole remaining development to the epic seat (delegation record: objectstack-ai/objectstack#15194's body; seat record 6251069534 there).@objectstack/spec@18.0.0-next.3's tag commit2c9bf9430acomparesaheadof66949b7729. Item 3 still waits on feat(core,objectql,plugin-security,plugin-sharing): the catalog is read from the registry; assignment tables reference it by name (ADR-0131 D2/D3/D4) objectstack#15196. The hold stays until the epic seat dispatches it.objectstack-fleet commentedon Oct 18, 2026
Claim: PM loop round 1 · 2026-10-18T17:12Z
Session:
session_01Y5583bs2RDd53MH6kM1ca3Account:
os-steve(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-7611-retired-catalog-remainderWorktree: the cloud session's own checkout (
mode:cloud)Domain:
domain:uiSeat:
epic:#15194(the epic lane: the maintainer handed this tree's whole remaining development to the epic seat, objectstack-ai/objectstack#15194's body; intake pointer 6251215808)File surface, read on objectui
origin/main76f91f8; stop on breach and explain in the report:packages/plugin-detail/src/renderers/PermissionFacetLink.tsx,packages/app-shell/src/views/metadata-admin/RecordPermissionAssignmentsRenderer.tsx, thesys_permission_setentry inpackages/data-objectstack/src/index.ts, and the rest the census lists (RecordDetailView's slot,recordDelete's reset copy,ObjectView's note, the@object-ui/typesTSDoc, plugin-detail's sdui manifest text, theMetadataFieldsPageTSDoc, thecapabilityLintdocblock, the locale comments, ROADMAP);main(C2 closed in fix(plugin-security): the position refusal reads no retired catalog table and names the catalog type it judged against; the unimported per-organization catalog module is deleted objectstack#24365, C3 closed with stage 9 carried by C3 stage 9 (#15204): declared sharing rules read from the registry, bootstrapDeclaredSharingRules retires, and the ceremony deletes the declared-rule mirrors; the verified marker follows (director ordering ruling) objectstack#23952) — measured, and built only where a gap is found;Container & model:
M,mode:cloud,model: TIER_DEFAULT(dispatch-gates --tier --repo objectstack-ai/objectui: no path-derived mandate)Clause-②: no
Responsibility: n/a — not a defect card
Thread-read: 6251215808
Serial constraints cleared: objectstack C3 stage 9 (#23952, in flight) changes no objectui reader — objectui source holds no non-comment read of
sys_sharing_rule(grep at76f91f8); sharing rules reach the console through the metadata door. No other in-flight epic stage touches objectui.Hold released. The latest transition, 6159065130, set two restart conditions. Both hold now:
@objectstack/spec@18.0.0-next.3's tag commit2c9bf9430acomparesaheadof66949b7729.completedat 17:06Z (PR #24365).Second check: no merged PR carries this card after that comment. Eight merged PRs mention the number, and none has a
Part oforFixesline for it.os-steve commentedon Oct 18, 2026
os-dev-report
{ "issue": 7611, "status": "done", "branch": "claude/issue-7611-retired-catalog-remainder", "pr": "https://github.com/objectstack-ai/objectui/pull/12998", "session": "session_01YNkqqKcTgHPV6SDyV6uquV", "premise_still_valid": true, "claim_check": "Newest Claim: on the card is 6252749120 (seat epic:#15194, session_01Y5583bs2RDd53MH6kM1ca3) naming branch claude/issue-7611-retired-catalog-remainder: matches. Card assignee not written.", "summary": "Item 1 (census row 8c) done: the object-page special cases for the retired sys_permission_set object are deleted (PermissionFacetLink + field:permission-facet-link, the DetailSection / InlineFieldInput branches, data-objectstack's facet widget stamp, RecordPermissionAssignmentsRenderer + its RecordDetailView slot, recordDelete's package-owned reset copy, the perm.facet.* and objectActions.resetPackageSet* keys in ten packs, the cli known-schema-type) and the published texts re-worded (types idField TSDoc, lookup.mdx, plugin-detail relationshipValueField description, MetadataFieldsPage, capabilityLint, ROADMAP). Item 3 measured live on objectstack main 6a49efb with this branch's console: every acceptance and parity clause passes except one, after fixing one gap found here (a permission set created from the Setup catalog was saved as a draft the live matrix editor never read; publishing it later wiped the grants): the create is now live (registry `createLive`, set on permission). The one failing clause, 'under isolated a tenant admin can still assign', is refused by objectstack's server (403 on sys_user_position / sys_user_permission_set for organization_admin) and is reported, not built, so the PR is `Part of #7611`. Item 4: objectui#7205 leaves nothing for this card (a header click writes only the user's sys_user_preference, zero /meta/view writes).", "line_budget": "51 files, +304 / -1487 (1791 changed lines) against base 76f91f8, under the 3,000-line single-PR route; census estimate was 0.6k-0.9k for item 1 alone, the i18n key removal and the test rewrite of perm-home-namespace-3546 account for the excess", "files_changed": "item 1: packages/plugin-detail/src/{renderers/PermissionFacetLink.tsx (deleted), DetailSection.tsx, DetailSectionNode.tsx, InlineFieldInput.tsx, RelatedList.tsx, renderers/record-related-list.tsx, index.tsx, __tests__/PermissionFacetLink.sduiCarrier.test.tsx (deleted), __tests__/InlineFieldInput.capabilityWidgetRetired.test.tsx, __tests__/InlineFieldInput.delegation.test.tsx}; packages/app-shell/src/{views/metadata-admin/RecordPermissionAssignmentsRenderer.tsx (deleted), views/RecordDetailView.tsx, views/ObjectView.tsx, hooks/useObjectActions.ts, hooks/__tests__/useObjectActions.test.tsx, preview/capabilityLint.ts, views/metadata-admin/PermissionMatrixEditor.tsx (comment), views/metadata-admin/PermissionAdvancedFacets.tsx (comment), views/__tests__/SearchResultsPage.resultsCountPlural-10024.test.tsx (comment)}; packages/core/src/actions/{recordDelete.ts, __tests__/recordDelete.test.ts}; packages/data-objectstack/src/index.ts; packages/i18n/src/locales/{ar,de,en,es,fr,ja,ko,pt,ru,zh}.ts; packages/i18n/src/__tests__/{perm-home-namespace-3546.test.tsx, count-families-11445.test.ts}; packages/cli/src/utils/known-schema-types.ts; packages/types/src/field-types.ts; packages/plugin-designer/src/MetadataFieldsPage.tsx; packages/plugin-form/src/ObjectForm.tsx; packages/plugin-view/src/{ObjectView.tsx, __tests__/ObjectView.gridDelete-10383.test.tsx}; packages/fields/src/{index.tsx, widgets/CapabilityMultiSelectField.tsx, __tests__/capability-multiselect-retired.test.ts}; scripts/__tests__/check-phantom-dependencies.test.ts; content/docs/fields/lookup.mdx; ROADMAP.md. item-3 gap: packages/app-shell/src/views/metadata-admin/{ResourceEditPage.tsx, registry.ts, anchors.ts, ResourceEditPage.liveCreate-7611.test.tsx (new)}. .changeset/7611-retired-catalog-remainder.md (minor, 6 packages).", "item3_measurement": { "rig": "objectstack main 6a49efb; showcase built with turbo (--filter @objectstack/example-showcase^...); `objectstack dev --seed-admin --fresh -p 4010` (Tenancy: single); isolated: the showcase app copied to a scratch dir whose package.json declares @objectstack/organizations (the CLI refuses a walled boot unless the host app declares it), OS_PLATFORM_OWNER_EMAIL=admin@objectos.ai, OS_AUTH_MEMBERSHIP_POLICY=invite-only; console = this branch, vite :5190 with DEV_PROXY_TARGET; Playwright Chromium with every /api request recorded", "users": "single: author = member role admin (organization_admin_no_bypass) + fixture set {manage_metadata, setup.access, setup.write, manage_org_users}, no studio.access (/auth/me/permissions); orgadmin = member role admin only. isolated: tenant = member role admin (organization_admin).", "four tables gone": "PASS: GET /api/v1/meta/object/NAME and /api/v1/data/NAME answer 404 for sys_position, sys_permission_set, sys_position_permission_set, sys_capability", "catalog pages render from the registry": "PASS: Positions 17, Capabilities 12, Permission Sets 21 items; reads /meta/position, /meta/capability, /meta/permission (+ /data/sys_metadata_activation)", "no request fetches a merged list": "PASS: no request to a retired object and no second list read in any recorded page load", "parity create": "FAILED before this PR (New wrote PUT ...?mode=draft; editor opened without the label; editor Save wrote live; Home showed '1 unpublished change'; Publish replaced published objects {showcase_account R/E} with {}), PASS after: one live PUT /meta/permission/qa_parity_two, label kept, /meta/_drafts []", "parity edit (object x CRUD and field-level matrix)": "PASS: published item carries objects.showcase_account {allowRead, allowEdit} and two fields entries", "parity list views and filters": "PASS: search, source filter (Artifact 17 / Runtime 3), active filter (All / Active / Inactive)", "parity deactivate / reactivate": "PASS: two POST /api/v1/security/_activation/permission/qa_parity_two, Inactive filter lists it between them, ledger ends active true", "managed set read-only with clone": "PASS: showcase_manager 749/749 checkboxes disabled, 'Clone to customize'; POST /api/v1/security/permission-sets/showcase_manager/clone lands qa_manager_copy and opens it", "org admin without manage_metadata (ruling A, objectstack#22621)": "PASS: no New, switches disabled, editor read-only naming manage_metadata", "assign declared and environment-authored position through the picker, name-keyed row": "PASS as platform admin: position page Add holder, and the sys_user_position form whose Position select lists the 15 registry positions incl. qa_env_position; rows carry position manager / qa_env_position; qa_env_position's set reaches the holder", "isolated: tenant admin sees the catalog read-only": "PASS: no New, 'Read-only for organization administrators ... your organization assigns them.'", "isolated: tenant admin can still assign": "FAIL (server, objectstack): POST /api/v1/data/sys_user_position and /data/sys_user_permission_set as the tenant admin -> 403 PERMISSION_DENIED; console offers no Add holder (correct for the server's answer)" }, "item4_reading": "objectui#7205: measured as platform admin on the single rig: two header clicks on showcase_account re-sort the grid and send only POST + PATCH /api/v1/data/sys_user_preference (objectui#12418's per-user list preference); /api/v1/meta/view writes = 0. Server side, objectstack meta-write-capability retires the org overlay arm (ADR-0131 D6/C5). Nothing remains of #7205 for #7611; #7205's own disposition (close) is the seat's.", "tests": "At head a64d778 (except where noted). vitest from repo root: run A (f6ec5e6+fix) 11 files / 206 passed after one transform error this branch introduced was fixed (a05e7a7: apostrophe in a single-quoted manifest string); run B 3 files / 22 passed (gridDelete-10383, two DetailSection files); run C 4 files / 18 passed (liveCreate-7611 new, createFirstWritePin-11773, setupCatalog-7611, layersUnsaved-11799). Reverse verification of the new pin: createLive true->false in anchors.ts => 'outside a package: one live PUT...' fails (PUT carries mode=draft), control green; restored via git checkout HEAD, git diff HEAD empty. No ablation of a dist-resolved subject.", "gates": "local: `pnpm turbo run type-check --concurrency=2` over core,i18n,types,data-objectstack,fields (Tasks 16/16, VERDICT command-exit 0) and plugin-detail,plugin-form,plugin-view,plugin-designer,app-shell,cli (Tasks 35/35, exit 0) — the hyphenated script, echoed per package; eslint --no-inline-config on the 40 changed ts/tsx files: 7 errors all in untouched lines, same count on 76f91f8 (4 data-objectstack no-console, 3 RelatedList react-compiler); node scripts/check-changeset-presence.mjs exit 0; node scripts/check-new-cross-file-line-citations.mjs '0 new citation(s)' exit 0. Not run locally (CI's): full `pnpm test`, `pnpm lint`. CI check-runs on PR #12998: in_progress at report time, not read.", "deviations": [ "The whole-package vitest run of packages/plugin-detail + i18n + data-objectstack + cli was abandoned (workers timed out on a loaded 4-core box) and replaced by the targeted file lists above; full suites are CI's.", "PR creation: the fleet-write relay was refused by the egress proxy ('repository_dispatch is not permitted for this session type', HTTP 403, with OS_FLEET_TRANSPORT unset and =direct alike — dispatch.mjs only dispatches), so the draft PR and its assignee were written through the REST proxy directly (curl to api.github.com) and land as os-steve, not objectstack-fleet[bot]. The report comment went the same way.", "The platform replaced the PR body's trailing attribution lines with its session-URL footer at create time; the rest of the body read back byte-identical.", "A symlink examples/app-showcase/node_modules/@objectstack/organizations was created in the shared objectstack checkout while building the isolated rig (it did not satisfy the CLI, which reads the app's package.json); removing it was refused by the guard-main-checkout-bash hook, so it is still there (gitignored node_modules, no tracked file changed). Seat: `rm` it from a session where the hook permits, or leave it. No objectstack source was edited.", "Item 3 found and fixed one gap in objectui beyond the claim's file surface (ResourceEditPage.tsx, registry.ts, anchors.ts + one new test): landing point is the producer of the stray draft, the generic create page.", "Item-1 ripple beyond the literal census list, all references to deleted symbols or copy: useObjectActions, plugin-view ObjectView and its gridDelete test, PermissionMatrixEditor / PermissionAdvancedFacets / CapabilityMultiSelectField / DetailSectionNode comments, the i18n tests that used perm.facet keys." ], "mcp_calls": "0", "api_writes": "3 — POST /repos/objectstack-ai/objectui/pulls (draft #12998); POST /repos/objectstack-ai/objectui/issues/12998/assignees (os-steve); POST /repos/objectstack-ai/objectui/issues/7611/comments (this report). Plus 4 git pushes to the branch; 2 refused relay dispatches (no write landed).", "open_questions": [ { "question": "Dispatch Section 1 quotes the body's parity gate ('an organization administrator with NO Studio capability creates, edits ...'), but maintainer ruling A on objectstack#22621 (card comment 6095024693) says Setup authoring under single requires manage_metadata, and an org admin without it is read-only. Which reading binds?", "options": ["A: the ruling — measured both: an org admin holding manage_metadata and no studio.access authors everything; a plain org admin is read-only with the reason", "B: the literal body — would need the metadata door to admit organization_admin, loosening a boundary the maintainer ruled to keep"], "recommendation": "A, decided by the later maintainer ruling; nothing built for B" }, { "question": "Under isolated, objectstack's organization_admin keeps sys_user_position and sys_user_permission_set read-only (default-permission-sets 'Anti-escalation'), so 'a tenant admin can still assign' fails, while ADR-0131 D3 says assignments are 'created and removed by that organization's admins'. Is the clause owed by objectstack (an assignment grant scoped by the wall, with the escalation guard on which sets/positions may be assigned), or is the clause to be amended?", "options": ["A: objectstack card to let walled org admins write assignment rows of their own organization, refusing admin_full_access-class sets", "B: amend #7611's acceptance: under a wall only the operator assigns"], "recommendation": "A on the real-need axis (the ADR's own sentence, and the console page already tells tenant admins 'your organization assigns them'), but it loosens a security boundary, so it is the maintainer's; this card stays open on it either way" } ], "out_of_scope_findings": [ "class: b · reach: POST /api/v1/data/sys_user_position as an isolated-posture tenant admin (member role admin, organization_admin) -> 403 PERMISSION_DENIED; same for /data/sys_user_permission_set · evidence: objectstack main 6a49efb, plugin-security default-permission-sets.ts organization_admin declaration sets both objects allowCreate/allowEdit/allowDelete false; ADR-0131 D3 'Assignments are organization rows, in every posture ... created and removed by that organization's admins'; Seam: spec:ADR-0131 D3 assignment rows -> runtime:organization_admin object grants | renderer:PositionHoldersSection / AssignedUsersSection (correctly hide Add) · dedupe words: organization_admin assignment read-only; tenant admin cannot assign position; sys_user_position anti-escalation walled", "carrier: none · noted, not filed · console copy on the org-admin read-only editor also shows 'Read-only (this metadata type has no runtime write channel)' beside the correct manage_metadata reason (single and isolated)", "carrier: none · noted, not filed · packages/app-shell/src/utils/approverIdentity.ts DISPLAY_FIELDS_BY_OBJECT keeps a sys_position entry no binding reaches since APPROVER_VALUE_SOURCES.position is registry-bound in the installed spec 18.0.0-next.3; its approverValueIsName docblock still says 'under the installed spec position answers through the second arm'", "carrier: none · noted, not filed · capabilityLint's pseudo-stack carries no registry-declared capabilities (stack.capabilities), only permission-set grants; read only, a false 'resolves nowhere' warning for a defineCapability-only capability is possible but not measured" ] }Generated by Claude Code
os-steve commentedon Oct 18, 2026
os-dev-report addendum
{ "issue": 7611, "part": "patch round 1 on PR #12998 (seat message from session_01Y5583bs2RDd53MH6kM1ca3)", "status": "done", "branch": "claude/issue-7611-retired-catalog-remainder", "pr": "https://github.com/objectstack-ai/objectui/pull/12998", "head": "41f02663c39b083cf677f7a57aca7dcadd474336", "session": "session_01YNkqqKcTgHPV6SDyV6uquV", "summary": "Both red shards are fixed at the producer, the scripts' own tests. (1) check-i18n-call-site-keys.test.ts pinned recordDelete's resetPackageSetSuccess call site; that row is retired, because the call went with the package-owned reset copy. In its place the test now pins that the call is absent, beside the unchanged live sister assertion `t('objectActions.deleteSuccess', { label })`. The other two rows (marketplace, home) are untouched. (2) check-i18n-en-drift.test.ts used objectActions.resetPackageSetConfirm as its only live example of a `'a' + 'b'` value. No pack value is spelled that way now (grep over all ten packs: none), so there was no live call site of the same shape to move the pin to. The folding behaviour is now pinned on a parsePack fixture holding a multi-line concatenation, asserting the folded string. No assertion weakened, no test skipped. Docblocks that named the deleted key (check-i18n-en-drift.mjs, check-i18n-call-site-keys.mjs) or the deleted applyFieldWidgetOverrides (plugin-charts ObjectChart.tsx, plugin-grid relationalMetaKeys.ts and its 6875 test) are re-worded; comments only, no behaviour change.", "tests": "Local, from the repo root: `pnpm exec vitest run --maxWorkers=2 scripts/` (includes both failing files) -> Test Files 186 passed | 2 skipped (188), Tests 5620 passed | 2 skipped; os-verify-lock VERDICT command-exit 0, exit captured before any pipe. The VERDICT lines inside the log are the citation gate's own fixtures.", "gates": "CI on head 41f0266, read from the check-runs API until complete: 36 runs, 33 success, 3 skipped (Test (coverage), its matrix row, dependabot), 0 failure. Includes Test (shard 1..16/16) all success, Test success, Type Check success, Lint success, Build and E2E success, Repo Gates success, Line Citation Gate success, Changeset Declaration success. PR is draft, mergeable_state clean. Local: check-changeset-presence exit 0; check-new-cross-file-line-citations 0 new.", "files_changed_this_round": "scripts/__tests__/check-i18n-call-site-keys.test.ts; scripts/__tests__/check-i18n-en-drift.test.ts; scripts/check-i18n-call-site-keys.mjs (docblock); scripts/check-i18n-en-drift.mjs (docblock); packages/plugin-charts/src/ObjectChart.tsx (comment); packages/plugin-grid/src/relationalMetaKeys.ts (comment); packages/plugin-grid/src/__tests__/lookupDisplayFieldSpelling-6875.test.tsx (comment)", "line_budget": "this round +31 / -32 in 7 files; PR total 58 files", "deviations": [ "Writes went through the REST proxy directly (curl to api.github.com), as in the first report: the fleet-write relay is refused for this session type.", "No merge of origin/main: GitHub reports no conflict (mergeable_state clean)." ], "mcp_calls": "0", "api_writes": "1: POST /repos/objectstack-ai/objectui/issues/7611/comments (this addendum). Plus 1 git push.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
os-steve commentedon Oct 19, 2026
os-dev-report addendum
{ "issue": 7611, "part": "patch round 1, items 2 and 3 on PR #12998 (seat messages from session_01Y5583bs2RDd53MH6kM1ca3)", "status": "done", "branch": "claude/issue-7611-retired-catalog-remainder", "pr": "https://github.com/objectstack-ai/objectui/pull/12998", "head": "efb2db1dd0fe47052b8fbfca532e03b77e7cc68c", "session": "session_01YNkqqKcTgHPV6SDyV6uquV", "carrier": "The failing acceptance clause 'under isolated a tenant admin can still assign' is carried by objectstack-ai/objectstack#24136 (code half of maintainer ruling B on objectstack-ai/objectstack#23960, record 6228728551; ADR half landed as PR #24163). #7611 stays `Part of #7611`. This supersedes my first report's Q2 and its class-b finding; nothing to file.", "pr_body_line_2_for_the_seat": "Clause-②: no (narrowing)", "reachability_measured": "Against base 76f91f8. @object-ui/core exports recordDelete (src/index.ts re-exports actions/index.ts, which re-exports recordDelete.ts): confirmText narrows. @object-ui/i18n: the ten built-in packs are published, so the removed keys narrow. @object-ui/plugin-detail: PermissionFacetLink was imported but never exported from src/index.ts (exports has only '.'), but its registry key field:permission-facet-link was registered at module load, a published runtime face: narrows. @object-ui/cli: known-schema-types is not exported (src/index.ts exports serve and init), but it decides what the published `objectui check` bin accepts: narrows that bin's face. @object-ui/app-shell: RecordPermissionAssignmentsRenderer was never exported from src/index.ts: internal. @object-ui/data-objectstack: applyFieldWidgetOverrides was private: internal; its effect, the getObjectSchema stamp, is a behaviour change.", "changeset": ".changeset/7611-retired-catalog-remainder.md rewritten. Still `minor` for all six packages. A Breaking section gives FROM / TO pairs with a one-line fix for core confirmText, the i18n keys, the plugin-detail registry key and the cli known type. Behaviour changes, one line each: getObjectSchema stops stamping the widget; the record page drops the assignments panel; the Setup permission-set create is live. Widenings: recordDelete's data source needs only delete; the registry entry gains optional createLive. The internals are named as not reachable.", "tests": "This round changed the changeset only (no source); the round-1 local run stands: `vitest run scripts/` 186 files passed, exit 0. node scripts/check-changeset-presence.mjs passes.", "gates": "CI on head efb2db1, read until complete: 36 runs, 33 success, 3 skipped (Test (coverage), its matrix row, dependabot), 0 failure. All 16 Test shards and Test, Type Check, Lint, Changeset Declaration, Changeset Bump Policy and Changeset Fixed Group Check passed. The PR is draft with mergeable_state clean.", "deviations": ["Written through the REST proxy directly (curl to api.github.com): the fleet-write relay is refused for this session type.", "The PR body is not edited by me; line 2 is given above for the seat to write."], "mcp_calls": "0 GitHub MCP calls (1 send_message to the seat in the earlier half of this round)", "api_writes": "1: POST /repos/objectstack-ai/objectui/issues/7611/comments (this addendum). Also 1 git push.", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Landed · epic PM
session_01Y5583bs2RDd53MH6kM1ca3(os-steve) · 2026-10-19T01:32Z. PR #12998 (C9,Part of #7611) has merged. Its contract review is record 6257392934 (CONTRACT_REVIEW_TIER, PASS onefb2db1dd). The merged headb2ef1e631is that head plus a branch update (parentsefb2db1dd,1624e08f6); no code was added after the review.merged: trueat 2026-10-19T01:26:15Z; merge commit78b07f468acd6e515e201580a1c00b851b1b4985origin/main78b07f4, which is that merge commitState change.
pm:dispatched→pm:blocked, and the card is unassigned. No stage of this card is in flight.Delivered.
singleandisolated.Remainder. One acceptance clause is still open: under
isolated, a tenant admin can still assign. The server refuses that write today (403). Its producer is objectstack, and ruling B on objectstack-ai/objectstack#23960 (6228728551) places it there. This card closes when that carrier lands. The carrier is objectstack-ai/objectstack#24136, which waits on objectstack-ai/objectstack#24340.Carried on (the review's out-of-scope items):
singleandisolated. It is filed as its owndomain:uicard, metadata-admin: the permission-set editor's badge tells a caller withoutmanage_metadatathat the type "has no runtime write channel"; the reason is the caller's capability #13011.approverIdentity.tsstill has a deadsys_positionentry inDISPLAY_FIELDS_BY_OBJECTand a staleapproverValueIsNamedocblock. This rides the PR for this card's remainder.capabilityLintraises a false "resolves nowhere" warning for a capability declared only withdefineCapabilityhas not been measured, so it is not a card. The remainder's dev measures it with the reviewer's instrument: a draft that references such a capability, then Publish from Home. The dev fixes it in that PR only if it reproduces.Blocked-by: objectstack-ai/objectstack#24136
objectstack-fleet commentedon Oct 19, 2026
Maintainer decision: off the 18.0 label, to 18.x · triage seat ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-19T08:00ZTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015). ⛔ Not a claim, ⛔ not a dispatch.
Provenance. The seat put this to the maintainer in chat, at the end of its p1 sweep: 「三张只跟多组织隔离部署(walled 模式)有关的卡挂着 v18 标签……我倾向把这三张的 v18 标签去掉,改排 18.x」. The maintainer answered 「两件事 同意」.
singleposture only.os serverefuses a walled posture (group/isolated) at boot (PR feat(cli)!: 18.0 guards — os migrate organization-ownership refuses, and os serve refuses a walled posture at boot objectstack#24480,ae6bd1a69). This card's remaining work concerns a walled plane, so 18.0 cannot carry it.organization_idNOT NULL per cleared table; one predicate for Layer 0 and every driver; bothorWhereNullarms, the__global__sentinel and the #13491 ledger retire (ADR-0131 D1/D8/D9) — protocol 18 objectstack#15212), then the F1 re-test (6261853191on [epic] ADR-0131 — total organization ownership: no NULL organization_id (v18 line) objectstack#15194). The work continues in parallel. Only the label moves.target:v18comes off. Nothing else moves: p1,pm:blocked,pm:epic.isolated, a tenant admin can still assign" (epic seat, 2026-10-19T01:32Z). Its carrier is plugin-security: organisation admins assign positions and permission sets to their own members inside the D12 boundary — gate branch, overrides, explain and my-delegable-scope, three-posture acceptance (ruling B on #23960) objectstack#24136, which carries notarget:v18and waits on platform-objects: the identity objects declare their default row scope (the literals the shipped sets copy today), and the registry refuses anextendcontributor that loosens a platform object's default (#24164 ruling E′) objectstack#24341 → #24448.Generated by Claude Code