# Big Plan > Review agent plans and reach agreement before an agent acts. :::caution[Pre-alpha] Big Plan has no compatibility contract until an explicit milestone establishes one. Commands, document formats, and rendered output may change together as the product finds its cleanest model. ::: Big Plan turns your agent's MDX plan into a document built for review, so you reach real agreement before the agent acts. Choose **Install now** to give your coding agent the stable setup prompt. The linked [setup guide](/setup.md) stays current as Big Plan evolves. [What is Big Plan?](/intro/what-is-big-plan/) · [Demo](/intro/demo/) · [Architecture](/architecture/) · [Components](/components/) --- # What is Big Plan? > Big Plan turns your agent's MDX plan into a document built for review. Big Plan turns your agent's standard text plan into a rich, inert HTML document specially designed for human review. Run it in your favorite agent harness as a skill like this: ### Claude Code ``` Give me a /big-plan for implementing the following feature... ``` ### Codex ``` Give me a $big-plan for implementing the following feature... ``` ## Why build it? Agent plans are kind of a big deal. The more confident you are in your agent's plan, the better your agent will perform at the execution step and the faster your final review will go. But an agent's standard wall-of-text plan is painful to read! If plans are so important for the human, they should present in a first-class way. These plans really are a big deal, so we call them "big plans". ## What makes a good agent plan A great agent plan should be: 1. **Easy to scan.** You don't always want to read the full plan. Sometimes it's better to scan the sections and read the details where they interest you. 1. **Easy to read.** There are many ways to present an idea. Sometimes a paragraph of text is best, but often a visual arrangement conveys the same information with far less cognitive load. 1. **Easy to update.** It's painful to reference a specific paragraph of prose. You should be able to instantly highlight a section and give the agent feedback. 1. **Token-efficient.** Plans get written, revised, and re-read by agents, and every one of those interactions costs tokens. Authoring a plan, updating it, and pulling in feedback should all be as token-efficient as possible. 1. **Versioned.** Sometimes the plan updates and you're not sure what changed, or you accidentally overwrite something. Versioning should allow you to easily see older plans. 1. **Local and private.** Your plan can contain sensitive information; it shouldn't be shared with anyone else without a good reason. ## Next step The fastest way to get a feel for Big Plan is to see one. [Check out the demo](/intro/demo/), then [render your own plan in under a minute](/intro/installation/). --- # Demo > See a fully rendered big plan in light and dark appearances, with typed components in action. This is what a rendered plan looks like: ### Light appearance ![The example plan rendered with Big Plan's Default colour theme in its light appearance: branding bar, section navigation, and a reading column showing a highlighted code diff.](../../../assets/viewer-full-light.png) ### Dark appearance ![The example plan rendered with Big Plan's Default colour theme in its dark appearance, with the same layout on dark shades.](../../../assets/viewer-full-dark.png) The viewer follows your OS appearance and uses the `Default` colour theme until you choose otherwise in `Settings`; appearance and colour theme are separate controls. [See the full rendered plan in your browser.](/demo/) Some parts of this plan are ordinary Markdown. But take a look at the **code diff** and the warning under **Risks and mitigations**. Those use [`CodeDiff`](/components/code-diff/) and [`Callout`](/components/callout/), two of the [typed components](/components/) Big Plan ships for presenting common plan information in a first-class way. The diff adds line numbers, counts, change coloring, and a line-anchored annotation without asking the agent to design custom HTML. The output runs locally without a third-party service. The [two-artifact delivery ADR](https://github.com/josh-padnick/big-plan/blob/main/adr/0001-two-artifact-plan-delivery.md) owns the delivery and script-behavior contract. To see it in action, [install it](/intro/installation/). --- # Features > Everything the Big Plan viewer ships today, at a glance. Everything on this page is shipped and works today. ## Reading experience - One reading column with coordinated light and dark variants for every colour theme. - A `Settings` dialog built as a sidebar of settings pages beside the page you pick. A standalone document opens it from the branding bar's gear; a live review opens it from **More actions**. Every setting is its own page there, so none crowds another and a later one joins the sidebar instead of lengthening a page. On wide screens the sidebar is a narrow column beside a dominant content pane; on phones it becomes a compact row of pages above a single column, wrapping onto a second row rather than scrolling sideways. - The `Appearance` page offers `Light`, `Dark`, and `System`. The choice applies immediately, is saved for every review document in this browser, and is applied before the first paint so the other appearance never flashes. - The `Color theme` page offers `Default`, `Rosé Pine`, `Nord`, `Catppuccin`, and `Brutalist`. A theme is a palette rather than a mode: each one works in both light and dark, appearance still decides which, and every swatch previews that theme's own shades. The choice also applies immediately, is saved across review documents, and is restored before the first paint. `Default` is Big Plan's warm paper look and is what a document with no saved choice renders. `Brutalist` also squares cards and controls, replaces the soft shadows with hard offset slabs, and sets one weight heavier, so it changes the shape of the reading surface and not only its colours; pill-shaped badges stay round. - `System` follows your OS preference, and is the value you get on a first run or when the browser refuses storage. - The `Approval message` page holds the covering note sent to the agent with a plan approval. One note covers every plan; there is no separate one per plan. It starts from a standard wording, accepts up to 2,000 characters, saves as you type, and `Reset to default` puts the standard wording back. Emptying the field does the same thing: a blank note falls back to the standard wording, so an approval never carries nothing. If the browser refuses to save, the field keeps what you typed and says so. Like the other settings, it is saved for every review document in this browser. - A fixed branding bar whose logo follows the effective light or dark appearance, independently of the colour theme. - In-document `Maximize` controls for fenced code, code snippets and diffs, tree diffs, data tables, database schemas, [flow diagrams](/components/flow-diagram/), and [wireframes](/components/wireframe/), with Escape restoring the reading view after any pending-feedback prompt is resolved. ## Navigation - A table of contents built from the plan's level-two headings. - A viewport-bounded sticky sidebar on wide screens, with a fixed `Contents` header and an independently scrolling section list that reveals the active entry when needed; a compact sticky `Sections` menu on narrow ones. - Section links scroll smoothly, unless you've asked your OS for reduced motion. - During a wide-screen section-link jump, the sidebar keeps its exact scroll position until the requested section becomes current, then resumes active-entry tracking. - Collapse controls on Parts, slides, and sub-slides, plus document-wide expand-all and collapse-all controls in the table of contents; TOC jumps expand collapsed ancestors. - Collapse choices, CodeDiff and FileTreeDiff views, and database-schema column order and visibility persist only for the exact source path and authored revision, so same-titled plans and distinct authored revisions never share viewer state. - A static render's document-level review-comment draft follows that same revision-scoped browser-storage rule; live review persistence is described below. ## Live review - `big-plan review` serves a loopback session with a per-plan review token, comments on slides, components, or selected text, plus plan-wide chat and coding-agent status. - Sent feedback stays attached to durable threads while the connected coding agent answers, asks for input, declines, warns, or publishes a validated plan revision. - **Proposed changes** gives each comment thread one evolving change set: its first committed baseline against the result of its latest committed reply. Every changed round is marked **Updated plan**, while the thread shows one current diff in its own conversation turn instead of retaining superseded per-reply diffs. If another reply advances a change set while its diff stepper is open, the stepper follows the set and keeps the reviewer on the change they were reading when it can identify the same plan block. Plan-wide chat and unsolicited revisions remain request-scoped change sets. Every diff preserves structured component presentation and guides the reviewer through accepting each changed place; comment threads then offer resolution. - Confirmed decision answers are saved with the review and stay current only while their decision's content is unchanged; they remain in the review until approval writes each answer into the plan source and delivers the recorded answers to the agent, and a standalone rendered document keeps answers for the reading session only. - An **Inputs** list names what the review is still waiting for - for now, every decision the plan asks - with each one marked answered, not answered, or stale, and the ones the plan's author called critical marked as such. - **Approve plan** sits in the branding bar of a live, authoritative review. The dialog shows change sets, decisions, and the covering note from Settings; confirming auto-accepts every change set, records answered decisions in the plan source while leaving unanswered decisions unchanged, writes a durable approval record, sends an `approval` request to the agent, and stamps the page approved. If the plan later changes, the bar offers Re-approve. Revoke returns the plan to review and cancels a still-unanswered approval request. Read-only sessions keep showing an approval already in force without offering approval actions; static documents do not show the control, but a `big-plan render` export of a plan whose approval still pins that exact source carries the approved stamp, and an unapproved or stale plan exports with no stamp. - **More actions** in a live review offers **Export** and **Settings**, in that order. Export downloads the latest committed plan source as portable Markdown, with every built-in component represented as semantic text. It includes current saved decision answers and an approval only when that approval matches the exported version. Comments, draft agent edits, feedback dispositions, and agent status are excluded. Standalone documents keep the Settings gear and do not offer export because they have no authoritative current source to read. - Review state and feedback packages stay in an ignored, owner-only `.big-plan/` directory beside the plan. - When stable-link publication succeeds, a review gets a stable local address that stays identical through runtime restarts, even when the replacement runtime's direct debugging address changes. The CLI presents this stable address as the one to open and labels the runtime address for debugging only; if publication is unavailable, it explains why and falls back to the direct runtime address. A small loopback service serves the live review while one runs, holds an unexpectedly interrupted review for its replacement, explains deliberate endings, starts itself when a command prints an address, and is inspected or stopped with `big-plan service`. See [Reviewing a plan](/reference/reviewing/) for the workflow, persistence model, causal diff behavior, and trust boundaries. ## Feedback and revision - `big-plan review` serves the plan locally for anchored comments, plan-wide chat, agent progress, revision-aware responses, and source diffs without an account or third-party service. - `big-plan agent` connects a coding-agent session to that live review while the MDX remains authoritative; [Reviewing a plan](/reference/reviewing/) owns the workflow, persistence, revision, and trust-boundary details. ## Code - Syntax highlighting for fenced code blocks with a declared language. - Unknown and undeclared languages stay plain and readable. - Keyboard-accessible copy controls for fenced code, code snippets and diffs, data tables, and database schemas; success replaces the copy icon with a check without shifting the toolbar, updates the accessible name, and suppresses the tooltip until the control resets. ## Plan authoring - An MDX plan format made of standard Markdown, GFM, and built-in components; imports, exports, expressions, and inline JSX are rejected and never executed. - Positional diagnostics that aggregate recoverable unsupported syntax, unknown components, invalid attributes, and malformed component content after MDX parses. - `Slide` markers from a closed, growing catalog, with type-specific authoring guidance, derived structural names, plan-specific heading titles, and conservative objective lint. - `DecisionAnalysis` components for weighty choices, rendered as keyed qualitative or weighted criteria matrices with lifecycle state, recommendations, required reversibility, optional interactive choice, and calculated totals. - `Callout` components for notes, tips, warnings, and dangers. - `CodeDiff` components with optional line numbers and change counts, unified and side-by-side views, and scoped line annotations. - `CodeSnippet` components for excerpts with optional file identity, file-absolute line numbers, and scoped annotations. - `DataTable` components for reference datasets with sorting, optional search, selectable and reorderable columns, grouping, and text-fit controls. - `DatabaseTableSchema` components for one table's schema: a psql-style columns grid with key badges, foreign keys, indexes, checks, and titled verbatim-DDL bands. - `FileTree` components for plain hierarchies with optional per-entry notes. - `FileTreeDiff` components with entry-level change status, summaries, and combined or side-by-side before/after views. - `HttpEndpoint` components for HTTP contracts with location-grouped parameters, request examples, and status-coded responses. - `GraphqlOperation` components for queries, mutations, and subscriptions with literal argument types, one-level input and payload fields, and grouped executable examples with repeatable labeled responses. - `GrpcMethod` components for streaming-aware proto signatures, message-typed request and response fields, gRPC status codes, grouped examples, and proto source. - `QuickDecision` components for standalone brief questions with recommendations and an answer flow, without a comparison expander. - `Wireframe` components for true-width product screens with device-honest fixed or growing frames, walkable prototypes, opt-in common layout patterns, and an open vocabulary for custom layouts, including named glyphs as standalone marks or inside controls, verbatim references drawn as one bordered object with the copy control inside it, surfaces layered over the page with a dimmed or clear backdrop, and toolbars anchored at both ends. ## Output - Local, self-contained review delivery; the [two-artifact delivery ADR](https://github.com/josh-padnick/big-plan/blob/main/adr/0001-two-artifact-plan-delivery.md) owns the artifact and script-behavior contract. - No external requests, ever. - Renders anywhere Node.js 22+ runs, straight from `npx -y big-plan@latest render`. See the [CLI reference](/reference/cli/) for command details. ## Next step [Render your first plan in under a minute.](/intro/installation/) --- # Installation > Give your agent one stable prompt and it sets up the current Big Plan workflow. The fastest install is the one you don't do yourself. ## Give this to your coding agent Copy this prompt into your agent: ```text Set up Big Plan for me: read https://bigplan.dev/setup.md and follow it. ``` The agent reads the server-controlled setup guide at [https://bigplan.dev/setup.md](https://bigplan.dev/setup.md), uses the current CLI without installing it, can install the thin skill shell, adopts the plan-review workflow, and adds the rule to your project's agent instructions so every future session keeps it. Authoring principles stay in `big-plan guidance`, so package upgrades refresh them without hand-editing skill files. ## Or install it yourself Big Plan needs Node.js 22 or newer; the published package runs under plain Node.js, so Bun is not required. Run it with no install at all: ```sh # Read how to write a plan humans love to review. npx -y big-plan@latest guidance # Turn plan.mdx into a self-contained plan.html review document. npx -y big-plan@latest render plan.mdx ``` Or install it globally: ```sh npm install -g big-plan@latest # Read how to write a plan humans love to review. big-plan guidance # Turn plan.mdx into a self-contained plan.html review document. big-plan render plan.mdx ``` Either way, `render` writes `plan.html` next to the input. Pass a second argument to choose the output path: `big-plan render plan.mdx reviews/plan.html`. Reading `guidance` first is required; it unlocks `render` for the working directory. ## Render your first plan Download the example plan, or use any plan your agent has written: ```sh # Download a complete example plan. curl -o plan.mdx https://bigplan.dev/demo/example-plan.md # Read how to write a plan humans love to review. npx -y big-plan@latest guidance # Turn the example into a self-contained plan.html review document. npx -y big-plan@latest render plan.mdx ``` Open `plan.html` in your browser, and you should see this: ![The example plan rendered in the Big Plan viewer, with section navigation, a comparison table, and themed reading column.](../../../assets/viewer-light.png) The output is one self-contained HTML file with embedded assets, no external requests, and a complete reading experience when scripts are disabled. ## Next steps - [See how Big Plan works under the hood.](/architecture/) - [Learn the plan document format.](/for-agents/authoring-plans/) --- # Big Plan vs. Other > How Big Plan compares to Lavish and Agent-Native Plans, and the two bets it makes differently. Big Plan is not the first tool to notice that agent plans deserve better than a wall of text. Two neighbors approach the same problem well, and comparing them is the clearest way to see the two bets Big Plan makes: discrete typed components, and a standalone local file you never sign in to view. Both bets come straight from Big Plan's [philosophy](/intro/what-is-big-plan/#philosophy) of what a plan should be. ## Big Plan vs. Lavish [Lavish](https://github.com/kunchenguid/lavish-axi) was a big inspiration for Big Plan. It lets an agent turn its plan into a rich HTML artifact, and its feedback loop is excellent: you annotate elements or text, message the agent without leaving the editor, and everything runs locally. The difference is what the agent is allowed to write. Lavish embraces freeform HTML: the agent designs each artifact from playbooks, which gives it enormous flexibility. The cost of that flexibility is consistency; each plan is its own custom page, so structure and quality vary from plan to plan, and reading ten plans means learning ten layouts. Big Plan makes the opposite bet. Plans are structured MDX with a fixed library of typed [components](/components/), so every plan renders into the same document shape. The agent spends its effort on the decisions, not the presentation, and the tenth plan you review reads exactly like the first. ## Big Plan vs. Agent-Native Plans [Agent-Native Plans](https://www.agent-native.com/apps/plan) shares Big Plan's conviction about structure. It renders plans beautifully through discrete components, diagrams, annotated code, schema maps, and its comment system is polished. The difference is packaging and custody. Agent-Native Plans is part of a larger platform, and the default flow signs you in to view your plan. Big Plan sees no reason a plan on your own disk should require an account: it is one standalone command (`npx -y big-plan@latest render plan.mdx`), the output is one HTML file, and nothing about reviewing it involves logging in or leaving your machine. Big Plan is pre-alpha, but its [local review workflow](/reference/reviewing/) now carries comments and agent responses without an account or third-party service. What it offers is the combination the others do not: structured, consistent plan documents and a live feedback loop from a standalone tool that keeps everything on your disk. ## Next step [Render your first plan in under a minute.](/intro/installation/) --- # How Big Plan works > Why Big Plan treats a plan as a compiled document, and how that design produces machine-readable JSON, a self-contained review document, or portable Markdown. Big Plan's central architectural idea is to treat an authored plan like source code rather than an HTML template. Before Big Plan chooses an output format, it **compiles** the plan. Compilation here does not mean generating machine code. It means reading the authored MDX, rejecting code or component usage outside Big Plan's plan format, and translating each built-in component into plain validated data. The compiler is not one class or executable inside Big Plan. It is the coordinated translation path made from the MDX parser, authoring validators, and the compilation function owned by each built-in component. A component's compilation function knows how to turn that component's attributes and children into validated data; delivery decides whether that data becomes JSON, HTML, or portable Markdown. That shared translation is what keeps validation and every output consistent: - `big-plan compile` collects document metadata and validated component data into machine-readable JSON. - `big-plan render` presents that same validated component data inside a human-readable HTML review document. - `big-plan validate` renders the plan in memory while collecting the machine-readable summary, then applies linting rules to the authored plan without writing either output. - A live review's Markdown export reads the authoritative source once, uses the same compiler traversal, and asks each component for its semantic Markdown presentation. The commands run independently, and no command reads output produced by another. They agree because each starts from the authoritative source file and reuses the same parsing, validation, and component-compilation implementation. ```mermaid flowchart TB A["plan.mdx
authoritative source"] A --> F["compileMarkdownTree()
parse, validate, compile components,
render presentations, apply document transforms"] F --> Q{"What the command publishes"} Q -- "compilePlanModel()
compileMarkdownModel()" --> G["Publish the collected
component models"] Q -- "renderDocument()
compileMarkdown()" --> H["Package the rendered
document"] Q -- "validateDocument()
compileMarkdownModel()" --> M["Keep the collected models,
discard the document"] Q -- "renderMarkdownDocument()" --> X["Render component-owned
Markdown presentations"] G --> I["machine-readable JSON"] H --> J["self-contained HTML
review document"] M --> N["Apply linting rules
no output written"] X --> Y["portable Markdown
plus review overlay"] ``` In the source, `compileMarkdownModel()` and `compileMarkdown()` are thin entry points over `compileMarkdownTree()`. That function coordinates the compilation path described above. It is shared code executed separately by each command, not a cached intermediate artifact or a process that emits output files together. ## Plans are MDX A plan is an MDX document made from Markdown and built-in components. Imports, exports, expressions, and inline JSX are rejected. A plan is prose plus components, nothing else. That keeps every plan greppable and diffable, which the review workflow depends on, and it means the renderer never has to run code an agent wrote. The full contract lives in [Authoring plans](/for-agents/authoring-plans/) and [Linting rules](/reference/lint-rules/). ## Slide vocabulary is shared data Recurring slide roles live in a framework-free catalog below component compilation, lint, and rendering. Each type owns its stable id and name together with the matching boundary, authoring guidance, component pairings, and cardinality that give the type value. The [`Slide`](/components/slide/) compiler validates an authored marker against that catalog, the deck transform derives structural names from it, lint reads only its objective facts, and guidance generation returns the same records to agents. One file per type keeps catalog growth an ordinary reviewed contribution rather than a new architecture decision. ## Each component compiles once and each delivery presents it The [built-in components](/components/) come from a closed registry. When `compileMarkdownTree()` reaches a registered component, its definition validates the authored input and returns plain validated data paired with React and framework-free Markdown presentations. The component is compiled once during that invocation. Machine and human delivery give the validated data to the React view, cross one React-to-HAST boundary, replace the authored component node with plain document HAST, and apply the same document-wide transforms. Live Markdown export instead invokes the component-owned Markdown presentation and applies Markdown-wide transforms without rendering HTML or traversing the source a second time. What each delivery publishes differs: - **Machine delivery**, used by `big-plan compile` and `big-plan validate`, publishes the collected component models. It renders for the same reason: each published model carries the block address its rendered root was given, and a block address only exists over a finished deck. That address is present only where the component's root became a block a reader can point at, so a component rendered privately inside another component's markup, and a slide, which is a scope rather than a block, each publish a model with no address. Validation keeps that summary, discards the generated document, and applies its registered linting rules to the authored plan. - **Human delivery**, used by `big-plan render`, packages the rendered result as the self-contained inert HTML review document. - **Markdown delivery**, used by a live review's Export action, publishes portable Markdown and appends current review facts separately from the plan presentation. Machine and human delivery differ in exactly one other respect, and it is a consequence of what they publish rather than a separate decision: under machine delivery a component's model carries its nested components' presentation instead of a deferred placeholder, because no later pass reaches a placeholder that only a model holds. All three commands therefore agree on component semantics because they call the same compilation function, not because one consumes another command's output. No plan-authored code is evaluated or shipped. Ordinary Markdown prose participates only in the human document, while its heading metadata remains available in the machine-readable JSON. ```mermaid flowchart TB S["plan.mdx source"] --> P["Parse allowed Markdown
and component syntax"] P --> V["Validate authoring contract"] V --> C["Component definition returns
validated data + presentations"] C --> R["Invoke React presentation
and cross once to HAST"] C --> X["Invoke component-owned
Markdown presentation"] R --> T["Apply document transforms,
assign block addresses"] T --> Q{"What this command publishes"} Q -- "machine: compile" --> J["Document metadata and collected
component models, each with its
block address"] J --> O["Serialize JSON"] Q -- "human: render" --> H["Add chrome, serialize HTML"] H --> U["Write plan.html"] Q -- "machine: validate" --> W["Discard HTML, retain summary,
apply linting rules"] X --> Y["Apply Markdown transforms
and append review overlay"] Y --> Z["Download plan.md"] ``` An invalid document never renders partially. Validation collects every recoverable problem, including unknown components, bad attributes, and malformed fences, and fails with the complete list, each entry carrying a `line:column` position, so an agent can fix those problems in one pass. An MDX syntax error can stop parsing before component validation begins, so fix that reported error and render again. ## The HTML review document is self-contained The rendered document embeds everything it needs, makes no external requests, and works offline. See the [two-artifact delivery ADR](https://github.com/josh-padnick/big-plan/blob/main/adr/0001-two-artifact-plan-delivery.md) for the authoritative artifact definitions and script-dependent behavior. Rendering the static artifact touches no server, account, or other machine. The live `review` command adds a loopback runtime with a per-plan review token so the browser and local coding agent can exchange comments, progress, and responses; its owner-only state remains beside the plan on the reviewer's machine. ## One writer owns the plan source The plan file on disk is authoritative, and exactly one code path may write it. An agent's edits go into a claim-scoped stage rather than the plan itself. A stage publishes only under the plan-mutation lock, only while the recorded lock holder, the claim generation, and the source's base digest all still hold, and only through a single atomic rename, with a journal written beforehand so an interrupted publish can be settled after a crash. A reviewer's revert crosses that same boundary and re-proves the digest it was computed against. That is why a revision an agent published while you were deciding refuses the revert instead of disappearing under it: the revert is rejected rather than silently applied to content it never saw. One local filesystem limit is accepted rather than fixed. Node offers no file-open relative to an already-open directory handle, so someone who can already write inside your plan directory can swap an ancestor directory between the moment a path is validated and the moment it is opened. Closing that race is not possible with the available primitives, and an attacker who can write in that directory already has the access the check would protect, so Big Plan documents the limit instead of pretending to remove it. --- # Components > The component library that renders each kind of plan information in a first-class way. Plans are more than prose. They contain decisions, code changes, schemas, and risks, and each of those deserves purpose-built review UI instead of another wall of text. Components are flow-level elements from a closed, built-in registry, rendered entirely server-side so documents stay self-contained and readable without JavaScript. The registry never evaluates code from a plan. A component's attributes are strings or bare booleans, structured data arrives as fenced or scoped children, and any authoring mistake fails the render with a positional diagnostic; see [Authoring plans](/for-agents/authoring-plans/) for the contract. ## Available today | Component | What it is for | | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | [Callout](/components/callout/) | Surface a note, tip, warning, or danger so reviewers cannot miss it. | | [CodeDiff](/components/code-diff/) | Review one file's unified diff with gutters and line-anchored annotations. | | [CodeSnippet](/components/code-snippet/) | Inspect existing code with optional file identity, file-absolute line numbers, and annotations. | | [DataTable](/components/data-table/) | Query a dataset in place: sortable columns, optional search, selectable columns, grouping, and text fit. | | [DatabaseTableSchema](/components/database-table-schema/) | Review one table's DBML-subset schema and titled verbatim DDL. | | [Decision](/components/decision/) | Review one tradeoff option by option, each carrying its own verdict-lined considerations. | | [DecisionAnalysis](/components/decision-analysis/) | Audit or choose a weighty decision in a keyed qualitative or weighted scoring matrix. | | [FileTree](/components/file-tree/) | Show a plain file hierarchy with optional per-entry notes. | | [FileTreeDiff](/components/file-tree-diff/) | Review per-entry change status as one combined change tree. | | [FlowDiagram](/components/flow-diagram/) | Diagram a flow, dependency, or fan-out as staged cards joined by verb-labeled, directed connectors. | | [MermaidDiagram](/components/mermaid-diagram/) | Review a compile-time Mermaid diagram with static light/dark SVG and stable semantic review anchors. | | [GraphqlOperation](/components/graphql-operation/) | Review one GraphQL query, mutation, or subscription with one-level input and payload shapes and executable examples. | | [GrpcMethod](/components/grpc-method/) | Review one gRPC method headed by its proto signature, with message fields, status codes, and grouped examples. | | [HttpEndpoint](/components/http-endpoint/) | Review one HTTP endpoint's contract: parameters, request body, and status-coded responses. | | [Part](/components/part/) | Divide the plan's sections into numbered acts rendered as anchored divider bands. | | [QuickSummary](/components/quick-summary/) | Open the plan with its few key points as a standout card, capped at five bullets and six hundred characters. | | [QuickDecision](/components/quick-decision/) | Answer one small brief-format question; repeat the component to batch independent calls. | | [Slide](/components/slide/) | Apply a recurring slide type and its guidance while keeping its heading as the plan-specific title. | | [TableOfContents](/components/table-of-contents/) | Show the plan in one look: one linked row per section with its one-line gist. | | [Wireframe](/components/wireframe/) | Draw true-size product screens and connect them into a short walkable prototype. | Scoped child components are valid only in their declared hierarchy: `Annotation` in `CodeDiff` and `CodeSnippet`; `Column` in `DataTable`; `Ddl` in `DatabaseTableSchema`; `Stage` and `Edge` directly in `FlowDiagram`, with `Node` directly in that `Stage`; `Entry` in `TableOfContents`; `Option` directly in `Decision`, with `Consideration` directly in that `Option`; `Criterion`, `Details`, `Option`, and `Reversibility` directly in `DecisionAnalysis`, with `Score` directly in an `Option`; `Option` directly in `QuickDecision`; `Param`, `Request`, and `Response` in `HttpEndpoint`; `Argument`, `Field`, `Returns`, `Operation`, `Variables`, and `Response` in `GraphqlOperation`; `Field`, `Error`, `Example`, and `Proto` in `GrpcMethod`; and the screen and drawing vocabulary documented under [`Wireframe`](/components/wireframe/). --- # Callout > An accent-bordered panel with a typed icon and title, for the notes, tips, warnings, and dangers a plan reviewer must not miss. `Callout` highlights information that a reviewer must read even when skimming. Callouts can be used to share a `note`, `tip`, `warning` or `danger`. ## How it looks All four callout types rendered in the viewer ## When to use it See the [types](#types) for guidance on when to use the Callout. ### When not to use it Do not use a Callout for ordinary supporting detail that does not need to interrupt a skim. Overusing callouts makes the truly important information harder to spot. ## Use cases There are countless use cases of when it's worth calling out information to a user, but here are some concrete ones: - Warn a user about data-loss dangers - Call out important sequencing ## Usage ```mdx Enable the worker before stale reads. ``` ## Authoring ### Attributes | Attribute | Type | Required | Behavior | | --------- | ------------------------------------------ | -------- | ----------------------------------------------------------------------- | | `type` | `"note" \| "tip" \| "warning" \| "danger"` | Yes | Selects the accent palette, the icon, and the default title. | | `title` | string | No | Header text; defaults to `Note`, `Tip`, `Warning`, or `Danger` by type. | Any other attribute is a positional authoring error. ### Children Children are ordinary Markdown and keep every pipeline behavior: headings receive anchors, fenced code keeps syntax highlighting, and tables keep their scroll containers. Level-two headings inside a callout still join the document's table of contents. ## Types | Type | Icon | Intended use | | --------- | -------------- | ----------------------------------------------- | | `note` | info | A relevant aside. | | `tip` | lightbulb | Information that may be of use. | | `warning` | triangle-alert | Something that will go wrong if ignored. | | `danger` | octagon-alert | Irreversible or destructive consequences. | --- # CodeDiff > A reviewable single-file unified diff with line numbers, counts, and line-anchored annotations. `CodeDiff` shows a proposed change to one file the way a code review tool would: removed lines tinted red, added lines tinted green, under a header naming the file. The plan author pastes ordinary `git diff` output for that file into the component, and the reader gets a unified diff with optional line numbers, change counts, and anchored notes. With the viewer script active, a pressed-state segmented control switches between unified and side-by-side views and remembers the choice for this exact plan revision. With scripts disabled, the complete unified view remains readable and no dormant control appears. ## How it looks A unified diff with an annotation card beneath its line range and an accent spine on the covered lines ## When to use it Use `CodeDiff` whenever a plan proposes a concrete change to existing code, so the reviewer approves the exact lines rather than a prose description of them. ### When not to use it - Code that is not a change - a plain fenced code block presents it without diff framing - Decisions that are architectural rather than line-level - prose or a diagram carries those better - Changes too large to read line by line - summarize them in prose and reserve `CodeDiff` for the risky excerpts ## Use cases - Show the exact edit an agent intends to make before it touches the file - Explain a risky or subtle change with annotations anchored to the specific lines they discuss - Make additions and removals scannable through line markers, gutters, and color ## Usage ````mdx ```diff @@ -12 +12 @@ -const ttl = 30; +const ttl = 60; ``` ```` ## Authoring ### Attributes | Attribute | Type | Required | Behavior | | ----------------- | ------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | `file` | string (non-empty) | Yes | Shown in the header with the directory muted and filename bold. | | `showLineNumbers` | bare boolean | No | Renders old/new line-number gutters computed from `@@` hunk headers. | | `showLineCounts` | bare boolean | No | Shows the computed `+added -removed` summary in the header. | Attributes take the bare form (`showLineNumbers`, never `showLineNumbers="true"`). Any other attribute, an empty `file`, or `showLineNumbers` on a diff without `@@` headers is a positional authoring error. ### Children The component takes exactly one fenced ` ```diff ` code block, plus zero or more direct `Annotation` children, and nothing else. The fenced `diff` block accepts: - One file's unified `git diff` output, verbatim - the file preamble (`diff --git`, `index`, `---`, `+++`, mode, rename, and copy lines) may appear before the first hunk - Headerless diffs of bare `+`/`-`/context lines, when line numbers are not requested - A blank line inside a hunk as empty context, even when an editor has stripped its leading space Combined and multi-file diffs are not supported; use one `CodeDiff` per file. Validation is strict, and a malformed line fails the render with both the document position and the fence-relative line number: - Each `@@` header's declared old and new line counts must match the hunk content - Hunk coordinates and the line-number ranges they produce cannot exceed `9007199254740991` ### Annotation Nest `Annotation` directly inside `CodeDiff` to anchor a markdown note to specific lines: ```mdx Slug allocation must follow component rendering. ``` | Attribute | Type | Required | Behavior | | --------- | ------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `lines` | string | Yes | One canonical positive integer (`N`) or a strictly ascending inclusive range (`N-M`); zero and leading zeros are invalid. | | `side` | `"old" \| "new"` | No | Which side of the diff the range addresses; defaults to `new`. | Every referenced line must exist on the chosen side, and annotations require `@@` hunk headers. Annotation bodies accept prose, lists, inline formatting, and plain fenced code, but reject headings, footnotes, and typed components (each with a positional diagnostic). An `Annotation` anywhere other than a direct `CodeDiff` child is an unknown component. `Annotation` is a scoped child component; [`CodeSnippet`](/components/code-snippet/) reuses the concept with file-absolute line anchors. An annotation renders as a prose card after the final line of its range, with a comment glyph, a `Line N` / `Lines N-M` badge, and `role="note"`: - The card spans the component immediately after the last line in its range. - Covered lines carry the annotation accent as a left spine and a subtle wash blended over their add/remove tints, so ranges read at a glance. - Multiple annotations may target the same line or range and render in authored order. - Hovering an annotation or any of its anchored lines highlights both, so the pairing reads at a glance. - Long cards remain fully visible so no annotation detail is hidden. Added and removed lines are tinted, carry `+`/`-` markers, and include visually hidden `Added line:` / `Removed line:` prefixes so the change kind survives without color. --- # CodeSnippet > A component for code excerpts with optional file identity, file-absolute line numbers, and line-anchored notes. `CodeSnippet` shows an excerpt of existing code a reviewer must inspect line by line, adding a file association, file-absolute line numbers, or `Annotation` cards anchored to the lines they explain. ## How it looks An annotated snippet with the file header, file-absolute gutter, tinted anchor lines, and their annotation cards ## When to use it Use `CodeSnippet` when the code under review already exists and the reviewer needs file context, verifiable line numbers, or anchored notes that an anonymous sample cannot provide. ### When not to use it - Plain samples - a fenced code block already ships syntax highlighting; `CodeSnippet` earns its place only through the file association, real line numbers, and anchored notes a fence cannot express - Proposed changes - showing an edit is [`CodeDiff`](/components/code-diff/)'s job ## Use cases - Walk the reviewer through the exact lines a plan builds on, in their real location in the file - Explain load-bearing lines with annotations anchored to their file-absolute numbers ## Usage ````mdx ```ts const convertMarkdown = async ({ source, fallbackTitle }) => { const tree = await parseStaticMdx({ source, diagnostics }); rehypeRenderComponents({ diagnostics })(tree); rehypeSlug()(tree); return { tree, outline: collectOutline(tree) }; }; ``` The registry runs before every other transform so no MDX node can reach the serializer. Slug allocation must follow component rendering, because components may introduce new heading ids. ```` ## Authoring ### Attributes | Attribute | Type | Required | Behavior | | ----------------- | ------------------------ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | | `file` | string (non-empty) | No | File the excerpt belongs to; renders the header path. | | `startLine` | string, positive integer | No (default `"1"`) | The file line the first fenced line corresponds to; the gutter and all annotation anchors use this file-absolute numbering. | | `showLineNumbers` | bare boolean | No | Keeps the line-number gutter visible while resting; without it the gutter stays hidden until the reader maximizes the snippet. | ### Children The component takes exactly one fenced code block, plus zero or more `Annotation` components, and nothing else. The fence may declare any language or none; supported languages receive syntax highlighting, while unknown and undeclared languages remain plain. Component-specific violations report positional diagnostics, including: - A non-integer `startLine` - An annotation anchor outside the snippet's range (the message includes the valid range) - A bare snippet with no `file`, `startLine`, `showLineNumbers`, or annotations, which is rejected with a pointer to use a plain markdown fence - An `Annotation` with no `showLineNumbers`: an annotation's line claim must stay verifiable without JavaScript, so a snippet that anchors a note to a file-absolute line keeps its gutter visible at rest, whether or not `startLine` is authored. An excerpt with no `Annotation` may still omit `showLineNumbers` and reveal its gutter only on maximize. ### Annotation Nest `Annotation` directly inside `CodeSnippet` to anchor a markdown note to specific lines. | Attribute | Type | Required | Behavior | | --------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------- | | `lines` | string | Yes | A file-absolute line (`"47"`) or inclusive non-descending range (`"47-52"`); values must be safe integers inside the snippet's range. | The body is ordinary markdown - though not headings, footnotes, or nested components - and must not be empty; an `Annotation` outside a declaring parent stays an unknown component. An annotation renders as a prose card immediately after the last line of its range, sharing [`CodeDiff`](/components/code-diff/)'s annotation identity: the comment glyph, a `Line N` / `Lines N-M` badge, and the annotation tint, which also washes the anchor lines and their gutter marker in every colour theme and both appearances. Hovering an annotation or any of its anchored lines highlights both, so the pairing reads at a glance. The line-number gutter is excluded from text selection, so selecting the source stays clean. --- # DataTable > A component for a dataset the reviewer queries in place - sortable columns, optional search, selectable columns, group-by, a table-wide summary, and a text-fit choice instead of a horizontal scrollbar. `DataTable` renders tabular data a reviewer needs to work with rather than read through: it sorts by any column, narrows to matching rows, hides columns that are not part of the current question, bands rows under a grouping column, and lets the reader choose how cells meet the available width - so a reference grid stays useful instead of becoming a wall the reviewer scrolls past. ## Anatomy The figure opens with a header band carrying the table name, a live row count, and the reader's controls: an optional search box, the columns menu, a text-fit menu, reset, and maximize. Below it sits the complete grid, every authored row and column present in the served markup. Column headers are the sort controls. Clicking one cycles ascending, descending, and back to the order the author wrote, because authored order is information and a table that cannot return to it loses that on the first click. A table sizes to its contents. Three narrow columns stay narrow; nothing stretches to fill the reading column. ## When to use it Use `DataTable` when the grid is a **dataset the reviewer will query** rather than a paragraph laid out in columns: - it runs past roughly ten rows, or carries more than four columns - the reviewer's likely question is "which row" rather than "what does this say" - it is a reference they will return to after the plan is approved - its cells are long enough that a markdown table would scroll sideways ### When not to use it - A short comparison read top to bottom once, where every row matters to the argument - use a plain markdown table; most tables in most plans are this - A database table's shape - use [`DatabaseTableSchema`](/components/database-table-schema/), which understands keys, indexes, and DDL - Options scored against shared criteria - use [`DecisionAnalysis`](/components/decision-analysis/), which is a decision surface rather than a dataset - Anything needing a sentence of explanation per cell - that belongs in the prose around the table ## Authoring The body is one fenced block with language `table` holding an ordinary GFM pipe grid, so a markdown table that outgrew itself is wrapped rather than rewritten. The delimiter row's colons still set alignment. ````mdx ...one fenced `table` block here... ```table | Total | 222 | | | ``` ```` With no `Column` children every column is text and sortable, takes its alignment from the delimiter row, inherits the table's fit, and is shown in authored order. ### Attributes | Attribute | Values | What it does | | --- | --- | --- | | `title` | text | Names the table in its header and derives its persistence identity. | | `filter` | bare boolean | Renders the search box. Add it only when the table is long enough that a reviewer will hunt a row. | | `fit` | `wrap`, `truncate`, `scroll` | How cells meet the available width. Defaults to `wrap`. | | `groupBy` | a column name | Bands rows under that column's values. | ### `Column` `Column` refines one header by name; declare it only to override a default. | Attribute | Values | What it does | | --- | --- | --- | | `name` | a header in the grid | Which column this refines. Required. | | `type` | `text`, `number`, `date` | Picks the comparator. Empty and unreadable cells always sort last. | | `align` | `left`, `center`, `right` | Cell alignment, overriding the delimiter row. | | `sort` | `asc`, `desc` | The table's opening order. At most one column may declare it. | | `fit` | `wrap`, `truncate`, `scroll` | Overrides the table's fit for this column alone. | ### `SummaryRow` When one row describes the complete dataset rather than one record, use `SummaryRow`. Common summaries include totals, averages, ranges, and overall budgets. If a reader should sort, filter, or group the row like a record, keep it in the main grid. `SummaryRow` takes no attributes. Give it one fenced `table` block that contains one pipe row. Write one cell for every table column, in the same order as the headers. ````mdx ```table | Total | 222 requests | | Across all processors | ``` ```` A table accepts one summary row. To report several aggregates, place them in the relevant cells of that row. The summary row stays at the bottom and never participates in sorting, filtering, grouping, or the row count. Its cells follow the visible column order when a reader hides or reorders columns. Its values summarize the complete authored dataset and do not recalculate when a reader filters the table. When the reader copies the table as tab-separated text, the summary follows the visible data rows. A summary row is also valid when the table does not declare an opening sort. ## Text fit Too much content for the available width has exactly three answers, and `DataTable` makes the choice explicit instead of always picking the same one: - **Wrap** (the default) keeps every character and spends vertical space. - **Truncate** clamps each cell to one line. Reach for it when cells are long identifiers - paths, URLs, ids - that wrap into unreadable stacks. - **Scroll** keeps one line and moves sideways. Reach for it only when horizontal adjacency is itself the information. Wrapping is the default because content that has scrolled off-axis does not announce that it exists: the reviewer cannot tell they are not reading it. Below the narrow breakpoint the table wraps whatever anyone chose, because a horizontal scrollbar nested inside a vertically scrolling phone document is a trap. Sorting and filtering always read a cell's complete text, never the clamped text, so a truncated cell still sorts correctly and still matches a search for a word the reader cannot currently see. ## Grouping `groupBy` names a column whose values become subheading bands. The column stays a **real column** - listed in the columns menu, sortable, revealable - and only hides while it supplies the bands, because grouping is a setting over the data rather than a different shape of data. You choose the default; the reader can regroup by any column or turn grouping off entirely. Generous whitespace before each later band keeps the groups unmistakably separate without making the tinted band itself heavy. Sorting then reorders rows **within** a group and never across one: the groups are the structure you chose, and a sort is the reader's question about the rows inside it. Filtering removes empty bands and preserves that separation between the groups that remain. Use one level. A second level is an outline, and an outline is a different component. ## What the reader controls Everything below is the reader's, not the author's, and none of it changes the plan on disk: - **Sort** by clicking a header; three states, ending back at authored order. - **Search** to narrow rows, with a live count and a named empty state. - **Choose columns** from the columns menu. The first column cannot be hidden unless it supplies the grouping bands, because otherwise hiding the row identity makes every remaining cell unreadable. - **Group by** any column, or not at all. - **Text fit** between wrap, truncate, and scroll. - **Reorder columns** by dragging a header, or with Alt and an arrow key from a focused header. - **Reset table layout** restores everything you authored in one action. - **Maximize** promotes the table to the viewport; Esc restores it. Column order, visibility, grouping, and fit persist per document so a reader who returns finds the table as they left it. Persistence is best-effort: a document opened where storage is blocked behaves exactly like a first visit. Every control ships dormant and is revealed by the viewer script, so a document read with scripts disabled shows every row and column in authored order and no control that cannot act. --- # DatabaseTableSchema > A component for one database table's schema, rendered as a psql-style columns grid with keys, indexes, checks, and titled verbatim-DDL bands. `DatabaseTableSchema` shows one table's shape - columns, keys, constraints, defaults, the indexes behind its access paths, and engine-specific DDL outside the schema grammar - as a dense psql-style grid with titled verbatim-SQL bands, so a plan that proposes or changes a table can be reviewed on the schema itself instead of prose approximations of it. ## Anatomy The figure opens with a header band carrying the schema-qualified name and table note, above a `Column | Type | Constraints | Default | Comment` grid in which every column is exactly one equal-rhythm row. The Constraints cell carries key badges, explicit nullability, foreign keys with their actions, check expressions, and numbered index references beside the column they govern. The tinted Indexes band below the grid numbers each index (`INDX 1`, `INDX 2`, ...) and leads with its name; the columns, method, and partial predicate follow in demoted muted text with the invariant note beneath. A column that an index uses as a key carries the matching `INDX n` pill, while a column that only appears in a partial-index predicate is marked `WHERE INDX n`, so a reviewer can answer "is this column indexed?" without leaving the row. Each `Ddl` child adds a titled band of verbatim SQL after the indexes - row security, triggers, partitioning, grants, whatever the schema grammar deliberately leaves out. Every band renders stacked and labeled, so nothing is hidden from the reader. The rendering is optimized for Postgres but generic: column types are opaque text, any engine's types render unchanged, and the component never parses `Ddl` SQL - it displays exactly what was authored. ## When to use it Use `DatabaseTableSchema` whenever a plan proposes or modifies a table and the reviewer must judge its shape: keys, nullability, defaults, relationships, and the indexes that back the access paths. ### When not to use it - Exact DDL the reader will execute standalone - use a fenced `sql` block, which preserves every clause verbatim outside the figure - Multi-table relationship overviews - render one component per table; a diagram of the whole schema is a different concern - Restating the columns grid as a `CREATE TABLE` inside a `Ddl` child - that creates a second source of truth the component cannot check against the grid; reserve `Ddl` for what the grammar deliberately leaves out ## Use cases - Propose a new table and let the reviewer approve its keys, constraints, and indexes before a migration exists - Show the current shape of a table a plan is about to alter, beside a second component showing the planned shape ## Usage ````mdx ```dbml id bigint [pk, increment] cache_key text [not null, note: 'The catalog cache key this job refreshes.'] requested_by bigint [ref: > catalog.api_instances.id, delete: set null] attempts integer [not null, default: 0, check: 'attempts <= 5'] status text [not null, default: 'queued', note: 'Allowed: queued | running | done | failed.'] enqueued_at timestamptz [not null, default: `now()`] indexes { cache_key [unique, name: 'refresh_jobs_live_key_idx', where: 'status <> \'done\'', note: 'Ensures one unfinished job per cache key.'] (status, enqueued_at) [name: 'refresh_jobs_scan_idx'] } Note: 'One row per queued catalog refresh.' ``` ```sql ALTER TABLE catalog.refresh_jobs ENABLE ROW LEVEL SECURITY; ``` ```` ## Authoring ### Attributes | Attribute | Type | Required | Behavior | | --------- | ------------------ | -------- | ------------------------------------------------------------------------------------------------------------ | | `name` | string (non-empty) | Yes | The table identity, optionally schema-qualified (`catalog.refresh_jobs`); the last dot splits the muted schema prefix from the emphasized table name. | Any other attribute is a positional authoring error. ### Children The component takes exactly one fenced code block with the `dbml` language, followed by any number of `Ddl` children. ### Ddl Each `Ddl` child carries one titled band of verbatim SQL: a required non-empty `title` attribute, unique within the component after surrounding and repeated whitespace are normalized, and exactly one fenced code block with the `sql` language as its whole body. The component displays the statements exactly as authored and highlighted, never parsed or validated as SQL, so engine-specific DDL renders truthfully for any engine. ### Schema grammar The fence carries a deliberate subset of [DBML](https://dbml.dbdiagram.io/docs/) - column lines, one optional `indexes { ... }` block, and one optional table `Note:` - with Postgres-motivated referential-action and partial-index extensions. Every violation reports a positional diagnostic pointing at the offending fence line, and out-of-subset DBML (`Table` blocks, standalone `Ref:` lines, `Enum` blocks) is rejected with the supported alternative named in the message. Each column is one line, `name type [settings]`: - The name must be a unique bare identifier, and the fence must declare at least one column; the type is opaque text and may contain spaces (`timestamp with time zone`) or array brackets (`text[]`). - Marker settings are bare: `pk` (or `primary key`), `not null`, `null`, `unique`, `increment` (rendered as an Identity badge). Either primary-key spelling implies `not null`; combining `null` with `pk` or `not null` is rejected. - `default:` takes a number, `true`, `false`, `null`, a quoted string, or a backtick expression such as `` `now()` ``. - `note:` and `check:` take a single-line quoted value, and a check cannot be empty; notes render in the column's Comment cell, and checks render as `CHECK (...)` in its Constraints cell. - `ref: > table.column` or `ref: > schema.table.column` declares a many-to-one foreign key; other relationship operators are outside the subset. `delete:` and `update:` add referential actions (`cascade`, `restrict`, `set null`, `set default`, `no action`) and require the `ref:` on the same line. Each `indexes` block entry is a declared column, a composite `(a, b)` tuple whose members are declared columns or backtick expressions, or a backtick expression on its own. Every backtick expression must span its whole entry or tuple member. Its optional settings are the bare `unique` marker; a quoted, non-empty `name:` that must be unique in the table; `type:` (`btree`, `hash`, `gin`, `gist`); a quoted `note:`; and the extension `where:` with a non-empty quoted partial-index predicate. When an expression names a declared column directly, including as a double-quoted identifier, the column receives the matching `INDX n` pill. Only direct unqualified references drive those pills; SQL string literals are ignored. The table `Note:` is the table's comment, headed for `COMMENT ON TABLE`: one sentence saying what a single row represents. Operational behavior - pruning schedules, rollout plans, lifecycle narration - belongs in the prose around the component, not inside the schema. ### What stays outside the grammar Triggers, row-level security, partitioning, storage parameters, collation, and grants are deliberately not part of the schema grammar; they enter as verbatim SQL through `Ddl` children instead. Decision-worthy rationale still belongs in a [`Callout`](/components/callout/) beside the component, and one-line facts in the table `Note:`. ## Reader layout The grid and every section are server-rendered in authored order, and a wide grid scrolls inside the figure instead of widening the page. With the viewer script active, drag a column header to reorder it or focus the header and use Left / Right; keyboard moves are announced. The columns menu can hide non-identity columns, persists order and visibility for this table in this exact plan revision, and resets both choices with **Reset column layout**. With scripts disabled, the complete authored grid remains visible in authored order and no dormant controls appear. The `INDX n` and `WHERE INDX n` references remain compact visual links between columns and the numbered index list. With the viewer script active, each reference is a focusable button that moves focus to its named index and briefly tints it; keyboard activation is native, and reduced-motion preferences remove the scroll and tint transitions. --- # Decision > A compact option-by-option choice with inline considerations. **Purpose: ask one lightweight question and end with a confirmed answer.** `Decision` renders distinct option rows. Use a short `summary` and option-local `Consideration` values when the tradeoffs do not need a full matrix. ```mdx ``` `question` is required. Add at least two uniquely titled options and at most one `recommended` option. Add `critical` when the reviewer must settle this question before work begins; the card says so, and the review's [Inputs list](/reference/reviewing/#what-the-review-is-waiting-for) marks it. A `Consideration` requires `label` and `verdict`; its optional `tone` is `good`, `bad`, `mixed`, or `neutral`. `state` is `proposed` or `decided` and defaults to `proposed`, so a question you are asking needs no `state` at all. A decided decision marks exactly one option `chosen`, and a chosen option requires `state="decided"`; it renders as the record of what was chosen rather than as a question, and it stops accepting answers. Author the pair yourself only for a choice that was settled before the review began - when the reviewer answers the question, Big Plan writes `state="decided"` and `chosen` into the plan source at approval. A `Consideration` body defines its label: the first body authored for a label becomes the definition that label reveals on hover and keyboard focus. A label authored without a body stays plain text. The reader can choose an option, propose another approach, confirm, and later change or clear the answer. In a live review a confirmed answer is recorded with the review and survives reload; in a standalone rendered document it lasts only for the reading session. [Reviewing a plan](/reference/reviewing/#decision-answers) owns the recorded-answer behavior. --- # DecisionAnalysis > A keyed criteria matrix for auditing or interactively choosing a weighty decision. **Purpose: make the evidence and arithmetic behind a recommendation inspectable.** `DecisionAnalysis` uses the approved keyed chooser rail. Every criterion and value has a dashed definition affordance. Use `interaction="audit"` for the default qualitative audit surface; `interaction="choose"` enables a proposed decision to be selected, confirmed, and changed. Set `scoring="weighted"` to add editable 1–5 impacts directly below criterion names, editable 1–5 star ratings with their numeric values above, composite totals in the matrix foot, and a disclosure containing the full calculation matrix. The matrix supports seven or more criteria without changing its authoring shape. ```mdx How safely the store preserves review state. Changing stores requires a data migration. ``` `state` is `proposed`, `decided`, or `deferred`; `interaction` is `audit` or `choose`, and choosing is valid only while proposed. Every option must score every criterion. A decided analysis marks exactly one option `chosen`. `Reversibility` is required and `Details` is optional. Add `critical` when the reviewer must settle this question before work begins; it is accepted only while proposed and choosable, the card says so, and the review's [Inputs list](/reference/reviewing/#what-the-review-is-waiting-for) marks it. --- # FileTree > A component for a plain project file hierarchy, with directories, files, and optional per-entry notes. `FileTree` renders a plain file hierarchy from an indented text outline: directories, files, and an optional note beside any entry. It shows where code lives without implying that anything changes. Directories render fully expanded so the complete hierarchy remains visible in the inert document. ## How it looks A titled plain file hierarchy with folder and file icons, connector lines, and a muted note beside each file ## When to use it Use `FileTree` to orient a reviewer in an unchanged directory structure - the shape of a module, the layout of a package, or where existing files live. ### When not to use it - Proposed changes - showing files that are added, modified, removed, or renamed is [`FileTreeDiff`](/components/file-tree-diff/)'s job - A single path - inline code (`` `src/render/page.ts` ``) is enough when there is no hierarchy to show ## Use cases - Sketch the layout a plan assumes before describing the work - Point out which directory owns a concern the reviewer will need to find ## Usage ````mdx ```tree worker-pool/ refresh-worker.ts - Consumes deduplicated catalog refresh jobs. worker-config.ts - Owns concurrency and timeout settings. ``` ```` ## Authoring ### Attributes | Attribute | Type | Required | Behavior | | --------- | ------------------ | -------- | --------------------------------------------------------------- | | `title` | string (non-empty) | No | Header caption above the tree; omitted, the tree has no header. | Any other attribute is a positional authoring error. ### Children The component takes exactly one fenced code block with the `tree` language, and nothing else. ### Tree grammar Each non-blank line is one entry, and blank lines are ignored: - Indent with multiples of two spaces; each two-space step is one level deeper, and a line cannot jump more than one level past its parent. - End a name with `/` to mark a directory; anything else is a file, and a file cannot have children. - Add an optional note after `-` (space-dash-space); it renders muted, after the name. Change badges (`[added]`, `[modified]`, `[removed]`, `[renamed]`) and rename arrows (`->`) are rejected with a pointer to `FileTreeDiff`. Every violation - odd indentation, an indentation jump, a file given children, an empty tree, or change syntax - reports a positional diagnostic pointing at the offending line. --- # FileTreeDiff > A component for comparing project file hierarchies in combined or side-by-side views. `FileTreeDiff` renders a file hierarchy where each entry can carry a change status - added, modified, removed, or renamed - so a reviewer sees the shape of a change across the tree. It derives the complete transition from one authored change tree. With the viewer script active, a pressed-state segmented control switches between combined and side-by-side before/after views and remembers the choice for this exact plan revision. With scripts disabled, the complete combined tree remains readable and no dormant control appears. ## How it looks The combined change tree is the default view: The combined change tree with status-tinted names, spelled-out statuses, comment hints, and the header change summary ## When to use it Use `FileTreeDiff` to show which files a plan touches and how: the additions, modifications, deletions, and renames, in their real directory structure, before any code is written. ### When not to use it - A structure that does not change - a plain hierarchy is [`FileTree`](/components/file-tree/)'s job, and a `FileTreeDiff` with no change status is rejected - The contents of one edit - showing the changed lines is [`CodeDiff`](/components/code-diff/)'s job ## Use cases - Summarize the file-level footprint of a plan at a glance - Confirm a rename lands where intended by reading its old and new names together ## Usage ````mdx ```tree src/ catalog/ refresh-worker.ts [modified] refresh-queue.ts [added] - Deduplicate refresh jobs by cache key. metrics/ legacy-cache-counter.ts [removed] - Replace the ambiguous cache counter. config/ catalog-worker.env -> catalog-cache-worker.env [renamed] - Rename the worker config. README.md [modified] - Document the stale-while-revalidate path. ``` ```` ## Authoring ### Attributes | Attribute | Type | Required | Behavior | | ---------- | ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------ | | `title` | string (non-empty) | No | Header caption; when omitted, the change summary remains. | | `hideDiff` | bare boolean | No | Makes the alternate after pane plain rather than change-highlighted; the no-script document still opens in combined view. | Any other attribute is a positional authoring error. ### Children The component takes exactly one fenced code block with the `tree` language, and nothing else. It must carry at least one change status; a tree with none is rejected with a pointer to `FileTree`. ### Tree grammar `FileTreeDiff` uses the same indentation, directory, and note grammar as [`FileTree`](/components/file-tree/#tree-grammar), plus change syntax: - Append a status in brackets after the name: `[added]`, `[modified]`, `[removed]`, or `[renamed]`. - Statuses and renames apply to directories too; a rename must keep the entry a file or keep it a directory, and a removed directory lists its removed children beneath it. - To show both names for a rename, write `old -> new [renamed]`; both sides must stay files or stay directories, and the arrow only pairs with `[renamed]`. Each changed entry tints its name in the change color and spells out Added, Modified, Deleted, or Renamed at the row's edge; changed files also replace the plain file glyph with a status icon, and deleted names are struck through. A note on an entry renders as a comment hint rather than inline text, keeping rows status-first; hovering, focusing, or tapping the hint opens the note beside it immediately, and the hint stays a real disclosure that opens in place when scripts are unavailable. Every violation - an unknown badge, a rename without its `[renamed]` badge, or a tree with no change at all - reports a positional diagnostic. ## Combined view The combined tree keeps additions, modifications, removals, and renames in one fully expanded hierarchy. Renames show both names, deleted entries remain struck-through tombstones, and compact colored counts in the header summarize the whole change. ## Side-by-side view The side-by-side view derives before and after hierarchies from the same authored tree. It separates removals from additions while preserving directory context, so reviewers can compare the resulting project shape without maintaining two sources. --- # FlowDiagram > A staged diagram of tinted node cards joined by verb-labeled, directed connectors, with an explicit fork when one node feeds several. `FlowDiagram` diagrams genuinely relational content - flows, dependencies, fan-outs - as staged columns read left to right. Small-caps stage headers name what each column holds, and content-sized cards carry a bold label with an optional monospace identifier, status badge, and short body. Cards stay intrinsically sized for short content and wrap long labels, identifiers, URLs, and body text within a readable bound. Every connector touches its cards with an arrowhead pointing subject-to-object of its verb. When one node feeds several, the diagram draws an explicit branching fork rather than a lone arrow beside a stack. ## When to use it Reach for `FlowDiagram` when the point is a relationship: how an artifact travels, what depends on what, where one source fans out. A list of parallel claims is bullets, not a diagram. ## Authoring ```mdx The site republishes the same file One authored file - no content drift. ``` ## The contract - At least two `Stage` children, each with a required non-empty `title`, an optional unique `id`, and at least one `Node`. - `Node` requires a unique `id` and a `label`; `code` is an optional monospace identifier line, `badge` an optional status pill with `badgeTone` `neutral` or `warning`, and `tone` is `source`, `neutral` (default), or `destination`. - A `Node` body is at most one short paragraph: the relationship explained at the point of connection. - Every `Edge` needs `from` and `to` naming node ids in adjacent stages, read left to right; `label` carries the verb. - Only the last stage may hold more than one node, and every node after the first stage takes exactly one incoming edge, so the diagram always draws as columns with one connector or one fork between them. - Loose content inside `FlowDiagram` is at most one paragraph: the footer line rendered inside the graphic. Each violation fails `validate` and `render` with a positional diagnostic. Run `big-plan guidance FlowDiagram` for judgment-level usage guidance. ## Reading and marking up a diagram A diagram is the widest thing a plan can hold, so a rendered document gives the reader more than a scrolling strip. - **Maximize.** Every diagram carries the shared maximize control. It opens the figure over the reading column, fits the artboard to the available width - never above 100 percent - and zooms between 25 and 400 percent with toolbar buttons or a trackpad pinch. Pan with two fingers or by dragging; arrow keys move selection through the diagram. Escape or Restore requests an exit. If feedback remains, an accessible alert reports the actual pending-note count and offers `Go back` or `Exit full screen`; a completed exit clears the selection and returns focus quietly to the diagram, while going back preserves the work and prior focus. - **Elements are addressable.** Each stage, node, edge, and footer, plus the figure itself, carries an anchor such as `component/FlowDiagram#1/node/apply`. The same strings appear in the machine-readable `compile` output, so an agent and a reviewer name the same piece. A node keeps its anchor when its label, tone, or stage changes; a stage keeps its anchor across a reworded title only if the author gave it an `id`. - **Comment and correct.** Click an element to select it and reveal its Comment action. Type or double-click its text to suggest an edit, and press Delete to propose or reverse removal. A proposal repaints the document - a removal ghosts the element and its incident edges and says "Removed"; an edit renders the replacement on a highlight with the original still available - and never writes to the plan source. Before handoff, everything is revertible, and "Show original" hides the whole proposal layer. - **Collect and hand off.** Draft feedback stays in memory and appears in that diagram's tray while maximized. `Add to plan feedback` moves the batch to the page-level feedback package when that collector is available; the page owns the single send, and the diagram no longer offers to undo feedback after handoff. In a standalone preview without the collector, nothing moves and the tray reports that the notes are still there. - **Without scripts.** The document renders every diagram in full, shows no control that cannot act, and keeps horizontal scrolling as its fallback. --- # MermaidDiagram > A compile-time Mermaid diagram rendered as static, reviewable light and dark SVGs without a browser Mermaid runtime. `MermaidDiagram` accepts an explicit Mermaid subset and renders it during compilation. Official Mermaid owns parsing details that are accepted by the subset, text measurement, routing, and geometry; Big Plan owns review anchors, safety checks, and viewer integration. ## When to use it Use `MermaidDiagram` when the plan needs a general graph—a cycle, merge, fan-in/fan-out, parallel or rank-skipping edges—or one of the supported static Mermaid views such as a sequence, state, class, entity relationship, schedule, journey, timeline, mindmap, pie, or git graph. Use `FlowDiagram` when stages, comparable cards, and a chronological left-to-right relationship are the point. ## Authoring ````mdx ```mermaid flowchart LR source[Plan source] -->|compiles| model{Validated model} model --> html[Review HTML] model --> json[Machine JSON] ``` The same graph is available to a human reader and an agent. ```` ## The contract - The body contains exactly one fenced `mermaid` block and an optional one-paragraph footer. - `flowchart` and `graph` accept `TB`, `TD`, `BT`, `RL`, or `LR`. Their nodes have author-written ids and plain-text labels, and their edges may be solid, dotted, thick, open, or cross-ended with an optional label. - Static rendering also accepts `sequenceDiagram`, `classDiagram`, `stateDiagram`, `stateDiagram-v2`, `erDiagram`, `gantt`, `journey`, `pie`, `mindmap`, `timeline`, and `gitGraph`. - Subgraphs in flowcharts, Mermaid directives/configuration, style/class statements, click handlers, HTML labels, and unsupported diagram types are rejected with positional diagnostics. ## Reading and marking up a diagram - Both light and dark SVG variants are embedded in the document. CSS selects one from `data-theme`; appearance and colour-theme changes do not rerender Mermaid. - A diagram's surfaces, borders, text, and edges are delivered as colour roles rather than baked shades, so a compiled diagram follows whichever colour theme the reviewer picks. The alternate node tints some diagram types use have no role of their own and stay fixed. - Flowchart and graph nodes and edges receive semantic anchors such as `component/MermaidDiagram#1/node/source`. Supported static types use their rendered source labels for stable semantic anchors and accessible names; unlabeled geometry is not exposed as a review target. - Every type supports whole-figure comments from the toolbar and an optional footer comment. Selectable nodes, relationships, tasks, slices, events, or commits also support element comments and deletion proposals when Mermaid exposes stable target geometry. - The diagram uses FlowDiagram's zoom steps, percentage readout, Fit, Maximize, roving selection, and comment positioning. Mermaid's runtime is never shipped to the reader. - The SVG, labels, relationships, and an equivalent figure description remain present when scripts are disabled. Run `big-plan guidance MermaidDiagram` for authoring judgment guidance. ## Upgrade probe Mermaid `11.16.0`, Playwright `1.61.1`/Chromium, and the repository-shipped Noto Sans and targeted Noto Sans SC faces are exact rendering pins. The compiler loads and awaits the Latin, Chinese, and symbol glyphs used by the fixture corpus before Mermaid measures text, and the delivered document embeds the same files. Before changing any package or font pin, run the renderer and fixture suites, render `examples/mermaid-gallery.mdx` in every colour theme and both appearances, and inspect the semantic anchor assertions and screenshot diffs. Confirm that Chromium is available with `bunx playwright install chromium` and that scripts-off output still contains both the accessible figure text and the selected static SVG. Only then update the pins and commit the resulting lockfile and reviewed visual baselines together. --- # GraphqlOperation > A component that renders one GraphQL query, mutation, or subscription as a kind-badged review card with arguments, return type, and executable examples. `GraphqlOperation` shows one proposed GraphQL capability - a query, mutation, or subscription - so a plan that introduces or changes a schema can be reviewed on the contract: what the operation takes, what it returns, and what running it actually looks like. ## How it looks An operation card with a mutation kind badge, monospace name, access line, literal GraphQL argument types, and one-level input and payload field expansions ## When to use it Use `GraphqlOperation` when a plan proposes or changes a query, mutation, or subscription and the reviewer should judge its arguments, return shape, and an executable example with variables and response. ### When not to use it - Loose GraphQL samples with no schema contract to review - use a plain `graphql` fence - Whole-schema SDL dumps - reference sites do not show SDL per entry, and neither does this card; describe type definitions in prose or a fence ## Use cases - Propose a new mutation with its input, payload convention, and an executable example operation - Enumerate a planned schema surface compactly, since a header-only operation with just kind and name is valid ## Usage ````mdx Creates a comment anchored to a highlighted range of the plan. The plan id, the anchored range, and the markdown comment body. The plan receiving the comment. The comment body as authored markdown. The created `comment` plus a `userErrors` list following the mutation-payload convention. The created comment; null when validation fails. Field-anchored validation failures; empty on success. ```graphql mutation commentCreate($input: CommentCreateInput!) { commentCreate(input: $input) { comment { id } userErrors { field message } } } ``` ```json { "input": { "planId": "pln_42", "body": "Keep the retry budget explicit." } } ``` ```json { "data": { "commentCreate": { "comment": { "id": "cmt_8f3a" }, "userErrors": [] } } } ``` ```json { "data": { "commentCreate": { "comment": null, "userErrors": [{ "field": ["input", "body"], "message": "Body is required." }] } } } ``` ```` ## Authoring ### Attributes | Attribute | Type | Required | Behavior | | ------------------- | ------------------------------------------ | -------- | ----------------------------------------------------------------------------- | | `kind` | enum: `query` `mutation` `subscription` | Yes | The spec's operation type; renders the kind badge beside the name. | | `name` | string (non-empty) | Yes | The operation name, rendered monospace. | | `access` | string | No | Access requirement (scopes, permissions), rendered as a lock-annotated line. | | `deprecated` | bare boolean | No | Renders a Deprecated badge and strikes the name. | | `deprecationReason` | string | No | The `@deprecated` reason, shown with the badge; invalid without `deprecated`. | The markdown body before the scoped children is the operation's description. ### Argument Each `Argument` documents one argument: a required non-empty `name` and a required non-empty `type` rendered literally - GraphQL's `!` and `[...]` markers convey requiredness, so there is no separate required flag - plus a markdown body description. Duplicate argument names are rejected. ### Field Each `Field` expands one level of the input or payload shape: a required `in` (`input` or `payload`) that seats it under Arguments or Returns, a required `name` and literal `type` (GraphQL's `!` and `[...]` markers convey requiredness), an optional `default`, and a markdown body. Duplicate `in`-plus-`name` identities are rejected; deeper nesting belongs to prose, not the card. ### Returns At most one `Returns` names the required non-empty return `type` and carries a markdown walkthrough of the payload fields. ### Operation, Variables, and Response `Operation` and `Variables` appear at most once; `Response` repeats with an optional `label` so a success example can sit beside the validation error that teaches how `userErrors` behaves. Each takes exactly one fence of its required language - an executable `graphql` operation, `json` variables, and `json` responses - and all render together under one labeled Example section. `Variables` without an `Operation` beside it is rejected, and every fence flows through the standard highlighting pipeline. Component-specific violations report positional diagnostics, including a wrong-language or missing fence, duplicate arguments, repeated single-instance children, a `deprecationReason` without `deprecated`, and headings, footnotes, or nested components inside scoped-child bodies. `Argument`, `Field`, `Returns`, `Operation`, `Variables`, and `Response` outside a declaring `GraphqlOperation` stay unknown components. --- # GrpcMethod > A component that renders one gRPC method as a review card headed by the authentic proto signature with streaming badges, field lists, and canonical error codes. `GrpcMethod` shows one proposed RPC on a service, headed by the literal proto signature - `rpc WatchComments(WatchCommentsRequest) returns (stream Comment)` - so a plan that introduces or changes a gRPC surface is reviewed on what the `.proto` would actually say. ## How it looks A method card with the service caption, a signature with a tinted stream keyword, a streaming badge, message-typed request and response field sections, a gRPC status code, and a service-block proto fence ## When to use it Use `GrpcMethod` when a plan proposes or changes an RPC and the reviewer should judge the signature, the streaming kind, the request and response fields, and the failure codes. ### When not to use it - Loose proto samples with no method contract to review - use a plain fence - Whole-service or message-heavy schema dumps - the card documents one method; larger proto excerpts belong in prose or fences ## Use cases - Propose a streaming RPC where the streaming kind must be unmissable - the signature places the `stream` keyword and the badge names the kind, which even Google's reference fails to surface - Document the canonical `google.rpc.Code` failures reviewers usually have to ask about ## Usage ````mdx Streams new comments on a plan as reviewers create them. Required. Resource name of the plan being watched. The comment body as authored markdown. The plan does not exist or the caller cannot see it. ```json { "plan_id": "plans/pln_42" } ``` ```text comment: cmt_8f3a comment: cmt_901b ``` ```proto service CommentService { rpc WatchComments(WatchCommentsRequest) returns (stream Comment); } ``` ```` ## Authoring ### Attributes | Attribute | Type | Required | Behavior | | ------------ | ----------------------------------------------------------------- | ------------------- | ----------------------------------------------------------------------------- | | `service` | string (non-empty) | Yes | Fully qualified service name, rendered as the card's caption. | | `name` | string (non-empty) | Yes | The method name inside the signature. | | `request` | string (non-empty) | Yes | Request message type inside the signature. | | `response` | string (non-empty) | Yes | Response message type inside the signature. | | `kind` | enum: `unary` `serverStreaming` `clientStreaming` `bidiStreaming` | No (default `unary`) | Places the tinted `stream` keywords and renders the streaming badge. | | `deprecated` | bare boolean | No | Renders a Deprecated badge and strikes the method name. | The markdown body before the scoped children is the method's description. A method with no description or scoped children renders as a compact header-only service entry. ### Field Each `Field` documents one message field: a required `in` (`request` or `response`) that groups it into the matching section - each section names its message type beside the label, keeping the signature's RPC-to-message model alive - a required non-empty `name`, an optional `type`, and a markdown body. Proto3 has no required label, so requiredness stays prose in the description ("Required. ..."), matching the ecosystem. Duplicate `in`-plus-`name` identities are rejected. ### Error Each `Error` documents one transport-level failure under the gRPC status codes section: a required `code` from the canonical `google.rpc.Code` error names except `OK` (`NOT_FOUND`, `PERMISSION_DENIED`, `RESOURCE_EXHAUSTED`, and the rest) and a markdown body explaining when it happens. Duplicate codes are rejected. ### Example `Example` repeats with an optional `label` and exactly one fenced code block with a declared language, rendered together under one labeled Example section - typically a `json` request payload beside a `text` stream trace, since a stream's behavior over time is what streaming-unfamiliar reviewers need to see. ### Proto At most one `Proto` carries exactly one `proto` fence - the raw-source secondary affordance behind the structured card. Author the surrounding `service` block rather than repeating the header's signature line, so the fence adds context instead of duplication. Component-specific violations report positional diagnostics, including an unknown error code, duplicate field or error identities, a second `Proto` or a wrong-language fence, and headings, footnotes, or nested components inside scoped-child bodies. `Field`, `Error`, `Example`, and `Proto` outside a declaring `GrpcMethod` stay unknown components. --- # HttpEndpoint > A component that renders one HTTP endpoint as a structured API review card with parameters, request, and responses. `HttpEndpoint` shows one proposed HTTP endpoint - method, path, parameters, request body, and responses - so a plan that introduces or changes an API can be reviewed on the contract itself instead of prose approximations of it. ## When to use it Use `HttpEndpoint` when a plan proposes, changes, or relies on an HTTP endpoint and the reviewer should judge the contract: which parameters exist and where they live, what the request carries, and which statuses can come back with what bodies. ### When not to use it - Loose examples - a single request or response sample with no contract to review is just a fenced code block - Changed endpoints as diffs - change states are deliberately not part of this component; describe before-and-after in prose until a diff treatment exists ## Use cases - Propose a new endpoint with its full request and response contract, including the error responses reviewers usually have to ask about - Enumerate a planned API surface compactly, since a header-only endpoint with just method, path, and summary is valid ## Usage ````mdx The endpoint accepts one review comment anchored to a plan that is already open in the local workspace. Identifier of the plan receiving the comment. Includes the selected plan text in the response. Session identifier issued by the local browser bridge. Markdown comment text supplied by the reviewer. ```json { "body": "Keep the retry budget explicit." } ``` ```json { "id": "cmt_8f3a", "status": "open" } ``` ```` ## Authoring ### Attributes | Attribute | Type | Required | Behavior | | ------------ | ----------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------- | | `method` | enum: `GET` `POST` `PUT` `PATCH` `DELETE` `HEAD` `OPTIONS` | Yes | Renders the color-coded method pill. | | `path` | string (non-empty) | Yes | The URL template; `{placeholder}` segments render tinted so template variables read at a glance. | | `summary` | string | No | One-line summary beside the path. | | `auth` | string | No | Short auth requirement, rendered as a lock-annotated line; keep the mechanics in plan prose. | | `deprecated` | bare boolean | No | Renders a Deprecated badge and mutes and strikes the path. | The markdown body before the scoped children is the endpoint's long description. A bare endpoint with no description, parameters, request, or responses still renders; the header row alone is a legitimate way to enumerate a surface area. ### Param Nest `Param` directly inside `HttpEndpoint` to document one parameter; the body is its markdown description. Put constraints - ranges, item limits, accepted values - in the body right beside the field they govern instead of in distant prose. | Attribute | Type | Required | Behavior | | ---------- | --------------------------------------- | -------- | --------------------------------------------------------------- | | `name` | string (non-empty) | Yes | The parameter name, rendered monospace. | | `in` | enum: `path` `query` `header` `body` | Yes | Seats the parameter under its location section - Path parameters, Query parameters, Headers - or among the Request body fields. | | `type` | string | No | Free-form type label, rendered muted. | | `required` | bare boolean | No | Renders the emphasized required marker; optional params show a muted optional marker instead. | | `default` | string | No | Rendered beside the optional marker; invalid on a required param. | ### Request At most one `Request` documents the request body: an optional `contentType` rendered as a chip, and exactly one fenced code block as the example. The Request body section states what the body is in one place: the media type up front, the `in="body"` Params as the payload's fields, then the fenced example demonstrating it; body Params without a `Request` still render the section. ### Response Each `Response` documents one status: a required three-digit `status` (`100`-`599`) rendered as a class-colored pill (1xx and 3xx muted, 2xx green, 4xx amber, 5xx red), an optional `label`, and an optional markdown body with at most one fenced example. Document the failure statuses reviewers usually have to ask about, not only the success shape. Component-specific violations report positional diagnostics, including: - A `status` that is not a three-digit HTTP status - Duplicate `Param` identities (same `name` and `in`) or duplicate `Response` statuses - More than one `Request`, a `Request` without exactly one fence, or a `Response` with more than one fence - Headings, footnotes, or nested components inside a scoped child's body `Param`, `Request`, and `Response` outside a declaring `HttpEndpoint` stay unknown components. ## Section layout Path, Query, Headers, Body, and Responses render as stacked labeled sections, so the complete contract remains visible in the inert document, printouts, and text extraction. Request and response fences flow through the standard code pipeline, so supported declared languages receive syntax highlighting. --- # Part > The self-closing act divider - a numbered band that groups the sections after it into one act of the deck. `Part` divides a plan's sections into numbered acts. Each marker renders as a borderless, surface-tinted band carrying an accent `PART N` tag and the act title, and every section after it belongs to that act. Big Plan derives slide numbers, sidebar navigation grouping, and [TableOfContents](/components/table-of-contents/) group headers from the dividers, so the deck structure is authored exactly once. ## When to use it Group a plan of roughly five or more sections into about three acts, canonically Context, The proposal, and Shipping & your review. A short plan whose sections already read in one breath does not need dividers. ## Authoring ```mdx ## Inline retries delay checkout ... ## Success looks like ... ## The retry queue ... ``` ## The contract - `title` is required and non-empty; it names the act, never its number. - `Part` is self-closing and rejects body content. - Numbers are assigned in document order at render time; a title containing its own number would read "Part 1: 1. Context". Each violation fails `validate` and `render` with a positional diagnostic. Run `big-plan guidance Part` for judgment-level usage guidance. --- # QuickSummary > A standout card of the plan's key points, capped at five bullets and six hundred characters so it stays a summary. `QuickSummary` opens a plan with the few points a reviewer must know, rendered as a labeled card that stands apart from body prose. Its caps are the point: a summary that cannot grow cannot become an aggregation of the whole plan. ## When to use it Place one `QuickSummary` directly after the plan's lede, before any section. A reader who stops after it should know what will change, how it will work, which decisions the plan needs from them, and the biggest risk. ### When not to use it Do not use it anywhere but the top of the document, and never as a section recap. If a point only matters to readers of one section, it belongs in that section. ## Authoring The body holds `Why`, `What`, and `How` facet sections; the card renders Why as an accent hero band above What and How cards: ```mdx - For checkout to stay fast, failed captures must retry without blocking requests. - Build a persistent retry queue with explicit state and an audit trail. - Move capture retries out of the API server and into a queue worker. - Ship operator controls to pause, force, and cancel retries. ``` ## The contract - `Why` and `What` are required; `How` is optional; each at most once, in that order. - Each facet's body is exactly one bullet list: one bullet for `Why` and `What`, at most 3 for `How`; prose, headings, and other components are rejected. - At most 450 characters of readable text across all facets, counted after collapsing whitespace and including inline code and emphasis. - At most one `QuickSummary` per document, enforced by the `quick-summary-singleton` linting rule. - No attributes on the component or its facets. Each violation fails `validate` and `render` with a positional diagnostic. Run `big-plan guidance QuickSummary` for judgment-level usage guidance. --- # QuickDecision > One small brief-format question without a comparison expander. **Purpose: batch several independent plan calls without making them one component.** Each `QuickDecision` is a standalone brief: recommendation framing, radio options, **Suggest another option**, and **Confirm choice**. It deliberately has no compare expander. ```mdx ``` `question` is required and `context` is optional. Add `critical` when the reviewer must settle this question before work begins; the card says so, and the review's [Inputs list](/reference/reviewing/#what-the-review-is-waiting-for) marks it. Add at least two uniquely titled options and at most one `recommended` option. Render several `QuickDecision` components in sequence when a plan has a batch of small questions. `state` is `proposed` or `decided` and defaults to `proposed`, so a question you are asking needs no `state` at all. A decided question marks exactly one option `chosen`, and a chosen option requires `state="decided"`; it renders as the record of what was chosen and stops accepting answers. Author the pair yourself only for a choice that was settled before the review began - when the reviewer answers the question, Big Plan writes `state="decided"` and `chosen` into the plan source at approval. --- # Slide > The self-closing type marker that connects a recurring slide role to its specific authoring guidance and structural name. `Slide` applies one type from Big Plan's closed, guidance-bearing catalog to the heading immediately after it. Most markers describe an h2 slide. A `user-journey` marker can also describe an h3 sub-slide inside an h2 group. Most types supply the reusable structural name shown in the kicker, [TableOfContents](/components/table-of-contents/), and sidebar navigation; user journeys supply their deeper naming forms on the marker. The heading remains the large, plan-specific title. The marker itself emits no HTML. Untyped slides keep the existing behavior: the h2 is both their name and title. ## Authoring ```mdx ## Inline retries delay checkout ... ``` Run `big-plan guidance Slide` once before drafting a plan. It returns the complete catalog in one digest: matching boundaries, writing guidance, component pairings, and cardinality for every type. For each intended slide, use a type only when its matching rule fits; otherwise use an untyped slide under the general guidance. ## The catalog | Type id | Name | Role | | --------------------- | ------------------- | ---------------------------------------------------------------------- | | `status-quo` | Status quo | What is true today, including what already works | | `desired-experience` | Desired experience | The concrete lived experience introduced by a new feature | | `desired-outcome` | Desired outcome | The concrete payoff of a bug fix, re-architecture, or tech-debt change | | `user-journey` | User journeys | One complete human loop nested under a journeys container | | `acceptance-criteria` | Acceptance criteria | Independently checkable verification | `desired-experience` and `desired-outcome` are mutually exclusive. They are light recommendations when their sharper framing fits; the canonical untyped “Success looks like” section remains valid and receives no discouraging lint. ## Names and titles A typed slide's name and title are distinct concepts. For most types the catalog name is stable across plans; the h2 title states this plan's message. Normally make the title distinct and write it in plain language with concrete nouns and active verbs, omitting evaluative adjectives, superlatives, slogans, and abstract noun stacks. Big Plan does not lint that judgment because broad language checks would create false positives, and an identical name and title remains structurally valid when a distinct title would be strained. ### User journeys User journeys add one deeper name/title layer. Name the container “User journeys,” make it a Part, and nest every journey underneath it rather than beside it. Then count the actors to pick the shape. **Two or more actors: group by actor.** This is the default. Each actor gets one untyped group slide inside the Part, titled for that actor, and each of their journeys becomes a sub-slide of it, so 2.2 “Merchant journeys” holds 2.2.1 and 2.2.2. A reviewer who owns one actor reads that group and collapses the rest. **One actor: keep the journeys flat.** They stay typed slides directly inside the Part, numbered 2.1, 2.2, 2.3, because grouping a single actor adds a level that only repeats its owner. The marker sits above the heading the journey owns: the h3 when grouped, the h2 when flat. Either way the journey keeps its `name`, `toc`, and wireframe contract, and the heading beneath the marker becomes the title. Authoring typed journey slides beside an untyped container slide is rejected by the `slide-type-structure` lint rule, because they render as the container's siblings. ```mdx ## Merchant journeys The merchant sees the failure first. ### A merchant reads why one payment failed ... ``` With a single actor, drop the group slide and put the marker above the h2 instead. For each typed journey: - `name` is a distinct, concrete journey name shown in the kicker and sidebar. - `toc` is an ultra-concise form shown in the TableOfContents. - The heading under the marker is the full plain-language claim. - A default `Wireframe` carries the actual `Screen` mockups for the shortest path that proves the journey. If no UI exists to show, add a non-empty `wireframeReason` attribute to the marker. Repeat the singular `user-journey` marker for several individual journeys. The catalog's plural “User journeys” name belongs to the container, not every journey kicker. Distinct journey names and TOC forms keep repeated entries navigable. The Wireframe makes a UI journey visible and walkable; prose can annotate the screens but cannot replace them when a UI exists. Apply the Wireframe component's CLEAR quality bar to every mockup. ## The contract - `type` is required and accepts only the five registered ids above. - `Slide` is self-closing and rejects body content. - The marker must be top-level and immediately followed by the h2 or h3 it describes. On an h3 it types one journey sub-slide: the marker's name fills the kicker, and the h3 becomes that sub-slide's title. - `user-journey` additionally requires non-empty `name` and `toc` attributes and accepts an optional non-empty `wireframeReason`; other types reject all three. - Every `user-journey` section must contain a `Wireframe` with actual UI mockups, or a non-empty `wireframeReason` that explains why no UI was created. Carrying both is rejected, because the reason only explains an absent wireframe. - Every `user-journey` slide must sit inside a Part whose title names the journeys container, such as “User journeys”; a grouped journey sub-slide may instead sit under an actor group titled “Merchant journeys”. - Singleton types may appear at most once; `user-journey` may repeat. - A plan may use `desired-experience` or `desired-outcome`, never both. - An acceptance-criteria slide with more than seven criteria must group them by a useful dimension. Unknown types and misplaced markers fail compilation with source positions. Objective catalog violations fail lint. No rule requires every slide to be typed. ## Growing the catalog The catalog is closed but intentionally grows over time. A new type is justified when the same untyped slide purpose recurs across plans and agents need materially different guidance to author it well. A one-off label is not enough. Adding a type is a normal product contribution: 1. Add one file under `src/plan-vocabulary/slide-types/definitions/` with its matching boundary, counterexample, authoring guidance, component pairings, and cardinality. 2. Add its id to the registry and closed `Slide` attribute contract. 3. Update the focused catalog tests, the smallest validated example, and this reference. 4. Submit the evidence and guidance for normal Big Plan maintainer review. Until a type is accepted, authors use untyped slides rather than defining local types. A future captain-approved agent proposal flow may package evidence for maintainer review, but it will not mutate the installed catalog or create runtime custom types. --- # TableOfContents > The plan in one look - one linked row per section, each carrying the section's one-line gist. `TableOfContents` shows the whole argument before the reader commits to any of it: one row per section, each row a link carrying the section name and its one-line gist. Big Plan completes the overview at render time with slide numbers, section links, and group headers derived from the plan's [Part](/components/part/) dividers, so the author writes only the entries. ## When to use it Place one `TableOfContents` directly after the `QuickSummary`, before the first `Part` or section. Skip it only in a very short plan whose sidebar navigation already tells the whole story. ## Authoring ```mdx ``` ## The contract - At least one self-closing `Entry`, each with required non-empty `section` and `gist` attributes; loose body content is rejected. - `section` must repeat each section's overview form exactly, in order, one to one: the catalog name for most typed [Slide](/components/slide/) instances, a user journey's ultra-concise `toc` attribute, or the h2 title for an untyped slide. The `table-of-contents-matches-sections` linting rule enforces the match. - No attributes on `TableOfContents` itself. Each violation fails `validate` and `render` with a positional diagnostic. Run `big-plan guidance TableOfContents` for judgment-level usage guidance. --- # Wireframe > True-size product screens with honest device proportions, safe content growth, an open drawing vocabulary, and short walkable prototypes. `Wireframe` draws low-fidelity product UI inside a device-appropriate frame. Each screen lays out at its device's true width and scales as one unit to fit the review document; desktop screens preserve their 1200 px logical layout within a shared 768 px painted cap. That cap is the figure budget every device shares, and it never widens: the reading column holds the table of contents beside it, so a screen that does not fit is simplified rather than enlarged. Because a desktop drawing is painted at roughly five-eighths of its declared size, desktop artboards use a deliberately larger type ramp than the product they depict, and a browser geometry test fences the painted result against role-based legibility floors. While maximized, the same uniform zoom is constrained by both available width and height so the complete device frame and its caption remain visible. Desktop pages and phone screens use realistic minimum silhouettes and grow with content. A desktop `AppShell` instead fills the 1200 × 820 silhouette: persistent panes own their overflow while the app itself never scrolls sideways. Tablet holds a real iPad aspect ratio; content lays out to fit that fixed frame instead of stretching its bezel or scrolling inside it. Only desktop uses browser chrome; tablet renders as a native device. Multiple screens can link to one another without adding executable plan-authored code, while the complete storyboard remains readable when scripts are disabled. Every wireframe carries the shared `Maximize` control; while maximized, the screen switcher reflows into a left rail and ArrowUp/ArrowDown step through the screens with focus following. ## When to use it Use a wireframe when a reviewer must picture a screen or interaction path to judge the plan. Keep explanations and design rationale in the surrounding prose, and put only customer-visible product UI inside the artboard. Run `big-plan guidance Wireframe` before authoring one. That component guidance owns the judgment calls for product layout, form-factor honesty, action hierarchy, and choosing among primitives; this page is the syntax reference. ## Design front door: CLEAR Use CLEAR as the index into the design standard, not as a replacement for its detail. It covers the product screen and any comments, decisions, diagrams, toolbars, or expanded modes the screen depicts. The generated `big-plan guidance Wireframe` output groups every implementation principle, anti-pattern, per-device pass criterion, and mechanical contract beneath these five headings: 1. **Clear job** - decision complexity selects the composition before layout begins; one screen and one step advance one present decision; every persistent pane and review action has one owner; every temporary surface has an exit. 2. **Layout follows attention** - visual order follows decision order; a small tablet choice is one dominant column of complete touch surfaces; option titles, criteria, definitions, anchored comments, toolbars, facts, recommendations, and side effects remain visually distinct. 3. **Explicit change** - consequential choices start unselected and reveal continuation only after a deliberate tap; selections, modes, comments, destructive edits, live counts, persistence, focus return, and preserved scroll make every state transition observable. 4. **Audience language** - one screen speaks to one audience using one term per concept, natural outcome copy, visible identity and escape, anchored context without repetition, actionable time, and unconfusable live-state labels. 5. **Real device** - desktop, tablet, phone, and expanded viewers keep truthful viewport, navigation, zoom, marker-size, density, and interaction contracts; on tablet the decision is the dominant touch interaction, never a miniature workspace. The generated guidance is the exact agent-facing owner of those grouped rules. The device table below is the syntax-level form-factor contract; the component, compiler, lint, and geometry tests own mechanical facts; LOOP in the generated guidance owns render-and-review practice. The top-level guidance owns CRAP for the surrounding plan page, while the generated Wireframe guidance applies those same fundamentals to product UI inside an artboard. ### How the standards were distilled - **Fourteen hierarchy principles** retain their explicit focal-point, reading-order, proximity, grouping, scanning, decoration, emotional-goal, and rough-fidelity rules under CLEAR. - **The original task-flow round** retains one job, goal-matching actions, selection outcomes, progressive reveal, hierarchy over containers, attention order, affordances, mode boundaries, concrete language, and importance-based contrast. - **The complete task-flow refinement round** retains all 23 check-step, handoff/authentication, and learning-loop principles; its earlier fifteen-rule summary is absorbed by this complete inventory rather than competing with it. - **The maximize navigation and commenting-calm round** retains left-side expanded navigation, arrow-key movement, select-then-comment, passive-scroll calm, comment-role ownership, and context/scroll preservation. - **Commenting rounds 4–5** retain anchor-visible presence, glyph-safe highlights, non-repeated context, `… more`, edit/delete/confirmation, the shared anchor flow, lifecycle navigation, outcome chips, separated chat scopes, live counts, exact labels, and adversarial path review. - **Decision rounds 4–5** retain option-name rules, type contrast, bold-colon criterion labels, regular values, readable matrix headers, centered collapsed actions, idiomatic focus, exit paths, separated dashed-underlined definitions, and explicit component ownership. - **Diagram rounds 5–6** retain valid load state, visible deletion diffs, anchor markers, contained tray chrome, toolbar-owned actions, no redundant whole-diagram control, no meaningless footer hover, fixed-size zoom markers, stable note placement, and focus return. - **The desktop workspace round** retains viewport fit, independent pane scroll, anchored header and composer, primary dominance, multi-signal dangerous modes, one state owner, compare-versus-judge panes, justified widths, saved views versus filters, actionable time, recommendation provenance, distinct facts/recommendations/side effects, explicit settings context, nested dependencies, outcome labels, and observable persistence. - **The CLEAR gap critique** retains all twelve gold-bar corrections: composition follows decision complexity; touch surfaces look touchable; selection uses several signals; consequential choices start unselected; child vocabulary survives selection; detail earns its place; instructions are not repeated; identity and escape stay visible; tablet space enlarges rather than shrinks; the grid quiets behind interaction; copy sounds natural; and next actions stay short. - **STAMP** is retired as a competing acronym, but its details remain: Space, Tiers, Align, and Minimal boxes live under Layout and mechanics; Plain state lives under Explicit change. - **Per-form-factor principles** live under Real device as explicit desktop/tablet/phone pass and reject criteria. - **Type, aspect, state, and target contracts** live under Real device and their mechanical owners: the closed metadata/body/panel-title/heading hierarchy, fixed iPad frame, state paint, 44 px tablet/phone targets, compile diagnostics, and browser geometry tests. - **LOOP** remains only the delivery workflow; **CRAP** remains the plan-page layout standard. ## Authoring ```mdx