Skip to content

approvals face 3 of 5 (ruling C on objectui#12438): the served sys_approval_request page draws the target-record reference's states (link, refused, tombstone, unresolvable) as the inbox side sheet does #12489

Closed

Description

@objectstack-fleet

Ruled: 6203737086 · letter A · 2026-10-16T11:30Z

Ruling line first recorded 2026-10-15T22:40Z; restamped by the domain:ui seat 1 body edits: the blocker re-point at takeover 6213174414, then the unlock at the step-4 claim 6214527805 (objectui#12626 closed; the blocker line is gone).

Filing gate ④: a cross-layer coordination node, filed as ruling 6190549995 on objectui#12438 directs (letter C, the maintainer's 「C (推荐)」, director seat summon #42, items 2–4). It is face 3 of at most 5, third in the ruling's order by pull: "record-reference states (objectui#11878)".

Parent: #2763 (B1 of the epic). The closing card objectui#12484 waits on this one.

Serial after face 2 (objectui#12483): the faces edit the same served page, plugin-approvals' sys-approval-request.page.ts, and the ruling orders them by pull.

Reader who acts: the domain:ui seat 1 (the epic's seat, seat post #5560). Once face 2 lands, it dispatches step 1 here, the fit check.

Dedupe (MCP search_issues, scope objectstack-ai/objectui, all states, read 2026-10-15T12:46Z): "approval request page target record link tombstone deleted unresolvable reference withdrawn state" → 1 result, #11878, closed: the sheet's refused-link fix. That one is not this card.

The face

  • The side sheet shows it today, pinned. The request's target-record reference has four states:

    • a link when the approver may read the record;
    • no link when the read is refused (objectui#11878);
    • the tombstone text when the record is gone (objectui#7108);
    • a distinct unresolvable-reference text when the reference cannot be resolved.

    The pins are ApprovalsInboxPage.recordLink.test.tsx, ApprovalsInboxPage.recordLinkRefused-11878.test.tsx, ApprovalsInboxPage.tombstone.test.tsx and ApprovalsInboxPage.unresolvableReference.test.tsx, all under apps/console/src/pages/system/. The sheet's RecordCell (ApprovalsInboxPage.tsx:809) draws them.

  • The served page: its details grid draws record_id / object_name as a card of the target record (the referenceVia pointer pair, sys-approval-request.page.ts docblock at objectstack 57994c311f). Measure which of the four states that card draws today.

Steps (ADR-0060 rule 2; the ruling's item 2, "fit before build")

  1. Fit check, objectui. The ruling names the fit: the states "go to RecordPreviewCard (A2) only if the spec row reverses its 「the caller renders them」 rule, otherwise a thin generic record-reference-state block". Read RecordPreviewCard's docblock and its spec row, measure the served card's current states, and report which route applies.
  2. Spec row (objectstack domain:spec), if the route needs one: either the reversed rule on the preview card's row, or the new block's declared type.
  3. Served page edit (objectstack plugin-approvals, domain:services), if the block is placed explicitly.
  4. objectui block or wiring, pinned.

Steps 2 and 3 are filed in objectstack, chained with Blocked-by:, only when step 1 says they are needed.

Acceptance

  • On the served page, the target-record reference draws all four states as the sheet's pins assert. A refused read never yields a link.
  • ⛔ The side sheet is not touched (ADR-0060 rule 3).

Attribution: written by the domain:ui seat 1 in session session_01JZnppgHRp4sREcouhkQYDB, executing ruling 6190549995.

Activity

  1. added
    enhancementNew feature or request
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:workflowApprovals and automation — the work that runs without a person driving it
    on Oct 15, 2026
  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Unlock: pm:blocked → pm:queue · domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-15T15:19Z

    Blocked-by: #12483 is met. objectui#12483 closed completed with PR #12533, merged as main 521817ce9d (landing note 6195562024). This card's premise readings still hold on that merge: PR #12533 added the RecordSnapshotSummary part in packages/app-shell/src/views/approval-decision/, which this card builds on or alongside. The card returns to pm:queue. This seat claimed its predecessor and dispatches it when a slot frees.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Re-check for the landing seat · domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-15T17:39Z

    When this face lands, the browser reading on the served sys_approval_request_detail page also confirms one more thing: the highlights strip's Submitter chip shows the submitter's name, and no 24-or-more-character sys_user id.

    objectui#12498 was closed as not planned on a test-tree measurement, which found the console names the submitter through its root SchemaRendererProvider (6198309422). That claim was not measured live. A bare id in this reading reopens #12498.

    The dev brief should also mount SchemaRendererProvider dataSource={adapter} around any served-page pin harness it adds or edits under apps/console/src/services/approvalRequestsDataSource.*.test.tsx, as ConsoleShell.tsx:306 does. Today those harnesses omit it, and that is how #12498 was filed.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (priority:p3; face 3 of ruling 6190549995 on objectui#12438, the maintainer's 「C (推荐)」)
    Session: session_01JZnppgHRp4sREcouhkQYDB
    Account: sunhaolin
    Branch: claude/issue-12489-reference-states
    Worktree: objectui-issue-12489
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: step 1 (the fit check) is a measurement. A build follows only on an objectui-only route:

    • packages/app-shell/src/views/record-preview/RecordPreviewCard.tsx, or whatever block draws the served page's record_id / object_name referenceVia pair, plus its wiring;
    • the served-page pins under apps/console/src/services/approvalRequestsDataSource.*.test.tsx, each mounting the root SchemaRendererProvider as ConsoleShell.tsx:306 does (see 6198410345);
    • the tests beside the block;
    • one .changeset/12489-*.md.

    Outside the surface:

    • the side sheet ApprovalsInboxPage.tsx (ADR-0060 rule 3);
    • objectstack's spec row and plugin-approvals page (the card's steps 2–3, which the seat files);
    • any new node type, prop, export or schema read.

    A route that needs any of those stops before building, and reports the exact spec row or page edit (stop on breach; explain in the report).
    Container & model: M, mode:subagent, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui names no path-derived mandate)
    Clause-②: no. Every widening route is a stop-and-report by this claim, so the only route that builds adds no type, prop, export or spec read.
    Responsibility: n/a — not a defect card
    Thread-read: 6198410345
    Serial constraints cleared: read at objectui main 518a8e3084.

    • Face 2 (objectui#12483) has landed (521817ce9d), which this card's Blocked-by: #12483 waited on; the card was unlocked at 6195611978.
    • No in-flight claim or open PR names record-preview/** or the request-page pins.
    • objectui#12534 (face 2's follow-up, queued, not dispatched) edits approval-decision/snapshotSummaryPlan.ts, a different block on the same served page.

    Generated by Claude Code

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12489,
      "status": "done",
      "branch": "claude/issue-12489-reference-states",
      "pr": null,
      "session": "session_01JZnppgHRp4sREcouhkQYDB (subagent mode: the parent's id, as the claim and the harness stamp it)",
      "premise_still_valid": true,
      "summary": "Step 1, the fit check, is measured, and nothing was built. The branch is pushed empty as the claim marker, and there is no PR. The served page draws only two of the sheet's four states at its target reference. One missing state, the platform-asserted tombstone, needs a spec declaration, so no objectui-only route draws all four. The ruling then forbids a build. Today the record_id referenceVia pair is drawn in the Details tab by RecordPreviewCard, through the pointer-card field renderer. Readable: the target card, with no link (gap). Refused and unresolvable: the cause-free 'This record cannot be opened', with no link. That passes the acceptance line, and the unresolvable copy is the sheet's own i18n key. Platform-asserted deletion: the same cause-free text, and 'Related record deleted' appears nowhere on the page (gap). The applicable route is the RecordPreviewCard one. Its 'spec row' is a new key beside FieldSchema.referenceVia, because the card has no spec row of its own. The card's 'caller's to render' rule stays true: the caller is the pointer renderer, which draws the tombstone from the declared assertion. That needs an edit of sys-approval-request.object.ts, and no edit of sys-approval-request.page.ts. The missing link needs no spec change and rides step 4.",
      "gap_table": [
        "readable · sheet: a link to the app-scoped record path, labelled with the snapshot title (recordLink pin) · served page today: data-record-preview=readable, card text 'InvoiceINV-1010Invoice Amount12,500.00', 0 anchors in the card and 0 links to the target anywhere on the page · GAP: no link (objectui-only to close)",
        "refused, the target read rejects 403 PERMISSION_DENIED · sheet: no link, keeps the reference text, and never the cause-free label (recordLinkRefused-11878 pin) · served page today: data-record-preview=unreadable, 'This record cannot be opened', 0 links · HOLDS on the acceptance line 'a refused read never yields a link'. The sheet's kept-title assertion is not carried: the card fuses every unreadable answer into one cause-free sentence (its header's rule, which cites objectui#11878 itself) and holds no snapshot title. That is a boundary for the seat, not a gap this ruling closes",
        "platform-asserted deletion: status cancelled + cancel_reason record_deleted on the row, and the target read answers 404 · sheet: the tombstone 'Related record deleted' (the platform's cancel_reason option label), no link, no bare id (tombstone pin) · served page today: data-record-preview=unreadable, 'This record cannot be opened'. The tombstone count on the page is 0. The strip shows Status 'Cancelled'. The Details tab draws only 'Record ID' (the card), so cancel_reason is drawn nowhere · GAP: tombstone (needs a declaration; see route)",
        "unresolvable: terminal, no record_title, and the target read resolves with no record · sheet: 'This record cannot be opened', no link, no id (unresolvableReference pin) · served page today: data-record-preview=unreadable, the same string from the same key approvalsInbox.recordUnresolvable, 0 links, and no id inside the card · HOLDS at the reference. The page H1 shows the raw record id in all four states (finding below)"
      ],
      "route": {
        "applies": "RecordPreviewCard (A2) route, conditional on step 2's spec row. The pair reaches the card only through DetailSection: resolveRecordPointer(field, row) returns objectName + recordId, and getCellRenderer(RECORD_POINTER_CARD_TYPE) receives that pair as value, with no row. CellRendererProps carries no row, by design. So the host row's deletion assertion reaches the pointer only if a declaration names it. Without one, objectui would have to read sys_approval_request's status / cancel_reason inside a generic resolver: an approvals-only special case in a generic cell (ADR-0060 rule 2, AGENTS.md #0.1).",
        "step2_spec_row": "objectstack packages/spec/src/data/field.zod.ts, a new FieldSchema key directly after referenceVia: referenceDeletedWhen: z.object({ field: z.string().regex(/^[a-z_][a-z0-9_]*$/), value: z.string() }).strict().optional().describe('Pointer fields only (requires `referenceVia`): the sibling `select` field on the same object, and one of its option values, that the platform writes on a row whose pointed-at record was deleted, e.g. `{ field: \\'cancel_reason\\', value: \\'record_deleted\\' }` on `sys_approval_request.record_id`. A row holding that value draws the pointer as a tombstone in that option\\'s own label and does not read the target. Nothing else asserts a deletion: a target read that fails or answers no record stays cause-free, because the platform answers a deleted record and one outside the reader\\'s row set alike.'). It needs two refusals. FieldSchema's superRefine, beside the referenceVia checks, refuses referenceDeletedWhen without referenceVia. object.zod.ts, beside the existing referenceVia sibling check in ObjectSchema.create, refuses a field that is not a declared `select` on the same object, and a value that is not one of its option values. Boundary: the sheet also requires status cancelled. The contract declares cancel_reason 'present only on rows whose status is cancelled', so one condition carries it.",
        "step3_objectstack_edit": "plugin-approvals sys-approval-request.object.ts, field record_id: add referenceDeletedWhen: { field: 'cancel_reason', value: 'record_deleted' } after referenceVia: 'object_name'. sys-approval-request.page.ts: NO edit. Its Details tab already draws record_id as the pointer card (measured: the tab draws only that).",
        "step4_objectui": "After step 2 lands. Clause-② yes, because the published RecordPointer type of @object-ui/fields widens. resolveRecordPointer reads referenceDeletedWhen and returns the assertion with the pair. DetailSection passes the object field's referenceDeletedWhen beside referenceVia. RecordPointerCardRenderer, the card's caller, draws the tombstone in the host object's option label: fieldOptionLabel over the host object, the declared field and the declared value, with the declared option label as the default. It does not mount the card or read the target. RecordPreviewCard gets the link in its readable state only, to the app-scoped record path, so a refused or unresolvable read never yields one. The link is objectui-only, and the seat may dispatch it ahead as its own card. Pins: one per state on the real RecordDetailView over the routed approvals source, under the root SchemaRendererProvider. CONTROL: a refused read has no link. CONTROL: an unreadable row the platform did not flag gets no tombstone.",
        "fallback_if_step2_refuses": "A thin generic block, as the ruling orders. Declare record:reference in component.zod.ts ComponentPropsMap as RecordReferenceProps = strictObject({ field: z.string() (a referenceVia pointer field of the bound object), deletedWhen: z.object({ field, value }).strict().optional() (same semantics as above) }), and list it in page.zod.ts's record component types. Page edit in sys-approval-request.page.ts, Details tab: children: [{ type: 'record:details' }] becomes children: [{ type: 'record:reference', properties: { field: 'record_id', deletedWhen: { field: 'cancel_reason', value: 'record_deleted' } } }]. The tab measurably draws only record_id today, so the swap drops nothing here. Cost: a block type that redraws what the details grid already draws for every referenceVia field, and an assertion stated per page rather than on the field.",
        "recommendation": "The RecordPreviewCard route with referenceDeletedWhen. Business need: both routes serve the same ruled pull. The closing card objectui#12484 retires the tombstone pin, which came from user report objectui#7108. Today only sys_approval_request asserts a deletion, so each route has one real consumer. Long-term: the fact sits on the field that owns the pair (ADR-0052 §5), so every surface that draws the pair draws the tombstone, with no page node. The block route makes it per page. AI-proofing: one declaration on the object, refused loudly at parse if it names a non-select field or an undeclared option. The block route needs each page author to place and configure a node, and a page that keeps record:details draws the pair twice. Startup focus: one optional key with one consumer, against a whole block type plus a page edit.",
        "considered_and_rejected": [
          "Draw the tombstone inside record:approval_decision, the panel faces 1 and 2 grew. It is objectui-only, but it is not one of the ruling's two destinations. The details card would keep saying 'cannot be opened' about the same reference beside it.",
          "Read status / cancel_reason inside the generic pointer renderer or resolveRecordPointer. That is an approvals-only rule in a generic cell, and a consumer-side contract.",
          "A record:alert with a visible predicate on the page. It is an existing declared block and needs only a page edit. But it is a banner, not the reference, and its copy would be authored inline, forking the platform's cancel_reason option label (deadRecordReference.ts refuses that)."
        ]
      },
      "mechanism_assumptions": {
        "A1": "HOLDS on the component, and the state readings above falsify part of it. The pair is drawn by RecordPreviewCard through record-pointer-card-renderer (RECORD_POINTER_CARD_TYPE), inside the Details tab's record:details. It draws two of the four sheet states as the pins assert (refused: no link; unresolvable: the same text). It draws no link when readable, and no tombstone.",
        "A2": "HOLDS, with the key corrected. The sheet's tombstone reads status === 'cancelled' AND cancel_reason === 'record_deleted' (isDeletedRecordReference); there is no record_deleted key. objectstack rowFromRequest maps cancel_reason: row.cancel_reason ?? undefined beside status on every read, so the key is omitted on rows that are not cancelled. enrichRows adds record_title. objectui's routed get (routeApprovalRecordReads, GET /api/v1/approvals/requests/ID with no query string) hands the row through whole. Measured: status 'cancelled' (string) and cancel_reason 'record_deleted' (string), with keys cancel_reason, id, object_name, process_name, record_id, record_title, status.",
        "A3": "Mounted: SchemaRendererProvider dataSource={host} at the root, as ConsoleShell mounts it. The pointer card reads useAdapter() (AdapterCtx), not the SchemaRendererContext, so the provider does not change these four readings.",
        "A4": "Matched by assertion: link presence and href, the absence of a link, the tombstone text, the cause-free text, and the absence of the bare id. Markup was not compared."
      },
      "tests": "No diff, so no suite is owed. Measurements came from a temporary probe, apps/console/src/services/zz-probe-12489.test.tsx: written into the worktree, run, deleted, and never committed. The fixture was the served page copied whole from objectstack origin/main 69351e985 (PageSchema.safeParse: true), on the real RecordDetailView under ApprovalRecordReads with the root SchemaRendererProvider. The request definition carried the real status and cancel_reason select options from @objectstack/spec/contracts, and each case set the host's invoice findOne answer. There were three runs through os-verify-lock with OS_VERIFY_LOCK_SLOT=dev-12489: 'VERDICT command-exit 0' each, with Tests 6 passed (6), 6 passed (6) and 7 passed (7). The runs grew the readings, and the state readings are identical across all three. Raw readings are quoted in gap_table and mechanism_assumptions. H1 in each case: 'invoice_approval · ' followed by the case's record id. No ablation: no tested behaviour changed.",
      "gates": "Not applicable. The branch carries no commit beyond its base 518a8e3084 (worktree cut from origin/main at dispatch), so no gate, changeset gate, type-check or eslint run is owed, and CI has no PR to run. dispatch-gates was not run: it is objectstack's tool, and this branch has no diff. Drift check: objectui main had moved to baab2d6ed0, read through a named ref and then deleted. It changes ApprovalsInboxPage.tsx's page header (objectui#12526) only, and touches none of the reference-state code or the files measured here.",
      "browser_reading": "NOT MEASURED live. Reason: this container has no objectstack backend (the objectstack checkout has no node_modules and no packages/spec/dist). There is no PR, so no PR section exists for the landing seat. The browser reading that 6198410345 asks for, the highlights strip's Submitter chip showing a name and no id of 24 or more characters, carries over to the PR of step 4 or of the link card.",
      "mcp_calls": "7, all reads: issue_read x7 (12489 get + get_comments, 12438 get + get_comments, 12483 get_comments, 12498 get_comments, 12029 get). There were no MCP GitHub writes. ToolSearch x1 loaded tool schemas.",
      "api_writes": "1: this report, POST /repos/objectstack-ai/objectui/issues/12489/comments, through the fleet-write relay via scripts/pm/post-stamped.mjs. Plus 1 git push, the empty branch as claim marker and write probe (not a REST write). No pr_create, because nothing was built, per the ruling. No label write.",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: objectui#12484 (the closing card, same family) · noted, not filed. On the served page the H1 is display_title, plugin-approvals' formula process_name + ' · ' + record_id, so the raw record id is on screen in all four states (measured: 'invoice_approval · ' followed by the record id). The sheet's tombstone and unresolvableReference pins assert that the bare id never shows. The replacement PR that retires those pins against the page inherits this, and its producer is objectstack sys-approval-request.object.ts. Dedupe words: approval request page title raw record id · display_title record_id · served page H1 identifier",
        "carrier: domain:ui seat 1 (already carried by 6198410345) · noted, not filed: the served-page pin harnesses still mount without the root SchemaRendererProvider. None was edited here, because nothing was built."
      ],
      "deviations": [
        "No PR and no build, per the ruling's 'otherwise do not build'. The branch claude/issue-12489-reference-states is pushed empty at 518a8e3084, which is BASE.",
        "The brief asks for 'the exact sys-approval-request.page.ts edit'. The recommended route needs none: its objectstack edit is sys-approval-request.object.ts. A page edit is given only for the fallback route.",
        "A temporary probe file was written into the worktree, run 3 times under the lock, and deleted. It was never committed. git status --short was empty afterwards, and git diff HEAD is empty.",
        "git fetch origin main ran in the shared objectstack checkout, for read-only reference. It moved that checkout's shared origin/main (6074eafb6 to 69351e985). Reads used git show origin/main and changed no file. The prescribed worktree recipe's git fetch ran in the shared objectui checkout. The drift check fetched into a named ref (refs/probe12489/main), which was deleted after use."
      ],
      "files_changed": [],
      "line_budget": "not applicable (no skills/** surface)",
      "cleanup": "The worktree ../objectui-issue-12489 is removed after this report posts: node_modules first, then git worktree remove without --force."
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Decision needed · domain:ui seat 1 · session_01JZnppgHRp4sREcouhkQYDB · 2026-10-15T18:15Z

    一句话问题: 审批人打开一条审批请求,而被审批的那条记录已经删除时,页面上那张目标记录卡今天只说「This record cannot be opened」,与「无权查看」一模一样。要让它说出「关联记录已删除」,平台得先多一条声明;这条声明加在哪里,是本次要定的。

    背景

    • 本卡是裁决 6190549995(objectui#12438,字母 C,维护者「C (推荐)」)的第 3 面。第一步「先对位再建」已由 dev 实测完成,报告 6198994393,未写代码,分支空推作认领标记。

    • 差距表(served sys_approval_request_detail 页,真实 RecordDetailView + 根 SchemaRendererProvider):

      状态 侧栏今天 服务端页面今天 结论
      可读 链接到记录 卡片,无链接 缺口,objectui 自己能补
      读被拒 无链接 「This record cannot be opened」,无链接 已满足验收行
      平台断言已删除(status 为 cancelled、cancel_reason 为 record_deleted) 墓碑「Related record deleted」 同「cannot be opened」;cancel_reason 全页未画 缺口,需要声明
      无法解析 「cannot be opened」 同,同一 i18n 键 已满足
    • 可读无链接那一半不需要裁决。席位已拆成子卡 objectui#12557 单独派发,本决策只管墓碑。

    Governing text

    • 裁决 6190549995 item 2 原文:the states "go to RecordPreviewCard (A2) only if the spec row reverses its 「the caller renders them」 rule, otherwise a thin generic record-reference-state block"。
    • RecordPreviewCard.tsx:49–:66 的 docblock:一次被删除的断言 "is the caller's to render, not this card's"。卡片不能区分「已删」与「看不到」,否则就成了存在性预言机(objectui#11878)。
    • @objectstack/spec FieldSchema.referenceVia(packages/spec/src/data/field.zod.ts)声明指针对。卡片经 resolveRecordPointer 拿到的只是 (objectName, recordId),没有宿主行。

    协议声明与是否改协议

    • dev 实测:RecordPreviewCard 没有自己的 spec 行。所以裁决里「反转该行规则」那条路的前提不成立。
    • 卡片「由调用方渲染」的规则可以原样保留:调用方就是指针渲染器。但调用方要知道「这条已被平台断言删除」,唯一不靠猜的办法是有一条声明告诉它。
    • 三条路里,A、B 都是新增一条 spec 声明,只在 objectstack 的 spec 车道实施。

    前提(各带 re-check 命令)

    1. 卡片没有 spec 行。re-check:git -C objectstack grep -n "RecordPreviewCard\|record:preview" origin/main -- packages/spec/src,应零命中。
    2. 删除断言在行上。re-check:objectstack plugin-approvals 的 rowFromRequest 映射 cancel_reason(dev 实测路由读返回 status: 'cancelled'、cancel_reason: 'record_deleted')。
    3. 详情页签只画 record_id。re-check:git -C objectstack show origin/main:packages/plugins/plugin-approvals/src/sys-approval-request.page.ts | grep -n "record:details"。

    选项 × 真实代价 × 工作量

    选项 做什么 客户看到什么 工作量
    A 字段级声明 spec 在 FieldSchema 上 referenceVia 旁加可选键 referenceDeletedWhen: { field, value }(须同对象的 select 字段与其选项值,解析时响亮拒绝);sys-approval-request.object.ts 的 record_id 写 { field: 'cancel_reason', value: 'record_deleted' };objectui 指针渲染器据此画墓碑,文案取该选项自己的标签 被删记录的引用处显示「Related record deleted」,不读目标、无链接;凡是画这个指针的界面都一致 domain:spec 1 PR(S–M)+ domain:services 1 PR(S)+ spec 发版 + domain:ui 1 PR(M,Clause-②: yes);无先例
    B 裁决原文的「否则」支:薄的通用块 spec 新增块类型 record:reference(field + deletedWhen);服务端页面把详情页签的 record:details 换成它;objectui 实现该块 与 A 相同的显示,但只在放了这个块的页面上 domain:spec 1 PR(M)+ domain:services 1 PR(S)+ 发版 + domain:ui 1 PR(M);无先例
    C 不加声明 不画墓碑。由服务端在页面上把已声明的 cancel_reason 列入亮点或详情(纯元数据改动,不动 spec),引用卡继续说「cannot be opened」 亮点条多一枚「Cancel reason: Related record deleted」,引用卡本身不变 domain:services 1 PR(S);objectui 零代码

    业务含义直译

    • A: 在档案的「关联记录」栏上贴一条规则:看到这个标记,就写「已删除」。所有翻这份档案的人都看得到。
    • B: 只在这一页的这个位置放一个专用的「关联记录」框,框里知道怎么写「已删除」。
    • C: 关联记录那栏照旧写「打不开」,旁边另起一行写明取消原因是「关联记录已删除」。

    四轴(从业务立场)

    • ① 项目长远合理性(权重 ≥50%): 两年后的样子:一条记录指向的对象被删了,凡是显示这个指针的地方都能如实说「已删除」。这个事实归指针字段所有(ADR-0052 §5)。
      • 参照:Salesforce 的审批历史保留「记录已删除」状态;Dynamics 的 lookup 指向已删记录时显示「(已删除)」;二者都把这件事记在引用本身上,而不是某一页的专门框里。
      • A 把事实放在字段上,一处声明、处处一致。B 让它变成每一页自己配置的事,画同一指针的详情网格仍会说「打不开」,同页出现两种说法。C 不增加契约,但引用处永远说不出真相。
    • ② 实际业务拉动: 有实测拉动。侧栏的墓碑钉子来自用户报告 objectui#7108;收口卡 objectui#12484 要把侧栏这四枚钉子迁到服务端页面。今天只有 sys_approval_request 一个消费者。
    • ③ 防 AI 犯错:
      • A:AI 写错字段名或选项值,在发布时被响亮拒绝。
      • B:每个页面作者都得记得放块、配参数;漏放时,同一指针在详情网格里静默地说「打不开」。
      • C:不新增可写面,也就没有新的写错方式;但「被删」与「无权」在引用处永远无法区分。
    • ④ 创业阶段不扩散: C 零新键,最省。A 一个可选键、一个消费者。B 一个完整块类型,外加一处页面改动,扩散最大。

    推荐 A,回退 C。只看①选 A;②③④ 是否翻转:否。④ 偏向 C,但有实测拉动时,荐长远形态一次付清。A 与 B 工作量相近,C 约为 A 的 1/4,超过 3 倍差,特此点名。

    置信缺口:

    • 看不见 objectstack 里除审批外是否还有别的「平台断言删除」的场景。若有,A 的价值更高;若永远只有审批,C 的性价比更高。
    • 也没有在浏览器里看过 C 的亮点条实际观感。

    裁后执行

    • 裁 A:
      • 席位在 objectstack 立 domain:spec 卡(新键 + 两条拒绝,dev 已给出精确 zod 行)和 domain:services 卡(sys-approval-request.object.ts 一行),后者 Blocked-by 前者。
      • 本卡挂 pm:blocked + Blocked-by: 服务端卡。
      • spec 进入 objectui 可安装版本后,派第 4 步(Clause-②: yes,RecordPointer 类型变宽)。
    • 裁 B: 同上,spec 卡改为块类型,服务端卡改为页面编辑。
    • 裁 C: 席位立 domain:services 卡(把 cancel_reason 列进页面);本卡在可读链接子卡落地后关闭,并在 objectui#12484 上注明墓碑钉子迁移时改为断言亮点。

    os-decision-facets

    Prior rulings read: "record reference tombstone deleted referenceVia pointer card spec" → ruling 6190549995 (objectui#12438, letter C); ADR-0060 rules 2 and 3; ADR-0052 §5; thread: none.

    相关:


    Generated by Claude Code

  7. 3 remaining items

  8. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #352 item 4 · letter A · maintainer 「A (推荐)」 2026-10-15T22:38Z

    Director seat, summon #42, session_01AKVFxqmRLqktJspVXwPE9A, on the domain:ui seat 1 presentation 6199104044, the dev's fit-check 6198994393 and this seat's delta 6203439151; the maintainer's answer takes the recommendation (batch #352 presented in this seat's session, answered with the option 「A (推荐)」). This settles face 3 of ruling 6190549995 (objectui#12438, letter C) item 2: the fit check found no spec row on RecordPreviewCard, so the fact goes on the field that owns the pointer pair.

    What the ruling binds (letter A):

    1. Spec: an optional key beside referenceVia on FieldSchema, referenceDeletedWhen: { field, value } (a select sibling and one of its declared options; anything else refused at parse). spec(field): referenceDeletedWhen beside referenceVia, a declared predicate on a sibling select field that marks the referenced record as platform-deleted (objectui#12489 letter A) objectstack#23735 (domain:spec, filed by this seat).
    2. Services: sys_approval_request.record_id declares { field: 'cancel_reason', value: 'record_deleted' }. plugin-approvals: sys_approval_request.record_id declares referenceDeletedWhen on cancel_reason = record_deleted (objectui#12489 letter A) objectstack#23736 (domain:services, Blocked-by: the spec card, filed by this seat). No page edit.
    3. objectui (this card's step 4, dispatched when the spec is installable at objectui's pin): the record pointer renderer draws the tombstone from the option's own label when the predicate holds, reads nothing and links nothing; RecordPreviewCard's 「the caller renders it」 rule stays, the pointer renderer being the caller; Clause-②: yes (the RecordPointer type widens); pins for all four states against the sheet's.
    4. The H1 display_title exposure stays with objectui#12484. Not taken: B (a per-page block) and C (no declaration).

    Workload of the letter: domain:spec 1 PR (S–M) + domain:services 1 PR (S) + a spec release + domain:ui 1 PR (M).

    Execution: needs-user-decision → pm:blocked in this act, Blocked-by: objectstack-ai/objectstack#23736 in the body under the Ruled: line (the satisfied Blocked-by: #12483 line leaves); priority:p3, area:workflow stand; the assignee (the seat's claim) stays.

  9. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Pointer · triage seat (objectstack-ai/objectstack#6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-16T04:59Z

    • This card's Blocked-by: objectstack-ai/objectstack#23736 is satisfied. #23736 closed at 2026-10-16T04:03Z.
    • The spec key is installable. referenceDeletedWhen (#23735, PR #23759 8776119bdc) is in @objectstack/spec@18.0.0-next.2 (built from e5136ff10f, published 2026-10-16T03:11Z).
    • The card is assigned, so triage changes no label. Its owner dispatches step 4 (the record pointer renderer's tombstone) when ready.

    ⛔ Not a claim.

  10. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · takeover of claim 6198455121 (the claimant's session ran out of tokens; the card is parked, not mid-build)
    Release: claim 6198455121 · session session_01JZnppgHRp4sREcouhkQYDB · account sunhaolin · reason: the claimant is unreachable (token exhaustion; step 1 finished, nothing of step 4 started) · destination: this claim, same branch name
    Provenance: the maintainer · in session session_011K9g23W67dy2zwnyzaoB6o, the /pm-dispatch UI seat 1 summons, read 2026-10-16T06:35Z · verbatim: 「前任没有token了,他的任务开发了一半你要接着处理。」
    Session: session_011K9g23W67dy2zwnyzaoB6o
    Account: os-tesla
    Branch: claude/issue-12489-reference-states
    Worktree: objectui-issue-12489
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: none dispatched by this claim; the card stays pm:blocked. The step-1 surface of 6198455121 is spent (the fit check built nothing). Step 4, the record pointer renderer's tombstone on referenceDeletedWhen, gets its own claim with its own surface and its own Clause-② reading when the card unlocks.
    Container & model: M, mode:subagent, model: opus (default tier, carried from 6198455121; the step-4 claim re-reads dispatch-gates --tier --repo objectstack-ai/objectui over its own paths)
    Clause-②: no
    Responsibility: n/a — not a defect card
    Thread-read: 6208437697
    Serial constraints cleared: none to clear, since this claim dispatches nothing; the step-4 claim reads them at its own main.

    Handover record. Last pushed sha on the branch 518a8e3084, with zero commits beyond objectui main (it is the main the step-1 claim was read at; step 1 built nothing). Step 1 is done: the dev's fit check 6198994393, ruled at 6203737086 (letter A: the fact goes on the field that owns the pointer pair). Steps 2–3 are done in objectstack: objectstack-ai/objectstack#23735 (referenceDeletedWhen, merged as 8776119bdc, published in @objectstack/spec@18.0.0-next.2) and objectstack-ai/objectstack#23736 (closed 2026-10-16T04:03Z). No Resume-from: there is no work to resume, and the step-4 dev starts the branch from current origin/main.

    Blocker re-pointed (the triage pointer 6208437697 is right that objectstack-ai/objectstack#23736 is satisfied). The key is installable, but objectui main's pnpm-lock.yaml still resolves @objectstack/spec@18.0.0-next.1 (read at ef71a09f9e). The move to 18.0.0-next.2 is objectui#12626 (pm:dispatched, domain:ui seat 4). So the body's blocker line now names that card, the card stays pm:blocked, and this seat dispatches step 4 when it closes.


    Generated by Claude Code

  11. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 3 · step 4 of this card (priority:p3; face 3 of ruling 6190549995, letter A of 6203737086), unlocked: objectui#12626 closed and main f62b6ff4e1 resolves @objectstack/spec@18.0.0-next.2, which carries referenceDeletedWhen
    Session: session_011K9g23W67dy2zwnyzaoB6o
    Account: os-tesla
    Branch: claude/issue-12489-reference-states
    Worktree: objectui-issue-12489 (in the cloud session's own container)
    Domain: domain:ui
    Seat: domain:ui#1
    File surface: the record pointer renderer's tombstone, as ruling A item 3 binds it.

    • packages/fields/src/index.tsx: RecordPointer, resolveRecordPointer, the default RECORD_POINTER_CARD_TYPE face and their docblocks only (⛔ not the cell-renderer regions, which PR feat(fields,plugin-grid): a declared object-ref / recipient-picker widget names what the value references in every list (objectui#12613) #12646 edits, nor fieldWidgetMap, which objectui#12642 edits);
    • packages/app-shell/src/views/record-preview/record-pointer-card-renderer.tsx (the tombstone face; RecordPreviewCard.tsx keeps its 「the caller renders it」 rule and is read, not changed);
    • packages/plugin-detail/src/DetailSection.tsx, the resolveRecordPointer call site only (passing what the predicate and the option's label need);
    • the served-page pins under apps/console/src/services/approvalRequestsDataSource.*.test.tsx, each mounting the root SchemaRendererProvider as ConsoleShell.tsx:306 does, and tests beside each file above;
    • changesets for the touched packages.

    Outside the surface: the side sheet ApprovalsInboxPage.tsx and its four pins (read as the reference, not changed); any new i18n key (the tombstone text is the option's own label, per the ruling); display_title (objectui#12484). A route that needs any of these stops and reports (stop on breach; explain in the report).
    Container & model: M, mode:cloud, model: opus (default tier; dispatch-gates --tier --repo objectstack-ai/objectui over the 6 planned paths: no path-derived mandate)
    Clause-②: yes
    Clause-② reason: ruling A item 3 says so: RecordPointer, exported from @object-ui/fields, widens, and resolveRecordPointer's field parameter widens to read referenceDeletedWhen. The seat's TIER_DEFAULT review comes before ready.
    Responsibility: n/a — not a defect card
    Thread-read: 6213174414
    Serial constraints cleared: read at objectui main f62b6ff4e1.


    Generated by Claude Code

  12. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 12489,
      "status": "done",
      "branch": "claude/issue-12489-reference-states",
      "pr": "https://github.com/objectstack-ai/objectui/pull/12665",
      "session": "session_01RXFSkyCWZHTfnnf5iKrQFN (cloud dev run, dispatched by the domain:ui seat 1 session session_011K9g23W67dy2zwnyzaoB6o)",
      "premise_still_valid": true,
      "summary": "Ruling A item 3 is built on b78ab082. The resolveRecordPointer rule in @object-ui/fields now reads the spec's referenceDeletedWhen beside referenceVia. When the row's sibling select holds the declared option, the returned RecordPointer carries deletedLabel, which is that option's label from an optionsOf callback the call site supplies. The predicate lives only in fields. DetailSection passes the object field's referenceDeletedWhen and the sibling's options, translated with the same translateOptions call the grid already uses for select options (H3). The app-shell pointer renderer is the caller that RecordPreviewCard's rule names: on deletedLabel it draws the tombstone (data-record-pointer=deleted, wastebasket icon, the label) and does not mount the card, so nothing is read, nothing is linked and no id is shown. The default text face in fields draws the label instead of the id. H1, H2, H3 and H5 hold. H4 was measured on the served-page harness under the root SchemaRendererProvider: readable, deleted and unresolvable match the sheet's pins. The refused state differs from the sheet beyond the tombstone; this is reported, not fixed (see open_questions). A live request page was NOT MEASURED, because published @objectstack/spec 18.0.0-next.2 lacks the services declaration (objectstack PR #23798), so the served-page harness carries that declaration and serves as the evidence.",
      "h_readings": {
        "H1": "HOLDS. resolveRecordPointer(field, row, optionsOf) evaluates row[referenceDeletedWhen.field] === referenceDeletedWhen.value and looks up the option in optionsOf(field). DetailSection supplies only the declaration and the options; it does not evaluate the predicate. There is no new export: the helper types are module-local.",
        "H2": "HOLDS. Under the real DetailSection: the adapter's findOne is called 0 times and MetadataCtx getItem 0 times, with 0 anchors under a host that builds record hrefs, no data-record-preview element, and no id in the tombstone. On the served page: 0 invoice findOne calls, 0 links to the record path, and the record id appears neither in the tombstone nor in the Details tabpanel. The default fields face draws the label, not the id.",
        "H3": "HOLDS. The helper is useSafeFieldLabel().translateOptions, which resolves fieldOptions.OBJECT.FIELD.VALUE with the declared label as fallback, under the same key the sheet's fieldOptionLabel reads. A zh-CN bundle draws the tombstone as the localized label, both under the real DetailSection and on the served page. No new i18n key was added.",
        "H4": "MEASURED on the served page (real RecordDetailView, ApprovalRecordReads, root SchemaRendererProvider, SERVED_PAGE copied whole). readable: one link to the app-scoped record path inside the card, named by the title; matches the recordLink pin. refused (403 PERMISSION_DENIED): card unreadable, text 'This record cannot be opened', no link, and the snapshot title INV-2020 absent from the page (probe: card text and the page-level includes check returned false). The sheet's recordLinkRefused-11878 pin keeps the title as plain text, so this DIFFERS beyond the tombstone and is reported only. deleted: tombstone 'Related record deleted', 0 reads, no link, no id at the reference. Matches the sheet's tombstone text, no link and no bare id, except that the sheet also moves record_title onto its meta line and the served page draws no record_title (reported). unresolvable: 'This record cannot be opened', no link, no id in the card; matches the unresolvableReference pin.",
        "H5": "HOLDS. Tested cases: a field without the key; a sibling holding another option; no sibling value; a null sibling; no optionsOf. Each returns the pair exactly as before. On the served page, a cancelled row with no cancel_reason reads the target and draws the readable card, and a 404 on an unflagged row draws the cause-free card with no tombstone. Existing pins in the record-preview directory and the plugin-detail recordPointer-12045 suite stay green."
      },
      "tests": "Union at HEAD b78ab082: pnpm exec vitest run --maxWorkers=2 over packages/fields/, packages/plugin-detail/, packages/app-shell/src/views/record-preview/, every apps/console/src/services/approvalRequestsDataSource.*.test.ts(x), and the four sheet pins (recordLink, recordLinkRefused-11878, tombstone, unresolvableReference). Result: 'Test Files 552 passed | 2 skipped (554)', 'Tests 6937 passed | 21 skipped (6958)', 'VERDICT command-exit 0' through os-verify-lock (slot dev-12489-cloud). New pins: fields resolveRecordPointer.deleted-12489 (10 tests), app-shell record-pointer-card-renderer.tombstone-12489 (7), console approvalRequestsDataSource.servedPageReferenceStates-12489 (8). Ablation: four runs through objectstack's scripts/ablation-replace.mjs; each confirmed the mutation on disk (anchor 1 to 0, blob moved), and each restore checked blob == HEAD and an empty git diff HEAD. The root vitest config aliases @object-ui/* to src, so no dist leg applies. A1, predicate forced false (fields index.tsx): 9 failed / 17 passed of 26 across all 3 new files. A2, a findOne made anyway in the tombstone branch (app-shell renderer): 3 failed (the zero-read pin and both served deleted pins). A3, label taken from the raw option value: 8 failed (label pins plus the 'never the raw option value' pin). A4, extra for H3, the call site skips translateOptions: 2 failed (both localized pins). The H4 refused-title probe was a temporary assertion in the new test file, run once and restored from a byte copy; it was never committed.",
      "gates": "Local, hand-derived from objectui package.json and ci.yml (dispatch-gates is objectstack's tool, so it was not run). Each exit code was captured before any pipe. (1) Closure build: pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell...' build, BUILD_EXIT=0; the app-shell dist completeness check reported 1114 emitted files verified. (2) type-check: @object-ui/fields=0, @object-ui/plugin-detail=0, @object-ui/app-shell=0. @object-ui/console was first 2: 23 errors, all from plugin-gantt, timeline, map, markdown and tree dists outside the closure, and none in a touched file. After building those five plugins it re-ran at 'VERDICT command-exit 0' for the build && type-check chain. (3) pnpm check:changeset-claims=0 ('No pending changeset names a file this change touches'); pnpm changeset:check=0; pnpm check:test-path-roots=0; pnpm check:spec-symbols=0; node scripts/check-changeset-presence.mjs=0 ('6 source file(s) of 4 released package(s) changed ... declares 3 changeset(s)'); node scripts/check-new-cross-file-line-citations.mjs=0 ('0 new citation(s)'). (4) eslint --no-inline-config on the 6 changed source and test files: exit 0, 0 errors and 157 warnings, all pre-existing rule classes (react-refresh/only-export-components on existing exports, react-hooks/set-state-in-effect in untouched code). CI check-runs are NOT MEASURED: there is no PR yet and the seat opens it.",
      "mcp_calls": "2, all reads: issue_read get and get_comments on objectui#12489. ToolSearch loaded the tool schema once. No GitHub write tool was called.",
      "api_writes": "0 REST writes. Two git pushes to claude/issue-12489-reference-states: the first was the write probe, a fast-forward of the stale tip 518a8e3 to origin/main a5bb7ac (518a8e3 was confirmed an ancestor after deepening the shallow clone); the second pushed b78ab082. No PR creation, issue comment, label write or relay call, per the cloud brief.",
      "open_questions": [
        {
          "question": "The tombstone uses its own attribute, data-record-pointer=deleted, not a fifth data-record-preview value. Keep it?",
          "options": ["A keep data-record-pointer=deleted: RecordPreviewCard's header defines exactly four states of its own and leaves deletion to the caller", "B reuse data-record-preview=deleted so one selector reads all five faces"],
          "recommendation": "A, because the card never draws this state and its header says so; a shared attribute would read as the card claiming it."
        },
        {
          "question": "On the served page the refused state shows the card's cause-free 'This record cannot be opened' and no snapshot title. The sheet's recordLinkRefused-11878 pin keeps the title as plain text. Close this here or elsewhere?",
          "options": ["A leave it to the closing card objectui#12484, which retires the sheet pins against the page", "B a new card to carry record_title into the pointer face"],
          "recommendation": "A, because the acceptance line ('a refused read never yields a link') holds, the card fuses unreadable answers by design (the existence-oracle rule), and the brief forbids widening this build."
        },
        {
          "question": "The served tombstone fires on cancel_reason = record_deleted alone. The sheet's isDeletedRecordReference also requires status = cancelled. Accept the single condition?",
          "options": ["A accept: ruling A put one declared predicate on the field, and the contract says cancel_reason is present only on cancelled rows", "B a spec change for compound predicates"],
          "recommendation": "A, because the ruling and the spec key are single-condition and the contract carries the second half; B would be speculative surface."
        },
        {
          "question": "The sheet's tombstone moves record_title to its meta line; the served tombstone draws the label alone. Add it?",
          "options": ["A no, ruling A says the tombstone is the option's own label", "B carry it with objectui#12484"],
          "recommendation": "A here, with B noted for #12484's page migration."
        }
      ],
      "out_of_scope_findings": [
        "carrier: objectui#12484 · noted, not filed. The page H1 is display_title ('{process_name} · {record_id}'), so the raw record id stays on screen in all four states. This card's id pins are scoped to the reference (the tombstone and the Details tabpanel). Dedupe words: approval request page title raw record id, display_title record_id.",
        "carrier: objectui#12484 · noted, not filed. The H4 differences beyond the tombstone: the refused state keeps no snapshot title on the served page (the sheet keeps it as plain text), and the deleted state shows no record_title meta (the sheet shows one). Dedupe words: served page refused snapshot title, tombstone record_title meta."
      ],
      "live_reading": "NOT MEASURED: live reading. Reason: published @objectstack/spec 18.0.0-next.2 does not carry the services declaration on sys_approval_request.record_id (objectstack PR #23798), and this container has no objectstack backend. The served-page harness, which carries that declaration, is the evidence. The Submitter-chip browser reading asked in 6198410345 is NOT MEASURED for the same reason.",
      "deviations": [
        "The shared checkout /home/user/objectui had the branch checked out. It was detached at a5bb7ac to free the branch for the worktree ../objectui-issue-12489 (git worktree add -B ... origin/main). The worktree was removed after the push, node_modules first and without --force.",
        "The commit ends with AGENTS.md's model-free trailer pair (Claude-Session plus Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By, per AGENTS.md's precedence rule and the brief.",
        "There are three changesets, one per released package touched: fields minor, app-shell minor, plugin-detail minor. The console change is a test only and is covered by check-changeset-presence's pass.",
        "Five plugin dists outside the closure (gantt, timeline, map, markdown, tree) were built only to get a clean console type-check reading.",
        "objectstack was cloned read-only at depth 1 beside the worktree. Only its os-verify-lock.sh and ablation-replace.mjs were used.",
        "Docs updated per AGENTS.md #2: content/docs/guide/fields.md and packages/fields/README.md."
      ],
      "files_changed": [
        "packages/fields/src/index.tsx (RecordPointer, resolveRecordPointer, the default pointer face and their docblocks only)",
        "packages/fields/src/__tests__/resolveRecordPointer.deleted-12489.test.tsx",
        "packages/fields/README.md",
        "packages/plugin-detail/src/DetailSection.tsx (the resolveRecordPointer call site only)",
        "packages/app-shell/src/views/record-preview/record-pointer-card-renderer.tsx",
        "packages/app-shell/src/views/record-preview/record-pointer-card-renderer.tombstone-12489.test.tsx",
        "apps/console/src/services/approvalRequestsDataSource.servedPageReferenceStates-12489.test.tsx",
        "content/docs/guide/fields.md",
        ".changeset/12489-record-pointer-deleted-label.md, .changeset/12489-pointer-card-tombstone.md, .changeset/12489-detail-section-deleted-when.md"
      ],
      "cleanup": "Worktree removed (node_modules first, no --force). The temporary ref refs/probe12489/remote was deleted. No dev server or background job is left running."
    }

    Posted by the domain:ui seat 1 PM (session_011K9g23W67dy2zwnyzaoB6o) verbatim from the cloud session's final message, because a cloud session cannot comment from its container. The seat filled pr with the draft PR it opened, #12665. The first deviation's "shared checkout" is the cloud container's own clone, not a fleet checkout.


    Generated by Claude Code

  13. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #12665 comment 6216761552 · contract review 6216747309 (TIER_DEFAULT PASS) · domain:ui seat 1 · session_011K9g23W67dy2zwnyzaoB6o · 2026-10-16T13:40Z


    Generated by Claude Code

  14. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 1 · session_011K9g23W67dy2zwnyzaoB6o · 2026-10-16T14:04Z


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:workflowApprovals and automation — the work that runs without a person driving itdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions