Public records

Public records request response

Drafts a complete, itemized response to a records request: every item addressed and classified as releasable, withheld, or redacted. The skill researches the law, exemptions, and deadline from reputable sources, presents each with its source for the official to verify, asks for what it can't find, and only then drafts — never inventing an exemption.

Download folder (.zip)

What it does

A records response has to account for every record asked for, classify each as releasable, withheld, or redacted, and tie each non-release to a specific exemption, without smoothing over real ambiguity. This skill encodes that structure and a verification loop, but it never supplies the exemptions or deadlines itself: it researches them from reputable sources, presents each call and citation with its source for the custodian to verify, asks for anything it can't find, and drafts only once everything is confirmed.

Where it earns its place

Records responses are slow, high-stakes, and easy to get wrong: miss one item and you risk a complaint; over-withhold and you risk an appeal; over-release and you can't take it back. The riskiest move is a confidently wrong exemption, so the skill does the legwork but never the deciding: it itemizes the request, researches the law, deadline, and exemptions from reputable sources, proposes a disposition with each source shown, and has the custodian confirm or correct every call before it drafts. A completeness/classification/grounding loop guards the result.

The two halves

The craft, and your facts

the skill The craft

How to approach the task and word it, the way an election expert would.

  • Structure the document and its steps
  • Plain language a voter can act on
  • Flag genuine uncertainty, never smooth it over
  • Run the checks before a human sees it

Drafted by AI, reviewed by an expert

you The facts

The facts it must be right about: found from real sources, and verified by you.

  • The skill searches reputable sources for each one
  • It shows you the value and the source to confirm
  • Nothing is used until you verify it
  • Where it finds nothing, it asks you

Researched, then verified by you

Verification loop

It checks itself before it ships

This skill drafts, tests the draft against explicit, SME-validated criteria, revises, and only surfaces what passes. For this task the checker is more reliable than the writer.

Draft model generates
Checks
  • classification
  • completeness
  • grounding
Ships only what passes

The package

What’s in the folder

The craft

SKILL.md

The thin, jurisdiction-agnostic instructions — the whole skill. It tells the model how to structure and word the task, and to ask you for facts rather than invent them. Read it before you trust it.

SKILL.md
---
name: public-records-request
description: Draft a complete, itemized, defensible response to a public records request, with every requested item addressed and classified as releasable, withheld, or redacted. Use when an election official or records custodian needs to answer a records request. The skill researches the controlling law, exemptions, deadline, and confidentiality rules from reputable sources, presents each with its source for the official to verify, asks for what it can't find, runs completeness/classification/grounding checks, and only then drafts. It never invents an exemption. Works in any U.S. jurisdiction.
---

# Public records request response

You help an election official or records custodian draft a complete, defensible
response to a public records request.

**The division of labor is the point.** You structure the response, itemize the
request, write the language, and do the legwork of *finding* the governing law.
But you never name an exemption, deadline, or fee from the model's memory, and you
never finalize the response until the official has verified every legal call.

## How facts are handled (the one rule)

For every legal fact the response needs — the controlling law, each exemption, the
deadline, fees, the custodian rule, the confidentiality screens — work in order:

1. **Find it.** Use your web-search or browsing tools to locate the fact from a
   reputable, authoritative source: the controlling records statute, the state's
   chief election or open-government authority, or official guidance. Capture the
   value **and its source** (title + link).
2. **Show it for verification.** Present each fact to the official with the value,
   the source, and your confidence, and ask them to confirm or correct it — and,
   for each requested item, to confirm the **release / withhold / redact** call
   and the exemption. A searched fact is a *proposal*, not an answer.
3. **Ask where you can't find it.** If no reputable source gives you a fact, or a
   classification call is genuinely the custodian's judgment, ask the official —
   don't guess.
4. **Only then draft.** Once every fact and call is verified, write the complete
   response. Never leave an item unresolved or a placeholder in the final response.

If you have no search tools available, skip step 1 and ask the official for each
fact directly.

## Step 1 — Get oriented

Ask the official for what you need to search and itemize:

- the **state** and the **controlling records law** (if they know it);
- **the request itself** (pasted in full);
- who the **custodian of record** is.

## Step 2 — Research and itemize

Break the request into a numbered list of discrete items. Then search reputable
sources for each fact the response needs, capturing value + source:

- the **response deadline** and any **fee rules**;
- the **exemptions** that plausibly apply to each item, with the citation;
- the **confidentiality screens** for voter / election records (signatures,
  protected-address programs, sensitive identifiers).

Prefer official `.gov` sources: the statute, the state authority, official
guidance. Mark anything from an unofficial source, or anything uncertain, as
**low-confidence** for the official.

## Step 3 — Present for verification

Show the official a **fact-check list and a proposed disposition table**: each item
with your suggested call (releasable / withheld / redacted), the exemption and
source you found, your confidence, and the deadline/fee/screens with their sources.
Ask them to **confirm or correct each call and each fact**, and to supply anything
you couldn't find. Do not draft until every call and fact is confirmed.

## Step 4 — Build the response (the craft)

1. **Itemize** every discrete request; one sentence asking several things is
   several items.
2. **Classify each item** releasable / withheld / redacted; prefer **redaction over
   wholesale withholding** where an exemption reaches only part of a record.
3. **Cite per non-release** the verified exemption.
4. **No responsive records:** state that explicitly; never drop an item.
5. **Vague or overbroad request:** issue a clarification request (confirm the rule
   with the official) and a category menu; don't invent items.
6. **Cover language:** professional, neutral, defensible; the verified deadline and
   appeal information.

## The verification loop

Before surfacing, run the three checks in `checks/`: **completeness** (every item
addressed), **classification** (every non-release cites a verified exemption), and
**grounding** (every legal specific traces to a verified source — none from
memory). If a check can't pass because a fact isn't verified, return to the
official for it rather than surface a gap.

Then run **`python scripts/check_response.py <draft-file>`** for a deterministic
pass: no leftover blanks or unresolved items, every withhold/redact carries a
citation, the request is itemized, and a source stamp is present. It checks
structure, not correctness — the custodian still verifies each call. If you can't
run code, apply its checks by hand.

## Output

- **The complete itemized draft response** — for the custodian to review and sign.
- **A disposition table** (item → call → verified authority).
- **A source stamp** listing each legal fact with its verified source.
- **A confirm-before-send checklist** of every legal specific — each one filled and
  verified, for the custodian to double-check before sending.

## What you must not do

- Do not name an exemption, deadline, fee, or confidentiality rule from the model's
  memory. Research it, and have it verified.
- Do not present a searched fact or a proposed call as settled before the official
  confirms it.
- Do not assume a jurisdiction the official did not name.
- Do not classify an item **releasable** by default just because no exemption came
  up. Absence of a found exemption is a prompt to confirm, not proof of public
  status.
- Do not release voter or election data without applying the verified
  confidentiality screens.
- Do not draft before every call and fact is verified, and never leave an item
  unresolved or a placeholder in the final response.
- This is a draft for a human to review and sign. It is never sent on its own.

Grounding

Where the facts come from

This skill carries no baked-in legal facts. It researches the deadline, statute, exemption, or contact it needs from reputable sources, shows you each value with its source to verify, and asks for anything it can't find, before it drafts. Every legal fact in the output is researched and verified, never the model's memory.

Checks

checks/

The explicit, expert-checked test points the verification loop runs against.

checks/classification.md

Check: classification

Every item must carry a classification (releasable, withheld, or redacted), and every withhold/redact must name a specific exemption that was researched from a reputable source and verified by the official, not a vague label and not one the model supplied from memory.

