Real Word Redlines, Not a Diff View

Native OOXML tracked changes a lawyer can Accept or Reject in Word, plus the grounding and sign-off gates behind them.

Most legal-AI tools will show you a redline. Colored text on a web page: red strikethrough for what came out, green underline for what went in. It looks like a redline, and for a demo that is enough. Then the lawyer asks the only question that matters. "Can I send this to the other side and have them accept and reject my changes in Word?" For a colored diff on a web page, the answer is no. That is not a redline a lawyer can work with. It is a picture of one.

This post is about the difference between the picture and the real thing, and why we went to the trouble of generating the real thing. There are two small markup snippets, simplified for readability, because the interesting part here is a public document standard you can inspect rather than a claim you have to trust.

Here is the whole path a proposed edit travels before it becomes a real revision in a file you can send.

Loading diagram...

The grounding check and the sign-off gate on the left run inside the review pipeline before the export ever sees an edit; the positioning and emit steps on the right are the export itself. The rest of this post walks the parts of that path where the picture and the real thing diverge.

What a real redline actually is

When a lawyer marks up a contract in Microsoft Word with Track Changes on, Word does not just color the text. It records each edit as a first-class object inside the .docx file. The .docx format is OOXML, an open, published standard, and inside it every insertion is wrapped in a <w:ins> element and every deletion in a <w:del> element. Each of those carries an author, a date, and a revision id. That is what makes the edit a revision rather than a font choice.

Because the edit is a revision, Word can do things a colored diff can never do. The recipient opens the Review tab and clicks Accept, and the inserted text becomes ordinary body text with the revision gone. They click Reject, and the deleted text comes back. They can step through the changes one at a time, accept some, reject others, and turn the whole thing back into a clean document. None of that is possible if "the redline" is really just red and green formatting. With formatting, Accept does nothing, because there is nothing structured for Word to accept. The color is the change, and the color stays.

So when we export a corrected contract, the edits are native OOXML revisions, not colored text. A tiny, simplified fragment of what we write into the document looks like this:

<!-- simplified OOXML: one insertion, one deletion -->
<w:ins w:id="7" w:author="Vaquill AI Contract Review" w:date="2026-01-15T10:00:00Z">
  <w:r><w:t xml:space="preserve">thirty (30) days</w:t></w:r>
</w:ins>
<w:del w:id="8" w:author="Vaquill AI Contract Review" w:date="2026-01-15T10:00:00Z">
  <w:r><w:delText xml:space="preserve">ninety (90) days</w:delText></w:r>
</w:del>

In plain English: "thirty (30) days" is being proposed as an insertion, and "ninety (90) days" is being struck as a deletion, and each is stamped with who proposed it and when. When the counterparty's lawyer opens this file, those two edits show up in the Review pane as real changes they can accept or reject individually.

The one detail that makes Word ignore a deletion

There is a subtlety in that fragment that is easy to get wrong and costs you the whole feature when you do.

A deleted run cannot hold its text in the usual <w:t> element. It has to hold it in a <w:delText> element instead. If you wrap a normal run in <w:del> but leave the text in <w:t>, Word silently drops the deletion. The change simply does not appear, and you do not get an error telling you why.

So our tracked-run builder does two things for every edit. It wraps the run in <w:ins> or <w:del>, and for a deletion it rewrites the run's text element from <w:t> to <w:delText> before saving. Simplified, that is the core of it:

# simplified: wrap a run as a native Word revision
wrapper = make_element("w:ins" if kind == "insertion" else "w:del")
wrapper.set("w:id", rev_id)
wrapper.set("w:author", "Vaquill AI Contract Review")
wrapper.set("w:date", date_iso)
run_element.wrap_in(wrapper)
if kind == "deletion":
    for t in run_element.find("w:t"):
        t.tag = "w:delText"   # a deleted run MUST carry delText, or Word ignores it

That last line is the difference between a deletion the lawyer can reject and a deletion that never shows up. It is the kind of detail that does not exist in a colored-diff implementation, because a colored diff never has to satisfy Word's schema. It only has to satisfy a browser.

Comments, in the margin, where lawyers expect them

A redline is only half of how lawyers negotiate. The other half is the margin comment: "we moved this to 30 days to match the MSA," or "this indemnity is one-sided, pushing back." Those are not edits to the contract text. They are notes attached to a span of it.

OOXML handles comments as a separate part of the .docx package, a file called word/comments.xml, related back to the document. Each comment is anchored to a run of text by a matching id, using a start marker, an end marker, and a reference. We generate that part directly. When an accepted edit carries a negotiation note, we attach it as a native Word comment anchored to the inserted text, so it renders in the margin exactly like a comment a human typed. Word shows it in the review margin, and Google Docs, which imports .docx comments, shows it too. The rationale for a change travels with the change, in the place a lawyer already looks for it.

Keeping the negotiation redlined end to end

There is one more flag that matters more than it looks. In the document's settings we turn Track Changes on for the whole file. That is a single element, <w:trackChanges/>, and it changes how the file behaves after it leaves us.

