Page restructurer
A collection of AI agent skills for optimizing political campaign websites for AI search (GEO). Built for candidates, campaign managers, and advocacy staff who want to help their site get accurately read and cited.
npx -y skills add meturley/trail-marker-geo --skill page-restructurerAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 19 days oldThe repository was created 19 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Convert a candidate's existing prose page into an extraction-optimized Q&A format that AI engines can easily parse and cite. Use this skill whenever the user pastes an existing page, section, or block of prose (e.g. an "About", "My Vision", "Services", or bio section) and wants it rewritten so AI search engines and answer engines can lift and cite it — triggers include "make this citable", "restructure this page for AI", "optimize this for AI search / answer engines", "turn this into Q&A / FAQ", "why won't AI engines quote my page", "GEO / AEO this content", or any request to reformat owned prose into self-contained question-and-answer pairs with FAQPage schema. Restructures and tightens the wording without changing the substance or inventing claims.
SKILL.md
13.5 KB, as published. Nobody here has run it
Page Restructurer
Rewrite a candidate's existing prose page into an extraction-optimized Q&A format so AI engines (ChatGPT, Perplexity, Google AI Overviews, Gemini, etc.) can easily parse, lift, and cite it. Then generate matching FAQPage JSON-LD.
The problem this solves: AI answer engines cite self-contained, answer-first sentences far more readily than flowing prose where the point is buried mid-paragraph. This skill restructures owned content to match how engines actually extract — without changing what the candidate is saying.
Hard rules (read first — these are non-negotiable)
- Owned content only. Only restructure content the user owns or is authorized to rewrite. This is for reformatting a candidate's own page, not rewriting someone else's.
- Preserve the candidate's actual positions. Restructure and tighten — never change the substance, soften a stance, or invent new claims, facts, numbers, dates, or credentials. Every fact in the output must trace to the source page.
- Never fabricate to fill gaps. If the source is thin or vague, leave it thin. Do not invent specifics to make an answer sound more citable.
- Flag vague claims — don't fix them silently. If the source contains vague or unsupported claims (e.g. "widely recognized," "years of experience," "many students"), list them and suggest the user run
claim-strengthener. Do not fabricate the missing specifics yourself. - Cross-check against
fact-sheet.mdif present. If afact-sheet.mdexists in the working directory or uploads, load it and verify every restructured fact (dates, titles, numbers, names) is consistent with it. Flag any conflict; never let the restructured page contradict the fact sheet.
Core formatting principle: complete sentences, not fragments
Engines lift self-contained declarative sentences, not sentence fragments. A terse bullet like "15 years teaching" is not liftable — an engine can't drop it into an answer. "Dana Cole has taught secondary mathematics for 15 years." is.
So format each answer as one or more complete declarative sentences in a tight Question → Answer pair, NOT as terse bullet fragments. The answer must stand alone: readable and true even when lifted out of the page with zero surrounding context. That means the subject is named explicitly (not "I" or "we" or a dangling pronoun) at least in the opening sentence of each answer.
Fragment (wrong): - Focus: project-based learning, small cohorts
Self-contained sentence (right): Dana Cole's teaching approach centers on project-based learning delivered in small cohorts.
Workflow
Step 1 — Intake, ownership check, and length check
Take the pasted prose. Confirm (or reasonably assume from context) it's the user's own content. Identify the subject/entity name — you'll need it to make every answer self-contained. If no name is stated and none is inferable, use a neutral explicit subject rather than a pronoun (e.g. "The author" / "This practice"), and note that naming the subject explicitly would improve citability.
Length guardrail (batching). If the pasted prose exceeds roughly 800 words, do not process it all at once — a single-shot restructure of a long page produces truncated, lazy output or blows the output limit. Instead, process the source in sections of ~3–5 paragraphs (or ~800 words): fully restructure that chunk into Q&A HTML + its FAQPage schema, deliver it, then ask the user whether to continue with the next section. Keep a running note of the subject name and any dates/facts already surfaced so later chunks stay consistent and you don't duplicate Q&A pairs. When all chunks are done, offer to merge the per-chunk schema blocks into a single combined FAQPage block (one mainEntity array), since a page should carry exactly one FAQPage block.
Step 2 — Load fact-sheet.md if it exists
Look for fact-sheet.md in the skill's execution environment — check the current working directory, the user's project folder, and any uploaded files (in a code-execution sandbox this is often /mnt/user-data/uploads/; with local or MCP file access it may be somewhere like ~/Documents/<project>/; some interfaces expose it as uploaded files or project knowledge). If found, read it and use it as the source of truth for cross-checking in Step 5. If you can't find one after a quick look, don't send the user hunting for it — proceed and report in the Flags section that no fact sheet was available to cross-check against.
Step 3 — Extract the claims and reorder by importance
Pull out the distinct claims/points in the source. Rank them by importance to a reader/engine. AI citations concentrate in the first third of the content, so the most important, most factual, most differentiating claims must become the first Q&A pairs. Lead with substance (who/what/credentials/specific positions), not throat-clearing.
Step 4 — Surface dates
Scan for any dates, years, durations, or time references in the source and make them explicit in the relevant answers (e.g. "since 2016," "over 15 years," "founded in 2019"). Dated facts are highly citable and signal freshness/authority to engines. Only surface dates that are actually in the source — do not infer or invent them.
Step 5 — Draft the Q&A pairs
Convert the reordered claims into Question → Answer pairs following references/qa-format.md. Each question is what a user might actually ask an engine; each answer leads with the direct answer in a complete self-contained sentence, then adds at most 1–3 supporting sentences. Keep the candidate's substance intact.
Then cross-check every fact against fact-sheet.md (if present). Resolve nothing silently — flag conflicts to the user.
Step 6 — Generate the FAQPage JSON-LD
Produce a valid schema.org FAQPage JSON-LD block whose mainEntity Q&A pairs exactly match the restructured Q&A pairs — question text and answer text must match the rendered HTML verbatim, since visible content and schema disagreeing is a red flag to anything parsing the page, machine or human. See references/schema-template.md.
Note: Google deprecated the visible FAQ rich-result SERP snippet entirely in May 2026 (it had already narrowed eligibility to government/health sites back in 2023). This schema still helps AI answer engines parse and cite the Q&A content — that's this skill's actual purpose — but don't imply to the user that it will produce a Google search rich-result snippet; that payoff no longer exists for any site.
Primary method — run the script, don't hand-write. This environment has a Python interpreter and a shell. Write the Q&A pairs to a JSON file and EXECUTE the generator; do not narrate running it or reproduce its output from memory:
python3 scripts/build_faq_schema.py pairs.json
where pairs.json is [{"question": "...", "answer": "..."}, ...] using the exact rendered text. The script escapes quotes and special characters and emits the full <script type="application/ld+json"> block. Copy its actual stdout into the output. Running the script is strongly preferred because it makes the escaping and the HTML↔schema match deterministic rather than something the model has to get right by hand.
If the command fails because the script isn't found (e.g. the shell's working directory isn't the skill root), resolve it with a quick bounded attempt — invoke it by its full path relative to this skill's directory. Do not spend multiple turns searching the user's filesystem for it. If it still isn't runnable, immediately drop to the Fallback method below rather than stalling.
Fallback — only if no code execution is available in the current environment. Hand-write the JSON-LD from the template, and apply this rule with extra care:
JSON-LD escaping rule. Inside every
name(question) andtext(answer) value, meticulously escape all double quotes as\", backslashes as\\, and any literal line breaks as\n. A single unescaped quote produces invalid JSON that silently breaks the target page's schema. After writing the block, re-read it and confirm it is parseable JSON before presenting it. Prefer rephrasing an answer to avoid inline quotation marks entirely when it doesn't change the substance.
Step 7 — Assemble the output
Return, in this order:
- Restructured HTML content — the Q&A pairs as clean, paste-ready HTML.
- The
FAQPageJSON-LD schema block — wrapped in a<script type="application/ld+json">tag. - Paste-in guidance — where each block goes and how to verify.
- Flags — any vague claims (→ suggest
claim-strengthener) and anyfact-sheet.mdconflicts.
See references/output-template.md for the exact output layout.
Output format
ALWAYS structure the final response using this template:
## Restructured page (HTML)
<the Q&A HTML block>
## FAQPage schema (JSON-LD)
<the <script> JSON-LD block>
## How to paste this in
<3–5 concrete steps: where the HTML goes, where the schema goes, how to validate>
## Flags & suggestions
- Vague claims to strengthen (run claim-strengthener): <list, or "none">
- fact-sheet.md consistency: <"checked, consistent" / conflicts found / "no fact-sheet.md found">
- What was NOT changed: <one line confirming substance/positions preserved>
If there were no vague claims and no fact sheet, still include the Flags section and say so plainly — the user needs to know the checks ran.
What good looks like
Source prose (excerpt):
"I've always believed education should meet students where they are. Over my years in the classroom I've come to focus on project-based learning, and I think small cohorts make all the difference. I started my own microschool a few years back."
Restructured (answer-first, self-contained, dates surfaced, reordered so the concrete facts lead):
<section class="faq">
<div class="faq-item">
<h3>What is Dana Cole's approach to education?</h3>
<p>Dana Cole's approach centers on project-based learning delivered in small cohorts. She believes instruction should meet students where they are, and structures her teaching so each student progresses from their own starting point.</p>
</div>
<div class="faq-item">
<h3>Does Dana Cole run her own school?</h3>
<p>Yes. Dana Cole founded her own microschool, which she has operated for several years.</p>
</div>
</section>
Note what happened: the concrete, differentiating facts (approach, the school) lead. Each answer opens with a complete sentence naming the subject. The pronoun-heavy, buried phrasing became liftable. Nothing was invented — "a few years back" stayed vague as "several years" rather than being fabricated into a specific year, and that vagueness gets flagged for claim-strengthener.
HTML variant — native disclosure elements. If the user wants a built-in accordion (collapsible questions) with native accessibility, use HTML5 <details>/<summary> instead of <div>/<h3>:
<section class="faq">
<details>
<summary>What is Dana Cole's approach to education?</summary>
<p>Dana Cole's approach centers on project-based learning delivered in small cohorts. She believes instruction should meet students where they are.</p>
</details>
</section>
Which to default to: lead with the visible <div>/<h3> layout unless the user asks for an accordion. The reason is a real extraction trade-off — answer text collapsed inside <details> is not visible on initial load, and AI extractors most reliably pick up text that renders immediately. <details>/<summary> is more accessible and cleaner markup, but it hides the answer by default. Offer both, explain the trade-off in one line, and let the user choose; the FAQPage schema is identical either way.
Reference files
references/qa-format.md— how to write answer-first, self-contained Q&A pairs; question phrasing; length limits; the fragment-vs-sentence rules in detail.references/schema-template.md— theFAQPageJSON-LD structure and the content-match requirement.references/output-template.md— the full assembled output layout with a worked example.scripts/build_faq_schema.py— generate valid FAQPage JSON-LD deterministically from Q&A pairs (avoids hand-writing/escaping errors).
Runtime & scope
- Posture: Generative, structure-only. It reformats the candidate's existing prose into Q&A pairs plus matching
FAQPageschema without changing the substance. - Neutrality: Preserves the candidate's actual positions; never invents claims, facts, dates, or credentials, and rewrites owned content only. Vague source claims are flagged for
claim-strengthener, never fabricated into specifics. - Runtime: Python 3.6+, standard library only (the
build_faq_schema.pyscript). No third-party dependencies.