Skip to content

Repository files navigation

JetRedline

Appellate judicial opinion and bench memo editor and proofreader. Produces a Word document (.docx) with tracked changes showing proposed edits, plus a separate analysis document with explanations. Applies Garner's Redbook, Bluebook citation format, and style preferences drawn from opinions issued by the North Dakota Supreme Court within the last ten years. Good practice to have standing instructions in your profile preferences that help ensure you get needed stress testing of arguments. One approach: "When I argue against a position that knowledgeable experts would defend, answer as a smart expert who would still argue back. Lead with the counterarguments rather than with the agreement. Give a detailed response/steelman of the strongest arguments against my position and don't needlessly soften or backtrack."

Not an Official Court Product

JetRedline is an independent, open-source project published by an individual in a personal capacity as legal-educational software, consistent with Rule 3.1 of the North Dakota Code of Judicial Conduct. It is not authorized, endorsed, or maintained by the North Dakota Supreme Court or the state court system, and is being developed without court staff, equipment, or resources. The embedded style preferences are personal preferences, not official court style. The tool edits documents you supply and runs locally; you are responsible for handling any confidential or draft material appropriately and for independently reviewing every proposed edit — especially citation and quotation checks — before adopting it. Its suggestions are machine-generated, are not authoritative, and are not legal advice.

Caution: Privacy Settings Before Use

Screenshot 2026-03-07 at 15 31 25

The editing pipeline runs seven passes:

  1. Jurisdictional check — verifies timeliness of appeal, procedural posture, and standard of review against the ND Rules of Appellate Procedure
  2. Style and grammar — applies Redbook rules and plain-language preferences; produces structured edit list
  3. Citation check — Bluebook format review (3A) and substantive verification of ND, federal, and state citations against local reference files and official sources (3B)
  4. Fact check — verifies factual claims against party briefs and record materials, with claim-to-record mapping
  5. Analytical rigor — internal consistency, standard-of-review consistency, readability metrics, and (for opinions) structural completeness
  6. Brief matching — confirms the opinion or memo addresses every argument raised by the parties
  7. Dissent/concurrence cross-check — checks fair characterization and responsiveness between majority and separate writings

Passes 1–7 run as parallel subagents where possible; each delegated pass reads its instructions from references/pass-instructions/ rather than having them relayed through the main context. A .docx draft's text is extracted deterministically by extract_text.py (paragraph numbering reconstructed, footnotes preserved, tracked changes resolved to the as-accepted view) — never transcribed by the model. After all passes complete, the pipeline collects results and produces up to two outputs: a tracked-changes .docx (Pass 2 edits become tracked insertions/deletions; other pass findings become document comments; apply_edits.py operates directly on the .docx ZIP archive with no unpack/pack pipeline) and a companion analysis document summarizing all findings. The analysis document is also saved as a markdown file in the working directory.

Analysis Document

The analysis document is written as markdown (<case>-ANALYSIS.md) and rendered to a single self-contained HTML page (<case>-ANALYSIS.html) beside it. The markdown is the record; the HTML is what you read.

The page is built for triage: a banner and a sidebar table of contents show how many rows each section flagged, status cells become badges (each with a glyph and its label, so the colors are not doing the work), and every substantial table gets a filter box and a Problems only toggle. It prints cleanly — use the browser's print-to-PDF for a chambers copy. Open it in any browser; nothing is fetched from the network.

One caution: a count of zero flagged rows is not a clean bill of health. Only columns with a recognized status vocabulary are counted, and findings also live in tables without one and in the narrative sections.

The analysis document includes the following sections (some vary by document type):

  • Case Highlight (opinions only) — case name, citation, disposition, and core holdings
  • Jurisdictional Notes — timeliness, procedural posture, and standard of review issues
  • Summary of Edits — overview of types and volume of changes
  • Fact Check — table of factual claims verified against record materials
  • Brief Matching — table showing whether each party argument is addressed
  • Internal Consistency — name, date, and terminology discrepancies across the document
  • Standard of Review Consistency — whether deference language matches stated standards
  • Readability Metrics — Flesch-Kincaid grade, sentence length, passive voice, and nominalization density by section
  • Substantive Concerns (opinions) — potential dicta, alternative rationales, ambiguity/vulnerability, logical issues, and dissent/concurrence cross-check
  • Memo Analysis (memos) — issue completeness, balance of presentation, recommendation assessment, analytical gaps, and standard of review application
  • Citation Verification — table with quote checks, substantive support assessments, and source links
  • Citation Format Issues — Bluebook corrections
  • Style Notes — significant style changes by category

