ccppccpp home

Profiles

Vercel AI SDK 7

AI SDK 7 (ai 7.0.x) code without v4–v6 APIs or invented exports, models and options, with owned streams, tools, approvals and telemetry, and package-manager-owned dependencies; any app shape, framework or runtime. Rule IDs BASE/CLI/MIG/ARCH/TOOL/OUT/RUN/UI/SEC/QA.

Set this profile

ccpp cpo profile set ai-sdk-7

Inside Claude Code, prefix the command with ! to run it in the session. Downloading a profile needs a Builder or Team plan; listing them does not.

Policies

101 policies, grouped by what they guard.

Secrets & private data 6

Credentials, keys and personal data stay out of files, logs, commands and the conversation.

  • ai-arch07-shared-credentials

    ARCH-07 · Per-request credentials never land in module-level singletons or process.env, where concurrent requests share them

  • ai-sec01-public-credentials

    SEC-01 · Provider and service keys never reach a browser bundle or the source: no public-prefixed key variables, no keys in client components, no literal apiKey

  • ai-sec08-logged-payloads

    SEC-08 · Logs never dump raw request/response bodies, headers, credentials or whole generation results

  • ai-sec09-devtools-capture

    SEC-09 · DevTools captures (.devtools/) never enter version control

  • ai-sec09-devtools

    SEC-09 · AI SDK DevTools run only in local development: devToolsMiddleware/DevToolsTelemetry sit behind a development guard

  • ai-tool05-credentials-to-model

    TOOL-05, SEC-01 · Credentials never become model-visible: no secret fields in a tool inputSchema, no secret environment values in prompts or instructions

Authentication & authorization 4

Who may do what, from roles, privileges and permissions to CSRF, CORS and verified tokens.

  • ai-sec03-sensitive-tools

    SEC-03 · A call that gives the model destructive or sensitive local tools sets an explicit toolApproval policy

  • ai-sec04-approval-replay

    SEC-04 · Approvals replayed from client-submitted history are protected against forgery (approval signing or trusted server-side state)

  • ai-sec05-provider-tool-approval

    SEC-05 · toolApproval is not relied on for provider-executed tools (webSearch, codeExecution, computer use…): the provider runs them

  • ai-tool02-identity-inputs

    TOOL-02 · Identity, tenancy and permission come from trusted context, not from fields of a tool's model-filled inputSchema

Untrusted input 3

Requests, downloads and tool output are validated before they reach SQL, a shell, eval or a deserializer.

  • ai-sec02-untrusted-instructions

    SEC-02, MIG-12 · Request data never becomes privileged instructions: no request values in instructions/system, no system messages from submitted history

  • ai-sec12-unsandboxed-exec

    SEC-12 · Tools never run commands or code chosen by the model outside a real sandbox (declared in trustedExecutionPaths)

  • ai-ui05-unvalidated-messages

    UI-05 · UI messages parsed from a request or storage are validated (validateUIMessages/safeValidateUIMessages) before conversion when tools are in play

Network & TLS 2

Outbound data, verified certificates, destinations taken from requests and services exposed to others.

  • ai-sec10-custom-download

    SEC-10 · A custom experimental_download keeps the SDK's URL, redirect and credential-origin protections

  • ai-sec11-mcp-lifecycle

    SEC-11 · MCP clients are closed on completion, failure and cancellation, and keep the default redirect: 'error'

Weakened checks 2

Suppressions, disabled lint or CI steps and relaxed strictness need a reason or the user's approval.

  • ai-cli08-suppressions

    CLI-08, QA-01 · AI SDK code gets no new @ts-ignore, @ts-nocheck or @ts-expect-error: type errors from an SDK mismatch are fixed, not muted

  • ai-qa06-exceptions

    QA-06 · A project override that disables or weakens an ai-sdk-7 rule records its reason, owner and expiry (x-reason, x-owner, x-expires)

Type safety 3

No escapes from the type checker (any, unchecked casts, non-null assertions) and explicit contracts.

  • ai-arch05-type-escapes

    ARCH-05 · SDK types are inferred from their definitions (tools, schemas, agents, UI messages), not re-declared or forced with any/double casts

  • ai-mig18-tool-context

    MIG-18 · Tools that read context declare it with contextSchema instead of casting a shared context object

  • ai-mig23-chunk-narrowing

    MIG-23 · onChunk narrows chunk.type before reading variant fields: in v7 it also receives lifecycle, finish, error and abort parts

Error handling 6

