diff --git a/SKILL.md b/SKILL.md index c978264..74e362a 100644 --- a/SKILL.md +++ b/SKILL.md @@ -110,6 +110,40 @@ recorded run instead of re-billing under the new organization. selection crops in one call and returns `crops[]`; never loop `find` into `crop` yourself. +## No schema yet? Invoke the build-schema skill + +The loop assumes a JSON Schema exists; authoring one is its own +discipline. When the user needs a schema authored, improved, or +validated, do not hand-write one and eyeball the output — invoke the +**build-schema skill** (the `landingai-ade` plugin of +[landing-ai/claude-skills](https://github.com/landing-ai/claude-skills)) +and let it run its loop. If the plugin is not installed, use a local +copy of the skill if one exists; otherwise shallow-clone that repo and +follow `plugins/landingai-ade/skills/build-schema/SKILL.md`. + +The skill drives this same CLI through measured iteration: it +negotiates per-field accuracy targets with the user, validates every +schema version with a real extraction run, scores against +reviewer-confirmed ground truth, and stops only converged with numbers +or blocked with evidence. It delivers the final schema at +`/deliverable/schema.json` — hand that straight to step 3: + +```sh +ade extract JOB_ITEM_ID --schema WORKSPACE/deliverable/schema.json --json +``` + +Two things to surface before starting a run: + +- **It bills per iteration, not once.** Every schema version is + validated by a real extraction, so a converging loop costs roughly + one extraction per document per iteration. The final extract above + is normally a free cache hit — the skill's last iteration already + ran it. +- **Seed it with what the store already holds.** Pass along the + `job_item_id` of any parse you already ran (and its environment) — + re-runs are free, so the skill authors from the cached parse instead + of re-billing one. + ## Reuse posture — parse bills once Every parse the CLI ever runs is a reusable job item. Given a document diff --git a/docs/adr/0010-schema-authoring-stays-in-the-skill-layer.md b/docs/adr/0010-schema-authoring-stays-in-the-skill-layer.md new file mode 100644 index 0000000..a4bb004 --- /dev/null +++ b/docs/adr/0010-schema-authoring-stays-in-the-skill-layer.md @@ -0,0 +1,58 @@ +# The schema gap is bridged in the skill layer, not in the CLI + +## Context + +The workflow is parse → schema → extract, and the middle step is the +user's: author a JSON Schema, then pass it to `extract --schema`. +Hand-authoring means guessing field names, running an extraction, +eyeballing the output, and repeating — with no measurement of whether it +got better. The build-schema skill (the `landingai-ade` plugin of +[landing-ai/claude-skills](https://github.com/landing-ai/claude-skills), +mirrored from `schema-loop` where it is benchmark-gated) already does +this properly: an AI-agent session drives this very CLI through measured +iteration — real extractions, reviewer-confirmed ground truth, +negotiated per-field accuracy targets — and delivers the final schema at +`/deliverable/schema.json`. The two just didn't know about +each other. + +A CLI-side bridge was designed and prototyped (a `schema build` command +plus a post-parse offer that launches an agent CLI as a foreground +subprocess). It was rejected: it grows the command surface, adds agent +adapters, config keys, and terminal-gating logic to a CLI whose posture +is deterministic plumbing, and it duplicates a doorway that the primary +callers — agents — never take, since an agent must not be handed an +interactive subprocess. + +## Decision + +The bridge lives in the skill layer. The root SKILL.md — the agent +contract shipped with this repo — teaches the integration: when the +user needs a schema authored, improved, or validated, the agent driving +this CLI invokes the **build-schema skill** directly (installing or +cloning it if absent), then feeds the delivered +`deliverable/schema.json` to `ade extract`. + +The CLI itself is unchanged: no new commands, no menus, no config keys, +no subprocess launching, no agent detection. `parse`, `extract`, and the +whole machine contract stay byte-identical. + +SKILL.md also carries the cost disclosure the agent must surface before +starting a run: the skill validates every schema version with a real +extraction, so a converging loop bills roughly one extraction per +document per iteration — and the final extract is normally a free cache +hit, because the loop's last iteration already ran it. + +## Consequences + +- Agents get the integration everywhere the skill travels, with zero + new CLI surface to gate, test, or keep out of scripts and CI. +- ade never fetches, pins, or updates the build-schema skill — no new + network surface, no version coupling. Skill acquisition is the + agent's job, as SKILL.md instructs. +- Humans without an agent session keep the status quo: hand-author a + schema or start an agent session themselves. If a human-facing + doorway is ever wanted, it is a separate decision that must revisit + the rejection above. +- The deliverable contract (`deliverable/schema.json`) is the one seam + this repo trusts from the skill; if the skill's output layout ever + changes, SKILL.md is the single place to follow it. diff --git a/tests/test_help.py b/tests/test_help.py index 0881a23..143e341 100644 --- a/tests/test_help.py +++ b/tests/test_help.py @@ -311,3 +311,14 @@ def test_skill_teaches_pending_resume_and_json(): assert "Always pass `--json`" in SKILL assert "same command" in SKILL # the resume gesture assert '"status": "pending"' in SKILL + + +def test_skill_hands_schema_authoring_to_the_build_schema_skill(): + """ADR-0010: the schema gap is bridged in the skill layer — SKILL.md + routes schema authoring to the build-schema skill, names the one + trusted seam (the deliverable path), and carries the cost + disclosure an agent must surface before starting a run.""" + assert "build-schema skill" in SKILL + assert "landing-ai/claude-skills" in SKILL + assert "deliverable/schema.json" in SKILL + assert "bills per iteration" in SKILL