.agents/skills/plate-plan/SKILL.md
Handle $ARGUMENTS.
This is the Plate editor-behavior planning and law workflow. It turns behavior ideas, review findings, or spec drift into:
docs/plans/docs/editor-behavior/docs/research/ when evidence is stale or thinUse this when the failure mode is "we keep finding more Plate planning gaps later."
pending.current_pass_status: complete; do not use
top-level done unless the whole lane is closed.done is legal only in the closure/final-gates pass, after the
active plan proves every earlier pass-state row is complete or explicitly
skipped with evidence.build-web-apps:shadcn for UI/editor chrome,
vercel-react-best-practices for React/Next/runtime performance, and
react-useeffect for effects, derived state, subscriptions, and external
synchronization. Use performance-oracle for hot paths, algorithms, memory,
network, query, bundle, and scalability concerns. Use tdd for behavior
additions, bug fixes, and regression classes that need test-first proof. If a
lens is skipped, record why.docs/plans/.docs/editor-behavior/ when law changes.docs/research/ when the evidence lane is stale,
contradictory, or incomplete.docs/plans/<same-slug>-objection-ledger.md and link it from the plan.applied or skipped with a concrete reason.Before creating or resuming a Plate Plan:
get_goal first. Call create_goal() only
when no goal exists; repeated create_goal() calls fail while a thread goal
exists.done means.Good goal:
Plate Plan proves the editor-behavior authority, node model, protocol rows,
and proof gates are ready for user review. Execution starts only when the user
accepts the plan and invokes Plate Plan again for that accepted plan.
Bad goal:
Run Plate Plan passes 1 through 9.
Default plan path:
docs/plans/YYYY-MM-DD-plate-plan-review-plan.md
Reuse an active plan when the prompt names one, or when the active goal and plan both point at the same surface and the latest user request is clearly resuming that lane.
Always read only what is relevant, but start from these sources:
docs/plans/ if present.docs/research/index.md,
and docs/research/log.md when present.Read when relevant:
../raw when compiled research is missing, thin, stale, or contradictory.build-web-apps:shadcn when UI, editor chrome, shadcn components, registry
components, overlays, command menus, inputs, forms, or styling are in scope.Use research-wiki when the compiled layer is stale, contradictory, or missing
coverage. For framework evidence, inspect local official clones under .. or
normalized ../raw before external docs.
If the review depends on current Plate behavior, cite live source files, docs, examples, or tests. If it depends on external editor behavior, cite the compiled research page or local source read used for the claim.
Current Plate source, docs, tests, generated artifacts, and editor-behavior law win over old plans, stale research notes, generated handoffs, and memory.
Before any pass, score, protocol/parity row, authority-map decision, ledger row, migration/adoption answer, docs/example answer, proof row, implementation phase, final handoff, or user-facing explanation that relies on what currently exists:
already done in live source and move the decision to docs/tests/spec
cleanup.decision: ...,
target shape: ..., or gap: ... instead of inventing a current state.Stale docs, old plans, audit history, and compiled research can explain why a decision exists, but they cannot prove current Plate behavior when live evidence is available.
For code/API/UI examples, grep the exact symbols first. For behavior-law claims,
read the relevant docs/editor-behavior/** files and any linked tests or
browser contracts first.
This applies to every related step, not only final before/after summaries. A protocol row, parity row, objection, proof matrix row, migration answer, implementation phase, or final chat answer can be wrong in the same way if it uses a stale current state.
The active goal is the durable lane state. The plan is the durable evidence and pass-state ledger. Do not create hook state for Plate Plan work.
Use the active plan for lightweight current-pass state:
current_pass: current-state-read
current_pass_status: in_progress
next_pass: intent-boundary-and-decision-brief
next_action: finish current pass and update the plan
goal_status: active
Complete the goal only when all completion gates pass. Use blocked only when
no autonomous progress is possible because evidence, tooling, access, or a user
decision is missing.
Allowed current_pass_status values:
pendingin_progresscompletereviseblockedskippedSingle-pass completion is invalid by default:
pendingdonependingBefore completing the goal, prove in the plan:
complete or intentionally skipped with a
concrete reason and evidencepending, in_progress, revise, or blocked with a
runnable next movecurrent_pass is the closure/final-gates passcurrent_pass_status is completenext_pass is nonenext_action is noneIf any assertion fails, keep the goal active and name the earliest runnable
next_pass.
Score every review pass from 0.00 to 1.00.
Weights:
| Dimension | Weight |
|---|---|
| Evidence and authority strength | 0.18 |
| Plate editor-behavior DX and product fit | 0.16 |
| Node model, affinity, and permanent-home coherence | 0.16 |
| Protocol, parity, and regression-proof testing | 0.20 |
| Research freshness and completeness | 0.15 |
| React/shadcn/effect implementation-review discipline | 0.10 |
| Roadmap and implementation-handoff clarity | 0.05 |
Score evidence rules:
0.80.0.85 without current citations for
external systems or local repos the review relies on.0.80 without named
replayable browser/unit/stress/protocol contracts.0.85 if package ownership,
performance cost, DX, and future consumer impact are not answered.0.80 when an applicable
shadcn, Vercel React, react-useeffect, performance-oracle, or tdd lens is
missing.0.85 when a lens is
marked applied or skipped without findings, plan deltas, or a concrete
skip reason.0.85.0.85.0.85
unless the invalidated alternatives are named and fairly rejected.Completion threshold:
All rows are conjunctive. Passing score is necessary but never sufficient.
>= 0.920.85unresolved, revise, or drop without a
corresponding plan responseIf any gate fails, status stays pending.
The plan must include:
Run the review as passes, not one giant essay:
The closure score and final gates are their own pass. Do not fold closure into
the previous pass. The closure pass may start only when every earlier
pass-state row is already complete or intentionally skipped with evidence.
After each pass, update the active plan with pass status, evidence, changes, and next owner. Keep the active goal open while any pass or revision remains runnable.
Pass-state ledger rows must include:
pending, in_progress, or completeDo not mark multiple major passes complete in one activation. Finish the current
pass, refresh the active continuation prompt, keep status pending, and let the
next activation run the next pass.
This workflow answers four questions:
That maps to:
For each output file, either patch it or state why it stayed unchanged. Do not leave a layer implicit.
Classify the request before editing:
Classify the feature family:
Classify the evidence state:
Before treating a plan as ready, record:
Gather repo facts before asking the user about internals. If one user answer is needed, ask exactly one high-leverage boundary question, not a questionnaire.
Pressure-test weak answers with one of:
Do not score ready while non-goals or decision boundaries are vague.
For every major behavior, authority, package-boundary, API, protocol, or proof decision, record:
If only one option is viable, say which alternatives were considered and why they are invalid. "No alternative" is not a reason; it is usually a missed pass.
Use the research layer before inventing new law.
Use research-wiki for choosing and running the right research mode when:
docs/research but needs refreshDo not skip the research layer and jump from a raw source into law unless the request is tiny and the evidence is already obvious.
Do not call research "full" if one likely corpus stayed silent. Silence is a gap, not agreement.
Use:
When recording evidence, use:
agreepartialgaptensiondivergeNever mark behavior locked because it feels standard.
Live source/docs/tests/generated artifacts and behavior-law files outrank
compiled research and previous plans when describing the current state. If they
disagree, record stale research, stale plan, or stale audit history and
update the active plan from live evidence.
Before writing UX law, lock:
Node model classes:
block non-voidblock void atominline non-void spaninline void atomleaf marktext tokenoverlay / no nodeAffinity classes:
directionalhardoutwardnone / n-aDo not spec hover, click, backlink, toolbar, or popover behavior until the model is explicit.
For any new shared contract or cross-surface rule, answer:
Candidate homes:
@platejs/coreIf the answer differs from current file placement, the spec should say so.
Use this order unless the task is small enough that a subset is obviously enough. If a file stays unchanged, record why.
Patch markdown-standards.md when:
Patch markdown-editing-spec.md to define:
If behavior includes editor chrome or navigation UI, define it in a way that is compatible with shadcn composition: popovers, commands, menus, triggers, truncation, keyboard composition, semantic styling, and no one-off overlay markup when a standard pattern exists.
If behavior includes React rendering, subscriptions, overlays, server/client boundaries, data fetching, or editor runtime projections, define the performance shape explicitly: what subscribes, what stays static, what work is deferred, and which Vercel React rule family applies.
If behavior includes effects, derived state, reset-on-prop behavior,
subscriptions, browser APIs, external stores, or data synchronization, define why
an effect is needed. Prefer render-time calculation, event handlers, keyed
resets, useMemo, or useSyncExternalStore when they express the behavior.
Patch editor-protocol-matrix.md to enumerate:
If a surface has different winners by scenario, split the rows. Do not keep one coarse row that lies.
Patch markdown-parity-matrix.md when:
Do not inflate the parity matrix for speculative future product ideas that are not current Plate features.
Patch master-roadmap.md when:
Do not strand implementation debt only in parity wording or a plan doc.
Patch markdown-editing-reference-audit.md only when:
Do not treat the audit as current law.
For current feature/current surface, update all affected layers:
For deferred or future surfaces, usually update:
deferred or specifiedDo not pretend deferred behavior is release-gated current behavior.
Before scoring above threshold, decide whether each review lens applies. Record the decision in the active plan even when skipped.
Use this matrix:
| Lens | Applies when | Must answer |
|---|---|---|
build-web-apps:shadcn | UI/editor chrome, components, registry components, menus, popovers, command palettes, inputs, forms, overlays, styling, or component composition are in scope | Are existing components used first? Are variants, semantic tokens, gap-*, size-*, truncate, cn(), accessible titles, grouped menu/select items, full Card composition, Button loading, and icon data-icon rules respected? |
vercel-react-best-practices | React/Next components, rendering, external-store subscriptions, data fetching, server/client boundaries, bundle size, or runtime performance are in scope | Are waterfalls avoided, bundles split sanely, server/client serialization minimized, global listeners deduped, subscriptions derived and narrow, expensive renders deferred, transient values kept in refs, and inline components avoided? |
react-useeffect | useEffect, useState for derived values, reset-on-prop, state synchronization, subscriptions, browser APIs, external systems, data fetching, or parent notifications are in scope | Is the effect actually synchronizing with an external system? Can the behavior be render calculation, useMemo, keyed reset, event handler, framework fetch, or useSyncExternalStore instead? |
performance-oracle | Hot paths, algorithms, large collections, memory lifetime, network/database I/O, bundle cost, editor runtime loops, browser event paths, or scalability are in scope | Is complexity bounded? Are allocations, subscriptions, listeners, network calls, and cache lifetimes controlled? What happens at 10x, 100x, and 1000x scale? |
tdd | Behavior additions, bug fixes, public interface changes, regression classes, or executable acceptance criteria are in scope | Is there a red-green-refactor slice through a public interface? Does the test verify behavior rather than implementation details? |
For each applicable lens, record:
applied or skippedDo not turn these lenses into generic busywork. If the plan is pure law with no UI, React, or effect surface, skip them with one sentence and keep moving.
Trigger this mode when a proposal changes:
When triggered, add to the active plan:
High-risk mode is not a separate workflow. It is one stricter pass inside this skill.
Simulate a skeptical Plate maintainer and serious downstream Plate user. The goal is to prevent "they changed things for no reason."
For every major behavior, authority, API, package-boundary, protocol, or parity change, record:
keep, revise, drop, or unresolved.Ledger rows are mandatory for changes like:
Rules:
0.85 in DX, authority, or
parity unless it has a ledger row with a convincing answer.keep and every required
field is concrete: evidence, steelman antithesis, tradeoff tension, rejected
alternative, adoption answer, docs/example answer, regression proof, and
ecosystem answers when triggered.TBD, says only
"cleaner", or lacks proof that a real user problem is solved.revise or drop.unresolved, revise, or drop rows must feed back into the plan before
completion can be done.Do not create separate full ledgers by default. Trigger this pass only when the proposal changes extension, plugin, package, rendering, collaboration, operation, identity, normalization, snapshot, or data-model behavior.
For each triggered ledger row, add short answers:
For core API/data-model changes, also name:
The pass catches ecosystem breakage. It does not veto every cleanup.
Every review pass must either change the plan or explicitly defend no change.
Record:
If pressure passes produce no plan delta and no explicit no-change defense, the
review is a rubber stamp and completion stays pending.
Before raising the score above threshold, run these passes and record the result in the plan:
When the score is below threshold, any required pass remains open, or any completion gate has a runnable next move:
When final gates pass, complete the planning goal and stop for user review. Implementation starts only after a later explicit execution request that invokes Plate Plan again against the accepted plan. That execution invocation must use a new execution-shaped goal, read the accepted plan, run the next implementation owner, record verification, and keep the goal active while any accepted owner remains runnable.
When setting completion to done, the final chat response must include a
concise but exhaustive bullet list of every accepted plan item and decision so
the user can review without opening the full plan.
Group bullets by surface when useful:
Each bullet should include:
add, keep, cut, rename, revise, or gateCurrent-state / before-after rules:
gap.before must be copied from live source, docs, examples, tests, generated
artifacts, behavior-law rows, or authoritative reference material.after must be an accepted target shape or already done.stale claim.decision: ...
or target shape: ... instead of inventing one.Do not list only highlights. If the plan accepts twenty decisions, the handoff lists twenty bullets. Keep each bullet short; group them instead of omitting items.
When the plan is still pending, say what score remains and what the next owner is.
When the plan reaches done, use this shape:
Plate Plan is ready for user review: [docs/plans/...](docs/plans/...)
Decisions:
- Authority: ...
- Node model: ...
- Editor-behavior outputs: ...
- Protocol/parity: ...
- Tests/proof: ...
Then tell the user to review the plan and invoke Plate Plan again with the accepted plan path to execute it. Do not paste the whole plan into chat. Do paste the exhaustive decision bullets.