Failures are propagated or handled, never swallowed or turned into fake success.

  • ai-arch08-fabricated-tools

    ARCH-08 · Production tools never return random demo values, placeholders or a swallowed failure dressed as success

  • ai-out02-partial-effects

    OUT-02 · Irreversible effects wait for the completed, validated output; partial structured output only feeds previews

  • ai-out03-output-fallbacks

    OUT-03 · A missing or invalid structured output is handled, never replaced by an empty object or a cast passed off as success

  • ai-run03-stream-errors

    RUN-03 · Streaming failures are handled where the stream is consumed (onError, error parts, iteration), not by a try/catch around streamText

  • ai-run07-retried-tool-effects

    RUN-07 · A generation with tools is not replayed by an outer retry: its tool side effects would run again

  • ai-tool10-fabricated-results

    TOOL-10 · Pending tool calls are resolved by real outputs, errors or approvals, never by writing output-available states by hand

Async & concurrency 4

Owned tasks, awaited promises, preserved cancellation and no blocking on event loops.

  • ai-arch07-shared-state

    ARCH-07 · Conversation, approval and cache state is not kept in module-level collections that every request and user shares

  • ai-run02-tool-abort

    RUN-02 · Tool I/O receives the call's abort signal, so cancelling a generation also cancels its tools

  • ai-run04-abort-cleanup

    RUN-04 · Cleanup and persistence that must happen on cancellation run in onAbort (and onError), not only in onEnd, which an aborted stream never calls

  • ai-run05-unconsumed-streams

    RUN-05, ARCH-06 · Every SDK promise and stream has an owner: awaited, returned, consumed or deliberately supervised, never dropped or hidden behind void

Performance & resource bounds 3

Timeouts, bounded retries and fan-out, reused clients, closed resources, no N+1 queries.

  • ai-run01-budgets

    RUN-01 · With requireBudgets, generation calls state or inherit maxOutputTokens and a timeout or abort signal

  • ai-run01-timer-race

    RUN-01 · Generation deadlines use the SDK timeout or an abort signal, not Promise.race against a timer that leaves the call running

  • ai-run06-outer-retries

    RUN-06 · Retries use the SDK budgets (maxRetries before streaming, streamRetries after it starts), not an outer loop or retry helper around the whole call

Architecture & boundaries 5

