Custom Risk Registers

Custom Risk Registers

You can upload your own risk register to customize what Contract Risk Scanner for Microsoft 365 looks for when analyzing contracts.


When to use a custom risk register

  • ✅ Your liability cap requirements differ from standard defaults
  • ✅ You have industry-specific clauses that must be present
  • ✅ You want to add language your legal team has standardized
  • ✅ Your risk tolerance differs from the default scoring bands

If you don’t upload a custom risk register, the agent uses its built-in risk rules, which cover standard commercial contract risks.


How it works

Upload a risk_rules_config.json file in your prompt alongside your contract:

“Use this risk register for the scan” (attach your JSON)

The agent merges your config with its built-in rules. Your rules take priority.


The structure

A risk register has six top-level fields:

{
  "playbook_metadata": { ... },
  "required_clauses": [ ... ],
  "unacceptable_terms": [ ... ],
  "preferred_language": [ ... ],
  "scoring_weights": { ... },
  "thresholds": { ... }
}

Section 1 - playbook_metadata

Identifies your risk register.

"playbook_metadata": {
  "name": "Acme Corp Risk Register",
  "version": "1.0",
  "publisher": "Acme Legal Ops",
  "description": "Internal standards for vendor agreements at Acme Corp",
  "last_updated": "2026-06-18"
}

💡 Always bump the version when you change rules. This shows up in CSV/JSON exports for traceability.


Section 2 - required_clauses

Clauses that must be present.

{
  "id": "REQ-001",
  "clause": "Term and Termination",
  "description": "Contract must specify duration and termination rights.",
  "severity_if_missing": "High",
  "business_impact": "Locked in indefinitely if missing."
}
Field Required Notes
id Yes Use a prefix that identifies your org (e.g., ACME-REQ-001)
clause Yes Short name
description Yes What the clause should cover
severity_if_missing Yes Low / Medium / High / Critical
business_impact Yes Plain-language consequence

Section 3 - unacceptable_terms

Language patterns that trigger findings when found.

{
  "id": "UNACC-001",
  "term": "Unlimited liability",
  "patterns": ["unlimited liability", "no cap on liability"],
  "exceptions": ["security breaches excluded from cap"],
  "severity": "Critical",
  "business_impact": "Unlimited financial exposure."
}
Field Required Notes
id Yes Unique ID
term Yes Short name
patterns Yes List of phrases to match (case-insensitive)
exceptions No Phrases that suppress the finding if also present
severity Yes Low / Medium / High / Critical
business_impact Yes Plain-language consequence

💡 Use multiple patterns to catch common variations.


Section 4 - preferred_language

Your standard redlines, used in Negotiation Prep mode.

{
  "id": "PREF-001",
  "topic": "Liability Cap",
  "preferred": "Total liability of either party shall not exceed the fees paid in the prior twelve (12) months.",
  "use_when": "Liability section is missing a cap or has an unfavorable one."
}
Field Required Notes
id Yes Unique ID
topic Yes Short name
preferred Yes The redline language to propose
use_when Yes Condition for offering this redline

Section 5 - scoring_weights

Multipliers for each risk area. Default is 1.0.

"scoring_weights": {
  "Liability": 1.5,
  "Data": 1.2,
  "IP": 1.0
}

Increase to make an area count more toward the overall score. Decrease for less.

Valid areas: Liability, Indemnification, Termination, Payment, Confidentiality, IP, Compliance, Data, SLA, Renewal, Other


Section 6 - thresholds

Recommendation band cutoffs.

"thresholds": {
  "low_risk_max": 25,
  "moderate_risk_max": 50,
  "high_risk_max": 75,
  "critical_risk_min": 76,
  "auto_escalate_at": 60
}

Lower thresholds make the risk register more conservative.


How scoring works

Each finding gets a point value based on:

points = base_severity_weight × confidence_multiplier × scoring_weight

Base severity weights:

Severity Points
Low 3
Medium 8
High 15
Critical 25

Confidence multipliers:

Confidence Multiplier
Low 0.5
Medium 0.8
High 1.0

Scoring weights are defined in your risk register (or default to 1.0).

Total is capped at 100.

Every score is shown with its breakdown so you can see what drove it.


Recommendation bands

The default cutoffs are:

Band Score Range
🟢 Low 0–25
🟡 Moderate 26–50
🟠 High 51–75
🔴 Critical 76–100

You can adjust these via the thresholds field in your custom risk register.


Example: Adding a new required clause

Let’s add a “Force Majeure” requirement.

Step 1 - Create your risk register file

Save a new file as acme_risk_register.json.

Step 2 - Add the new clause

Add to required_clauses:

{
  "id": "ACME-REQ-007",
  "clause": "Force Majeure",
  "description": "Contract must include a force majeure clause covering pandemic, war, and supply chain disruption.",
  "severity_if_missing": "Medium",
  "business_impact": "Without force majeure, you may bear performance risk for events outside your control."
}

Step 3 - Set the version

"playbook_metadata": {
  "name": "Acme Custom Risk Register",
  "version": "1.0"
}

Step 4 - Upload to the agent

“Use the risk register in this file” (attach acme_risk_register.json)


Common mistakes

Mistake Result
Reusing existing IDs Rules silently overwrite each other
Forgetting to bump version Audit trail loses track of changes
Setting weights too high (>2.5) Score saturates at 100 instantly
Inconsistent area names Weights don’t apply
Invalid JSON syntax Agent falls back to built-in rules

Testing your risk register

After uploading, run a scan on a known contract you’ve reviewed before:

  1. Are findings catching what you expected?
  2. Is the score in the range you expected?
  3. Are redlines using your preferred language?

Iterate until results match your team’s judgment.


Version control

Treat risk registers like code:

  • ✅ Store them in SharePoint or a Git repo
  • ✅ Use semantic versioning (1.0 → 1.1 → 2.0)
  • ✅ Document changes in release notes
  • ✅ Train your team when you ship updates