Prerequisites

  • Claude Code (CLI) or Claude Desktop with Cowork
  • An Opus-class model (Opus, Fable, or Mythos). jetredline checks at startup and asks you to confirm before running on Sonnet or Haiku — those models miss materially more citation and record-fact errors on this workload, and the miss is silent. Switch with /model opus.
  • Python 3.10+
  • Node.js 18+ (for creating new .docx from scratch; not needed for tracked-changes editing)
  • uv (recommended) or pip

Windows additional requirements:

  • PowerShell 5.1+ (included with Windows 10/11)
  • Git Bash (recommended, included with Git for Windows)

Installation

JetRedline installs as a skill to ~/.claude/skills/jetredline/. Both Claude Code (CLI) and Claude Desktop with Cowork use the same skill directory, so any of the options below work for either.

Option A: From .zip

  1. Download and extract jetredline-skill.zip
  2. Run the installer:
    • macOS/Linux:
      bash install.sh
    • Windows (PowerShell):
      powershell -ExecutionPolicy Bypass -File install.ps1
    The installer will:
    • Copy skill files to ~/.claude/skills/jetredline/
    • Create a Python virtual environment with required packages
    • Run npm install for the docx Node.js package

Option B: From source

git clone https://github.com/jet52/jetredline.git
cd jetredline
make install

Option C: Manual

macOS/Linux:

