Skip to content

refactor(development-pr-workflow): convert backtest-change from command to skill - #553

Merged
wkoutre merged 5 commits into
nextfrom
feat/backtest-change-as-skill
Aug 3, 2026
Merged

refactor(development-pr-workflow): convert backtest-change from command to skill#553
wkoutre merged 5 commits into
nextfrom
feat/backtest-change-as-skill

Conversation

@dylanschmittle-uniswap

@dylanschmittle-uniswap dylanschmittle-uniswap commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

What

Converts backtest-change from a command into a skill, leaving the command as a thin wrapper that delegates to it.

Why

backtest-change has gate semantics — its description literally reads "Before opening a PR for a data-driven change… Refuses to ship when the data disproves the premise." Its entire value is firing at a moment the user will not think to invoke it.

But commands only run when explicitly typed. A gate implemented as a command can never fire.

Observed live: during INC-357 a request came in to "add a monitor on container.memory.rss by host at ~700 MB warn / ~1.2 GB alert" — a textbook match for this command's description, right down to "monitor threshold". The command never entered the picture. The backtest happened only because a memory file independently said to always backtest tunes.

That backtest then rejected the proposed number: a third host had held 1.34–1.37 GB flat for ~21 consecutive hours with no incident, so a 1.2 GB critical would have paged for most of a day. Shipped 1.6 GB instead (Uniswap/backend#11074). Exactly the outcome this gate exists to produce — reached without it.

Audit context

Reviewed all 7 commands across the toolkit. This is the only miscategorisation:

Command Verdict
backtest-change Gate semantics, no skill counterpart — can never fire. Converted here
review-pr Correct. Skill counterpart review-code already handles auto-trigger
update-claude-md, claude-init-plus Correct. Skill counterpart update-claude-docs handles auto-trigger
linear-task-and-pr-from-changes, start-linear-task, work-through-pr-comments Correct. User-initiated, flag-driven, side-effectful or explicitly interactive

The toolkit already uses a deliberate dual pattern — skill for the unprompted case, command for the parameterized run — which is what makes backtest-change conspicuous as the only gate with no skill half. This PR gives it one.

Changes

  • New skills/backtest-change/SKILL.md — the full workflow, with a description carrying upstream triggers so it fires when a number is proposed, not only when a PR is imminent: "add a monitor at 700MB", "set the threshold to N", "warn at X / critical at Y", "change the sampling rate", "tighten this alert".
  • Rewrote commands/backtest-change.md as a thin wrapper preserving argument-hint and $ARGUMENTS parsing, so /backtest-change still works for deliberate runs.
  • Updated the plugin CLAUDE.md — skill list, command list, directory tree.

Two additions to the workflow, both learned from the INC-357 run:

  • Population separation step — report the highest legitimate value against the lowest incident value. If they overlap the threshold cannot work at any setting, and the signal itself needs to change.
  • REVISED verdict — the goal is sound but the proposed number isn't. The existing taxonomy only had EFFECTIVE / PARTIAL / INEFFECTIVE, which didn't cover the most common real outcome.

Plus a framing line stated explicitly: a user-supplied number is a hypothesis, not a specification.

Blast radius

Additive. /backtest-change keeps working with the same arguments and same behaviour. No other command, skill, or agent is touched. Docs/markdown only — no code, no hooks, no CI.

Correction (review round 1)

The first revision of this body claimed "skills are auto-discovered from skills/ — no plugin.json change needed", and ticked that as validated. That was wrong, and the review caught it as blocking.

Skills in this repo are not auto-discovered — CLAUDE.md is explicit that a skills array entry is required, and .claude/rules/plugin-docs.md makes "plugin.json skills array matches actual skill directories" a required verification step. Without it this PR would have shipped the file but not the behaviour it is justified by, which is the one failure mode the PR is supposed to prevent.

I generalised from a different marketplace whose manifest omits the skills array, and did not check this repo's. Both blocking items are fixed in 030fb90; the version bump was also missed and is included.

Validation

  • quick_validate.py passes on the new skill
  • Description under 1024 chars, no angle brackets
  • Registered ./skills/backtest-change in plugin.json and bumped the plugin 2.2.02.3.0 (minor, per CLAUDE.md: new skill)
  • Verified the skills manifest exactly matches the skills/ directory listing — no manifest-only or dir-only entries
  • model: opus added, matching 4 of 5 sibling skills
  • Command frontmatter keeps argument-hint + allowed-tools, so /backtest-change is unchanged from a caller's view
  • Not yet verified that the skill actually auto-triggers in a live session — worth one deliberate test ("add a monitor at N") before merge

Not in this PR

The audit also flagged that update-claude-md exists as a command here and as a skill in the Uniswap backend repo. A rename would be the correct fix but it touches 22 files, including scripts/lefthook/update-claude-docs.sh, which shells out to claude -p "/update-claude-md" from a git hook. That is a separate change with a real breakage path and does not belong bundled with this one. Details in the PR discussion.

Left as a draft for review.

@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ai-toolkit-slack-oauth-backend Ready Ready Preview Aug 3, 2026 4:42pm

Request Review

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

📚 Documentation Check ✅

Verdict: Passed

The critical requirement (plugin version bump) is satisfied: development-pr-workflow's plugin.json was bumped 2.2.0 → 2.3.0 (correct minor bump for a new skill), and the root CLAUDE.md version table was kept in sync. Plugin CLAUDE.md and README.md were both updated to document the new backtest-change skill, the reworked thin-wrapper command, and the new file-structure entry. Only a minor, non-blocking ordering inconsistency was found.


Documentation Review — PR #553

Checks performed:

  1. Plugin version bump (CRITICAL) — ✅ packages/plugins/development-pr-workflow/.claude-plugin/plugin.json bumped 2.2.02.3.0. Minor bump is correct semver for a new skill addition (backward-compatible). Confirmed on disk: plugin.json currently reads 2.3.0 and skills array includes "./skills/backtest-change".
  2. Root CLAUDE.md version table — ✅ Updated in the same diff to match (development-pr-workflow | 2.3.0), keeping the table in sync with the plugin manifest per the project's documentation rule.
  3. Plugin CLAUDE.md — ✅ Updated: new skill bullet added under ### Skills (./skills/), the backtest-change command description rewritten to reflect its new role as a thin wrapper around the skill, and the File Structure diagram gained backtest-change/ under skills/ (alphabetically placed, matches disk layout).
  4. Plugin README.md — ✅ Skills table gained a backtest-change row (alphabetically first, consistent with plugin.json ordering); commands table column widths were re-aligned for the existing rows (cosmetic, no content change).
  5. Naming conventions — ✅ backtest-change follows the required verb-noun pattern for skills/commands; no new agent was added, so no noun-role naming check needed.
  6. Changelog — N/A. This repo does not maintain per-plugin CHANGELOG.md files (verified none exist under packages/plugins/*), so there's nothing to check here; this is informational only per the validator's own rules.

Minor, non-blocking observation:

In packages/plugins/development-pr-workflow/CLAUDE.md, the ### Skills (./skills/) bullet list places backtest-change third (between resolve-pr-issues and review-code) rather than first. Every other listing touched by this PR — plugin.json's skills array, the README skills table, and this same file's own "File Structure" diagram — is alphabetical with backtest-change first. This is purely cosmetic and doesn't affect functionality or discoverability, so it doesn't block the PR, but it's worth a quick fix for consistency.

Verdict: PASS — the blocking requirement (version bump) is met, and both CLAUDE.md files plus the README were meaningfully updated to reflect the new skill and the command's changed role.

Suggestions (1)

💡 Inline suggestions have been posted as review comments. Click "Commit suggestion" to apply each fix directly.

  • ℹ️ packages/plugins/development-pr-workflow/CLAUDE.md: Reorder the Skills bullet list alphabetically so it matches the ordering already used in plugin.json's skills array, the README skills table, and this same file's File Structure diagram (all of which list backtest-change first).

🤖 Generated by Claude Documentation Validator | Mode: suggest

@dylanschmittle-uniswap
dylanschmittle-uniswap marked this pull request as ready for review July 28, 2026 20:26
@dylanschmittle-uniswap
dylanschmittle-uniswap requested a review from a team as a code owner July 28, 2026 20:26
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

● Reviewed · against 4322707 · 2026-08-03 16:46 UTC · view run ↗

Note

Approved — one warning on the wrapper command's skill reference.

Converts backtest-change from a command into a skill so its gate semantics can fire unprompted, keeping /backtest-change as a thin wrapper; the manifest, version bump (2.2.0 → 2.3.0), and all three doc surfaces are in sync with the new shape.

Assessment

The old command body carries over intact — all six workflow steps, the verdict taxonomy, and the output format are present in the new SKILL.md, plus the two documented additions (population separation, REVISED verdict). The one portability gap is in the wrapper: it points at the skill via a monorepo-absolute path that only resolves inside this checkout, diverging from the @../ and name-only delegation patterns every other plugin command uses.

Suggestions

  • Monorepo-absolute skill path in the wrapper. packages/plugins/.../SKILL.md doesn't exist for a marketplace-installed consumer; use the plugin-relative @../skills/backtest-change/SKILL.md form like the sibling commands. view inline thread →

Tip

Teach the reviewer. React 👍 on findings that helped, 👎 on false positives. Reply to push back or add context — we aggregate this weekly to tune the bot.

Comment @request-claude-review to re-run.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: REQUEST_CHANGES

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only. 1 inline comment(s) are attached below.

…e/SKILL.md

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@github-actions
github-actions Bot dismissed their stale review July 29, 2026 17:01

Superseded by new review after PR update

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: REQUEST_CHANGES

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only.

…ugin to 2.3.0

Addresses review on #553:
- register ./skills/backtest-change in plugin.json (skills are not
  auto-discovered in this repo; CLAUDE.md requires the manifest entry)
- bump plugin 2.2.0 -> 2.3.0 (minor: new skill)
- add model: opus to match sibling skills
@github-actions
github-actions Bot dismissed their stale review July 29, 2026 17:05

Superseded by new review after PR update

github-actions[bot]
github-actions Bot previously approved these changes Jul 29, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: APPROVE

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only.

…able, sync root version table

Addresses review round 2 on #553:
- README skills table was missing the new skill (plugin inventory drift)
- root CLAUDE.md version table still said 2.2.0

Also picks up pre-existing prettier debt in the README Commands table,
which was already non-compliant under the repo's pinned prettier 2.8.8.
@github-actions
github-actions Bot dismissed their stale review July 29, 2026 17:49

Superseded by new review after PR update

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review verdict: APPROVE

👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.

This formal review submission is for the verdict only.

@wkoutre
wkoutre enabled auto-merge (squash) August 3, 2026 16:40
@wkoutre
wkoutre merged commit 7eb5c55 into next Aug 3, 2026
16 of 17 checks passed
@wkoutre
wkoutre deleted the feat/backtest-change-as-skill branch August 3, 2026 16:42

Validate a **data-driven change against real historical data before opening the PR** — and be willing to abandon or redirect the approach when the data says it won't work. This is the gate that stops a plausible-but-ineffective change from shipping.
Load and follow the **`backtest-change` skill**
(`packages/plugins/development-pr-workflow/skills/backtest-change/SKILL.md`),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ warning · portability — This is the only command body in the repo that references an in-plugin file by monorepo path. For a marketplace-installed consumer, packages/plugins/... doesn't exist in their checkout, so the Read misses and the wrapper falls back to name-based loading. Sibling commands use the plugin-relative form (start-linear-task.md:108, linear-task-and-pr-from-changes.md:141).

Suggested change
(`packages/plugins/development-pr-workflow/skills/backtest-change/SKILL.md`),
(`@../skills/backtest-change/SKILL.md`),

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Approved — see full review in the sticky comment ↑

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants