Skip to main content
Playbooks load only when relevant to the task, and never during PR review. You can maintain many playbooks and make them highly specific.
Related: Proactive behaviors let Charlie run selected playbooks on a schedule. If you want repo‑wide guidance that always applies (planning, coding, reviews), use Instructions instead. New to customization? Start with the Customization overview.

What to include

  • Action-oriented title that will be used to determine when a playbook is relevant.
  • Repeatable workflows with exact steps and gotchas (one outcome per file).
  • Concrete content: Overview, prerequisites (caps, env vars, context), numbered steps (1–2 lines each), exact commands.
  • Quality gates: “Verify” checks and minimal “Rollback” notes.
  • References: links or repo paths for background or to compose playbooks.

What to exclude

  • Never: secrets, tokens, credentials.
  • Vague verbs (“handle,” “update”) without concrete actions.
  • Cross‑cutting “kitchen‑sink” playbooks; split into focused outcomes.
  • Duplicating the same content/steps across multiple files — consolidate and cross-reference.
  • Long rationale or essays — link out.
  • Giant code blocks, generated outputs, changelogs.
  • Anything meant for PR reviews (playbooks aren’t available during PR review).

Structure & style

  • File location: .charlie/playbooks/*.md (one playbook per file).
  • Title: the first H1 is the title (≤ 80 chars). This is required and must be the first line (no front‑matter).
  • Sections (all but steps are optional):
    1. Overview (one sentence: the outcome)
    2. Prerequisites (capabilities, env vars, context)
    3. Steps (numbered; 1–2 lines each; include exact commands)
    4. Verify (what to run/see)
    5. Rollback (how to recover in case of failure)
    6. References (other playbooks, instructions, or URLs)
  • Commands: idempotent, copy‑pasteable; use clear placeholders like <SERVICE_NAME> — not .
  • Not subtree‑scoped: path doesn’t limit applicability; relevance filtering does.

Example playbooks (copy‑paste)

These examples are safe to copy into .charlie/playbooks/ in any repository. They are repo‑agnostic and emphasize small, reversible changes.

Fix README errors and outdated info

Place in: .charlie/playbooks/readme-corrections.md
# Fix README errors and outdated info

## Overview

Make a small, reversible PR that fixes objectively wrong items in a single README. Focus on broken links/badges, incorrect commands, and stale version notes. Do not rewrite prose.

## Creates

- Artifact: Pull request
- Title pattern: "Fix README.md errors and outdated info"
- Branch: `readme-fixes-YYYYMMDD`

## Limits

- Max artifacts per run: 1 PR
- Max files changed: 1 file (exactly one `README.md`)
- Max total diff: 150 changed lines
- Allowed paths (pick one file only):
  - Any `README.md` file anywhere in the repository (e.g., `**/README.md`)
- Guardrails:
  - Only fix factual inaccuracies (commands, links, badges, version/engine notes). No wording/style rewrites.
  - Do not change license text, security policies, or contributor agreements.
  - Prefer removing broken badges over replacing them unless a current, authoritative URL is known.

## Data collection

- Candidate selection:
  - Build the list of README files matching the Allowed paths.
  - Sort by last modified time ascending (oldest first).
  - Inspect each file until you find one with clear issues (see checks below); stop after selecting the first valid candidate.

- Checks for the selected file:
  - Commands/scripts: compare examples in the README with the project’s manifest/scripts (e.g., `package.json` or equivalent). Flag renamed/removed scripts and outdated CLI flags.
  - Engines/versions: align any Node/PNPM/Bun (or other runtime/tool) version statements with the project’s declared engine/version constraints where present.
  - Links/badges: verify external links open successfully (treat 4xx/5xx as broken). For intra‑repo links, ensure the targets exist on the default branch.
  - Quickstart: ensure minimal setup steps match actual scripts (e.g., “install dependencies”, “start dev server”), or reduce to a safe subset.
  - General mistakes/inaccuracies: fix clear factual errors (e.g., wrong repository slugs, typos in commands/paths, mismatched badge labels) without changing tone or style.

## No‑op when

- No README file exhibits factual errors per the checks above, or
- Fixes would exceed any limit (files/lines), or
- The authoritative target for a broken link is unclear.

## Steps

1. Create a branch `readme-fixes-YYYYMMDD`.
2. From Candidate selection, pick the first README with clear issues; keep edits surgical.
3. Apply fixes:
   - Replace or remove broken links/badges (prefer authoritative replacements).
   - Update command snippets to match current scripts and flags.
   - Align engine/version notes with declared constraints (or remove stale notes).
   - Address other objective mistakes (see checks above).
4. Run the repository’s code formatter on the changed file(s) only.
5. Open a PR titled "Fix README.md errors and outdated info".
   - PR body should list the specific fixes (e.g., “Updated install command”, “Replaced dead link to X”) and note how links/commands were validated.

## Verify

- Updated links open successfully.
- Example commands exist in the project’s scripts/manifest and are accurate.
- Diff touches a single README and remains small.

## Rollback

- Revert the PR (single revert commit). If badges were removed, include prior URLs in the revert description for future reference.

Delete dead/dormant code (single‑file PR)

Place in: .charlie/playbooks/dead-code-cleanup.md
# Delete dead/dormant code (single‑file PR)

## Overview

Remove code that is clearly unused or obsolete. Keep the change small, limited to one file, and fully reversible. Require multiple independent signals before deleting anything.

## Creates

- Artifact: Pull request
- Title pattern: "Delete dead/dormant code in <path>"
- Branch: `dead-code-cleanup-YYYYMMDD`

## Limits

- Max artifacts per run: 1 PR
- Max files changed: 1 (the single modified file)
- Allowed operations: delete one entire file OR delete specific symbols (functions, types, constants, classes) within one file
- Allowed paths: source files only (e.g., `src/**`). Exclude tests, mocks, examples, fixtures, docs, generated code, build outputs, and migrations.
- Guardrails:
  - Require at least two strong signals the target is unused (see Data collection).
  - Do not delete anything that is part of a public API or SDK surface.
  - Avoid targets re‑exported by “barrel” index modules or listed in package/module export maps.
  - Do not pick a target that would force edits to other files.

## Data collection

- Candidate selection:
  - Prefer leaf modules or helpers that appear isolated.
  - Favor code untouched for a long period while nearby code changed.
  - Look for deprecated/legacy comments or logic behind a permanently disabled flag.

- Signals to justify deletion (use at least two):
  - Zero imports (or dynamic imports) of the file anywhere in the repository.
  - For symbol‑level deletions: zero references to the symbol outside the file; within the file, only the definition remains.
  - Not re‑exported from an index/barrel file in the same folder or any ancestor.
  - Not exposed via public exports, routing tables, command registries, or plugin discovery.
  - Dormant history: unchanged for a long period (e.g., 6–12 months) while adjacent modules evolved.
  - Registration gap: route/command/job/tool code exists but is not wired into any runtime registry.

## No‑op when

- You cannot produce two independent signals.
- Deletion would break a public API surface or require edits outside the single file.
- Usage may be dynamic/reflection‑based and you cannot confidently rule it out.

## Steps

1. Create a branch `dead-code-cleanup-YYYYMMDD`.
2. Choose one safe target based on the signals above.
3. Delete the file, or remove the specific unused symbols within it. Keep other exports intact.
4. Run your project’s standard checks:
   - Format the changed file.
   - Build/compile (or type‑check) the project.
   - Run unit tests and linting if available.
   - If anything fails due to unresolved imports/exports, revert this deletion and pick a different target.
5. Open a PR titled "Delete dead/dormant code in <path>".
   - In the PR body, cite the two strongest signals and confirm all checks passed. Note that only one file changed and the change is reversible.

## Verify

- Code search shows no imports/usages of the deleted path/symbols.
- Build/tests/lint succeed with the deletion.
- Public API, barrels, and export maps remain unaffected.

## Rollback

- Revert the PR (single commit). No follow‑up actions required.

> Note: This playbook applies to any language. Map “barrels/exports/registries” to your ecosystem’s equivalent (e.g., module index files, public headers, service/route registries).

Generate a team update (single‑file PR)

Place in: .charlie/playbooks/team-update.md
# Generate a team update (single‑file PR)

## Overview

Create a concise, narrative report of what the team accomplished in a fixed date window by summarizing merged/updated work across code and issues. Produce one Markdown file with clear sections and lightweight references; open a PR that changes only that file.

## Creates

- Artifact: Pull request
- Title pattern: "team update: <Month D–D, YYYY>"
- Branch: `team-update-YYYYMMDD`
- Report file (create dirs as needed): `reports/team-updates/<YYYY-MM-DD>--<YYYY-MM-DD>.md`

## Limits

- Max artifacts per run: 1 PR
- Max files changed: 1 (the new/updated report file)
- Allowed operations: add a new Markdown report for the window; update an existing report only to correct factual errors
- Guardrails:
  - No raw data dumps, exports, or screenshots in the PR—only the human‑readable report.
  - Use a single, fixed timezone for the window (UTC recommended) and treat it as a half‑open interval: `[START_DATE, END_DATE)`.
  - Attribute bot‑opened PRs to the human assignee/owner when crediting work.
  - Exclude sensitive/private data and links requiring special access.

## Data collection

- Choose window:
  - Set `START_DATE` and `END_DATE` anchored to 00:00 in a single timezone (e.g., UTC). Example: yesterday → today.
- Gather inputs (any tooling/API is fine):
  - Code: PRs merged within the window; open/draft PRs updated within the window; basic churn (files/lines) when available.
  - Issues: items updated/closed within the window; notable comments/decisions.
  - People: authors, reviewers, assignees; count unique contributors.
  - Projects/areas: group related work into themes.
- Derive metrics (keep it simple and explain in prose):
  - Merged PR count; updated‑open PR count; repos/packages touched; approximate churn (additions/deletions) if available.
  - Top contributors/reviewers (by count), noting cross‑repo impact when relevant.

## Drafting the report

Write `reports/team-updates/<YYYY-MM-DD>--<YYYY-MM-DD>.md` with:

- Header:
  - `# Team report: <Month D–D, YYYY>`
  - `Window: <START_DATE> → <END_DATE> (UTC)`
- Two lead paragraphs:
  - The narrative: what moved forward and why it matters.
  - Headline numbers woven into prose (no raw bullet scoreboard).
- Sections (in order):
  1. `## Overview` – 2–3 paragraphs linking the story to the metrics.
  2. `## By person` – short paragraph per human contributor (attribute bot PRs to the human assignee).
  3. `## By project` – one short paragraph per major effort (`###` subheadings).
  4. `## What changed in practice` – short paragraph (or up to 3 bullets) describing user/team impact.
  5. `## Focus moving forward` – ≤3 sentences with actionable next steps.
  6. `## References` – footnotes only:
     - Use `[^fn1]: <plain URL> — one‑sentence context`
     - Place markers like `[^fn1]` after sentences in the body.
     - When a PR links to an issue, put both in the same footnote (PR first, then the issue), separated by `/`.
- Style guardrails:
  - Prefer paragraphs; use lists only when needed.
  - Format numbers with thousands separators.
  - Keep all external links in footnotes; no inline raw URLs in the prose.

## No‑op when

- There is effectively no activity (e.g., 0 merged PRs and no notable issue updates), or
- Required sources are unavailable, or
- The report would require multiple files or exceed repository size constraints.

## Steps

1. Create a branch `team-update-YYYYMMDD`.
2. Pick the window (`START_DATE`, `END_DATE`); gather inputs; compute simple metrics.
3. Draft the report following "Drafting the report" above; ensure it lives at `reports/team-updates/<YYYY-MM-DD>--<YYYY-MM-DD>.md`.
4. Run your normal project checks for Markdown/docs (format/lint if applicable).
5. Open a PR titled "team update: <Month D–D, YYYY>".
   - PR body: a short summary paragraph (no footnotes) echoing the headline numbers and themes.
6. (Optional) Post a brief summary to your team channel with a link to the PR.

## Verify

- Exactly one file changed under `reports/team-updates/`.
- Footnotes render and every marker has a definition.
- Numbers in prose match the simple counts you computed.
- Links open without auth errors (or are intentionally internal and labeled as such).

## Rollback

- Revert the PR (single commit). No further cleanup required.