agentleFS
markphelpsmarkphelps/agent-plugins/skills/whiteboard/SKILL.md

whiteboard

Skill5 starsChanged 45 days agoMITView on GitHub

Help the user pass the whiteboard defense on a codebase: if someone pulls them aside and asks how a system works, why it was built this way instead of another way, where it fails, or what happens when an actor misbehaves, they can answer confidently. Line-level recall is not the goal. A high-level, defensible mental model is. The skill has two halves that feed each other: 1. Map. Explore the repo and write a layered architecture map with receipts for…

6 other projects use a version of this.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

21 rules. 0 are common, 8 are distinctive, and 13 are very specific to this project.

  • 0

    Common

    Most of the 5 edited versions we read keep these.

  • 8

    Distinctive

    This author's own choices. Worth a look.

  • 13

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Never invent rationale: Every claim about why something is the way it is carries an evidence tag.

    line 46
  2. Very specific:

    Read .map/defense/*.md for pass status.

    line 79
  3. Distinctive:

    Before scouting, run git status --short, resolve the source snapshot with git rev-parse --verify HEAD, and check external receipts with git …

    line 101
  4. Very specific:

    when a component appeared: git log --diff-filter=A --format='%h %ad %s' -- <path> | tail -1

    line 157
  5. Very specific:

    PR and issue history (if gh is available): search merged PRs and issues for design discussion on the components found so far.

    line 160
  6. Distinctive:

    Only after this, read implementation code, and only enough to confirm the boundaries and flows you're about to draw.

    line 164
  7. Distinctive:

    When the harness supports subagents, assign every inventoried area to a subagent, using bounded batches if needed.

    line 176
  8. Distinctive:

    Before finishing, compare the full inventory with the output: every area must have a mapped region or a justified Unexplored entry.

    line 185
  9. Very specific:

    Write docs/map/<region-slug>.md one layer deeper than its parent: internal structure, the key flows through it, data structures and state, …

    line 214
  10. Very specific:

    If no overview exists yet, do a light scout (steps 2–5) just to bound the region and understand its neighbors, write a minimal index.md …

    line 219
  11. Very specific:

    Every region file (and index.md, for cross-cutting items) has an Open questions & friction section.

    line 237
  12. Very specific:

    When unexplained items accumulate, tell the user they are good candidates for decision records (ADRs) documenting the rationale.

    line 266
  13. Very specific:

    When suspected-bug items exist, tell the user these suspected bugs could be verified before anyone acts on them.

    line 268
  14. Very specific:

    Update .map/scout.md at the end of every map, zoom, or refresh: evidence sources found (records directory, useful PR labels or search …

    line 273
  15. Very specific:

    Keep [stated] evidence unless the change contradicts it.

    line 285
  16. Very specific:

    If paths no longer match anything, the region was moved or deleted.

    line 290
  17. Distinctive:

    Propose: every candidate change in chat, grouped by target file, each with a one-line summary and its source map entry.

    line 304
  18. Very specific:

    When a later /whiteboard or refresh finds a proposed change reachable from HEAD, remove the entry and upgrade its evidence: [stated] …

    line 313
  19. Very specific:

    Read references/defense.md before starting a session.

    line 324
  20. Distinctive:

    Pick a region: If none is given, prefer unpassed regions with the fewest passed core questions, skipping stale ones.

    line 327
  21. Distinctive:

    After a map, zoom, or refresh, reply briefly in chat: what was written or updated (file links), the two or three most important things the …

    line 345

“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Whiteboard

Help the user pass the whiteboard defense on a codebase: if someone pulls them aside and asks how a system works, why it was built this way instead of another way, where it fails, or what happens when an actor misbehaves, they can answer confidently. Line-level recall is not the goal. A high-level, defensible mental model is.

The skill has two halves that feed each other:

  1. Map. Explore the repo and write a layered architecture map with receipts for every claim about why.
  2. Defend. Quiz the user on the map, one question at a time, and record what they know, what they missed, and what the code failed to explain.

Hard rules

  • Never modify the working tree. While mapping, refreshing, or defending, the only files this skill writes are under docs/map/ (or the repo's existing docs location, see below) and .map/. Cleanup ideas go in the friction log, not in edits; changing code mid-map corrupts the thing being mapped. The one exception is /whiteboard docs, which writes to a separate branch in a git worktree, and changes source files only in a comments-only commit that passes the comment check (see references/docs.md).
  • Keep map artifacts local if desired. Map files, supporting evidence under the map root, and .map/ may be untracked or gitignored. They are local working state, not a requirement to change the repository's tracked files.
  • Persist external receipts. Any citation or evidence outside the map artifacts—source code, existing docs, records, configuration, or similar repository files—must point to a persistent path committed in HEAD. Never cite an untracked, ignored, staged-only, or locally modified external file. If an external change matters, ask the user to commit it first and then map the new commit.
  • Never invent rationale. Every claim about why something is the way it is carries an evidence tag. If there is no evidence, say so and log it as an open question. A fabricated "why" is worse than a missing one, because the defense will then grade the user against fiction.
  • Keep personal records out of shared files. Defense logs and pass status live only in .map/, which may stay untracked.

Commands

Parse the argument after /whiteboard:

InvocationAction
/whiteboardRead state, report it, propose the next step (see below)
/whiteboard mapBuild or rebuild the overview and map every identified architecture area
/whiteboard zoom <region>Map one region in depth; works even with no overview yet
/whiteboard defend [reg]Run a defense session; no region means pick one (see defense)
/whiteboard refreshCheck every mapped region for staleness and remap what changed
/whiteboard docsPropose repo doc and comment fixes from the map, on a branch

A <region> can be an existing region slug, a name from the Unexplored list, or a plain description ("the sync engine", "auth"). Resolve descriptions to paths during scouting and confirm the boundary with the user in one line before writing.

Bare /whiteboard: read state, then propose

  1. Find the map directory (see "Where the map lives"). If none exists, say so and propose map.
  2. For each region file, compute staleness from its frontmatter: git log --oneline <mapped_at>..HEAD -- <paths...> | wc -l. Also note if mapped_at is no longer an ancestor of HEAD (rebased or force-pushed history), which makes the region stale by definition.
  3. Read .map/defense/*.md for pass status.
  4. Resolve any proposed: <branch> friction entries (see "Docs write-back").
  5. Report in chat, compactly: regions with staleness counts and pass status, the Unexplored list, and one recommended next step with a one-line reason. Example: "Sync engine is 38 commits stale; refresh it before defending." Report pass status only in chat, never in a committed file.

Where the map lives

  • Map artifacts: docs/map/. Before creating it, check for an existing architecture or design-docs convention (docs/architecture/, docs/design/, ARCHITECTURE.md, architecture/). If one exists, ask the user once whether to put the map there instead, and record the choice in .map/scout.md. Overview files, region files, and supporting evidence under this root may be untracked or gitignored.
  • Local only: .map/ at the repo root, holding scout.md and defense/<region>.md. On first run, add .map/ to .git/info/exclude rather than .gitignore, so nothing personal or tool-specific touches the repo's tracked files. This matters most on repos the user doesn't own.

External evidence boundary

Before scouting, run git status --short, resolve the source snapshot with git rev-parse --verify HEAD, and check external receipts with git ls-tree -r --name-only HEAD. The map root and .map/ are explicit local artifacts and are exempt from this check. For every receipt outside those artifacts, read the committed version from HEAD (use git show HEAD:<path> when the working tree may differ) and do not use pending edits as evidence. If an external file is not present in HEAD, ask the user to commit it before citing it. Record the full HEAD SHA in map frontmatter so the external references can be checked later.

File templates are in references/templates.md. Read it before writing any map file. Skill-maintainer fixture checks are documented in references/testing.md.

Evidence tiers

Tag every claim about rationale (why, not what) with one of these, inline:

TagMeaning
[documented: <link/path>]An ADR, design doc, README, or PR/issue description says so
[historical: <sha>]A commit message or clear pattern of changes shows it
[inferred]Your reading of the code; plausible but unconfirmed
[stated: <date>]The user explained it during a defense and confirmed saving

Descriptions of what the code does need a file receipt (path/to/file.go, optionally a symbol) but no tier. Prefer the strongest tier available, and when sources disagree (the ADR says one thing, the code does another), record both and log the mismatch as friction.

Map phase

Scouting order

Scout cheaply before reading implementation code. Most architecture is visible from the edges of a repo, and reading function bodies first fills the context with detail before the shape is known. Work through these in order, stopping early on small repos:

  1. Prior state: existing docs/map/, .map/scout.md (known evidence sources, dead ends, leads from last time).
  2. Manifests and build: go.mod, package.json, Cargo.toml, pyproject.toml, Package.swift, Dockerfiles, Makefiles, CI config, workspace/monorepo config. These reveal languages, major dependencies, deployables, and module boundaries.
  3. Entry points: main packages, cmd/, server bootstraps, CLI roots, app delegates, exported library surfaces.
  4. Directory tree: two or three levels deep, excluding vendored and generated code.
  5. Prose: README, CONTRIBUTING, AGENTS.md/CLAUDE.md, docs/, and any records directory (docs/records/, docs/adr/, docs/decisions/, adr/).
  6. Git signals:
    • hot files: git log --since="1 year ago" --name-only --format= | sort | uniq -c | sort -rn | head -30
    • big structural commits: git log --date=short --format='%h %ad %s' --shortstat | grep -B2 -E '[0-9]{2,} files? changed' (large refactors, moves, and rewrites often mark a decision)
    • when a component appeared: git log --diff-filter=A --format='%h %ad %s' -- <path> | tail -1
    • where a decision came from: git log -S '<identifier>' --format='%h %s'
  7. PR and issue history (if gh is available): search merged PRs and issues for design discussion on the components found so far. Note useful labels or search terms in scout.md for next time.

Only after this, read implementation code, and only enough to confirm the boundaries and flows you're about to draw.

Delegation

For /whiteboard map, complete the first scout pass yourself and make an inventory of the major architecture areas before delegating. Give every area a clear, non-overlapping path scope; note its neighbors and the evidence sources found. Do not let a delegate silently redefine or omit its scope. If a delegate finds a distinct area outside the inventory, add it to the inventory and assign it before finishing the map.

When the harness supports subagents, assign every inventoried area to a subagent, using bounded batches if needed. Give each delegate its scope, neighbors, evidence sources, the committed HEAD snapshot, and instructions to return a compact summary—not raw file contents or map files—with responsibility, key flows, decisions tagged with evidence and persistent receipts, and friction or open questions. Delegates do not write map artifacts. The main mapper reconciles their reports and writes the overview and region files using the existing templates.

Before finishing, compare the full inventory with the output: every area must have a mapped region or a justified Unexplored entry; no area may disappear, and overlapping scopes, duplicate coverage, or conflicting reports must be surfaced rather than silently merged. Preserve disagreements as open questions or friction with their receipts. Check that rationale remains evidence-tagged and every external receipt points to a path committed in HEAD. If delegation is unavailable, cover the same inventory component by component yourself and apply the same completeness and reconciliation checks.

Full architecture map (map)

/whiteboard map builds the overview and maps every inventoried major area; it does not stop after writing the overview. First write docs/map/index.md at high altitude: the major components and their responsibilities, the boundaries between them (process, network, trust, package), the one or two flows that matter most, and the decisions that shape the whole system. Aim for something a person could redraw on a whiteboard from memory after reading it twice. If a detail wouldn't survive that test, it belongs in a region file, not the overview.

Then write a docs/map/<region-slug>.md for each mapped area, link it from index.md, and preserve each area's path boundary and evidence. End index.md with an Unexplored list for any inventoried areas not mapped in this pass; include their paths, rough size, why they might matter, and why they remain unmapped. Do not leave an area out of both Regions and Unexplored. The list remains the menu for zooms into deferred areas or deeper subregions.

Zoom (zoom <region>)

Write docs/map/<region-slug>.md one layer deeper than its parent: internal structure, the key flows through it, data structures and state, its decisions with evidence, trust boundaries, and failure modes. Link it from index.md and remove it from Unexplored.

If no overview exists yet, do a light scout (steps 2–5) just to bound the region and understand its neighbors, write a minimal index.md containing only this region's place in the system plus an Unexplored list, then zoom.

Regions can nest. A zoom into part of a region gets its own file with parent: pointing at the containing region. Don't go deeper than the user asked; the altitude model only works if each layer stays readable.

Choosing views

Pick the smallest view that makes each point clear, and place it next to the short text it supports. Read references/views.md for the catalog (component diagrams, sequence diagrams, call trees, shallow file trees, data shapes, state machines, pseudocode). Use an HTML file only for a single concept too dense for Mermaid, never as a second copy of the map.

Friction log

Every region file (and index.md, for cross-cutting items) has an Open questions & friction section. Add to it during scouting, zooming, and defense. Each entry is typed:

TypeWhat it capturesUsually found in
unexplainedA significant decision with no recorded whyscout, zoom
confusingMisleading names, surprising indirection, comment contradicts codezoom
inconsistentTwo patterns doing the same jobscout
stale-docA doc claim (README, docs, AGENTS.md) contradicts the codescout, zoom
undocumentedA region or entry point that no doc coversscout, zoom
cleanupDead code, abandoned dependency, ancient TODOany
suspected-bugA concrete scenario where the code looks wrong or unhandledzoom, defense
defense-exposedThe user missed a question because the code misled themdefense

The signal here is simple: if an agent with full read access struggled to understand something, a new contributor will too. Keep entries to one line plus a receipt. Don't fix anything.

A suspected-bug entry must name the triggering scenario, not just a feeling: "two concurrent Sync calls both pass the running check before either sets it (sync/engine.go:Run)", not "possible race in sync." Don't investigate further or try to reproduce it; a suspected bug is a lead, and the map treats it as unverified. Leave the verdict slot empty (see references/templates.md) so a later verification pass can fill it in.

Handoffs use plain wording and nothing more; this skill depends on no other tooling:

  • When unexplained items accumulate, tell the user they are good candidates for decision records (ADRs) documenting the rationale.
  • When suspected-bug items exist, tell the user these suspected bugs could be verified before anyone acts on them.

Scout notes

Update .map/scout.md at the end of every map, zoom, or refresh: evidence sources found (records directory, useful PR labels or search terms), dead ends to skip, generated or vendored paths to ignore, and leads not yet followed. Store distilled findings only, never raw logs; the region frontmatter and the Unexplored list carry the rest.

Refresh

For each stale region, read git log <mapped_at>..HEAD -- <paths> and the diff stat. Small changes: update the affected sections in place and bump mapped_at. Large or structural changes: remap the region. Either way:

  • Keep [stated] evidence unless the change contradicts it; if it does, move it to friction as inconsistent and flag it for the user.
  • Resolve proposed: <branch> entries the same way the bare command does.
  • Re-derive the region's core questions (see references/defense.md); keep pass status for any question whose underlying decision didn't change.
  • If paths no longer match anything, the region was moved or deleted; find where it went via git log --follow or rename detection, and ask before rewriting the boundary.

Docs write-back (docs)

Carry what the map learned back into the repo's own docs. Read references/docs.md before starting; it covers inputs, targets, the comment check, content rules, and the PR. In short:

  1. Check whether the map is shared: git ls-files docs/map on the target branch and git check-ignore docs/map. If it isn't tracked, ask once whether to include the map in this PR or write self-contained docs, and record the answer in .map/scout.md.
  2. Propose every candidate change in chat, grouped by target file, each with a one-line summary and its source map entry. The user picks what to include. Nothing is written before that.
  3. Write the selected changes in a git worktree on a new branch, as two commits: docs first, then comments. The comments commit must pass the comment check.
  4. Push and open a PR only on an explicit yes, after showing the diff stat.
  5. Mark each included friction entry proposed: <branch> in the map.

When a later /whiteboard or refresh finds a proposed change reachable from HEAD, remove the entry and upgrade its evidence: [stated] rationale and answered unexplained decisions become [documented: <path>]. If the branch is gone and the change never landed, reopen the entry.

Rationale that belongs in decision records is handed off by wording: tell the user these are candidates for decision records (ADRs). If they'd rather not, it goes into the repo's existing design-docs location instead.

Defense phase

Read references/defense.md before starting a session. It covers question types, grading, hints, core questions, pass rules, and write-backs. In short:

  • Pick a region. If none is given, prefer unpassed regions with the fewest passed core questions, skipping stale ones. If the chosen region is stale, offer to refresh first; defending against a stale map teaches the wrong system.
  • One question at a time. Open-ended first. If the user is stuck or says they don't know, offer a multiple-choice hint rather than the answer.
  • Grade against the map's receipts, and tell the user what they got right, missed, or got wrong, with file links. Drill deeper on misses before moving on.
  • Inferred and unexplained decisions are framed as "defend this or tell me why it's wrong," not graded. A good answer can become [stated] evidence, but only after asking the user to confirm it should be saved.
  • Stop around ten questions or when the user says so. Summarize, update .map/defense/<region>.md, add any defense-exposed friction to the region file, and say what's left to pass.

Reporting

After a map, zoom, or refresh, reply briefly in chat: what was written or updated (file links), the two or three most important things the map shows, the count of friction items by type, and the recommended next step. Don't restate the map; the user can read it.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.