description: Fix Slate v2 bugs in one pass with reproduction, behavior tests, architecture/DX/perf pressure, proactive rearchitecture when the patch is not the cleanest long-term shape, and final autoreview.
argument-hint: '[repair
Slate Patch
Handle $ARGUMENTS.
If the arguments start with repair <expectation>, run Repair Command. Otherwise
run the normal Slate Patch workflow.
Use this for Slate v2 bug fixes where the agent should fix the bug now, then challenge its own patch with Slate Plan-level architecture pressure before handoff. This is the implementation lane for "fix it, but do not ship a dirty local patch".
One pass means: reproduce, test, fix, re-architect if the first patch is not the right long-term shape, verify, autoreview, hand off. It does not mean "smallest diff wins".
Use When
- The user invokes
slate-patch. - The user reports a Slate v2 browser/editor bug and wants a fix, not a plan.
- Multiple recent bugs share a category: selection, focus, history, undo, multi-root, content roots, void roots, DOM coverage, hidden DOM, rendering, schema, normalization, clipboard, IME, or browser event ownership.
- A prior local patch fixed the symptom but smells like example-only glue, caller-specific branching, or test appeasement.
- The user invokes
slate-patch repair <expectation>because futureslate-patchruns missed a recurring proof, workflow, or handoff standard.
Do Not Use When
- The user asks only for an architecture plan or proposal. Use
slate-plan. - The user asks for a normal diff review. Use
autoreview. - The target is not Slate v2 or
.tmp/slate-v2. - The repair belongs to every goal-backed workflow. Use
autogoal repair. - The only honest next step is a multi-pass public API RFC with user review.
Say that and route to
slate-plan.
Hard Rules
- Current
.tmp/slate-v2source wins over memory, old plans, and prior diagnosis. - Run Slate v2 commands from
.tmp/slate-v2.plate-2commands do not prove Slate v2 behavior. - Benchmark target work runs from
plate-2throughbenchmarks/targets/slate-v2.jsonandpnpm bench:targets:*. It can route next work, expose benchmark gaps, and hand optimization toslate-ar-perf, but it never replaces.tmp/slate-v2reproduction, tests, or browser proof. - Reproduce first whenever practical. For browser routes, use the real route and behavior-level interaction, not only model-state calls.
- Add a behavior-level regression test when sane. Prefer tests that cover the bug class, not only the exact screenshot.
- Fix the ownership boundary. Package/runtime fixes beat example patches when the bug is systemic. Example patches are valid only when the example contract is wrong.
- Breaking changes are allowed when they produce the best long-term architecture/API/DX/perf result. Do not preserve bad compatibility by reflex.
- If the first patch is not the cleanest long-term shape, rework it before verification. Do not hand off "works but dirty".
- When multiple bugs in the same category appear, assume the subsystem is not robust enough. Search adjacent owners and add class-level coverage before calling the slice done.
- For selection/navigation bugs, use the generic editor navigation matrix. Do not scope coverage to only content roots, hidden blocks, voids, synced blocks, or the one route that exposed the failure.
- Do not create issue-ledger or PR-reference ceremony unless the prompt is issue-backed or explicitly asks for issue accounting.
- Final checklist item is always
autoreviewfor non-trivial implementation changes.
Boundary With Slate AR
- Correctness fails: use
slate-patch. - Generic measured loop with an existing proof surface: use
slate-ar. - Metric optimization with an existing correctness oracle: use
slate-ar-perf. - Missing oracle for a performance loop: add repro/test/browser proof here
first, then hand off to
slate-ar-perf. - A perf-sensitive correctness fix may end with a benchmark target handoff, not an Autoresearch packet loop.
Repair Command
Trigger when $ARGUMENTS starts with:
repair <expectation>
Repair Command updates this workflow so future slate-patch runs do the right
thing by default. It is for missed recurring behavior in the skill, not for
fixing Slate runtime bugs.
Use it for misses like:
- future patches should include a recurring behavior matrix;
- the skill forgot a required proof or handoff field;
- the workflow reviewed the wrong checkout;
- a recurring class of editor bugs was treated as a one-off local patch.
Do not use it for:
- runtime/product bugs in
.tmp/slate-v2; - one-off wording preferences;
- unrelated goal lifecycle misses that belong to
autogoal repair; - hand-editing generated
.agents/skills/*/SKILL.md.
Repair workflow:
- Restate the missed expectation in one sentence.
- Patch the source owner, normally
.agents/rules/slate-patch.mdc. - If the expectation is too large for the skill body, add or update a small
reference doc and link it from the skill. For selection/navigation coverage,
use
docs/slate-v2/selection-navigation-coverage.md. - After changing
.agents/rules/**, runpnpm installto regenerate.agents/skills/**. - Prove the repair with:
rgfor the new rule in.agents/rules/slate-patch.mdc;rgfor the regenerated text in.agents/skills/slate-patch/SKILL.md;- the relevant docs audit or syntax check when docs/scripts changed.
- Final response says: expectation, repaired owner, sync command, and proof.
Goal Setup
Use autogoal as the lifecycle kernel for non-trivial Slate Patch work.
This derived lane owns repro, behavior coverage, Slate v2 proof, architecture pressure, autoreview, and any benchmark handoff. Autogoal owns active-goal conflicts, objective shape, plan state, completion rules, blocker rules, and repair routing.
Goal handle:
Fix Slate Patch <bug/cluster>; done when repro, behavior coverage, Slate v2
proof, and autoreview pass; target `.tmp/slate-v2`.
Do not create a Slate Plan pass schedule. This skill is one implementation slice, not a planning lane.
Workflow
1. Reproduce And Bound
- Read the latest user report, attached media, route, issue, or failing test.
- Inspect the live owner in
.tmp/slate-v2. - Reproduce with the narrowest honest path:
- browser route and real keyboard/mouse input for UI bugs;
- package/unit test for pure model behavior;
- both when DOM import/export and model mutation can disagree.
- Capture:
- actual behavior;
- expected behavior;
- current model selection/value when relevant;
- DOM/native selection when relevant;
- owning package/example/test.
2. Classify The Bug Class
Name the class before patching:
- selection import/export
- focus ownership
- history/undo
- DOM coverage / hidden content
- multi-root / content root / void root
- synced/root state
- normalization / schema
- rendering/projection
- clipboard/paste
- IME/mobile/browser event ownership
- performance/scalability
If the class appeared recently in the thread or adjacent tests, broaden the fix. Search for sibling examples, package helpers, and tests that likely share the same broken assumption.
3. Red Test
Add or update the smallest behavior test that fails for the current bug:
- Playwright for browser-visible selection, focus, hidden DOM, mouse, keyboard, clipboard, and route regressions.
- Package tests for model transforms, schema, operation, history, normalization, and deterministic state behavior.
- Both when the browser symptom is caused by a model transform.
The test should assert the user-visible invariant and the model invariant when both matter.
Editor Selection Navigation Coverage
When the bug class touches selection, keyboard navigation, mouse selection,
focus handoff, history focus, DOM coverage, hidden DOM, multi-root, content
root, editable void, synced root, clipboard after selection, delete after
selection, or insert break after selection, pick a relevant slice from
docs/slate-v2/selection-navigation-coverage.md before writing the test.
The red test must name:
- command family: arrow, shift-arrow, option-arrow, shift-option-arrow, command-arrow, shift-command-arrow, mouse drag, delete, backspace, insert break, copy, undo, or redo;
- direction: forward, backward, up, down, into boundary, out of boundary, or across many boundaries;
- topology: plain blocks, hidden DOM, DOM coverage boundary, multi-root, content root, editable void, synced root, virtualized DOM, or mixed topology;
- starting state: collapsed, expanded forward, expanded backward, edge of block, multi-line, after focus handoff, or after history restore;
- assertions: exact model selection/value plus DOM selection/focus/chrome sanity when browser-visible behavior is involved.
Do not claim "fully tested selection/navigation" unless the proof covers the relevant command x direction x topology x starting-state rows. If the bug only needs a narrower slice, record the intentionally skipped rows and why.
For selectionPolicy: 'materialize' bugs, include the materialize-specific
coverage rows from docs/slate-v2/selection-navigation-coverage.md: first
vertical Shift+Arrow entry must open hidden DOM, and the next plain vertical
Shift+Arrow after mount must not remain model-owned unless it enters another
unmounted materialize boundary. Include a mid-line caret on the last rendered
line before hidden content, not only block-edge positions.
4. Fix The Owner
Patch the owner that makes the behavior generally true.
Use this ownership ladder:
- core package/runtime architecture;
- shared DOM/react bridge;
- schema/API contract;
- shared example/component pattern;
- one example only, when the example is the contract owner.
Prefer:
- fewer public concepts;
- narrower subscriptions and dirty scopes;
- deterministic model operations;
- schema-owned behavior over renderer guesses;
- root/content identity over DOM/index inference;
- stable browser proof over timing waits;
- deleting workaround code after the real owner is fixed.
Do not prefer:
- caller-specific branches;
- example-only masking of package bugs;
- compatibility shims for unreleased bad APIs;
- tests that assert implementation trivia;
- helper extraction when inline code is clearer and used once.
5. Architecture Pressure Review
After the first green patch, stop and review it like a harsh Slate maintainer. If any answer is weak, rework the patch before final verification.
Checklist:
- Architecture: Is this the cleanest long-term owner, or did we patch a symptom?
- API/DX: Would a raw Slate user or plugin author understand the contract without reading this bug thread?
- Unopinionated core: Did we keep Plate/product policy out of Slate core?
- Performance: Are hot paths bounded? Any global scans, broad rerenders, stale DOM reads, or repeated layout work?
- Data/model: Are paths, runtime ids, root ids, schema, and operation semantics deterministic after edits, undo, and remote-ish replay?
- Browser: Does DOM selection/focus/hidden content behavior match the model contract?
- Regression coverage: Does the test catch the class, including the sibling case that is likely to fail next?
- Breaking changes: If the clean fix needs a break, did we take it instead of keeping a bad shape alive?
- Simplicity: Can any helper, branch, option, shim, or test fixture be deleted?
Verdict must be one of:
keep: patch is the right long-term shape.rework: fix before final verification.escalate: stop and route toslate-planbecause the right fix is a broader public architecture decision.
6. Verify
Run focused gates from .tmp/slate-v2.
Pick the relevant set:
- changed package unit tests;
- changed package typecheck;
- changed site typecheck for examples;
- focused Playwright route tests;
- browser repro script when Playwright is not enough;
bun checkonly when the touched surface justifies a broader fast gate;bun check:fullonly for release-quality browser claims or when explicitly requested.
If a gate fails for unrelated existing debt, record the exact command and why it is unrelated. Do not hide a relevant failure.
7. Benchmark Target Handoff
After Slate v2 correctness proof, decide whether the patch needs benchmark
target sync or a slate-ar-perf handoff.
Run this when the bug class or patch touches performance/scalability,
rendering/projection, React rerender behavior, huge documents, history,
clipboard, collaboration, browser traces, operation replay, Slate-vs-Slate-v2
parity, or any behavior that should be covered by
benchmarks/targets/slate-v2.json.
Workflow:
- From
plate-2, inspectbenchmarks/targets/slate-v2.jsonand runpnpm bench:targets:check. - Use
pnpm bench:targets:listornode tooling/scripts/slate-autoresearch.mjs suggest-loops --with-checksto find the matching target. - If a target exists, run
pnpm bench:targets:dry-run -- <target-id>and record whetherslate-ar-perfshould own further optimization. - If no target exists, record
Benchmark target candidate needed - <behavior>and the likely benchmark plus correctness command. - If the correctness oracle is missing, keep ownership in
slate-patchuntil the test/browser proof exists.
Do not run this as a tax on tiny model-only fixes with no benchmark family. Also do not skip it for perf-sensitive editor behavior just because focused tests passed. Tests prove correctness; the target registry keeps the benchmark backlog honest.
8. Autoreview
Final checklist item for non-trivial implementation changes:
- Load
.agents/skills/autoreview/SKILL.md. - Run the helper from the checkout that owns the patch.
- For
.tmp/slate-v2patches, cwd must be.tmp/slate-v2:
/Users/zbeyens/git/plate-2/.agents/skills/autoreview/scripts/autoreview --mode local
- Verify every accepted/actionable finding against source.
- Fix valid findings.
- Rerun focused proof and autoreview until no accepted/actionable findings remain.
Do not run dirty-local autoreview from plate-2 for .tmp/slate-v2 patches.
That reviews the wrong checkout.
Final Response
Keep it short. Include:
- root cause;
- architectural decision and whether anything was reworked after pressure review;
- selection/navigation matrix slice covered or intentionally skipped when applicable;
- tests/proof run with cwd when not obvious;
- benchmark target handoff when applicable: target dry-run,
slate-ar-perfhandoff, candidate target needed, or N/A with reason; - autoreview result;
- any relevant unresolved gate or unrelated existing failure.
If the architecture pressure verdict is escalate, say exactly why and name the
slate-plan surface to open next.