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 }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
decision: objectui#11168 — action:button.undoable is declared, but the block path never captures Undo for operation: 'update' (no row stash): deliver it on the block (B) or narrow it off the spec row (C)? #11754
Filing gate: ② a decision only the maintainer can make. Filed by the triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015, session_01AavokzJ5DndAwitDXvKy4U), on the maintainer's instruction 「需要我决裁的问题,立决策卡」. ⛔ Not a claim. Once ruled, the ruling is recorded on this card and on the parent, and this card closes.
Parent: objectui#11168 (p2, pm:on-hold). Its Restart-when: is this ruling and nothing else: "the maintainer rules B or C on action:button.undoable" (5982135645). The question was raised in the slice-1 dev report (5907196304, open question 2) on 2026-09-30, and no decision card carried it until now.
维护者速读
页面上作者配置的"更新"按钮(action:button,operation: 'update')可以声明 undoable,spec 也接受这个写法,但点完之后没有"撤销"按钮。原因是运行时要靠一份行快照才能做撤销,而按钮区块从来不写这份快照。记录详情页上的 api 写法则能正常撤销。
Prior rulings read: undoable / ActionSchema fulfilment → ruling 5754211444 (objectstack batch #203 item 5, letter C, landed as objectstack-ai/objectstack#19635). Its rule: undoable: true is legal only on a shape some runtime fulfils (operation: 'update' through the framework runtime; type: 'api' through the console), and is refused elsewhere. That rule is why D (publish with a caveat) is out. It does not choose between delivering and narrowing on the block. check-prior-rulings on these terms: 0 further hits. Thread: objectui#11168 5907196304, 5907833984, 5982135645.
Ruling: batch #284 item 1 · letter B · maintainer 「同意」 2026-10-07T03:33Z
Director seat, summon #35, session_01VYToj6PQehTEKNrjGM9akg (GitHub os-zhuang; written as objectstack-fleet[bot] via the relay). Batch #284 was presented in chat with this card's options B / C (A and D as the card lists them); the maintainer answered 「同意」, which takes the recommendation. Freshness gate: the body (no comments) and the parent's thread (objectui#11168: the hold correction 5982135645, triage's pointer 6029656672) were re-read before this record; nothing newer exists. Thread-read: none on this card.
The ruling
B. The button block delivers undoable where a record is in scope. The runtime already captures Undo whenever the invoking surface hands it the row (packages/core/src/actions/ActionRunner.ts:1788: action.undoable && rowRecord && writtenFields.length > 0), and the surfaces that do so today are the record page's declared-actions bar, the related-record bridge, the layout containers and the grid's rows; the action:button renderer hands it nothing. The change is at the block: when the block runs inside a record context (the record page's current record, a table's current row), it passes that record as the Undo baseline the runner already reads; the key is then published on action:button, with its description stating the one limit (a standalone button with no record in scope offers no Undo, because there is no row to restore). ⛔ Not taken: C (a breaking narrowing of the spec row, v18 only, which would also contradict the closed table the 5754211444 ruling fixed, where operation: 'update' is the shape the framework runtime fulfils, and would strip an already-fulfilled key from the record page's api path), A (the entry stays booked forever) and D (publishing a key that does not deliver, which 5754211444 already excluded).
Why B: the spec's closed table of fulfillable shapes is already ruled; B makes the block honour it. In two years the same undoable behaves the same on the block, the record page and the list: wherever a record is in scope, the action can be undone, whatever surface it started from.
Activity
objectstack-fleet commentedon Oct 7, 2026
Ruling: batch #284 item 1 · letter B · maintainer 「同意」 2026-10-07T03:33Z
Director seat, summon #35,
session_01VYToj6PQehTEKNrjGM9akg(GitHubos-zhuang; written asobjectstack-fleet[bot]via the relay). Batch #284 was presented in chat with this card's options B / C (A and D as the card lists them); the maintainer answered 「同意」, which takes the recommendation. Freshness gate: the body (no comments) and the parent's thread (objectui#11168: the hold correction 5982135645, triage's pointer 6029656672) were re-read before this record; nothing newer exists. Thread-read: none on this card.The ruling
B. The button block delivers
undoablewhere a record is in scope. The runtime already captures Undo whenever the invoking surface hands it the row (packages/core/src/actions/ActionRunner.ts:1788:action.undoable && rowRecord && writtenFields.length > 0), and the surfaces that do so today are the record page's declared-actions bar, the related-record bridge, the layout containers and the grid's rows; theaction:buttonrenderer hands it nothing. The change is at the block: when the block runs inside a record context (the record page's current record, a table's current row), it passes that record as the Undo baseline the runner already reads; the key is then published onaction:button, with its description stating the one limit (a standalone button with no record in scope offers no Undo, because there is no row to restore). ⛔ Not taken: C (a breaking narrowing of the spec row, v18 only, which would also contradict the closed table the 5754211444 ruling fixed, whereoperation: 'update'is the shape the framework runtime fulfils, and would strip an already-fulfilled key from the record page'sapipath), A (the entry stays booked forever) and D (publishing a key that does not deliver, which 5754211444 already excluded).Why B: the spec's closed table of fulfillable shapes is already ruled; B makes the block honour it. In two years the same
undoablebehaves the same on the block, the record page and the list: wherever a record is in scope, the action can be undone, whatever surface it started from.State
completedin this act; the pointer is recorded on objectui#11168, whoseRestart-when:(5982135645: "the maintainer rules B or C onaction:button.undoable") is met by this ruling, so the hold is released there in the same act (pm:on-hold→pm:queue, no assignee). The next slice on spec parity: the ten blocks @objectstack/spec 17.5.0 newly carries, with their unpublished inputs, refused arms and member pins — declare each by measurement (objectui#11111 decision 3 = B) #11168 does B with the publication and its pins; the claimant first counts the stored pages that declareundoableonaction:button(the card's unmeasured gap).Generated by Claude Code