mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 05:16:23 -06:00
feat(approvals): typed approval scope summaries on channel cards (#130116)
* feat(approvals): typed approval scope summaries on channel cards Approval owners can attach a closed ApprovalScope union (message-send, payment, external-post) describing an action's blast radius. The gateway sanitizes it once at the producer boundary, the core view model renders a Scope metadata row so Slack/Discord/Google Chat cards show it unchanged, shared text builders cover Telegram/WhatsApp/Signal/iMessage/Matrix, and the durable presentation carries it additively for operator surfaces. Scope is display-only, never authorization; missing scope keeps today's cards. * fix(approvals): emit native ApprovalScope union and clamp recipient previews Name the three scope variants as registered protocol schemas so the Swift generator emits the ApprovalScope discriminated union the presentation structs reference, and commit the regenerated GatewayModels.swift. Clamp recipient previews to the declared recipientCount at the sanitize boundary so a count of 1 with 2 previews can no longer render inconsistently. Addresses both ClawSweeper findings on #130116. * refactor(approvals): extract text sanitizer to break the exec-approvals import cycle check:architecture flagged approval-scope joining the exec-approvals SCC through exec-approval-command-display. Move the self-contained display sanitizer into a leaf module (exec-approval-text-sanitize) with no exec-approvals imports and migrate all sanitize importers; command-display keeps only the payload-typed command/preview resolver. * chore(plugin-sdk): ratchet public surface budgets down after sanitizer extraction The approval display sanitizers left the publicly reachable SDK graph when they moved to the exec-approval-text-sanitize leaf: exports 4343 -> 4338, callable exports 2582 -> 2578. Shrink-only budget pin.
This commit is contained in:
committed by
GitHub
parent
8a101ed5a5
commit
99a02bf115
@@ -88,6 +88,65 @@ Write prompt text for the person who will approve the action:
|
||||
- `timeoutMs` defaults to 120000 (2 minutes) and is capped at 600000 (10
|
||||
minutes) regardless of the requested value.
|
||||
|
||||
## Declare approval scope
|
||||
|
||||
Set `requireApproval.scope` when your plugin knows the consequences of an
|
||||
operation. Scope is typed, optional, and display-only: it helps reviewers
|
||||
understand the action but never grants permission or changes the approval
|
||||
decision. The plugin declaring the approval supplies these facts; channels never
|
||||
infer scope from commands, titles, or message text.
|
||||
|
||||
For an email to three external recipients, include the destination, total
|
||||
recipient count, an optional preview, and the audience:
|
||||
|
||||
```typescript
|
||||
requireApproval: {
|
||||
title: "Send customer update",
|
||||
scope: {
|
||||
kind: "message-send",
|
||||
target: "email",
|
||||
recipientCount: 3,
|
||||
recipients: ["alice@example.com", "bob@example.com"],
|
||||
audience: "external",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
For a payment, provide the exact decimal amount as a string, its currency, and
|
||||
the payee or payment system:
|
||||
|
||||
```typescript
|
||||
requireApproval: {
|
||||
title: "Pay invoice",
|
||||
scope: {
|
||||
kind: "payment",
|
||||
amount: "49.99",
|
||||
currency: "EUR",
|
||||
target: "Stripe",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
For an external post, identify its destination and declare its visibility:
|
||||
|
||||
```typescript
|
||||
requireApproval: {
|
||||
title: "Publish announcement",
|
||||
scope: {
|
||||
kind: "external-post",
|
||||
target: "github",
|
||||
visibility: "public",
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Message audiences can be `internal` or `external`; external-post visibility can
|
||||
be `public` or `restricted`. Recipient previews contain at most five identities.
|
||||
All strings are sanitized and bounded before display: targets and recipient
|
||||
identities are limited to 128 characters, payment amounts to 40, and currencies
|
||||
to 12. If sanitization would exceed a bound, OpenClaw omits the scope while
|
||||
preserving the normal approval prompt.
|
||||
|
||||
## Decision behavior
|
||||
|
||||
OpenClaw creates a pending approval with a `plugin:` ID, delivers it to the
|
||||
|
||||
Reference in New Issue
Block a user