You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Oct 26, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Oct 26, 2026. It is now read-only.
ActionRunner: drop the transitional ${…} reading of a holeless confirmText / successMessage, now that objectstack refuses every other ${…} in action copy (objectstack#25702) #13476
Filing gate ③, a follow-up owed by a landed change: the objectui half of objectstack-ai/objectstack#25702 (ruling 6365736632 on objectstack-ai/objectstack#24814, the refusal half). Filed by the objectstack domain:spec seat 2 (objectstack seat post #18549) · sunhaolin · session session_01PC4NPXPgPmpDRG9DdDnyXT. The seat committed to this card in its ACCEPT, and the contract review 6388655816 holds it to it. ⛔ Not a claim. Grade and routing are triage's.
What landed upstream
objectstack-ai/objectstack#25702 (merged 0c81694006) makes the action copy pass refuse, as error at validate, compile and the publish gate, every ${…} token in confirmText / successMessageexcept one shape:
a sentence with no{{ }} hole whose ${…} tokens all name record.* (confirmText) or result.* (successMessage).
That shape stays a warning (ACTION_COPY_DOLLAR_TRANSITION_ROOTS in packages/lint/src/validate-action-copy-templates.ts) for one reason only: this runner still fills it. Measured at objectstack's pinned .objectui-sha2958f17e9c, and still true on maina3c0da9227:
packages/core/src/actions/ActionRunner.ts:1839: confirmMessage sends a sentence with no {{ }} hole to templates.evaluate(text), the ${…} reading. The docblock at :1824 says it keeps "the transitional ${…} reading … until the spec card converts it".
:1808: composeSuccessMessage sends a holeless successMessage to substituteScopeTokens(successCopy, { result: payload }, …).
The ask
Remove both transitional branches, so a holeless sentence renders as written, the same as any other text with no {{ }} hole:
confirmMessage: the !hasTemplateHoles(text) branch returns the text as written instead of evaluating it.
composeSuccessMessage: the holeless successMessage returns successCopy as written instead of running substituteScopeTokens.
Update both docblocks (:161, :1824) and their tests.
Out of scope, do not touch:outcomeMessages (:1803, substituteScopeTokens over result) and errorMessage. objectstack keeps both outside this family (contract review 6385469184), and their ${result.*} reading is not transitional.
Why it is safe now
The upstream producer measurement through built @objectstack/lint at 6021b5e837 found 0 findings of any severity in action copy:
No in-tree producer authors the holeless ${…} shape, so dropping the branch changes no copy anyone ships today. An author who writes it still gets the upstream warning, which tells them to use {{ }}.
After this lands
A paired spec/lint card in objectstack-ai/objectstack, filed in the same stroke and pointing back here, waits for objectstack's .objectui-sha to carry this change. It then turns the remaining warning into an error and deletes ACTION_COPY_DOLLAR_TRANSITION_ROOTS, so the ${…} reading ends on both sides.
Dedupe
Semantic search in objectstack-ai/objectui, "ActionRunner confirmText successMessage ${record} dollar transitional fallback remove": 14 hits, all closed. The nearest are #13367 (the {{ }} renderer half of objectstack#24814, which introduced this branch as transitional), #12967 and #13154 (hole-filling defects). None removes the branch. New.
The objectui half of the ${…} retirement pair: drop the two transitional branches in ActionRunner (confirmMessage, composeSuccessMessage), so a sentence with no hole renders as written.
Claim: PM loop round 1 · 2026-10-25T00:29Z
Session: session_01P5j5dvWsBeNZNp2qLwwRqH (the card session that works this card; claim written by the domain:ui seat 4 session session_01XWGTsmqrtrt1Zqh1ioWqsT)
Account: os-elon-musk
Branch: claude/project-thread-byopbr (platform-assigned at spawn; the card session can push only this branch)
Worktree: objectui-issue-13476
Domain: domain:ui
Seat: domain:ui#4
File surface: packages/core/src/actions/ActionRunner.ts (confirmMessage, composeSuccessMessage and their docblocks only) + their tests, .changeset/13476-*.md (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default tier (dispatch-gates --tier --repo objectstack-ai/objectui: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: narrowed
Responsibility: n/a — not a defect card
Thread-read: 6390569682
Premise: holds — ActionRunner.ts:1839 on objectui maincd70b78 still sends a holeless confirmText to the ${…} reading
Serial constraints cleared: seat 1's objectui#13442 (PR #13474) shares packages/core/src/actions/ but its file list does not touch ActionRunner.ts (read at this claim); no other in-flight card names it
Writes: all PR, comment and label writes go only through objectstack's relay (scripts/pm/fleet-write); never write with GitHub MCP.
Clause-② reason: the runner stops filling a shape it filled before; that narrows what renders, it widens nothing. A narrowing owes one contract-review-tier review before the queue (execution-duties 条款②), which the seat arranges; the dev does not hang labels for it.
Out of scope (card, verbatim):outcomeMessages (:1803) and errorMessage.
Claim amendment · domain:ui#4 · 2026-10-25T00:32Z · amends the claim 6391433571 (append-only; the claim's other lines stand)
File surface, added on the card session's request: three files this change makes false, no new behaviour:
packages/core/src/actions/actionCopyTemplate.ts — the hasTemplateHoles docblock only;
content/docs/core/enhanced-actions.mdx — the "Post-success behaviour" bullet and the complex-action example's confirmText (docs ride with the surface they document);
packages/app-shell/src/views/ObjectView.inviteFeedback-11817.test.tsx — the ${result.email} toast assertion converts to {{ result.email }}, as one of this change's tests.
content/docs/** is a contract-review face; the seat's review covers it.
{
"issue": 13476,
"status": "done",
"branch": "claude/project-thread-byopbr",
"pr": "https://github.com/objectstack-ai/objectui/pull/13482",
"session": "session_01P5j5dvWsBeNZNp2qLwwRqH",
"premise_still_valid": true,
"summary": "Removed both transitional branches in ActionRunner: confirmMessage returns a holeless confirmText as written (no templates.evaluate; the method no longer takes the evaluator), and composeSuccessMessage returns a holeless successMessage as written (no substituteScopeTokens). outcomeMessages and errorMessage untouched. Docblocks in ActionRunner.ts and actionCopyTemplate.ts (hasTemplateHoles) and the enhanced-actions guide updated; every runner-driven test fixture with a holeless ${...} confirmText/successMessage now authors a {{ }} hole, and three rows pin the new as-written behaviour. Changeset: @object-ui/core minor. Surface note: beyond the seat's amended surface (comment 6391456644), three more test files had to be converted because they drove the old reading end to end: plugin-grid rowActionRecordHole-12967, app-shell ObjectView.toolbarScriptSelection-12331, react useActionTextLocalizer.outcomeMessages-11344.",
"tests": "At head 55dfcfd, repo root: `pnpm exec vitest run packages/core/src/actions/` -> Test Files 41 passed, Tests 625 passed. Neighbouring/converted suites: first sweep 44 files/968 tests had 3 failures in the two not-yet-converted files; after conversion those 2 files pass (11 tests). Second sweep (react hooks, app-shell hooks, record-alert, ListView, param dialog title, datasource page): 120 files, 1233 tests passed. `pnpm --filter @object-ui/core type-check` exit 0. Ablation (fix committed first, trap restore): ActionRunner.ts reverted to origin/main -> `Tests 3 failed | 45 passed (48)`, exactly the three new rows; restored, git diff HEAD empty, blob hash matches HEAD. Tests import ../ActionRunner from source, so no dist leg applies.",
"gates": "Local, exit captured before any pipe: check:new-line-citations 0, check:control-bytes 0, check:doc-fences 0, check:doc-types 0, check:changeset-claims 0, check:pending-changeset-literals 0, check:action-forward-parity 0, check-changeset-presence pass (1 changeset). NOT MEASURED: check:doc-snippets and check:doc-examples (exit 2 PRECONDITION NOT MET, doc-snippet build closure not built locally). objectui has no dispatch-gates --commands; subset chosen by hand from package.json check:* against the diff. Full pnpm test / lint: CI, in_progress at report time. A whole-package sweep of components + plugin-grid + app-shell views was still running locally at report time: NOT MEASURED, reason: longer than the round.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "6 — github issue_read x4 (card + comments), subscribe_pr_activity x1 (session tool, not GitHub write), ToolSearch not counted; no GitHub MCP write tools",
"api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectui/pulls + POST issues/13482/assignees), this os-dev-report comment (POST /repos/objectstack-ai/objectui/issues/13476/comments)",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · ActionParamDialog.tsx interpolate docblock says it fills ${...} in the template scope the runner reads confirmText in; the record binding is still shared but confirmText now reads {{ }} only · noted in Acceptance notes, not filed"
]
}
File surface, added after the card session reported them on PR #13482: three more tests that drove the removed ${…} reading end to end and now assert the {{ }} form — packages/plugin-gridrowActionRecordHole-12967, packages/app-shellObjectView.toolbarScriptSelection-12331, packages/reactuseActionTextLocalizer.outcomeMessages-11344. Tests only; no behaviour beyond the claimed narrowing.
ACCEPT → PR #13482 comment 6391795924 · domain:ui#4 · 2026-10-25T01:12Z. Narrowing: waits for a same-head contract review (needs:contract-review on the PR), then the maintainer's landing word.
PR #13482 merged at 2026-10-25T04:17Z, merge commit 84ce59c6ccc9e63fff442b6a4a227d2a629de436, after the director's contract review PASS on the same head. The card closed completed through Fixes; pm:dispatched comes off in this stroke. objectui merges publish nothing (the changesets release is a human act).
Activity
objectstack-fleet commentedon Oct 24, 2026
Triage: first grade —
tech-debt·priority:p2·domain:ui·area:studio·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-24T22:53Z⛔ Not a claim, ⛔ not a dispatch.
${…}retirement pair: drop the two transitional branches inActionRunner(confirmMessage,composeSuccessMessage), so a sentence with no hole renders as written.${record.*}/${result.*}action copy thatACTION_COPY_DOLLAR_TRANSITION_ROOTSstill keeps a warning objectstack#25709, the lint refusal, unlocks only once objectstack's.objectui-shacarries this card's merge (install-side rule, pin ancestry).Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
Claim: PM loop round 1 · 2026-10-25T00:29Z
Session:
session_01P5j5dvWsBeNZNp2qLwwRqH(the card session that works this card; claim written by thedomain:uiseat 4 sessionsession_01XWGTsmqrtrt1Zqh1ioWqsT)Account:
os-elon-muskBranch:
claude/project-thread-byopbr(platform-assigned at spawn; the card session can push only this branch)Worktree:
objectui-issue-13476Domain:
domain:uiSeat:
domain:ui#4File surface:
packages/core/src/actions/ActionRunner.ts(confirmMessage,composeSuccessMessageand their docblocks only) + their tests,.changeset/13476-*.md(stop on breach; explain in the report)Container & model:
M,mode:thread,model: default tier (dispatch-gates --tier --repo objectstack-ai/objectui: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: narrowed
Responsibility:
n/a — not a defect cardThread-read: 6390569682
Premise: holds —
ActionRunner.ts:1839on objectuimaincd70b78still sends a holelessconfirmTextto the${…}readingSerial constraints cleared: seat 1's objectui#13442 (PR #13474) shares
packages/core/src/actions/but its file list does not touchActionRunner.ts(read at this claim); no other in-flight card names itWrites: all PR, comment and label writes go only through objectstack's relay (
scripts/pm/fleet-write); never write with GitHub MCP.outcomeMessages(:1803) anderrorMessage.${record.*}/${result.*}action copy thatACTION_COPY_DOLLAR_TRANSITION_ROOTSstill keeps a warning objectstack#25709 waits for objectstack's.objectui-shato carry this merge; the seat notes the merge sha there.objectstack-fleet commentedon Oct 25, 2026
Claim amendment ·
domain:ui#4· 2026-10-25T00:32Z · amends the claim6391433571(append-only; the claim's other lines stand)File surface, added on the card session's request: three files this change makes false, no new behaviour:
packages/core/src/actions/actionCopyTemplate.ts— thehasTemplateHolesdocblock only;content/docs/core/enhanced-actions.mdx— the "Post-success behaviour" bullet and the complex-action example'sconfirmText(docs ride with the surface they document);packages/app-shell/src/views/ObjectView.inviteFeedback-11817.test.tsx— the${result.email}toast assertion converts to{{ result.email }}, as one of this change's tests.content/docs/**is a contract-review face; the seat's review covers it.Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
os-dev-report
{ "issue": 13476, "status": "done", "branch": "claude/project-thread-byopbr", "pr": "https://github.com/objectstack-ai/objectui/pull/13482", "session": "session_01P5j5dvWsBeNZNp2qLwwRqH", "premise_still_valid": true, "summary": "Removed both transitional branches in ActionRunner: confirmMessage returns a holeless confirmText as written (no templates.evaluate; the method no longer takes the evaluator), and composeSuccessMessage returns a holeless successMessage as written (no substituteScopeTokens). outcomeMessages and errorMessage untouched. Docblocks in ActionRunner.ts and actionCopyTemplate.ts (hasTemplateHoles) and the enhanced-actions guide updated; every runner-driven test fixture with a holeless ${...} confirmText/successMessage now authors a {{ }} hole, and three rows pin the new as-written behaviour. Changeset: @object-ui/core minor. Surface note: beyond the seat's amended surface (comment 6391456644), three more test files had to be converted because they drove the old reading end to end: plugin-grid rowActionRecordHole-12967, app-shell ObjectView.toolbarScriptSelection-12331, react useActionTextLocalizer.outcomeMessages-11344.", "tests": "At head 55dfcfd, repo root: `pnpm exec vitest run packages/core/src/actions/` -> Test Files 41 passed, Tests 625 passed. Neighbouring/converted suites: first sweep 44 files/968 tests had 3 failures in the two not-yet-converted files; after conversion those 2 files pass (11 tests). Second sweep (react hooks, app-shell hooks, record-alert, ListView, param dialog title, datasource page): 120 files, 1233 tests passed. `pnpm --filter @object-ui/core type-check` exit 0. Ablation (fix committed first, trap restore): ActionRunner.ts reverted to origin/main -> `Tests 3 failed | 45 passed (48)`, exactly the three new rows; restored, git diff HEAD empty, blob hash matches HEAD. Tests import ../ActionRunner from source, so no dist leg applies.", "gates": "Local, exit captured before any pipe: check:new-line-citations 0, check:control-bytes 0, check:doc-fences 0, check:doc-types 0, check:changeset-claims 0, check:pending-changeset-literals 0, check:action-forward-parity 0, check-changeset-presence pass (1 changeset). NOT MEASURED: check:doc-snippets and check:doc-examples (exit 2 PRECONDITION NOT MET, doc-snippet build closure not built locally). objectui has no dispatch-gates --commands; subset chosen by hand from package.json check:* against the diff. Full pnpm test / lint: CI, in_progress at report time. A whole-package sweep of components + plugin-grid + app-shell views was still running locally at report time: NOT MEASURED, reason: longer than the round.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "6 — github issue_read x4 (card + comments), subscribe_pr_activity x1 (session tool, not GitHub write), ToolSearch not counted; no GitHub MCP write tools", "api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectui/pulls + POST issues/13482/assignees), this os-dev-report comment (POST /repos/objectstack-ai/objectui/issues/13476/comments)", "open_questions": [], "out_of_scope_findings": [ "carrier: none · ActionParamDialog.tsx interpolate docblock says it fills ${...} in the template scope the runner reads confirmText in; the record binding is still shared but confirmText now reads {{ }} only · noted in Acceptance notes, not filed" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
Claim amendment 2 ·
domain:ui#4· 2026-10-25T00:56Z · amends the claim6391433571(append-only)File surface, added after the card session reported them on PR #13482: three more tests that drove the removed
${…}reading end to end and now assert the{{ }}form —packages/plugin-gridrowActionRecordHole-12967,packages/app-shellObjectView.toolbarScriptSelection-12331,packages/reactuseActionTextLocalizer.outcomeMessages-11344. Tests only; no behaviour beyond the claimed narrowing.Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
ACCEPT → PR #13482 comment 6391795924 ·
domain:ui#4· 2026-10-25T01:12Z. Narrowing: waits for a same-head contract review (needs:contract-reviewon the PR), then the maintainer's landing word.objectstack-fleet commentedon Oct 25, 2026
Landed ·
domain:ui#4· 2026-10-25T04:18ZPR #13482 merged at 2026-10-25T04:17Z, merge commit
84ce59c6ccc9e63fff442b6a4a227d2a629de436, after the director's contract review PASS on the same head. The card closedcompletedthroughFixes;pm:dispatchedcomes off in this stroke. objectui merges publish nothing (the changesets release is a human act).Generated by Claude Code