| name | patch-md |
| description | Interpret and apply a `patch.md` file — the open markdown format for declarative, AI-native code transformations. Handles both source-tree patches (RFC 0001) and overlay / runtime-injection patches (RFC 0002, for userscripts, browser extensions, service workers, CDN edge, game mods, and any other host the author doesn't own). Use this skill whenever the user asks you to apply, run, execute, or "use" a patch.md file; whenever the user points you at a file named `*.patch.md` or `patch.md`; whenever a file they share opens with a `# patch.md` heading and contains sections like `## files`, `## overlay`, `## verify`, or `## meta`; whenever the user describes wanting to apply a packaged code transformation, codemod-like change, shareable integration recipe, userscript, userstyle, runtime injection, or behavioral overlay to a host they use but don't own. Even if the user does not name the format explicitly, trigger this skill as soon as you recognize the convention. |
patch.md
A patch.md file is a structured markdown document that declaratively describes a change in natural language. Your job when this skill triggers is to read the patch, figure out which mode it's in, resolve its parameters, apply it to the target, and verify the result — treating the patch as a behavioral contract, not a literal script.
The format is human-authored, so the patch you receive may be terse, thorough, or anywhere in between. Meet it where it is. A one-section patch is valid. A patch with every section defined is valid. Don't refuse to proceed because optional sections are missing.
Two modes: source-tree and overlay
patch.md has two modes of application. They share a document format but describe different kinds of change.
Source-tree patches describe edits to a filesystem the user owns — a codebase they can read and modify. Building a browser extension, mobile app, plugin, or mod as source is a source-tree patch, regardless of what the built artifact later does. This mode is specified in RFC 0001.
Overlay patches describe behavior injected into a running host the user does not own and cannot edit at source — a website viewed through a userscript manager, an app viewed through a browser extension, a deployed service modified by an edge worker, a game modified by a mod loader. This mode is specified in RFC 0002.
You distinguish the two by the shape of the document, not by a target-type declaration:
| If the document contains… | Treat as… |
|---|
## files section with ### <path> (create|modify|delete) subsections | Source-tree patch |
## overlay section with ### <name> subsections, plus ## match | Overlay patch |
| Both | A hybrid; apply each mode's sections by its own procedure |
| Neither | Not a patch.md; tell the user what you saw |
Mode detection is shape-based on purpose — the spec deliberately does not enumerate host types, because the ecosystem will grow faster than the enum.
Recognizing a patch.md
The file is a patch.md if any of these are true:
- Filename is
patch.md or ends in .patch.md.
- The first heading is
# patch.md.
- The body contains a
## files section with operation-tagged subheadings, or a ## overlay section.
If you're unsure, treat a document whose structure matches either mode as a patch. The convention is loose on purpose.
Shared sections
Both modes use these sections. Their semantics do not change with mode.
| Section | What it does |
|---|
meta | Identity: name, version, author, target, depends, spec. target is advisory for mode selection, not authoritative — use shape instead. |
params | User-supplied variables. Prompt the user for values at apply time, then substitute $VARNAME throughout the patch. |
env | Environment variables the target will need. Flag missing required vars before applying. |
verify | Assertions checked after applying. The behavioral contract — implementation may vary between executors; verify must hold for all. |
rollback | How to cleanly undo the patch. Semantics differ by mode (see the apply sections below). |
examples | Informative before/after snippets or structural patterns for ambiguous cases. |
if / when | Conditional blocks (e.g. ## if typescript). Evaluate against the target and only apply matching blocks. |
Source-tree sections (RFC 0001)
| Section | What it does |
|---|
context | Files to read but never modify. Use these to absorb project conventions before generating code. |
files | The core. Each ### <path> (create|modify|delete) subsection is one file operation in natural language. |
run | Side effects outside file edits. pre: runs before file changes, post: after. |
scope | Filesystem globs declaring where the patch may create / modify / delete. Hard sandbox — never touch anything outside it. |
Overlay sections (RFC 0002)
| Section | What it does |
|---|
match | Activation conditions (URL patterns, host identifiers, event triggers — executor-defined). Overlay is live only when at least one matches. |
overlay | The core. Each ### <name> subsection is one named injection in natural language. Source order matters — later injections may depend on earlier ones being active. |
permissions | Capabilities the overlay needs from the host or executor (storage, cross-origin fetch, privileged APIs). Executor-defined names. |
lifecycle | When to activate relative to host phases (run-at: document-idle, priorities, etc.). Executor-defined phase names. |
scope | In overlay mode this is not filesystem globs. It's abstract resource limits: what DOM selectors, network reach, storage keys, etc. the overlay is allowed to touch. Still a hard sandbox. |
How to apply a source-tree patch
This procedure covers source-tree mode (RFC 0001). For overlay mode, see the next section.
Work through these phases in order. Don't skip ahead — the early phases surface problems that are much more expensive to discover mid-apply.
1. Read the whole patch first
Read the entire file before taking any action. You need the full picture — dependencies, scope, verify contract, rollback plan — before you start editing. A patch that looks simple in ## files may have a strict ## scope or a ## run step that changes how you should approach the edits.
2. Resolve meta and dependencies
- Check
target. If the target project doesn't match (wrong framework, wrong version), stop and report the mismatch to the user rather than pressing on.
- Check
depends. If the patch depends on others that haven't been applied, tell the user — don't silently proceed.
3. Collect params and env
- For each entry in
params, ask the user for a value. Offer a sensible default if one is obvious from context, but let the user override.
- For each entry in
env, check whether it's set in the project (.env, .env.example, shell). For required vars that are missing, ask the user to provide them or confirm they'll set them later.
4. Resolve conditionals
Evaluate ## if <condition> / ## when <condition> blocks against the target project:
## if typescript → check for tsconfig.json.
## if using prisma → check package.json dependencies or prisma/ directory.
## if next.js >= 14 → parse the version from package.json.
Only apply blocks whose conditions match. If a condition is ambiguous, ask the user.
5. Read context
Before generating any code, read every file listed under ## context. These files exist to teach you the project's conventions — import style, error handling patterns, naming, where types live, how tests are structured. The generated code should feel native to the codebase, which it won't if you skip this step.
6. Enforce scope
If ## scope is declared, treat it as a sandbox:
- Any file operation outside the declared
create / modify / delete globs must not happen.
- If applying the patch seems to require touching out-of-scope files, stop and report — don't silently expand the scope.
7. Snapshot before modifying
Before any modify or delete operation, capture the current contents of those files. You'll need the snapshot for rollback. A simple approach: copy the affected files to a temporary directory, or commit the pre-apply state to git so it can be reverted.
8. Run pre side effects
Execute any run.pre steps (e.g. npm install stripe). These typically install dependencies that the subsequent file edits will import. If a pre step fails, stop — don't proceed to the file edits.
9. Apply file operations
For each entry in ## files:
- create: Generate the file from the natural-language description. Write it in a style that matches what you learned from
## context.
- modify: Read the existing file, apply the described change, preserve everything the description doesn't mention.
- delete: Remove the file.
Substitute $PARAM references with the values the user supplied. If the patch includes ## examples snippets, use them to disambiguate — the description is the spec, the example is the vibe.
Key judgment calls:
- The natural-language description is behavioral intent, not pseudocode. You have license to choose variable names, helper structure, and idioms that fit the project.
- If the description is ambiguous and the ambiguity matters, ask the user rather than guessing.
- If a
modify target doesn't exist, or a create target already exists, stop and ask — don't silently overwrite or create empty-parents.
10. Run post side effects
Execute any run.post steps (e.g. database migrations, format commands, verification scripts).
11. Verify
Work through every entry in ## verify and check whether it holds. Verify entries are the behavioral contract — even though your implementation choices may differ from another executor's, these assertions must pass for both.
For each entry:
- If it's objectively checkable (a file exists, an export is named X, a command returns a specific status), check it directly: read the file, run the command, inspect the output.
- If it's behavioral (a button renders, a route responds correctly), either run the relevant test/dev command, or clearly tell the user this assertion needs manual verification and describe how they'd check it.
Report verification results plainly:
- What passed.
- What failed, with evidence (actual output vs. expected).
- What couldn't be automatically verified and needs a human.
If critical verify entries fail, proceed to rollback unless the user says otherwise.
12. Report
Summarize what changed:
- Files created / modified / deleted.
- Commands run.
- Env vars the user still needs to set.
- Verify results.
- How to roll back if they change their mind (point at
## rollback).
Rollback (source-tree)
If a source-tree patch fails mid-apply, or the user asks you to undo it:
- Restore modified files from the snapshot taken in step 7.
- Delete any files created by the patch.
- Run any cleanup commands in
## rollback (e.g. npm uninstall <pkg>).
- If the patch declared
rollback steps explicitly, follow them in the order given.
If you took a git snapshot, offer git reset / git checkout to the pre-apply commit as the simplest path.
How to apply an overlay patch
This procedure covers overlay mode (RFC 0002). Overlay patches inject behavior into a running host the user does not own — a website viewed through a userscript manager, an app modified by an extension, a deployed service wrapped by an edge worker, a game extended by a mod loader. The RFC is deliberately host-agnostic; you map the abstract primitives onto whatever host the user's environment actually supports.
Work through these phases in order. Many parallel the source-tree procedure, but there is no filesystem snapshot, no pre / post shell side effects, and no ## files section.
1. Read the whole patch first
Same reason as source-tree: you need the full picture (permissions, scope, verify contract) before activating anything.
2. Resolve meta, dependencies, params, env, conditionals
Same as source-tree steps 2–4. meta.target in overlay mode is advisory only — use it to confirm the user's host matches the patch's intent, not as a controlled enum. If the user's host can't be reconciled with meta.target, ask.
3. Identify the host and map the primitives
Figure out which host the overlay is going to run on (browser userscript manager? browser extension? service worker? edge function? mod loader?). The user's environment and the meta.target advisory usually make this obvious. If it's ambiguous, ask.
Then translate the abstract primitives onto the host's concrete mechanisms. Common mappings:
| Abstract primitive | Userscript (Tampermonkey-like) | Content script (WebExtension) | Edge / CDN worker |
|---|
match | @match URL patterns | matches manifest field | Route predicates |
permissions | @grant functions | permissions manifest field | API scopes |
lifecycle | @run-at | run_at | Request lifecycle hook |
overlay entries | Injected JS blocks / GM calls | Content script body | Request/response handlers |
scope (DOM/network/storage) | Selector + @connect + GM storage prefix | Selector + host_permissions + storage prefix | Route pattern + fetch origin list + KV prefix |
You don't need to memorize this table — the point is that there's a translation layer, and you do it at application time based on what the user actually has. If the host is unfamiliar, tell the user and ask how they'd like the primitives mapped.
4. Resolve permissions
For every entry in ## permissions:
- If the host has an equivalent concept, request it (adding to the generated manifest, the
@grant header, the worker config, etc.) and tell the user which permissions will be requested.
- If the host cannot grant a declared permission, do not proceed silently with reduced permissions. Stop and ask the user whether to continue in a degraded mode or abort.
Surface the full permission list to the user before activation — overlays running against third-party hosts are security-sensitive and the user deserves to see what they're authorizing.
5. Enforce scope
Overlay scope is not filesystem globs; it's a declaration of the abstract resources the overlay may touch (DOM selectors, network origins, storage key prefixes, etc.). Treat it as a hard sandbox just like filesystem scope:
- If accomplishing an
overlay entry would require reaching outside the declared scope, stop and report.
- If the host cannot enforce the scope (for example, you cannot actually restrict what selectors a userscript queries), warn the user that scope enforcement is advisory in their environment.
If scope is absent, infer a conservative default from the overlay entries and show the user what you inferred before proceeding.
6. Generate the injection artifact
Produce whatever the host consumes: a .user.js file for a userscript manager, a content.js + manifest.json pair for a WebExtension, a worker script for an edge runtime, a mod script for a mod loader.
Translate each ### <name> entry under ## overlay into code that realizes its behavioral intent. Order matters — later entries may depend on earlier ones. Honor ## lifecycle when generating the host's lifecycle hooks.
Substitute $PARAM references with the values the user supplied.
7. Activate
Install / register the artifact with the host — hand the userscript to the manager, load the extension, deploy the worker. Activation MUST be idempotent: activating an already-active overlay must not produce duplicate injections.
If the host requires user action to complete activation (for example, "open Tampermonkey and approve the new script"), tell the user exactly what they need to do and confirm completion before proceeding to verify.
8. Verify
Run through ## verify against the running host, not against any source tree. Trigger the host if needed (open the page, make the request, run the app) and check each assertion:
- Observable DOM or runtime state checks: do directly if you have host access.
- Behavioral assertions that require interaction: describe exactly what the user should do and what they should see.
- Assertions that cannot be automatically verified: report them as unverified, do not skip silently.
9. Report
Summarize:
- Which host the overlay was installed into.
- Match conditions where the overlay is now active.
- Permissions requested and granted.
- Injections now live, in source order.
- Verify results, including any unverified items the user must check manually.
- How to deactivate — see below.
Deactivating (overlay rollback)
Overlay rollback is deactivation, not file restoration. The host's own state was never modified.
- Disable or uninstall the overlay from the host (turn off the userscript, disable the extension, remove the worker deployment).
- Clear any executor-managed state the overlay created within its declared
scope.storage (storage keys, cookies, cache entries). If the patch has an explicit ## rollback section describing such cleanup, follow it.
- Confirm to the user that no residual state remains that they'd want to know about.
If the overlay has been publishing data externally (sending requests, syncing to a server), tell the user explicitly — deactivation stops future sends but doesn't undo past ones.
Authoring a patch.md (when the user asks)
If the user asks you to write a patch.md rather than apply one, start by asking which mode fits. If they describe editing a codebase they own (including building a browser extension, mod, or plugin as source), it's source-tree. If they describe injecting behavior into something they can't edit at source (a site they visit, a deployed service they use, a game they play), it's overlay. If they aren't sure, ask concrete questions — "Are you editing files in a repo, or arranging for this to run when you use someone else's app?"
Good authoring heuristics apply to both modes:
- Describe intent, not implementation. "Hide short-form video shelves on the YouTube homepage" is better than a selector-by-selector recipe. The executor can choose better specifics than you can prescribe.
- Let specificity earn its place. Don't add
## verify, ## rollback, ## scope, ## permissions unless the stakes justify them. A one-off personal patch doesn't need the full ceremony. A publishable, shareable patch does.
- Write verify entries as behavioral contracts. "POST /api/checkout with a valid priceId returns 200 with a
url field" or "The sidebar contains no link whose href begins with /shorts" — not "the file contains the string X" or "document.querySelector returns null." The implementation can vary; the behavior must hold.
- Scope matters for shared patches. If you'd publish this patch to a registry or hand it to a stranger, declare
## scope. In source-tree mode this is filesystem globs; in overlay mode it's abstract resources (DOM selectors, network origins, storage prefixes). Either way, the executor enforces it as a sandbox.
- Source-tree: use
## context generously. Listing a handful of existing files the agent should read before generating code is one of the highest-leverage things a source-tree author can do.
- Overlay: use
## match precisely. Match too broadly and the overlay activates where it shouldn't. Match too narrowly and users will hit edge cases where it doesn't activate when it should. Prefer listing several specific URL patterns over one catch-all.
Principles
Three things to keep in mind through the whole process, regardless of mode:
- The behavioral contract is in
verify. Two executors applying the same patch may produce different code or different injections. That's fine, and by design. What must hold is the contract in ## verify.
- The patch is a spec, you are the implementer. The author wrote natural language on purpose. They're trusting you to choose idioms, names, selectors, and structure that fit this specific target — which is why
## context (source-tree) and host-specific mappings (overlay) exist.
- Fail loudly, don't guess silently. Missing params, failed preconditions, scope violations, refused permissions, ambiguous descriptions — surface them to the user. A patch that half-applies and leaves the target in a broken intermediate state is much worse than one that stops and asks.