When the counterparty opens the document and starts editing, their own changes are captured as revisions too, because tracking is already on. The negotiation stays redlined end to end. This is exactly how a Word-native review workflow runs in practice: a .docx goes back and forth, each side's edits stacked as tracked changes, until someone accepts the final set. A colored-diff export breaks that loop on the first pass, because there is nothing to round-trip. A real tracked-changes .docx drops into the loop and stays in it.

Placing the edits without garbling the document

Turning a set of proposed edits into revisions inside the original text is a positioning problem, and positioning problems are where these features quietly corrupt documents.

Each accepted redline names the current language it is replacing. We find that language in the contract by exact match first, then fall back to a whitespace-normalized match for edits whose spacing drifted. Two edits whose spans overlap cannot both be applied, so we track accepted intervals and skip any later edit that intersects one already placed. That guard exists because the earlier, start-position-only version let overlapping edits through, and the document then emitted the overlap region twice: a garbled file. We apply the replacements in reverse order so earlier edits do not shift the positions of later ones.

Two cases fall outside "replace this span." A clause the playbook wanted but the contract never had is not a replacement at all, so it goes into a "Recommended New Clauses" section rather than being force-fit into the body. An accepted edit whose current language we cannot locate in the text goes into an appendix, labeled for manual application, instead of being silently dropped. The lawyer sees every accepted change somewhere, either as a revision in place or as a flagged item to handle by hand.

Where an edit is a small change inside a sentence, we render it as a word-level diff: only the changed words are struck and inserted, and the shared words stay as plain text. That is the surgical redline a lawyer expects, not a whole paragraph deleted and retyped to change two words. The inline path is chosen deterministically, not always: it is used only for a single-line edit that still shares words with the original, and it deliberately falls back to a whole-block deletion-then-insertion for multi-line spans, for replacement text carrying markdown the inline renderer cannot style, and for a full rewrite with no words in common, where a token diff would be all-or-nothing anyway. The comment ids that anchor a margin note are reserved per insertion and consumed on the first inserted run, so a note attaches to exactly one span rather than smearing across the edit. The whole file is assembled in memory and never written to disk.

What has to be true before an edit becomes acceptable

Native revisions raise the stakes on correctness. A colored diff that misquotes the contract is a bad screenshot. A tracked change that misquotes the contract is a change the lawyer might accept into the actual document. So before a proposed edit reaches the export, the review pipeline grounds it.

Every redline the model proposes names the "current language" it claims to be editing. We check that this current language is a literal span of the contract, using a deterministic substring match after normalizing smart quotes, whitespace, and unicode compatibility forms so a genuine quote is not failed on a curly apostrophe. If the quote is found, the redline is tagged verified. If it is not found, it is tagged unverified, and the interface warns that the quoted language is not in the contract and should be checked before relying on it. This is non-destructive: nothing is silently deleted, and the lawyer stays in control of what gets accepted. The reason this matters is specific. A fabricated "current language" cannot be anchored to any real span, so an ungrounded edit is the one most likely to attach itself to the wrong place, and it is the failure mode worth catching before the edit ever becomes a revision.

Separately, the review pipeline runs a deterministic sign-off gate, never a model call. Each deviation is matched to its playbook position, which carries a required approval level and a deal-breaker flag, and conditions can raise that level based on deal value, whose paper the contract is on, the governing law, or the severity of the deviation. The levels are a single ranked ladder, none below manager below partner below GC, so aggregation is just taking the maximum rank across every gating clause, and a declared deal-breaker carries a hard floor of partner even when the position named no explicit level. The pipeline then aggregates a review-level gate with a plain-language summary, for example "Requires partner sign-off before sending: 3 clauses deviate from your playbook, including 1 deal-breaker." The point is that a deal-breaker edit does not quietly ride out to the counterparty without the sign-off your own playbook says it needs.

Test it yourself in about two minutes

You do not need our code to tell a real redline from a picture of one. You need Word and one click.

Take any redline a legal-AI tool produces, however it presents it, and get it into a .docx file. Open that file in Microsoft Word. Go to the Review tab and look at the changes. Now click on a single insertion and press Accept, then click a deletion and press Reject.

A real tracked change behaves natively. Accept an insertion and the new text becomes ordinary body text with the revision gone from the Review pane. Reject a deletion and the original wording comes back. You can walk the whole document change by change and end with a clean file.

A fake one does not. If "the redline" was really colored text, Accept and Reject do nothing, because there is no revision for Word to act on. The red and the green just sit there as formatting, and the lawyer is left to retype the change by hand. That is the whole test, and it is the whole difference. The output either drops into the way lawyers already negotiate in Word, or it makes them do the work the tool claimed to do.

New legal AI guides, weekly.

Priyansh Khodiyar

Priyansh Khodiyar

Co-Founder & CTO

Priyansh leads engineering and AI at Vaquill, from the matter workbench to drafting, document comparison, document matrix, and citation-verified research.

Research, review, and draft, with a source on every answer.

Vaquill AI reads your documents and knows the law. Every answer shows where it came from. 7-day free trial.