Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use whenever the user asks about a motor-vehicle statute, citation, contributing factor, OR a Canadian personal-injury fact pattern — always query Specter's Harvester API before answering. The API auto-routes between two collections (US statutes + Canadian PI case law).
.claude/skills/thomasmoreai-harvester-query/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 65% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 29% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 15% | 0% |
| case-11 | ✗→✓ | ▲ Improved | -39% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 41% | 0% |
Specter's Harvester is a FastAPI service that fronts two Chroma collections:
| Collection | Contents | When the API uses it | |---|---|---| | specter_statutes | 384 US motor-vehicle statutes (CA, TX, FL, PA, IL, OH) | default — any US-jurisdiction or generic query | | canada_pi_cases | 340 real Canadian PI cases (CanLII, with damages, injury type, plaintiff_won, deciding_factor) | auto-routed when the query mentions Canada / Ontario / Quebec / Toronto / ONSC / ONCA / canlii / etc., or when ?jurisdiction=Canada or ?state=CA-CAN is passed |
Every citation the user sees should come from the Harvester (or, on miss, from a verified web source). Never fabricate.
search first; ask follow-ups only after showing what hit.lookup_citationsearchaskfactor filter (see categories below).For Canadian fact-pattern queries especially, call search first with whatever the user said, even if it's vague. Show the top hits, THEN ask any follow-ups. The Canada corpus is fact-pattern-indexed — thin queries still return relevant cases. Demanding more facts before searching wastes the corpus.
The helper module sits next to this SKILL.md:
pythonimport sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent)) # if running ad hoc from client import lookup_citation, search, ask, healthz, list_factors
In OpenClaw, prefer running it via exec:
bashcd ~/Specter && python3 -m openclaw.skills.harvester_query.client lookup "Cal. Veh. Code § 23152(a)" cd ~/Specter && python3 -m openclaw.skills.harvester_query.client search "drunk driving" --state CA --factor "DUI/DWI" cd ~/Specter && python3 -m openclaw.skills.harvester_query.client ask "what statutes cover hit and run in CA"
Or from Python:
pythonfrom openclaw.skills.harvester_query.client import lookup_citation, search, ask
lookup_citation(citation: str) -> dict | NoneExact match by citation string. Returns the full record or None if not in the Harvester.
search(q: str, *, state=None, factor=None, pi_only=False, k=10) -> list[dict]Semantic search. state is a 2-letter code ("CA", "TX"). factor must be one of the 17 canonical categories.
ask(question: str, *, state=None, factor=None, k=8) -> list[dict]Same as search but framed as a question. Use this when the user hands you a natural-language query.
healthz() -> dictCheap liveness check. Use to confirm the API is running before reporting a miss.
list_factors() -> list[str]The 17 categories. Useful for synonym mapping in voice.
Specter's voice rules (see SOUL.md): 2–3 lines max by default. Cite, don't quote.
Good: > Cal. Veh. Code § 22350. Basic speed law — drive no faster than reasonable for conditions. > leginfo.legislature.ca.gov
Bad: > Of course! Pursuant to California Vehicle Code Section 22350, "no person shall drive a vehicle…" (wall of text)
Always include the source_url from the record. Never include a citation without one — per hackathon ground rules, records without a real source URL don't count.
If lookup_citation returns None or search/ask returns []:
healthz() — if the API is down, say so plainly.Never paper over a miss with a guess.
DUI/DWI
Driving Too Fast For Conditions
Failure to Maintain Lane
Failure to Obey Traffic Control Device
Failure to Use/Activate Horn
Failure to Yield at a Yield Sign
Failure to Yield the Right-of-Way
Fleeing a Police Officer
Fleeing the Scene of a Collision
Following Too Closely
Improper Lane of Travel
Improper Passing
Improper Starting
Improper Stopping
Improper Turning
Reckless Driving
Using a Wireless Telephone/Texting While DrivingIf the user uses a synonym, map internally and answer in their words.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 13,935 | 11,805 | -15% | 1 | 1 | 0% | 2,594 | 3,159 | +22% | 0 | 0 | — |
case-02 | fail→fail | 3,900 | 6,964 | +79% | 1 | 1 | 0% | 770 | 1,665 | +116% | 0 | 0 | — |
case-03 | fail→fail | 5,361 | 5,296 | -1% | 1 | 1 | 0% | 1,137 | 1,800 | +58% | 0 | 0 | — |
case-04 | pass→pass | 7,206 | 6,211 | -14% | 1 | 1 | 0% | 1,189 | 2,519 | +112% | 0 | 0 | — |
case-05 | pass→pass | 7,654 | 3,201 | -58% | 1 | 1 | 0% | 1,257 | 1,770 | +41% | 0 | 0 | — |
case-06 | fail→pass | 12,626 | 1,290 | -90% | 1 | 1 | 0% | 984 | 1,625 | +65% | 0 | 0 | — |
case-07 | fail→pass | 7,599 | 1,592 | -79% | 1 | 1 | 0% | 1,388 | 1,791 | +29% | 0 | 0 | — |
case-08 | pass→pass | 8,037 | 1,846 | -77% | 1 | 1 | 0% | 1,392 | 1,760 | +26% | 0 | 0 | — |
case-09 | fail→pass | 7,710 | 1,729 | -78% | 1 | 1 | 0% | 1,559 | 1,786 | +15% | 0 | 0 | — |
case-10 | pass→pass | 8,682 | 7,188 | -17% | 1 | 1 | 0% | 1,761 | 2,810 | +60% | 0 | 0 | — |
case-15 | fail→fail | 10,294 | 5,306 | -48% | 1 | 1 | 0% | 1,942 | 1,824 | -6% | 0 | 0 | — |
case-11 | fail→pass | 13,454 | 1,380 | -90% | 1 | 1 | 0% | 2,820 | 1,711 | -39% | 0 | 0 | — |
case-12 | fail→pass | 7,050 | 2,759 | -61% | 1 | 1 | 0% | 1,390 | 1,955 | +41% | 0 | 0 | — |
case-13 | fail→pass | 9,438 | 2,640 | -72% | 1 | 1 | 0% | 1,724 | 1,659 | -4% | 0 | 0 | — |
case-14 | fail→pass | 8,891 | 1,311 | -85% | 1 | 1 | 0% | 1,562 | 1,704 | +9% | 0 | 0 | — |
case-16 | pass→pass | 10,560 | 1,508 | -86% | 1 | 1 | 0% | 1,919 | 1,754 | -9% | 0 | 0 | — |
case-17 | fail→pass | 8,918 | 2,490 | -72% | 1 | 1 | 0% | 1,511 | 2,005 | +33% | 0 | 0 | — |
case-18 | fail→pass | 10,359 | 1,847 | -82% | 1 | 1 | 0% | 1,608 | 1,735 | +8% | 0 | 0 | — |
case-19 | pass→fail | 15,028 | 7,465 | -50% | 1 | 1 | 0% | 2,653 | 1,852 | -30% | 0 | 0 | — |
case-20 | fail→pass | 16,259 | 7,004 | -57% | 1 | 1 | 0% | 3,181 | 2,675 | -16% | 0 | 0 | — |
case-21 | pass→pass | 12,380 | 2,821 | -77% | 1 | 1 | 0% | 2,250 | 1,980 | -12% | 0 | 0 | — |
case-22 | fail→fail | 18,548 | 22,378 | +21% | 1 | 1 | 0% | 4,172 | 5,336 | +28% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 18 counted toward the lift figure. The other 4 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +41 percentage points is the difference between those two pass rates over the 18 comparable cases. 3 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.