Skip to content

feat(spec): verifiedAt re-verification clock; re-verify action.undoable/type against objectui (#3714 follow-up) - #3845

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

feat(spec): verifiedAt re-verification clock; re-verify action.undoable/type against objectui (#3714 follow-up)#3845
os-zhuang merged 1 commit into
mainfrom
claude/action-undoable-experimental-j8g24i

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Follow-up to #3829 / #3714, covering the three next steps agreed there. The objectui repo was added to the session for this pass, so the claims below are verified against objectstack-ai/objectui@732b1bf rather than carried over from the issue.

1. action.undoable re-verified — call graph closed by hand

Both readers stand. The evidence now records the whole chain rather than two isolated gates:

  1. app-shell/useConsoleActionRuntime.tsx:409 and app-shell/RecordDetailView.tsx:573 each gate if (action.undoable …) on building result.undo;
  2. core/ActionRunner.ts:640-643 pushes it onto globalUndoManager and passes undo to the toast handler;
  3. the toast's Undo button calls undoCtl.undo()useGlobalUndoUndoManagerdataSource.

That's the "close the call graph by hand" standard this ledger's own methodology section asks for, short of booting the app.

The cited line numbers had already driftedRecordDetailView moved 545→573 and 404→432 in the ~1 day between the issue being filed and this pass. Nothing behavioural, but it's a live demonstration of why an evidence string with bare line numbers rots. objectui-side evidence now pins the commit (objectui @732b1bf).

2. content/docs/ui/actions.mdx — the same understatement, one page over

The page told authors:

The schema also accepts api and form types, but they have no runtime executor / renderer today — stick to the four above.

Both are false at objectui HEAD: apiexecuteAPI (ActionRunner.ts:974, string-or-ApiConfig endpoint with method/headers/queryParams/responseType), formexecuteForm (:920, routes to /forms/:target?recordId=…). The ledger's own action.type entry has recorded form as live since #2377 — the doc and the ledger have been contradicting each other.

3. verifiedAt — the re-verification clock

Two entries have now been falsified by code moving under them (flow.status #3711, action.undoable #3714), both understated, and both found only because a sweep aimed at the opposite failure walked past them. Nothing in the gate asked how old a claim was.

Entries may now carry "verifiedAt": "YYYY-MM-DD". The asymmetry is the design:

Behaviour
Age Never fails CI — re-verification is a worklist, not a merge gate. One summary line per run; pnpm check:liveness --stale-verification[=days] prints the worklist, stale oldest-first then undated. Default 180d.
Malformed / future date Fails CI. An unparseable date silently exempts that entry from every staleness window — the same silent-no-op shape this ledger exists to catch. Calendar-invalid dates are rejected too, since new Date('2026-02-30') rolls over to March 2 rather than throwing.

New pure module verification.mts (injectable now/threshold, so the gate, the tests and any future sweep share one arithmetic) + verification.test.ts.

Currently 2 of 401 entries are dated. The rest predate the field and report as undated — the README says to date them as you re-verify rather than back-fill guesses.

re-verification clock: 2 entr(ies) carry `verifiedAt` (0 older than 180d), 399 undated.
  run with --stale-verification[=days] for the worklist.

Verification

  • pnpm --filter @objectstack/spec check:liveness — exits 0.
  • Failure path exercised directly: temporarily set verifiedAt: "2026-13-99"✗ 1 malformed \verifiedAt` value(s)`, gate exits 1. Value restored.
  • pnpm --filter @objectstack/spec test — 260 files, 6763 tests passed (includes the 11 new verification.test.ts cases).
  • pnpm vitest run src/utils/lint-liveness-properties.test.ts (cli) — 15 passed.
  • ESLint: packages/spec/scripts/** is outside the lint config (pre-existing, same as check-liveness.mts).

Not done: booting the app and clicking Undo. The static chain is closed end to end, which the README treats as sufficient for a presence claim — but it also says the decisive check is "author the property, boot the app and look." Worth a dogfood-verification pass before this pattern gets copied to other objectui-backed entries.


Generated by Claude Code

…le/type against objectui (#3714 follow-up)

A ledger entry is a claim with a timestamp, and twice now one has been falsified
by code moving under it — flow.status (#3711) and action.undoable (#3714), both
understated, both found only because a sweep aimed at the opposite failure
walked past them. Nothing in the gate asked how old a claim was.

1. verifiedAt clock. Entries may carry "verifiedAt": "YYYY-MM-DD". Age never
   fails CI (re-verification is a worklist, not a merge gate) — one summary line
   per run, full worklist under `check:liveness --stale-verification[=days]`,
   default 180d. A malformed or future date DOES fail: it would silently exempt
   the entry from every staleness window, the same silent-no-op shape this
   ledger exists to catch. Calendar-invalid dates are rejected too, since
   new Date('2026-02-30') rolls over rather than throwing.
   New pure module verification.mts + 11 unit tests, incl. a contract test that
   every verifiedAt in the shipped ledgers parses.

2. Re-verified against objectui 732b1bf:
   - action.undoable — both readers stand; evidence now closes the call graph
     end to end (gate -> result.undo -> globalUndoManager + toast -> undoCtl
     -> UndoManager -> dataSource). The cited RecordDetailView lines had already
     drifted 545->573 / 404->432 one day after the issue was filed, hence the
     pinned sha.
   - action.type — api -> executeAPI, form -> executeForm, both real.

3. content/docs/ui/actions.mdx told authors `api` and `form` have "no runtime
   executor / renderer today". Both have executors in objectui's ActionRunner,
   and the ledger's own action.type entry recorded `form` as live since #2377 —
   the same understatement shape as #3714, one page over. Added table rows for
   both, kept the true half of the callout (shortcut/bulkEnabled really are
   unwired), and added `undoable` to the UX property list.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ajwvrmd1hDC9RBofYBhGuR
@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Jul 28, 2026 9:28am

Request Review

@github-actions github-actions Bot added 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 1 package(s): @objectstack/spec.

104 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 @objectstack/spec)
  • content/docs/ai/skills.mdx (via @objectstack/spec)
  • content/docs/api/client-sdk.mdx (via @objectstack/spec)
  • content/docs/api/environment-routing.mdx (via @objectstack/spec)
  • content/docs/api/error-catalog.mdx (via @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/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/cli.mdx (via @objectstack/spec)
  • 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/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/email-service.mdx (via packages/spec)
  • content/docs/kernel/runtime-services/index.mdx (via 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/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/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/spec)
  • 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/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/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 10:26
@os-zhuang
os-zhuang merged commit c757854 into main Jul 28, 2026
17 checks passed
@os-zhuang
os-zhuang deleted the claude/action-undoable-experimental-j8g24i branch July 28, 2026 10:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants