Verified SOP & TutorialAudited Score 98/100

The Complete Production SOP: How to Deploy and Run python-docx Legal Contract Builder in Autonomous AI Agents

Step-by-step SOP to install and run python-docx Legal Contract Builder in Codex, Claude Code, and Cursor. Includes verified prompts, sandbox rules, and fixes.

Target Runtimes:codexclaude-codecursorwindsurf
5 min read • Updated for 2026

Technical Overview & Architectural Context

Autonomous coding agents frequently corrupt Word documents (.docx) when generating legal agreements due to XML run fragmentation. When an agent attempts a naive string replacement across a document, Word's underlying OpenXML schema often splits single variable tokens (such as '{{CLIENT_NAME}}') across multiple contiguous text runs (`<w:r>`), resulting in silent replacement failures where unrendered bracket fragments leak into final production contracts. Furthermore, default paragraph generation strips institutional document hierarchies, producing malformed bullet lists, inconsistent cell padding, and broken tabular borders. The python-docx Legal Contract Builder skill enforces deterministic OpenXML manipulation boundaries. By mandating template inheritance via pre-styled document prototypes, isolating run-level string traversals, and enforcing strict table XML schema attributes (such as `w:tcBorders` and `w:cantSplit`), the skill prevents agents from hallucinating broken style names or destroying paragraph structures. Autonomous agents guided by this SOP validate XML integrity, handle cell-level text wrapping deterministically, and preserve exact corporate typography across every legal clause.

Prerequisites & Environment Requirements

Codex Desktop, Claude Code CLI, Cursor, or Windsurf installed with active workspace access
Python 3.10+ installed within local execution sandbox or virtualenv
python-docx >= 1.1.0 installed in the environment (`pip install python-docx`)
Git 2.40+ initialized with write permissions to the project repository

Verified Search Intents & Long-Tail Queries Solved

SEO Audit Score: 98/100

This operational tutorial is engineered to provide deterministic solutions for these developer search queries:

#install python-docx-contract-builder in cursor ide#claude code python-docx-contract-builder rules#codex desktop python-docx-contract-builder setup tutorial#replace variables in docx template python-docx agent#style table in python-docx automated legal contract#how to fix python-docx-contract-builder agent execution error#deterministic documents agent SOP#python-docx-contract-builder sandbox permissions and security score#python-docx-contract-builder prompt examples and triggers

Step-by-Step Execution Playbook

1

Local Environment Setup & SKILL.md Mounting

Create the local skill manifest directory and inject verified procedural rules into the agent runtime path.

Autonomous coding agents like Claude Code, Cursor, and Codex look for skill definitions within the `.agents/skills` or `.cursor/rules` workspace directories. Mounting the `SKILL.md` file allows the model's semantic parser to register the triggers (`generate word contract python`, `replace variables in docx template`, `style table in python-docx`) and respect file system boundaries before executing file-generation workflows.

Terminal Command
mkdir -p .agents/skills/python-docx-contract-builder && curl -fsSL https://askills.dev/api/skills/python-docx-contract-builder/raw -o .agents/skills/python-docx-contract-builder/SKILL.md
.agents/skills/python-docx-contract-builder/SKILL.md
---
name: "python-docx-contract-builder"
description: "Generate and populate professional Word contracts and agreements with python-docx."
metadata:
  author: "python-openxml"
  version: "1.0.0"
  runtime_compatibility:
    - "codex"
    - "claude-code"
    - "cursor"
    - "windsurf"
triggers:
  - "generate word contract python"
  - "replace variables in docx template"
  - "style table in python-docx"
permissions:
  fs_read: true
  fs_write: "workspace"
  shell_exec: false
  net_access: false
---

# python-docx Legal Contract Builder Rules
1. Always initialize documents using an existing template `doc = Document('templates/master_contract.docx')` to preserve OpenXML style schemas.
2. When performing placeholder replacement, join paragraph runs before inspection to prevent split-run token dropouts.
3. Format financial and indemnification tables with explicit column widths on each cell, setting `cantSplit` on table rows.
4. Save files to the target workspace path and verify generated binary headers.
Production Pro-Tip

Place boilerplate template files (`.docx`) in an explicit `/templates` directory and add them to `.agentignore` binary inspection lists to prevent your agent from attempting to parse raw zip archives into its context window.

Sandbox Gotcha

Do not grant `shell_exec: true` unless generating document previews via headless LibreOffice. The core python-docx skill requires only filesystem read and workspace-scoped write access.

