mirror of
https://github.com/qwibitai/nanoclaw.git
synced 2026-07-09 18:57:08 +08:00
de7e596aa5
One hold-record contract over the existing tables and ONE click-authorization rule for every approval stack (hub: engineering/discovery/guarded-actions-decisions + engineering/requirements/guarded-actions, phase 1). - ApproverEligibility (exclusive | admins-of-scope) + mayResolve() replace the three divergent click-auth copies; a2a named approvers stay exclusive, sender/channel keep named-or-admin — the hold row encodes which. - pending_approvals gains eligibility / approver_scope / dedup_key (migration 019, with backfills); requestApproval stamps agent_group_id, supports sessionless holds, per-card options, dedup keys, and blast-radius scope. - Sender admission folds onto the primitive (action 'sender_admit'): addMember + routeInbound replay on approve; pending_sender_approvals and its card/click code are deleted. - Channel registration + OneCLI keep their flows, adopt eligibility/mayResolve; their terminal resolutions (click / expiry / boot sweep) announce through notifyApprovalResolved (outcome: approve|reject|expire|sweep, session nullable). - Absorbed defect fixes (intentional decision-outcome changes): D1 — global-blast holds (roles grant …) require an owner/global-admin click; D4 (approver half) — channel-registration approvers come from the global chain, not getAllAgentGroups()[0]. Everything else is behavior-preserving: card text/buttons, approver DM walk, reject-with-reason, OneCLI two-button card, oa- short ids, expiry timer and startup sweep are untouched; durable a2a holds stay durable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
72 lines
2.9 KiB
TypeScript
72 lines
2.9 KiB
TypeScript
import { registerResource } from '../crud.js';
|
|
|
|
registerResource({
|
|
name: 'approval',
|
|
plural: 'approvals',
|
|
table: 'pending_approvals',
|
|
description:
|
|
'Pending approval — in-flight approval cards waiting for an admin response. Created by requestApproval() (self-mod install_packages/add_mcp_server) and OneCLI credential approval flow. Rows are deleted after the admin approves/rejects or the request expires.',
|
|
idColumn: 'approval_id',
|
|
columns: [
|
|
{
|
|
name: 'approval_id',
|
|
type: 'string',
|
|
description: 'Unique approval identifier (also used as the card questionId).',
|
|
},
|
|
{
|
|
name: 'session_id',
|
|
type: 'string',
|
|
description: 'Session that requested the approval. Null for OneCLI credential approvals.',
|
|
},
|
|
{
|
|
name: 'request_id',
|
|
type: 'string',
|
|
description: 'Original request identifier (OneCLI request UUID or same as approval_id).',
|
|
},
|
|
{
|
|
name: 'action',
|
|
type: 'string',
|
|
description:
|
|
'Action type — matches the registered approval handler (e.g. install_packages, add_mcp_server, onecli_credential).',
|
|
},
|
|
{ name: 'payload', type: 'json', description: 'JSON payload carried through to the approval handler.' },
|
|
{ name: 'created_at', type: 'string', description: 'Auto-set.' },
|
|
{ name: 'agent_group_id', type: 'string', description: 'Originating agent group.' },
|
|
{ name: 'channel_type', type: 'string', description: 'Channel the approval card was delivered on.' },
|
|
{ name: 'platform_id', type: 'string', description: 'Platform chat ID the card was delivered to.' },
|
|
{
|
|
name: 'platform_message_id',
|
|
type: 'string',
|
|
description: 'Platform message ID of the delivered card (for editing on expiry).',
|
|
},
|
|
{ name: 'expires_at', type: 'string', description: 'When this approval expires (OneCLI gateway TTL).' },
|
|
{
|
|
name: 'status',
|
|
type: 'string',
|
|
description: 'Current status.',
|
|
enum: ['pending', 'approved', 'rejected', 'expired'],
|
|
},
|
|
{ name: 'title', type: 'string', description: 'Card title shown to the admin.' },
|
|
{ name: 'options_json', type: 'json', description: 'Card button options as JSON array.' },
|
|
{
|
|
name: 'approver_user_id',
|
|
type: 'string',
|
|
description: 'Named approver (exclusive) or the admin the card was delivered to (admins-of-scope).',
|
|
},
|
|
{
|
|
name: 'eligibility',
|
|
type: 'string',
|
|
description: 'Who may resolve: only the named approver, or the admin chain of the anchoring group.',
|
|
enum: ['exclusive', 'admins-of-scope'],
|
|
},
|
|
{
|
|
name: 'approver_scope',
|
|
type: 'string',
|
|
description: "Blast radius: 'global' holds require an owner or global admin to resolve.",
|
|
enum: ['group', 'global'],
|
|
},
|
|
{ name: 'dedup_key', type: 'string', description: 'In-flight dedup key (e.g. sender admission per chat+sender).' },
|
|
],
|
|
operations: { list: 'open', get: 'open' },
|
|
});
|