All skills
mblode avatar

/ax-audit

@57eb304
by Matthew Blodemblode/agent-skills136 stars
12

Audits agentic products for tool parity, authority, approval payloads, recovery, and trust using 27 rules and a ship verdict. Use when asked for an "AX audit", to review an agent approval flow, or whether an agent can operate the product. For human-facing API ergonomics use dx-audit; for ordinary UI use ui-design.

Use this Skill: https://skilld.dev/gh/mblode/agent-skills/ax-audit

This session only. Nothing lands on disk.

referencesframework-signals.md

≈2.1k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Framework Signals

Where the things the rules audit live in the four stacks agentic code is usually written in. Rule greps carry the common spellings; this file carries the rest, plus the spec defaults the rules lean on. When a grep misses in code that plainly does the thing, look the concept up here before recording unknown. Identifiers are current for AI SDK 7, MCP 2025-11-25, and the Claude Agent SDK as of the sources listed at the end.

Contents

Approval gate

Stack Where the gate lives What the rules read off it
AI SDK 7 toolApproval on streamText or ToolLoopAgent: per tool one of 'not-applicable', 'approved', 'denied', 'user-approval', or a function of ({ toolCall, tools, messages }). 'user-approval' emits a tool-approval-request part and pauses; the client answers with useChat().addToolApprovalResponse({ id, approved, reason }). needsApproval on tool() is the deprecated v6 spelling and still works A catch-all returning 'approved' is control-no-approval-gate Scenario A; 'user-approval' on read-only tools is Scenario B. A renderer that branches on part.state === 'approval-requested' and prints the tool name without part.input is control-thin-approval-payload. experimental_toolApprovalSecret HMAC-binds an approval to its call id and input, so a replayed approval cannot authorize different arguments
MCP 2025-11-25 The host. The spec says there SHOULD always be a human in the loop able to deny tool invocations, and clients SHOULD show tool inputs to the user before calling the server. Servers describe stakes through annotations: readOnlyHint (default false), destructiveHint (default true), idempotentHint (default false), openWorldHint (default true). Clients MUST treat annotations as untrusted unless the server is trusted The defaults already fail closed; a host that relaxes them from an untrusted server's hints is comm-no-approval-gate. In Claude Code hosts a server can force a prompt with _meta["anthropic/requiresUserInteraction"]
Claude Agent SDK Six steps in order: PreToolUse hooks, deny rules, ask rules, permissionMode, allow rules, then canUseTool(toolName, input, { suggestions, signal }) returning { behavior: 'allow', updatedInput } or { behavior: 'deny', message }. Modes: default, dontAsk, acceptEdits, bypassPermissions, plan, auto A bare allowedTools entry, acceptEdits, or bypassPermissions resolves a call before canUseTool runs, so a check that exists only in the callback is off the path for every pre-approved tool (comm-no-approval-gate); a PreToolUse hook runs before every other step and is on it. dontAsk plus an explicit allowlist is a standing boundary for comm-unrequested-action-no-consent; the notice half still has to exist

Progress and completion

Stack Step-level events Terminal signal
AI SDK 7 Server: createUIMessageStream with writer.write({ type: 'data-<name>', ... }), createUIMessageStreamResponse, result.toUIMessageStream(). Persistent parts reach the client in message.parts; parts written with transient: true reach it only through the onData callback. Client: status is 'submitted', 'streaming', 'ready', or 'error'; isLoading no longer exists finishReason on the result; the loop stops by stopWhen (isStepCount(n) in v7, stepCountIs before). A default ToolLoopAgent stops at 20 steps
Anthropic Messages API Streaming events per content block stop_reason: end_turn, tool_use, max_tokens, stop_sequence, pause_turn, refusal, model_context_window_exceeded. pause_turn means resend and continue, max_tokens means truncated; a loop that treats either as done fails comm-no-completion-signal
AG-UI RUN_STARTED, STEP_STARTED and STEP_FINISHED, TEXT_MESSAGE_START/CONTENT/END, TOOL_CALL_START/ARGS/END/RESULT, STATE_SNAPSHOT and STATE_DELTA (JSON Patch) RUN_FINISHED with an outcome, or RUN_ERROR
MCP notifications/progress keyed by the request's progressToken; long calls can negotiate tasks through execution.taskSupport The tools/call result

Tool results

Stack Success shape Failure shape
MCP content[] plus structuredContent conforming to the tool's outputSchema; servers MUST conform, clients SHOULD validate isError: true on the result, with actionable text the model can retry on. The schema says: if not set, this is assumed to be false (the call was successful). Error prose in content with no isError is parity-unstructured-tool-output
AI SDK 7 tool({ inputSchema, outputSchema, execute }); toModelOutput shapes what the model sees versus what the UI keeps Throw, or a discriminated union in the output. UI part states: output-available, output-error, output-denied
Anthropic tool-writing guidance Return meaningful, human-readable identifiers and offer a response_format of concise or detailed Errors steer: say what to do next, not just what failed

Escape hatch

Stack Where it lives
AI SDK 7 useChat().stop() aborts the client fetch only. The route passes req.signal as abortSignal to streamText, and each tool's execute reads abortSignal from its options, or the server finishes the loop after Stop. resumeStream reconnects only when the server kept the run
Claude Agent SDK query.interrupt(); the signal handed to canUseTool is an AbortSignal. A PreToolUse hook returning defer persists the session so an approval can wait past process exit
AG-UI RUN_FINISHED carrying an interrupt outcome

Handshake and clarification

Stack Primitive
Claude Agent SDK AskUserQuestion (1 to 4 questions, 2 to 4 options each) routed through canUseTool; plan mode sends every write to the callback
MCP elicitation/create in form mode (flat primitives, exposed to the client) or url mode (credentials and payments, never through the client). Answered accept, decline, or cancel; only accept means proceed, and treating cancel as accept fails comm-no-intent-handshake
AI SDK 7 addToolApprovalResponse({ id, approved: false, reason }) carries the user's correction back into the loop

Agent-rendered UI

Stack Shape
MCP Apps Servers publish ui:// resources with mimeType: text/html+mcp and link them from a tool's _meta["ui/resourceUri"]; hosts render them in a sandboxed iframe and talk over JSON-RPC on postMessage, with consent for UI-initiated tool calls. Rendered controls count as direct manipulation for control-over-conversational and as phase-specific UI for context-no-adaptive-canvas
AI SDK 7 data-<name> parts rendered by a component chosen on part.type; a chat that renders only text parts has the tool and step states in hand and drops them

Sources

Source: SKILL.md on GitHub

No alerts13d3 checks · Risk SAFE
  • Gen Agent Trust Hub13d

    The skill is a specialized auditing framework for AI agent products, focusing on architectural integrity and user trust. It uses standard shell tools for static analysis of codebases. The analysis found no malicious behavior, obfuscation, or data exfiltration risks.

  • Socket13d

    No alerts

  • Snyk13d

    Risk: LOW · No issues

Signed by skilld at 57eb304. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 4 hours ago.

Activeupdated 2 weeks ago

README badge

README badge for mblode/agent-skills/ax-audit