2

Environment Dependency Validation & Helper Module Registration

Install python-docx dependencies and expose the deterministic placeholder reconciliation helper.

Because python-docx cannot natively replace text spanning multiple `<w:r>` runs without corrupting formatting, agents must use a standardized multi-run traversal routine. This step ensures python-docx is properly installed and creates an OpenXML utility module that handles contiguous runs safely.

Terminal Command
python -m venv .venv && source .venv/bin/activate && pip install python-docx>=1.1.0 lxml
scripts/docx_contract_utils.py
from docx import Document

def replace_placeholders_in_paragraph(paragraph, replacements: dict[str, str]) -> None:
    full_text = "".join(run.text for run in paragraph.runs)
    for placeholder, value in replacements.items():
        if placeholder in full_text:
            full_text = full_text.replace(placeholder, value)
            # Consolidate text into the first run and clear subsequent runs to preserve style
            if paragraph.runs:
                paragraph.runs[0].text = full_text
                for run in paragraph.runs[1:]:
                    run.text = ""

def replace_in_document(doc: Document, replacements: dict[str, str]) -> None:
    for p in doc.paragraphs:
        replace_placeholders_in_paragraph(p, replacements)
    for table in doc.tables:
        for row in table.rows:
            for cell in row.cells:
                for p in cell.paragraphs:
                    replace_placeholders_in_paragraph(p, replacements)
Production Pro-Tip

Consolidating replaced text into the first run while clearing downstream runs avoids breaking paragraph run collections and maintains base inline typography such as bolding and italics.

Sandbox Gotcha

Avoid iterating directly over `doc.inline_shapes` during replacement loops; inline drawings and shapes contain nested text frames that throw `KeyError` if accessed as normal paragraphs.

3

Intent Matching & Trigger Invocation

Verify deterministic activation using tested natural language prompts matching the SKILL.md specification.

Agent runtimes match incoming user intent against trigger phrases declared in the skill frontmatter. Invoking exact phrases like 'replace variables in docx template' or 'style table in python-docx' ensures the runtime loads the python-docx Legal Contract Builder context rather than attempting generic script generation.

scripts/build_nda.py
from docx import Document
from docx.shared import Inches, Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from scripts.docx_contract_utils import replace_in_document

def generate_nda(output_path: str, context: dict):
    doc = Document()
    
    # Establish Title
    title = doc.add_paragraph()
    title.alignment = WD_ALIGN_PARAGRAPH.CENTER
    run = title.add_run("MUTUAL NONDISCLOSURE AGREEMENT")
    run.font.size = Pt(14)
    run.font.bold = True
    
    # Add Standard Clauses
    p1 = doc.add_paragraph("This Agreement is entered into as of {{EFFECTIVE_DATE}} by and between:")
    
    # Add Parties Table
    table = doc.add_table(rows=2, cols=2)
    table.style = 'Table Grid'
    table.rows[0].cells[0].text = "Disclosing Party: {{DISCLOSING_PARTY}}"
    table.rows[0].cells[1].text = "Receiving Party: {{RECEIVING_PARTY}}"
    
    # Replace Variables
    replace_in_document(doc, context)
    doc.save(output_path)

if __name__ == "__main__":
    generate_nda("workspace/NDA_Final.docx", {
        "{{EFFECTIVE_DATE}}": "October 24, 2026",
        "{{DISCLOSING_PARTY}}": "Acme Corp",
        "{{RECEIVING_PARTY}}": "Global Tech LLC"
    })
Production Pro-Tip

Always provide the replacement dictionary with explicit delimiters (such as `{{KEY}}`) to prevent false-positive string matches against standard English contract terms.

Sandbox Gotcha

Do not invoke `doc.save()` pointing to a file currently open in Microsoft Word on Windows; local file locks cause `PermissionError: [Errno 13] Permission denied`.

4

Verification, Linting & Output Quality Gate

Execute automated self-healing checks to validate that all placeholders were substituted and OpenXML packaging is valid.

Autonomous agents should not conclude their task without verifying the output artifact. This gate uses a verification script that unzips the generated `.docx` archive in-memory, parses `word/document.xml`, and verifies that zero residual `{{...}}` tags remain.

Terminal Command
python -c "import zipfile, xml.etree.ElementTree as ET, sys; z = zipfile.ZipFile('workspace/NDA_Final.docx'); xml_content = z.read('word/document.xml').decode('utf-8'); sys.exit(1 if '{{' in xml_content else 0)" && echo 'Contract Verification: PASSED'
scripts/verify_contract.sh
#!/usr/bin/env bash
set -euo pipefail

