Repository navigation
Commit d727348
feat(lint,spec)!: refuse a holeless ${record.*} / ${result.*} action copy sentence, the last action-copy warning (#25989)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} -->
_Requested by **Steedos** · [project
thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9Ubb1498XergPD9UgXyoeHSEDC)_
Fixes #25709
Clause-②: no (narrowing)
Metadata-protocol: narrowed
## What changes
The console's action runner no longer fills `${…}` in an action's copy:
`ActionRunner.confirmMessage` and `composeSuccessMessage` in
`ui/packages/core/src/actions/ActionRunner.ts` return a sentence with no
`{{ }}` hole as written (objectui#13476, in the imported `ui/` tree on
`main`). So the one action-copy shape the doors still kept a warning, a
holeless `${record.*}` `confirmText` or `${result.*}` `successMessage`,
is now an error at `objectstack validate`, `compile` and the publish
gate, like every other `${…}` token.
- `packages/lint/src/validate-action-copy-templates.ts`:
`isTransitionalDollar`, its warning branch and the `TRANSITIONAL` suffix
are deleted. Every `closedScopeTemplateRefusal` finding is now
`refuse(...)`.
- `packages/spec/src/ui/action-copy-template.ts`:
`ACTION_COPY_DOLLAR_TRANSITION_ROOTS` is retired (and its export in
`ui/index.ts`). The module note and the `confirmText` / `successMessage`
describes no longer say the shape is a warning; the stale
`.objectui-sha` wording now names the `ui/` tree.
- `packages/spec/src/automation/flow-text-slot-template.ts`:
`dollarOnlyTokenRoots` is retired; the lint branch was its only reader.
- Stale wording fixed: `packages/lint/src/authoring-rules.ts`,
`validate-expressions.ts` (two comments), the conformance ledger rows
`template-action-confirm-text` / `template-action-success-message`.
- Generated: `api-surface/ui.json`, `api-surface/automation.json`,
`export-origins/ui.json`, `export-origins/automation.json`, and the
reference pages the describes feed
(`content/docs/references/ui/action.mdx`, `ui/component.mdx`,
`data/object.mdx`, `kernel/metadata-plugin.mdx`), all through
`check:generated --fix`.
Landing point: as the order expected,
`packages/spec/src/ui/action-copy-template.ts` and
`packages/lint/src/validate-action-copy-templates.ts`. No producer
carries the shape (below), so nothing moves on the producer side.
The two retired exports are not in `@objectstack/spec@18.1.0` (the
latest published version; read from its npm tarball: 0 hits for either
name in `dist/`, against hits for `closedScopeTemplateRefusal`, the
control). No published version carries them.
## Producer measurement (before the crossing)
Every action-copy sentence reachable from each module's exports, walked
on the base `38050ced` and judged through the built `@objectstack/lint`:
| producer | confirmText | successMessage | errorMessage | with a `${…}`
token | holeless `${…}` shape | lint copy findings |
|---|---|---|---|---|---|---|
| `examples/app-crm` | 0 | 2 | 2 | 0 | 0 | 0 |
| `examples/app-todo` | 1 | 8 | 0 | 0 | 0 | 0 |
| `examples/app-showcase` | 6 | 24 | 0 | 0 | 0 | 0 |
| `examples/app-multi-package` | 0 | 0 | 0 | 0 | 0 | 0 |
| `@objectstack/platform-objects` | 68 | 256 | 16 | 0 | 0 | n/a |
| `@objectstack/plugin-approvals` | 0 | 9 | 0 | 0 | 0 | n/a |
**Count: 0 sentences of the shape in `examples/**`**, and 0 in the
platform packages. Control: a planted `Delete ${record.name}?`
`confirmText` on each example stack draws the finding (a warning before
this change). A text scan of `examples`, `packages/platform-objects`,
`packages/plugins` and `packages/services` for a `confirmText` /
`successMessage` line carrying `${` also answers 0. (The
platform-objects counts include translation-map copies the deep walk
reaches, so they are an upper bound on sentences, not a declaration
count.) HotCRM was not re-measured here.
## The pending #25680 release note is corrected in this PR
`.changeset/25680-action-copy-refusal.md` is still pending (not yet
released). Two of its sentences become false with this change, and they
would ship in the same release: "**Still a warning.** …" (the holeless
shape) and "`@objectstack/spec` adds two exports:
`ACTION_COPY_DOLLAR_TRANSITION_ROOTS` … `dollarOnlyTokenRoots`". This PR
rewrites exactly those two sentences (plus "all but one" in the summary
sentence) and adds its own changeset,
`.changeset/25709-action-copy-holeless-dollar-refusal.md`.
This is the DELIBERATE CORRECTION class `check-empty-changeset.mjs`
names, so `Check Changeset` stays red on purpose (route 0 of its
message). **Confirmation requested in writing on this PR** that the
rewrite of the #25680 note is wanted. `skip-changeset` is not applied.
## Pins flipped (load-bearing)
- `packages/lint/src/validate-action-copy-templates.test.ts`: the
holeless `${result.email}` / `${record.name}` case now asserts
`severity: 'error'`, its location, its `{{ }}` prescription and no "A
warning, not a refusal"; the `action:group` / inline-action case asserts
four errors; the publish-gate cases assert one error on the error
channel and an empty advisory channel for a page write and an action
write.
-
`packages/metadata-protocol/src/protocol.runtime-authoring-gate.test.ts`
(c): through the real `saveMetaItem`, the holeless `${record.*}` page
save now answers `422 INVALID_METADATA` with one `expression-invalid`
error prescribing `{{ record.name }}`, and nothing is stored.
- Spec: the `ACTION_COPY_DOLLAR_TRANSITION_ROOTS` and
`dollarOnlyTokenRoots` unit pins are deleted with their subjects; the
export snapshot (`api-surface/`) pins their absence.
- Repo-wide sweep for the same meaning ("still fills", "transitional",
"A warning, not a refusal, for now", the two symbol names): every hit
outside `ui/` and released text is in this diff.
## Evidence
Final head `a3b0809d`.
- **Ablation** (committed fix first; `scripts/ablation-replace.mjs` with
a trap restore): the refusal branch was mutated back to a warning for a
holeless `${…}` sentence. Lint unit file: 6 failed / 11 passed (the
flipped pins). Rebuilt `@objectstack/lint`, `ablation-dist-preflight`
confirmed the marker in 4 built files, then the protocol gate file: 1
failed / 210 passed (pin (c)). Restore: blob equals HEAD, `git diff
HEAD` empty, rebuilt, `--absent` preflight clean.
- Tests: `@objectstack/lint` 163 files / 7335 tests passed;
`@objectstack/spec` 722 files / 21881 passed (1 todo);
`protocol.runtime-authoring-gate.test.ts` 211/211;
`expression-conformance.test.ts` 8/8 on `a3b0809d`. Typecheck:
`@objectstack/lint`, `@objectstack/spec`,
`@objectstack/metadata-protocol` exit 0.
- Derived gates (`dispatch-gates.mjs --commands`, 113 families, `--ran`
reconciliation: 113 derived, 113 run): green except
`check-empty-changeset` (the declared correction above, exit 1);
`check:type-check-debt` and `check:dual-build-cjs-loads` exited 3,
PREREQUISITE NOT MET (no lock turn for the re-measure's closure build;
unbuilt packages outside this closure): NOT MEASURED locally, CI's `Lint
& Repo Gates` runs both. `check:skill-examples`, `check:dts-closure` and
`check-plugin-teardown-shape --self-test` first read a dist mid-rebuild
or a shallow clone and were re-run green. `check:doc-authoring` found a
tracker id in the ledger string; fixed in `a3b0809d` and re-run green.
`check-platform-checklist --changed-from origin/main`: OK, 0 anchors
lost. `check:generated`: all 14 artifacts up to date.
- **Dogfood battery** (owed by the `(narrowing)` arm): `pnpm --filter
@objectstack/dogfood test` under the verify lock, launched at
`5a6ed48a`; the ledger string edit of `a3b0809d` landed on disk 43 s
into the run, so `expression-conformance.test.ts` was re-run on
`a3b0809d` (8/8). VERDICT command-exit 1: Test Files 1 failed / 295
passed / 3 skipped; Tests 1 failed / 2522 passed / 18 skipped. The one
failure is `test/authz-probe-blind-spot.test.ts`
"packages/runtime/src/domains/i18n.ts — every positive control is still
present in THAT file" (control `handleI18nRequest` expected 3, read 4).
This diff touches nothing under `packages/runtime` or that test, so the
failure does not come from it (inferred from the file list; the test was
not re-run on the base `38050ced`).
## Acceptance notes
- Contract review at CONTRACT_REVIEW_TIER is owed (narrowing).
- `outcomeMessages` and `ActionSchema.errorMessage` stay outside the
family, unchanged.
---
_Generated by [Claude
Code](https://claude.ai/code/session_0148U1UfHrMrKAyJbiSs1ZYr)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 3518664 commit d727348
21 files changed
Lines changed: 115 additions & 178 deletions
File tree
- .changeset
- content/docs/references
- data
- kernel
- ui
- packages
- lint/src
- metadata-protocol/src
- qa/dogfood/test
- spec
- api-surface
- export-origins
- src
- automation
- ui
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
492 | 492 | | |
493 | 493 | | |
494 | 494 | | |
495 | | - | |
496 | | - | |
| 495 | + | |
| 496 | + | |
497 | 497 | | |
498 | 498 | | |
499 | 499 | | |
| |||
0 commit comments