Sonar AI — User Manual

The missing AI agent for NetSuite: what it does, how it stays safe, and how to get the most out of it.
Baseline: v1.7.1 Generated 2026-08-29 Account: TD3016323 (Production)
How this manual was built This is a living document generated from a direct survey of the Sonar AI source as of version 1.7.1. Facts about tool names, settings, error codes, and defaults are drawn from the actual code, not from general assumptions about what an "AI agent" typically does. Where a feature is still being designed rather than shipped, this manual says so explicitly instead of describing it as if it exists.
Who this is for Written for the NetSuite administrator or power user driving Sonar directly — the person who wants to know not just what button to click but what Sonar can and cannot do, and why. If you hand Sonar to less technical colleagues, Parts 1–2 stand alone as an onboarding guide; Part 5 is reference material you can skip until you need it.

Table of contents

Part 1

Getting Started

1. What Is Sonar AI

Sonar AI is an AI agent embedded directly in NetSuite as a Suitelet. It is not a separate integration or an external chatbot bolted onto NetSuite — it runs inside your account, as a page you navigate to like any other NetSuite screen, and every action it takes executes under your own NetSuite login, subject to your role's actual permissions. There is no service account, no elevated privilege, and no bypass of NetSuite's own security model.

How it's built

The architecture has three parts:

The core loop You ask a question in plain English. The model decides which NetSuite "tools" (SuiteQL, record operations, file operations, etc.) would answer it, calls them, reads the results, and either calls more tools or replies to you. Every tool call is visible in the conversation as a card you can expand. Nothing happens silently.

What makes it different from asking a generic AI chatbot about NetSuite

A generic chatbot can only guess at your account's schema, your customizations, and your data. Sonar actually queries your live account — it runs real SuiteQL against your real tables, loads your real records, and reads your real custom fields. When it doesn't know something (a field id, a script's behavior, a saved search's filters) the house rule is to look it up rather than guess, because a wrong-but-plausible field id is the single most common way an AI agent silently gets something wrong in NetSuite.

2. First Launch

Terms of Use

The first time you open Sonar AI (or after a Terms of Use version bump), you'll see an acceptance screen. It explains, in plain terms, that Sonar uses third-party LLM APIs (Anthropic, OpenAI, Google, Mistral, xAI, Cohere, or any OpenAI-compatible provider you configure) to plan and execute actions, that those actions can create/modify/delete records based on the model's reasoning, and that you are responsible for reviewing destructive operations before approving them and for choosing which provider receives your data. Acceptance is recorded in your browser's localStorage.

License / subscription check

Sonar checks a subscription/license status on load, cached for about 12 hours so it doesn't re-check on every page view. If your subscription needs attention, a modal offers a Refresh action.

Choosing a provider and model

Sonar needs an AI model to run. On first use, open Settings (gear icon) and either:

ProviderKey required?Current default model (new installs)
AnthropicYesclaude-sonnet-4-6
OpenAIYesgpt-5.6-terra
xAIYesgrok-4.6
MistralYesmistral-medium-latest
OpenAI-compatible (custom base URL)Usuallynone — you supply base URL + model
Cohere (NS-bundled)Non/a — governed by NetSuite's own LLM allowance
Google Gemininot implemented — slot exists in Settings but returns an error if selected; see §20.
Switching models later You never need to dig back into Settings to switch models day to day — use the model chip in the header, or type /model claude-opus-5 (or any model id) in the chat box. See §18 for the full slash command list.

Theme

Sonar defaults to your OS-level light/dark preference; a toggle in the header switches it manually.

3. The Chat Interface

Composing messages

What you see per turn

Managing conversations

Part 2

Core Capabilities

4. Asking Questions About Your Data

Sonar has several distinct ways to answer a data question, and it's worth knowing which one it reaches for:

SuiteQL (runSql)

Direct, Oracle-flavored SQL against NetSuite's query engine. This is the workhorse for custom slicing, joins across tables, and anything a saved search or standard report can't express. Results over ~10KB are paginated/truncated automatically with a clear marker; Sonar refines the query rather than guessing when that happens.

Standard NetSuite reports

When you ask for something that has an actual NetSuite report — an Income Statement, Balance Sheet, A/R Aging, Comparative Income Statement, and so on — Sonar uses the real, NS-rendered report rather than reconstructing the numbers itself in SQL. The flow is: reportsList (find the report) → reportInfo (discover its exact filter fields and valid values) → reportRun (execute it, with named period presets like Q1TFY or custom date ranges).

If a report run fails Sonar will surface the actual NetSuite error to you and ask how to proceed — it will not silently fall back to a SQL approximation of the report. That substitution can look plausible while being subtly wrong (different rounding, different period logic), so the fallback only happens if you explicitly ask for it.

Saved searches

savedSearchList finds a search by name, savedSearchInspect (advanced tool group) shows its filters/columns without running it, and savedSearchRun executes it — optionally with filter/column overrides.

Record inspection

recordJson / recordXml load a record's full state (all fields, all sublists). recordTypeDescribe answers "what fields does this record type even have" by loading a live sample. fieldDescribe drills into one field — its type, whether it's really mandatory, and (for select fields) its valid options, resolved live from the account rather than guessed.

5. Getting Files Out

Two distinct mechanisms, and Sonar defaults to the one that leaves less clutter:

Artifacts (the default)

artifactCreate produces an ephemeral, downloadable file held as a browser Blob — it appears as a clickable chip on the tool call and in a footer Artifacts panel, but is never written to the NetSuite File Cabinet. It lives only for the current browser session. This is the default for "give me this as a download" requests (CSV exports, generated reports, JSON dumps).

Bulk SQL exports: sqlToArtifact

When you want raw query results (potentially thousands of rows) dumped straight to a file, sqlToArtifact runs the query and formats the file entirely server-side — the rows never pass through the AI model as tokens. This is dramatically faster than the alternative (query, then re-emit every row as model output) for anything beyond a trivial row count, and it's what Sonar reaches for whenever a bulk data dump is requested.

File Cabinet writes (when it should persist)

fileCreate writes a real, persistent file into NetSuite's File Cabinet. Sonar reaches for this only when the file genuinely needs to live in NetSuite — Suitelet source being deployed, integration assets, reference documents meant to outlive the browser session (like this manual).

6. Making Changes Safely

The dry-run → diff → approval workflow

recordCreate, recordUpdate, recordSubmitFields, recordDelete, and their bulk equivalents all accept dryRun: true. A dry run computes and returns exactly what would change (a before→after field diff, or a delete summary) without saving anything. For any update you haven't spelled out field-by-field yourself, Sonar dry-runs first, shows you the diff as a table, and only proceeds after you approve — the diff shown to you always comes from the dry-run result itself, never from Sonar's own description of what it intends to do.

The approval-gate modal

Destructive or modifying tool calls surface an approval modal before executing, with an "always allow" option for that specific tool if you want to stop being asked for routine, low-risk operations within a session.

What Sonar will never do

7. Tool Groups

To keep Sonar's default toolset small and easy to reason about, most core capabilities (SuiteQL, reports, record CRUD, files, artifacts, search, web fetch, skills) are always available. More specialized capabilities are organized into deferred tool groups that Sonar loads on demand with toolGroupLoad as soon as a task points to them — you'll typically never notice this happening except as a brief "N tools now callable" note.

GroupWhat it unlocks
customizeCreate/modify custom fields, custom lists, custom record types.
rolesInspect and modify roles and permissions.
scriptingEvaluate SuiteScript ad hoc, list/toggle script deployments, read execution logs, resolve/invoke RESTlets, trigger workflows.
bulkBulk record create/update/delete (capped at 100 records per call).
transactionsRecord transforms (e.g. Sales Order → Invoice/Fulfillment), voiding, GL impact inspection.
commsSend email; create task / event / phone-call records.
advancedRecord XML export, saved-search inspection without running it, page/UI scraping, browser-side fetch, installed-bundle listing, file delete/copy/move, folder creation.
Loading a group never changes what's allowed Tool groups only control what's advertised to the AI model — not what's permitted. The permission mask (§8) and your NetSuite role are the actual security boundary, enforced independently at the moment a tool call is dispatched.
Part 3

Safety & Governance

8. The Permission Mask

Sonar runs in one of three modes, controlled by a shield icon in the header:

ModeEffect
StandardAll tools available (still subject to your NetSuite role's actual permissions and the safeguards elsewhere in this Part).
No-deletesBlocks recordDelete, recordDeleteBulk, and fileDelete. Dry-run previews of deletes are still allowed — you can see what would be deleted without the mode letting it happen.
Read-onlyBlocks every mutating tool. Sonar can look at anything, change nothing.
This is a structural boundary, not a request the AI can honor or ignore The mask is enforced at the tool-dispatch layer, independent of the AI model's own judgment. If a blocked call is attempted, it fails with AGENT_MASK_BLOCKED before it ever executes. Critically, the mode can only be changed by you, clicking the shield toggle in the header — there is no way to ask Sonar in chat to widen its own permissions, by design.

Widening the mode (e.g., Read-only → Standard) shows a confirmation before taking effect.

9. Production Delete Confirmation

On top of the permission mask, real deletes (recordDelete, recordDeleteBulk, fileDelete) in a production account require an additional flag, confirmedByUser: true, or they are rejected with CONFIRMATION_REQUIRED. The intended workflow is always: dry-run → show you exactly what would be deleted → get your explicit approval of that specific delete → only then re-issue with the flag set.

What this gate actually is — honestly This flag is currently set by the AI model itself, after it judges that you gave genuine, specific approval in the conversation. It is not a token the interface independently mints when you click a button. The safeguard today is: (1) the model is instructed never to set it without real, specific approval, and (2) every use of the flag is written verbatim to the audit trail (§10), so a false claim would be forensically visible after the fact. This is a detective control, not a preventive one — a structural hardening of this gate (a UI-minted, single-use approval token) is a documented improvement idea, not yet built.

Practical implication: always read the dry-run diff Sonar shows you before saying yes to a delete. Your "yes" is the actual control here.

10. The Audit Trail

Every mutating tool call — success, error, dry-run, or blocked — is logged automatically to NetSuite's script execution log with the title prefix SONAR_AUDIT. This logging happens in the dispatch layer, not by the AI model choosing to log something, so it can't be skipped or talked around.

What's recorded

Each entry's detail field is JSON:

{ ts, user: { id, name, role }, tool, outcome, errorCode, mask, purpose, target, args }

outcome is one of success / error / dryrun / blocked. args is clipped (~3.5KB) rather than storing arbitrarily large payloads.

How to look it up

The built-in Sonar Activity viewer shows the last 100 entries. For anything deeper, query directly:

SELECT date, title, detail FROM scriptnote
WHERE title LIKE 'SONAR_AUDIT%'
ORDER BY date DESC
These entries cannot be deleted through any Sonar tool The audit trail is written by the runtime, not the model, and there is no Sonar tool capable of removing a scriptnote audit entry — it is immutable from inside the product.

11. Privacy Mode

Privacy Mode lets you run analyses on customers, vendors, employees, and contacts without their identities ever entering the AI model's context — useful for clustering, segmentation, or any workflow where the underlying pattern matters more than the names attached to it.

The strictness dial

A header toggle (👤) cycles through three states:

StateBehavior
OffNo redaction. Normal operation.
ONEntity names are tokenized before reaching the model.
STRICTEverything in ON, plus several free-text tools are blocked outright (e.g. fileGet, fileGetLines, fileGrep, scriptExecutionLogs, recordXml) because their result shape can't be safely redacted.

How it works

Fail-closed, not fail-open If the redaction dictionary isn't ready yet (e.g., right after a page reload, or immediately after a record was created/updated and the dictionary is invalidated), Sonar withholds the result rather than risk sending unredacted data. You'll see a clear "not ready yet" response rather than a silent leak.

A tightening-only privacySpecApply tool lets you describe additional protections in plain language (extra never-grant columns, extra sensitive terms, extra blocked tools) which get applied with your confirmation. A synthetic canary customer exists in this account specifically to self-test the redaction pipeline end-to-end.

Privacy Mode and a private/self-hosted AI provider are complementary, not competing, protections: Privacy Mode keeps entity identities out of whatever model you're using; choosing where that model runs (see §17) determines whether your data leaves your organization's network at all.

Part 4

Advanced Features

12. Skills & Field Notes

Skills

Skills are curated reference documents Sonar loads before doing something that needs deep, NS-specific knowledge — SuiteQL quirks, SuiteScript hard limits, roles and permissions, and account-specific conventions. There are two kinds:

skillList shows what's available; skillRead loads one before relevant work begins.

Field notes

Field notes are Sonar's persistent memory of this specific account: verified facts, configuration, schema quirks, and known-good query patterns discovered in past sessions. They live in a single markdown file (sonar-field-notes.md, injected at load) and are treated as hints, never authority — if live introspection ever contradicts a field note, the live account wins, and Sonar flags the stale note for correction. You can ask Sonar to "update your field notes" after a session to distill what was genuinely learned (verified ids, corrected mistakes, stated preferences) into surgical edits, keeping the file under a size ceiling and never recording anything sensitive.

13. Processes

Processes are supervised, multi-step workflows defined as markdown files in /SuiteScripts/sonar-processes — things like a customer onboarding check, month-end close, or a permissions audit. Each defines an ordered sequence of steps tagged research / action / gate.

Running one

Say "run <process name>" and Sonar loads the definition, renders a live checklist card, and executes step by step — marking each step running/done/error as it actually happens (never marking a step done that wasn't executed). A gate step always stops and asks you directly in the conversation; gates are never relaxed by a process run, and every mutation inside a process still goes through the normal dry-run + approval flow from §6.

The starter library

processStarterSeed installs a bundled library of account-agnostic process definitions into sonar-processes, without ever overwriting an existing file of the same name — your edits and deletions always win. It always previews a dry-run plan (CREATE vs. SKIP per file) for your approval before writing anything.

Authoring or importing your own

If you want to write a new process, or someone hands you a process definition file, Sonar loads a dedicated authoring guide skill first — it covers the file anatomy, the quality bar, and (for imported files specifically) an intake protocol: validate, check for collisions with existing processes, run a quality review, then trial-run it ad hoc before installing it for real.

14. Subagents

For a self-contained, read-only investigation that would otherwise burn many tool calls whose intermediate results you don't need to see — surveying an unfamiliar schema, searching through a large source file, archaeology on old customizations — Sonar can dispatch a subagent: a nested agent loop with its own private context and a restricted, read-only tool whitelist.

Guarantees Every dispatch requires your approval, runs at a hard iteration cap, is strictly read-only, and cannot itself dispatch further subagents (depth 1 only). You see the full live transcript in the tool card, not just the eventual summary.

15. Second Opinion

Second Opinion requests an independent, adversarial review of Sonar's own analysis from a different Anthropic model — a structural check against a single AI's blind spots, using an API key you supply and control separately from your main provider key.

Setup

Settings > Second Opinion — enter a dedicated Anthropic API key (a workspace key with its own monthly spend cap is recommended), and optionally set a per-session spend ceiling and an auto-approve threshold below which review dispatches don't need individual confirmation.

How a review packet is built

Sonar assembles source data first (raw extracts, not its own prose), then computed metrics with the formulas that produced them so arithmetic is independently checkable, then claims stated neutrally with stable ids — withholding its own recommendations on the first pass so the reviewer isn't anchored by them.

Guardrails

Available even under Read-only / Privacy STRICT Second Opinion spends money but mutates nothing in NetSuite, so it remains available regardless of the permission mask; under Privacy Mode, review packets keep entity tokens intact rather than de-tokenizing them.

16. Projects & Prompt Library

Projects

A Project is a named, importable markdown document (similar in spirit to a CLAUDE.md file) that provides standing context for a conversation — house rules, background on an initiative, terminology specific to how your organization talks about its own data. One Project is active at a time, managed via a header button and modal.

Prompt Library

A modal offering a hosted library of ready-made prompts, relayed from an external service (suitestep.com) via a signed request.

Under internal review Unlike the other advanced features in this Part, the Prompt Library has not yet had a formal design review documenting exactly what data leaves your browser when you use it and whether it interacts with Privacy Mode or the permission mask. Until that review is complete, treat it like any other third-party integration: fine for browsing generic prompt ideas, but don't assume it carries the same privacy guarantees documented elsewhere in this manual.
Part 5

Reference

17. Settings Reference

SettingWhat it controls
Provider & API keysPer-provider key storage (Anthropic / OpenAI / xAI / Mistral / OpenAI-compatible base URL). Keys live only in your browser's localStorage.
Model (per provider)Which model to use for that provider. Anthropic enforces a maintained allowlist (currently: claude-fable-5, claude-opus-5, claude-opus-4-8, claude-sonnet-5, claude-sonnet-4-6, claude-opus-4-7, claude-haiku-4-5-20251001); other providers accept free-text model ids since their naming moves faster than Sonar's release cadence.
Max output tokensDefaults to the model's ceiling (currently 64,000) — a high cap costs nothing unless the model actually generates that much.
TemperatureIgnored automatically on models that reject it (Opus 4.7 and later, per Anthropic's own deprecation of the parameter).
ThemeLight / dark; defaults to OS preference.
Display nameOverride the name Sonar uses for you; empty defaults to your NetSuite user name.
Notify on turn completeTab-title flash + OS notification when a long-running turn finishes while you're looking elsewhere.
Show usage chipToggle the per-turn tokens/cost chip on assistant messages.
Second OpinionSeparate API key, spend ceiling, auto-approve threshold, reviewer model allowlist override. See §15.
Agent permission maskStandard / No-deletes / Read-only. Also available as the header shield toggle. See §8.
Privacy ModeOff / ON / STRICT. Also available as the header 👤 toggle. See §11.
Auto-approve mapPer-tool "always allow" choices made via the approval modal, remembered for the session.
On the roadmap: expanded provider support A design is approved for a future release that would consolidate provider/model configuration into a single registry and add support for user-defined "custom providers" — corporate LLM gateways, Azure OpenAI, or other OpenAI-compatible endpoints your organization controls, with proper authentication schemes and connection diagnostics. This is not yet built as of v1.7.1; today, only the single OpenAI-compatible base-URL slot exists. This manual will be updated once it ships.

18. Slash Command Reference

CommandEffect
/clearStart a new conversation.
/settingsOpen the Settings panel.
/model <id>Switch the model for the current provider (e.g. /model claude-opus-5). With no argument, shows the current model.
/cohereSwitch provider to Cohere (no API key needed).
/anthropicSwitch provider to Anthropic.
/exportExport the current conversation as Markdown.
/helpList all slash commands.
/aboutShow version and account/build information.

19. Complete Tool Catalog

Sonar has roughly 70–80 distinct tools. The core set below is always callable; the grouped sets require toolGroupLoad first (see §7). This catalog is organized by function, not alphabetically, so related tools sit together.

Always available — data & reporting

ToolPurpose
runSqlRun a SuiteQL query.
sqlToArtifactRun SuiteQL straight to a downloadable file, bypassing the model entirely.
reportsList / reportInfo / reportRunFind, inspect, and execute standard NetSuite reports.
savedSearchRun / savedSearchListRun a saved search by id/name; list searches by name.
recordsCatalog / recordsCatalogSchemaIntrospect the account's record type catalog.
accountingPeriodGet / accountingPeriodListResolve or list accounting periods.
subsidiaryListList subsidiaries (OneWorld).
accountFeaturesGetCheck which NetSuite features are enabled.

Always available — records

ToolPurpose
recordJsonLoad a record's full state as JSON (all fields + sublists).
recordLoadLoad a record's field values (optionally with sublists).
recordCreateCreate a record. Supports dryRun.mutating
recordUpdateUpdate a record (load + apply + save). Supports dryRun (before→after diff).mutating
recordSubmitFieldsFast field update without a full load. Supports dryRun.mutating
recordDeletePermanently delete a record. Supports dryRun; production real deletes need confirmedByUser. See §9.mutating
recordTypeDescribeFull field list + sublist shape for a record type.
fieldDescribeOne field's label, type, mandatory/select-options detail.

Always available — search & lookup

ToolPurpose
customerSearchFind customers by name/email/phone.
itemSearchFind items by name/SKU/UPC.
fileSearchSearch the File Cabinet by name/folder/type.

Always available — files & artifacts

ToolPurpose
artifactCreateEphemeral browser-download file. See §5.
fileCreateCreate/overwrite a persistent File Cabinet file.mutating
fileGet / fileGetLinesRead a file's content (whole, byte range, or line range).
fileGrepFind lines matching a pattern in a file.
fileEditModify a file via find-and-replace (cheaper than a full rewrite; validated on .js files).mutating

Always available — web & compute

ToolPurpose
webFetchFetch any HTTPS URL from the NetSuite server.
evalJsRun sandboxed pure JavaScript (no NetSuite/DOM access) for computation.
secondOpinionCross-model adversarial review. See §15.

Always available — orchestration & meta

ToolPurpose
skillList / skillReadDiscover and load reference skill documents. See §12.
processList / processRead / processStart / processStepUpdateDiscover, load, and run supervised process definitions. See §13.
processStarterSeedInstall the starter process library (never overwrites). See §13.
subagentRun / subagentRunParallelDispatch read-only research subagents. See §14.
toolGroupLoadLoad a deferred tool group. See §7.
agentHealth / agentSession / userPermissionsCheckSelf-introspection — version, current mask, governance remaining, role and permissions.
privacyManifest / privacySpecApplyInspect/tighten Privacy Mode's column manifest. See §11.

Deferred group: customize

ToolPurpose
customFieldCreate / customFieldUpdate / customFieldGetCreate, update, and inspect custom fields.create/update mutating
customListCreate / customListGetCreate and inspect custom lists.create mutating
customRecordTypeCreateCreate a custom record type.mutating

Deferred group: roles

ToolPurpose
roleGetInspect a role's permissions.
rolePermissionSetModify a role's permissions.mutating

Deferred group: scripting

ToolPurpose
scriptEvalRun SuiteScript ad hoc for inspection/testing (not for deploying — see §6).
scriptList / scriptDeploymentListList scripts / script deployments.
scriptDeploymentToggleEnable/disable a deployment.mutating
scriptExecutionLogsRead a script's execution log output.
restletInvoke / restletDiscoverCall or discover RESTlets.
workflowTriggerTrigger a SuiteFlow workflow.mutating
suiteletUrlResolve a Suitelet's URL.

Deferred group: bulk

ToolPurpose
recordCreateBulk / recordUpdateBulkBulk create/update, capped at 100 records per call.mutating
recordDeleteBulkBulk delete, capped at 100 per call. Production real deletes need confirmedByUser.mutating

Deferred group: transactions

ToolPurpose
recordTransformTransform a transaction (e.g. Sales Order → Invoice).mutating
transactionVoidVoid a transaction.mutating
glImpactInspect a transaction's GL impact.

Deferred group: comms

ToolPurpose
emailSendSend email. Recipients/subject/body always shown for approval first; external-domain recipients treated as especially sensitive.mutating
taskCreate / eventCreate / phoneCallCreateCreate CRM activity records.mutating

Deferred group: advanced

Verified live in this account on 2026-08-29 — this is the exact set toolGroupLoad("advanced") returns.

ToolPurpose
recordXmlLoad a record's state as XML.
pageFetchFetch and extract a NetSuite UI page (Suitelets, dashboards, etc.).
webFetchBrowserFetch a URL from your browser rather than the NetSuite server — for intranet/CORS-restricted resources.
fileDeleteDelete a File Cabinet file.mutating
folderCreateCreate a File Cabinet folder.mutating
fileCopy / fileMoveDuplicate / rename / relocate a file.mutating
savedSearchInspectDescribe a saved search's filters/columns without running it.
bundleListList installed SuiteCloud bundles.

20. Troubleshooting & Limits

Common error codes

CodeWhat it means
AGENT_MASK_BLOCKEDThe permission mask (§8) blocked this call. Change the mode via the header shield toggle if you intended it.
CONFIRMATION_REQUIREDA production delete needs confirmedByUser: true. See §9.
PRIVACY_DICT_NOT_READYPrivacy Mode's redaction dictionary isn't built yet (fail-closed by design). Try again shortly, or after the triggering mutation settles.
SCRIPT_RECORD_RESTRICTEDAn attempt to create a script/scriptdeployment record was blocked. This is permanent, by design — see §6.
NO_KEY_CONFIGUREDNo API key stored for the selected provider (or Second Opinion). Add one in Settings.
MODEL_NOT_ALLOWEDThe requested model isn't on the relevant allowlist (Anthropic models, or a Second Opinion reviewer allowlist).
PROVIDER_NOT_IMPLEMENTEDCurrently returned for Google Gemini — the Settings slot exists but the adapter isn't built yet. Pick a different provider.
MISSING_BASE_URLThe OpenAI-compatible custom provider slot has no base URL configured.
CONTEXT_TOO_LARGEA Second Opinion packet exceeded the ~150K token ceiling. Chunk or summarize before retrying.
RATE_LIMITEDToo many calls in a short window (e.g. Second Opinion's 3/minute cap, or the AI provider's own 429).
SPEND_CEILINGA Second Opinion dispatch would exceed your configured per-session spend ceiling.
BATCH_TOO_SMALL / BATCH_TOO_LARGEsubagentRunParallel requires 2–3 dispatches — use subagentRun for one, or split into sequential batches for more than 3.
STARTER_LIBRARY_MISSINGThe starter process library folder wasn't included in this install of Sonar.

Governance & performance

If something looks wrong