agentleFS
HainrixzHainrixz/claude-seo-ai/skills/seo-fix-apply/SKILL.md

seo-fix-apply

Skill81 starsChanged 2 months agoMITView on GitHub

Writer protocol preloaded into the seo-fixer-writer agent — how confirmed SEO/AI-search fixes are applied (git pre-flight, backup, Edit/Write for local diffs, ticketed adapter CLIs for remote targets, re-verify, publish only on a second ticket, rollback) and the findings-array output contract. Used only by the fix flow after the user has confirmed changes; never invoked on its own.

  • Reads credentials

The file

We split this skill into the rules it gives an agent

5 rules. About 0 are common, 0 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  • could be automatic: a setting could enforce it
  1. Very specific:

    Read plan.json for the Change records.

    line 34
  2. Very specific:

    Idempotent: If the change is already present (the JSON-LD block, the marker comment, the field's value), make no edit: report status: pass …

    line 59
  3. Very specific:

    Re-verify: Run verify --run "<RUN_DIR>" --change <id> and the finding's verification.reproduce verbatim.

    line 62
  4. Very specific:

    Never touch .env*, .git/, lockfiles, key material, wp-config.php, CI configs, or a Shopify config/settings_data.json.

    line 91
  5. Very specific:

    Never fabricate a value (price, date, rating, sameAs, author) and never backdate dateModified.

    line 94

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md
<!-- Portions Copyright (c) 2026 Enrique Rocha (@soyenriquerocha) - see LICENSE for original authors · tododeia.com · id er-d03758e1 -->

seo-fix-apply (writer protocol)

This file is the authoritative protocol; agents/seo-fixer-writer.md carries the in-context summary — keep the two in sync. Edit, Write and Bash are deliberately not pre-approved here: Claude Code's native diff and command prompts must reach the user for every write, and the guard-write / guard-bash hooks run on top of them.

You apply what was already confirmed. You do not decide what to fix, you do not improve a diff you were given, and you never widen the change set.

Inputs

The fix command dispatches you with a JSON envelope:

keymeaning
RUN_DIR<DATA>/fix/runs/<id>/ — plan.json, manifest.json (with confirmed[]), preview/, before/, after/, log.ndjson
SCRIPTS_DIRabsolute <plugin_root>/scripts/. Run scripts as node "<SCRIPTS_DIR>/<x>.mjs" … with the literal path — never a ${...} token, never a relative scripts/ path
DATAplugin data root. Backups live here, never in the user's project
PROJECT_ROOTthe user's project (local targets only)
confirmed_change_ids[]the ONLY change ids you may apply
tickets{ <change_id>: <ticket id or the exact command> } — one-shot, 15-minute, issued after the user confirmed
publishfalse by default; true only after a second confirmation, and it carries its own ticket
forceallows writing into a dirty git tree
return"JSON array of findings only"

Read plan.json for the Change records. A change you were not given an id for does not get applied, previewed again, or "helpfully" included.

Protocol (per confirmed change, in order)

  1. Git pre-flight. git status --porcelain in PROJECT_ROOT. Dirty tree and no force: true ⇒ do not write: return the finding with its pre-fix status and skipped_dirty_tree in evidence.observed. Never stash, checkout or reset — the user's uncommitted work is theirs.
  2. Backup before the first write. Local files: copy to <DATA>/backups/<run-id>/<relative path> (the adapter's apply does this itself; when you write with Edit/Write, do it yourself with mkdir -p + cp before the first edit of that file). Remote resources: the adapter writes before/<change_id>.json. Record nothing in the project.
  3. Local diffs — Edit/Write, not the adapter. For target.kind: file changes whose strategy is AUTO (html-head, front-matter, config-file, liquid), apply the previewed diff with Edit (or Write for a new file) so the native diff prompt and guard-write engage. Apply exactly the preview: same insertion point, same text, no reformatting, no extra content, TODO:<field> placeholders preserved verbatim. A JSX/TSX or other non-AUTO strategy arrives as skipped_unready from the adapter and is yours to apply by hand — still exactly as previewed.
  4. Remote targets — the adapter CLI, with its ticket. Anything whose target.kind is not file goes through node "<SCRIPTS_DIR>/adapters/<adapter>.mjs" apply --run "<RUN_DIR>" --change <id> --ticket <ticket> --data "<DATA>" --json. The ticket is required and one-shot; a missing or expired one is a real failure, not something to route around. Never emulate an adapter with ad-hoc curl, wp, or shopify commands — the guard-bash hook blocks them and it is right to. If no adapter exists for that target, keep the finding's pre-fix status with skipped_unready plus the manual path from preview/.
  5. Idempotent. If the change is already present (the JSON-LD block, the marker comment, the field's value), make no edit: report status: pass with skipped_idempotent in evidence.observed. Re-running must never duplicate or corrupt content.
  6. Re-verify. Run verify --run "<RUN_DIR>" --change <id> and the finding's verification.reproduce verbatim. Record the assertion's pass/fail. A stale CDN or page cache is pending_cache in evidence.observed with status: warn — never a claimed pass. A local framework target with no dev server is a source-level pass: say "source verified, re-audit after deploy" rather than claiming the live page changed.
  7. Publish — only with publish: true and its own ticket. Publishing is what makes staged work public (shopify theme publish, a Webflow site publish, a HubSpot draft push-live). It is a separate op with a separate confirmation and a separate ticket: node "<SCRIPTS_DIR>/adapters/<adapter>.mjs" publish --run "<RUN_DIR>" --ticket <publish ticket> --data "<DATA>". Without both, leave the change staged and say so in the finding. Never pass --allow-live, --live or -a to the Shopify CLI: that path is blocked and publishing has its own op.
  8. Log. One NDJSON line per change in <RUN_DIR>/log.ndjson (change id, files or resource, result). Redact anything credential-shaped; the adapters' own logging already does.
  9. On failure, stop widening. A failed change is reported as fail with the error text; do not retry with a different method, a different file, or a broader edit. Rollback is rollback --run "<RUN_DIR>" --change <id> and it needs its own ticket.

Output contract

Return a JSON array of findings conforming to schema/finding.schema.json for the confirmed changes only (id, module, title, status, severity, scope, evidence, expected, recommendation, fixable, verification, expected_impact). status uses the schema enum (pass when re-verification succeeded, else fail/warn; needs_api when verification needs an API you do not have) — there is no skipped status: a change that was not applied keeps its pre-fix status and states the reason in evidence.observed as skipped_unconfirmed, skipped_unready, skipped_idempotent, skipped_dirty_tree or pending_cache. Quote what changed and name the backup path. Do not render the report — the fix flow does.

Hard rules

  • Apply only confirmed_change_ids; write only inside PROJECT_ROOT or <DATA>.
  • Never touch .env*, .git/, lockfiles, key material, wp-config.php, CI configs, or a Shopify config/settings_data.json.
  • Credentials come from the environment; never put one in a command line, a file, or your output.
  • Never fabricate a value (price, date, rating, sameAs, author) and never backdate dateModified.
  • Back up before the first write, re-verify after every write, refuse a dirty tree without force, publish only with publish: true and a publish ticket.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.