Skip to content

fix(spec): action.undoable is live, not experimental — two objectui readers gate it (#3714) - #3829

Merged
os-zhuang merged 1 commit into
mainfrom
claude/action-undoable-experimental-j8g24i
Jul 28, 2026
Merged

fix(spec): action.undoable is live, not experimental — two objectui readers gate it (#3714)#3829
os-zhuang merged 1 commit into
mainfrom
claude/action-undoable-experimental-j8g24i

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Closes#3714.

The claim vs the code

The liveness ledger marked action.undoableexperimental on a #1992-era note — "no runtime reader yet: neither service-automation nor objectui consume the action's undoable flag (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.

ReaderWhat the flag gates
app-shell useConsoleActionRuntime.tsx:409builds the undo operation the success toast's Undo button invokes (:147)
app-shell RecordDetailView.tsx:545restores the record's prior field values (:404)

componentsaction/action-button.tsx:113 forwards 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 experimental as well as dead, so authoring a working property emitted liveness-experimental-property — "declared but NOT enforced at runtime". An author, or an AI consulting the ledger, concludes undoable is aspirational and skips a shipped feature.

Changes

  • packages/spec/liveness/action.jsonexperimentallive, 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 row 33 | 1 | 234 | 0 | 2. undoable joins flow.status as the second understatement in the narrative, and the "when in doubt, err toward dead" 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 toward dead stays 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 own skills/objectstack-ui/SKILL.md and the action.zod.ts comment); describes the snapshot/restore behaviour instead.
  • packages/cli/src/utils/lint-liveness-properties.test.ts — the experimental-path assertion repoints to agent.memory (action.json now has zero experimental entries) and asserts the rule is liveness-experimental-property, plus a new regression guard that undoable is silent.
  • Changesetpatch on @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/undoable is 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/undoable is not bound to a high-risk proof class, so live needs no proof ref.

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 quoted action-button.tsx comment — 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

…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
@vercel

vercelBot commented Jul 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredJul 28, 2026 8:46am

Request Review

@github-actionsgithub-actionsBot added size/s documentation Improvements or additions to documentation tests tooling labels Jul 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/cli, @objectstack/spec.

110 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx(via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx(via packages/cli, @objectstack/spec)
  • content/docs/ai/skills.mdx(via @objectstack/spec)
  • content/docs/api/client-sdk.mdx(via @objectstack/cli, @objectstack/spec)
  • content/docs/api/data-flow.mdx(via @objectstack/cli)
  • content/docs/api/environment-routing.mdx(via @objectstack/cli, @objectstack/spec)
  • content/docs/api/error-catalog.mdx(via @objectstack/cli, @objectstack/spec)
  • content/docs/api/error-handling-client.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx(via @objectstack/spec)
  • content/docs/api/index.mdx(via @objectstack/spec)
  • content/docs/automation/approvals.mdx(via packages/spec)
  • content/docs/automation/flows.mdx(via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx(via packages/cli, packages/spec)
  • content/docs/automation/hooks.mdx(via @objectstack/spec)
  • content/docs/automation/index.mdx(via @objectstack/spec)
  • content/docs/automation/webhooks.mdx(via @objectstack/spec)
  • content/docs/automation/workflows.mdx(via @objectstack/spec)
  • content/docs/concepts/architecture.mdx(via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx(via packages/spec)
  • content/docs/concepts/index.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx(via packages/spec)
  • content/docs/concepts/north-star.mdx(via packages/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx(via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx(via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx(via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx(via @objectstack/spec)
  • content/docs/data-modeling/index.mdx(via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx(via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx(via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx(via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx(via @objectstack/spec)
  • content/docs/deployment/backup-restore.mdx(via @objectstack/cli)
  • content/docs/deployment/cli.mdx(via @objectstack/cli, @objectstack/spec)
  • content/docs/deployment/self-hosting.mdx(via @objectstack/cli)
  • content/docs/deployment/troubleshooting.mdx(via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx(via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx(via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx(via @objectstack/spec)
  • content/docs/getting-started/examples.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx(via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx(via @objectstack/cli, @objectstack/spec)
  • content/docs/kernel/cluster.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx(via packages/spec)
  • content/docs/kernel/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/data-service.mdx(via packages/cli)
  • content/docs/kernel/runtime-services/email-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx(via packages/cli, packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx(via packages/spec)
  • content/docs/kernel/services-checklist.mdx(via @objectstack/spec)
  • content/docs/permissions/authentication.mdx(via @objectstack/cli)
  • content/docs/permissions/authorization.mdx(via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx(via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx(via @objectstack/spec)
  • content/docs/permissions/positions.mdx(via @objectstack/spec)
  • content/docs/permissions/rls.mdx(via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx(via @objectstack/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx(via @objectstack/spec)
  • content/docs/plugins/development.mdx(via @objectstack/spec)
  • content/docs/plugins/index.mdx(via @objectstack/spec)
  • content/docs/plugins/packages.mdx(via @objectstack/cli, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx(via @objectstack/spec)
  • content/docs/protocol/diagram.mdx(via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx(via @objectstack/cli, @objectstack/spec)
  • content/docs/protocol/kernel/realtime-protocol.mdx(via @objectstack/cli)
  • content/docs/protocol/kernel/runtime-capabilities.mdx(via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx(via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx(via @objectstack/spec)
  • content/docs/releases/implementation-status.mdx(via @objectstack/cli, @objectstack/spec)
  • content/docs/releases/index.mdx(via @objectstack/spec)
  • content/docs/releases/v12.mdx(via @objectstack/spec)
  • content/docs/releases/v13.mdx(via @objectstack/spec)
  • content/docs/releases/v16.mdx(via @objectstack/cli, @objectstack/spec)
  • content/docs/releases/v9.mdx(via @objectstack/spec)
  • content/docs/ui/actions.mdx(via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx(via @objectstack/spec)
  • content/docs/ui/dashboards.mdx(via @objectstack/spec)
  • content/docs/ui/forms.mdx(via @objectstack/spec)
  • content/docs/ui/index.mdx(via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx(via @objectstack/spec)
  • content/docs/ui/setup-app.mdx(via @objectstack/spec)
  • content/docs/ui/translations.mdx(via @objectstack/spec)
  • content/docs/ui/views.mdx(via @objectstack/spec)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@os-zhuang
os-zhuang marked this pull request as ready for review July 28, 2026 09:16
@os-zhuang
os-zhuang merged commit f63cd09 into mainJul 28, 2026
17 checks passed
@os-zhuang
os-zhuang deleted the claude/action-undoable-experimental-j8g24i branch July 28, 2026 09:16
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/steststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[P3] liveness: action.undoable is marked experimental but has two real runtime readers

2 participants

@os-zhuang@claude