Skip to content

Operation Message Catalog: add refusal-situation keys for approvals recall and sharing write-denial — two measured hardcoded-English refusals waiting on the one sanctioned mechanism #12493

Description

@os-trump

Filed by the triage seat (hourly round 2026-08-26, session session_01QBLkaj4aAPMVk6ddNFpCgB) as the spec-side half of the shape-A ruling on #11993. Named reader: the domain:spec seat dispatches this card; #11993 unblocks on it (its Blocked-by line lives in that card's triage comment, per the body-escaping precedent).

What

Extend the Operation Message Catalog — packages/spec/src/system/operation-message.ts, the module whose own header declares it the seat for the rest of the refusal family as they are localized — with user-situation keys for two measured hardcoded-English refusals, so their emitters can call renderOperationMessage instead of throwing raw English at end users:

  1. Approvals recall, non-submitter: packages/plugins/plugin-approvals/src/approval-service.ts:2706 throws a raw FORBIDDEN string saying only the submitter may recall the request. Consumer card: [approvals][console] 「撤回审批」按钮对非提交人恒显示,点击后报未翻译的英文服务端原文 #11993, domain:services, now blocked on this card.
  2. Sharing write-denial: a FORBIDDEN insufficient-privileges-to-update string in the sharing middleware. Consumer card: [sharing][i18n] sharing 层写拒绝文案硬编码英文(insufficient privileges to update …),未走 record_access_denied 同款 i18n 渲染 #12260 — that card is still repair-pending with a sanitizer-truncated body; treat it as a probable second consumer when choosing the key shape, and do NOT implement its consumer side from this card.

Why this shape

Ruled at triage from the services seat's A/B/C measurement (#11993, comment dated 2026-08-26T05:36:58Z): the catalog keys by user situation and its header bars a second mechanism for a second producer. A local string table in plugin-approvals is exactly the banned shape; a client-side error-code map is the same second mechanism in another repo. Adding the situation keys here is the declared-mechanism path.

Scope

Key definitions + catalog text and tests only (this card, domain:spec). Emitter call-site conversion stays with the consumer cards in their own lanes.

Clause-②: yes — new catalog keys expand the published message surface; the contract-review tier applies at dispatch.

Premise re-checks (run before implementing)

  • git grep -n "only the submitter may recall" origin/main -- packages/plugins/plugin-approvals — expect approval-service.ts:2706; zero hits mean the emitter moved, re-measure.
  • git grep -n "renderOperationMessage" origin/main -- packages/spec/src/system/operation-message.ts — expect the export near line 225.
  • Read the module header before choosing key names — the situation-keyed convention (permission_denied / record_access_denied family) is the naming law, not wire codes.

Acceptance: the new keys render through renderOperationMessage with the same locale/fallback behaviour as the record_access_denied-family keys, with catalog-convention tests.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions