MainSDK
Search⌘K
Interfaces

AI and agents

Playbook advisor

advisor

Optionally let a model read signals and norms and propose one of the app's declared playbooks with a reason a person approves; off by default.

Building for 0.6ships as a experimental APIPhase 2 · Cloud and Teams, 1.0Spec advisorFree in your app, Apache-2.0

Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.

Stability The promise an interface ships with.

  • Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
  • Beta Usable in production; may change before it becomes stable.
  • Experimental May change or go away; needs an explicit opt-in in main.yaml.
Stability levels
Updated 2026-10-28

advisor lets a model read your signals and propose one of the playbooks you declared, with a reason. A person approves. It is off unless declared, and it never runs on the request path.

At a glance

advisor:
  on: [attack.suspected, anomaly.detected]
  may: [attack.contain, pressure.slim]
  run: approve
  model: anthropic/claude-sonnet-4-5   # optional; the first of ai.models by default
  feature: advisor                     # the ai feature its calls are made under

Calls

  • advisor.propose({ signals? })
  • advisor.get(id)
  • advisor.list({ cursor?, limit? })

Guarantees

Whatever the driver.

  • Chooses only from declared playbooks, or none
  • Never approves, and approval is the default
  • Sees signals and norms only, redacted

Drivers

1 drivers. Select one to see its line in main.yaml.

main.yamlBuilt in (calls the ai interface) (default)
advisor:
  driver: builtin

Change this one line to swap providers; your calls stay the same.Built-in and local drivers integration

Codes

CodeWhere it appearsMeaning
MAIN-ADVISOR-0001Checkmainsdk check, before deployadvisor is invalid: may empty or naming an undeclared rule, run: auto with a rule in may that has an app or people step, an unknown wake signal, or no agents.advisor
MAIN-OPS-0001Checkmainsdk check, before deployAn ops value is invalid: write: auto, a port outside 1024 to 65535, or http: on in production without ops.agent declared under agents
MAIN-ADVISOR-0002RuntimeError responses and logsSee the spec
MAIN-ADVISOR-0003RuntimeError responses and logsSee the spec
MAIN-ADVISOR-0004RuntimeError responses and logsSee the spec
MAIN-OPS-0002RuntimeError responses and logsSee the spec
MAIN-OPS-0003RuntimeError responses and logsSee the spec
MAIN-OPS-0004RuntimeError responses and logsSee the spec
MAIN-OPS-0006RuntimeError responses and logsSee the spec

Features

Nothing here has shipped yet. Each feature lands in its phase; the spec ticket builds it.

FeaturePhaseMilestoneSpec ticket
Proposals limited to declared playbooksPhase 20.6advisor#propose
Offline local driver for testsPhase 20.6advisor#offline
The operate surface over MCPPhase 10.4ops-mcp#tools-read

Quick start

main.yaml
advisor:
  on: [attack.suspected, anomaly.detected]
  may: [attack.contain, pressure.slim]
  run: approve
agents:
  advisor: { budget: { spend: $2/day, calls: 50/day } }
ops/ask.ts
import { advisor } from "mainsdk/experimental/advisor";

const p = await advisor.propose();
console.log(p.choice, p.reason, p.evidence);

Configuration

KeyDefaultMeaning
onnoneSignals that wake it, at medium severity or above
mayrequiredPlaybooks it may propose; at least one
runapproveapprove holds every proposal for a person. auto is allowed only when every step of the chosen rule is a notice or instance step
window15mHow far back it reads signals
max-per-hour4The most times it runs in an hour
featureadvisorThe ai feature that sets models, redaction and limits
modelfirst of ai.modelsThe model it asks

What you get

Server only.

CallWhat it does
advisor.propose({ signals? })Ask for a proposal now. Returns a Proposal with choice (one of may, or none), reason (up to 600 characters), evidence (signal ids), confidence (0 to 1, shown but never used to skip approval) and state
advisor.get(id)Read one proposal
advisor.list({ cursor?, limit? })List proposals, newest first

A proposal with a choice starts a playbook run with source advisor, held for approval unless run: auto applies.

Always:

  • Chooses only from declared playbooks, or none.
  • Never approves, and approval is the default.
  • Sees signals and norms only, redacted, under 16 KB. It never sees logs, request content, app data, config values, secrets or user identifiers.
  • Calls the model through ai as agent advisor, so the model allowlist, region, budget and audit apply.

Examples

With ai.driver: local, replies come from the scripted fixture you give the test app:

test/advisor.test.ts
import { createTestApp } from "@mainsdk/testing";

const app = await createTestApp({
  ai: { replies: [JSON.stringify({ choice: "attack.contain", reason: "Many failed sign-ins", evidence: ["s1"], confidence: 0.8 })] },
});
const p = await app.advisor.propose();   // evidence aliases s1..sN map back to real signal ids

Errors and checks

CodeMeaning
MAIN-ADVISOR-0001Check: advisor is invalid, for example may is empty or names an undeclared rule
MAIN-ADVISOR-0002The model's output didn't fit; it was refused and logged
MAIN-ADVISOR-0003The advisor stopped (budget, rate or model failure); playbooks carry on
MAIN-ADVISOR-0004The input matched a secret or personal-data detector; the field was dropped

Each code's cause and fix is in check codes.

Swapping drivers

DriverProvider
builtinBuilt in, through the ai interfacedefault

The advisor asks whichever ai driver the app uses. Proposals are kept in memory (the last 200); the playbook run they start is durable.

Testing

With ai.driver: local the advisor runs offline on the scripted reply and the fake clock, so a simulated attack gives the same proposals every time and makes no outbound connection. See Test your app.

Security and privacy

  • The model sees only redacted signals and norms, never logs, app data, config values, secrets or user identifiers.
  • It cannot approve, revert, change a rule or name a step.
  • Calls run under the advisor agent's budget and the ai allowlist and region.

Next

Was this page helpful?

↑↓ moveEnter openEsc close

Not decided yet