
Tech Contract Negotiation
- 45 installs
- 451 repo stars
- Updated July 21, 2026
- borghei/claude-skills
tech-contract-negotiation is a Claude skill that provides negotiation frameworks and scoring tools for technology services and B2B contracts.
About
Tech-contract-negotiation provides frameworks for negotiating technology services agreements, B2B contracts, and professional services deals. It offers a Three-Position Framework, five-tier objection handling, regulatory leverage arguments, and concession roadmaps. A legal, procurement, or deal-desk user runs its scripts to classify contract provisions and score deal complexity.
- Negotiation frameworks for technology services and B2B contracts
- Three-Position Framework (provider/balanced/client) plus 5-tier deal-size tactics
- Python position analyzer and deal complexity scorer across 7 dimensions
Tech Contract Negotiation by the numbers
- 45 all-time installs (skills.sh)
- Ranked #1,674 of 3,282 Productivity & Planning skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
tech-contract-negotiation capabilities & compatibility
- Capabilities
- contract negotiation · deal scoring · objection handling
- Use cases
- documentation · data analysis
- Pricing
- Free
What tech-contract-negotiation says it does
Provides a Three-Position Framework (provider-favorable, balanced, client-favorable) for every major provision, Deal-Size Tactics across 5 tiers, Five-Tier Objection Handling, regulatory leverage argu
Takes deal parameters and scores complexity across 7 dimensions.
npx skills add https://github.com/borghei/claude-skills --skill tech-contract-negotiationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 45 |
|---|---|
| repo stars | ★ 451 |
| Last updated | July 21, 2026 |
| Repository | borghei/claude-skills ↗ |
What it does
Negotiate technology and B2B service contracts using position frameworks, objection handling, and deal-complexity scoring.
Who is it for?
Legal counsel, procurement leads, and deal-desk teams negotiating tech contracts from $100K to $10M+.
Skip if: Situations needing formal legal advice (marked experimental) or non-technology consumer contracts.
When should I use this skill?
Reviewing or negotiating a technology services agreement, SLA, or professional services deal.
What you get
A position map, deal-tier estimate, and objection/concession plan for a negotiation.
- position map
- deal complexity score
- objection responses
By the numbers
- Three-Position Framework
- 5 deal-size tiers
- 7 complexity dimensions
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.
Tech Contract Negotiation Skill
Overview
Production-ready negotiation toolkit for technology services agreements, professional services contracts, and B2B transactions. Provides a Three-Position Framework (provider-favorable, balanced, client-favorable) for every major provision, Deal-Size Tactics across 5 tiers, Five-Tier Objection Handling, regulatory leverage arguments, and concession roadmaps. Designed for legal counsel, procurement leads, and sales/deal desk teams negotiating technology contracts from $100K to $10M+.
Table of Contents
- Tools
- Reference Guides
- Workflows
- Troubleshooting
- Success Criteria
- Scope & Limitations
- Anti-Patterns
- Tool Reference
Tools
1. Negotiation Position Analyzer (scripts/negotiation_position_analyzer.py)
Analyzes contract text and classifies each provision as provider-favorable, balanced, or client-favorable based on keyword patterns and structural analysis. Generates a position map and recommended negotiation priorities.
# Analyze a contract draft
python scripts/negotiation_position_analyzer.py contract_draft.txt
# JSON output for integration
python scripts/negotiation_position_analyzer.py contract_draft.txt --json
# Analyze from a specific party's perspective
python scripts/negotiation_position_analyzer.py contract_draft.txt --perspective client2. Deal Complexity Scorer (scripts/deal_complexity_scorer.py)
Takes deal parameters and scores complexity across 7 dimensions. Recommends deal tier (1-5), expected timeline, number of rounds, and key focus areas.
# Score deal complexity from parameters file
python scripts/deal_complexity_scorer.py deal_params.json
# JSON output
python scripts/deal_complexity_scorer.py deal_params.json --json
# Override deal value for quick what-if
python scripts/deal_complexity_scorer.py deal_params.json --deal-value 5000000Reference Guides
| Reference | Purpose |
|---|---|
references/three_position_framework.md | Provider/balanced/client positions for 5 major provisions with deal-size tactics |
references/objection_handling.md | Five-tier objection methodology, prediction matrix, communication templates |
references/regulatory_leverage.md | GDPR, DORA, NIS2, SOX leverage arguments, concession roadmap, industry considerations |
Workflows
Workflow 1: Pre-Negotiation Assessment
1. Classify the deal -- Run deal_complexity_scorer.py with deal parameters to determine tier, timeline, and focus areas 2. Analyze the draft -- Run negotiation_position_analyzer.py on the initial contract to map current positions 3. Identify gaps -- Compare position map against your target positions from three_position_framework.md 4. Prepare objection responses -- Review objection_handling.md for predicted objections based on client type 5. Map regulatory leverage -- Identify applicable frameworks from regulatory_leverage.md
Workflow 2: Active Negotiation
1. Open with position -- Use the Opening Position Statement template from objection_handling.md 2. Handle pushback -- Apply Five-Tier Objection Handling: Acknowledge, Market Context, Business Rationale, Alternatives, Bright Lines 3. Track concessions -- Follow the 4-tier concession roadmap (Easy Gives through Bright Lines) 4. Re-analyze after redlines -- Run negotiation_position_analyzer.py on each revised draft 5. Close -- Use Closing the Deal template; verify no Bright Lines were crossed
Workflow 3: Deal Review and Approval
1. Final position analysis -- Run analyzer on execution-ready draft 2. Complexity validation -- Confirm final terms match expected deal tier parameters 3. Regulatory check -- Verify all mandatory regulatory provisions are present 4. Document concessions -- Record what was traded and why for future negotiations 5. Approval package -- Combine position map, complexity score, and concession log
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| Analyzer flags everything as "provider-favorable" | Input is a vendor's first draft (expected behavior) | Use --perspective provider to flip the analysis; compare against balanced baseline |
| Complexity scorer returns Tier 5 for a small deal | High regulatory or multi-jurisdictional flags triggered | Review the regulatory and jurisdiction inputs; lower if overestimated |
| Position map shows no IP provisions detected | Contract uses non-standard terminology for IP clauses | Check for terms like "work product," "deliverables ownership," or "background IP" manually |
| Deal timeline estimate seems too short | Scorer does not account for internal approval delays | Add internal review buffer (typically 1-2 weeks per approval level) to the estimated timeline |
| Objection framework doesn't cover a specific pushback | Counterparty raised an atypical demand | Start with Acknowledge tier; frame using closest Market Context example; escalate to Bright Lines if needed |
| Regulatory leverage arguments rejected as irrelevant | Framework doesn't apply to counterparty's jurisdiction | Verify which regulations actually bind each party; remove inapplicable leverage points |
Success Criteria
- Position Accuracy: Analyzer correctly classifies 85%+ of provisions when validated against expert review
- Deal Tier Alignment: Complexity scorer tier matches actual negotiation effort within one tier for 90% of deals
- Negotiation Efficiency: Average number of negotiation rounds reduced by 30% compared to ad-hoc approach
- Concession Tracking: 100% of material concessions documented with rationale and trade-off analysis
- Bright Line Protection: Zero instances of crossing defined Bright Lines without executive escalation and approval
- Regulatory Coverage: All applicable regulatory provisions identified and addressed in 95%+ of contracts
- Time-to-Signature: Deals close within estimated timeline +/- 20% for 80% of negotiations
Scope & Limitations
This skill covers:
- Technology services agreements, SaaS subscriptions, professional services contracts, and B2B licensing deals
- Negotiation position analysis for liability, IP, payment, SLA, and warranty provisions
- Deal complexity scoring with tier-based recommendations for timeline, rounds, and focus areas
- Regulatory leverage for GDPR, DORA, NIS2, and SOX in technology contract contexts
- Objection handling frameworks and communication templates for common negotiation scenarios
This skill does NOT cover:
- Employment agreements, M&A transactions, real estate contracts, or consumer-facing terms of service
- Jurisdiction-specific legal advice or attorney-client privileged analysis (this is a framework, not legal counsel)
- Contract drafting from scratch (assumes an existing draft to analyze and negotiate)
- Litigation strategy, dispute resolution beyond contract clauses, or enforcement proceedings
- Price negotiation tactics for commodity purchases or non-technology procurement
Anti-Patterns
| Anti-Pattern | Why It Fails | Better Approach |
|---|---|---|
| Treating every provision as a Bright Line | Counterparty disengages when everything is non-negotiable | Classify provisions into 4 concession tiers; trade Easy Gives early to build goodwill |
| Skipping deal complexity assessment | Under-preparing for complex deals or over-preparing for simple ones | Always run complexity scorer first to calibrate effort, timeline, and approval requirements |
| Using regulatory leverage when the regulation doesn't apply | Destroys credibility and trust with informed counterparties | Verify applicability before citing any regulation; use the genuine-vs-preference test from the framework |
| Accepting "this is our standard template" at face value | Every template is negotiable; accepting defaults leaves value on the table | Analyze the "standard" template with the position analyzer to identify moveable provisions |
| Negotiating provisions in isolation | Conceding on SLAs without linking to liability caps creates exposure | Use the Three-Position Framework holistically; link related provisions (SLAs to credits to liability) |
Tool Reference
scripts/negotiation_position_analyzer.py
Analyze contract text and classify provisions by negotiation position.
usage: negotiation_position_analyzer.py [-h] [--json] [--perspective {provider,client}]
input_file
positional arguments:
input_file Path to contract text file (.txt or .md)
options:
-h, --help Show help message and exit
--json Output results as JSON
--perspective {provider,client}
Analysis perspective (default: client)Outputs: Provision-by-provision position classification (provider-favorable / balanced / client-favorable), overall position score, position distribution summary, and prioritized negotiation recommendations.
scripts/deal_complexity_scorer.py
Score deal complexity across 7 dimensions and recommend negotiation parameters.
usage: deal_complexity_scorer.py [-h] [--json] [--deal-value DEAL_VALUE]
input_file
positional arguments:
input_file Path to JSON file with deal parameters
options:
-h, --help Show help message and exit
--json Output results as JSON
--deal-value DEAL_VALUE
Override deal value in dollarsOutputs: 7-dimension complexity breakdown (value, regulatory, technical, multi-party, duration, strategic importance, IP sensitivity), composite score, deal tier (1-5), recommended timeline, expected negotiation rounds, and key focus areas.
Objection Handling Framework for Technology Contract Negotiation
Five-tier objection handling methodology with real examples, prediction matrices by client type, communication templates, and common negotiation mistakes.
Table of Contents
Five-Tier Methodology
Every objection response follows the same five-tier escalation. Start at Tier 1 and escalate only as needed. Most objections resolve at Tier 2 or 3.
Tier 1: Acknowledge
Purpose: Demonstrate that you heard and understand the concern. Build rapport. Never dismiss.
Technique: Restate the objection in your own words. Show you understand the business reason behind it.
Example:
"I understand your concern about the liability cap. Given that this service will process your customer payment data, it's reasonable that you'd want stronger protection against potential data breaches."
When to use: Always. Every objection response starts here.
| Do | Don't |
|---|---|
| Restate the specific concern | Jump straight to your counter-position |
| Reference the business context | Say "that's standard" or "everyone signs this" |
| Show genuine understanding | Minimize or dismiss the concern |
Tier 2: Market Context
Purpose: Frame your position within industry norms and market practice. Reduce the sense that your terms are unusual.
Technique: Reference market standards, industry benchmarks, and comparable deals without revealing specific counterparty names.
Example:
"The liability cap we've proposed -- 12 months of fees -- is consistent with what we see across the enterprise SaaS market. Gartner's most recent report on cloud contracts notes that 12-24 month fee caps represent the standard range for services at this tier."
When to use: When the objection targets your position as unreasonable or non-standard.
| Provision | Market Context Data Points |
|---|---|
| Liability cap | 12-24 months fees is standard SaaS range |
| Uptime SLA | 99.9% is standard; 99.99% is premium/enterprise |
| Payment terms | Net 30 is standard B2B; Net 60+ is enterprise |
| Warranty period | 12 months is standard; 90 days for bug fixes |
| IP ownership | Provider retains platform IP; client owns bespoke is standard |
Tier 3: Business Rationale
Purpose: Explain why your position exists from a business perspective. Connect terms to pricing, service quality, or sustainability.
Technique: Show the economic logic. Link specific terms to the deal economics.
Example:
"The reason we cap liability at 12 months of fees is that our pricing model is built on that risk allocation. If we were to accept unlimited liability for consequential damages, we'd need to purchase additional insurance coverage, which would increase the annual fee by approximately 15-20%. We're happy to discuss that trade-off if it's important to you."
When to use: When market context alone doesn't resolve the objection. This tier is the most effective for educated counterparties.
Tier 4: Alternatives
Purpose: Offer concrete trade-offs. Show flexibility without conceding your core position.
Technique: Present 2-3 alternative structures that address the concern while protecting your interests.
Example:
"I'd like to propose three alternatives that address your liability concern:
1. Super-cap structure: We maintain the 12-month general cap but create a separate, higher cap (2x annual fees) specifically for data breach and confidentiality claims.
2. Insurance backstop: We increase our cyber insurance to $10M and name your company as an additional insured, while keeping the contractual cap at 12 months.
3. Tiered pricing: We remove the cap for data breach claims but adjust the annual fee by 12% to reflect the additional risk we're assuming."
When to use: When the counterparty has a legitimate business need that your standard position doesn't address.
Tier 5: Bright Lines
Purpose: Clearly communicate non-negotiable positions with respect and finality.
Technique: State the bright line, explain why it exists, and confirm what you can do within those boundaries.
Example:
"I appreciate the discussion on this point, and I want to be transparent: unlimited liability without any cap is a position we cannot accept. It's a board-level policy that applies across all our enterprise agreements. What I can do is work with you on the super-cap structure to ensure meaningful protection for data breach and IP claims. Would that approach work for you?"
When to use: Only when a true organizational constraint exists. Overuse destroys credibility.
| Typical Bright Lines | Rationale |
|---|---|
| No unlimited liability (general) | Existential risk to provider; uninsurable |
| No penalties exceeding 100% of fees | Makes the deal unprofitable |
| No assignment of background IP | Core platform value; affects all clients |
| No audit rights into source code (non-escrow) | Trade secret protection |
| No unilateral termination for convenience without payment | Revenue certainty |
Objection Prediction Matrix
Predict which objections to expect based on client type and industry sector.
By Client Type
| Provision | Enterprise (F500) | Mid-Market | Startup | Government |
|---|---|---|---|---|
| Liability cap | Push for uncapped/high cap | Accept balanced cap | Often accept standard | Uncapped; statutory requirements |
| IP ownership | Demand bespoke ownership | Negotiate per project | Flexible | Government owns all |
| Payment terms | Net 60-90 | Net 30-45 | Net 30; may need flexibility | Net 30-60; PO-based |
| SLAs | 99.99% with financial penalties | 99.9% with service credits | 99.9% acceptable | Strict SLAs; liquidated damages |
| Warranties | Extended; fitness for purpose | Standard 12-month | Flexible | Extended; compliance warranties |
| Data protection | GDPR-plus; DPA required | Standard DPA | Basic compliance | Sovereignty requirements |
| Audit rights | Full audit rights; annual minimum | Annual audit right | Rarely requested | Unlimited audit rights |
| Termination | Termination for convenience | Mutual convenience | Mutual convenience | Government convenience; no provider convenience |
By Industry Sector
| Provision | Financial Services | Healthcare | Technology | Manufacturing | Government |
|---|---|---|---|---|---|
| Top concern | Data security, regulatory | HIPAA, PHI | IP ownership | Supply chain | Sovereignty |
| Liability focus | Regulatory fines coverage | PHI breach liability | IP infringement | Product liability | Statutory compliance |
| Regulatory leverage | DORA, SOX, PCI DSS | HIPAA, HITECH | GDPR (data) | Product safety | FedRAMP, ITAR |
| SLA priority | Availability, RPO/RTO | Uptime, data integrity | Performance, scalability | Delivery timelines | Availability, accessibility |
| Expected difficulty | High | High | Moderate | Moderate | Very High |
| Typical rounds | 5-8 | 4-6 | 3-5 | 3-4 | 8-12 |
Communication Templates
Template 1: Opening Position Statement
Use when presenting your initial position on a marked-up contract.
Subject: [Company] / [Provider] -- Contract Discussion: Initial Position
>
Dear [Name],
>
Thank you for sharing the draft [Agreement Type]. We've completed our review and have a few areas where we'd like to discuss alignment.
>
Summary of our position:
We're aligned on the majority of the terms. We've identified [N] provisions where we'd like to discuss adjustments, and [M] areas where we have questions for clarification.
>
Key discussion items:
1. [Provision 1] -- [One-sentence summary of your position]
2. [Provision 2] -- [One-sentence summary of your position]
3. [Provision 3] -- [One-sentence summary of your position]
>
We've attached a marked-up version with our proposed changes. We're available to discuss these at your convenience and are confident we can reach terms that work for both parties.
>
Best regards,
[Name]
Template 2: Responding to Aggressive Demands
Use when the counterparty's position is significantly more aggressive than expected.
Dear [Name],
>
Thank you for sharing your position on [specific provision]. I want to make sure I fully understand the business concern driving this request.
>
As I understand it, your primary concern is [restate their concern]. Is that accurate?
>
For context, the position we've proposed is consistent with market practice for [deal type] of this size and scope. [Cite specific market data point if available.]
>
That said, I recognize that your [specific business context -- e.g., regulatory environment, service criticality] may warrant a different approach. I'd like to propose we schedule a call to discuss [2-3 specific alternatives you can offer].
>
Would [date/time] work for a 30-minute discussion?
>
Best regards,
[Name]
Template 3: Proposing Trade-Offs
Use when offering a concession in exchange for something.
Dear [Name],
>
Following our discussion on [date], I'd like to propose a package that addresses both parties' priorities:
>
We're prepared to:
- [Concession 1 -- be specific]
- [Concession 2 -- be specific]
>
In exchange, we'd ask for:
- [Counter-request 1 -- be specific]
- [Counter-request 2 -- be specific]
>
This approach addresses your concern about [their key issue] while ensuring [your key interest] is protected. I believe this represents a fair balance.
>
Shall we schedule a call to discuss, or would you prefer to respond in writing?
>
Best regards,
[Name]
Template 4: Drawing Bright Lines
Use when communicating a non-negotiable position.
Dear [Name],
>
I appreciate the constructive dialogue we've had on [provision]. I want to be transparent about where we stand.
>
After careful internal review, [specific position] represents a firm policy position that we apply consistently across all our [enterprise/strategic] agreements. This is driven by [brief rationale -- e.g., insurance constraints, board policy, regulatory requirements].
>
What I can offer is [maximum flexibility within your constraint]. Specifically:
- [Alternative 1]
- [Alternative 2]
>
I'm confident one of these approaches can address the substance of your concern. I'd welcome the opportunity to discuss which option works best for your team.
>
Best regards,
[Name]
Template 5: Closing the Deal
Use when agreement is near and you want to lock down remaining items.
Dear [Name],
>
Great progress on our discussions. I believe we're very close to final terms. Here's my summary of where we stand:
>
Agreed items: [List resolved provisions]
>
Remaining items (proposed resolution):
1. [Item] -- We propose [specific resolution]
2. [Item] -- We propose [specific resolution]
>
If you're aligned on these final points, I'd suggest we move to execution copies. Our target is to have signatures by [date].
>
Please confirm whether you're comfortable with the above, or let me know if there are any remaining concerns I've missed.
>
Best regards,
[Name]
Common Negotiation Mistakes
| # | Mistake | Impact | Fix |
|---|---|---|---|
| 1 | Opening with your bottom line | No room to negotiate; counterparty assumes there's more | Start with your aspirational position (one tier more favorable than your target) |
| 2 | Negotiating provisions in isolation | Conceding on SLAs without linking to liability creates exposure | Always negotiate related provisions as a package (SLAs + credits + liability) |
| 3 | Treating "standard template" as non-negotiable | Leaves value on the table; every template is negotiable | Analyze the template objectively; mark up based on your position, not theirs |
| 4 | Making concessions without getting something in return | Sets expectation of one-way movement; weakens future positions | Always frame concessions as trades: "We can move on X if you can move on Y" |
| 5 | Escalating to Bright Lines too early | Credibility damage; counterparty stops engaging | Reserve Bright Lines for truly non-negotiable items; use Alternatives tier first |
| 6 | Failing to document concession rationale | Loses institutional knowledge; repeats mistakes | Maintain a concession log: what was traded, why, and what was received |
| 7 | Letting internal stakeholders negotiate directly | Inconsistent positions; unauthorized concessions; loss of control | Single point of contact for all external communication; brief stakeholders separately |
| 8 | Ignoring the counterparty's internal constraints | Demands that their negotiator cannot deliver create deadlock | Ask: "Is there a way to structure this that works within your approval framework?" |
Regulatory Leverage in Technology Contract Negotiation
How to use regulatory requirements as negotiation leverage, with framework-specific arguments, the genuine-vs-preference test, concession roadmap, and industry-specific considerations.
Table of Contents
- Overview
- GDPR / Data Protection
- DORA / Financial Services
- NIS2 / Critical Infrastructure
- SOX / Financial Reporting
- The Genuine-vs-Preference Test
- Concession Roadmap
- Industry-Specific Considerations
Overview
Regulatory requirements create legitimate, evidence-backed negotiation leverage. When a client's industry mandates specific contractual provisions, those requirements are non-discretionary -- the provider must accommodate them or lose the deal. However, distinguishing genuine regulatory mandates from risk preferences presented as mandates is critical to maintaining credibility.
Key Principle: Use regulation as a framework for discussion, not a weapon. Informed counterparties will challenge dubious regulatory claims, destroying trust.
GDPR / Data Protection
Client Demands with Justification
| Demand | GDPR Basis | Article |
|---|---|---|
| Data Processing Agreement (DPA) | Mandatory for controller-processor relationships | Art. 28 |
| Sub-processor notification and approval | Controller must authorize sub-processing | Art. 28(2) |
| Data breach notification within 72 hours | Controller must notify supervisory authority | Art. 33 |
| Right to audit processor | Controller must ensure compliance verification | Art. 28(3)(h) |
| Data deletion on termination | Processor must delete/return data | Art. 28(3)(g) |
| Data transfer impact assessment | Required for transfers outside EEA | Art. 46 |
| Records of processing activities | Both controller and processor obligations | Art. 30 |
| Data Protection Impact Assessment support | Processor must assist controller | Art. 35-36 |
Provider Responses
| Demand | Reasonable Response | Pushback Threshold |
|---|---|---|
| DPA | Accept; use your standard DPA template | Never push back -- it's mandatory |
| Sub-processor approval | Right to object with switching assistance | Blanket veto right is excessive |
| Breach notification | 72 hours to client; client handles authority | 24-hour notification is aggressive but common |
| Audit rights | Annual audit right; accept SOC 2 as alternative | Unlimited on-site access is excessive |
| Data deletion | 30-day deletion with certification | Immediate deletion may not be technically feasible |
| Data transfers | Standard Contractual Clauses + TIA | Requiring data residency may increase costs |
| DPIA support | Reasonable assistance at provider's cost | Client cannot outsource entire DPIA to provider |
Genuine vs. Preference Assessment
| Claim | Genuine Requirement | Risk Preference |
|---|---|---|
| "We need a DPA" | Yes -- Art. 28 mandate | N/A |
| "We need 24-hour breach notification" | Partially -- 72 hours is the legal requirement | 24 hours is preference beyond legal minimum |
| "We need data residency in EU" | Depends -- adequate if SCCs are in place | Preference unless specific national law requires it |
| "We need to approve all sub-processors" | Yes -- Art. 28(2) requires authorization | General authorization with objection right is sufficient |
DORA / Financial Services
Client Demands with Justification
| Demand | DORA Basis | Article |
|---|---|---|
| ICT risk management provisions | Financial entities must manage ICT third-party risk | Art. 28 |
| Contractual right to audit ICT provider | Mandatory for critical ICT providers | Art. 28(2)(e) |
| Exit strategy and transition plan | Required in all ICT service contracts | Art. 28(2)(h) |
| Sub-contracting notification | Must be notified of material sub-contracting | Art. 28(2)(a) |
| Incident reporting support | ICT providers must report major incidents | Art. 19 |
| Business continuity testing | Threat-led penetration testing requirements | Art. 26-27 |
| Regulatory access | Regulators must be able to access/audit provider | Art. 28(2)(e) |
| Service level definitions | Clear performance metrics required | Art. 28(2)(b) |
Provider Responses
| Demand | Reasonable Response | Pushback Threshold |
|---|---|---|
| Audit rights | Annual audit; pooled audit model for efficiency | Unlimited audits at provider cost is excessive |
| Exit plan | 12-month transition assistance; data portability | Mandating specific competitor migration is excessive |
| Incident reporting | 24-hour notification for major incidents | Real-time notification for all incidents is excessive |
| Penetration testing | Annual TLPT; share results under NDA | Client-directed pen testing of provider infrastructure is excessive |
| Regulatory access | Facilitate regulator access within reasonable notice | Open-ended regulatory access without notice is excessive |
NIS2 / Critical Infrastructure
Client Demands with Justification
| Demand | NIS2 Basis | Article |
|---|---|---|
| Supply chain security measures | Entities must address supply chain risk | Art. 21(2)(d) |
| Incident reporting within 24 hours | Early warning within 24 hours; report within 72 | Art. 23 |
| Cybersecurity risk management measures | 10 minimum security measures required | Art. 21(2) |
| Vulnerability handling and disclosure | Required cybersecurity hygiene practice | Art. 21(2)(e) |
| Business continuity and crisis management | Backup, disaster recovery, crisis management | Art. 21(2)(c) |
| Encryption and cryptography policies | Basic cyber hygiene including encryption | Art. 21(2)(h) |
| Access control and asset management | Multi-factor authentication, access management | Art. 21(2)(i-j) |
Provider Responses
| Demand | Reasonable Response | Pushback Threshold |
|---|---|---|
| Supply chain security | Share SOC 2 + security certifications | Requiring provider to audit their sub-suppliers is excessive |
| Incident reporting | 24-hour early warning; 72-hour detailed report | 1-hour notification for all security events is excessive |
| Encryption | Encrypt at rest and in transit; document standards | Mandating specific encryption algorithms limits flexibility |
| MFA | Enforce MFA for all access to client data | MFA for all internal provider systems is excessive |
SOX / Financial Reporting
Client Demands with Justification
| Demand | SOX Basis | Section |
|---|---|---|
| Internal controls over financial reporting | ICFR requirements extend to outsourced processes | Section 404 |
| Audit trail and logging | Must maintain audit trails for financial data | Section 302/404 |
| Segregation of duties | Controls must prevent unauthorized access | Section 404 |
| Change management controls | Changes to financial systems must be controlled | Section 404 |
| Access controls | Limit access to financial data and systems | Section 404 |
Provider Responses
| Demand | Reasonable Response | Pushback Threshold |
|---|---|---|
| Audit trails | 7-year retention; immutable logs | Client dictating specific logging technology is excessive |
| SOD controls | Demonstrate SOD in SOC 1 Type II report | Client designing provider's internal control structure is excessive |
| Change management | ITIL-compliant change management | Client approval of all provider system changes is excessive |
The Genuine-vs-Preference Test
Before citing a regulation as leverage, apply this three-part test:
Test 1: Does the regulation actually require this specific provision?
| Question | If Yes | If No |
|---|---|---|
| Is there a specific article mandating this exact term? | Genuine requirement -- cite the article | May be an interpretation or preference |
| Does the regulation specify the exact standard (e.g., 72 hours)? | Use the exact standard as baseline | The standard is negotiable |
| Is there regulatory guidance or enforcement precedent? | Reference the guidance | Position is less certain |
Test 2: Is this the minimum compliance standard or gold-plated?
| Indicator | Genuine Minimum | Gold-Plated |
|---|---|---|
| Matches regulatory text exactly | Yes | N/A |
| Exceeds regulatory text (shorter timelines, broader scope) | N/A | Yes -- acknowledge as preference |
| Required by industry-specific guidance beyond the regulation | Genuine if guidance is binding | Preference if guidance is advisory |
Test 3: Would a regulator actually enforce this interpretation?
| Evidence | Strength |
|---|---|
| Enforcement action on this exact issue | Strong -- cite the case |
| Regulatory guidance specifically addressing this | Moderate -- reference guidance |
| Industry association recommendation | Weak -- present as best practice, not mandate |
| Internal legal opinion only | Very weak -- present as risk position, not requirement |
Decision Framework:
| Test 1 | Test 2 | Test 3 | Classification | Approach |
|---|---|---|---|---|
| Yes | Minimum | Strong | Genuine Requirement | Non-negotiable; cite regulation |
| Yes | Gold-plated | Strong | Genuine + Preference | Negotiate to minimum; gold-plating is optional |
| Yes | Minimum | Weak | Likely Genuine | Cite regulation; acknowledge enforcement uncertainty |
| No | N/A | N/A | Risk Preference | Be transparent; frame as "our risk position" |
Concession Roadmap
Four tiers of concessions, from easy gives to absolute bright lines. Trade concessions strategically -- never give without getting.
Tier 1: Easy Gives (Concede Early for Goodwill)
Low-cost concessions that signal flexibility and build trust.
| Concession | Cost to Provider | Value to Client |
|---|---|---|
| Extend warranty from 90 days to 12 months | Minimal (if quality is good) | High perceived value |
| Add force majeure detail (pandemic, cyberattack) | Minimal (mutual) | Moderate -- reduces ambiguity |
| Provide quarterly SLA reports instead of annual | Low (automate) | Moderate -- transparency |
| Accept client's DPA template vs. your own | Low (if substantively similar) | Moderate -- reduces their review time |
| Add notice period before price increase (90 days) | Low | Moderate -- planning time |
| Include basic data deletion certification | Low | Moderate -- compliance evidence |
Tier 2: Moderate Concessions (Trade for Counter-Value)
Meaningful concessions that should be traded for something in return.
| Concession | Trade For |
|---|---|
| Increase liability cap from 12 to 24 months | Longer initial term or volume commitment |
| Add super-cap for data breach claims | Higher annual fee (5-10% premium) or extended term |
| Improve SLA from 99.5% to 99.9% | Higher fees or reduced service credit exposure |
| Shorten payment terms from Net 60 to Net 30 | Early payment discount (1-2%) |
| Grant annual audit right | Accept SOC 2 report as primary evidence; limit on-site to 1/year |
| Add termination for convenience right | Notice period (90+ days) and early termination fee |
Tier 3: Significant Concessions (Requires Executive Approval)
High-value concessions that materially change the deal economics or risk profile.
| Concession | Conditions |
|---|---|
| Uncapped liability for data breach claims | Insurance backstop verified; premium reflected in pricing |
| Client ownership of all bespoke IP | License-back for general improvements; background IP retained |
| 99.99% uptime SLA with financial penalties | Premium pricing tier; dedicated infrastructure |
| Most-Favored-Customer pricing clause | Minimum volume commitment; multi-year term |
| Termination for convenience with 30 days notice | Pro-rated payment for work completed; wind-down costs covered |
| Full source code delivery (not escrow) | Restricted use license; confidentiality obligations |
Tier 4: Bright Lines (Never Concede)
Positions that represent existential risk or fundamental business constraints.
| Bright Line | Rationale |
|---|---|
| Unlimited general liability (no cap at all) | Existential risk; uninsurable |
| Assignment of background/platform IP | Destroys core business value |
| Unlimited penalty exposure exceeding contract value | Makes deal unprofitable by definition |
| Waiver of limitation of liability for gross negligence | Defeats the purpose of the liability framework |
| Unilateral regulatory compliance guarantee | Cannot guarantee future regulatory interpretations |
| Client control over provider's other client relationships | Anti-competitive; affects entire business |
Industry-Specific Considerations
Financial Services
| Factor | Impact on Negotiation |
|---|---|
| Regulatory environment | DORA, SOX, PCI DSS create strong client leverage |
| Audit expectations | Expect extensive audit rights; offer pooled audit model |
| Exit planning | Regulators require documented exit strategy -- concede early |
| Data sovereignty | Often require EEA data residency -- price accordingly |
| Incident reporting | 24-hour notification is becoming industry standard |
| Typical deal difficulty | High -- 5-8 rounds average |
Healthcare
| Factor | Impact on Negotiation |
|---|---|
| Regulatory environment | HIPAA, HITECH create strong compliance leverage |
| BAA requirements | Business Associate Agreement is non-negotiable |
| PHI handling | Strict data handling requirements -- price accordingly |
| Breach liability | HIPAA penalties create strong indemnification demands |
| Audit requirements | HHS audit access may be required |
| Typical deal difficulty | High -- 4-6 rounds average |
Government / Public Sector
| Factor | Impact on Negotiation |
|---|---|
| Regulatory environment | FedRAMP, ITAR, procurement regulations |
| Non-negotiable terms | Government terms often cannot be modified |
| IP ownership | Government typically owns all deliverables |
| Pricing | Fixed-price or cost-plus; limited flexibility |
| Audit rights | Unlimited government audit rights are standard |
| Typical deal difficulty | Very High -- 8-12 rounds average |
Technology / Startups
| Factor | Impact on Negotiation |
|---|---|
| Regulatory environment | GDPR for data; less sector-specific regulation |
| IP sensitivity | Often the most contentious issue |
| Speed | Faster deal cycles; less bureaucracy |
| Flexibility | More creative deal structures possible |
| Payment | May need flexible payment terms (cash management) |
| Typical deal difficulty | Moderate -- 3-5 rounds average |
Enterprise / Fortune 500
| Factor | Impact on Negotiation |
|---|---|
| Regulatory environment | Multiple overlapping frameworks |
| Procurement process | Formal RFP/RFI; structured evaluation |
| Template insistence | Will push their paper (client template) |
| Approval layers | Multiple internal approvals; long cycles |
| Volume | Large deal values justify extensive negotiation investment |
| Typical deal difficulty | High -- 5-8 rounds average |
Three-Position Framework for Technology Contract Negotiation
Complete position reference for 5 major provisions with exact language examples for Provider-Favorable, Balanced, and Client-Favorable positions, plus position selection matrix and deal-size tactics.
Table of Contents
- Position Framework Overview
- 1. Liability and Indemnification
- 2. Intellectual Property
- 3. Payment Terms
- 4. Service Level Agreements
- 5. Warranties
- Position Selection Matrix
- Deal-Size Tactics
Position Framework Overview
Every major contract provision exists on a spectrum from provider-favorable to client-favorable. Effective negotiation requires knowing all three positions, understanding where the current draft falls, and having a target position justified by deal context.
| Position | Description | When to Target |
|---|---|---|
| Provider-Favorable | Maximum risk transfer to client, minimum provider obligation | Provider has dominant leverage; commodity service; client is price-sensitive |
| Balanced | Fair allocation of risk and obligation; industry standard | Most negotiations; neither party has dominant leverage; long-term relationship |
| Client-Favorable | Maximum provider obligation and client protection | Client has dominant leverage; mission-critical service; regulated industry |
1. Liability and Indemnification
Provider-Favorable Position
Liability Cap: Total liability capped at fees paid in the 12 months preceding the claim.
"Provider's aggregate liability under this Agreement shall not exceed the total fees paid by Client in the twelve (12) months immediately preceding the event giving rise to the claim."
Consequential Damages: Full exclusion of indirect, consequential, special, and incidental damages.
"In no event shall Provider be liable for any indirect, incidental, special, consequential, or punitive damages, including but not limited to loss of profits, data, business opportunity, or goodwill."
Indemnification: Client indemnifies provider for client's misuse; no provider indemnification beyond IP infringement.
| Element | Provider-Favorable |
|---|---|
| Cap | 12 months fees paid |
| Consequential | Fully excluded |
| Indemnification | Mutual for IP only; client indemnifies for misuse |
| Carve-outs | None |
| Insurance | Not required |
Balanced Position
Liability Cap: Total liability capped at fees paid in the 24 months preceding the claim, with a super-cap for specific claims (data breach, IP infringement, confidentiality).
"Provider's aggregate liability shall not exceed the total fees paid in the twenty-four (24) months preceding the claim. For Excluded Claims (data breach, IP infringement, breach of confidentiality), liability shall not exceed two (2) times the general cap."
Consequential Damages: Mutual exclusion with carve-outs for willful misconduct, data breach, and confidentiality breach.
| Element | Balanced |
|---|---|
| Cap | 24 months fees paid |
| Consequential | Mutually excluded with carve-outs |
| Indemnification | Mutual: Provider for IP, data breach; Client for misuse |
| Carve-outs | Willful misconduct, data breach, confidentiality |
| Insurance | Commercially reasonable levels required |
Client-Favorable Position
Liability Cap: Annual contract value as general cap; unlimited liability for data breach, IP infringement, willful misconduct, and confidentiality breach.
"Provider's aggregate liability shall not exceed the total annual fees payable under this Agreement. The foregoing cap shall not apply to: (a) Provider's indemnification obligations; (b) breach of data protection obligations; (c) IP infringement; (d) breach of confidentiality; or (e) willful misconduct or gross negligence."
| Element | Client-Favorable |
|---|---|
| Cap | Annual contract value (general); unlimited for specified claims |
| Consequential | Recoverable for specified claims |
| Indemnification | Broad provider indemnification including data breach, regulatory fines |
| Carve-outs | Extensive: data breach, IP, confidentiality, willful misconduct, regulatory |
| Insurance | Specific minimum coverage amounts required |
2. Intellectual Property
Provider-Favorable Position
Provider retains all IP, including all deliverables and customizations. Client receives a non-exclusive, non-transferable, limited license.
"All intellectual property rights in the Services, Deliverables, and any modifications, enhancements, or derivative works thereof shall vest in and remain the exclusive property of Provider. Client is granted a non-exclusive, non-transferable, non-sublicensable license to use the Deliverables solely for Client's internal business purposes during the Term."
| Element | Provider-Favorable |
|---|---|
| Ownership | Provider owns all IP including custom deliverables |
| License | Non-exclusive, non-transferable, term-limited |
| Background IP | Provider retains; no license to client |
| Foreground IP | Provider owns |
| Source code | Not provided; no escrow |
Balanced Position
Provider retains background IP and platform IP. Client owns bespoke deliverables. Mutual license-back arrangement.
"Background IP shall remain the property of the originating party. Foreground IP developed specifically for Client ('Bespoke Deliverables') shall be owned by Client. Provider is granted a non-exclusive, royalty-free license to use Bespoke Deliverables for general product improvement, excluding Client's confidential business logic."
| Element | Balanced |
|---|---|
| Ownership | Split: background IP to originator; bespoke to client |
| License | Perpetual license to client for platform components; license-back to provider |
| Background IP | Each party retains own; cross-license for integration |
| Foreground IP | Client owns bespoke; provider owns general improvements |
| Source code | Escrow arrangement for critical components |
Client-Favorable Position
Client owns all deliverables, customizations, and foreground IP. Work-for-hire designation where applicable.
"All Deliverables, including any modifications, customizations, configurations, and derivative works, shall be considered works made for hire and shall be the exclusive property of Client. To the extent any Deliverable does not qualify as work for hire, Provider hereby irrevocably assigns all rights, title, and interest to Client."
| Element | Client-Favorable |
|---|---|
| Ownership | Client owns all foreground IP; work-for-hire |
| License | Perpetual, irrevocable, exclusive for deliverables |
| Background IP | Provider retains but grants perpetual, irrevocable license to client |
| Foreground IP | Client owns exclusively |
| Source code | Full source code delivery with documentation |
3. Payment Terms
Provider-Favorable Position
| Element | Provider-Favorable |
|---|---|
| Payment timing | Net 15 or payment in advance |
| Invoicing | Annual upfront or quarterly in advance |
| Price escalation | Annual CPI + 3-5% increase, automatic |
| Late payment | 1.5% per month interest + suspension right after 15 days |
| Withholding | No right to withhold; dispute after payment |
| MFN | Not offered |
| Early termination | Full remaining contract value due |
Balanced Position
| Element | Balanced |
|---|---|
| Payment timing | Net 30 |
| Invoicing | Quarterly in arrears or milestone-based |
| Price escalation | Annual CPI cap (max 5%), with 90-day notice |
| Late payment | Statutory interest rate; suspension after 30 days written notice |
| Withholding | Right to withhold disputed amounts in good faith |
| MFN | Not typically included |
| Early termination | Pro-rated fees for services rendered + reasonable wind-down costs |
Client-Favorable Position
| Element | Client-Favorable |
|---|---|
| Payment timing | Net 60 or Net 90 |
| Invoicing | Monthly in arrears; milestone-based for projects |
| Price escalation | Fixed pricing for initial term; any increase capped at CPI (max 3%) |
| Late payment | No interest for first 30 days past due; statutory rate thereafter |
| Withholding | Broad right to withhold, offset, and set-off |
| MFN | Most-favored-customer pricing clause |
| Early termination | Termination for convenience with 30-60 days notice; pay only for delivered services |
4. Service Level Agreements
Provider-Favorable Position
| Element | Provider-Favorable |
|---|---|
| Uptime | 99.5% monthly availability |
| Measurement | Provider-measured; excludes scheduled maintenance, force majeure, client-caused |
| Credits | Service credits up to 5% of monthly fees; sole and exclusive remedy |
| Response time | Best efforts; no guaranteed response SLAs |
| Reporting | Quarterly availability reports |
| Termination trigger | None |
Balanced Position
| Element | Balanced |
|---|---|
| Uptime | 99.9% monthly availability |
| Measurement | Third-party monitoring acceptable; excludes scheduled maintenance with notice |
| Credits | Service credits up to 15% of monthly fees; escalating by severity |
| Response time | P1: 1 hour response, 4 hour resolution target; P2: 4 hour response |
| Reporting | Monthly SLA performance reports with root cause analysis for failures |
| Termination trigger | Right to terminate if SLA missed for 3 consecutive months |
Client-Favorable Position
| Element | Client-Favorable |
|---|---|
| Uptime | 99.99% monthly availability |
| Measurement | Client-selected third-party monitoring; minimal exclusions |
| Credits | Service credits up to 100% of monthly fees; not sole remedy |
| Response time | P1: 15 min response, 1 hour resolution; P2: 1 hour response, 4 hour resolution |
| Reporting | Real-time dashboard + weekly reports + root cause analysis within 24 hours |
| Termination trigger | Right to terminate for any month below 99.5% or 2 months below 99.9% |
5. Warranties
Provider-Favorable Position
| Element | Provider-Favorable |
|---|---|
| Scope | Services provided "as is" with limited conformity warranty |
| Duration | 90 days from delivery |
| Remedy | Re-performance only; if re-performance fails, refund pro-rata fees |
| Disclaimers | Full disclaimer of merchantability, fitness for purpose, non-infringement |
| Performance | No performance warranties beyond uptime SLA |
Balanced Position
| Element | Balanced |
|---|---|
| Scope | Services conform to specifications and documentation |
| Duration | 12 months from acceptance |
| Remedy | Re-performance at no cost; if re-performance fails twice, refund + termination right |
| Disclaimers | Standard disclaimer of implied warranties except as expressly stated |
| Performance | Warranty that services meet agreed performance benchmarks |
Client-Favorable Position
| Element | Client-Favorable |
|---|---|
| Scope | Services conform to specs, industry standards, and fitness for stated purpose |
| Duration | 24 months from acceptance; perpetual for latent defects |
| Remedy | Re-performance + damages; client may engage third party at provider's cost |
| Disclaimers | Limited disclaimer; express warranties of merchantability and fitness |
| Performance | Full performance warranty with measurable benchmarks and liquidated damages |
Position Selection Matrix
Select your target position based on these 7 leverage factors:
| Leverage Factor | Provider Position | Balanced | Client Position |
|---|---|---|---|
| Deal value relative to provider revenue | < 0.5% | 0.5% - 2% | > 2% |
| Competitive alternatives available | Few/none | Some | Many |
| Service criticality to client | Low | Moderate | Mission-critical |
| Regulatory requirements | None | Standard | Extensive |
| Client brand/reference value | Low | Moderate | High |
| Switching costs for client | Low | Moderate | High (lock-in) |
| Market demand for provider's service | High demand | Balanced | Oversupply |
Scoring: Count factors favoring each position. Majority determines your starting position. Adjust based on relationship strategy (long-term partnership vs. transactional).
Deal-Size Tactics
Tier 1: Standard ($100K - $500K)
| Parameter | Guideline |
|---|---|
| Timeline | 2-4 weeks |
| Rounds | 1-2 |
| Focus | Payment terms, basic SLA, standard warranties |
| Approach | Use provider's template with targeted redlines; limit to top 5 issues |
| Approval | Department head sign-off |
| IP | Standard license terms acceptable |
| Liability | 12-month fee cap generally acceptable |
Tier 2: Enhanced ($500K - $1M)
| Parameter | Guideline |
|---|---|
| Timeline | 4-6 weeks |
| Rounds | 2-3 |
| Focus | Liability caps, IP provisions, SLA customization, data protection |
| Approach | Start from balanced position; negotiate liability and IP first |
| Approval | VP or Director level |
| IP | Negotiate bespoke deliverable ownership |
| Liability | Push for 24-month cap with data breach carve-out |
Tier 3: Complex ($1M - $3M)
| Parameter | Guideline |
|---|---|
| Timeline | 6-10 weeks |
| Rounds | 3-5 |
| Focus | Full liability framework, IP ownership, custom SLAs, regulatory compliance, indemnification |
| Approach | Use client template or heavily marked-up provider template; full legal review |
| Approval | SVP or General Counsel |
| IP | Full foreground IP ownership with license-back |
| Liability | Super-cap structure with extensive carve-outs |
Tier 4: Strategic ($3M - $10M)
| Parameter | Guideline |
|---|---|
| Timeline | 10-16 weeks |
| Rounds | 5-8 |
| Focus | Enterprise liability, complex IP, multi-year SLAs, full regulatory suite, governance |
| Approach | Client template; dedicated deal team; external counsel review |
| Approval | C-Suite or Board committee |
| IP | Joint development framework with clear allocation |
| Liability | Uncapped for specified claims; insurance requirements |
Tier 5: Transformational ($10M+)
| Parameter | Guideline |
|---|---|
| Timeline | 16-26 weeks |
| Rounds | 8-12 |
| Focus | Bespoke everything; joint governance; exit planning; audit rights |
| Approach | Fully bespoke agreement; multiple workstreams; executive sponsorship |
| Approval | Board approval required |
| IP | Co-development IP framework with reversion rights |
| Liability | Bespoke structure with insurance backstop |
#!/usr/bin/env python3
"""
Deal Complexity Scorer
Takes deal parameters and scores complexity across 7 dimensions.
Recommends deal tier (1-5), expected timeline, number of rounds,
and key focus areas.
Usage:
python deal_complexity_scorer.py deal_params.json
python deal_complexity_scorer.py deal_params.json --json
python deal_complexity_scorer.py deal_params.json --deal-value 5000000
Expected JSON input format:
{
"deal_value": 1500000,
"duration_months": 36,
"parties": 2,
"regulatory_requirements": ["GDPR", "DORA"],
"service_criticality": "high",
"technical_complexity": "moderate",
"ip_sensitivity": "high",
"multi_jurisdictional": false,
"custom_development": true,
"data_processing": true,
"strategic_importance": "high"
}
"""
import argparse
import json
import sys
from typing import Any, Dict, List, Optional, Tuple
# Deal tier definitions
DEAL_TIERS: Dict[int, Dict[str, Any]] = {
1: {
"name": "Standard",
"value_range": "$100K - $500K",
"timeline_weeks": "2-4",
"expected_rounds": "1-2",
"focus": ["Standard terms review", "Basic SLA alignment", "Payment terms"],
"approval_level": "Department Head",
},
2: {
"name": "Enhanced",
"value_range": "$500K - $1M",
"timeline_weeks": "4-6",
"expected_rounds": "2-3",
"focus": ["Liability caps", "IP provisions", "SLA customization", "Data protection"],
"approval_level": "VP / Director",
},
3: {
"name": "Complex",
"value_range": "$1M - $3M",
"timeline_weeks": "6-10",
"expected_rounds": "3-5",
"focus": ["Full liability framework", "IP ownership structure", "Custom SLAs", "Regulatory compliance", "Indemnification"],
"approval_level": "SVP / General Counsel",
},
4: {
"name": "Strategic",
"value_range": "$3M - $10M",
"timeline_weeks": "10-16",
"expected_rounds": "5-8",
"focus": ["Enterprise liability framework", "Complex IP arrangements", "Multi-year SLAs with escalation", "Full regulatory suite", "Governance structure"],
"approval_level": "C-Suite / Board Committee",
},
5: {
"name": "Transformational",
"value_range": "$10M+",
"timeline_weeks": "16-26",
"expected_rounds": "8-12",
"focus": ["Bespoke liability and indemnification", "IP co-development framework", "Mission-critical SLAs", "Full regulatory and audit rights", "Joint governance", "Exit and transition planning"],
"approval_level": "Board Approval",
},
}
# Scoring criteria for each dimension (1-5 scale)
CRITICALITY_MAP = {"low": 1, "moderate": 2, "high": 4, "critical": 5}
COMPLEXITY_MAP = {"low": 1, "moderate": 2, "high": 4, "very_high": 5}
IMPORTANCE_MAP = {"low": 1, "moderate": 2, "high": 4, "strategic": 5}
# Regulatory complexity weights
REGULATORY_WEIGHTS: Dict[str, float] = {
"GDPR": 1.5, "DORA": 2.0, "NIS2": 1.8, "SOX": 1.5,
"HIPAA": 1.8, "PCI_DSS": 1.5, "ISO_27001": 1.0, "SOC_2": 1.0,
"FedRAMP": 2.5, "CCPA": 1.0, "EU_AI_ACT": 2.0,
}
def score_value_dimension(deal_value: float) -> Tuple[int, str]:
"""Score the deal value dimension (1-5)."""
if deal_value < 500_000:
return 1, f"${deal_value:,.0f} -- Standard tier, minimal complexity from value alone"
elif deal_value < 1_000_000:
return 2, f"${deal_value:,.0f} -- Enhanced tier, moderate commercial scrutiny"
elif deal_value < 3_000_000:
return 3, f"${deal_value:,.0f} -- Complex tier, significant commercial and legal review"
elif deal_value < 10_000_000:
return 4, f"${deal_value:,.0f} -- Strategic tier, executive-level commercial terms"
else:
return 5, f"${deal_value:,.0f} -- Transformational tier, board-level commercial significance"
def score_regulatory_dimension(regulations: List[str]) -> Tuple[int, str]:
"""Score regulatory complexity based on applicable frameworks."""
if not regulations:
return 1, "No specific regulatory requirements identified"
total_weight = sum(REGULATORY_WEIGHTS.get(r.upper().replace(" ", "_"), 1.0) for r in regulations)
count = len(regulations)
if total_weight <= 1.5:
score = 1
elif total_weight <= 3.0:
score = 2
elif total_weight <= 5.0:
score = 3
elif total_weight <= 8.0:
score = 4
else:
score = 5
reg_list = ", ".join(regulations)
return score, f"{count} framework(s): {reg_list} (weighted complexity: {total_weight:.1f})"
def score_technical_dimension(params: Dict[str, Any]) -> Tuple[int, str]:
"""Score technical complexity."""
base = COMPLEXITY_MAP.get(params.get("technical_complexity", "low"), 1)
factors: List[str] = []
if params.get("custom_development", False):
base = min(5, base + 1)
factors.append("custom development")
if params.get("data_processing", False):
base = min(5, base + 1)
factors.append("data processing")
if params.get("system_integration", False):
base = min(5, base + 1)
factors.append("system integration")
detail = f"Base: {params.get('technical_complexity', 'low')}"
if factors:
detail += f" + {', '.join(factors)}"
return min(5, base), detail
def score_multiparty_dimension(parties: int, multi_jurisdictional: bool) -> Tuple[int, str]:
"""Score multi-party and jurisdictional complexity."""
if parties <= 2 and not multi_jurisdictional:
return 1, f"{parties} parties, single jurisdiction"
elif parties <= 2 and multi_jurisdictional:
return 3, f"{parties} parties, multi-jurisdictional"
elif parties <= 4:
score = 3 if not multi_jurisdictional else 4
return score, f"{parties} parties, {'multi-jurisdictional' if multi_jurisdictional else 'single jurisdiction'}"
else:
return 5, f"{parties} parties, {'multi-jurisdictional' if multi_jurisdictional else 'single jurisdiction'}"
def score_duration_dimension(months: int) -> Tuple[int, str]:
"""Score contract duration complexity."""
if months <= 12:
return 1, f"{months} months -- short-term, minimal long-term risk exposure"
elif months <= 24:
return 2, f"{months} months -- medium-term, moderate renewal and escalation considerations"
elif months <= 36:
return 3, f"{months} months -- multi-year, requires escalation caps and exit planning"
elif months <= 60:
return 4, f"{months} months -- long-term, significant lock-in and exit complexity"
else:
return 5, f"{months} months -- extended commitment, full lifecycle planning required"
def score_strategic_dimension(importance: str) -> Tuple[int, str]:
"""Score strategic importance."""
score = IMPORTANCE_MAP.get(importance, 1)
descriptions = {
1: "Low strategic importance -- commodity service, easily replaceable",
2: "Moderate strategic importance -- enhances operations but alternatives exist",
4: "High strategic importance -- core to business operations, limited alternatives",
5: "Strategic/transformational -- defines competitive advantage, no viable alternatives",
}
return score, descriptions.get(score, "Unknown importance level")
def score_ip_dimension(sensitivity: str, custom_dev: bool) -> Tuple[int, str]:
"""Score IP sensitivity."""
base = CRITICALITY_MAP.get(sensitivity, 1)
if custom_dev and base < 5:
base = min(5, base + 1)
descriptions = {
1: "Low IP sensitivity -- standard off-the-shelf services",
2: "Moderate IP sensitivity -- some customization, clear ownership lines",
3: "Notable IP sensitivity -- significant customization, ownership negotiation needed",
4: "High IP sensitivity -- custom development with co-created IP",
5: "Critical IP sensitivity -- core technology, trade secrets, or competitive advantage at stake",
}
return base, descriptions.get(base, "Unknown IP sensitivity level")
def calculate_composite(dimensions: Dict[str, Dict[str, Any]]) -> Tuple[float, int]:
"""Calculate weighted composite score and determine deal tier."""
weights = {
"value": 1.5, "regulatory": 1.3, "technical": 1.0,
"multi_party": 0.8, "duration": 0.8, "strategic": 1.2, "ip_sensitivity": 1.0,
}
weighted_sum = sum(dimensions[d]["score"] * weights[d] for d in dimensions)
total_weight = sum(weights[d] for d in dimensions)
composite = weighted_sum / total_weight
# Map composite to tier
if composite <= 1.5:
tier = 1
elif composite <= 2.5:
tier = 2
elif composite <= 3.3:
tier = 3
elif composite <= 4.2:
tier = 4
else:
tier = 5
return round(composite, 2), tier
def format_text_output(result: Dict[str, Any]) -> str:
"""Format results as human-readable text."""
lines: List[str] = []
lines.append("=" * 70)
lines.append("DEAL COMPLEXITY ASSESSMENT")
lines.append("=" * 70)
lines.append("")
lines.append(f"Composite Score: {result['composite_score']:.2f} / 5.00")
lines.append(f"Deal Tier: {result['tier']} -- {result['tier_details']['name']}")
lines.append(f"Value Range: {result['tier_details']['value_range']}")
lines.append(f"Timeline: {result['tier_details']['timeline_weeks']} weeks")
lines.append(f"Expected Rounds: {result['tier_details']['expected_rounds']}")
lines.append(f"Approval Level: {result['tier_details']['approval_level']}")
lines.append("")
lines.append("-" * 70)
lines.append("DIMENSION SCORES")
lines.append("-" * 70)
lines.append(f"{'Dimension':<20} {'Score':>5} {'Detail'}")
lines.append("-" * 70)
for dim_name, dim_data in result["dimensions"].items():
display_name = dim_name.replace("_", " ").title()
bar = "#" * dim_data["score"] + "." * (5 - dim_data["score"])
lines.append(f" {display_name:<18} [{bar}] {dim_data['score']}/5 {dim_data['detail']}")
lines.append("")
lines.append("-" * 70)
lines.append("KEY FOCUS AREAS")
lines.append("-" * 70)
for i, focus in enumerate(result["tier_details"]["focus"], 1):
lines.append(f" {i}. {focus}")
lines.append("")
lines.append("-" * 70)
lines.append("HIGH-COMPLEXITY DIMENSIONS (score >= 4)")
lines.append("-" * 70)
high_dims = [
(k, v) for k, v in result["dimensions"].items() if v["score"] >= 4
]
if high_dims:
for dim_name, dim_data in high_dims:
lines.append(f" * {dim_name.replace('_', ' ').title()} ({dim_data['score']}/5): {dim_data['detail']}")
else:
lines.append(" None -- all dimensions below high-complexity threshold")
lines.append("")
return "\n".join(lines)
def main() -> None:
"""Main entry point."""
parser = argparse.ArgumentParser(
description="Score deal complexity across 7 dimensions and recommend negotiation parameters."
)
parser.add_argument("input_file", help="Path to JSON file with deal parameters")
parser.add_argument("--json", action="store_true", help="Output results as JSON")
parser.add_argument("--deal-value", type=float, help="Override deal value in dollars")
args = parser.parse_args()
try:
with open(args.input_file, "r", encoding="utf-8") as f:
params = json.load(f)
except FileNotFoundError:
print(f"Error: File not found: {args.input_file}", file=sys.stderr)
sys.exit(1)
except json.JSONDecodeError as e:
print(f"Error: Invalid JSON: {e}", file=sys.stderr)
sys.exit(1)
# Apply overrides
if args.deal_value is not None:
params["deal_value"] = args.deal_value
# Validate required fields
deal_value = params.get("deal_value", 0)
if deal_value <= 0:
print("Error: deal_value must be a positive number.", file=sys.stderr)
sys.exit(1)
# Score each dimension
dimensions: Dict[str, Dict[str, Any]] = {}
score, detail = score_value_dimension(deal_value)
dimensions["value"] = {"score": score, "detail": detail}
score, detail = score_regulatory_dimension(params.get("regulatory_requirements", []))
dimensions["regulatory"] = {"score": score, "detail": detail}
score, detail = score_technical_dimension(params)
dimensions["technical"] = {"score": score, "detail": detail}
score, detail = score_multiparty_dimension(
params.get("parties", 2), params.get("multi_jurisdictional", False)
)
dimensions["multi_party"] = {"score": score, "detail": detail}
score, detail = score_duration_dimension(params.get("duration_months", 12))
dimensions["duration"] = {"score": score, "detail": detail}
score, detail = score_strategic_dimension(params.get("strategic_importance", "moderate"))
dimensions["strategic"] = {"score": score, "detail": detail}
score, detail = score_ip_dimension(
params.get("ip_sensitivity", "low"), params.get("custom_development", False)
)
dimensions["ip_sensitivity"] = {"score": score, "detail": detail}
# Calculate composite and tier
composite, tier = calculate_composite(dimensions)
tier_details = DEAL_TIERS[tier]
result = {
"composite_score": composite,
"tier": tier,
"tier_details": tier_details,
"dimensions": dimensions,
"input_parameters": params,
}
if args.json:
print(json.dumps(result, indent=2))
else:
print(format_text_output(result))
if __name__ == "__main__":
main()
#!/usr/bin/env python3
"""
Negotiation Position Analyzer
Analyzes contract text and classifies each provision as provider-favorable,
balanced, or client-favorable based on keyword patterns and structural analysis.
Generates a position map and recommended negotiation priorities.
Usage:
python negotiation_position_analyzer.py contract_draft.txt
python negotiation_position_analyzer.py contract_draft.txt --json
python negotiation_position_analyzer.py contract_draft.txt --perspective client
"""
import argparse
import json
import re
import sys
from typing import Any, Dict, List, Optional, Tuple
# Provision detection patterns: (provision_name, section_patterns)
PROVISION_PATTERNS: Dict[str, List[str]] = {
"liability": [
r"(?i)\bliabilit(?:y|ies)\b", r"(?i)\bindemnif(?:y|ication|ied)\b",
r"(?i)\blimit(?:ation)?\s+of\s+liability\b", r"(?i)\bdamages?\b",
r"(?i)\bcap\s+on\s+(?:liability|damages)\b",
],
"ip_ownership": [
r"(?i)\bintellectual\s+property\b", r"(?i)\b(?:ip|i\.p\.)\s+(?:rights|ownership)\b",
r"(?i)\bwork\s+product\b", r"(?i)\bdeliverables?\s+ownership\b",
r"(?i)\bbackground\s+ip\b", r"(?i)\bforeground\s+ip\b",
r"(?i)\blicen[cs]e\s+(?:grant|back)\b",
],
"payment_terms": [
r"(?i)\bpayment\s+terms?\b", r"(?i)\bnet\s+\d+\b", r"(?i)\binvoic(?:e|ing)\b",
r"(?i)\bmilestone\s+payment\b", r"(?i)\bpayment\s+schedule\b",
r"(?i)\blate\s+(?:payment|fee)\b", r"(?i)\bprice\s+(?:increase|escalation)\b",
],
"sla": [
r"(?i)\bservice\s+level\b", r"(?i)\bsla\b", r"(?i)\buptime\b",
r"(?i)\bavailabilit(?:y|ies)\b", r"(?i)\bservice\s+credit\b",
r"(?i)\bresponse\s+time\b", r"(?i)\bresolution\s+time\b",
],
"warranties": [
r"(?i)\bwarrant(?:y|ies|s)\b", r"(?i)\brepresentation(?:s)?\b",
r"(?i)\bas[- ]is\b", r"(?i)\bdisclaimer\b",
r"(?i)\bfitness\s+for\s+(?:a\s+)?particular\s+purpose\b",
r"(?i)\bmerchantabilit(?:y|ies)\b",
],
}
# Position indicators: keyword -> (score_delta, explanation)
# Negative = provider-favorable, Positive = client-favorable
POSITION_INDICATORS: Dict[str, List[Tuple[str, float, str]]] = {
"liability": [
(r"(?i)\bunlimited\s+liabilit", 2.0, "Unlimited liability favors client"),
(r"(?i)\bcap(?:ped)?\s+at\s+(?:the\s+)?fees?\s+paid", -1.5, "Liability capped at fees paid favors provider"),
(r"(?i)\b(?:12|twelve)\s+months?\s+(?:of\s+)?fees", -1.0, "12-month fee cap is moderately provider-favorable"),
(r"(?i)\b(?:24|twenty.?four)\s+months?\s+(?:of\s+)?fees", 0.0, "24-month fee cap is balanced"),
(r"(?i)\bexclud(?:e|es|ing)\s+(?:indirect|consequential|special|incidental)", -1.5, "Excluding indirect damages favors provider"),
(r"(?i)\bindirect\s+(?:and\s+)?consequential\s+damages?\s+(?:are\s+)?(?:included|recoverable)", 1.5, "Including indirect damages favors client"),
(r"(?i)\bmutual\s+indemnif", 0.0, "Mutual indemnification is balanced"),
(r"(?i)\bprovider\s+(?:shall\s+)?indemnif", 1.0, "Provider-only indemnification favors client"),
(r"(?i)\bclient\s+(?:shall\s+)?indemnif", -1.0, "Client-only indemnification favors provider"),
(r"(?i)\bsuper[- ]?cap\b", 1.0, "Super-cap for specific claims favors client"),
(r"(?i)\bcarve[- ]?out", 0.5, "Carve-outs from liability cap favor client"),
],
"ip_ownership": [
(r"(?i)\bclient\s+(?:shall\s+)?own\s+all", 2.0, "Client owns all IP favors client"),
(r"(?i)\bprovider\s+(?:shall\s+)?(?:retain|own)\s+all", -2.0, "Provider retains all IP favors provider"),
(r"(?i)\bjoint\s+ownership", 0.0, "Joint IP ownership is balanced"),
(r"(?i)\bwork\s+(?:made\s+)?for\s+hire", 1.5, "Work-for-hire favors client"),
(r"(?i)\blicen[cs]e\s+back\s+to\s+(?:the\s+)?provider", -0.5, "License-back to provider is moderately provider-favorable"),
(r"(?i)\bperpetual.*\blicen[cs]e\s+to\s+(?:the\s+)?client", 1.0, "Perpetual license to client favors client"),
(r"(?i)\bnon[- ]?exclusive\s+licen[cs]e", -0.5, "Non-exclusive license is moderately provider-favorable"),
(r"(?i)\bexclusive\s+licen[cs]e", 1.5, "Exclusive license favors client"),
(r"(?i)\bassignment\s+of\s+(?:all\s+)?(?:ip|intellectual)", 1.5, "IP assignment favors client"),
(r"(?i)\bbackground\s+ip\s+(?:remains|retained)", 0.0, "Background IP retained is standard/balanced"),
],
"payment_terms": [
(r"(?i)\bnet\s+15\b", -1.0, "Net 15 payment favors provider"),
(r"(?i)\bnet\s+30\b", 0.0, "Net 30 is standard/balanced"),
(r"(?i)\bnet\s+45\b", 0.5, "Net 45 favors client"),
(r"(?i)\bnet\s+60\b", 1.5, "Net 60 strongly favors client"),
(r"(?i)\bnet\s+90\b", 2.0, "Net 90 strongly favors client"),
(r"(?i)\b(?:advance|upfront)\s+payment", -1.5, "Upfront payment favors provider"),
(r"(?i)\bmilestone[- ]?based\s+payment", 0.5, "Milestone-based payment favors client"),
(r"(?i)\bprice\s+(?:increase|escalation)\s+(?:cap|limit)", 1.0, "Price increase cap favors client"),
(r"(?i)\b(?:annual|yearly)\s+(?:price\s+)?increase", -0.5, "Annual price increase favors provider"),
(r"(?i)\bright\s+to\s+(?:withhold|offset|set[- ]?off)", 1.0, "Right to withhold payment favors client"),
(r"(?i)\blate\s+(?:payment\s+)?(?:fee|interest|penalty)", -0.5, "Late payment penalties favor provider"),
(r"(?i)\bmost[- ]?favou?red[- ]?(?:customer|nation)", 1.5, "MFN pricing favors client"),
],
"sla": [
(r"(?i)\b99\.9{2,}%?\s+(?:uptime|availability)", 1.5, "99.99%+ uptime commitment favors client"),
(r"(?i)\b99\.9%?\s+(?:uptime|availability)", 0.5, "99.9% uptime is moderately client-favorable"),
(r"(?i)\b99\.?5?%?\s+(?:uptime|availability)", -0.5, "99.5% or lower uptime favors provider"),
(r"(?i)\bservice\s+credit(?:s)?\s+(?:up\s+to\s+)?(?:\d+%|100%)", 1.0, "Service credits favor client"),
(r"(?i)\b(?:sole|exclusive)\s+remed(?:y|ies)", -1.0, "Service credits as sole remedy favors provider"),
(r"(?i)\btermination\s+(?:right|for)\s+(?:repeated\s+)?(?:sla|service\s+level)\s+(?:failure|breach)", 1.5, "Termination for SLA failure favors client"),
(r"(?i)\bexclud(?:e|es|ing)\s+(?:scheduled\s+)?maintenance", -0.5, "Excluding maintenance windows favors provider"),
(r"(?i)\broot\s+cause\s+analysis", 0.5, "Root cause analysis requirement favors client"),
(r"(?i)\b(?:financial\s+)?penalt(?:y|ies)", 1.0, "Financial penalties for SLA breach favor client"),
],
"warranties": [
(r"(?i)\bas[- ]is\b.*\bno\s+warrant", -2.0, "As-is/no warranty strongly favors provider"),
(r"(?i)\bdisclaim(?:s|er|ed)?\s+(?:all\s+)?(?:other\s+)?warrant", -1.5, "Warranty disclaimer favors provider"),
(r"(?i)\bwarrant(?:s|ies)?\s+(?:that\s+)?(?:the\s+)?(?:services?|deliverables?)\s+(?:shall|will)\s+(?:conform|comply)", 1.0, "Conformity warranty favors client"),
(r"(?i)\b(?:12|twelve|1[- ]?year)\s+warrant(?:y|ies)", 0.0, "12-month warranty is standard/balanced"),
(r"(?i)\b(?:24|twenty.?four|2[- ]?year)\s+warrant(?:y|ies)", 0.5, "24-month warranty favors client"),
(r"(?i)\b(?:90|ninety)\s+day\s+warrant(?:y|ies)", -1.0, "90-day warranty favors provider"),
(r"(?i)\bfitness\s+for\s+(?:a\s+)?particular\s+purpose", 1.0, "Fitness for particular purpose warranty favors client"),
(r"(?i)\bmerchantabilit(?:y|ies)", 0.5, "Merchantability warranty favors client"),
(r"(?i)\bre[- ]?perform(?:ance)?\s+(?:at\s+)?(?:no\s+)?(?:additional\s+)?(?:cost|charge)", 1.0, "Re-performance at no cost favors client"),
],
}
def extract_sections(text: str) -> Dict[str, str]:
"""Extract text sections relevant to each provision type."""
sections: Dict[str, str] = {}
lines = text.split("\n")
for provision, patterns in PROVISION_PATTERNS.items():
relevant_lines: List[str] = []
for i, line in enumerate(lines):
for pattern in patterns:
if re.search(pattern, line):
start = max(0, i - 2)
end = min(len(lines), i + 15)
relevant_lines.extend(lines[start:end])
break
sections[provision] = "\n".join(relevant_lines) if relevant_lines else ""
return sections
def analyze_provision(provision: str, text: str) -> Dict[str, Any]:
"""Analyze a single provision and return position assessment."""
if not text.strip():
return {
"provision": provision,
"detected": False,
"position": "not_found",
"score": 0.0,
"indicators": [],
"recommendation": f"No {provision.replace('_', ' ')} provisions detected. Review manually.",
}
indicators = POSITION_INDICATORS.get(provision, [])
found_indicators: List[Dict[str, Any]] = []
total_score = 0.0
for pattern, score, explanation in indicators:
matches = re.findall(pattern, text)
if matches:
found_indicators.append({
"pattern": explanation,
"score": score,
"matches": len(matches),
})
total_score += score
# Normalize score to -3 to +3 range
if found_indicators:
avg_score = total_score / len(found_indicators)
else:
avg_score = 0.0
# Classify position
if avg_score <= -0.75:
position = "provider-favorable"
elif avg_score >= 0.75:
position = "client-favorable"
else:
position = "balanced"
# Generate recommendation
recommendations = {
"provider-favorable": f"Push for balanced or client-favorable {provision.replace('_', ' ')} terms. High negotiation priority.",
"balanced": f"Current {provision.replace('_', ' ')} terms are reasonable. Low negotiation priority unless strategic.",
"client-favorable": f"Current {provision.replace('_', ' ')} terms favor client. Protect these in negotiation.",
}
return {
"provision": provision,
"detected": True,
"position": position,
"score": round(avg_score, 2),
"indicators": found_indicators,
"recommendation": recommendations[position],
}
def generate_position_map(results: List[Dict[str, Any]], perspective: str) -> Dict[str, Any]:
"""Generate overall position map and negotiation priorities."""
detected = [r for r in results if r["detected"]]
not_detected = [r for r in results if not r["detected"]]
if not detected:
return {
"overall_position": "indeterminate",
"overall_score": 0.0,
"distribution": {"provider-favorable": 0, "balanced": 0, "client-favorable": 0, "not_found": len(results)},
"priorities": ["Unable to analyze -- no recognized provisions found. Verify the input contains contract language."],
"provisions": results,
}
distribution = {"provider-favorable": 0, "balanced": 0, "client-favorable": 0, "not_found": len(not_detected)}
scores: List[float] = []
for r in detected:
distribution[r["position"]] += 1
scores.append(r["score"])
avg_score = sum(scores) / len(scores) if scores else 0.0
if avg_score <= -0.5:
overall = "provider-favorable"
elif avg_score >= 0.5:
overall = "client-favorable"
else:
overall = "balanced"
# Flip perspective if analyzing from provider side
if perspective == "provider":
flip = {"provider-favorable": "client-favorable", "client-favorable": "provider-favorable", "balanced": "balanced"}
overall = flip.get(overall, overall)
# Generate priorities: sort by how far from client-favorable (from client perspective)
priority_order = sorted(detected, key=lambda r: r["score"])
priorities: List[str] = []
for r in priority_order:
if r["position"] == "provider-favorable":
priorities.append(f"HIGH: {r['provision'].replace('_', ' ').title()} -- currently {r['position']} (score: {r['score']})")
elif r["position"] == "balanced":
priorities.append(f"LOW: {r['provision'].replace('_', ' ').title()} -- currently {r['position']} (score: {r['score']})")
if not_detected:
for r in not_detected:
priorities.append(f"REVIEW: {r['provision'].replace('_', ' ').title()} -- not detected in contract text")
return {
"overall_position": overall,
"overall_score": round(avg_score, 2),
"distribution": distribution,
"priorities": priorities,
"provisions": results,
}
def format_text_output(position_map: Dict[str, Any], perspective: str) -> str:
"""Format position map as human-readable text."""
lines: List[str] = []
lines.append("=" * 70)
lines.append("NEGOTIATION POSITION ANALYSIS")
lines.append(f"Perspective: {perspective.upper()}")
lines.append("=" * 70)
lines.append("")
lines.append(f"Overall Position: {position_map['overall_position'].upper()}")
lines.append(f"Overall Score: {position_map['overall_score']:+.2f} (range: -3.0 provider to +3.0 client)")
lines.append("")
dist = position_map["distribution"]
lines.append("Position Distribution:")
lines.append(f" Provider-Favorable: {dist['provider-favorable']}")
lines.append(f" Balanced: {dist['balanced']}")
lines.append(f" Client-Favorable: {dist['client-favorable']}")
lines.append(f" Not Found: {dist['not_found']}")
lines.append("")
lines.append("-" * 70)
lines.append("PROVISION DETAILS")
lines.append("-" * 70)
for prov in position_map["provisions"]:
lines.append("")
name = prov["provision"].replace("_", " ").title()
if not prov["detected"]:
lines.append(f" {name}: NOT DETECTED")
lines.append(f" -> {prov['recommendation']}")
continue
pos_display = prov["position"].upper()
lines.append(f" {name}: {pos_display} (score: {prov['score']:+.2f})")
for ind in prov["indicators"]:
marker = "+" if ind["score"] >= 0 else "-"
lines.append(f" [{marker}] {ind['pattern']}")
lines.append(f" -> {prov['recommendation']}")
lines.append("")
lines.append("-" * 70)
lines.append("NEGOTIATION PRIORITIES")
lines.append("-" * 70)
for i, priority in enumerate(position_map["priorities"], 1):
lines.append(f" {i}. {priority}")
lines.append("")
return "\n".join(lines)
def main() -> None:
"""Main entry point."""
parser = argparse.ArgumentParser(
description="Analyze contract text and classify provisions by negotiation position."
)
parser.add_argument("input_file", help="Path to contract text file (.txt or .md)")
parser.add_argument("--json", action="store_true", help="Output results as JSON")
parser.add_argument(
"--perspective", choices=["provider", "client"], default="client",
help="Analysis perspective (default: client)"
)
args = parser.parse_args()
try:
with open(args.input_file, "r", encoding="utf-8") as f:
contract_text = f.read()
except FileNotFoundError:
print(f"Error: File not found: {args.input_file}", file=sys.stderr)
sys.exit(1)
except IOError as e:
print(f"Error reading file: {e}", file=sys.stderr)
sys.exit(1)
if len(contract_text.strip()) < 50:
print("Error: Input file appears too short to contain contract language.", file=sys.stderr)
sys.exit(1)
# Extract and analyze each provision
sections = extract_sections(contract_text)
results: List[Dict[str, Any]] = []
for provision in PROVISION_PATTERNS:
result = analyze_provision(provision, sections[provision])
results.append(result)
# Generate position map
position_map = generate_position_map(results, args.perspective)
if args.json:
print(json.dumps(position_map, indent=2))
else:
print(format_text_output(position_map, args.perspective))
if __name__ == "__main__":
main()
Related skills
FAQ
What is the Three-Position Framework?
For every major provision it maps provider-favorable, balanced, and client-favorable positions so you can target and trade concessions.
What does the deal complexity scorer do?
It scores complexity across 7 dimensions and recommends a deal tier (1-5), timeline, number of rounds, and focus areas.