Un Claude Skill qui prend un contrat exécuté unique — .docx ou .pdf avec couche texte — et émet un enregistrement JSON ancré sur des citations avec les clauses que votre CLM utilise réellement : droit applicable, plafond de responsabilité, indemnisation, durée, renouvellement automatique, déclencheurs de résiliation, conditions de paiement, propriété intellectuelle, durée de confidentialité, ainsi que les champs personnalisés que vous configurez (résidence des données, MFN, changement de contrôle, cession). Chaque valeur extraite porte un extrait verbatim, une citation {page, char_span}, et un score de confiance, afin que le réviseur en aval puisse vérifier en quelques secondes plutôt que de relire le contrat.
Cette page couvre quand l’exécuter, quand explicitement ne pas le faire, ce que cela coûte, et les modes d’échec nommés dont vous devez tenir compte avant de le pointer vers un référentiel de production.
Quand utiliser
Faites appel au skill lorsque vous avez un besoin de sortie structurée sur des contrats ayant déjà passé le filtre du secret professionnel :
Rétro-alimentation du CLM. Vous avez hérité d’un référentiel de fichiers plats (Box, SharePoint, lecteur réseau) et devez alimenter les champs de métadonnées d’Ironclad ou d’Agiloft sans mobiliser un trimestre de travail paralégal.
Construction d’une bibliothèque de clauses. Vous souhaitez disposer de toutes les clauses « plafond de responsabilité » du portefeuille afin que la bibliothèque de clauses reflète ce que vous avez réellement accepté, et non la position déclarée du playbook.
Due diligence. Vous avez 48 heures pour remonter les clauses de changement de contrôle, de cession, et de client le plus favorisé dans le parc de contrats d’une cible avant la clôture d’une transaction.
Triage des renouvellements. Vous devez signaler chaque contrat se renouvelant automatiquement dans les 90 prochains jours avec le champ nombre-de-jours-de-préavis renseigné.
Le bundle se trouve dans apps/web/public/artifacts/clause-extraction-claude-skill/ et contient :
SKILL.md — la définition du Skill avec méthode, format de sortie, et points de vigilance
references/1-clause-taxonomy.md — les clauses à extraire par type de contrat, avec en-têtes et synonymes
references/2-output-schema.json — le JSON Schema contre lequel chaque enregistrement est validé (versionner ce fichier)
references/3-citation-format.md — la grammaire des citations et les règles de repli « non présent » / « impossible à extraire »
Quand NE PAS utiliser
Le skill est délibérément étroit. Refusez l’invocation dans l’un de ces cas.
Brouillons privilégiés en négociation active. La politique IA de la plupart des équipes juridiques (et le modèle de politique IA que nous recommandons) trace une ligne ferme sur les brouillons de négociation en cours — en particulier les redlines de conseils externes et le produit du travail d’avocat. Ce skill est destiné aux contrats exécutés ou quasi-définitifs ayant déjà passé la question du secret. Si vous n’êtes pas certain qu’un document a passé ce filtre, la réponse est non.
Tout via des fournisseurs IA non-Tier-A. Exécutez uniquement contre l’endpoint Tier-A approuvé de votre cabinet (API Anthropic directe, ou votre tenant Claude entreprise). Jamais le chatbot grand public. Jamais un plugin navigateur. Jamais un wrapper SaaS non vérifié qui promet « Claude sous le capot ». Envoyer un contrat par un fournisseur Tier-B est un vecteur de fuite de secret professionnel — refusez l’invocation plutôt que de contourner la politique IA. Le Skill lui-même code en dur une liste d’endpoints autorisés ; si vous l’exécutez dans Claude Code ou Claude.ai avec votre tenant entreprise, vous êtes dans les règles.
Rédaction ou redlining. Ce skill est en lecture seule. Pour le redlining, utilisez le skill contract-redline séparé.
Interprétation juridique. La sortie est du texte + des citations. Si un plafond de responsabilité de 12 mois est « suffisant » étant donné le contexte de la transaction, c’est un jugement qui reste avec le conseil.
Configuration
Déposez le bundle dans ~/.claude/skills/ (Claude Code) ou téléversez le répertoire references/ et SKILL.md dans un projet Claude.ai.
Remplacez le contenu de references/1-clause-taxonomy.md par la taxonomie réelle de votre cabinet. La taxonomie par défaut contient les clauses MSA courantes ; la plupart des cabinets ajoutent 5 à 10 champs personnalisés (résidence des données par juridiction, carve-outs de changement de contrôle, durée de non-sollicitation, périmètre MFN).
Versionner references/2-output-schema.json. Incrémentez extractor_version dans le schéma et dans le Skill à chaque modification de taxonomie afin que les consommateurs en aval puissent détecter la dérive.
Exécutez sur un contrat connu — choisissez-en un dont vous disposez déjà des valeurs de clauses dans le CLM. Comparez le JSON extrait avec l’enregistrement CLM. Itérez sur les synonymes de taxonomie jusqu’à obtenir la correspondance.
Exécutez à grande échelle. Le Skill est par contrat ; orchestrez le traitement par lots dans n8n, une boucle shell, ou le hook d’intake de votre CLM.
Ce que le skill fait réellement
Quatre étapes, dans l’ordre.
Extraction de texte avec préservation de la mise en page..docx est analysé via le XML docx ; .pdf via pdfplumber afin que les numéros de page et les étendues de caractères par boîte de délimitation soient préservés. Si le PDF n’a pas de couche texte (image scannée), le Skill abandonne avec error: "ocr_required" plutôt que d’émettre du texte vide. Router les PDF scannés vers l’OCR est une préoccupation amont distincte ; ce Skill n’effectue pas d’OCR, car produire silencieusement une extraction « propre » vide à partir d’un scan est pire qu’échouer bruyamment.
Extraction ancrée sur des citations, une passe par clause. Pour chaque clause dans la taxonomie : trouver les paragraphes candidats par correspondance d’en-tête + synonyme, ne passer que ces candidats (pas l’intégralité du contrat) à Claude avec la définition de la clause, et exiger en retour la valeur, un extrait verbatim de ≤ 280 caractères, la citation {page, char_span}, et un score de confiance high | medium | low. Tout extrait non byte-identique à une sous-chaîne des paragraphes source est rejeté — c’est la garde contre les hallucinations, et elle est non négociable. Les prompts par clause (vs un méga-prompt unique) permettent de ne réessayer que les échecs, de plafonner les tokens d’entrée de chaque appel, et d’isoler l’hallucination à un seul champ plutôt qu’à l’ensemble de l’enregistrement.
Validation de schéma contre le output-schema.json versionné. Les erreurs de validation atterrissent dans le tableau errors de la sortie. Le Skill ne coerce pas silencieusement les types.
Repli « non présent ». Lorsqu’une clause n’est pas localisée, émettre value: null, status: "not_present", note: "Searched headings: [...]". Ne pas deviner. Les pipelines de rétro-alimentation CLM traitent null + status:not_present comme confirmé absent (classer le contrat sans ce champ) et null + status:error comme à-réexécuter (ne pas classer). Confondre les deux corrompt les données CLM au fil du temps.
Réalité des coûts
Au tarif 2026 de Claude — disons ~3 $ / M tokens en entrée et ~15 $ / M tokens en sortie pour le modèle économique utilisé dans le Skill — le coût est dominé par les tokens en entrée, et les tokens en entrée sont dominés par la longueur des paragraphes candidats (car le Skill n’envoie jamais le contrat complet, seulement les paragraphes correspondants par clause).
Estimations par contrat :
Contrat court (5 pages, ~3 000 tokens en entrée sur tous les appels par clause, ~500 tokens en sortie) : ~0,02 $ par contrat.
MSA standard (20 pages, ~12 000 tokens en entrée, ~1 000 tokens en sortie) : ~0,05 $ par contrat.
MSA enterprise long avec annexes (60 pages, ~35 000 tokens en entrée, ~2 000 tokens en sortie) : ~0,13 $ par contrat.
Pour une équipe legal-ops mid-market typique traitant ~200 contrats nouveaux et hérités par mois, cela représente 10 à 30 $ / mois en dépenses de tokens. Le coût est négligeable comparé à une heure de paralégal. Là où il cesse d’être négligeable, c’est le projet de due diligence portant sur 50 000 contrats — à 0,05 $ chacun, cela fait 2 500 $, ce qui reste bon marché, mais vaut la peine d’être budgété en amont plutôt que découvert sur le relevé de carte de crédit.
Le coût non-token : chaque extraction avec confidence: medium | low (et un échantillon de 10 % des high) nécessite une révision humaine. Prévoyez ~30 secondes par enregistrement en medium et ~2 minutes en low. Le Skill est plus rapide qu’un paralégal, pas gratuit.
Mesure de succès
Deux métriques à instrumenter dès le premier jour.
Précision d’extraction sur un ensemble étiqueté. Constituez un ensemble étalon de 50 contrats avec des extractions manuelles. Mesurez la précision et le rappel par clause. Objectif : ≥ 95 % de précision sur les clauses obligatoires (governing_law, liability_cap, term_length_months, auto_renewal). En dessous, les faux positifs empoisonnent le CLM et les réviseurs apprennent à ignorer le champ. Le rappel importe moins — not_present est une réponse load-bearing, et une clause manquée est routée vers la révision humaine de toute façon.
Temps par contrat, de bout en bout. Y compris la passe de révision humaine sur les enregistrements signalés. Objectif pour un MSA de 20 pages : moins de 4 minutes au total, contre 20 à 30 minutes pour une extraction manuelle complète. Si vous n’atteignez pas un facteur 5×, la file de révision humaine est trop agressive — resserrez les seuils de confiance.
Par rapport aux alternatives
vs extraction de clauses IA native d’Ironclad. L’extraction intégrée d’Ironclad est excellente si tous les contrats qui vous intéressent vivent dans Ironclad. Elle est limitée lorsque vous rétro-alimentez depuis l’extérieur d’Ironclad (le chemin d’import est maladroit) et lorsque vous souhaitez des clauses personnalisées au-delà de l’ensemble modélisé d’Ironclad. Ce Skill s’exécute sur n’importe quel fichier sur disque et utilise votre taxonomie. Si vous vivez entièrement dans Ironclad, utilisez leur extraction native ; si vous alimentez plusieurs destinations ou effectuez de la due diligence sur un référentiel non Ironclad, ce Skill est mieux adapté.
vs Kira Systems. Kira est le standard enterprise — haute précision, bibliothèque de modèles étendue, coûteux (six chiffres), cycle de vente long, nécessite des données d’entraînement par clause personnalisée. Si vous êtes un grand cabinet d’avocats faisant de la due diligence M&A à grande échelle, Kira justifie son prix. Si vous êtes une équipe legal-ops de 50 personnes rétro-alimentant quelques milliers de MSAs hérités, Kira est excessif et ce Skill est deux ordres de grandeur moins cher pour la précision dont vous avez besoin.
vs révision manuelle par paralégal. La comparaison honnête. Un paralégal extrayant 10 clauses d’un MSA de 20 pages prend 20 à 30 minutes et atteint ≥ 99 % de précision sur les clauses faciles (droit applicable, durée) et ~90 % sur les difficiles (structure du plafond de responsabilité, carve-outs d’indemnisation). Ce Skill le fait en moins d’une minute à ~0,05 $, atteint ~95 % sur les faciles et ~85 % sur les difficiles, et route le reste vers un humain via le flag de confiance. La bonne approche pour la plupart des équipes est hybride : le Skill sur chaque contrat, le paralégal sur les enregistrements signalés.
Points de vigilance
Fuite de secret professionnel via un fournisseur Tier-B. Router un document privilégié par un endpoint IA non approuvé peut lever le secret professionnel. Garde : le Skill vérifie une liste d’endpoints autorisés codée en dur (api.anthropic.com plus votre tenant entreprise) au démarrage et refuse de s’exécuter si l’endpoint configuré n’en fait pas partie. Documentez le responsable de la liste dans votre politique IA.
Lacunes textuelles induites par l’OCR sur les PDF scannés. Un PDF image scannée sans couche OCR extrait comme des pages vides ; sans garde, le Skill signalerait la plupart des clauses not_present et ressemblerait à une exécution propre. Garde : l’étape 1 détecte les pages avec moins de 50 caractères extraits et abandonne avec ocr_required plutôt que d’émettre un enregistrement trompeur. Routez le contrat via l’OCR en amont et ré-exécutez.
Clauses hallucinations. Les modèles inventeront volontiers une clause de « résiliation pour convenance » qui n’existe pas si on la leur demande. Garde : la vérification de sous-chaîne byte-identique de l’extrait à l’étape 2 — tout extrait non littéralement présent dans les paragraphes source est rejeté et la clause enregistre status: "error", error: "excerpt_not_grounded". Il n’existe pas de chemin d’hallucination haute confiance par construction.
Dérive de schéma entre les versions de contrat. Une mise à jour de taxonomie qui change liability_cap d’une chaîne à un objet {type, amount, period} casse silencieusement chaque consommateur en aval. Garde : versionner extractor_version dans references/2-output-schema.json et l’incrémenter à chaque modification de taxonomie ou de schéma. Les consommateurs en aval s’appuient sur la version, pas sur une hypothèse de stabilité.
Résolution des termes définis. « Comme indiqué dans l’Annexe A » retourne la référence, pas la valeur. Garde : le Skill détecte as set forth in / as defined in et émet confidence: medium avec note: "cross-reference, manual resolution required". La résolution automatique naïve est pire que le flag honnête.
Pas de conseil juridique. L’extraction est mécanique. Si un plafond de 12 mois est acceptable pour cette transaction, c’est un jugement qui reste avec le conseil.
Stack
Claude — orchestration d’extraction de texte, extraction de clauses ancrée sur des citations, validation de schéma
---
name: clause-extraction
description: Extract a fixed set of contract clauses from a single .pdf or .docx and emit citation-grounded JSON with page/span references. Use after intake to backfill CLM metadata, build a clause library, or surface change-of-control / liability terms during diligence.
---
# Clause extraction
## When to invoke
Invoke this skill per contract, after the document has been ingested and you need a structured clause record (governing law, liability cap, term, auto-renewal, indemnification, payment terms, IP ownership, confidentiality term, termination triggers, plus any custom clauses you configure).
Typical callers:
- CLM backfill — populating Ironclad / Agiloft / DealHub metadata for a legacy contract repository
- Diligence — surfacing change-of-control, assignment, MFN clauses on a target company's contract set before deal close
- Clause library — building a corpus of "what we actually agreed to" across a portfolio so the playbook reflects reality
Do NOT invoke this skill for:
- **Privileged drafts in active negotiation** — per AI policy in most legal teams, in-flight negotiation drafts (especially with outside counsel redlines) do not get sent to AI tooling. This skill is for executed or near-final contracts that have already cleared privilege.
- **Anything via non-Tier-A AI vendors.** Run only against the firm-approved Tier-A model endpoint (Anthropic API or your enterprise Claude tenant). A general-purpose chatbot, browser plugin, or unvetted SaaS wrapper is a privilege-leak vector — refuse the invocation rather than route around the AI policy.
- Drafting or redlining clauses (this skill reads only)
- Interpreting legal effect (the output is text + citation; legal judgment stays with counsel)
## Inputs
- Required: `contract_path` — absolute path to a `.pdf` or `.docx`. PDFs must be text-based or pre-OCR'd; scanned-image PDFs without an OCR layer are rejected at step 1.
- Required: `taxonomy` — path to `references/clause-taxonomy.md` (or a custom taxonomy keyed by contract type). Defines the clauses to look for and the expected value type (string, number, boolean, enum).
- Required: `output_schema` — path to `references/output-schema.json`. The JSON Schema the output must validate against. Schema drift across contract versions is the #1 source of downstream pipeline breakage; pinning the schema per run guards against it.
- Optional: `contract_type` — `msa | sow | nda | dpa | order_form`. Selects the clause subset from the taxonomy. Defaults to `msa`.
- Optional: `custom_clauses` — array of additional clause names to look for beyond the taxonomy defaults (e.g. `data_residency_clause`, `most_favored_customer_clause`).
## Reference files
Read these from `references/` before processing. They are templates — replace the placeholder content with your firm's real taxonomy and schema before running on production contracts.
- `references/clause-taxonomy.md` — clause definitions per contract type, with the value type, required/optional flag, and synonym phrases the extraction step matches against
- `references/output-schema.json` — the JSON Schema every emitted record must validate against
- `references/citation-format.md` — citation grammar (page + span anchor) and the rules for "not present" / "could not extract" fallbacks
## Method
Run these steps in order. Do not parallelize — later steps depend on the artifacts produced by earlier ones.
### 1. Text extraction with layout preservation
For `.docx`: parse via the docx XML and emit a flat text stream with paragraph indices and section headings preserved.
For `.pdf`: use a text-layer extractor (pdfplumber or pdfminer.six) that preserves page numbers and bounding-box character spans. If the PDF has no text layer (scanned image), abort with `error: "ocr_required"` rather than silently emitting empty text. Routing a scanned PDF to OCR is a separate upstream concern; this skill does not OCR.
The output of step 1 is a list of `{page, paragraph_index, char_span, text}` records. Every later citation references these coordinates.
### 2. Citation-grounded extraction (one pass per clause)
For each clause in the taxonomy:
1. Locate candidate paragraphs by heading match (e.g. "Governing Law", "Term") and synonym phrase match (e.g. "shall be governed by", "initial term of this Agreement").
2. Pass the candidate paragraphs (not the full contract) to Claude with the clause definition and ask for: the value, the verbatim source excerpt (≤ 280 chars), the `{page, char_span}` citation, and a `confidence` score (`high | medium | low`).
3. **Reject any extracted excerpt that is not byte-identical to a substring of the source paragraphs.** This is the hallucination guard — if the model returns text not actually in the contract, drop the extraction and record `value: null, error: "excerpt_not_grounded"`.
Why one pass per clause and not a single mega-prompt: per-clause prompts let you retry only the failures, cap each call's input tokens (cheaper, faster), and isolate hallucination failures to a single field instead of the whole record.
### 3. Schema validation
Validate the assembled record against `output-schema.json`. If validation fails, emit the validation error in the output's `errors` array. Do not silently coerce types.
### 4. "Not present" fallback
If a clause is not located in step 2 (no candidate paragraphs above confidence threshold), emit `value: null, status: "not_present", note: "Searched headings: [...]; no matching paragraphs found."` Do not guess. "Not present" is a load-bearing answer; CLM backfill pipelines treat `null + status:not_present` differently from `null + error:*`.
## Output format
Always emit a single JSON object per contract. Soft constraints below are enforced by `references/output-schema.json`.
```json
{
"contract_file": "vendor_msa_2026.pdf",
"contract_type": "msa",
"extracted_at": "2026-05-03T14:22:00Z",
"extractor_version": "clause-extraction@2026.05",
"clauses": {
"governing_law": {
"value": "Delaware",
"excerpt": "This Agreement shall be governed by and construed in accordance with the laws of the State of Delaware, without regard to its conflict of laws principles.",
"citation": { "page": 14, "char_span": [1820, 1980] },
"confidence": "high",
"status": "extracted"
},
"liability_cap": {
"value": "12 months fees",
"excerpt": "In no event shall either party's aggregate liability exceed the fees paid by Customer in the twelve (12) months preceding the event giving rise to the claim.",
"citation": { "page": 18, "char_span": [220, 410] },
"confidence": "high",
"status": "extracted"
},
"auto_renewal": {
"value": true,
"renewal_term_months": 12,
"notice_period_days": 90,
"excerpt": "This Agreement shall automatically renew for successive 12-month terms unless either party provides 90 days' written notice of non-renewal.",
"citation": { "page": 3, "char_span": [50, 230] },
"confidence": "high",
"status": "extracted"
},
"most_favored_customer_clause": {
"value": null,
"status": "not_present",
"note": "Searched headings: ['Most Favored', 'MFN', 'Pricing']; no matching paragraphs found."
}
},
"errors": []
}
```
## Watch-outs
- **Privilege leak via Tier-B vendor.** Routing a privileged or attorney-work-product document through a non-approved AI endpoint can waive privilege. Guard: hard-coded allowlist of model endpoints (`ALLOWED_ENDPOINTS = ["api.anthropic.com", "<your-enterprise-tenant>"]`) checked at skill startup. Refuse to run if the configured endpoint is not on the list. Document the allowlist owner in your AI policy.
- **OCR-induced text gaps on scanned PDFs.** If step 1 silently emits empty pages from a scanned image PDF, the skill will report many clauses as `not_present` and look like a clean extraction. Guard: step 1 detects pages with < 50 extracted characters and aborts with `ocr_required` rather than producing a misleading "clean" record.
- **Hallucinated clauses.** Models will helpfully invent a "termination for convenience" clause that doesn't exist if asked. Guard: byte-identical excerpt-substring check in step 2 — any excerpt not literally present in the source paragraphs is rejected. Pair with `confidence: low` flagging for human review on the rest.
- **Schema drift across contract versions.** A taxonomy update that changes `liability_cap` from a string to a structured `{type, amount, period}` silently breaks every downstream consumer. Guard: pin `extractor_version` in the output and bump it on every taxonomy or schema change. Downstream consumers key on version, not on the assumption that the schema is stable.
- **Defined-term resolution.** When a clause says "as set forth in Schedule A" the excerpt is the reference, not the value. Guard: detect the substring "as set forth in" / "as defined in" and emit `confidence: medium, note: "cross-reference, manual resolution required"` rather than treating the reference as the answer.
- **Heading-light contracts.** Contracts without clear section headings (older or short-form) extract less reliably. Guard: when fewer than 60% of expected headings match in step 2, mark the whole record `confidence: medium` and note `"heading_density: low"` so downstream QA routes it to human review.
# Clause taxonomy — TEMPLATE
> Replace this template's contents with your firm's actual clause taxonomy
> per contract type. The clause-extraction skill reads this file on every
> run; without your real taxonomy, extractions will use the generic defaults
> below and miss the clauses your CLM cares about.
The skill keys on `clause_id`. Every clause record in the output JSON uses the `clause_id` as the property name. Adding a clause means: add an entry here AND add the matching property to `output-schema.json`.
## Convention
For each clause:
- `clause_id` — snake_case identifier used as the JSON key
- `value_type` — `string | number | boolean | enum | structured`
- `required` — `true | false` (drives `not_present` vs hard error in validation)
- `headings` — list of section heading strings the locator matches against
- `synonyms` — list of phrase substrings the locator falls back to when no heading matches
- `value_hint` — what the extractor should pull (e.g. "the named jurisdiction state or country", "12-month-fees / 24-month-fees / unlimited / other")
## MSA defaults
### governing_law
- value_type: `string`
- required: true
- headings: `["Governing Law", "Choice of Law", "Applicable Law"]`
- synonyms: `["shall be governed by", "construed in accordance with the laws of"]`
- value_hint: the named jurisdiction (state, province, or country)
### liability_cap
- value_type: `structured` — `{ type: "fees_period" | "fixed_amount" | "unlimited" | "other", amount?: number, period_months?: number, currency?: string }`
- required: true
- headings: `["Limitation of Liability", "Liability Cap", "Cap on Liability"]`
- synonyms: `["aggregate liability shall not exceed", "in no event shall either party's liability exceed"]`
- value_hint: extract the cap amount or formula. Distinguish indirect-damages exclusions (do NOT extract those here) from the cap itself.
### indemnification
- value_type: `structured` — `{ ip_indemnity: boolean, mutual: boolean, carveouts: string[] }`
- required: true
- headings: `["Indemnification", "Indemnity"]`
- synonyms: `["shall defend, indemnify and hold harmless"]`
- value_hint: pull the IP indemnity boolean and the carveouts list (e.g. combinations, modifications, open source).
### term_length_months
- value_type: `number`
- required: true
- headings: `["Term", "Term and Termination"]`
- synonyms: `["initial term of this Agreement", "shall commence on the Effective Date"]`
- value_hint: convert years to months (3-year term → 36).
### auto_renewal
- value_type: `structured` — `{ enabled: boolean, renewal_term_months?: number, notice_period_days?: number }`
- required: true
- headings: `["Renewal", "Term and Termination"]`
- synonyms: `["shall automatically renew", "evergreen", "successive renewal terms"]`
### termination_triggers
- value_type: `structured` — `{ for_convenience: { allowed: boolean, notice_days?: number }, for_cause: { material_breach_cure_days?: number }, for_insolvency: boolean }`
- required: true
- headings: `["Termination"]`
- synonyms: `["may terminate this Agreement", "for material breach"]`
### payment_terms
- value_type: `structured` — `{ net_days: number, currency: string, late_fee_apr?: number }`
- required: true
- headings: `["Payment", "Fees and Payment", "Invoicing"]`
- synonyms: `["payable within", "net thirty (30) days"]`
### ip_ownership
- value_type: `enum` — `vendor | customer | joint | work_for_hire | other`
- required: true
- headings: `["Intellectual Property", "Ownership", "IP Rights"]`
- synonyms: `["all right, title and interest"]`
### confidentiality_term_months
- value_type: `number`
- required: true
- headings: `["Confidentiality", "Non-Disclosure"]`
- synonyms: `["confidentiality obligations shall survive", "for a period of"]`
- value_hint: convert years to months. If trade-secret carveout is "in perpetuity", emit `-1` and set `confidence: medium`.
## NDA defaults
(Replace with your NDA-specific taxonomy. Typical: `term_months`, `survival_period_months`, `permitted_purposes`, `residual_rights`, `return_or_destroy`.)
## DPA defaults
(Replace with your DPA-specific taxonomy. Typical: `data_residency`, `subprocessor_consent`, `audit_rights`, `breach_notification_hours`, `sccs_module_used`.)
## Custom clauses (firm-specific)
Add your firm-specific clauses here. Examples to consider:
- `change_of_control_clause` — boolean + carveouts
- `most_favored_customer_clause` — boolean + scope
- `data_residency_clause` — enum of jurisdictions
- `assignment_restriction` — enum: `no_restriction | consent_required | prohibited`
- `non_solicit_term_months` — number
## Last edited
{YYYY-MM-DD} — bump on every taxonomy change. The extractor records this date in `extractor_version` so downstream consumers can detect schema drift.
# Citation format — TEMPLATE
> The clause-extraction skill emits a citation on every extracted clause so
> the downstream reviewer can verify the extraction in seconds rather than
> re-reading the contract. Without a usable citation grammar, extractions
> are unfalsifiable — and unfalsifiable extractions become silent CLM data
> rot. This file pins the format and the fallback rules.
## Citation grammar
A citation is a structured object, not a string. The skill emits:
```json
{
"page": 14,
"char_span": [1820, 1980]
}
```
- `page` — 1-indexed page number in the source PDF, or paragraph cluster index for `.docx` (since `.docx` has no fixed pagination).
- `char_span` — `[start, end]` character offsets within the page's extracted text, where `start` is inclusive and `end` is exclusive.
The `excerpt` field on the clause record is the verbatim substring at that span. The skill enforces that `page_text[char_span[0]:char_span[1]] == excerpt`. If the assertion fails, the extraction is rejected and the clause is recorded with `status: "error", error: "excerpt_not_grounded"`.
## Why structured, not "p. 14, ¶ 3"
Free-text citations like "p. 14, paragraph 3" cannot be machine-verified. A reviewer cannot click them. A pipeline cannot diff them across re-runs. A regression test cannot assert "the citation moved by exactly N characters when we re-ran extraction after taxonomy v2." Structured citations make every extraction reproducible and reviewable.
## Reviewer UX expectations
Downstream tooling (CLM, review queue, audit log) is expected to render the citation as a deep link into the source PDF page with the excerpt highlighted. Without that affordance, reviewers fall back to ctrl-F on the excerpt — which works, but doubles review time.
Recommended renderer behavior:
- Display the excerpt with the citation page badge inline
- On click, open the source PDF at the cited page with the excerpt highlighted (PDF.js supports `#highlight=<text>`)
- Show `confidence` as a colored chip: high = green, medium = amber, low = red
## "Not present" — the load-bearing answer
When a clause is not located, the citation is omitted and `status: "not_present"` is set with a `note` field documenting the search:
```json
{
"value": null,
"status": "not_present",
"note": "Searched headings: ['Most Favored', 'MFN', 'Pricing']; searched synonyms: ['most favored', 'no less favorable']; no matching paragraphs found."
}
```
This is intentionally explicit. CLM backfill pipelines treat a `null` with `status: "not_present"` as confirmed-absent (file the contract without that field) and a `null` with `status: "error"` as needs-rerun (do not file). Conflating the two corrupts CLM data over time.
## Cross-reference handling
When the matched paragraph is a pointer ("as set forth in Schedule A"), the skill emits:
```json
{
"value": "see Schedule A",
"excerpt": "Liability shall be limited as set forth in Schedule A.",
"citation": { "page": 18, "char_span": [220, 274] },
"confidence": "medium",
"note": "cross-reference; manual resolution required"
}
```
Resolving cross-references is out of scope. The skill could chase the reference into Schedule A, but the failure modes (mis-numbered schedules, amendments overriding the schedule, partially-resolved chains) make naive resolution worse than an honest "needs human" flag.
## Confidence calibration
| Confidence | Meaning | Reviewer action |
|---|---|---|
| `high` | Heading match + synonym match + clean excerpt grounded in source | Spot-check 10% sample; trust the rest |
| `medium` | Synonym match without heading, OR cross-reference, OR low heading density on the contract overall | Review every record |
| `low` | Multiple candidate paragraphs and the model picked one with weak signal, OR excerpt is ≥ 200 chars | Review every record before filing |
The skill MUST NOT emit `high` for a record that did not pass the byte-identical excerpt check. There is no "high-confidence hallucination" case — by construction.
## Last edited
{YYYY-MM-DD}