Repository navigation
feat(lint,spec)!: refuse a holeless ${record.*} / ${result.*} action copy sentence, the last action-copy warning - #25989
Conversation
…copy sentence
The console's runner no longer fills ${…} in an action's copy (objectui#13476,
in the ui/ tree), so the one shape the doors kept a warning is now an error.
Retire ACTION_COPY_DOLLAR_TRANSITION_ROOTS, dollarOnlyTokenRoots and the
isTransitionalDollar warning branch; flip the pins that held the warning.
Claude-Session: https://claude.ai/code/session_0148U1UfHrMrKAyJbiSs1ZYr
Co-authored-by: Claude <noreply@anthropic.com>
…s for the retired transition exports Claude-Session: https://claude.ai/code/session_0148U1UfHrMrKAyJbiSs1ZYr Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0148U1UfHrMrKAyJbiSs1ZYr Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 2 package(s): 11 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 4 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 144 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 7773245a2f0b1660afe4063a13db880385929b99 && git checkout 7773245a2f0b1660afe4063a13db880385929b99
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 05f7758f054d70f3ba0f709b37423124be3e6e3d a3b0809dd24087fabd8546299106ab1b4f8643b6 && git checkout -B drift-repro 05f7758f054d70f3ba0f709b37423124be3e6e3d && git merge --no-ff a3b0809dd24087fabd8546299106ab1b4f8643b6
node scripts/docs-audit/affected-docs.mjs --json 05f7758f054d70f3ba0f709b37423124be3e6e3d
|
Contract reviewServed-tier: Inputs: card #25709 (body and all 7 comments, the os-dev-report 6411273906 included), PR #25989 (body, 21-file list, diff against its merge base 05f7758), the 47 check-runs on the head. The one local checkout read is origin/main at cdd4eea; main has since moved 3 commits past the PR base with no overlap on any touched path or on ActionRunner.ts (compare 05f7758...main). Gate verdicts on the head47 check-runs, all completed: 37 success, 9 skipped by workflow condition (Lint UI, Test UI, Temporal Conformance, Dogfood Verify CLI, the 3 dogfood shards, the two opt-in harnesses), 1 failure: Check Changeset. Its annotations name exactly one cause: ① Derived judgmentsPremise (the card's precondition). RIGHT. On main, ui/packages/core/src/actions/ActionRunner.ts Accept-set, the narrowing. RIGHT, and the only one. Before: at every door ( Error envelope. RIGHT. Every refusal in the family now goes through the one Stored data. RIGHT, covered by measured absence plus an unchanged parse. The parse is not touched: Public surface. RIGHT. Describes and reference pages. RIGHT. The Ledger rows. RIGHT. Both One wording left behind, non-blocking. packages/lint/src/validate-action-copy-templates.test.ts keeps two unchanged context comments inside the renamed ② Semver levelChangeset The rewrite of the pending
The rewrite touches nothing else in the note (frontmatter, declaration lines, the ADR-0087 marker and the measurement bullet are unchanged). Leaving the note as it stands on main would ship three false sentences in the same CHANGELOG entry, which is the class the gate's own remedy says not to restore. This record is the written judgment the gate's remedy asks for on the PR: each rewritten sentence is true against the diff and main. ③ Boundary flagsDev deviations (os-dev-report 6411273906) and the one out-of-scope finding;
The dev's two NOT-MEASURED local families are measured green on the head by Type Check · debt ledger and Lint & Repo Gates. The ablation on the PR body (refusal branch mutated back to a warning: 6 lint pins and protocol pin (c) red, restore verified) is the dev's own evidence and is consistent with the pins this record read; it was not re-run here. Implemented-by: VERDICT: PASS |
席位核对ACCEPT · domain:spec seat 2 · 2026-10-26T08:41Z · head
|
Requested by Steedos · project thread
Fixes #25709
Clause-②: no (narrowing)
Metadata-protocol: narrowed
What changes
The console's action runner no longer fills
${…}in an action's copy:ActionRunner.confirmMessageandcomposeSuccessMessageinui/packages/core/src/actions/ActionRunner.tsreturn a sentence with no{{ }}hole as written (objectui#13476, in the importedui/tree onmain). So the one action-copy shape the doors still kept a warning, a holeless${record.*}confirmTextor${result.*}successMessage, is now an error atobjectstack validate,compileand the publish gate, like every other${…}token.packages/lint/src/validate-action-copy-templates.ts:isTransitionalDollar, its warning branch and theTRANSITIONALsuffix are deleted. EveryclosedScopeTemplateRefusalfinding is nowrefuse(...).packages/spec/src/ui/action-copy-template.ts:ACTION_COPY_DOLLAR_TRANSITION_ROOTSis retired (and its export inui/index.ts). The module note and theconfirmText/successMessagedescribes no longer say the shape is a warning; the stale.objectui-shawording now names theui/tree.packages/spec/src/automation/flow-text-slot-template.ts:dollarOnlyTokenRootsis retired; the lint branch was its only reader.packages/lint/src/authoring-rules.ts,validate-expressions.ts(two comments), the conformance ledger rowstemplate-action-confirm-text/template-action-success-message.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 throughcheck:generated --fix.Landing point: as the order expected,
packages/spec/src/ui/action-copy-template.tsandpackages/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 indist/, against hits forclosedScopeTemplateRefusal, 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
38050cedand judged through the built@objectstack/lint:${…}token${…}shapeexamples/app-crmexamples/app-todoexamples/app-showcaseexamples/app-multi-package@objectstack/platform-objects@objectstack/plugin-approvalsCount: 0 sentences of the shape in
examples/**, and 0 in the platform packages. Control: a plantedDelete ${record.name}?confirmTexton each example stack draws the finding (a warning before this change). A text scan ofexamples,packages/platform-objects,packages/pluginsandpackages/servicesfor aconfirmText/successMessageline 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.mdis 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/specadds 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.mjsnames, soCheck Changesetstays 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-changesetis not applied.Pins flipped (load-bearing)
packages/lint/src/validate-action-copy-templates.test.ts: the holeless${result.email}/${record.name}case now assertsseverity: 'error', its location, its{{ }}prescription and no "A warning, not a refusal"; theaction: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 realsaveMetaItem, the holeless${record.*}page save now answers422 INVALID_METADATAwith oneexpression-invaliderror prescribing{{ record.name }}, and nothing is stored.ACTION_COPY_DOLLAR_TRANSITION_ROOTSanddollarOnlyTokenRootsunit pins are deleted with their subjects; the export snapshot (api-surface/) pins their absence.ui/and released text is in this diff.Evidence
Final head
a3b0809d.scripts/ablation-replace.mjswith 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-preflightconfirmed the marker in 4 built files, then the protocol gate file: 1 failed / 210 passed (pin (c)). Restore: blob equals HEAD,git diff HEADempty, rebuilt,--absentpreflight clean.@objectstack/lint163 files / 7335 tests passed;@objectstack/spec722 files / 21881 passed (1 todo);protocol.runtime-authoring-gate.test.ts211/211;expression-conformance.test.ts8/8 ona3b0809d. Typecheck:@objectstack/lint,@objectstack/spec,@objectstack/metadata-protocolexit 0.dispatch-gates.mjs --commands, 113 families,--ranreconciliation: 113 derived, 113 run): green exceptcheck-empty-changeset(the declared correction above, exit 1);check:type-check-debtandcheck:dual-build-cjs-loadsexited 3, PREREQUISITE NOT MET (no lock turn for the re-measure's closure build; unbuilt packages outside this closure): NOT MEASURED locally, CI'sLint & Repo Gatesruns both.check:skill-examples,check:dts-closureandcheck-plugin-teardown-shape --self-testfirst read a dist mid-rebuild or a shallow clone and were re-run green.check:doc-authoringfound a tracker id in the ledger string; fixed ina3b0809dand re-run green.check-platform-checklist --changed-from origin/main: OK, 0 anchors lost.check:generated: all 14 artifacts up to date.(narrowing)arm):pnpm --filter @objectstack/dogfood testunder the verify lock, launched at5a6ed48a; the ledger string edit ofa3b0809dlanded on disk 43 s into the run, soexpression-conformance.test.tswas re-run ona3b0809d(8/8). VERDICT command-exit 1: Test Files 1 failed / 295 passed / 3 skipped; Tests 1 failed / 2522 passed / 18 skipped. The one failure istest/authz-probe-blind-spot.test.ts"packages/runtime/src/domains/i18n.ts — every positive control is still present in THAT file" (controlhandleI18nRequestexpected 3, read 4). This diff touches nothing underpackages/runtimeor that test, so the failure does not come from it (inferred from the file list; the test was not re-run on the base38050ced).Acceptance notes
outcomeMessagesandActionSchema.errorMessagestay outside the family, unchanged.Generated by Claude Code