
Legal Risk Assessment
- 47 installs
- 451 repo stars
- Updated July 21, 2026
- borghei/claude-skills
legal-risk-assessment is a skill that scores legal risks on a 5x5 Severity x Likelihood matrix, maintains a risk register, and guides escalation decisions.
About
This skill runs structured legal risk assessment using a quantitative 5x5 Severity x Likelihood matrix. It scores individual risks, assigns color-coded levels with recommended actions, maintains a risk register, and generates assessment memos. Legal teams use it for risk scoring, register maintenance, and escalation decisions. It is explicitly experimental and not legal advice.
- Scores legal risk with a quantitative 5x5 Severity x Likelihood matrix
- Assigns color-coded risk levels (GREEN/YELLOW/ORANGE/RED) and recommended actions
- Generates risk assessment memos and guides outside-counsel escalation decisions
Legal Risk Assessment by the numbers
- 47 all-time installs (skills.sh)
- Ranked #1,355 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
legal-risk-assessment capabilities & compatibility
- Capabilities
- risk assessment · risk scoring · escalation routing · compliance check
- Use cases
- security audit · planning
- Pricing
- Free
What legal-risk-assessment says it does
Structured legal risk assessment using a quantitative 5x5 Severity x Likelihood matrix. Scores risks, maintains registers, generates assessment memos, and guides escalation decisions.
Color-coded level (GREEN / YELLOW / ORANGE / RED)
When to engage outside counsel:
npx skills add https://github.com/borghei/claude-skills --skill legal-risk-assessmentAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 47 |
|---|---|
| repo stars | ★ 451 |
| Last updated | July 21, 2026 |
| Repository | borghei/claude-skills ↗ |
What it does
Score legal risks on a 5x5 severity-likelihood matrix, maintain a risk register, and guide escalation decisions.
Who is it for?
Legal teams scoring risks, maintaining risk registers, and deciding when to escalate to outside counsel.
Skip if: Anyone needing actual legal advice; the skill is experimental and explicitly not legal advice.
When should I use this skill?
You need risk scoring, a risk register, escalation decisions, or a risk memo.
What you get
Produces a color-coded risk score, recommended action, register entry, and an assessment memo with escalation guidance.
- Risk scores
- Risk register
- Risk assessment memo
By the numbers
- 5x5 Severity x Likelihood matrix
- Four color-coded risk levels: GREEN, YELLOW, ORANGE, RED
- Two Python tools: risk scorer and risk report generator
Files
⚠️ EXPERIMENTAL — This skill is provided for educational and informational purposes only. It does NOT constitute legal advice. All responsibility for usage rests with the user. Consult qualified legal professionals before acting on any output.
Legal Risk Assessment
Structured legal risk assessment using a quantitative 5x5 Severity x Likelihood matrix. Scores risks, maintains registers, generates assessment memos, and guides escalation decisions.
---
Table of Contents
- Tools
- Risk Scorer
- Risk Report Generator
- Reference Guides
- Workflows
- Troubleshooting
- Success Criteria
- Scope & Limitations
- Anti-Patterns
- Tool Reference
---
Tools
Risk Scorer
Calculates risk scores from severity and likelihood inputs, assigns color-coded risk levels, and generates summary statistics.
# Score a single risk
python scripts/risk_scorer.py --severity 4 --likelihood 3 \
--category "Contract" --description "Vendor SLA non-compliance"
# JSON output
python scripts/risk_scorer.py --severity 4 --likelihood 3 \
--category "Contract" --description "Vendor SLA breach" --json
# Batch mode from risk register file
python scripts/risk_scorer.py --input risks.json --json
# Batch mode with human-readable output
python scripts/risk_scorer.py --input risks.jsonInput JSON format (batch mode):
{
"risks": [
{"severity": 4, "likelihood": 3, "category": "Contract", "description": "Vendor SLA breach"},
{"severity": 2, "likelihood": 2, "category": "Regulatory", "description": "Minor filing delay"}
]
}Output includes:
- Risk score (Severity x Likelihood)
- Color-coded level (GREEN / YELLOW / ORANGE / RED)
- Recommended action (Accept / Monitor / Mitigate / Escalate)
- Batch summary statistics (count per level, average score)
---
Risk Report Generator
Generates a formatted risk assessment memo in markdown from a risk register JSON file.
# Generate memo from risk register
python scripts/risk_report_generator.py --input risk_register.json
# Save to file
python scripts/risk_report_generator.py --input risk_register.json --output memo.md
# JSON metadata output
python scripts/risk_report_generator.py --input risk_register.json --jsonReport includes:
- ASCII risk matrix visualization
- Risk distribution summary (counts and percentages per level)
- Top risks ranked by score
- Recommended actions per risk with owner assignments
- Monitoring plan suggestions
- Escalation recommendations
---
Reference Guides
Risk Framework
references/risk_framework.md
Complete Severity x Likelihood matrix reference:
- Severity levels 1-5 with financial exposure percentages
- Likelihood levels 1-5 with probability ranges
- Risk matrix visualization
- Risk classification (GREEN/YELLOW/ORANGE/RED) with actions
- Documentation standards for memos and register entries
Escalation Guide
references/escalation_guide.md
When to engage outside counsel:
- Mandatory engagement triggers (litigation, investigation, criminal)
- Strongly recommended scenarios (novel issues, material exposure)
- Consider scenarios (complex disputes, employment, data incidents)
- Risk category definitions and contributing/mitigating factors
---
Workflows
Workflow 1: New Risk Assessment
Step 1: Identify risk category and description
→ Use references/risk_framework.md category definitions
Step 2: Score severity (1-5) and likelihood (1-5)
→ python scripts/risk_scorer.py --severity N --likelihood N \
--category "Category" --description "Description"
Step 3: Review risk level and recommended action
→ GREEN: Accept and document
→ YELLOW: Assign owner and monitor
→ ORANGE: Escalate to senior counsel
→ RED: Immediate escalation, crisis management
Step 4: Determine outside counsel need
→ Consult references/escalation_guide.md
Step 5: Document in risk register
→ Add entry to register JSON fileWorkflow 2: Periodic Risk Register Review
Step 1: Load current risk register
→ python scripts/risk_scorer.py --input register.json
Step 2: Generate assessment memo
→ python scripts/risk_report_generator.py --input register.json --output memo.md
Step 3: Review top risks and distribution
→ Focus on ORANGE and RED risks first
Step 4: Update severity/likelihood for changed risks
→ Re-score and regenerate report
Step 5: Distribute memo to stakeholdersWorkflow 3: Escalation Decision
Step 1: Score the risk
→ python scripts/risk_scorer.py --severity N --likelihood N \
--category "Category" --description "Description"
Step 2: Check escalation triggers
→ Mandatory: active litigation, government investigation, criminal exposure
→ Strongly Recommended: novel issues, jurisdictional complexity, material exposure
→ Consider: complex disputes, employment matters, data incidents
Step 3: Document escalation rationale
→ Include risk score, level, and specific trigger in memo
Step 4: Select outside counsel if needed
→ See references/escalation_guide.md criteria---
Troubleshooting
| Problem | Possible Cause | Resolution |
|---|---|---|
| Risk score seems too low for a serious matter | Severity or likelihood underestimated; qualitative factors not captured | Review severity descriptions in risk_framework.md; consider worst-case financial exposure; add contributing factors to description |
| Multiple risks in same category but different scores | Risks have different severity/likelihood combinations | This is expected; each risk is independent; review category-level trends in report |
| Batch mode fails on input file | Malformed JSON or missing required fields | Verify JSON structure matches expected format; ensure each risk has severity, likelihood, category, description |
| Report generator produces empty matrix | No risks in input file or all risks have invalid scores | Check that input JSON contains valid risks with severity 1-5 and likelihood 1-5 |
| Escalation guide suggests outside counsel but budget is constrained | Risk score indicates material exposure | Document the budget constraint and residual risk acceptance; consider limited-scope engagement |
| Risk register grows unwieldy | Risks not being closed or consolidated | Archive resolved risks; consolidate related risks; review register quarterly |
---
Success Criteria
- All identified legal risks scored and documented -- every risk has severity, likelihood, category, description, and recommended action in the register
- Risk distribution reviewed quarterly -- memo generated and distributed to stakeholders with trend analysis
- ORANGE and RED risks have assigned owners and mitigation plans -- no high-severity risk without accountability
- Escalation decisions documented with rationale -- outside counsel engagement triggers clearly recorded
- Risk register maintained as living document -- risks updated, resolved, or archived as status changes
---
Scope & Limitations
In Scope:
- Quantitative risk scoring using 5x5 Severity x Likelihood matrix
- Risk register management and batch processing
- Risk assessment memo generation with matrix visualization
- Escalation guidance for outside counsel engagement
- Risk categorization (Contract, Regulatory, Litigation, IP, Data Privacy, Employment, Corporate)
Out of Scope:
- Legal advice on specific risk mitigation strategies -- consult legal counsel
- Insurance coverage analysis or actuarial calculations
- Regulatory filing or submission preparation
- Contract drafting or review
- Litigation strategy or case management
---
Anti-Patterns
- Scoring by committee consensus without criteria -- use the defined severity and likelihood scales consistently; do not negotiate scores to make stakeholders comfortable; a risk scored as 4 severity should match the framework definition
- Treating the risk register as a one-time exercise -- risk registers are living documents; risks change as circumstances evolve; schedule quarterly reviews and update scores accordingly
- Escalating everything to outside counsel -- the escalation guide defines specific triggers; not every YELLOW risk needs external counsel; over-escalation wastes budget and creates dependency
- Ignoring GREEN risks entirely -- GREEN risks still require documentation and periodic monitoring; a GREEN risk can escalate to YELLOW or ORANGE if circumstances change
- Using risk scores as the sole decision factor -- scores are inputs to judgment, not substitutes; qualitative factors like reputational impact or strategic importance may warrant action beyond what the score suggests
---
Tool Reference
risk_scorer.py
Calculates risk scores and assigns color-coded risk levels with recommended actions.
| Flag | Required | Description |
|---|---|---|
--severity <1-5> | Yes (single mode) | Severity rating: 1=Negligible, 2=Minor, 3=Moderate, 4=Major, 5=Critical |
--likelihood <1-5> | Yes (single mode) | Likelihood rating: 1=Remote, 2=Unlikely, 3=Possible, 4=Likely, 5=Almost Certain |
--category <text> | Yes (single mode) | Risk category: Contract, Regulatory, Litigation, IP, Data Privacy, Employment, Corporate |
--description <text> | Yes (single mode) | Risk description |
--input <file> | Yes (batch mode) | Path to JSON file containing multiple risks |
--json | No | Output results in JSON format |
risk_report_generator.py
Generates formatted risk assessment memo from a risk register JSON file.
| Flag | Required | Description |
|---|---|---|
--input <file> | Yes | Path to risk register JSON file |
--output <file> | No | Save memo to specified file path (markdown format) |
--json | No | Output report metadata in JSON format |
Outside Counsel Escalation Guide
Guidance for when and how to engage outside counsel based on risk assessment results, matter type, and organizational capability.
---
Table of Contents
- Escalation Decision Framework
- Mandatory Engagement
- Strongly Recommended Engagement
- Consider Engagement
- Selecting Outside Counsel
- Risk Category Definitions
- Contributing Factors Framework
- Mitigating Factors Framework
- Engagement Models
- Cost Management
---
Escalation Decision Framework
Use this decision tree when determining whether to engage outside counsel:
Is this an active litigation, government investigation,
or matter with criminal exposure?
→ YES → MANDATORY engagement (see Mandatory section)
Is this a novel legal issue, multi-jurisdictional matter,
or exposure exceeding 5% of revenue?
→ YES → STRONGLY RECOMMENDED (see Strongly Recommended section)
Is this a complex dispute, sensitive employment matter,
or data incident affecting >1,000 individuals?
→ YES → CONSIDER engagement (see Consider section)
Does the matter involve specialized expertise not
available in-house?
→ YES → CONSIDER engagement for that specific expertise
None of the above?
→ Handle in-house. Document rationale for not engaging outside counsel.---
Mandatory Engagement
Outside counsel must be engaged in the following situations. Do not attempt to handle these matters solely with in-house resources.
| Trigger | Rationale | Urgency |
|---|---|---|
| Active litigation filed | Court-imposed deadlines, procedural requirements, potential sanctions for missteps | Engage within 48 hours of service |
| Government investigation | Subpoena response, document preservation, Fifth Amendment considerations, regulatory expertise | Engage immediately upon notice |
| Criminal exposure | Constitutional protections, sentencing implications, parallel proceedings management | Engage immediately; separate counsel for entity vs. individuals |
| Securities enforcement | SEC/DOJ coordination, insider trading, disclosure obligations, director liability | Engage immediately; consider specialized securities defense counsel |
| Board-level matters | Special committee investigations, shareholder derivative suits, fiduciary duty claims | Engage before first board discussion of matter |
| Existential threats | Matters threatening company viability, license revocation, debarment | Engage immediately with crisis management capability |
Mandatory Engagement Checklist
When mandatory engagement is triggered:
- [ ] Identify matter type and immediate deadlines
- [ ] Issue litigation hold / document preservation notice
- [ ] Brief General Counsel and CEO/executive sponsor
- [ ] Select outside counsel with relevant specialization
- [ ] Execute engagement letter with scope and budget
- [ ] Establish privilege protocols (joint defense or common interest if applicable)
- [ ] Create dedicated matter folder with access controls
- [ ] Schedule initial strategy session within 72 hours
---
Strongly Recommended Engagement
Outside counsel should be engaged in these situations unless compelling reasons exist to handle in-house. Document rationale if not engaging.
| Trigger | Rationale | Considerations |
|---|---|---|
| Novel legal issues | Untested legal theories, first-impression questions, rapidly evolving law | In-house team may lack depth in emerging areas; outside counsel brings broader case law awareness |
| Jurisdictional complexity | Multi-state or international matters, forum selection, choice of law disputes | Local counsel needed for jurisdictional requirements; coordination across jurisdictions |
| Material financial exposure | Exposure exceeding 5% of annual revenue or $5M (whichever is lower) | Financial risk warrants best available expertise; insurance carrier may require approved counsel |
| Specialized expertise | Antitrust, patent prosecution/litigation, international trade, tax controversy | In-house team unlikely to have depth in all specializations |
| Regulatory changes | New regulations with material compliance obligations, enforcement transitions | Outside counsel track regulatory developments and enforcement trends full-time |
| M&A transactions | Due diligence, deal structuring, regulatory approvals, post-closing integration | Transaction-specific expertise, volume of documentation, deadline pressure |
| Class action risk | Potential for class certification, multi-district litigation, mass arbitration | Class defense requires specialized strategy and experience |
Strongly Recommended Engagement Checklist
- [ ] Assess whether in-house capabilities are sufficient (document assessment)
- [ ] Identify specific expertise needed
- [ ] Determine budget and engagement scope
- [ ] Evaluate 2-3 outside counsel options
- [ ] Brief senior leadership on recommendation
- [ ] Execute engagement letter with clear scope boundaries
---
Consider Engagement
Outside counsel may be beneficial but is not strictly necessary. Evaluate based on in-house capacity, matter complexity, and available resources.
| Trigger | When to Engage | When to Handle In-House |
|---|---|---|
| Complex commercial disputes | Multiple parties, complex fact patterns, arbitration with significant exposure | Clear liability, small exposure, cooperative counterparty |
| Employment matters | Discrimination claims, wage/hour class potential, executive terminations, whistleblower retaliation | Routine discipline, straightforward terminations, standard HR issues |
| Data incidents | >1,000 affected individuals, sensitive data categories, multi-jurisdictional notification | <1,000 affected, standard notification, no regulatory inquiry |
| IP disputes | Infringement claims with injunction risk, trade secret litigation, patent portfolio strategy | Routine trademark monitoring, standard licensing, DMCA notices |
| Insurance coverage | Complex coverage disputes, D&O claims, cyber insurance claims, coverage litigation | Straightforward claims with clear coverage |
| Real estate | Complex leases, environmental issues, condemnation, development disputes | Standard lease renewals, routine landlord-tenant matters |
| International matters | Foreign law applies, cross-border enforcement, international arbitration | Domestic matters with incidental international elements |
---
Selecting Outside Counsel
Selection Criteria
| Criterion | Weight | Assessment Method |
|---|---|---|
| Relevant expertise | 30% | Track record in specific practice area; published authority; peer recognition |
| Industry knowledge | 20% | Prior work in same industry; understanding of business context and regulatory landscape |
| Responsiveness | 15% | Response time to inquiries; availability for urgent matters; partner accessibility |
| Cost structure | 15% | Hourly rates; willingness to offer alternative fee arrangements; budget predictability |
| Conflicts clearance | 10% | Clean conflict check; no representation of adverse parties or competitors |
| Cultural fit | 10% | Communication style; willingness to work with in-house team; diversity commitment |
Alternative Fee Arrangements
| Arrangement | Best For | Risk Allocation |
|---|---|---|
| Fixed fee | Predictable matters with defined scope (transactions, regulatory filings) | Risk on outside counsel |
| Capped fee | Matters with variable scope but a known ceiling | Shared risk |
| Success fee / contingency | Litigation with clear upside; affirmative claims | Risk on outside counsel |
| Blended rate | Multiple attorneys at different levels | Balanced |
| Phased budget | Complex matters with distinct phases (investigation → litigation → trial) | Phase-by-phase assessment |
| Secondment | Extended need for specific expertise; surge capacity | Predictable cost |
---
Risk Category Definitions
Detailed definitions for each risk category to ensure consistent categorization.
Contract Risk
| Sub-Category | Description | Typical Severity Range |
|---|---|---|
| Breach of contract | Failure to perform material obligations | 2-4 |
| Indemnification exposure | Claims under indemnification clauses | 3-5 |
| SLA violations | Service level failures triggering penalties or termination | 1-3 |
| Force majeure disputes | Disagreements over force majeure applicability | 2-4 |
| Termination disputes | Contested contract terminations | 2-4 |
| Warranty claims | Product or service warranty breach allegations | 2-4 |
Regulatory Risk
| Sub-Category | Description | Typical Severity Range |
|---|---|---|
| Enforcement action | Regulatory investigation or enforcement proceeding | 3-5 |
| Compliance gap | Identified non-compliance with applicable regulation | 2-4 |
| License/permit risk | Threat to required licenses or permits | 3-5 |
| Reporting failure | Missed or inaccurate regulatory reporting | 2-4 |
| Regulatory change | New regulation requiring material compliance effort | 2-3 |
Litigation Risk
| Sub-Category | Description | Typical Severity Range |
|---|---|---|
| Active lawsuit | Filed complaint or arbitration demand | 3-5 |
| Threatened litigation | Demand letter or pre-suit notice | 2-4 |
| Class action exposure | Potential class certification | 4-5 |
| Appellate risk | Adverse ruling subject to appeal | 2-4 |
| Judgment enforcement | Risk of adverse judgment enforcement | 3-5 |
IP Risk
| Sub-Category | Description | Typical Severity Range |
|---|---|---|
| Patent infringement | Infringement claim or assertion | 3-5 |
| Trade secret misappropriation | Theft or unauthorized disclosure of trade secrets | 3-5 |
| Trademark dispute | Trademark infringement or dilution claim | 2-4 |
| Copyright infringement | Unauthorized use of copyrighted material | 2-4 |
| Open-source compliance | License violation in open-source software | 2-4 |
Data Privacy Risk
| Sub-Category | Description | Typical Severity Range |
|---|---|---|
| Data breach | Unauthorized access to personal data | 3-5 |
| Regulatory non-compliance | GDPR, CCPA, or other privacy law violations | 3-5 |
| Cross-border transfer | Unlawful international data transfers | 2-4 |
| Consent management | Inadequate consent mechanisms | 2-3 |
| Vendor data handling | Third-party processor non-compliance | 2-4 |
Employment Risk
| Sub-Category | Description | Typical Severity Range |
|---|---|---|
| Discrimination claim | Protected class discrimination allegation | 3-5 |
| Wrongful termination | Unlawful termination claim | 2-4 |
| Wage and hour | Misclassification, overtime, or wage disputes | 2-5 |
| Harassment | Workplace harassment allegation | 3-5 |
| Non-compete enforcement | Non-compete or non-solicitation disputes | 2-4 |
| Whistleblower retaliation | Retaliation claim after protected activity | 3-5 |
Corporate Risk
| Sub-Category | Description | Typical Severity Range |
|---|---|---|
| M&A liability | Post-closing claims, earnout disputes, rep & warranty claims | 3-5 |
| Governance failure | Board fiduciary duty breach, conflicts of interest | 3-5 |
| Shareholder dispute | Minority shareholder claims, derivative suits | 3-5 |
| Securities compliance | Disclosure violations, insider trading | 4-5 |
| Corporate restructuring | Insolvency, reorganization, wind-down complications | 3-5 |
---
Contributing Factors Framework
Factors that increase overall risk profile. Consider these when scoring severity and likelihood.
| Factor | Impact | Assessment Questions |
|---|---|---|
| No compliance program | +1 likelihood | Is there a documented compliance program covering this risk area? |
| Prior incidents | +1 likelihood | Has the organization experienced similar issues before? |
| Aggressive counterparty | +1 likelihood | Is the opposing party known for aggressive litigation or enforcement? |
| Public visibility | +1 severity | Will this matter attract media attention or public scrutiny? |
| Precedential risk | +1 severity | Could an adverse outcome create harmful precedent for future matters? |
| Multi-jurisdictional | +1 to both | Does this matter span multiple jurisdictions with different legal requirements? |
| Criminal exposure | Sets severity to 5 | Is there any potential for criminal charges against the entity or individuals? |
| Class action potential | +2 severity | Could this matter become or contribute to a class action? |
| Regulatory trend | +1 likelihood | Is there an active enforcement trend in this area? |
| Internal control weakness | +1 likelihood | Have audits or assessments identified relevant control gaps? |
---
Mitigating Factors Framework
Factors that reduce overall risk profile. Consider these when evaluating residual risk after controls.
| Factor | Impact | Assessment Questions |
|---|---|---|
| Strong compliance program | -1 likelihood | Is there a robust, documented, and regularly tested compliance program? |
| Insurance coverage | -1 severity | Is there applicable insurance coverage with adequate limits? |
| Favorable precedent | -1 likelihood | Is there favorable case law or regulatory guidance supporting our position? |
| Cooperative counterparty | -1 likelihood | Is the opposing party willing to negotiate or mediate? |
| Contractual protections | -1 severity | Are there indemnification, limitation of liability, or insurance requirements? |
| Early detection | -1 both | Was the risk identified early, allowing proactive response? |
| Experienced counsel | -1 severity | Is experienced counsel (internal or external) already engaged? |
| Regulatory safe harbor | -1 likelihood | Does a safe harbor or exemption apply to the conduct at issue? |
| Document retention | -1 likelihood | Are relevant documents preserved and organized for potential litigation? |
| Self-reporting | -1 severity | Has the organization self-reported to regulators (where applicable)? |
---
Engagement Models
Full Representation
Outside counsel manages all aspects of the matter with in-house oversight.
| Aspect | Detail |
|---|---|
| When to use | Complex litigation, government investigations, M&A transactions |
| In-house role | Strategic oversight, business context, budget management |
| Outside counsel role | Legal strategy, court appearances, document review, depositions, negotiations |
| Budget approach | Phased budgets with quarterly true-ups |
Co-Counsel / Supervision
Outside counsel handles specific aspects while in-house manages the rest.
| Aspect | Detail |
|---|---|
| When to use | Matters requiring specific expertise but manageable in-house overall |
| In-house role | Day-to-day management, routine filings, witness preparation |
| Outside counsel role | Specialized analysis, expert witness, specific motions or hearings |
| Budget approach | Task-based fees for specific deliverables |
Advisory Only
Outside counsel provides advice and guidance while in-house handles execution.
| Aspect | Detail |
|---|---|
| When to use | Novel legal questions, regulatory interpretation, risk assessment validation |
| In-house role | All execution, document preparation, counterparty communication |
| Outside counsel role | Legal research, opinion letters, strategy review, risk assessment |
| Budget approach | Hourly or fixed fee for defined advisory scope |
---
Cost Management
Budget Controls
| Control | Description |
|---|---|
| Engagement letter scope | Define scope precisely; require written approval for out-of-scope work |
| Staffing guidelines | Specify acceptable staffing levels; limit partner hours to strategy and court |
| Invoice review | Review invoices against budget; challenge block billing and excessive charges |
| Phase gates | Require budget re-approval at each phase transition |
| Status reporting | Monthly matter status and budget reports from outside counsel |
| Early case assessment | Require early case assessment with budget estimate within 30 days |
Cost Benchmarks
| Matter Type | Typical Range | Key Cost Drivers |
|---|---|---|
| Single-plaintiff employment | $50K - $300K | Discovery scope, depositions, trial vs. settlement |
| Commercial litigation (mid-size) | $200K - $1M | Complexity, document volume, expert witnesses |
| Patent litigation | $500K - $5M+ | Claim construction, technical experts, trial |
| Regulatory investigation | $300K - $3M+ | Document production, witness preparation, negotiation duration |
| M&A transaction | $200K - $2M+ | Deal size, regulatory approvals, diligence scope |
| Class action defense | $1M - $10M+ | Class size, discovery, certification fight, settlement negotiations |
Legal Risk Assessment Framework
Complete reference for the 5x5 Severity x Likelihood risk scoring matrix, classification levels, and documentation standards.
---
Table of Contents
- Severity Scale
- Likelihood Scale
- Risk Matrix
- Risk Classification Levels
- Risk Categories
- Risk Assessment Memo Format
- Risk Register Entry Format
- Contributing and Mitigating Factors
---
Severity Scale
Severity measures the potential impact if the risk materializes. Each level corresponds to a financial exposure range relative to annual revenue.
| Level | Label | Financial Exposure | Description | Examples |
|---|---|---|---|---|
| 1 | Negligible | <0.1% revenue | Minimal impact, easily absorbed | Minor contract amendment needed; administrative filing correction; internal policy clarification |
| 2 | Minor | 0.1-1% revenue | Limited impact, manageable within normal operations | Small claims dispute (<$50K); routine regulatory inquiry; employee grievance without litigation |
| 3 | Moderate | 1-5% revenue | Noticeable impact requiring dedicated resources | Mid-size contract dispute ($50K-$500K); regulatory audit with findings; employment discrimination claim |
| 4 | Major | 5-15% revenue | Significant impact affecting business operations | Large litigation ($500K-$5M); regulatory enforcement action; data breach affecting >10K individuals; patent infringement claim |
| 5 | Critical | >15% revenue | Existential or near-existential impact | Class action lawsuit; government investigation with potential criminal charges; market-moving regulatory penalty; loss of critical license or IP |
Severity Assessment Guidance
When assessing severity, consider all dimensions of impact:
| Dimension | Questions to Ask |
|---|---|
| Financial | What is the maximum monetary exposure (damages, fines, settlements, legal fees)? |
| Operational | Will business operations be disrupted? For how long? |
| Reputational | Will this become public? What is the media risk? Customer impact? |
| Strategic | Does this affect key business relationships, market position, or growth plans? |
| Regulatory | Could this trigger additional regulatory scrutiny or license revocation? |
| Precedential | Could the outcome create adverse precedent for future matters? |
---
Likelihood Scale
Likelihood measures the probability that the risk will materialize within the assessment period (typically 12 months).
| Level | Label | Probability | Description | Indicators |
|---|---|---|---|---|
| 1 | Remote | <5% | Extremely unlikely to occur | No known precedent; multiple safeguards in place; theoretical risk only |
| 2 | Unlikely | 5-20% | Could occur but not expected | Historical precedent exists but rare; some controls may have gaps; early warning signs absent |
| 3 | Possible | 20-50% | Reasonable chance of occurring | Similar events have occurred in industry; some warning indicators present; controls partially effective |
| 4 | Likely | 50-80% | More probable than not | Clear warning indicators; known vulnerability; similar events have occurred to organization; regulatory trend toward enforcement |
| 5 | Almost Certain | >80% | Expected to occur | Active threat or demand received; regulatory action announced; deadline approaching with known non-compliance; litigation filed |
Likelihood Assessment Guidance
| Factor | Increases Likelihood | Decreases Likelihood |
|---|---|---|
| Regulatory environment | Active enforcement campaigns; new regulations; industry under scrutiny | Regulatory safe harbor; established compliance program; favorable guidance |
| Counterparty behavior | Aggressive counterparty; history of litigation; demand letters received | Cooperative relationship; mutual interest in resolution; history of settlements |
| Internal controls | Control gaps identified; audit findings unresolved; staff turnover | Strong compliance program; recent audit clearance; trained personnel |
| External events | Market downturn; industry consolidation; political changes | Stable market; favorable court rulings; supportive industry associations |
| Temporal factors | Approaching statute of limitations; regulatory deadline imminent | Long time horizon; no known trigger events |
---
Risk Matrix
LIKELIHOOD
Remote Unlikely Possible Likely Almost Certain
(1) (2) (3) (4) (5)
Critical (5) | 5-Y | 10-O | 15-O | 20-R | 25-R |
| | | | | |
Major (4) | 4-G | 8-Y | 12-O | 16-R | 20-R |
S | | | | | |
E Moderate (3)| 3-G | 6-Y | 9-Y | 12-O | 15-O |
V | | | | | |
E Minor (2)| 2-G | 4-G | 6-Y | 8-Y | 10-O |
R | | | | | |
I Negligible(1)| 1-G | 2-G | 3-G | 4-G | 5-Y |
T | | | | | |
Y
Legend: G=GREEN Y=YELLOW O=ORANGE R=RED
Score = Severity x Likelihood---
Risk Classification Levels
GREEN (Score 1-4) — Accept
| Aspect | Guidance |
|---|---|
| Overall posture | Risk is within acceptable tolerance. No immediate action required. |
| Documentation | Record in risk register with description, score, and rationale. |
| Monitoring | Review quarterly during regular risk register reviews. |
| Ownership | Legal operations or assigned team member. |
| Escalation | Not required unless circumstances change. |
| Reporting | Include in quarterly risk summary for awareness. |
Typical actions:
- Document the risk and rationale for acceptance
- Set a calendar reminder for quarterly review
- Monitor for changes in severity or likelihood triggers
- No dedicated resources required
YELLOW (Score 5-9) — Monitor and Mitigate
| Aspect | Guidance |
|---|---|
| Overall posture | Risk requires active attention. Controls should be in place or planned. |
| Documentation | Detailed risk register entry with mitigation plan and timeline. |
| Monitoring | Monthly review by assigned risk owner. |
| Ownership | Named risk owner from legal team with accountability for mitigation. |
| Escalation | Escalate to senior counsel if score increases or mitigation stalls. |
| Reporting | Monthly update in legal team risk report. |
Typical actions:
- Assign a specific risk owner
- Develop and implement mitigation controls
- Set measurable milestones for risk reduction
- Monitor leading indicators monthly
- Document all mitigation activities
ORANGE (Score 10-15) — Escalate and Plan
| Aspect | Guidance |
|---|---|
| Overall posture | Significant risk requiring senior attention and proactive response. |
| Documentation | Full risk assessment memo with analysis, mitigation plan, and contingency options. |
| Monitoring | Bi-weekly review by senior counsel. |
| Ownership | Senior counsel with executive sponsor. |
| Escalation | Consider engaging outside counsel for specialized expertise. |
| Reporting | Bi-weekly update to legal leadership; include in executive risk summary. |
Typical actions:
- Escalate to senior counsel or deputy general counsel
- Develop comprehensive mitigation plan with resource allocation
- Create contingency plan for risk materialization
- Evaluate outside counsel engagement (see escalation_guide.md)
- Brief relevant business stakeholders
- Consider litigation hold if appropriate
RED (Score 16-25) — Immediate Escalation
| Aspect | Guidance |
|---|---|
| Overall posture | Critical risk requiring immediate response and executive involvement. |
| Documentation | Crisis management memo; board reporting as required. |
| Monitoring | Weekly review (daily during active response). |
| Ownership | General Counsel with board-level oversight. |
| Escalation | Engage outside counsel immediately. Brief board or audit committee. |
| Reporting | Weekly to executive team; board reporting per governance requirements. |
Typical actions:
- Immediate escalation to General Counsel
- Activate crisis management protocol
- Engage outside counsel with appropriate specialization
- Assemble cross-functional response team (legal, comms, business unit)
- Prepare board or audit committee briefing
- Implement litigation hold if applicable
- Establish dedicated communication channel for response team
- Consider disclosure obligations (regulatory, contractual, public)
---
Risk Categories
| Category | Definition | Common Sources |
|---|---|---|
| Contract | Risks arising from contractual obligations, breaches, disputes, or inadequate terms | Vendor agreements, customer contracts, partnership deals, SLAs, indemnification clauses |
| Regulatory | Risks from non-compliance with laws, regulations, or regulatory actions | Industry regulations, data protection laws, securities rules, environmental requirements |
| Litigation | Risks from active or threatened lawsuits, claims, or dispute resolution | Customer disputes, employee claims, competitor actions, product liability, class actions |
| IP | Risks to intellectual property rights or from IP infringement claims | Patent disputes, trade secret misappropriation, trademark conflicts, open-source compliance |
| Data Privacy | Risks related to personal data handling, breaches, or privacy regulation | GDPR, CCPA, data breaches, consent management, cross-border transfers, AI training data |
| Employment | Risks from employment relationships, labor law, or workplace issues | Wrongful termination, discrimination claims, wage disputes, non-compete enforcement, union matters |
| Corporate | Risks related to corporate governance, structure, or transactions | M&A due diligence, board governance, shareholder disputes, corporate restructuring, securities compliance |
---
Risk Assessment Memo Format
A complete risk assessment memo should include the following 10 sections:
| Section | Content |
|---|---|
| 1. Executive Summary | 2-3 sentence overview of key findings and highest-priority risks |
| 2. Risk Matrix | Visual representation of all assessed risks by severity and likelihood |
| 3. Risk Distribution | Count and percentage of risks at each level (GREEN/YELLOW/ORANGE/RED) |
| 4. Category Breakdown | Risks grouped by category with average and maximum scores |
| 5. Top Risks | Ranked list of highest-scoring risks with descriptions and scores |
| 6. Recommended Actions | Specific action items for each ORANGE and RED risk |
| 7. Monitoring Plan | Review frequency and responsible parties per risk level |
| 8. Escalation Summary | Outside counsel needs and escalation decisions |
| 9. Trend Analysis | Comparison with previous assessment (if available) |
| 10. Appendix | Detailed risk register entries and supporting documentation |
---
Risk Register Entry Format
Each risk in the register should capture:
| Field | Description | Required |
|---|---|---|
| Risk ID | Unique identifier (e.g., LR-2026-001) | Yes |
| Description | Clear, specific description of the risk | Yes |
| Category | One of the 7 defined categories | Yes |
| Severity | 1-5 per severity scale | Yes |
| Likelihood | 1-5 per likelihood scale | Yes |
| Score | Calculated: Severity x Likelihood | Auto |
| Level | GREEN/YELLOW/ORANGE/RED | Auto |
| Owner | Named individual responsible for monitoring | Yes (YELLOW+) |
| Mitigation Plan | Specific actions to reduce risk | Yes (YELLOW+) |
| Target Score | Desired score after mitigation | Optional |
| Status | Open / Mitigating / Monitoring / Closed | Yes |
| Date Identified | When the risk was first identified | Yes |
| Last Reviewed | Date of most recent review | Yes |
| Notes | Additional context, updates, or related matters | Optional |
---
Contributing and Mitigating Factors
Contributing Factors (Increase Risk)
| Factor | Impact on Scoring |
|---|---|
| No existing controls or compliance program | +1 to likelihood |
| History of similar incidents | +1 to likelihood |
| Aggressive counterparty or regulator | +1 to likelihood |
| Public visibility or media interest | +1 to severity |
| Precedential risk (could create adverse precedent) | +1 to severity |
| Multi-jurisdictional exposure | +1 to both severity and likelihood |
| Criminal exposure potential | Automatically severity 5 |
| Class action potential | +2 to severity |
Mitigating Factors (Decrease Risk)
| Factor | Impact on Scoring |
|---|---|
| Strong compliance program in place | -1 from likelihood |
| Insurance coverage applicable | -1 from severity (financial dimension only) |
| Favorable legal precedent | -1 from likelihood |
| Cooperative counterparty | -1 from likelihood |
| Strong contractual protections (indemnification, limitation of liability) | -1 from severity |
| Early detection and response | -1 from both severity and likelihood |
| Experienced counsel (internal or external) already engaged | -1 from severity |
Note: Adjustments are advisory. Final scoring should reflect professional judgment. Contributing factors cannot push a score above 5 on either axis, and mitigating factors cannot reduce below 1.
#!/usr/bin/env python3
"""
Legal Risk Report Generator
Generates a formatted risk assessment memo in markdown from a risk register
JSON file. Includes risk matrix visualization, distribution summary,
top risks, recommended actions, and monitoring plan.
Usage:
python risk_report_generator.py --input risk_register.json
python risk_report_generator.py --input risk_register.json --output memo.md
python risk_report_generator.py --input risk_register.json --json
"""
import argparse
import json
import sys
from datetime import datetime
from pathlib import Path
from typing import Any, Dict, List, Optional
SEVERITY_LABELS: Dict[int, str] = {1: "Negligible", 2: "Minor", 3: "Moderate", 4: "Major", 5: "Critical"}
LIKELIHOOD_LABELS: Dict[int, str] = {1: "Remote", 2: "Unlikely", 3: "Possible", 4: "Likely", 5: "Almost Certain"}
ACTIONS: Dict[str, str] = {"GREEN": "Accept and document. Monitor quarterly.", "YELLOW": "Assign owner. Implement controls. Review monthly.", "ORANGE": "Escalate to senior counsel. Develop contingency plan. Consider outside counsel.", "RED": "Immediate escalation. Assemble response team. Engage outside counsel. Report to board."}
MONITORING: Dict[str, str] = {"GREEN": "Quarterly review", "YELLOW": "Monthly review", "ORANGE": "Bi-weekly review", "RED": "Weekly review (daily during active response)"}
def get_risk_level(score: int) -> str:
"""Return risk level color based on score."""
if score <= 4: return "GREEN"
elif score <= 9: return "YELLOW"
elif score <= 15: return "ORANGE"
return "RED"
def get_action(level: str) -> str:
return ACTIONS.get(level, "Unknown")
def get_monitoring_frequency(level: str) -> str:
return MONITORING.get(level, "Unknown")
def load_register(filepath: str) -> List[Dict[str, Any]]:
"""Load risk register from JSON file."""
path = Path(filepath)
if not path.exists():
print(f"Error: File not found: {filepath}", file=sys.stderr)
sys.exit(1)
try:
with open(path, "r") as f:
data = json.load(f)
except json.JSONDecodeError as e:
print(f"Error: Invalid JSON: {e}", file=sys.stderr)
sys.exit(1)
if isinstance(data, dict) and "risks" in data:
return data["risks"]
elif isinstance(data, list):
return data
else:
print("Error: Expected 'risks' array or top-level array", file=sys.stderr)
sys.exit(1)
def enrich_risks(risks: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
"""Calculate scores and levels for each risk."""
enriched: List[Dict[str, Any]] = []
for risk in risks:
sev: int = risk.get("severity", 1)
lik: int = risk.get("likelihood", 1)
score: int = sev * lik
level: str = get_risk_level(score)
enriched.append({
**risk,
"score": score,
"level": level,
"action": get_action(level),
"monitoring": get_monitoring_frequency(level),
"severity_label": SEVERITY_LABELS.get(sev, "Unknown"),
"likelihood_label": LIKELIHOOD_LABELS.get(lik, "Unknown"),
})
enriched.sort(key=lambda r: r["score"], reverse=True)
return enriched
def build_matrix(risks: List[Dict[str, Any]]) -> str:
"""Build ASCII risk matrix showing risk counts per cell."""
cell_counts: Dict[tuple, int] = {}
for risk in risks:
key = (risk["severity"], risk["likelihood"])
cell_counts[key] = cell_counts.get(key, 0) + 1
lines: List[str] = ["```", " L=1 L=2 L=3 L=4 L=5"]
for sev in range(5, 0, -1):
row: List[str] = []
for lik in range(1, 6):
score = sev * lik
level = get_risk_level(score)[0] # G/Y/O/R
count = cell_counts.get((sev, lik), 0)
cell = f"{count}x" if count > 0 else f" {level}"
row.append(f"{score:>2d}({cell})")
lines.append(f" S={sev} {' '.join(row)}")
lines.append(" Legend: G=GREEN Y=YELLOW O=ORANGE R=RED Nx=risk count")
lines.append("```")
return "\n".join(lines)
def build_distribution(risks: List[Dict[str, Any]]) -> str:
"""Build risk distribution summary table."""
dist: Dict[str, int] = {"RED": 0, "ORANGE": 0, "YELLOW": 0, "GREEN": 0}
for risk in risks:
dist[risk["level"]] += 1
total: int = len(risks)
lines: List[str] = [
"| Level | Count | Percentage | Action Required |",
"|-------|-------|------------|-----------------|",
]
for level in ["RED", "ORANGE", "YELLOW", "GREEN"]:
count = dist[level]
pct = round(100 * count / total, 1) if total > 0 else 0.0
action = get_action(level).split(".")[0] + "."
lines.append(f"| {level} | {count} | {pct}% | {action} |")
lines.append(f"| **Total** | **{total}** | **100%** | |")
return "\n".join(lines)
def build_top_risks(risks: List[Dict[str, Any]], limit: int = 10) -> str:
"""Build top risks table."""
top = risks[:limit]
lines: List[str] = [
"| # | Score | Level | Category | Description | Action |",
"|---|-------|-------|----------|-------------|--------|",
]
for i, risk in enumerate(top, 1):
desc = risk.get("description", "N/A")
if len(desc) > 50:
desc = desc[:47] + "..."
lines.append(
f"| {i} | {risk['score']} | {risk['level']} | "
f"{risk.get('category', 'N/A')} | {desc} | {risk['action'].split('.')[0]}. |"
)
return "\n".join(lines)
def build_monitoring_plan(risks: List[Dict[str, Any]]) -> str:
"""Build monitoring plan section."""
lines: List[str] = [
"| Risk Level | Review Frequency | Responsible | Reporting |",
"|------------|-----------------|-------------|-----------|",
"| RED | Weekly (daily during active response) | General Counsel / Outside Counsel | Board + Executive Team |",
"| ORANGE | Bi-weekly | Senior Counsel | Legal Leadership |",
"| YELLOW | Monthly | Assigned Risk Owner | Legal Team |",
"| GREEN | Quarterly | Legal Operations | Internal Log |",
]
return "\n".join(lines)
def build_category_summary(risks: List[Dict[str, Any]]) -> str:
"""Build category breakdown table."""
cats: Dict[str, Dict[str, Any]] = {}
for risk in risks:
cat = risk.get("category", "Other")
if cat not in cats:
cats[cat] = {"count": 0, "total_score": 0, "max_score": 0}
cats[cat]["count"] += 1
cats[cat]["total_score"] += risk["score"]
cats[cat]["max_score"] = max(cats[cat]["max_score"], risk["score"])
sorted_cats = sorted(cats.items(), key=lambda x: x[1]["max_score"], reverse=True)
lines: List[str] = [
"| Category | Count | Avg Score | Max Score |",
"|----------|-------|-----------|-----------|",
]
for cat, data in sorted_cats:
avg = round(data["total_score"] / data["count"], 1)
lines.append(f"| {cat} | {data['count']} | {avg} | {data['max_score']} |")
return "\n".join(lines)
def generate_memo(risks: List[Dict[str, Any]]) -> str:
"""Generate the full risk assessment memo in markdown."""
now = datetime.now().strftime("%Y-%m-%d")
enriched = enrich_risks(risks)
scores = [r["score"] for r in enriched]
avg_score = round(sum(scores) / len(scores), 1) if scores else 0
max_score = max(scores) if scores else 0
sections: List[str] = []
# Header
sections.append(f"# Legal Risk Assessment Memo\n")
sections.append(f"**Date:** {now} ")
sections.append(f"**Total Risks:** {len(enriched)} ")
sections.append(f"**Average Score:** {avg_score} ")
sections.append(f"**Highest Score:** {max_score} ")
sections.append("")
# Executive Summary
red_count = sum(1 for r in enriched if r["level"] == "RED")
orange_count = sum(1 for r in enriched if r["level"] == "ORANGE")
sections.append("## 1. Executive Summary\n")
if red_count > 0:
sections.append(f"**CRITICAL:** {red_count} RED-level risk(s) require immediate escalation and response team activation.\n")
if orange_count > 0:
sections.append(f"**ATTENTION:** {orange_count} ORANGE-level risk(s) require senior counsel review and contingency planning.\n")
if red_count == 0 and orange_count == 0:
sections.append("No RED or ORANGE risks identified. Current risk posture is within acceptable tolerance.\n")
# Risk Matrix
sections.append("## 2. Risk Matrix\n")
sections.append(build_matrix(enriched))
sections.append("")
# Distribution
sections.append("## 3. Risk Distribution\n")
sections.append(build_distribution(enriched))
sections.append("")
# Category Breakdown
sections.append("## 4. Category Breakdown\n")
sections.append(build_category_summary(enriched))
sections.append("")
# Top Risks
sections.append("## 5. Top Risks\n")
sections.append(build_top_risks(enriched))
sections.append("")
# Recommended Actions
sections.append("## 6. Recommended Actions\n")
for i, risk in enumerate(enriched, 1):
if risk["level"] in ("RED", "ORANGE"):
sections.append(f"### Risk {i}: {risk.get('description', 'N/A')}")
sections.append(f"- **Score:** {risk['score']} ({risk['level']})")
sections.append(f"- **Category:** {risk.get('category', 'N/A')}")
sections.append(f"- **Action:** {risk['action']}")
sections.append(f"- **Monitoring:** {risk['monitoring']}")
sections.append("")
# Monitoring Plan
sections.append("## 7. Monitoring Plan\n")
sections.append(build_monitoring_plan(enriched))
sections.append("")
# Escalation Summary
sections.append("## 8. Escalation Summary\n")
if red_count > 0:
sections.append("- **Outside counsel engagement:** MANDATORY for RED-level risks")
if orange_count > 0:
sections.append("- **Senior counsel review:** REQUIRED for ORANGE-level risks")
sections.append(f"- **Next review date:** Schedule within {'1 week' if red_count > 0 else '2 weeks' if orange_count > 0 else '1 month'}")
sections.append("")
# Footer
sections.append("---\n")
sections.append(f"*Generated by Legal Risk Report Generator on {now}*")
return "\n".join(sections)
def generate_json_metadata(risks: List[Dict[str, Any]]) -> Dict[str, Any]:
"""Generate JSON metadata about the report."""
enriched = enrich_risks(risks)
dist: Dict[str, int] = {"RED": 0, "ORANGE": 0, "YELLOW": 0, "GREEN": 0}
for r in enriched:
dist[r["level"]] += 1
scores = [r["score"] for r in enriched]
return {
"generated": datetime.now().isoformat(),
"total_risks": len(enriched),
"distribution": dist,
"average_score": round(sum(scores) / len(scores), 1) if scores else 0,
"max_score": max(scores) if scores else 0,
"requires_escalation": dist["RED"] > 0,
"risks": enriched,
}
def main() -> None:
parser = argparse.ArgumentParser(
description="Legal Risk Report Generator — generates risk assessment memos"
)
parser.add_argument("--input", required=True, help="Path to risk register JSON file")
parser.add_argument("--output", type=str, help="Save memo to file (markdown)")
parser.add_argument("--json", action="store_true", help="Output report metadata as JSON")
args = parser.parse_args()
risks = load_register(args.input)
if not risks:
print("Error: No risks found in input file", file=sys.stderr)
sys.exit(1)
if args.json:
metadata = generate_json_metadata(risks)
print(json.dumps(metadata, indent=2))
else:
memo = generate_memo(risks)
if args.output:
Path(args.output).write_text(memo)
print(f"Memo written to {args.output}")
else:
print(memo)
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
Legal Risk Scorer
Calculates legal risk scores using a 5x5 Severity x Likelihood matrix.
Assigns GREEN/YELLOW/ORANGE/RED levels with recommended actions.
Supports single-risk and batch mode from JSON input.
Usage:
python risk_scorer.py --severity 4 --likelihood 3 --category "Contract" --description "SLA breach"
python risk_scorer.py --input risks.json --json
python risk_scorer.py --severity 5 --likelihood 4 --category "Litigation" --description "Patent claim" --json
"""
import argparse
import json
import sys
from datetime import datetime
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple
SEVERITY_LABELS: Dict[int, str] = {1: "Negligible", 2: "Minor", 3: "Moderate", 4: "Major", 5: "Critical"}
SEVERITY_EXPOSURE: Dict[int, str] = {1: "<0.1% revenue", 2: "0.1-1% revenue", 3: "1-5% revenue", 4: "5-15% revenue", 5: ">15% revenue"}
LIKELIHOOD_LABELS: Dict[int, str] = {1: "Remote", 2: "Unlikely", 3: "Possible", 4: "Likely", 5: "Almost Certain"}
LIKELIHOOD_PROBABILITY: Dict[int, str] = {1: "<5%", 2: "5-20%", 3: "20-50%", 4: "50-80%", 5: ">80%"}
VALID_CATEGORIES: List[str] = [
"Contract", "Regulatory", "Litigation", "IP",
"Data Privacy", "Employment", "Corporate",
]
def get_risk_level(score: int) -> str:
"""Return risk level color based on score."""
if score <= 4:
return "GREEN"
elif score <= 9:
return "YELLOW"
elif score <= 15:
return "ORANGE"
else:
return "RED"
def get_recommended_action(level: str) -> str:
"""Return recommended action for a risk level."""
actions: Dict[str, str] = {
"GREEN": "Accept — document risk, monitor quarterly, no immediate action required",
"YELLOW": "Monitor — assign risk owner, implement controls, review monthly",
"ORANGE": "Mitigate — escalate to senior counsel, develop contingency plan, consider outside counsel",
"RED": "Escalate — immediate escalation, assemble response team, engage outside counsel, board reporting",
}
return actions.get(level, "Unknown")
def validate_risk(risk: Dict[str, Any]) -> Tuple[bool, str]:
"""Validate a risk entry has required fields and valid values."""
required = ["severity", "likelihood", "category", "description"]
for field in required:
if field not in risk:
return False, f"Missing required field: {field}"
sev = risk["severity"]
lik = risk["likelihood"]
if not isinstance(sev, int) or sev < 1 or sev > 5:
return False, f"Severity must be integer 1-5, got: {sev}"
if not isinstance(lik, int) or lik < 1 or lik > 5:
return False, f"Likelihood must be integer 1-5, got: {lik}"
cat = risk["category"]
if cat not in VALID_CATEGORIES:
return False, f"Invalid category '{cat}'. Valid: {', '.join(VALID_CATEGORIES)}"
if not risk["description"].strip():
return False, "Description cannot be empty"
return True, ""
def score_risk(risk: Dict[str, Any]) -> Dict[str, Any]:
"""Score a single risk and return enriched result."""
sev: int = risk["severity"]
lik: int = risk["likelihood"]
score: int = sev * lik
level: str = get_risk_level(score)
return {
"description": risk["description"],
"category": risk["category"],
"severity": sev,
"severity_label": SEVERITY_LABELS[sev],
"severity_exposure": SEVERITY_EXPOSURE[sev],
"likelihood": lik,
"likelihood_label": LIKELIHOOD_LABELS[lik],
"likelihood_probability": LIKELIHOOD_PROBABILITY[lik],
"score": score,
"level": level,
"recommended_action": get_recommended_action(level),
}
def generate_summary(scored_risks: List[Dict[str, Any]]) -> Dict[str, Any]:
"""Generate summary statistics for a list of scored risks."""
total: int = len(scored_risks)
if total == 0:
return {"total": 0, "distribution": {}, "average_score": 0.0, "max_score": 0}
distribution: Dict[str, int] = {"GREEN": 0, "YELLOW": 0, "ORANGE": 0, "RED": 0}
scores: List[int] = []
for risk in scored_risks:
distribution[risk["level"]] += 1
scores.append(risk["score"])
avg_score: float = sum(scores) / total
max_score: int = max(scores)
max_risk = next(r for r in scored_risks if r["score"] == max_score)
return {
"total": total,
"distribution": distribution,
"average_score": round(avg_score, 1),
"max_score": max_score,
"highest_risk": max_risk["description"],
"red_count": distribution["RED"],
"orange_count": distribution["ORANGE"],
"requires_escalation": distribution["RED"] > 0,
}
def format_human_single(result: Dict[str, Any]) -> str:
"""Format a single risk result for human-readable output."""
lines: List[str] = [
"=" * 60,
"LEGAL RISK ASSESSMENT",
"=" * 60,
"",
f"Description: {result['description']}",
f"Category: {result['category']}",
"",
f"Severity: {result['severity']} — {result['severity_label']} ({result['severity_exposure']})",
f"Likelihood: {result['likelihood']} — {result['likelihood_label']} ({result['likelihood_probability']})",
"",
f"Risk Score: {result['score']} / 25",
f"Risk Level: {result['level']}",
"",
f"Action: {result['recommended_action']}",
"",
"=" * 60,
]
return "\n".join(lines)
def format_human_batch(scored_risks: List[Dict[str, Any]], summary: Dict[str, Any]) -> str:
"""Format batch results for human-readable output."""
lines: List[str] = [
"=" * 70,
"LEGAL RISK REGISTER — SCORED RESULTS",
f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')}",
"=" * 70,
"",
]
# Summary
lines.append("SUMMARY")
lines.append("-" * 40)
lines.append(f" Total Risks: {summary['total']}")
lines.append(f" Average Score: {summary['average_score']}")
lines.append(f" Highest Score: {summary['max_score']}")
lines.append("")
lines.append(" Distribution:")
for level in ["RED", "ORANGE", "YELLOW", "GREEN"]:
count = summary["distribution"][level]
bar = "#" * count
lines.append(f" {level:8s} {count:3d} {bar}")
lines.append("")
if summary["requires_escalation"]:
lines.append(" *** ESCALATION REQUIRED: RED-level risks detected ***")
lines.append("")
# Individual risks sorted by score descending
lines.append("RISKS (sorted by score, highest first)")
lines.append("-" * 70)
for i, risk in enumerate(scored_risks, 1):
lines.append(f"\n [{i}] {risk['description']}")
lines.append(f" Category: {risk['category']}")
lines.append(f" Severity: {risk['severity']} ({risk['severity_label']})")
lines.append(f" Likelihood: {risk['likelihood']} ({risk['likelihood_label']})")
lines.append(f" Score: {risk['score']} Level: {risk['level']}")
lines.append(f" Action: {risk['recommended_action']}")
lines.append("")
lines.append("=" * 70)
return "\n".join(lines)
def load_risks_from_file(filepath: str) -> List[Dict[str, Any]]:
"""Load risks from a JSON file."""
path = Path(filepath)
if not path.exists():
print(f"Error: File not found: {filepath}", file=sys.stderr)
sys.exit(1)
try:
with open(path, "r") as f:
data = json.load(f)
except json.JSONDecodeError as e:
print(f"Error: Invalid JSON in {filepath}: {e}", file=sys.stderr)
sys.exit(1)
if isinstance(data, dict) and "risks" in data:
return data["risks"]
elif isinstance(data, list):
return data
else:
print("Error: JSON must contain a 'risks' array or be a top-level array", file=sys.stderr)
sys.exit(1)
def main() -> None:
parser = argparse.ArgumentParser(
description="Legal Risk Scorer — 5x5 Severity x Likelihood matrix"
)
parser.add_argument("--severity", type=int, choices=range(1, 6), help="Severity rating (1-5)")
parser.add_argument("--likelihood", type=int, choices=range(1, 6), help="Likelihood rating (1-5)")
parser.add_argument("--category", type=str, help=f"Risk category: {', '.join(VALID_CATEGORIES)}")
parser.add_argument("--description", type=str, help="Risk description")
parser.add_argument("--input", type=str, help="JSON file with multiple risks (batch mode)")
parser.add_argument("--json", action="store_true", help="Output in JSON format")
args = parser.parse_args()
# Determine mode
if args.input:
# Batch mode
risks = load_risks_from_file(args.input)
scored: List[Dict[str, Any]] = []
for idx, risk in enumerate(risks):
valid, msg = validate_risk(risk)
if not valid:
print(f"Error in risk #{idx + 1}: {msg}", file=sys.stderr)
sys.exit(1)
scored.append(score_risk(risk))
# Sort by score descending
scored.sort(key=lambda r: r["score"], reverse=True)
summary = generate_summary(scored)
if args.json:
output = {"risks": scored, "summary": summary, "generated": datetime.now().isoformat()}
print(json.dumps(output, indent=2))
else:
print(format_human_batch(scored, summary))
elif args.severity and args.likelihood and args.category and args.description:
# Single risk mode
risk = {
"severity": args.severity,
"likelihood": args.likelihood,
"category": args.category,
"description": args.description,
}
valid, msg = validate_risk(risk)
if not valid:
print(f"Error: {msg}", file=sys.stderr)
sys.exit(1)
result = score_risk(risk)
if args.json:
print(json.dumps(result, indent=2))
else:
print(format_human_single(result))
else:
parser.error(
"Provide either --input for batch mode, or all of "
"--severity, --likelihood, --category, --description for single risk mode"
)
if __name__ == "__main__":
main()
Related skills
FAQ
What scoring model does it use?
A quantitative 5x5 Severity x Likelihood matrix that produces a color-coded level (GREEN/YELLOW/ORANGE/RED) and a recommended action.
Is this legal advice?
No. The skill is explicitly experimental, for educational purposes only, and not legal advice.