Pass criteria

  • Each item is classified as exactly one of: releasable / withheld / redacted (an item may be partly redacted and partly released; show both).
  • Every withheld or redacted item cites a specific exemption that was researched from a reputable source and confirmed by the official — with the citation and source. A bare "confidential," "internal," or "denied," or an exemption the model supplied from memory or from an unverified search, is a fail.
  • Redaction is preferred to wholesale withholding wherever the exemption reaches only part of a record (release the rest).
  • No item is classified releasable by default merely because no exemption came to mind. Absence of a provided exemption is a prompt to confirm, not proof of public status.
  • Every item classified releasable rests on a basis the official gave (an affirmative public-access rule they named), not on "no exemption came to mind," which is a fail.
  • For voter / election records, the draft applies every confidentiality screen the official named for their jurisdiction, each shown with its citation, and does not pass if a named screen is missing. (Common screens an official may name: signatures, protected-address / address-confidentiality programs, and sensitive personal identifiers such as SSN, driver's-license number, or date of birth. Use the ones the official actually provided — do not import a screen the official did not name, and do not skip one they did.)

Fail → revise

If any withhold/redact lacks an official-provided exemption, ask the custodian for the call and the citation before finalizing, then re-run. Do not leave the item pending in the response and do not guess: gather the missing call first, so the response goes out complete.

Why this is a good loop target

"Does each non-release cite a real exemption the official provided?" is a concrete, mechanical test the checker can apply more reliably than the generator can self-police. Where no provided exemption exists, the honest output is a flag, which the loop can detect and surface.

checks/completeness.md

Check: completeness

The draft response must account for every record the requester actually asked for, explicitly. A response that answers the request "in general" while silently dropping an item is the most common and most appealable failure.

Run this check on the draft before it is surfaced.

Pass criteria

  • The original request has been broken into a numbered list of discrete items. A single sentence requesting several things counts as several items.
  • Every item appears in the disposition table. None is merged away or skipped.
  • Items with no responsive records are stated explicitly ("No responsive records exist"), not omitted.
  • Compound or ambiguous items are either split into their parts or flagged for clarification, not answered with a single guess that covers only part of what was asked.
  • Any item the office is redirecting to another custodian (county clerk vs. board of elections vs. superintendent) is named and routed, not dropped.
  • If the request is too vague or overbroad to itemize at all (e.g. "send me everything about the last election"), the draft does NOT invent guessed items. Instead it issues a clarification request (a lawful response under most records laws — confirm the rule for the official's jurisdiction) within the deadline and offers a category menu. Over-construing a vague request into specific guessed items is itself a completeness fail.

Fail → revise

If any item is unaddressed, regenerate the disposition so it is covered, then re-run this check. Do not surface a response with an unaddressed item.

Why this is a good loop target

Completeness has a checkable target: the set of requested items is finite and enumerable, so the checker (does every item appear?) is more reliable than the generator (did the draft happen to mention everything?). This is exactly the condition under which a verification loop earns its place.

checks/grounding.md

Check: grounding

Every legal specific in the draft must trace to a reputable source that the official verified (or a fact the official supplied directly). Nothing may appear that came from the model's memory or from an unverified search result. This is the check that stops an invented or unverified citation from reaching the custodian.

Pass criteria

  • Every legal specific in the draft — exemption citation, response deadline, fee figure, custodian rule, confidentiality screen — was researched from a reputable source and confirmed by the official, or supplied by the official, and is shown with its source. A specific that is only a search result the official hasn't verified is a fail.
  • No facts from memory. No section number, dollar amount, or day-count that was not found in a cited source and verified.
  • No assumed jurisdiction. The draft cites only the records law for the jurisdiction the official named.
  • Where sources conflict, are unofficial, or are silent, the draft does not pick one silently: it surfaced the uncertainty to the official and uses only what the official confirmed.
  • Verify-source test (mechanical): for each citation, deadline, or fee in the draft, point to the source it was drawn from and to the official's confirmation of it. If you can't show both, it does not belong in the final draft. Presenting an unverified specific as settled is a fail — this is the most common laundering path (a confident search result slipped in as fact).

Fail → revise

Strip any specific that was not verified against a cited source. Return it to the official to confirm or correct, or research a better source, before it goes in the draft. Re-run until every legal statement is researched, sourced, and verified.

Why this matters most

The skill drafts in an authoritative, official voice, which makes a wrong fact more damaging, not less. Grounding is the check that makes that voice safe: every fact was found in a real source and confirmed by the official before it was used.

Deterministic checks

scripts/

Bundled validators the skill runs on a draft before surfacing it. They enforce the structural rules mechanically — no leftover blanks, every claim cited, the reading level — so the discipline doesn't rest on the model agreeing with itself. They check structure, not whether the facts are correct; that stays the official's verification.

scripts/check_response.py
check_response.py
#!/usr/bin/env python3
"""Deterministic discipline check for a records-response draft.

This checks STRUCTURE, not whether the legal calls are correct — only the
custodian's verification does that. What it guarantees, mechanically, is that the
draft obeys the skill's rules: no leftover blanks, and every withhold/redact
actually carries a citation (the single most appealable slip).

Usage:
    python check_response.py path/to/draft.txt
    # or pipe:  cat draft.txt | python check_response.py

Exit code 0 = pass, 1 = issues found. Standard library only.
"""
import re
import sys

# A citation token: a section symbol, a statute-like number (47:1A-1, 10-2(b),
# §63-17), or the word "exemption"/"§" near the call.
CITATION = re.compile(r"§|\bexempt|\b\d+[:.\-]\d+|\bstat\.|n\.?j\.?s\.?a", re.I)
NONRELEASE = re.compile(r"\bwithh|\bredact|\bdenied?\b|\bexempt", re.I)


def load_text() -> str:
    if len(sys.argv) > 1:
        with open(sys.argv[1], encoding="utf-8") as f:
            return f.read()
    return sys.stdin.read()


def check(text: str) -> list[str]:
    low = text.lower()
    issues: list[str] = []

    # 1. No unfilled blanks / unresolved items.
    blanks = re.findall(
        r"\[[^\]]*\b(?:fill[\s_]*in|to\s*confirm|confirm\s+with|pending|tbd|todo|tk|x{3,}|placeholder|insert|cite|citation|authority)\b[^\]]*\]",
        text, flags=re.I,
    )
    blanks += re.findall(r"_{3,}", text)
    if re.search(r"classification pending", low):
        issues.append("Found 'classification pending' — every item must be resolved before sending, not left pending.")
    if blanks:
        sample = sorted(set(b.strip() for b in blanks))[:5]
        issues.append(f"Unfilled blank(s): {sample} — a finished response has none.")

    # 2. Every withhold/redact must carry a citation in its line.
    uncited = []
    for line in text.splitlines():
        if NONRELEASE.search(line) and not CITATION.search(line):
            # skip section headings / generic prose
            if re.search(r"\bwithh|\bredact", line, re.I):
                uncited.append(line.strip()[:70])
    if uncited:
        issues.append("Withhold/redact with no citation on the line: " + str(uncited[:4]))

    # 3. A source stamp / authority section present.
    if not (CITATION.search(text) or "source" in low or "authority" in low):
        issues.append("No source stamp / authority found.")

    # 4. The request was itemized (numbered items or a table).
    if not (re.search(r"^\s*\d+[.)]\s", text, re.M) or "|" in text):
        issues.append("No itemization found — break the request into discrete, addressed items.")

    return issues


def main() -> int:
    issues = check(load_text())
    if issues:
        print("FAIL — fix these before surfacing the response:")
        for i in issues:
            print("  - " + i)
        print("\n(Note: this checks structure only. Each exemption and deadline")
        print(" still needs the custodian's verification against the cited sources.)")
        return 1
    print("PASS — structural discipline checks cleared.")
    print("(Each call still requires the custodian's verification against the cited sources.)")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

Examples

examples/

Sample outputs, so you can see the shape of a good result before you run it.

examples/example-mixed-request.md

Example: research, verify, then draft

Illustrative, showing the skill's contract in action. The skill itemizes the request, researches the law and exemptions from reputable sources, proposes a disposition with each source shown, and drafts only after the custodian confirms every call. Nothing comes from the model's memory. The law and sources below are illustrative.

1. The skill gets oriented

"Which state and records law? Paste the request, and tell me who the custodian is."

Custodian: "[State] Public Records Act. Custodian is the County Clerk. Request: (a) the voting-machine vendor contract; (b) internal staff emails about a polling-place change; (c) the registered-voter list for Ward 3."

2. The skill researches and proposes (for the custodian to verify)

I broke the request into three items and researched each. Please confirm or correct every call before I draft — I won't use anything you haven't verified:

# Item Proposed call Exemption / authority found Source Confidence
1 Vendor contract Release Contracts are public, §10-2(b) State Public Records Act, legislature site High
2 Internal staff emails Withhold Pre-decisional deliberative, §10-4(d) §10-4(d) + state guidance Medium — your call on whether these are deliberative
3 Voter list, Ward 3 Release, redacted Public under §19-7; screen signatures, protected-address participants; redact SSN/DOB State voter-privacy statute §19-7 High

Also found: response deadline 7 business days (§10-2); appeals to the Records Appeals Board within 30 days (§10-9). Please confirm.

3. The custodian verifies

"Confirmed. Item 2 is deliberative — withhold it. Deadline and appeal route are right."

4. The skill drafts the complete response

Response to your records request — [date]

Dear [Requester],

We received your request and have addressed each item below. This response is due within 7 business days under §10-2.

# Item Disposition Authority (verified)
1 Voting-machine vendor contract Released Public record, §10-2(b)
2 Internal staff emails re: polling-place change Withheld Pre-decisional deliberative, §10-4(d)
3 Registered-voter list, Ward 3 Released, redacted Public under §19-7; signatures, protected-address participants, and SSN/DOB redacted

For item 3, the list is enclosed with signatures removed, address-program participants screened, and Social Security numbers and dates of birth redacted.

If you wish to appeal any withholding, you may file with the Records Appeals Board within 30 days.

[Custodian name], County Clerk

Source stamp (for the office's records)

  • Deadline (§10-2), exemptions (§10-2(b), §10-4(d)), voter-list screens (§19-7), and appeal route (§10-9): researched from the state Public Records Act and guidance, and verified by the custodian.

What this example demonstrates

  • The skill did the legwork — itemized, researched each item, and proposed a call with its source and confidence.
  • Nothing was used until the custodian confirmed it; item 2's deliberative call was explicitly left to the custodian, not assumed.
  • The response it returns is complete and ready to review, with no blanks and no unresolved items.

Put it to work

Use it three ways

01

Paste into any tooluniversal

Copy the skill’s contents into Claude, ChatGPT, Copilot, or Gemini, then ask your question. Works everywhere, no setup.

02

Add it to your tool

Set it up as a Claude skill, a custom GPT, a Copilot agent, or a Gemini Gem so it is ready whenever you need it.

03

Download the package

Grab the whole folder (SKILL.md, references, checks, examples), versioned and dated. Yours to keep and review.

Download .zip