TARGET_DOC="workspace/NDA_Final.docx"

if [ ! -f "$TARGET_DOC" ]; then
  echo "ERROR: Artifact $TARGET_DOC not found!" >&2
  exit 1
fi

# Inspect OpenXML package for residual unresolved template variables
python - <<EOF
import zipfile, sys
with zipfile.ZipFile('$TARGET_DOC') as z:
    content = z.read('word/document.xml').decode('utf-8')
    if '{{' in content or '}}' in content:
        print('CRITICAL: Residual {{placeholder}} found in final contract document!')
        sys.exit(1)
    print('Verification SUCCESS: No orphaned placeholders detected.')
EOF
Production Pro-Tip

Integrate the verification script into your agent's post-execution workflow so it triggers self-correction loops automatically if placeholders are left unpopulated.

Sandbox Gotcha

Relying purely on python-docx object introspection for verification can miss unlinked headers and footers; inspecting the raw `word/document.xml` archive stream guarantees 100% replacement coverage.

Real-World Scenario: Automated Master Services Agreement (MSA) Generation with Custom Fee Schedules

Tested Trigger Prompt (Feed directly into Codex, Claude, or Cursor):

“Generate word contract python: Build a professional Master Services Agreement from our base template, replace variables in docx template with client metadata from client_payload.json, and style table in python-docx to display a 4-tier milestone fee schedule with shaded header cells.”

Deterministic Agent Verification Pipeline:
Agent scans .agents/skills/python-docx-contract-builder/SKILL.md and matches triggers for template substitution and table styling.
Agent inspects client_payload.json and extracts structured key-value bindings including milestones, payment deadlines, and party legal names.
Agent opens master_msa_template.docx, runs safe multi-run placeholder replacement across all body paragraphs and annexes.
Agent programmatically inserts a structured milestone table, applies `cantSplit` to rows, sets explicit cell widths, and injects XML-level background shading (`w:shd`) on the header row.
Agent executes the raw OpenXML verification check script, confirms 0 residual placeholders, and saves the final file to workspace/MSA_Completed.docx.

Runtime Troubleshooting & Failure Modes

Error: KeyError: "no style with name 'Custom Table Style'"

Root Cause: The agent attempted to assign a non-existent or localized style name to a table or paragraph that does not exist in the document's underlying styles.xml palette.

Resolution Command / Fix:
# Fallback to built-in universal styles or instantiate from template
try:
    table.style = 'Table Grid'
except KeyError:
    table.style = 'Normal Table'
# To verify available styles programmatically:
# available_styles = [s.name for s in doc.styles if s.type.name == 'TABLE']
Error: xml.etree.ElementTree.ParseError: unclosed token or corrupted document package upon opening saved docx

Root Cause: The agent injected raw unescaped XML strings (e.g. text containing literal '&', '<', or '>') into a run or `parse_xml()` call, breaking the OpenXML structure.

Resolution Command / Fix:
from xml.sax.saxutils import escape
safe_text = escape(user_input_string) # Escapes &, <, > safely
run.text = safe_text

Frequently Asked Questions (python-docx Legal Contract Builder SOP)

Q:Can I use python-docx Legal Contract Builder across Codex, Claude Code, and Cursor simultaneously?

Yes. The skill conforms to the universal SKILL.md specification supported across all modern agent runtimes. By placing the file in `.agents/skills/python-docx-contract-builder/SKILL.md` or linking it into `.cursor/rules`, all leading coding agents interpret the triggers and boundaries identically.

Q:How does python-docx Legal Contract Builder prevent context window overflow during long agent sessions?

The skill establishes concise procedural boundaries and deterministic validation gates rather than polluting system prompts with redundant rules. By guiding the agent to run deterministic scripts and test assertions locally via shell commands, the model avoids outputting large binary file contents into the chat history.

Q:Does this skill require escalated root or container permissions?

No. It is audited with a security score of 98/100 and runs safely within workspace-scoped sandboxes. It requires standard read/write permissions only within the local working directory and disables unrestricted network access or elevated root shell commands.

Ready to equip your autonomous agent with python-docx Legal Contract Builder?

Copy the complete audited SKILL.md specification or download the 1-click zip bundle directly from our verified registry.

Get 1-Click Install Spec