Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Normalize cross-skill JSONL interfaces (ids + titles + citation key formats) so downstream skills do not rely on best-effort joins. **Trigger**: schema normalize, jsonl contract, interface drift, join drift, 字段不一致, schema 规范化. **Use when**: you have generated C2-C4 JSONL artifacts (outline/briefs/bindings/packs/anchors) and want deterministic, stable fields before self-loops/writing.
.claude/skills/willoscar-schema-normalizer/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | -8% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 13% | 0% |
| case-12 | ✗→✓ | ▲ Improved | -3% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 37% | 0% |
| case-19 | ✗→✓ | ▲ Improved | -40% | 0% |
Purpose: close a common failure mode in skills-first pipelines: schema drift across JSONL artifacts.
When fields are inconsistent (missing ids/titles, mixed citation-key formats), downstream skills start doing best-effort joins and fragile parsing. This skill makes the interface explicit and deterministic.
outline/outline.yml (source of truth for section/subsection ids + titles)citations/ref.biboutline/subsection_briefs.jsonloutline/chapter_briefs.jsonloutline/evidence_bindings.jsonloutline/evidence_drafts.jsonloutline/anchor_sheet.jsonloutline/writer_context_packs.jsonloutput/SCHEMA_NORMALIZATION_REPORT.md (always written; PASS/FAIL + what changed).bak.* is created if changes are applied).For any record with sub_id: "<H2>.<H3>":
section_id exists (derived from the prefix before the dot)title, section_title exist (filled from outline/outline.yml)For any record with section_id: "<H2>":
section_title exists (filled from outline/outline.yml)Within these C2-C4 JSONL artifacts, normalize citation keys so they are raw BibTeX keys (no @ prefix):
"citations": ["smith2023", "jones2024"]Notes:
[@smith2023].Recommended placement in arxiv-survey(-latex):
evidence-draft + anchor-sheet and before writer-context-pack + evidence-selfloop.outline/evidence_drafts.jsonl and outline/anchor_sheet.jsonl are schema-stable before drafting packs are built.outline/outline.yml is missing or cannot be parsed, the skill FAILs.uv run python .codex/skills/schema-normalizer/scripts/run.py --helpuv run python .codex/skills/schema-normalizer/scripts/run.py --workspace <workspace>--workspace <dir>--unit-id <U###>--inputs <semicolon-separated>--outputs <semicolon-separated>--checkpoint <C#>uv run python .codex/skills/schema-normalizer/scripts/run.py --workspace <workspace> --inputs outline/outline.yml;citations/ref.bib;outline/subsection_briefs.jsonl;outline/chapter_briefs.jsonl;outline/evidence_bindings.jsonl;outline/evidence_drafts.jsonl;outline/anchor_sheet.jsonl --outputs output/SCHEMA_NORMALIZATION_REPORT.mdwriter-context-pack):uv run python .codex/skills/schema-normalizer/scripts/run.py --workspace <workspace> --inputs outline/outline.yml;citations/ref.bib;outline/writer_context_packs.jsonl --outputs output/SCHEMA_NORMALIZATION_REPORT.md| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 2,856 | 4,855 | +70% | 1 | 1 | 0% | 334 | 1,242 | +272% | 0 | 0 | — |
case-02 | fail→fail | 4,560 | 5,171 | +13% | 1 | 1 | 0% | 155 | 1,254 | +709% | 0 | 0 | — |
case-03 | fail→fail | 13,311 | 5,215 | -61% | 1 | 1 | 0% | 2,488 | 1,210 | -51% | 0 | 0 | — |
case-04 | pass→pass | 4,096 | 2,162 | -47% | 1 | 1 | 0% | 724 | 1,358 | +88% | 0 | 0 | — |
case-05 | fail→fail | 8,089 | 2,364 | -71% | 1 | 1 | 0% | 1,536 | 1,403 | -9% | 0 | 0 | — |
case-06 | fail→fail | 6,871 | 2,179 | -68% | 1 | 1 | 0% | 1,320 | 1,385 | +5% | 0 | 0 | — |
case-07 | pass→pass | 6,719 | 2,435 | -64% | 1 | 1 | 0% | 1,274 | 1,273 | -0% | 0 | 0 | — |
case-08 | pass→pass | 13,407 | 3,846 | -71% | 1 | 1 | 0% | 2,085 | 1,527 | -27% | 0 | 0 | — |
case-09 | fail→pass | 8,584 | 3,429 | -60% | 1 | 1 | 0% | 1,521 | 1,399 | -8% | 0 | 0 | — |
case-10 | fail→pass | 18,982 | 1,950 | -90% | 1 | 1 | 0% | 1,072 | 1,214 | +13% | 0 | 0 | — |
case-11 | pass→pass | 7,206 | 2,514 | -65% | 1 | 1 | 0% | 1,121 | 1,310 | +17% | 0 | 0 | — |
case-12 | fail→pass | 7,892 | 2,538 | -68% | 1 | 1 | 0% | 1,448 | 1,403 | -3% | 0 | 0 | — |
case-13 | pass→pass | 13,702 | 2,780 | -80% | 1 | 1 | 0% | 1,945 | 1,517 | -22% | 0 | 0 | — |
case-14 | fail→fail | 14,752 | 1,984 | -87% | 1 | 1 | 0% | 2,231 | 1,218 | -45% | 0 | 0 | — |
case-15 | pass→pass | 12,198 | 3,398 | -72% | 1 | 1 | 0% | 1,881 | 1,597 | -15% | 0 | 0 | — |
case-16 | fail→pass | 5,930 | 2,189 | -63% | 1 | 1 | 0% | 913 | 1,250 | +37% | 0 | 0 | — |
case-17 | fail→fail | 9,662 | 1,808 | -81% | 1 | 1 | 0% | 1,319 | 1,166 | -12% | 0 | 0 | — |
case-18 | pass→pass | 12,656 | 4,478 | -65% | 1 | 1 | 0% | 1,821 | 1,539 | -15% | 0 | 0 | — |
case-19 | fail→pass | 12,630 | 2,033 | -84% | 1 | 1 | 0% | 2,125 | 1,277 | -40% | 0 | 0 | — |
case-20 | fail→fail | 2,248 | 5,166 | +130% | 1 | 1 | 0% | 198 | 1,130 | +471% | 0 | 0 | — |
case-21 | fail→fail | 3,540 | 8,485 | +140% | 1 | 1 | 0% | 372 | 1,148 | +209% | 0 | 0 | — |
case-22 | fail→fail | 15,673 | 17,056 | +9% | 1 | 1 | 0% | 2,473 | 3,610 | +46% | 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 16 counted toward the lift figure. The other 6 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 +23 percentage points is the difference between those two pass rates over the 16 comparable cases.
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.