Declared layers and dependency directions, no import cycles, small modules, explicit dependencies.

  • ai-arch01-mixed-responsibilities

    ARCH-01 · One growing file does not mix transport, AI orchestration, inline tool execution and persistence

  • ai-arch02-import-cycles

    ARCH-02 · A new runtime import in AI SDK code does not close an import cycle (bounded walk of relative imports)

  • ai-arch04-pass-through-wrappers

    ARCH-04 · No pass-through wrappers around SDK calls: a function that only forwards its arguments to generateText/streamText adds no behaviour

  • ai-base05-file-size

    BASE-05 · AI SDK source files do not grow past maxLines (existing debt is judged by its growth only; 0 turns it off)

  • ai-base05-function-size

    BASE-05 · Functions of AI SDK code (handlers, tools' execute, callbacks) stay under maxFunctionLines when they are added or grown

Language idioms 3

The conventions of the language that keep code predictable for its readers.

  • ai-cli07-manual-stream-protocol

    CLI-07 · Streams to clients use the SDK helpers (UI message / text stream responses), not hand-written SSE framing or raw provider HTTP calls

  • ai-tool06-manual-tool-loop

    TOOL-06 · Multi-step tool use relies on stopWhen/prepareStep or ToolLoopAgent, not a hand-written loop re-calling generation with tool results

  • ai-tool07-step-budget

    TOOL-07, OUT-04 · generateText/streamText with tools state their step budget: their default is one step (ToolLoopAgent's is 20), too few for tools then an answer or output

HTTP & APIs 3

Request and response contracts, schemas, status codes, error bodies and published API surfaces.

  • ai-out01-manual-parsing

    OUT-01 · Structured results come from output: Output.object/array/choice, not JSON.parse or regexes over generated text

  • ai-out05-schema-portability

    OUT-05 · Tool and output schemas use constructs that convert to JSON Schema (no dates, functions, bigints, maps or transforms)

  • ai-tool03-tool-description

    TOOL-03 · Every tool() states what it does and its limits in a description

Framework conventions 7

Routing, server and client boundaries, hooks and plugins the way the framework expects them.

  • ai-ui02-chat-options

    UI-02 · useChat is configured through its transport (DefaultChatTransport or a custom ChatTransport), not the removed api/body/headers/maxSteps/initialMessages options

  • ai-ui03-chat-helpers

    UI-03 · Code reads only what the installed useChat returns: no input, handleInputChange, handleSubmit, append, reload, isLoading or data helpers

  • ai-ui04-message-content

    UI-04 · UI messages render their parts (text, files, tools, reasoning, data), not the removed content or toolInvocations fields

  • ai-ui06-original-messages

    UI-06 · A UI message stream whose end callback persists the chat receives originalMessages, so message IDs and tool states stay stable

  • ai-ui07-static-transport-body

    UI-07 · Changing values (tokens, model, options) reach requests per call or through transport functions, not a static body or headers object

  • ai-ui08-tool-output

    UI-08 · Client-side tool results go through addToolOutput with the tool name and call ID, never awaited inside onToolCall

  • ai-ui09-resume-stop

    UI-09 · A resumable chat (resume: true) cancels server work through an explicit, authorized endpoint; stop() alone only detaches the client

Versions & deprecated APIs 19

Code matches the installed version, without removed, renamed or deprecated APIs.

  • ai-base01-session-context

    BASE-01/02/06/08 · At session start, Claude learns the resolved ai and @ai-sdk/* versions, whether these v7 rules apply, and where the version-matched docs and sources are

  • ai-base02-remote-docs

    BASE-02 · Fetching AI SDK docs from the web while the installed package ships its own version-matched docs points Claude to them

  • ai-base02-unknown-exports

    BASE-02/06, MIG-01/02/03, UI-04, QA-02 · AI SDK imports name only exports and subpaths the installed package declares (no removed, invented or un-prefixed experimental names)

  • ai-base07-esm

    BASE-07 · AI SDK packages are consumed as ESM: no require() of ai or @ai-sdk/*, no SDK import in a CommonJS file

  • ai-base07-node-version

    BASE-07 · Where the project declares a Node.js version (engines, .nvmrc, .node-version, Dockerfile, CI), it meets AI SDK 7's Node.js 22

  • ai-mig03-removed-options

    MIG-03/18 · Generation calls and agents pass no option the installed AI SDK removed (maxSteps, maxTokens, experimental_output, experimental_context…), local spreads included

  • ai-mig04-deprecated-imports

    MIG-01/04/05/08, UI-01, MIG-24 · New imports avoid deprecated AI SDK aliases (stepCountIs, Experimental_Agent, generateObject, Vue Chat, GoogleGenerativeAI*…)

  • ai-mig04-deprecated-options

    MIG-04/05/22, UI-01 · SDK calls use current option names (instructions, telemetry, include, onEnd, onStepEnd, onStart…), checked per owning API

  • ai-mig06-result-members

    MIG-06/07/13/15/16 · Generation results are read through current members: stream, partialOutputStream, usage, finalStep, responseMessages and standalone response helpers

  • ai-mig09-unawaited-conversion

    MIG-09 · convertToModelMessages is awaited (or returned): its promise is never passed as the messages array

  • ai-mig10-prepare-step-carry-forward

    MIG-10/11 · A prepareStep that overrides instructions or messages for some steps restores them for the others: v7 carries overrides forward

  • ai-mig14-accumulated-results

    MIG-14 · Loops with effects over toolCalls/toolResults/content/files read finalStep or steps, since top-level values now accumulate every step

  • ai-mig17-usage-fields

    MIG-17 · Token usage is read from the v7 fields (inputTokenDetails/outputTokenDetails), not the removed cachedInputTokens, reasoningTokens, promptTokens or Anthropic cacheCreationInputTokens

  • ai-mig19-needs-approval

    MIG-19 · Approval moves from the deprecated tool-level needsApproval to call or agent toolApproval

  • ai-mig20-content-parts

    MIG-20 · Message and tool-result content uses current part shapes: file parts with mediaType, no removed media parts or mimeType

  • ai-mig20-legacy-parts

    MIG-20 · New content parts use the canonical file shape instead of the deprecated image part and image-*/file-* tool-output variants

  • ai-mig22-bodies

    MIG-22 · Code that reads request or response bodies asks for them with include (bodies are excluded by default in v7)

  • ai-tool01-input-schema

    TOOL-01 · Function tools declare inputSchema (not the v4 parameters), and tool calls/results are read as input/output, not args/result

  • ai-tool09-model-output

    TOOL-09 · toModelOutput takes its options object ({ toolCallId, input, output }), and messages are converted with the same tools

Configuration 4

Settings read once at a boundary, validated, with units and without unsafe defaults.

  • ai-arch03-repeated-model-config

    ARCH-03 · A model ID and its settings have one owner per use case, not a literal repeated across calls

  • ai-mig21-reasoning-overlap

    MIG-21 · A call sets portable reasoning or provider-specific reasoning options, deliberately, not both by accident

  • ai-run08-sampling

    RUN-08 · A call sets temperature or topP, not both, and does not treat temperature 0 as determinism

  • ai-run09-model-ids

    RUN-09, BASE-02 · Model IDs are ones the installed provider package declares (or the project allows), not retired or remembered ones

Logging & observability 2

Structured logs, bounded metric labels, no debug prints left in production code.

  • ai-sec06-telemetry-migration

    SEC-06 · OpenTelemetry tracing in v7 goes through @ai-sdk/otel registered once; a telemetry flag or a tracer option alone collects no spans

  • ai-sec07-telemetry-capture

    SEC-07 · Registering telemetry decides what it records: inputs/outputs are captured by default, and allowlisted context fields carry no credential

Dependencies & toolchain 19

Packages change through the package manager, lockfiles stay consistent and the project's tools are used.

  • ai-base01-install-specs

    BASE-01, CLI-04 · Installs keep ai on this profile's major, never give @ai-sdk/* packages ai's major, and add no removed SDK package

  • ai-base01-manifest-ranges

    BASE-01, CLI-04 · package.json keeps ai on this profile's major and gives @ai-sdk/* packages their own majors

  • ai-cli01-init-over-project

    CLI-01 · No package-manager initializer (npm/pnpm/yarn/bun init, npm create) runs in a directory that already has a package.json

  • ai-cli01-package-manager

    CLI-01 · Dependencies are installed with the project's package manager (packageManager field, lockfile)

  • ai-cli01-second-lockfile

    CLI-01/08 · No second lockfile next to another package manager's lockfile

  • ai-cli02-hand-edited-lockfile

    CLI-02 · Lockfiles are written by the package manager only (no hand edit, no script rewriting them)

  • ai-cli02-hand-written-manifest

    CLI-02 · A new package.json without dependencies is initialized with the package manager

  • ai-cli02-manual-dependency-edit

    CLI-02 · Dependencies change through the package manager (add/remove/update), never by editing package.json by hand

  • ai-cli02-new-manifest

    CLI-02 · A new package.json comes from the package-manager initializer (or a generator), and gets its dependencies from the package manager

  • ai-cli02-package-manager-call

    Records the tool calls that run a package manager (they may rewrite package.json and lockfiles; CLI-02/04, CLI-06)

  • ai-cli02-stale-lockfile

    CLI-02 · A turn that changes package.json dependencies also updates the lockfile next to it (once per stop)

  • ai-cli03-version-lookups

    CLI-02 · Registry version lookups are not a step before installing

  • ai-cli03-version-pins

    CLI-03 · Packages are installed by name: no guessed exact version, no @latest, no --save-exact without a reason

  • ai-cli04-resolved-version

    CLI-04 · After an install naming ai or an @ai-sdk/* package, the resolved ai is still on this profile's major

  • ai-cli05-unused-integrations

    CLI-05 · A turn adds only the AI SDK packages its code uses: no speculative UI adapter, provider, MCP, DevTools or telemetry install (once per stop)

  • ai-cli06-codemod-run

    CLI-06 · Records official AI SDK codemod runs, and asks for the diff to be reviewed afterwards (codemods do not cover every change)

  • ai-cli06-manual-migration

    CLI-06 · Repetitive manual migration of names an official codemod renames points to the codemod (from the third file of the session)

  • ai-cli08-forced-peers-config

    CLI-08 · No configuration that forces peers or pins AI SDK packages behind the package manager's back (.npmrc legacy peers, overrides/resolutions)

  • ai-cli08-forced-resolution

    CLI-08 · Dependency conflicts are fixed, not forced: no --force/--legacy-peer-deps installs, no lockfile deletion to make them pass

Tests 2

Tests assert behavior, stay deterministic and are not removed or skipped silently.

  • ai-qa02-test-mocks

    QA-02 · Tests use the installed ai/test mocks (V4 at this baseline) instead of older mock versions or module-mocking the SDK

  • ai-qa05-live-model-tests

    QA-05 · Automated tests do not call live, paid models: provider models and gateway IDs stay out of tests unless they are explicit integration tests

Completion evidence 4

A turn ends with its checks run and passing; claims of success need proof after the last edit.

  • ai-qa01-check-ledger

    QA-01 · Records successful type-check, build, lint and test commands (the evidence the end-of-turn check reads)

  • ai-qa01-unchecked-turn

    QA-01 · A turn that changed AI SDK code runs the project's type-check, build or tests after the last change (once per stop)

  • ai-qa01-write-ledger

    QA-01 · Counts the AI SDK code Claude changes in a turn (the end-of-turn check compares it with the last successful check)

  • ai-turn-baseline

    Records the work tree when a prompt starts: the baseline of the AI SDK end-of-turn checks (CLI-02, CLI-05, QA-01)