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 }}
Repository navigation
Action param dialog: an action key for the submit button's verb, falling back to Confirm #27944
Filing gate: ③ triage-directed. The order on #27434 said: triage rows 1–7, TAKE what is ui-only, CARD the rest. The card thread measured each row on origin/maine41642dd (report 6515174308, out_of_scope_findings).
Reach: any action with params, opened from the record header, a list row's ⋮ menu or the toolbar. HotCRM send_email, log_call, log_meeting.
Reader who acts: domain:spec first (the key), then domain:ui (the dialog reads it).
Duplicate search: search_issues "action param dialog submit button label verb instead of Confirm" → only closed cards about the confirm dialog's title and danger variant (#26580, #26781), not this.
Observed
The param dialog's footer always reads actionDialog.confirm ("Confirm"). An action that collects params cannot say its own verb ("Send", "Log Call"). packages/spec/src/ui/action.zod.ts has no such key, and ActionParamDialog reads t('actionDialog.confirm').
Wanted
An optional I18nLabel key on ActionSchema for the dialog's submit label (translation path _actions.NAME.KEY, resolved like description). The spec half: the key, the translation-reference lint (validate-translation-references) and the docs page. The ui half (a follow-up domain:ui card once the key ships): both param-collection handlers pass it, and ActionParamDialog draws it, with "Confirm" as the fallback.
Claim: PM loop round 3 · 2026-10-30T12:29Z
Session: session_017ihL2fi9zfJhUTubyJYb6V
Account: marchtian
Branch: claude/issue-27944-action-submit-label
Worktree: objectstack-issue-27944
Domain: domain:spec
Seat: domain:spec#4
Ruling-ref: maintainer 「可以开始派发 p3」 (2026-10-30T12:23Z), lifting the p3 hold; the card's filing gate ③ (triage-directed, order on #27434, report 6515174308)
File surface: packages/spec/src/ui/action.zod.ts (one optional I18nLabel key on ActionSchema for the param dialog's submit label, translation path _actions.NAME.KEY, resolved like description), the translation-reference lint (validate-translation-references in packages/lint), the action docs page, tests, regenerated spec artefacts, changeset (@objectstack/spec minor; @objectstack/lint patch if it moves). The ui half (ActionParamDialog reading it, falling back to actionDialog.confirm) is the card's own follow-up domain:ui card, filed by this PR's dev (stop on breach; explain in the report)
Container & model: S, mode:subagent, model: TIER_DEFAULT (opus) — the quota-exhaustion exemption (claude-fable-5-1 answered HTTP 429; maintainer 「你没有fable了,使用 opus开发完之后等契约复审」), effort: medium
Clause-②: yes (widening)
Metadata-protocol: added
Responsibility: an action that collects params always shows "Confirm" on its dialog's submit button and cannot say its own verb ("Send", "Log Call") | an optional translated label key on the action, read by the param dialog with "Confirm" as the fallback | every action with params opened from the record header, a row menu or the toolbar (HotCRM send_email, log_call, log_meeting)
Thread-read: none
Premise: holds — on 549203d040action.zod.ts carries confirmText / successMessage copy slots (L841–L947) and no submit-label key
Serial constraints cleared: no open PR touches action.zod.ts or validate-translation-references (open PR file lists read just before this claim)
{
"issue": 27944,
"status": "done",
"branch": "claude/issue-27944-action-submit-label",
"pr": "https://github.com/objectstack-ai/objectstack/pull/28188",
"head": "734502240e",
"session": "session_017ihL2fi9zfJhUTubyJYb6V",
"premise_still_valid": true,
"summary": "ActionSchema gains optional I18nLabel submitText (param dialog submit button label): blank refused, refused without a non-empty params, aliases submitLabel/confirmLabel. Translation slot at _actions.NAME.submitText and globalActions.NAME.submitText; translateAction overlays it only for an action with params. validate-translation-references reports translation-target-unknown (error) for a submitText translation under a param-less action. Liveness planned+authorWarn; form ledger omit row; ui SPEC_ACTION_KEYS lists it. Console half filed as #28158.",
"tests": "spec vitest src/ui src/system: 229 files/7942 tests, 1 fail (form reconciliation wanted the key) -> omit row added, rerun 2 files/94 passed; spec typecheck exit 0; lint 2 files/332 passed; metadata-protocol pin 18 passed (closure built); ui actionKeys.pin 19 passed; spec check:generated exit 0 after --fix; all at 734502240e",
"gates": "dispatch-gates --commands: 109 derived; --ran: 109 accounted, 105 run, 4 NOT-MEASURED (exit 3: check:skill-examples, check:dual-build-cjs-loads, check:i18n-walk-parity, check:lean-entry-closure; unbuilt workspace), 0 UNRUN; 104 exit 0; 1 exit 1: pnpm --dir ui exec vitest run scripts/ (3/4903: two 15s timeouts on the shared box, one needs @objectstack/client dist; none reads a changed file; read as NOT MEASURED, CI Test UI decides). CI check-runs: in_progress at report time.",
"line_budget": "21 files, +457 / -13 (generated included)",
"dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm",
"deviations": [
"key name submitText, not the proposed submitLabel: object-form's submitText is the live protocol word for submit-button copy; submitLabel is retired twice (element:form prop, page component-copy translation key) with refusals pointing to submitText. submitLabel and confirmLabel are aliases. Maintainer approves the name in the PR",
"added an authoring refusal of submitText without a non-empty params (ADR-0078, mirror of the confirmText-beside-params refusal); the translateAction overlay and the lint leg use the same condition",
"files outside the claim's named surface, each forced by a gate or by the card's 'resolved like description': packages/spec/src/system/translation.zod.ts, packages/spec/src/system/i18n-resolver.ts, packages/spec/liveness/action.json, packages/spec/src/system/metadata-form-zod-reconciliation.test.ts (omit row), packages/metadata-protocol/src/protocol.meta-types-degenerate-derivation.test.ts (count pin 48->49), ui/packages/core/src/actions/actionKeys.ts (SPEC_ACTION_KEYS pin), content/docs/ui/translations.mdx; changeset for @object-ui/core patch",
"not touched though the disabledReason precedent did: packages/cli i18n-extract (outside claimed surface) and the Studio action form row (recorded as a planned omit row instead, the page.print precedent)",
"PR body begins with the two session attribution lines, then Fixes #27944 (the order's _common rule); os-dev.md says Fixes on the first line",
"local spec test scope narrowed to src/ui + src/system; test:repo not run locally (CI)",
"no Fable review, per order; PR left as draft"
],
"files_changed": [
".changeset/27944-action-keys-submit-text.md",
".changeset/27944-action-submit-text.md",
".changeset/27944-lint-submit-text-translation.md",
"content/docs/protocol/objectui/actions.mdx",
"content/docs/references/data/object.mdx",
"content/docs/references/kernel/metadata-plugin.mdx",
"content/docs/references/system/translation.mdx",
"content/docs/references/ui/action.mdx",
"content/docs/ui/translations.mdx",
"packages/lint/src/validate-translation-references.test.ts",
"packages/lint/src/validate-translation-references.ts",
"packages/metadata-protocol/src/protocol.meta-types-degenerate-derivation.test.ts",
"packages/spec/authorable-surface/ui.json",
"packages/spec/liveness/action.json",
"packages/spec/liveness/state-counts/action.md",
"packages/spec/src/system/i18n-resolver.ts",
"packages/spec/src/system/metadata-form-zod-reconciliation.test.ts",
"packages/spec/src/system/translation.zod.ts",
"packages/spec/src/ui/action-submit-text.test.ts",
"packages/spec/src/ui/action.zod.ts",
"ui/packages/core/src/actions/actionKeys.ts"
],
"mcp_calls": "2: mcp__github__search_issues x2 (read-only dedupe). No write tool.",
"api_writes": "3, all via the fleet-write relay (repository_dispatch): issue_create -> #28158; pr_create -> #28188; this os-dev-report comment on #27944. Plus git push (not REST).",
"open_questions": [
{
"question": "Key name: submitText or submitLabel?",
"options": [
"A submitText (as shipped; submitLabel + confirmLabel alias to it)",
"B submitLabel (one mechanical rename commit; submitText becomes the alias)"
],
"recommendation": "A, one word for submit-button copy across the protocol, and submitLabel is a retired spelling"
},
{
"question": "Does the os i18n extract half ride #28158 or its own card?",
"options": [
"A add to #28158",
"B own card",
"C widen this PR"
],
"recommendation": "A, it is two lines and a test beside the console read"
}
],
"out_of_scope_findings": [
"class: none (gap in this card's own key) · reach: named producer: os i18n extract (packages/cli/src/utils/i18n-extract.ts#collectExpectedEntries) does not scaffold _actions.NAME.submitText · carrier: seat (proposed #28158) · noted, not filed",
"class: none · bulkActionDefs' confirmLabel is a plain string, not an I18nLabel · carrier: none · noted in PR Acceptance notes only"
],
"follow_up_card": 28158
}
Landed · 2026-10-31T06:25Z · PR #28188 merged by the queue at 2026-10-31T06:25Z as a7bdac495a; the card closed by Fixes. This seat strips pm:dispatched in the same act. The key is submitText (the platform's existing word for the button; submitLabel and confirmLabel are aliases that rename onto it), approved by 田騏. Contract review: PASS 6537832125, delta PASSes 6538202172 and 6539741066 on the landed head. It is planned until the console's param dialog reads it (#28158, which also carries the os i18n extract half); skills/docs follow-up is #28190.
Activity
objectstack-fleet commentedon Oct 30, 2026
domain:spec#4 · marchtian · session_017ihL2fi9zfJhUTubyJYb6V
Claim: PM loop round 3 · 2026-10-30T12:29Z
Session:
session_017ihL2fi9zfJhUTubyJYb6VAccount:
marchtianBranch:
claude/issue-27944-action-submit-labelWorktree:
objectstack-issue-27944Domain:
domain:specSeat:
domain:spec#4Ruling-ref: maintainer 「可以开始派发 p3」 (2026-10-30T12:23Z), lifting the p3 hold; the card's filing gate ③ (triage-directed, order on #27434, report 6515174308)
File surface:
packages/spec/src/ui/action.zod.ts(one optionalI18nLabelkey onActionSchemafor the param dialog's submit label, translation path_actions.NAME.KEY, resolved likedescription), the translation-reference lint (validate-translation-referencesinpackages/lint), the action docs page, tests, regenerated spec artefacts, changeset (@objectstack/specminor;@objectstack/lintpatch if it moves). The ui half (ActionParamDialogreading it, falling back toactionDialog.confirm) is the card's own follow-updomain:uicard, filed by this PR's dev (stop on breach; explain in the report)Container & model:
S,mode:subagent,model: TIER_DEFAULT(opus) — the quota-exhaustion exemption (claude-fable-5-1answered HTTP 429; maintainer 「你没有fable了,使用 opus开发完之后等契约复审」),effort: mediumClause-②: yes (widening)
Metadata-protocol: added
Responsibility: an action that collects params always shows "Confirm" on its dialog's submit button and cannot say its own verb ("Send", "Log Call") | an optional translated label key on the action, read by the param dialog with "Confirm" as the fallback | every action with
paramsopened from the record header, a row menu or the toolbar (HotCRMsend_email,log_call,log_meeting)Thread-read: none
Premise: holds — on
549203d040action.zod.tscarriesconfirmText/successMessagecopy slots (L841–L947) and no submit-label keySerial constraints cleared: no open PR touches
action.zod.tsorvalidate-translation-references(open PR file lists read just before this claim)objectstack-fleet commentedon Oct 30, 2026
domain:spec#4 · marchtian · session_017ihL2fi9zfJhUTubyJYb6V
os-dev-report
{ "issue": 27944, "status": "done", "branch": "claude/issue-27944-action-submit-label", "pr": "https://github.com/objectstack-ai/objectstack/pull/28188", "head": "734502240e", "session": "session_017ihL2fi9zfJhUTubyJYb6V", "premise_still_valid": true, "summary": "ActionSchema gains optional I18nLabel submitText (param dialog submit button label): blank refused, refused without a non-empty params, aliases submitLabel/confirmLabel. Translation slot at _actions.NAME.submitText and globalActions.NAME.submitText; translateAction overlays it only for an action with params. validate-translation-references reports translation-target-unknown (error) for a submitText translation under a param-less action. Liveness planned+authorWarn; form ledger omit row; ui SPEC_ACTION_KEYS lists it. Console half filed as #28158.", "tests": "spec vitest src/ui src/system: 229 files/7942 tests, 1 fail (form reconciliation wanted the key) -> omit row added, rerun 2 files/94 passed; spec typecheck exit 0; lint 2 files/332 passed; metadata-protocol pin 18 passed (closure built); ui actionKeys.pin 19 passed; spec check:generated exit 0 after --fix; all at 734502240e", "gates": "dispatch-gates --commands: 109 derived; --ran: 109 accounted, 105 run, 4 NOT-MEASURED (exit 3: check:skill-examples, check:dual-build-cjs-loads, check:i18n-walk-parity, check:lean-entry-closure; unbuilt workspace), 0 UNRUN; 104 exit 0; 1 exit 1: pnpm --dir ui exec vitest run scripts/ (3/4903: two 15s timeouts on the shared box, one needs @objectstack/client dist; none reads a changed file; read as NOT MEASURED, CI Test UI decides). CI check-runs: in_progress at report time.", "line_budget": "21 files, +457 / -13 (generated included)", "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm", "deviations": [ "key name submitText, not the proposed submitLabel: object-form's submitText is the live protocol word for submit-button copy; submitLabel is retired twice (element:form prop, page component-copy translation key) with refusals pointing to submitText. submitLabel and confirmLabel are aliases. Maintainer approves the name in the PR", "added an authoring refusal of submitText without a non-empty params (ADR-0078, mirror of the confirmText-beside-params refusal); the translateAction overlay and the lint leg use the same condition", "files outside the claim's named surface, each forced by a gate or by the card's 'resolved like description': packages/spec/src/system/translation.zod.ts, packages/spec/src/system/i18n-resolver.ts, packages/spec/liveness/action.json, packages/spec/src/system/metadata-form-zod-reconciliation.test.ts (omit row), packages/metadata-protocol/src/protocol.meta-types-degenerate-derivation.test.ts (count pin 48->49), ui/packages/core/src/actions/actionKeys.ts (SPEC_ACTION_KEYS pin), content/docs/ui/translations.mdx; changeset for @object-ui/core patch", "not touched though the disabledReason precedent did: packages/cli i18n-extract (outside claimed surface) and the Studio action form row (recorded as a planned omit row instead, the page.print precedent)", "PR body begins with the two session attribution lines, then Fixes #27944 (the order's _common rule); os-dev.md says Fixes on the first line", "local spec test scope narrowed to src/ui + src/system; test:repo not run locally (CI)", "no Fable review, per order; PR left as draft" ], "files_changed": [ ".changeset/27944-action-keys-submit-text.md", ".changeset/27944-action-submit-text.md", ".changeset/27944-lint-submit-text-translation.md", "content/docs/protocol/objectui/actions.mdx", "content/docs/references/data/object.mdx", "content/docs/references/kernel/metadata-plugin.mdx", "content/docs/references/system/translation.mdx", "content/docs/references/ui/action.mdx", "content/docs/ui/translations.mdx", "packages/lint/src/validate-translation-references.test.ts", "packages/lint/src/validate-translation-references.ts", "packages/metadata-protocol/src/protocol.meta-types-degenerate-derivation.test.ts", "packages/spec/authorable-surface/ui.json", "packages/spec/liveness/action.json", "packages/spec/liveness/state-counts/action.md", "packages/spec/src/system/i18n-resolver.ts", "packages/spec/src/system/metadata-form-zod-reconciliation.test.ts", "packages/spec/src/system/translation.zod.ts", "packages/spec/src/ui/action-submit-text.test.ts", "packages/spec/src/ui/action.zod.ts", "ui/packages/core/src/actions/actionKeys.ts" ], "mcp_calls": "2: mcp__github__search_issues x2 (read-only dedupe). No write tool.", "api_writes": "3, all via the fleet-write relay (repository_dispatch): issue_create -> #28158; pr_create -> #28188; this os-dev-report comment on #27944. Plus git push (not REST).", "open_questions": [ { "question": "Key name: submitText or submitLabel?", "options": [ "A submitText (as shipped; submitLabel + confirmLabel alias to it)", "B submitLabel (one mechanical rename commit; submitText becomes the alias)" ], "recommendation": "A, one word for submit-button copy across the protocol, and submitLabel is a retired spelling" }, { "question": "Does the os i18n extract half ride #28158 or its own card?", "options": [ "A add to #28158", "B own card", "C widen this PR" ], "recommendation": "A, it is two lines and a test beside the console read" } ], "out_of_scope_findings": [ "class: none (gap in this card's own key) · reach: named producer: os i18n extract (packages/cli/src/utils/i18n-extract.ts#collectExpectedEntries) does not scaffold _actions.NAME.submitText · carrier: seat (proposed #28158) · noted, not filed", "class: none · bulkActionDefs' confirmLabel is a plain string, not an I18nLabel · carrier: none · noted in PR Acceptance notes only" ], "follow_up_card": 28158 }Reported at 2026-10-30T15:52Z.
objectstack-fleet commentedon Oct 31, 2026
domain:spec#4 · marchtian · session_017ihL2fi9zfJhUTubyJYb6V
Landed · 2026-10-31T06:25Z · PR #28188 merged by the queue at 2026-10-31T06:25Z as
a7bdac495a; the card closed byFixes. This seat stripspm:dispatchedin the same act. The key issubmitText(the platform's existing word for the button;submitLabelandconfirmLabelare aliases that rename onto it), approved by 田騏. Contract review: PASS 6537832125, delta PASSes 6538202172 and 6539741066 on the landed head. It isplanneduntil the console's param dialog reads it (#28158, which also carries theos i18n extracthalf); skills/docs follow-up is #28190.