fix(spec): action.undoable is live, not experimental — two objectui readers gate it (#3714) - #3829
Merged
Merged
Conversation
…eaders gate it (#3714) The liveness ledger marked `action.undoable` `experimental` on a #1992-era note ("no runtime reader yet ... objectui has an UndoManager but does not key off this field"). True when written, falsified since: objectui wired two readers, both gating real behaviour — app-shell useConsoleActionRuntime.tsx:409 builds the undo operation the success toast's Undo button invokes (:147), and RecordDetailView.tsx:545 restores the record's prior field values (:404). components action/action-button.tsx:113 forwards the flag for exactly that reason, per its own comment. Because the CLI liveness lint warns on `experimental` as well as `dead`, authoring a *working* property produced a "declared but NOT enforced at runtime" warning — telling authors and AI to skip a shipped feature. - ledger: `experimental` -> `live` with the two readers as evidence; note records that the #1992 claim was true when written - README: action row 33|1|2 -> 34|0|2; `undoable` joins `flow.status` as the second understatement, with the cost of understating spelled out - protocol docs: drop the "no runtime consumer keys off it yet ... currently has no effect" claim, describe the snapshot/restore behaviour instead - CLI lint test: the experimental-path assertion repoints to agent.memory, plus a regression guard that `undoable` is now silent Schema, parsed shape and runtime are unchanged — only the classification. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ajwvrmd1hDC9RBofYBhGuR
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 2 package(s): 110 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
marked this pull request as ready for review
July 28, 2026 09:16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3714.
The claim vs the code
The liveness ledger marked
action.undoableexperimentalon a #1992-era note — "no runtime reader yet: neither service-automation nor objectui consume the action'sundoableflag (objectui has an UndoManager but does not key off this field)." That was true when written, and has since been falsified: objectui wired two readers, both gating real behaviour.useConsoleActionRuntime.tsx:409:147)RecordDetailView.tsx:545:404)componentsaction/action-button.tsx:113forwards the flag for exactly that reason, per its own comment: "without this the flag is dropped and the handler never builds the undo operation." Authoring side:ActionDefaultInspector.tsx"Offer undo" checkbox.Why it mattered: the CLI liveness lint warns on
experimentalas well asdead, so authoring a working property emittedliveness-experimental-property— "declared but NOT enforced at runtime". An author, or an AI consulting the ledger, concludesundoableis aspirational and skips a shipped feature.Changes
packages/spec/liveness/action.json—experimental→live, evidence = the two readers plus the plumbing site; note records that the feat(action): conditional visibility + undoable actions (CRM demo) #1992 claim was true when written and what falsified it.packages/spec/liveness/README.md— action row33 | 1 | 2→34 | 0 | 2.undoablejoinsflow.statusas the second understatement in the narrative, and the "when in doubt, err towarddead" guidance now says what understating costs: the ledger is read as a capability catalogue, so a stale warning is an invitation to skip working surface. Erring towarddeadstays the right default and a debt to re-verify.content/docs/protocol/objectui/actions.mdx— dropped the "no runtime consumer keys off it yet … currently has no effect" claim (it contradicted this repo's ownskills/objectstack-ui/SKILL.mdand theaction.zod.tscomment); describes the snapshot/restore behaviour instead.packages/cli/src/utils/lint-liveness-properties.test.ts— the experimental-path assertion repoints toagent.memory(action.json now has zero experimental entries) and asserts theruleisliveness-experimental-property, plus a new regression guard thatundoableis silent.patchon@objectstack/spec+@objectstack/cli.Schema, parsed shape and runtime are unchanged — only the classification of what they already do.
Verification
pnpm --filter @objectstack/spec check:liveness— exits 0;action/undoableis not in the stale-evidence list (the objectui evidence is prose-prefixed per this ledger's convention, so the path-existence check doesn't false-flag it).pnpm vitest run src/utils/lint-liveness-properties.test.ts(cli) — 15 passed.pnpm vitest run scripts/liveness/proof-registry.test.ts src/ui/action.test.ts(spec) — 128 passed.action/undoableis not bound to a high-risk proof class, soliveneeds noproofref.One caveat worth a reviewer's eye: objectui is not in this session's repo scope, so the two reader line numbers are carried over from the issue rather than re-verified against objectui
HEAD. Three in-repo sources corroborate the behaviour independently —action.zod.ts:511-513("the runtime captures the record's prior field values and offers an 'Undo' affordance on the success toast (backed by the client UndoManager)"),skills/objectstack-ui/SKILL.md:1669, and the quotedaction-button.tsxcomment — but per this ledger's own methodology section, the decisive check is authoring the property and booting the app. Worth doing before un-drafting if objectui has moved.Generated by Claude Code