# Personal playbook lifecycle

## Choose the smallest useful surface

Search first. Invoke an existing capability or one of the user's own saved
playbooks when it already does the work. Use `execute` for disposable
exploration, small transformations, and confirmed one-time operations.

Save a personal playbook when behavior will be reused, needs multiple files or
tests, or owns jobs, storage, an app, subscriptions, or webhooks. Playbooks are
private to their owner, not shared catalog entries. There is no fork/install
flow, Git lane, separate publish step, or retained source history.

Integrations store authentication; personal playbooks can provide reusable
provider operations. Search the user's wrappers before creating another.
Deferred one-shot work belongs in [workflows](https://github.com/kentcdodds/kody/blob/main/docs/use/workflows.md), not a new
recurring job.

## Save, edit, run

1. Create with `playbookSave({ files })`. Supply the complete text file map,
   including `package.json`. No README or agent-documentation gate applies.
2. For an existing playbook, call `playbookGet({ playbook_id })`.
3. Edit its returned files, keeping every unchanged file that should remain.
4. Save the complete replacement with `playbook_id` and `expected_edit_token`
   equal to the `edit_token` from that read.
5. A successful save returns a new `edit_token`. New executions use the latest
   successfully saved code without a separate activation step.

A failed save leaves current source unchanged. A conflict means another edit
won; reread and reconcile rather than silently overwriting. Omitted files are
deleted. Tokens prevent lost updates but do not retain prior revisions.

Saving does not run external actions. Existing runs finish with the source they
loaded. Use static `kody:@your-username/playbook/export` imports when the name
is known; computed `import(specifier)` is for owner-scoped names that are data.
See [authoring](/guides/playbook-authoring) for complete examples.

## Test schedules before enabling

Scheduled entrypoints receive no manifest params. Keep a shared implementation
with explicit inputs, plus a no-argument wrapper that loads current
configuration. Export that wrapper and point `kody.jobs` at it.

1. Save with the new job initially `"enabled": false`.
2. Inspect the current export contract with `playbookGet`.
3. Call the wrapper from authenticated `execute` without extra arguments.
4. Exercise realistic inputs and expected failures. Verify storage and intended
   external effects, using a real `dryRun` guard where applicable.
5. Enable only after evidence is satisfactory. Use `jobUpdate` to pause an
   existing enabled job; a manifest's create-time disabled default is not a
   substitute for pausing it.

Keep schedules disabled when credentials, host approvals, expected results, or
explicit consent for live external actions are missing.

## Permissions remain separate

Existing secret grants, host approvals, integration restrictions, runtime
isolation, and resource limits remain in force. A source edit never grants
additional authority. Use `playbookStorage()` for durable playbook data and
existing secret/integration APIs for credentials.

## Delete deliberately

Inspect with `playbookGet` or `playbookList`. Explain that deletion permanently
removes source and owned jobs, storage, secrets, tokens, grants, and derived
data. Require the owner to confirm the exact name, then call
`playbookDelete({ playbook_id, confirm_name })`.

Do not delete merely because code is unused, failing, or over quota. Hiding via
`playbookUpdate` is not deletion. There is no restore/history lane.

## Maintain

Read current files and token before every edit. Preserve the user's intended
behavior, update relevant tests and optional docs, save, and rerun affected
surface checks. Do not patch generated runtime caches instead of saved source.
