{"id":85704,"plugin_id":"plugin_asdk_app_6ae8d8410cc881919fe40cf76b3cc133","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-11-07T06:14:53.410Z","digest":"89a8b286fde50b0fa72c5f40b45abe942e158ce30dfa09bbe47fe4c130d3eb3f","against":null,"payload":{"description":"Research US primary law with the Vaquill AI tools - find a controlling section, resolve a citation to an exact provision, read a section as it stood on a past date, scope a search to the right corpus, and report currency honestly. Use whenever a question turns on what a US statute, regulation, court rule, constitution or agency guidance document actually says, or when a citation needs verifying against the official text.","included_files":[],"name":"us-statute-research","skill_md_contents":"---\nname: us-statute-research\ndescription: Research US primary law with the Vaquill AI tools - find a controlling section, resolve a citation to an exact provision, read a section as it stood on a past date, scope a search to the right corpus, and report currency honestly. Use whenever a question turns on what a US statute, regulation, court rule, constitution or agency guidance document actually says, or when a citation needs verifying against the official text.\n---\n\n# Researching US primary law\n\nThis corpus is enacted and promulgated text from official government publishers.\nEvery answer must rest on text a tool returned.\n\nA plausible fabricated citation is the worst output this tool set can produce, and it is the easiest to produce by accident: **a nonsense query still returns rows.** Vector search always returns nearest neighbours. Separation is the signal, not presence, and search says so directly with `noGoodMatch` (below). Across our labelled eval, a query with no answer in the corpus put its top row at a median `relevanceScore` of about 0.53, where a real one put it near 0.89. A high score still does not prove the top row is the right section: a same-topic section from the wrong jurisdiction or the wrong layer (a state statute for a federal question, a regulation for a statute) scores just as high, so check the citation and jurisdiction of every row you rely on.\n\nRead this before the first call. Most of what follows is the difference between an answer and a confidently wrong answer.\n\n---\n\n## 1. The corpus\n\n### Do not hardcode what it holds\n\nThe published docs say it plainly: do not hardcode credit costs, jurisdiction counts, or corpus lists.\nSection counts differ between the search documentation, the coverage endpoint and the marketing page, and all three go stale.\n\n`list_statutes_coverage` is **free** and is the only live answer. It returns a `corpusTypes` legend, per-jurisdiction counts, freshness notices and retrieval status.\nCall it rather than quoting a number from memory or from this file.\n\n### The corpus tokens\n\nRoughly 19 `corpusType` tokens. The live spec enum and the docs disagree on the exact set, so treat this as orientation and the coverage legend as truth.\n\n**Federal:** `USC`, `SESSION_LAW` (Statutes at Large, as enacted), `STATUTE_COMPILATION`, `CFR`, `CFR_ANNUAL`, `FEDERAL_REGISTER`, `FEDERAL_REGISTER_NOTICE`, `EXECUTIVE_ACTION`, `AGENCY_GUIDANCE`, `AGENCY_ADJUDICATION`, `US_TAX_TREATY`, `SENTENCING_GUIDELINES`, `FEDERAL_RULES`, `CONSTITUTION`.\n\n**State:** `STATE`, `REGULATION`, `STATE_RULES`, `STATE_AGENCY_GUIDANCE`, `STATE_CONSTITUTION`.\n\nA federal token needs only `corpusType`. **A state token needs `state`**, or the search spans every jurisdiction holding that corpus and costs exactly the same.\n\n`source` narrows the folded tokens (`AGENCY_GUIDANCE` alone covers dozens of named sources across many agencies). A bad `source` returns a 422 that names every valid code, **so the API itself is the authoritative list.** Ask it rather than guessing.\n\n### `CFR_ANNUAL` is excluded from the default pool\n\nHistorical CFR editions are not merely demoted, they are excluded from the default candidate pool. An unfiltered search never returns them.\nTo reach a historical edition you must ask for it by token.\n\n### What it does not hold\n\n**No general case law, no court dockets.** The roadmap puts them explicitly out of scope. There is no judicial-opinion search here.\nIf a question needs holdings rather than enacted text, say so instead of reaching for a statute tool that cannot answer it.\n\n**United States only.** A question about another country's law returns empty rather than erroring, which reads as a gap in US coverage. Say the corpus does not cover it.\n\n---\n\n## 2. `act_id`: the single most common failure\n\n> \"You never construct an `actId` by hand.\"\n\nIt looks assemblable. It is not.\n\n```text\nUSC_T42_C21_S1983                       42 U.S.C. § 1983\nCFR_T17_P240_S240_10b5_1                17 C.F.R. § 240.10b5-1\nSTATE_TX_Cpr_C93_S93.005                Tex. Property Code § 93.005\nSTATE_LA_Crevised-statutes_T14_S112.11  La. R.S. § 14:112.11\n```\n\nThe title and section are derivable from a citation. **The chapter is not.**\nIn the Texas example the `Cpr` segment exists only in the data. Ids are case-sensitive and mixed-case.\n\nAssembling ids happens to work for a few jurisdictions whose hierarchy sits in the citation, which is exactly what makes it dangerous: the failures look like missing coverage rather than wrong ids.\n\n| You have | Call | Cost |\n| --- | --- | --- |\n| A citation string | `resolve_statute_citation` | 2 |\n| Many citations | `resolve_statute_citations_batch` | 2 each |\n| A topic | `search_us_statutes` | 4 |\n| A place in the hierarchy | `list_statute_divisions` | 1 |\n\n### The batch endpoint tries to diagnose a bad id, but do not lean on it\n\n`get_sections_batch` (up to 50 ids) returns `notFound` plus `notFoundDetail` with a `reason`:\n\n- **`assembled_id`** - the id does not exist but the section does, under the ids in `didYouMean` (at most 3).\n- **`not_in_corpus`** - malformed beyond recovery, or genuinely absent.\n\nThat distinction is the point: read as \"not in corpus\", an assembled id looks like missing coverage, which is how a working integration gets abandoned.\n\n**Measured 2026-09-07, it is unreliable in both directions:**\n\n```text\nUSC_T42_S1983          -> not_in_corpus, didYouMean []\n                          USC_T42_C21_S1983 exists. This IS an assembled id\n                          and was not diagnosed as one.\n\nSTATE_TX_C93_S93.005   -> assembled_id,\n                          didYouMean [..._Cag_..., ..._Cbc_..., ..._Cfi_...]\n                          The correct code is Cpr. It is not in the list.\n```\n\nSo `not_in_corpus` does **not** mean the section is absent, and a `didYouMean` list does **not** necessarily contain the right id. The spec says it plainly and means it: treat it as a hint rather than a contract.\n\n**Never resolve a bad id by picking from `didYouMean`.** Go back to `resolve_statute_citation` or `search_us_statutes`, which return an id confirmed to exist. Misses are free, so the only cost of guessing here is a wrong answer.\n\n---\n\n## 3. Cost and billing\n\nCosts are in credits. **This table is a snapshot; `get_pricing` is free, unauthenticated and live.**\n\n| Cost | Operations |\n| --- | --- |\n| Free | `list_statutes_coverage`, `get_pricing` |\n| 1 | `list_statute_divisions` (refunded on an empty level), `get_section_changes` |\n| 2 | `get_us_statute_section`, `resolve_statute_citation`, `get_section_neighbors`, `get_section_cited_by`, `get_sections_batch` per section **returned** |\n| 4 | `search_us_statutes`, `get_section_definitions` |\n| 6 | `get_us_statute_section_text`, `get_section_cross_state` |\n\n### Read `creditsConsumed`, never compute it\n\n> \"Read it rather than assuming the list price: failed and refunded work bills 0, and batch endpoints charge per item returned.\"\n\nA batch of 50 ids resolving 47 costs 94 credits, not 100.\n\n### Charged on a negative answer, deliberately\n\nNot bugs. A confident negative is the answer you were paying for.\n\n- An unresolved citation on `resolve`, single or batch. Only backend errors refund.\n- A search returning zero results, including an empty `changedSince` window. \"Nothing moved since Tuesday\" is the answer.\n- An empty but real change history for a section that exists.\n- A `changes` response for a `removed` section. Learning that a provision was repealed is the point.\n- A point-in-time request where the section demonstrably did not exist yet.\n- `cited_by` returning `[]` with **no** `note`, meaning genuinely nothing cites it.\n\n### Refunded\n\n404s everywhere; `body` when `available: false`; `asOf` with `source: \"unavailable\"`; out-of-scope corpora on `cited_by` / `definitions` / `cross_state`; definitions that could not be parsed; an empty `divisions` browse; batch misses; `includeBody` rows that returned `body: null`; every validation rejection; **and any backend outage**.\n\n### A 200 with no results is a real answer, not an outage\n\nThis is load-bearing. When the corpus is unreachable you get a **503 and a refund**, never `200 results: []`.\n\nMeasured against production on 2026-08-15 while the corpus was down, the API *used to* return `200 results: []` and charge 4 credits. That is fixed. So today, an empty 200 means the corpus genuinely has nothing matching, and you should report it as such rather than suggesting a retry.\n\n---\n\n## 4. Search\n\nHybrid semantic plus keyword ranking. There is deliberately no keyword-only mode.\n\n### Scope it, always\n\n> \"Unscoped queries can surface keyword matches from unrelated corpora; a corpus filter sharply improves precision.\"\n\n- `state` takes a 2-letter code or `federal`, and a **list** works: `[\"ca\",\"ny\",\"tx\"]` is one call instead of three.\n- `code` is the only way to scope below a jurisdiction. `state=tx` alone searches all ~15 Texas codes. Values are the `identifier` from `list_statute_divisions`, fed straight back.\n- `chapter` and `part` **must** be paired with `titleNumber` (USC/CFR) or `code` (state). Unpaired is rejected, because chapter numbers repeat across titles.\n- `titleNumber` is only valid with `USC` or `CFR`. Without a corpus scope it is rejected, because an unscoped numeric title mixes state statutes with USC rows.\n- Every result carries a `parent` object. **Feed it back verbatim** to search that hit's neighbours; it always carries one of the required pairings.\n\n### Caps\n\n| Limit | Value |\n| --- | --- |\n| `limit` | max 50, default 10 |\n| `offset` | max 70 |\n| **Deepest reachable result** | **#120** |\n| `query` | 2 to 500 chars |\n| Batch `actIds` / `citations` | 50 |\n\nDo not page past `offset` 70. Narrow the query instead.\n\n`count` is the size of the current page. **`total` is a deprecated alias for `count`** whose name reads as a corpus-wide total, which it never was. Read `count` in new code.\nThere is no corpus-wide match total: ranking runs over a bounded 120-candidate pool. `total == count` with `hasMore: true` is correct.\n\n### `relevanceScore`\n\nRoughly 0 to 1, a **relative rank within one response**. Never compare across queries, never use a fixed threshold.\nOnly an exact citation match returns 1.0. It is **null** on endpoints that did not rank (fetch by id, batch fetch): null means \"not ranked\", not \"bad match\".\n\nJudge a result set by the *separation* between top and tail, not by whether rows came back.\n\n### `noGoodMatch`\n\nTop-level on a search response. **Read it before you cite anything from the page.**\n`true` means nothing in the corpus looks on point (or no rows came back): tell the user the corpus has nothing on this, and do not answer from the rows.\n`false` means something on point exists, or the top row is an exact citation match.\n`null` means the ranking was degraded (`rankingDegraded: true`); retry the query.\nIt never says the top row is the RIGHT section: a same-topic section from the wrong jurisdiction or layer can lead, so still check citation and jurisdiction.\n\n### `matchQuality`\n\nHow likely row 1 is the right section: `exact` (citation or section-number match), `strong` (right about 94% of the time in our measurements, about 91% for statutes and regulations), `moderate` (about 67%), `weak` (about 35%), `none` (same as `noGoodMatch: true`), `null` when degraded.\nOn `moderate` or `weak`, read the top few rows before answering and say which one you relied on and why. An unknown value means `moderate`.\n\n### `fields` projection\n\nA result carries 40+ fields, most null on any row. `fields` trims the payload; `actId` and `citation` are always included.\nAn unknown field name is **rejected with 422** so a typo does not silently drop a field you needed.\n\n### `includeBody` is a cost multiplier\n\nThe 4-credit search **plus the full 6-credit body price for every row that returns text**.\n\n- 10 rows with text: 4 + 60 = **64 credits**\n- `limit: 50`: **304 credits in a single call**\n\nRows with `body: null` are not charged, so the real cost is never computable from `limit`.\nIt buys latency, not a discount. Running out of credits for the bodies does **not** void the search: rows serve with `body: null` and you are charged only for the search.\n\n### The excerpt is not quotable\n\n> \"`excerpt` is a ranking preview windowed around the match, so it can begin mid-section and drop a leading subsection marker.\"\n\nMeasured 2026-09-02: four of five California rows were exactly 4 characters short, and the missing 4 were the leading `(a) `. `body.startswith(excerpt)` is **false**.\nFor statutory text that is a misquote, not a formatting nit.\n\n**Never quote `excerpt` to a user.** Use it to choose which section to fetch, then fetch the body. Raising `excerptChars` does not help; a bigger excerpt is still an excerpt.\n\n### Currency filters are not point-in-time\n\n- `yearFrom` / `yearTo` filter the **most recent** amendment year. A section amended in 2025 is excluded by `yearTo=2024` even though it existed in 2024.\n- Sections carrying no date at all are **silently excluded** the moment either bound is set, so an unbounded search returns strictly more.\n- The corpus holds one current text per citation. For a past text use `asOf`.\n\n### `changedSince` is the sync filter\n\n> \"These are observed changes, not effective dates. The date is when we SAW it, an upper bound on when it took effect.\"\n> \"An empty result means no captured change in the window, never that nothing was amended.\"\n\nEvents are swept at **24 months**. A window matching more than 20,000 sections is **refused, not truncated**, because a partial change set would look complete to a sync job. Narrow with `corpusType` and `state`.\n\n---\n\n## 5. Reading a section\n\n### Metadata is not text\n\n`get_us_statute_section` (2) returns citation, hierarchy, breadcrumb, status and format links.\n`get_us_statute_section_text` (6) returns the body.\nDo not pay 6 to answer \"does this exist\" or \"what is it called\".\n\n### On USC, the body is mostly not the law\n\nThe highest-impact fact in this skill.\n\n> \"The operative text is a median 46% of it across USC, and as little as 3.4% on `17 U.S.C. § 107`, where 28,529 of 29,775 characters are commentary.\"\n\n| `format` | Returns |\n| --- | --- |\n| `both` | html + plain (default; the same text twice) |\n| `plain` / `html` | one of them; roughly halves the payload |\n| `content` | **operative text only**, with `sourceCredit` and `notes` split out |\n\n**If you are feeding sections to a model, use `content`.** The full body invites quoting a 1992 amendment note as the law in force. On `17 U.S.C. § 107` that is ~1 KB instead of ~30 KB, same price.\n\n**`content` is USC only.** CFR and state corpora carry no equivalent structure, so all three split fields are null there and `plain` remains the whole body.\nNull means \"we cannot split this reliably\", never \"this section is empty\". Check for null and fall back to `plain`.\n\n### `structured: true`\n\nAdds `markdown` and a `subsections` tree at no extra cost. Nodes carry `label` (`(b)`), `pincite` (`(b)(2)`), a full pinpoint `citation`, and `text` **excluding nested children**.\nUse it when the user needs a specific subsection.\n\n### Which URL to cite\n\n- `sourceUrl` on the body, and `externalUrl` on a result, are the government's published address. **Cite these.**\n- `source` names our storage backend. It is **not a citation**.\n- `stateHtmlUrl` is the publisher's page for most state corpora, but for mirrored corpora it is our archived copy. Prefer `externalUrl`.\n- **A null source URL is often correct, not missing data.** Some state regulations and court rules are published through commercial platforms where the licence covers sourcing but not republishing the link, so a `licenseNote` says a link exists and is withheld. We never substitute a third-party compiler.\n\n---\n\n## 6. Point-in-time (`asOf`)\n\n`get_us_statute_section_text` takes `asOf=YYYY-MM-DD`, same 6 credits. There is no versions endpoint; `get_section_changes` is the timeline.\n\n> \"It is a reconstruction, not an archive. The corpus holds one current text per citation; an earlier one is rebuilt from the before-side of the first change we OBSERVED after your date.\"\n\n`html` is **never** returned on this path. Synthesising markup the publisher never printed would be a wrong answer on the endpoint whose job is fidelity.\n\n| Field | Meaning |\n| --- | --- |\n| `source: live` | No change captured after your date, so today's text is what stood then **as far as we ever saw** |\n| `source: reconstructed` | Rebuilt from the before-side of a captured change |\n| `source: unavailable` | We know it changed and cannot rebuild it. No text. **Refunded** |\n| `existed: false` | Earliest capture is its ADDITION, postdating your date. A real answer. **Charged** |\n| `observedFrom` | Earliest change ever captured. A property of when capture began, not of the age of the law |\n| `basisChangeId` | The change the reconstruction rests on. Null when `source` is `live` |\n| `coverage` | Prose, written to be shown to a reader verbatim |\n\n### `isBounded` is load-bearing\n\n> \"TRUE means: we observed no change affecting your date, and that is NOT the same as there having been none. Surface it. Rendering a bounded answer as authoritative point-in-time law makes a claim we did not make.\"\n\nNever say \"this is what the law said on that date\" for a bounded answer. Say what we can attest to, and show the `coverage` prose.\n\n### Published-edition corpora are enumerations\n\n`CFR_ANNUAL` and some compendia hold discrete published editions. `editionsObserved` **is an enumeration, never a range**: an edition list of 1996 and 2011 says nothing about 2004.\n\n---\n\n## 7. Currency: the fields that look alike\n\nGetting this wrong tells a lawyer that dead law is live.\n\n### `year` is a trap\n\n> \"The year this row was ingested, not the year of the law. Most ingesters stamp the capture year, so 1,575,300 statute sections currently read 2026. Do not filter or reason about currency with it.\"\n\n### `actStatus` is raw and filterable; `goodLawStatus` is derived and not\n\n`actStatus` is the publisher's own word as recorded, stored and indexed.\n`goodLawStatus` is computed at read time from status, jurisdiction, publisher and category. It is **not** filterable.\n\n> \"Filtering on the status we store and reporting the verdict we derive are deliberately separate, because only the first is indexable.\"\n\n### The `goodLawStatus` vocabulary\n\n| Value | Meaning |\n| --- | --- |\n| `good_law` | **Two claims**: the publisher marks it in force, AND we have verified this publisher actually prints repeals where we can read them, so an absent repeal marker is evidence |\n| `not_good_law` | Checked, and dead |\n| `not_operative` | Exists, no operative force right now (reserved, vacant, dormant, unfunded, not yet effective). It may become law later |\n| `unknown` | **Unverified.** Not a soft yes and not an alarm |\n| `null` | Currency checking is switched off server-side |\n\n**`unknown` is a statement about our measurement, not about the law.** It conflates three genuinely different situations the API cannot currently tell apart:\n\n1. A section its own legislature prints as in force, in a jurisdiction whose repeal signal nobody has verified. California statutes and a large share of state regulations sit here.\n2. A status the currency module does not classify: `enacted` (session laws), `snapshot` (mirrors), `pending`, `non_precedential`.\n3. A document that is not current law at all: a frozen enactment record, an internal procedure, an adjudication a later panel may have overruled.\n\n> \"Treat `unknown` as 'verify against the official source,' not as 'current.'\"\n\n`good_law` is the only affirmative currency claim. **Never infer currency from the absence of `not_good_law`.**\n\nBe especially careful under `AGENCY_ADJUDICATION`: a decision served as issued may have been overruled the week after it was decided, and nothing in this API will tell you.\n`SESSION_LAW` and `STATUTE_COMPILATION` carry `unknown` by design; they are records of enactment, not of current force.\n\n### `excludeRepealed` does not promise good law\n\n> \"This removes what we KNOW is dead. It does not promise the remainder is good law. A section survives when its status is `in_force` OR when we hold no trustworthy repeal signal for its jurisdiction, and those two are not the same thing.\"\n\nFilter with it, then **read `goodLawStatus` on every survivor**.\n\nTo find what was lost rather than what remains, use `actStatus: \"repealed\"`. Combining a dead `actStatus` with `excludeRepealed: true` contradicts itself and is rejected with 422.\n\nTwo filter asymmetries worth knowing:\n\n- **`non_precedential` is filterable but never excludable.** Excluding it would drop tens of thousands of documents from an \"exclude repealed law\" query, which is not what that asks for.\n- **`enacted`, `snapshot` and `pending` are rejected as filter values** even though they exist on hundreds of thousands of points, because \"offering a filter for a status we cannot interpret would sell certainty we do not have.\"\n\nDead law is **demoted, not dropped**, from default search results. It will appear unless you exclude it.\n\n### IRS written determinations\n\nThey carry `actStatus: \"non_precedential\"` and by statute \"may not be used or cited as precedent\" (26 U.S.C. § 6110(k)(3)). Say so if you surface one.\n\n### Amendment counts do not match amendment years\n\n> \"`amendmentsCount` is not the length of `amendmentYears`, and it is not safe to derive one from the other. The two differ on 181,757 regulation sections and 15,648 court-rule sections.\"\n\n`amendmentYears` is served newest-first and de-duplicated. `lastAmendedYear` is re-derived as its max.\n`effectiveDate` and `originalEnactmentDate` are deliberately separate: merging them reports an amended section as effective from its original year.\n`reviewDate` is a future review deadline, not an amendment date.\n\n### Follow the pointer when a section moved\n\n`supersededBy` carries the replacement's `actId`, so you can fetch current text in one hop. `renumberedTo` and `transferredTo` do the same.\n\n---\n\n## 8. Citation resolution\n\nAccepts `42 U.S.C. 1983`, `16 C.F.R. 444.1`, `Del. Code Ann. tit. 13, 1301`.\n\n**Charged whether or not it resolves**, by design: a confident \"this does not resolve\" is exactly the answer you want when checking a citation an LLM produced. Only server errors refund.\n\n> \"When it does not resolve, `resolved` is `false` and `section` is `null`: treat that as 'unverified', not 'current'.\"\n\nReport it as **\"did not resolve\"**, never as \"does not exist\". Only the first is something you observed.\n\n### Ambiguous acronyms resolve to false, correctly\n\n`MCA`, `IC`, `G.S.`, `G.L.`, bare `R.S.`, and court-rule sets like `CR`, `RAP`, `TCR` are genuinely ambiguous. `resolved: false` is the right answer, not a coverage gap.\n\n### `state` is a constraint, not a hint\n\nA citation naming a different jurisdiction returns `resolved: false` rather than being forced into the one you passed.\n`8 CCR 1206-2` is Colorado and `22 CCR 76227` is California; the acronym alone cannot say which.\nFor a batch spanning jurisdictions, omit `state` and let each citation name its own.\n\n### `subsection` has two meanings\n\n1. A pinpoint you cited resolves to the parent section and echoes the pinpoint back.\n2. The citation named a unit **smaller than the publisher issues**. Rhode Island cites `250-RICR-120-05-15.2` but publishes the whole Part, so `section` is Part 15 and `subsection` is `15.2`.\n\n> \"A non-null `subsection` always means `section` is the containing document, not the exact unit you cited.\"\n\nDo not quote a whole Part as if it were the cited subsection.\n\n### Batch\n\nUp to 50. Duplicates collapsed before pricing. **Every input gets an entry**, unresolved included, because a caller checking thirty citations needs to know *which* failed.\n\n---\n\n## 9. Section intelligence, and its scope limits\n\nEach returns empty with a `note` and **refunds** when out of scope.\nAn empty result **with** a `note` is an explanation. **Without** one it is a real answer.\n\n| Tool | Scope | Cost | Notes |\n| --- | --- | --- | --- |\n| `get_section_neighbors` | Any | 2 | `limit` 1-10 per side, default 3. Never crosses the containing chapter. Natural order: `9` before `10`, `1983` before `1983a` |\n| `get_section_cited_by` | **USC and CFR only** | 2 | State codes and FR rules carry no cross-reference index |\n| `get_section_definitions` | Strongest on USC; CFR and state best-effort | 4 | Refunded when terms cannot be parsed, but `definitionsSection` is still populated so you can read it yourself |\n| `get_section_cross_state` | **State statutes only** | 6 | One provision per state, `limit` 1-25 |\n\n### Definitions matter more than they look\n\n> \"Statutes do not use ordinary English. 'Person' routinely includes corporations, 'employee' routinely excludes independent contractors, and the section you are reading almost never says so.\"\n\nBefore interpreting a section that turns on a defined term, spend the 4 credits.\n\n### `cited-by` is evidence, not proof\n\n> \"A citation that the source never recorded in machine-readable form cannot appear here, so treat a result as evidence of a citation rather than proof there are no others.\"\n\n### `cross-state` similarity is not a legal opinion\n\n> \"A high score means the provisions cover the same ground, never that they impose the same obligation, and the differences are usually the point.\"\n\nFewer states than requested means the rest did not clear the similarity floor, not that they are missing.\nVerify each hit's body before saying two states' rules match.\n\n---\n\n## 10. Change history\n\n`get_section_changes`, 1 credit, `limit` up to 200.\n\n- `detectedAt` is when **we saw it**, an upper bound on effect. A weekly source is seen up to a week late. Never present it as the date the law changed. For the publisher's own dates read `amendmentHistory` on the section.\n- An empty history means **no captured change**, not never amended. Capture began long after the corpus, is per-source, and events are swept at 24 months. Surface the `coverage` prose rather than rendering an empty list as \"unchanged\".\n- **A removed section still answers.** `section` comes back null on a successful, charged 200, not a 404.\n- Absence of a `removed` event is not proof a section stands: a narrow, section-scoped refresh cannot observe a removal.\n- Page with `sinceId` forward, `beforeId` backward. `id` is monotonic corpus-wide, immune to clock skew, and cannot drop two changes sharing a timestamp. **Never page on `detectedAt`.**\n- `hasMore` means \"this page filled to `limit`\", not that more rows are known to exist.\n- Use `displayCitation` for display; it always has something readable.\n\nA 404 means no such section **and** no change ever captured for that id.\n\n---\n\n## 11. Rejected, ignored, or merely empty\n\n**Rejected with 422** (the request was wrong, and saying so is the point):\nany unknown key in the search body; unknown `state`, `source`, `fields` name, `corpusType` or `actStatus`; unpaired `chapter` or `part`; `titleNumber` without a USC/CFR scope; a dead `actStatus` with `excludeRepealed: true`; an impossible calendar date such as `2026-02-30`; `yearFrom > yearTo`; `limit` over 50; `offset` over 70; a batch over 50; a `changedSince` window over 20,000 sections.\n\nThe forbidden-extras rule exists because a customer sending a key that was not a filter \"was charged full price for results that were never filtered, and nothing in the response said so.\"\n**A 422 naming your key is the API working correctly.** Fix the key; do not retry without it.\n\nNote one inconsistency: the single `resolve` returns **400**, not 422, for a bad scope.\n\n**Silently ignored**: nothing important. Filters that cannot apply are rejected rather than dropped.\n\n**Empty, not an error**: `agency` combined with a non-Federal-Register corpus.\n\n**Branch on status, not on the `detail` string** (the wording is not part of the contract):\n401 bad key, 402 out of credits, 403 missing scope or plan entitlement, 404 no such resource, 429 rate limited, 503 backend unavailable and refunded.\n\n### Rate limits\n\n| Plan | Per minute | Per hour | Per day |\n| --- | --- | --- | --- |\n| Pro | 30 | 500 | 1,000 |\n| Business | 150 | 2,500 | 10,000 |\n\nFree and 1-credit discovery endpoints still count. `429` carries `Retry-After`; honour it, with exponential backoff as fallback.\n\n**Do not trust `X-RateLimit-Limit`.** It is computed without the plan multiplier, so a Business key enforced at 150/min has every response advertising 30. Derive your budget from your plan, not the header. `X-RateLimit-Reset` is always the next minute boundary, so it says nothing about an hour or day trip.\n\nBatch endpoints are how you stay under these: 30 citations in one call is one request, not 30.\n\n---\n\n## 12. Caching that affects your answer\n\n**Rankings are cached 300 seconds, shared across workers and customers.** The key covers the query and every ranking filter, but not `limit`, `offset`, `includeBody`, `excerptChars` or `fields`.\n\nConsequences:\n\n- Paging is stable by design: every page slices one ranking, so results never repeat or go missing.\n- Page 2 costs no compute but still costs 4 credits.\n- A corpus refresh landing mid-window is invisible until the TTL expires. If you need certainty about a just-published change, use the change endpoints, not search.\n- Empty rankings are never cached, so a transient degradation cannot pin a thin result as the answer.\n\n**Coverage metadata is cached 600 seconds with stale-while-revalidate, and a failing rebuild pins the last good value indefinitely** on purpose: \"a stale row is accurate while a degraded row reports a real corpus as absent.\"\n**Read `measuredAt`.** It can legitimately be hours old. It has been observed serving a 15.9-hour-old value at HTTP 200.\n\nA cold coverage call can take a long time (a cold build is ~52 facet queries). A slow first call is expected, not a fault.\n\n---\n\n## 13. Worked patterns\n\n### Verify a citation an LLM produced\n\n```text\nresolve_statute_citation(\"42 U.S.C. 1983\")     2 credits\n  resolved: false -> report UNVERIFIED, never \"does not exist\"\n  resolved: true  -> read goodLawStatus on the section\n                     good_law     -> current\n                     unknown      -> unverified, say \"verify against the source\"\n                     not_good_law -> lead with that\n```\n\n### \"What does the law say about X in California\"\n\n```text\nlist_statutes_coverage                          free   confirm CA holds STATE\nsearch_us_statutes(query=X, state=\"ca\",         4      scope it\n                   corpusType=\"STATE\",\n                   excludeRepealed=true)\n  -> judge by score SEPARATION, not by rows returned\n  -> choose from excerpts; do NOT quote them\nget_us_statute_section_text(act_id,             6      the actual text\n                            format=\"content\" if USC)\nget_section_definitions(act_id)                 4      only if a term is doing work\n```\n\nAbout 14 credits for a grounded answer.\n\n### Point-in-time\n\n```text\nresolve_statute_citation(cite)                  2\nget_section_changes(act_id)                     1      what was observed\nget_us_statute_section_text(act_id, asOf=date)  6\n  -> report text + the asOf block + coverage prose\n  -> if isBounded, say what we can attest to, not what the law was\n```\n\n### Check 30 citations in a brief\n\n```text\nresolve_statute_citations_batch([...30...])     60     ONE request\n  -> every input gets an entry; unresolved ones are named\nget_sections_batch(resolved act_ids)            2 each returned\n  -> read notFoundDetail.reason on any miss\n```\n\nSame price as one at a time, 2 requests instead of 60, and it keeps you inside the rate limit.\n\n---\n\n## 14. Reporting discipline\n\n- **Quote the body, never the excerpt.** The excerpt can start mid-section and drop a subsection marker.\n- **On USC, quote from `content`, not `plain`.** The median USC body is 54% commentary.\n- Judge a result set by score separation. Rows always come back, even for nonsense.\n- Give the citation exactly as reported, including subdivision. Use `citationShort` when a year would mislead.\n- Cite `externalUrl` or `sourceUrl`. Never `source`, which is storage.\n- Lead with `goodLawStatus` when it is not `good_law`. A correct quotation of dead law is still a wrong answer.\n- Report `unknown` as unverified, and tell the user to check the official source.\n- Surface the `coverage` prose on anything point-in-time or change-related. It is written to be shown verbatim.\n- Distinguish \"did not resolve\" from \"does not exist\".\n- If nothing was found, say nothing was found. Never fill the gap from memory.\n\n---\n\n## 15. Deprecated\n\n| Deprecated | Use instead |\n| --- | --- |\n| `/states`, `/laws` | `list_statutes_coverage` (a superset) |\n| `/codes` | `list_statute_divisions` |\n| bare `/api/v1/statutes/*` | `/api/v1/us/statutes/*` |\n| `total` on a search response | `count` |\n\nThe bare path still works and emits `Deprecation: true` with a successor link. There is no `Sunset` header and no committed removal date; existing keys keep working.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}