| name | schema-creation |
| description | Author and iterate one-shot extraction schemas for native COMPASS. Use whenever a user asks to create, expand, or debug schema feature definitions, value/unit rules, or extraction instructions. |
Schema Creation Skill
ONE-SHOT EXTRACTION ONLY. This skill applies only to schema-driven extraction
(new technology onboarding with JSON schema + plugin YAML). For legacy decision-tree
extraction (existing solar/wind/small-wind in compass/extraction/<tech>/),
consult COMPASS architecture docs.
Use this skill to define what the LLM extracts and how it formats results.
The schema is the single most important config file for output quality.
When to use
- Starting a new one-shot technology extraction (NOT decision-tree legacy extraction).
- Fixing inconsistent or incorrect extracted values in one-shot extraction.
- Adding new features to an existing one-shot extraction.
Do not use
- Retrieval tuning tasks that belong in plugin YAML.
- Legacy decision-tree extraction parser implementation.
Expected assistant output
When using this skill, return:
- The proposed schema diff (or full schema block) for the targeted features.
- The rationale for VALUE, UNITS, and IGNORE wording.
- A smoke-test check plan for validating the schema change.
Canonical reference
For complete examples, see the examples/ directory:
examples/one_shot_schema_extraction/wind_schema.json
examples/water_rights_demo/one-shot/water_rights_schema.json5
Each follows the pattern: <tech>_schema.json or <tech>_schema.json5.
Required output contract
Every schema must define outputs as an array. Each item must require
exactly these five fields and set additionalProperties: false:
{
"type": "object",
"required": ["outputs"],
"additionalProperties": false,
"properties": {
"outputs": {
"type": "array",
"items": {
"type": "object",
"required": ["feature", "value", "units", "section", "summary"],
"additionalProperties": false,
"properties": {
"feature": { "type": "string", "enum": ["..."] },
"value": { "anyOf": [{"type": "number"}, {"type": "string"}, {"type": "boolean"}, {"type": "array", "items": {"type": "string"}}, {"type": "null"}] },
"units": { "type": ["string", "null"] },
"section": { "type": ["string", "null"] },
"summary": { "type": ["string", "null"] }
}
}
}
}
}
These five fields map directly to the output CSV columns. COMPASS adds
county, state, FIPS, and other metadata columns automatically.
Build sequence
- Define the feature enum — one stable lowercase ID per siting-relevant
requirement. Keep naming consistent across iterations and group IDs by
family (setbacks, noise, zoning, permitting).
- Define
value and units rules per feature family — in each
feature's description, state the expected value type and accepted unit
vocabulary explicitly.
- Add
$definitions — group related feature descriptions here to keep
the feature enum block clean.
- Add
$instructions — encode global extraction policy (scope, null
handling, one-row-per-feature contract, verbatim quote preference).
- Smoke-test on one jurisdiction — validate all enum items appear in
output and null rows are correctly populated for missing features.
Feature definition template
Every feature description must answer four questions:
- What is this? One sentence identifying the regulatory concept.
- VALUE rule: What type is the value and what specific values/ranges are
valid?
- UNITS rule: What unit string is accepted, or
null if not applicable?
- IGNORE / CLARIFICATION: What near-miss concepts must NOT match this
feature?
Example (abbreviated):
"structure setback": {
"description": "Minimum distance from the generator to an occupied building. VALUE: numerical distance. UNITS: 'feet' or 'meters'. IGNORE: setbacks from property lines or roads — those are separate features."
}
Feature family taxonomy
Organize $definitions by these families:
| Family | Example features |
|---|
| Setbacks | structure setback, property line setback, road setback |
| Noise/Emissions | noise limit, emissions standard, vibration limit |
| Operational | hours of operation |
| Physical design | screening requirement, enclosure requirement, exhaust stack height |
| Zoning | primary use districts, conditional use districts, prohibited use districts |
| Permitting | permit requirement, capacity threshold |
| Compliance | decommissioning |
$instructions block
Always include a $instructions object at the top level with these keys:
"$instructions": {
"scope": "Describe exactly what to extract and what to ignore.",
"null_handling": "Output every enum feature. Use null value and null summary when a feature is not found in the document. Do not omit features.",
"verbatim_quotes": "In summary fields, prefer verbatim quotes from the source. Enclose in double quotation marks.",
"units_discipline": "Do not convert units. Record them exactly as they appear in the document."
}
Scope bleed control
When COMPASS retrieves a large land-use code instead of a tech-specific
ordinance, the LLM may extract off-domain provisions.
Fix order (most powerful first):
extraction_system_prompt in plugin YAML — state explicitly what is in
scope and what is excluded.
$instructions.scope in schema — reinforce with exclusion language.
heuristic_keywords.NOT_TECH_WORDS — reject documents upstream.
Do not expand the feature enum to absorb scope bleed. Narrow the prompt.
Cross-technology adaptation checklist
When cloning a schema for a new technology:
Quality checklist
Anti-patterns to avoid
- Feature IDs that change names between iterations.
- Implicit unit assumptions not stated in description text.
- Missing IGNORE clauses for common near-miss features.
- Examples in descriptions that contradict field rules.
- Widening the enum to absorb scope bleed instead of tightening the prompt.