Skip to content
docsv0.12.0

VerificationTool

Exposes {@see HumanVerifier} as two tools instead of one (D8 / T089, split in tool-runtime 0.3): `request_verification` opens a verification and returns its `request_id`; `resolve_verification` resolves a pending one with a `grant`/`reject` decision. Replaces the single combined verification tool tool-runtime 0.2 shipped, which mixed both phases into one schema with conditional fields ("omit `decision` to request") and a name that read as though the caller could grant its own request. The split gives each phase a clean, non-overlapping schema — `request_verification` has no `decision`/`principal` fields at all; `resolve_verification` requires them — and, as a direct consequence of being separate tools, lets a host's policy allow `request_*` broadly while restricting `resolve_*` to specific principals (the "policy dividend" — see the package README's Verification section for a worked example using {@see self::$resolveScopes} / {@see \Milpa\ValueObjects\Tooling\ToolOptions::$scopes}). Both tools register with `requiresConfirmation: false` — same reasoning as 0.2's single-tool bypass, now applying to each half independently: `handleRequest()` / `handleResolve()` together already ARE the two-phase confirmation protocol, so stacking the registry's generic step-4 confirm-token gate on top would recreate the exact double-gate choreography 0.2 killed. See {@see \Milpa\ToolRuntime\PolicyGate::requiresConfirmation()} for the one channel-level exception (`require_confirmation_for_mutating`, e.g. the built-in `telegram` policy) that still gates any `mutating: true` tool regardless of this flag.

VerificationTool::__construct()

public function __construct(Milpa\ToolRuntime\Verification\HumanVerifier $verifier, array $resolveScopes = []):

Parameters

Parameters of __construct()
NameTypeDescription
$verifierMilpa\ToolRuntime\Verification\HumanVerifier
$resolveScopeslist<string>Scopes required to call `resolve_verification` (empty = open to anyone who can reach the registry, matching the pre-split default). `request_verification` never takes a scopes parameter — it is always open; that asymmetry IS the policy dividend the split buys.

VerificationTool::register()

public function register(Milpa\Interfaces\Tooling\ToolRegistryInterface $registry): void

Register `request_verification` and `resolve_verification` on the given registry.

Parameters

Parameters of register()
NameTypeDescription
$registryMilpa\Interfaces\Tooling\ToolRegistryInterface

VerificationTool::handleRequest()

public function handleRequest(array $args): Milpa\ToolRuntime\ToolResult

Handle a `request_verification` call: open a verification request for `subject`. Always opens a new request and returns {@see ToolResult::confirmation()} carrying its `request_id` — this tool never resolves a verdict itself, only {@see handleResolve()} does.

Parameters

Parameters of handleRequest()
NameTypeDescription
$argsarray<string, mixed>

VerificationTool::handleResolve()

public function handleResolve(array $args): Milpa\ToolRuntime\ToolResult

Handle a `resolve_verification` call: resolve a pending verification by `request_id`. `subject` is optional here. When the caller echoes it back, the reconstructed {@see VerificationRequest} carries the true subject. When omitted, this builds the request via {@see VerificationRequest::forResolution()} — `subject = null`, identified purely by `id` — instead of fabricating a value from `request_id` (tool-runtime 0.3's behavior, dropped in favor of core 0.4's resolution seam: a listener on `verification.granted`/`verification.rejected` no longer sees a fake, opaque `subject` that silently diverges from the one carried on `verification.requested` for the same correlation id). The success MESSAGE below still falls back to `request_id` for readability — that is tool-runtime-owned formatting, not the VO's `subject`.

Parameters

Parameters of handleResolve()
NameTypeDescription
$argsarray<string, mixed>