- description
- Review Slate v2 architecture/API plans against React 19.2 runtime performance, Slate-close unopinionated DX, legacy-regression proof, research evidence, and shadcn-style composability; write a scored plan and keep completion pending until every required pass and closure gate is complete.
- argument-hint
- [--quick|--standard|--deep] <Slate v2 architecture/API review prompt>
- disable-model-invocation
- true
- name
- slate-plan
- metadata
- {"skiller":{"source":".agents/rules/slate-plan.mdc"}}
# Slate Plan
Handle $ARGUMENTS.
Use this for repeated "harsh honest, absolute best Slate v2 architecture/DX"
review prompts where the failure mode is death by incremental suggestions.
This is a two-phase lane skill.
Planning mode is the default. It creates or updates the execution-grade plan,
scores it, and uses the active goal as the durable lane contract until every
required pass, issue/reference sync gate, verification gate, and closure score
gate is complete. Score is only one input. A high score never permits goal
completion by itself; planning completion means the full pass schedule is
closed and the plan is ready for user review.
Execution mode starts only after the user explicitly accepts a ready plan and
invokes `slate-plan` again for that plan. Execution mode creates or continues a
new goal for the accepted plan's implementation target and then executes the
next plan owner with fresh verification evidence. Do not use the planning goal
as the execution goal. The user-review boundary is real.
## Use When
- Reviewing Slate v2 architecture, public API, hooks, runtime boundaries, or
render contracts.
- Executing a user-accepted Slate Plan against the live `.tmp/slate-v2`
workspace after a second explicit invocation names the accepted plan.
- The user asks whether the plan is the absolute best shape for:
- React 19.2 runtime performance
- unopinionated Slate-close DX
- Plate and slate-yjs migration
- regression-proof browser behavior
- Lexical / ProseMirror / Tiptap evidence
- shadcn-style composability and minimal props
- The user says repeated review keeps producing more suggestions and wants a
methodical plan-confidence gate.
## Do Not Use When
- The user asks for a narrow bug fix or browser repro.
- The user asks for a normal code review of a diff.
- The request has no plan and no architecture/API/spec lane shape; use `task`
or the issue-specific skill instead.
## Hard Policy
- In planning mode, do not patch Slate v2 implementation code. Planning mode may
edit only planning, research, issue-ledger, and PR-reference artifacts it
explicitly owns.
- In execution mode, Slate Plan may edit `.tmp/slate-v2` implementation, tests,
examples, package files, build config, and related reference docs only when
the latest user message explicitly accepts the ready plan or asks this skill
to execute that named plan.
- User phrases like "go", "rewrite", "feel free to build", "fix it", or
"execute" do not override planning mode when the plan is not yet
user-review-ready. Convert them into plan decisions and proof rows. Once the
plan is ready and the user explicitly accepts it, the same phrases can start
execution mode.
- Requires `autogoal` as the lifecycle kernel, `--template slate-plan` as the
plan shell, and one scheduled pass per activation.
- Slate Plan owns pass schedule, scorecard, ledgers, workspace proof, and final
handoff. Autogoal owns goal conflict, completion, and blocker semantics.
- Never write contradictory closeout state. If the plan has pending passes,
pending final handoff, or a runnable next action, the lane is not closed.
- Treat pasted review findings as context. The latest user request is the task.
- Keep Slate v2 unopinionated. Plate owns opinionated product APIs.
- A breaking or paradigm change needs an adoption story. "Cleaner architecture"
alone is not a justification.
- Prefer inline example logic when it is only used once. Do not invent local
helpers like `isAtStartOfX`, `getActiveX`, or `applyX` just to make a plan
look tidy. Extract a helper only when the same logic is reused, the inline
block is genuinely distracting, or the helper is the proposed public/internal
API being reviewed.
- Example DX matters: a Slate example should show the actual API shape at the
call site first. Helper extraction is a readability tool, not a default
architecture move.
- Intent, outcome, scope, non-goals, and decision boundaries must be explicit
before the plan can score as ready.
- Major decisions need a decision brief: principles, top drivers, viable
options, rejected alternatives, and why the chosen option wins.
- Plate/slate-yjs migration means architecture backbone, not support for their
current public APIs. Do not require current-version Plate adapters,
`editor.api` / `editor.tf` compatibility, or current slate-yjs integration
fixtures from raw Slate.
- Use current Plate/slate-yjs source only to understand migration pressure.
Required proof is substrate-level: `state` / `tx` extension namespaces,
schema/spec policy, deterministic operations/snapshots/commits, commit
metadata, and local-only target semantics.
- If a change touches extension, plugin, collaboration, operation, or data-model
surfaces, a raw-Slate answer alone is insufficient.
- Do not let a polished plan self-certify. Scores, verdicts, and keep/drop
decisions need cited evidence.
- Workspace verification is part of evidence. `plate-2` commands prove only
planning, ledgers, and completion-state artifacts. Any Slate v2 source,
runtime, browser, package, public API, or issue-fix claim must be verified
from the live `.tmp/slate-v2` workspace with the relevant `.tmp/slate-v2` command.
- Do not count `bun run test`, typecheck, lint, Playwright, or package filters
run in `plate-2` as Slate v2 verification. They may be recorded only as
plan-artifact checks.
- If execution mode touched `.tmp/slate-v2`, Slate Plan closure must require the
applicable `.tmp/slate-v2` verification command set.
A failing relevant `.tmp/slate-v2` command keeps the plan or execution review
`pending` unless the failure is proven unrelated with a cited command,
failing scope, and owner.
## Required Artifacts
- Plan file under `docs/plans/`.
- Create the plan from the Slate Plan goal template:
```bash
node .agents/skills/autogoal/scripts/create-goal-scratchpad.mjs \
--template slate-plan \
--title "<short Slate Plan title>"
```
The reusable project template is `docs/plans/templates/slate-plan.md`.
Runtime plans still go directly under `docs/plans/`; do not use `docs/goals`.
After creating the static plan, edit the generated file and fill the lane
objective, pass schedule details, closure threshold, verification surface,
constraints, boundaries, and blocked condition there.
- Active goal for planning mode: one Slate Plan planning lane uses one
short `create_goal` objective. The goal content must stay under 240
characters and name only the desired closed plan state, short completion
threshold, and plan path. Put the full pass schedule,
one-pass-per-activation policy, proof gates, user-review-ready closeout, and
blocked condition in the plan. Do not split the planning lane into multiple
goals.
- Active goal for execution mode: after explicit user acceptance, start a new
goal for the accepted plan path and implementation target. Keep that goal
objective short and put the execution queue, `.tmp/slate-v2` verification
gates, issue/reference sync, autoreview requirement, and closeout conditions
in the execution plan. For dirty local work, the autoreview skill's target is
`--mode local`; do not use `--uncommitted`.
- Research updates under `docs/research/` when the evidence lane is stale or
incomplete.
- Issue-ledger accounting in the active plan: fixed issue claims, related issue
classifications, cluster coverage, and explicit non-claim decisions grounded
in `docs/slate-issues`.
- ClawSweeper related-issue pass in the active plan whenever the plan changes
Slate v2 public API, runtime behavior, browser behavior, examples, issue
claims, or PR narrative. Run it once per related surface, not after every v2
edit. Re-run only when the touched issue surface changes materially.
- Issue discovery is ledger/cache-first. Reuse existing ClawSweeper output in
`docs/slate-v2/ledgers/fork-issue-dossier.md`,
`docs/slate-v2/ledgers/issue-coverage-matrix.md`,
`docs/slate-issues/gitcrawl-v2-sync-ledger.md`, and generated live rows
before any live GitHub read. Do not run broad `gh issue list`,
`gh search issues`, or unscoped live GitHub discovery from Slate Plan just
to refresh known corpus counts or already-classified surfaces.
- Live issue corpus input:
`docs/slate-issues/gitcrawl-live-open-ledger.md` is generated live gitcrawl
data only. Read it for current open rows and gitcrawl cluster IDs; do not add
manual classifications there.
- Current manual issue sync updates in
`docs/slate-issues/gitcrawl-v2-sync-ledger.md`: update current issue
classifications whenever a plan or implementation slice claims, improves,
reviews, or intentionally excludes an issue or cluster. If the file does not
exist yet, create it before recording current live sync state.
- Frozen corpus context in `docs/slate-issues/open-issues-ledger.md`: use it as
the `682`-issue historical classification seed, not as current live sync
truth.
- Fork issue dossier updates in
`docs/slate-v2/ledgers/fork-issue-dossier.md`: append one self-contained
section per reviewed related issue, using ClawSweeper's Fork Issue Dossier
Mode. This replaces upstream GitHub issue comments for the fork.
- Issue coverage ledger updates in
`docs/slate-v2/ledgers/issue-coverage-matrix.md`: every fixed issue must
appear as `Fixes #....: <description>`, and every related but not-fixed issue
must be categorized in the related issue matrix.
- PR reference sync in `docs/slate-v2/references/pr-description.md`: keep exact
fixed issue claims and counts, accepted current API shape, proof references,
not-claimed release gates, and a link to the full issue coverage ledger.
- Slate maintainer objection ledger in the active plan, with ecosystem answers
when triggered. If it grows too large, split it to
`docs/plans/<same-slug>-objection-ledger.md` and link it from the plan.
- Plan deltas from review in the active plan: what changed, what was dropped,
what was strengthened, and what stayed unchanged with reasons.
- Intent/boundary record in the active plan: intent, outcome, in-scope,
non-goals, decision boundaries, and unresolved user-decision points.
- Decision brief in the active plan: principles, decision drivers, viable
options, invalidated alternatives, consequences, and follow-ups.
- Ecosystem strategy synthesis in the active plan whenever Lexical,
ProseMirror, Tiptap, React, Plate, slate-yjs, or another reference system is
used as evidence. This is not a citations list; it must state the mechanism
Slate should steal, reject, or deliberately diverge from.
- Applicable implementation-skill review notes in the active plan: Vercel
React, performance-oracle, and tdd, plus shadcn/react-useeffect when relevant,
each marked `applied` or `skipped` with a concrete reason.
- Allowed edit scope in planning mode: `docs/plans/**`, `docs/research/**`,
`docs/slate-issues/**`, `docs/slate-v2/ledgers/**`, and
`docs/slate-v2/references/**`.
- Allowed edit scope in execution mode: the accepted plan's named `.tmp/slate-v2`
implementation, test, example, package, build, config, and reference-doc
owners, plus the active plan ledger.
## Goal Setup
Slate Plan requires `autogoal` as the lifecycle kernel.
- Template: `slate-plan`.
- Planning flow mode: agent-led plan hardening.
- Execution flow mode: one-shot execution after explicit acceptance of a named
ready plan.
- Goal handle: `<lane outcome>; done when <short threshold>; plan
<docs/plans/path>`.
- One pass per activation. Passes are rows in the active plan, not separate
goals.
- Autogoal owns `get_goal`, `create_goal`, `update_goal`, conflict handling,
completion, blocker semantics, and repair routing. Do not duplicate those
rules here.
- Slate Plan owns plan shape, pass table, scorecard, issue/reference ledgers,
workspace verification, objection ledger, and final handoff.
- Do not start execution mode under a planning goal. After user acceptance, use
an execution-shaped goal that names the accepted plan and proof gates.
- If no goal tool is available, record degraded control state in the active plan
and stop before autonomous pass work unless the user explicitly accepts that.
Good goal:
```txt
Close callback-memoization API plan; done when Slate Plan closure gates pass;
plan docs/plans/YYYY-MM-DD-callback-memoization-plan.md.
```
Good execution goal:
```txt
Execute docs/plans/<accepted-plan>.md; done when execution closeout gates pass;
target `.tmp/slate-v2`.
```
Bad goal:
```txt
Run Slate Plan passes 1 through 12.
```
Default plan path:
```txt
docs/plans/YYYY-MM-DD-slate-v2-absolute-architecture-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.
## Read First
1. Latest user request.
2. Current goal state, if a goal tool exists.
3. Active plan under `docs/plans/` if present.
4. `docs/research/README.md`, `docs/research/index.md`, and
`docs/research/log.md`.
5. `docs/slate-issues/gitcrawl-live-open-ledger.md`,
`docs/slate-issues/gitcrawl-v2-sync-ledger.md` when it exists,
`docs/slate-issues/open-issues-ledger.md`,
`docs/slate-issues/gitcrawl-clusters.md`,
`docs/slate-issues/issue-clusters.md`,
`docs/slate-issues/test-candidate-map/`,
`docs/slate-issues/benchmark-candidate-map.md`,
`docs/slate-issues/package-impact-matrix.md`, and
`docs/slate-issues/requirements-from-issues.md`.
6. `docs/slate-v2/ledgers/issue-coverage-matrix.md`,
`docs/slate-v2/ledgers/fork-issue-dossier.md`, and
`docs/slate-v2/references/pr-description.md`.
7. Relevant compiled research pages for Lexical, ProseMirror, Tiptap, Slate,
React 19.2, node/render DX, and browser proof.
8. Live `.tmp/slate-v2` API surfaces touched by the review.
Read when relevant:
- Intent/boundary pressure when intent, scope, non-goals, or decision
boundaries are unclear. Record the answer directly in this Slate Plan.
- Steelman pressure when major decisions need maintainer/user objection rows.
Record the strongest fair objection, tradeoff tension, and adoption answer in
this Slate Plan.
- High-risk deliberate pressure when a proposal changes public API, data model,
collaboration, runtime, browser behavior, migration, release gates, or package
boundaries. Record the pre-mortem and expanded proof plan in this Slate Plan.
- [vercel-react-best-practices](.agents/skills/vercel-react-best-practices/SKILL.md)
when React rendering, subscriptions, external stores, bundle shape, browser
event listeners, or runtime performance are in scope.
- [performance-oracle](.agents/skills/performance-oracle/SKILL.md) when hot
paths, algorithms, memory, browser/editor runtime, scalability, or measured
performance risk is in scope.
- [performance](.agents/skills/performance/SKILL.md)
when a performance lane needs GitHub-scale cohorting, repeated-unit budgets,
interaction-level INP/p95/p99 rows, memory tagging, degradation policy, or
production dashboard/RUM proof beyond generic React and algorithmic advice.
- [tdd](.agents/skills/tdd/SKILL.md) when the plan changes behavior, fixes a
regression class, or needs test-first acceptance criteria.
Use `research-wiki` when the compiled layer is stale, contradictory, or missing
coverage for the current question. For framework evidence, inspect local
official clones under `..` or normalized `../raw` before external docs.
If the review depends on current `.tmp/slate-v2` behavior, cite live source files
or tests. If it depends on React 19.2, Lexical, ProseMirror, Tiptap, or Slate
legacy behavior, cite the compiled research page or local source read used for
that claim.
## Live Source Grounding
Current Slate v2 source wins over every plan, research note, legacy Slate memory,
and previously generated handoff.
Before any pass, score, ledger row, migration answer, docs/example answer,
proof row, implementation phase, final handoff, or user-facing explanation that
relies on what currently exists:
1. Re-read the live `.tmp/slate-v2` source, example, test, or generated contract
that owns the shape.
2. State the exact current owner: file, test, route, generated contract, or
explicit gap.
3. Quote or summarize the current shape only if it exists on disk in the current
checkout.
4. Attach a file/line pointer in the plan or handoff.
5. If the live source already matches the proposed target, write
`already done in live source` and move the decision to docs/tests/cleanup
only.
6. If no live current shape exists, write `decision: ...`, `target shape: ...`,
or `gap: ...` instead of inventing a current state.
Stale docs and closed plans are not current API evidence. They can explain why
a decision exists, but they cannot prove what `.tmp/slate-v2` exposes today.
For render/API examples, grep the exact symbols first. Examples:
- `rg -n "RenderVoidProps|renderVoid|renderElement" .tmp/slate-v2/packages/slate-react .tmp/slate-v2/site`
- `rg -n "EditorExtension|commands\\?|setup\\(|extend\\(" .tmp/slate-v2/packages/slate/src`
- `rg -n "useElementSelected|useNodeSelector|useEditorState" .tmp/slate-v2/packages/slate-react/src`
Do not translate from old Slate by memory. If the current code says void
renderers already receive content-only props, do not describe a migration from
`attributes` / `children` void renderers. If the current code exposes
`commands?: EditorExtensionCommand[]`, do not describe a fake command-object
map.
This applies to every related step, not only final before/after summaries. A
maintainer objection, proof matrix row, migration answer, docs answer,
implementation phase, or final chat answer can be wrong in the same way if it
uses a stale "before". Re-ground those steps before writing them.
## Verification Workspace Gate
Slate v2 verification runs in `.tmp/slate-v2`, not in this planning repo.
Rules:
1. Before scoring, closing, or reviewing an implementation slice that changes or
claims `.tmp/slate-v2` behavior, run the relevant command `.tmp/slate-v2` dir.
2. Record the exact command, cwd, result, and failure scope in the active plan.
3. Broad Slate v2 closure after an execution pass needs the broadest
feasible `.tmp/slate-v2` gate for the touched surface. If `bun run test` is
the project-level release gate and it fails, closure stays `pending` until
the failure is fixed, isolated as unrelated, or explicitly moved to a
recorded owner.
4. Focused gates are acceptable during intermediate passes, but the plan must
name the remaining broad `.tmp/slate-v2` gate before calling the implementation
release-ready.
5. If tooling, time, browser availability, or device access prevents a required
`.tmp/slate-v2` gate, record `verification gap: <command>` and keep status
`pending` or `blocked` according to whether more autonomous work remains.
Common command ownership examples:
- Core package changes: run the relevant `bun --filter slate ...` test/typecheck
from `.tmp/slate-v2`, then the broader `.tmp/slate-v2` gate named by the package.
- React/runtime/browser changes: run focused `slate-react` tests and matching
Playwright rows from `.tmp/slate-v2`; do not use `plate-2` tests as proof.
- Public API/export changes: run public-surface contracts from `.tmp/slate-v2`.
- Issue-fix claims: run the exact proof route from `.tmp/slate-v2` and keep issue
claims conservative until it passes.
- Planning-only docs/ledger changes in `plate-2`: run the relevant source sync
and targeted text checks; no Slate v2 test claim may be made from that alone.
## Goal And Plan State
Use autogoal lifecycle rules. Slate Plan-specific state lives in the active
plan:
- `current_pass`
- `current_pass_status`
- `next_pass`
- `next_action`
- `slate_plan_lane_status`
- `final_handoff_status`
At activation, resolve the target plan path from the latest user request or the
active goal, read the pass-state ledger, run exactly the first runnable pass,
and update the plan.
Allowed `current_pass_status` values:
- `pending`
- `in_progress`
- `complete`
- `revise`
- `blocked`
- `skipped`
Before Slate Plan closure, prove in the plan:
- every scheduled pass row is `complete` or intentionally `skipped` with a
concrete reason and evidence
- no pass row is `pending`, `in_progress`, `revise`, or `blocked` with a
runnable next move
- `current_pass` is the closure/final-gates pass
- `current_pass_status` is `complete`
- `next_pass` is `none`
- `next_action` is `none`
Ver en GitHub