agents-lab

Local-first lab for reusable AI-agent primitives and the curated pi-stack.

View on GitHub

Operator confirmation signal

Status: design boundary for local-first control-plane safety.

Problem

Some destructive/protected confirmations happen before or around tool execution, but the local guard/monitor path must not infer authorization from free text. A monitor-visible string such as operator-confirmation-evidence: decision=match is spoofable unless it is backed by trusted structured details from the runtime.

Current bounded evidence:

Required signal shape

A trusted confirmation signal must bind to the pending action:

type OperatorConfirmationActionFingerprint = {
  actionKind: "destructive" | "protected";
  toolName: string;
  path?: string;
  scope?: string;
  payloadHash?: string;
};

The runtime evidence envelope must remain non-authorizing by itself:

type TrustedOperatorConfirmationEvidence = OperatorConfirmationActionFingerprint & {
  id: string;
  origin: "runtime-ui-confirm" | "operator-contract-review";
  trusted: true;
  createdAtIso: string;
  expiresAtIso: string;
  consumedAtIso?: string;
};

Consumers must enforce:

Implementation channel decision

For the local stack, the first implementation channel should be guard-owned report-only unless an explicit later task chooses wrapper or upstream PR work. resolveOperatorConfirmationImplementationChannelPlan encodes this boundary, and operator_confirmation_implementation_channel_plan exposes it as a read-only runtime planning tool after reload:

Acceptable integration paths

1. Guard-owned dialog

When a first-party guard owns the ctx.ui.confirm call, it can immediately call recordTrustedOperatorConfirmationUiDecision and append a structured audit entry. This is the current safe local path used by guardrails-core read guards.

2. Wrapper signal

If a wrapper owns or observes the confirmation before tool_call, it should emit a structured operator-confirmation-evidence envelope with hidden/display-false metadata and preserve the full details object for the consumer. The consumer must call consumeTrustedOperatorConfirmationAuditEnvelope; it must not parse free-text content.

3. Upstream PR/design

If confirmation is owned by upstream pi before extension tool_call handlers run, the preferred upstream shape is either:

Either option must preserve exact binding, TTL/single-use semantics, and no operational authorization by default.

Rejected integration paths

Current implementation references