legal-chronology
Legal chronology builder — turns case documents (contracts, correspondence, court filings, expert reports) into a sourced legal timeline. Every event carries mandatory provenance (document + locus), an undisputed/alleged/contested status with attribution, explicit date conflicts
Install
npx skills add https://github.com/fedec65/bettercallclaude/tree/main/bettercallclaude/skills/legal-chronology
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install fedec65-bettercallclaude@llmmart
git clone https://github.com/fedec65/bettercallclaude.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole fedec65/bettercallclaude collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Legal Chronology
You are the legal chronology method for BetterCallClaude. You turn the documents of a case into a legal timeline the way a lawyer actually reads a case: every event carries provenance, a contested/undisputed status, and feeds deadline computation.
The One Non-Negotiable Rule
No event without a source. Every event MUST cite its document and locus (page/paragraph/section). An event without provenance must never appear in any output — this is R1/R2 discipline applied to facts. The render script (scripts/timeline-render.mjs validate) rejects source-less events; do not try to work around that.
Event Model
Every event conforms to references/event-schema.md:
| Field | Rule |
|---|---|
date |
Normalised ISO YYYY-MM-DD. Partial dates ("March 2024") keep precision: month (or year); never invent a day. |
event |
One sentence, neutral factual wording — no argumentation, no evaluation. |
source |
Mandatory: {doc, locus} — document id + page/paragraph. Multiple sources allowed (multilingual duplicates). |
status |
undisputed | alleged (one party asserts, other silent) | contested (asserted and denied) — always with attribution ("Party A alleges delivery on 3.3.; Party B disputes"). |
parties |
Normalised names from the party register (references/party-register.md). |
conflicts |
If two documents date the same event differently, record BOTH dates with their sources and flag the discrepancy — never silently pick one. |
Procedure
Step 1: PARTY REGISTER
Build or load the party register (references/party-register.md): normalised name, aliases seen in documents, role (Kläger/Beklagte, venditore/acquirente, ...). All party references in events use the normalised name.
Step 2: EXTRACTION (delegated)
Per document, the chronology-builder agent extracts event candidates: structural read (document type, date of document, parties) → dated facts → event candidates conforming to the schema. Dates are normalised per references/date-normalization.md (DE/FR/IT/EN → ISO).
Step 3: RECONCILIATION
Merge candidates:
- Same event, multiple documents/languages → one event, multiple sources (e.g. DE contract + FR letter describing the same delivery).
- Same event, different dates → one event with
conflictslisting every dated variant + its source, flagged. - Status assignment:
undisputedwhen all sources agree and no party denies;allegedwhen asserted by one party, unaddressed by the other;contestedwhen asserted and denied — with attribution.
Step 4: GAPS AND DEADLINES
- Evidentiary gaps: any documented period of ≥ 30 days with no events is flagged as a gap (render script injects gap rows) — helps spot missing evidence.
- Deadlines (only when
--deadlines): map events to time limits perreferences/deadline-mapping.md:- Procedural (notification-type events: service of judgment, order, decision) →
legal-personacompute_deadlines(procedureType, notificationDate, canton, language). Produces a computed marker with holidays/judicial recess handling. Note the tool's scope: ZPO Art. 142-149, BGG Art. 46/100-101 only. - Substantive limitation (Verjährung/prescription) → the mapping table in
references/deadline-mapping.md(event date + statutory period). Mark every such marker as indicative — verify;compute_deadlinesdoes NOT cover Verjährung, and output must never imply it does.
- Procedural (notification-type events: service of judgment, order, decision) →
Step 5: RENDER
Events go to bcc-output/timeline/events.json, then render deterministically:
node "${CLAUDE_PLUGIN_ROOT}/scripts/timeline-render.mjs" validate bcc-output/timeline/events.json
node "${CLAUDE_PLUGIN_ROOT}/scripts/timeline-render.mjs" render bcc-output/timeline/events.json --outdir bcc-output/timeline --formats all
Outputs (per --format, default all):
timeline.md— chronological table: date | event | source | status | parties, plus conflict/gap/deadline sections.timeline.html— self-contained interactive view: colour-coded status, gap bands, deadline markers, click-through to source list.timeline.docx— case-file export: same table + conflict/gap/deadline summary.
Iterative Updates (--merge)
A chronology is a living case artifact. On re-run with --merge, load the existing events.json, reconcile new candidates against existing events (new → added; same key, different date → conflict added; same → source appended), re-render. Never silently drop existing events.
Reduced Mode
compute_deadlinesunavailable → skip procedural markers, note (termine procedurale non calcolato — tool non disponibile); Verjährung markers from the mapping table remain (indicative).- Illegible document (scan/OCR failure) → reported as unreadable in the inventory; never fabricate events to compensate.
Quality Rules
- Neutral wording: the timeline records facts, not arguments ("La lettera del 3.3.2024 segnala un difetto" — not "il convenuto ha fraudolentemente...").
- Dates always rendered in one normalised display format per output language; ISO in data.
- A deadline marker must anchor to a sourced event — no floating deadlines.
- Include the professional disclaimer: the chronology is a working aid; dates, statuses and deadlines must be verified against the case file. Deadline computations (including
compute_deadlinesoutput) are auxiliary, not legal advice.
Integration
- Invoked by
/legal-timeline(orchestration) and used as worker method in thetimeline-sourcedgoal-loop profile (evaluator:citation-specialist). - Receives: document inventory (+ optional party seed, date window, canton for deadlines).
- Returns:
events.json+ rendered outputs underbcc-output/timeline/.
Files (bettercallclaude)
-
references
-
date-normalization.md 2.7 KB
# Date Normalization — DE / FR / IT / EN → ISO Rules for normalising dates found in case documents to ISO `YYYY-MM-DD` with a precision level. Normalisation is deterministic: never guess missing components. ## Precision Levels | Input example | `date` | `precision` | Display (DE) | |---|---|---|---| | "3. März 2024" | `2024-03-03` | `day` | 3.3.2024 | | "März 2024" | `2024-03-01` | `month` | März 2024 | | "im Jahr 2024" | `2024-01-01` | `year` | 2024 | | undated fact | — | `unknown` | undatiert | The first-of-period date exists only for sorting; rendering MUST respect `precision` and never show a fake day ("1.3.2024" for a March-only source). ## Month Names | # | DE | FR | IT | EN | |---|---|---|---|---| | 01 | Januar, Jan. | janvier | gennaio | January | | 02 | Februar, Feb. | février | febbraio | February | | 03 | März | mars | marzo | March | | 04 | April | avril | aprile | April | | 05 | Mai | mai | maggio | May | | 06 | Juni | juin | giugno | June | | 07 | Juli | juillet | luglio | July | | 08 | August | août | agosto | August | | 09 | September | septembre | settembre | September | | 10 | Oktober | octobre | ottobre | October | | 11 | November | novembre | novembre | November | | 12 | Dezember | décembre | dicembre | December | ## Patterns - **DE**: `3. März 2024`, `3.3.2024`, `03.03.24` → day precision. Swiss numeric format is ALWAYS `day.month.year` — `3.4.2024` is 3 April, never 4 March. - **FR**: `le 3 mars 2024`, `3 mars 2024`, `03.03.2024`, `3/3/2024` → day precision (drop articles "le/du"). - **IT**: `3 marzo 2024`, `il 3 marzo 2024`, `3.3.2024` → day precision. - **EN**: `3 March 2024`, `March 3, 2024`, `3 March 2024 (sic)` → day precision. English numeric `03/04/2024` is ambiguous: default to Swiss convention (day first) and note the ambiguity in the event's `note`. - **Two-digit years**: `24` → 2024 when the document context is post-2000; if the case spans 1900s/2000s, resolve from context and flag low confidence. - **Relative dates** ("10 days after delivery", "innert 10 Tagen"): do NOT compute silently. Record the anchor event id in `note`; compute only if the anchor date is known, and mark `precision` of the anchor. - **Document date vs fact date**: a letter dated 5.4.2024 describing a delivery on 3.3.2024 yields TWO events (delivery 3.3; letter 5.4), each with its own source. - **Ranges** ("between March and April 2024"): store earliest as `date` with `precision: month` and record the range in `note`. ## Display Formats (render layer) | Language | Format | |---|---| | DE | `3.3.2024` | | FR | `3.3.2024` (or `3 mars 2024` in prose headers) | | IT | `3.3.2024` | | EN | `2024-03-03` | Data layer is always ISO; display conversion happens only at render. -
deadline-mapping.md 3.3 KB
# Deadline Mapping — Event Types → Time Limits Two distinct families. Keep them separate in output and never blur the distinction. ## A. Procedural Deadlines → `compute_deadlines` (MCP legal-persona) Scope of the tool: ZPO Art. 142-149 and BGG Art. 46, 100-101. Input: `procedureType`, `notificationDate` (ISO), `canton` (holiday calendar), `language`. Output includes holidays, judicial recess (Gerichtsferien) suspension, weekend adjustment. | Trigger event (examples) | `procedureType` | |---|---| | Service of first-instance judgment, appeal intended | `zpo_berufung_30` | | Service of decision/order, Beschwerde at cantonal level | `zpo_beschwerde_10` | | Order to file a statement (Stellungnahme) | `zpo_stellungnahme_20` | | Service of decision subject to Einsprache | `zpo_einsprache_10` | | Summary-procedure deadlines | `zpo_summarisch_10` / `zpo_summarisch_20` | | Service of cantonal final judgment, BGG appeal | `bgg_beschwerde_30` | | Constitutional complaint (subsidiäre Verfassungsbeschwerde) | `bgg_verfassungsbeschwerde_10` | Rules: - The anchoring event MUST be a sourced notification-type event ("notifica della sentenza del …", "Zustellung des Urteils vom …"). - `canton` comes from the case context (`--canton` or party register default); ask if unknown — the holiday calendar depends on it. - Marker label includes basis: `Berufung (ZPO 321: 30 Tage) — compute_deadlines`. - The tool's own disclaimer flows into output: auxiliary computation, not legal advice. - NOT covered by the tool (StPO, VwVG, other acts): mark `procedural (out of tool scope — manual computation needed)`; do not fabricate a computation. ## B. Substantive Limitation (Verjährung / prescription) → Mapping Table (INDICATIVE) `compute_deadlines` does NOT cover Verjährung. These markers are computed as `event date + period` and MUST be labelled **indicative — verify** (interruptions, waivers, and special rules can move the date). | Claim / event type | Period | Basis | |---|---|---| | General contractual claim | 10 years | Art. 127 OR | | Periodic payments (rent, interest), certain sales claims | 5 years | Art. 128 OR | | Tort / extra-contractual damages | 3 years (relative, from knowledge) / 10 years (absolute) | Art. 60 OR | | Unjust enrichment | 3 years (relative) / 10 years (absolute) | Art. 67 OR | | Defects liability, sale of goods (notice dependent) | 2 years | Art. 210 OR | | Warranty, immovable works (Bauwerk) | 5 years (defects noticed) | Art. 371 OR | | Employment claims (wages etc.) | 5 years (Art. 128 OR) / per contract | Art. 341 OR, Art. 128 Ziff. 1 OR | | Insurance claims | 5 years / 2 years (certain branches) | VVG | | Property gains tax assessment (cantonal) | per cantonal law | StG des Kantons | Rules: - Always show: anchor event, basis article, computed date, **indicative** flag. - Verjährung start can depend on knowledge (relative) — record what the anchor represents ("from knowledge of damage"). - If the case file suggests an interruption (acknowledgment of debt, payment, proceedings), note it — do NOT recompute silently. ## Output Marker Shape ```json { "kind": "procedural | verjaehrung", "label": "Berufung (ZPO 321: 30 Tage)", "due": "2024-04-29", "basis": "compute_deadlines | mapping-table (indicative)", "anchored_to": "evt-0007" } ``` No floating markers: every deadline anchors to a sourced event id. -
event-schema.md 3.5 KB
# Event Schema — legal-chronology Canonical JSON schema for timeline events. The renderer (`scripts/timeline-render.mjs validate`) enforces the mandatory parts. ## Schema ```json { "id": "evt-0001", "date": "2024-03-03", "precision": "day | month | year | unknown", "event": "One-sentence neutral factual description.", "source": [ {"doc": "01-vertrag", "locus": "p. 2, Ziff. 4.1"} ], "status": "undisputed | alleged | contested", "attribution": "Party A alleges X; Party B disputes / is silent. (required unless undisputed)", "parties": ["Muster AG", "Meier"], "conflicts": [ {"date": "2024-03-03", "source": {"doc": "01-vertrag", "locus": "Ziff. 4.1"}}, {"date": "2024-03-10", "source": {"doc": "02-brief", "locus": "p. 1, para. 2"}, "note": "delivery dated differently"} ], "deadline_markers": [ {"kind": "procedural | verjaehrung", "label": "Berufung (ZPO 30d)", "due": "2024-04-29", "basis": "compute_deadlines | mapping-table (indicative)", "anchored_to": "evt-0007"} ], "tags": ["contract", "delivery", "notification"] } ``` ## Field Rules - `id`: stable `evt-NNNN`, assigned at merge time; never reused after deletion. - `date`: ISO `YYYY-MM-DD`. For `precision: month` use the first of the month in `date` and keep `precision: month` (display renders "March 2024"). For `precision: year`, same with January 1. `precision: unknown` is allowed ONLY for candidates — the renderer excludes unknown-date events from the timeline body and lists them under "Undated sourced facts". - `event`: one sentence, neutral. No argumentation, no legal qualification ("allegedly" belongs in `attribution`, not in `event`). - `source`: **mandatory, non-empty**. Every entry: `doc` (document id from the inventory) + `locus` (page/paragraph/section as precise as the document allows). Multiple entries for multilingual/multi-document attestations of the same event. - `status`: - `undisputed` — all sources agree; no party denial on record. - `alleged` — one party asserts; the other is silent. `attribution` required. - `contested` — asserted and denied. `attribution` required ("A alleges …; B disputes …"). - `conflicts`: present when sources date the same event differently. Contains EVERY dated variant with its source. The `date` field holds the earliest variant for sorting; the conflict flag drives rendering of all variants. - `deadline_markers.kind`: `procedural` (compute_deadlines-backed) or `verjaehrung` (mapping-table, indicative). - `tags`: free-form, used for HTML filtering. ## Valid Example ```json { "id": "evt-0003", "date": "2024-03-03", "precision": "day", "event": "Lieferung der Maschine an das Werk des Käufers.", "source": [ {"doc": "01-vertrag", "locus": "Ziff. 4.1"}, {"doc": "02-brief", "locus": "p. 1, al. 2"} ], "status": "contested", "attribution": "Muster AG alleges delivery on 3.3.2024; Meier disputes proper delivery.", "parties": ["Muster AG", "Meier"], "conflicts": [ {"date": "2024-03-03", "source": {"doc": "01-vertrag", "locus": "Ziff. 4.1"}}, {"date": "2024-03-10", "source": {"doc": "02-brief", "locus": "p. 1, al. 2"}} ], "tags": ["delivery"] } ``` ## Invalid Example (rejected by validate) ```json { "id": "evt-0009", "date": "2024-05-01", "precision": "day", "event": "The defect was reported by phone.", "source": [], "status": "alleged", "parties": ["Meier"] } ``` Rejected: empty `source`. No event without provenance — ever. If a fact cannot be tied to a document locus, it does not enter the timeline. -
party-register.md 2.2 KB
# Party Register — Normalisation Rules The party register maps every name variant found in the documents to one normalised party. All events reference normalised names only. ## Register Shape ```json { "parties": [ { "name": "Muster AG", "aliases": ["Muster AG, Zürich", "la Muster AG", "die Beklagte", "Muster S.A.", "Muster"], "role": "Beklagte / défenderesse", "kind": "legal-entity" }, { "name": "Meier", "aliases": ["Herr Peter Meier", "M. Meier", "der Kläger", "il sig. Meier"], "role": "Kläger / demandeur", "kind": "natural-person" } ] } ``` ## Normalisation Rules 1. **Seed first**: `--parties=A,B,...` seeds the register before extraction; aliases accumulate as documents are read. 2. **Legal entities**: keep the legal form suffix and pick ONE canonical form — `Muster AG` (DE) / `Muster SA` (FR) / `Muster SA` (IT) normalise to the registered seat's form (commercial register form if known: usually the DE form for ZH-seat entities). Note the chosen form; do not mix forms in events. 3. **Natural persons**: `Family name` only in normalised form ("Meier"); full names ("Peter Meier") stay aliases. If two persons share a surname, normalise to "Meier P." / "Meier M." and flag the collision in the report. 4. **Procedural labels**: "Kläger/Beklagte", "demandeur/défenderesse", "attore/convenuto", "ricorrente" are aliases of the party they designate in that filing — resolve them to the normalised name and keep the label as alias. 5. **Third parties**: courts, experts, authorities, witnesses are NOT parties — record them under a separate `third_parties` list; they may appear in event text but not in `parties`. 6. **Unknown party**: if a document introduces a name that matches nothing, add a provisional entry flagged `provisional: true` and report it for user confirmation. 7. **Language variants**: normalise across languages ("die Muster AG", "la Muster SA", "la ditta Muster") to the one canonical name. ## Usage in Events - `parties` field: normalised names involved in the event. - `attribution` strings: normalised names ("Muster AG alleges …; Meier disputes …"). - Event text: normalised names; original wording stays in the source document, not in the event.
-
-
SKILL.md 6.6 KB
--- name: legal-chronology description: "Legal chronology builder — turns case documents (contracts, correspondence, court filings, expert reports) into a sourced legal timeline. Every event carries mandatory provenance (document + locus), an undisputed/alleged/contested status with attribution, explicit date conflicts (never silently resolved), evidentiary gaps, and optional deadline markers via legal-persona compute_deadlines. Trigger when: building a case chronology, Sachverhalt timeline, contested facts table, or Verjährung overview from documents. Do NOT trigger for: single-document analysis (swiss-document-analysis), citation formatting (swiss-citation-formats), or research without case documents (swiss-legal-research)." tools: - Read - Grep - Glob - Bash - WebSearch - WebFetch - mcp__plugin_bettercallclaude_legal-persona__compute_deadlines - mcp__legal-persona__compute_deadlines --- # Legal Chronology You are the legal chronology method for BetterCallClaude. You turn the documents of a case into a **legal timeline the way a lawyer actually reads a case**: every event carries provenance, a contested/undisputed status, and feeds deadline computation. ## The One Non-Negotiable Rule **No event without a source.** Every event MUST cite its document and locus (page/paragraph/section). An event without provenance must never appear in any output — this is R1/R2 discipline applied to facts. The render script (`scripts/timeline-render.mjs validate`) rejects source-less events; do not try to work around that. ## Event Model Every event conforms to `references/event-schema.md`: | Field | Rule | |---|---| | `date` | Normalised ISO `YYYY-MM-DD`. Partial dates ("March 2024") keep `precision: month` (or `year`); never invent a day. | | `event` | One sentence, neutral factual wording — no argumentation, no evaluation. | | `source` | **Mandatory**: `{doc, locus}` — document id + page/paragraph. Multiple sources allowed (multilingual duplicates). | | `status` | `undisputed` \| `alleged` (one party asserts, other silent) \| `contested` (asserted and denied) — always with `attribution` ("Party A alleges delivery on 3.3.; Party B disputes"). | | `parties` | Normalised names from the party register (`references/party-register.md`). | | `conflicts` | If two documents date the same event differently, record BOTH dates with their sources and flag the discrepancy — **never silently pick one**. | ## Procedure ### Step 1: PARTY REGISTER Build or load the party register (`references/party-register.md`): normalised name, aliases seen in documents, role (Kläger/Beklagte, venditore/acquirente, ...). All party references in events use the normalised name. ### Step 2: EXTRACTION (delegated) Per document, the `chronology-builder` agent extracts event candidates: structural read (document type, date of document, parties) → dated facts → event candidates conforming to the schema. Dates are normalised per `references/date-normalization.md` (DE/FR/IT/EN → ISO). ### Step 3: RECONCILIATION Merge candidates: - **Same event, multiple documents/languages** → one event, multiple sources (e.g. DE contract + FR letter describing the same delivery). - **Same event, different dates** → one event with `conflicts` listing every dated variant + its source, flagged. - **Status assignment**: `undisputed` when all sources agree and no party denies; `alleged` when asserted by one party, unaddressed by the other; `contested` when asserted and denied — with attribution. ### Step 4: GAPS AND DEADLINES - **Evidentiary gaps**: any documented period of ≥ 30 days with no events is flagged as a gap (render script injects gap rows) — helps spot missing evidence. - **Deadlines** (only when `--deadlines`): map events to time limits per `references/deadline-mapping.md`: - **Procedural** (notification-type events: service of judgment, order, decision) → `legal-persona` `compute_deadlines(procedureType, notificationDate, canton, language)`. Produces a computed marker with holidays/judicial recess handling. Note the tool's scope: ZPO Art. 142-149, BGG Art. 46/100-101 only. - **Substantive limitation (Verjährung/prescription)** → the mapping table in `references/deadline-mapping.md` (event date + statutory period). Mark every such marker as **indicative — verify**; `compute_deadlines` does NOT cover Verjährung, and output must never imply it does. ### Step 5: RENDER Events go to `bcc-output/timeline/events.json`, then render deterministically: ```bash node "${CLAUDE_PLUGIN_ROOT}/scripts/timeline-render.mjs" validate bcc-output/timeline/events.json node "${CLAUDE_PLUGIN_ROOT}/scripts/timeline-render.mjs" render bcc-output/timeline/events.json --outdir bcc-output/timeline --formats all ``` Outputs (per `--format`, default `all`): 1. `timeline.md` — chronological table: date | event | source | status | parties, plus conflict/gap/deadline sections. 2. `timeline.html` — self-contained interactive view: colour-coded status, gap bands, deadline markers, click-through to source list. 3. `timeline.docx` — case-file export: same table + conflict/gap/deadline summary. ## Iterative Updates (`--merge`) A chronology is a living case artifact. On re-run with `--merge`, load the existing `events.json`, reconcile new candidates against existing events (new → added; same key, different date → conflict added; same → source appended), re-render. Never silently drop existing events. ## Reduced Mode - `compute_deadlines` unavailable → skip procedural markers, note *(termine procedurale non calcolato — tool non disponibile)*; Verjährung markers from the mapping table remain (indicative). - Illegible document (scan/OCR failure) → reported as unreadable in the inventory; **never** fabricate events to compensate. ## Quality Rules - Neutral wording: the timeline records facts, not arguments ("La lettera del 3.3.2024 segnala un difetto" — not "il convenuto ha fraudolentemente..."). - Dates always rendered in one normalised display format per output language; ISO in data. - A deadline marker must anchor to a sourced event — no floating deadlines. - Include the professional disclaimer: the chronology is a working aid; dates, statuses and deadlines must be verified against the case file. Deadline computations (including `compute_deadlines` output) are auxiliary, not legal advice. ## Integration - Invoked by `/legal-timeline` (orchestration) and used as worker method in the `timeline-sourced` goal-loop profile (evaluator: `citation-specialist`). - Receives: document inventory (+ optional party seed, date window, canton for deadlines). - Returns: `events.json` + rendered outputs under `bcc-output/timeline/`.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.