mkdir -p ~/.claude/skills/jetredline
cp -a skills/jetredline/* ~/.claude/skills/jetredline/

cd ~/.claude/skills/jetredline
uv venv .venv
uv pip install -r requirements.txt --python .venv/bin/python
npm install

Windows (PowerShell):

New-Item -ItemType Directory -Force -Path "$HOME\.claude\skills\jetredline"
Copy-Item -Path "skills\jetredline\*" -Destination "$HOME\.claude\skills\jetredline" -Recurse -Force

Set-Location "$HOME\.claude\skills\jetredline"
uv venv .venv
uv pip install -r requirements.txt --python .venv\Scripts\python.exe
npm install

Claude Projects (web)

  1. Download jetredline-skill.zip from GitHub
  2. Open your Claude Project → Project Knowledge
  3. Upload jetredline-skill.zip
  4. Paste opinion text or upload .docx/.pdf files in conversation
  5. Use the same trigger phrases ("edit this opinion", "edit this bench memo", etc.)

Web mode limitations:

  • Produces markdown analysis only (no tracked-changes .docx)
  • All passes run inline — no subagent delegation (may hit context limits on very long opinions)
  • Citation verification uses web search instead of local opinion corpus (less reliable)
  • No PDF splitting for large record packets (upload individual documents)

Usage

Trigger phrases:

  • "Edit this opinion"
  • "Proofread this opinion"
  • "Review this draft opinion"
  • "Redline this opinion"
  • "Redline this draft"
  • "Redline this memo"
  • "Edit this draft order"

Provide a .docx draft opinion in the working directory. Optionally include .pdf briefs or record materials for fact-checking.

Your writing voice (optional)

By default, jetredline edits toward the style guide's general preferences (Redbook, Guberman, recent North Dakota Supreme Court opinions). If you keep a file describing your own writing voice, jetredline defers to it when editing your drafts, so the redline polishes your prose instead of nudging it toward someone else's.

Where jetredline looks (first match wins):

  1. my-writing-voice.md in the working directory (a per-case or per-project override)
  2. ~/.claude/my-writing-voice.md (your standing file)
  3. Claude Projects (web): a file named my-writing-voice.md in Project Knowledge

If none is found, nothing changes.

How it is applied. The voice file governs over jetredline's style preferences (sentence and paragraph length, transitions, word choices, register) wherever they conflict. It does not override the hard grammar rules or the citation rules. Patterns the file says to avoid are flagged as edits or comments. jetredline announces when it is using the file, applies it only to writing the file says it covers, and skips it when you say the draft is someone else's.

What the file may contain. Plain markdown; every section is optional. Useful sections:

  • Scope: what the file covers ("opinions and separate writings I sign; internal memos; articles"). jetredline respects this.
  • Calibration examples: citations or file paths for a few of your own pieces that best show your voice, with a note on what each illustrates. Real examples teach more than rules do.
  • Structure: how you open and close each kind of document (e.g., a one-line position at the start of a dissent; restating the disposition at the end).
  • Order of reasoning: the sequence you usually argue in (text, then history, then precedent, …), plus any method rules, such as how you choose dictionaries.
  • Voice: tone, how you express uncertainty, typical paragraph and sentence length, transitions you favor, preferred word choices ("here" not "in this case").
  • Register by genre: how opinions differ from memos, articles, or speeches.
  • Avoid: words, constructions, and habits that are not yours, stated concretely enough to find in a draft ("no sentence-initial However,"; "at most one or two em-dashes").

Keep it to one or two pages. Every rule competes for attention during an edit, and a short file of distinctive traits beats a long restatement of general style advice.

Suggestions for building one:

  1. Start from your own published writing, not your impressions of it. Gather 20 or more pieces you wrote yourself. Separate writings, articles, and speeches carry more of your voice than institutional documents shaped by house style and staff.
  2. Compare against a baseline. Your traits are what differs from peers writing in the same genre and period. A phrase you use often may just be house style. If you have a corpus, ask Claude to compare word and phrase frequencies between your writing and colleagues' writing, then read your pieces for structure and tone.
  3. Watch for drift. If recent drafts were produced with AI help, calibrate from earlier work and list any habits that crept in (em-dash density, "not X, but Y" reversals, punchy fragment pairs) under Avoid.
  4. Test it. Have Claude redline one of your older pieces with the file loaded. If the edits push your own prose away from how you wrote it, a rule is wrong or too broad.
  5. Keep it under version control and revise it as your preferences change.

Reviewing citations

The last step produces cite-review.html — a page that lists every citation in the draft and shows you the source next to it, so you can confirm each one against the official text or the scanned record yourself.

Opening it. Open the file from the case folder in Chrome or Edge. If the page arrived as a .zip, unzip it first and keep the _pdfs folder next to the HTML — the page needs it to show the record and the authorities.

Working through it.

Key Does
j / k Next / previous citation (arrow keys work too)
Space or Enter Mark verified and move to the next one
v Mark verified (without moving on)
f Flag it — something is wrong or needs a second look
s Skip it
h / l Switch the source pane between the local copy and the official source
n Type a note on this citation
a Stop (or resume) jumping to the next citation automatically
? Show all shortcuts

Most of a pass is Space when a citation checks out and f when it does not. Use h and l to put the official text or the scanned page in front of you before you decide.

Your marks are remembered in the browser as you go, so you can close the page and come back to it on the same computer.

Saving your review when you finish — this is the part that matters, because the marks only live in your browser until you do it:

  1. Click Save review. Your browser saves a file named cite-review-state__<case>__<date>.json.
  2. Put that file in the case folder — the same folder the review page came from. That is what makes your review available to everyone else and to the next run.

To make that one click instead of two, turn on Ask where to save each file once, in your browser settings under Downloads. Your browser will then ask where to put the file, and you can pick the case folder directly. It is a personal setting and needs no administrator rights. Without it, the file lands in your Downloads folder and you drag it into the case folder yourself.

If saving a file is awkward, click Copy instead and paste the review back into the chat — it can be filed for you from there.

Picking up where you left off. When the opinion is run again, the marks you saved come back automatically and you continue from where you stopped. If the draft was edited in between, citations that are no longer in it are reported and dropped rather than being matched to the wrong citation — so a mark never shows a citation as verified that nobody verified. The page tells you how many marks were restored when it opens.

A note on what "verified" means here. The tool finds the source and puts it in front of you; it does not decide whether the citation is right. A citation counts as verified when a person has looked at the official text or the scanned record and agrees. Text that has been through OCR or any automated extraction is there to help you find the right page — it is not the thing you are checking against.

File Structure

jetredline/
├── skills/
│   └── jetredline/
│       ├── SKILL.md
│       ├── VERSION
│       ├── package.json
│       ├── requirements.txt
│       ├── apply_edits.py          # Tracked-changes batch editor (direct ZIP)
│       ├── extract_text.py         # .docx → markdown extraction (direct ZIP)
│       ├── cite_check.py           # Citation checker (uses bundled jetcite)
│       ├── cite_review.py          # Interactive citation review HTML generator
│       ├── analysis_to_html.py     # Analysis report → readable, printable HTML
│       ├── parallel_check.py       # Parallel-cite consistency check (ndlaw / CourtListener)
│       ├── review_state.py         # Review marks round-trip: export → case folder → next run
│       ├── ndlaw_export.py         # ND opinion text/URL export from ndlaw corpus
│       ├── nd_rules_export.py      # Regenerates the appellate-rules reference from ndlaw
│       ├── lib/
│       │   └── jetcite/            # Vendored jetcite (run `make vendor-jetcite` to update)
│       ├── check_model.py          # Opus-class model gate (Step 0.0)
│       ├── check_update.py         # Version check on session start
│       ├── preflight.py            # Egress probe: names blocked hosts before any pass (Step 0)
│       ├── provenance.py           # Model/version/date stamp for analysis documents
│       ├── readability_metrics.py  # FK grade, passive voice, etc.
│       ├── textquality.py          # PDF text-layer triage: ok / image-only / corrupt (vendored)
│       ├── pdfsource.py           # Supplied-source PDFs: probe/locate/extract/compact
│       ├── authorities.py         # Pass 3D: inventory / candidates / match
│       ├── pdf_page_grep.py        # Find a string in a PDF, report its page
│       ├── splitmarks.py           # PDF bookmark splitter (bundled)
│       ├── ooxml_fixup.py          # OOXML debugging tool (not in main pipeline)
│       ├── ooxml_validate.py       # OOXML debugging tool (not in main pipeline)
│       └── references/
│           ├── nd-appellate-rules.md
│           ├── nd-citation-style.md
│           ├── style-guide.md
│           └── pass-instructions/  # Delegated-pass instructions read by subagents
│               ├── pass1-jurisdiction.md
│               ├── pass2-style.md
│               ├── pass3b-citations.md
│               ├── pass4-factcheck.md
│               ├── pass6-brief-matching.md
│               └── pass7-dissent-crosscheck.md
├── install.sh
├── install.ps1
├── LICENSE
├── Makefile
├── README.md
└── .gitignore

External Dependencies

Dependency Purpose Required?
Python 3.10+ PDF/XML processing Yes
Node.js 18+ New .docx creation from scratch Only if not editing existing
defusedxml Safe XML parsing Yes (installed by installer)
pypdf PDF manipulation Yes (installed by installer)
splitmarks PDF bookmark splitting Bundled script (no install)
textquality PDF text-layer triage Bundled script (no install)
textstat Readability metrics Yes (installed by installer)
jetcite Citation parsing and linking Bundled (vendored source)
docx (npm) New .docx creation from scratch Only if not editing existing

Network access in sandboxed environments

jetcite resolves and verifies citations against official-source domains (ndcourts.gov, courtlistener.com, etc.). Sandboxed Claude environments (Cowork, Claude Code) block outbound traffic to non-allowlisted hosts, which silently degrades ND opinion links to a search URL rather than the direct PDF. Add the domains listed in skills/jetredline/lib/jetcite/NETWORK.md to the egress allowlist (Cowork: sandbox settings → Allow network egress → Additional allowed domains; Claude Code: sandbox.network.allowedDomains), then start a new session. Also add ndlaw.org and *.ndlaw.org — two entries, since the wildcard does not cover the apex. The citation-review step pulls ND opinion text from the public ndlaw server at https://ndlaw.org/mcp; without it, that text has to be scribed through the model. Each run starts with preflight.py, which names any blocked host and the entry to add.

Contributing

On a fresh clone, activate the local pre-push sensitive-content check:

git config --local core.hooksPath .githooks

It scans commits being pushed for likely ND court dockets, confidential-case captions, and committed binaries. Bypass once with git push --no-verify.

About

A Claude skill for editing and cite checking bench memos and draft opinions. Checks citation format, validates quotes against official sources, numerous style and form checks. Best in Claude code.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages