---
name: edit-playbook
description: Read a CampaignStack workspace playbook, explain what each section does, and change it through a proposal the person accepts or rejects. Use when messages should say something different, stop saying something, handle an objection, or when someone asks what the playbook is.
---

# Edit the playbook

Every drafted message reads the playbook. It is the person's document, so
changes go in as a proposal they read as a diff first.

## 1. Read it

```
campaignstack_get_workspaces(include: {playbook: {}, playbookProposal: {}})
```

- `offerContext`: what is sold and to whom. Messages promise this, no more.
- `outreachIntents`: outcomes a message may ask for (customer, advice,
  intro, partner...). Unranked; each message picks what fits the reader.
- `sections`, each with a target and a hard cap (over the cap is rejected):
  - `identity` (aim 400, max 1,200, every message): who we are, what
    makes us different.
  - `voice` (400 / 1,200, every message): rules such as "answer their
    question first", "one ask per message". Tone comes from the sender's
    voice profile, so this section holds rules only.
  - `angles` (1,000 / 3,000, first messages): reasons to reach out that
    land.
  - `objections` (2,000 / 6,000, replies): pushback and the real answers.
  - `boundaries` (500 / 1,500, every message): topics to avoid, claims
    never to make.

Sections stand alone and leave the offer, personas and goal to their own
fields. `managed: true`: CampaignStack maintains this playbook. A non-null
`playbookProposal` is waiting: settle it first.

## 2. Pin the change

One sentence of what messages should do differently ("stop quoting prices
in first messages"). Name the section it belongs in and why.

## 3. Propose

```
campaignstack_propose_workspace_playbook_change(instruction, sectionKey?)
```

Returns `proposalId` and up to three changes (section, intent detail or
offer context), each with current text, proposed text and rationale. A new
proposal replaces a pending one. A null `proposalId` means it answered
instead: make the request more concrete.

## 4. Show the diff, then decide

Read each change back as before and after. On the person's word:

```
campaignstack_edit_workspace(proposalDecision: {proposalId,
  decision: "accept"})
```

or `"reject"`. Accept fails when the live text changed since the proposal:
propose again.

## 5. Verify and undo

Re-read with `include: {playbook: {}}`; see it in a real prompt with
`campaignstack_preview_craft_prompt(workflowId, nodeId, leadId)`.
`include: {playbookHistory: {}}` lists versions;
`campaignstack_edit_workspace(restorePlaybookVersionId)` restores one.

`campaignstack_refresh_workspace_playbook` redrafts everything (keeps the
person's own passages, costs credits): for a first draft, not one change.
