You've just launched a custom enterprise platform. The development budget is spent, the project team has disbanded, and three days later your commercial director reports that a search filter returns zero results. You call the vendor. They respond: "That's not a bug, that's an enhancement." Invoice: $1,500.
This scene repeats across every enterprise that builds custom business applications. The real problem isn't the amount, it's the absence of rules. The boundary between correction (free under warranty) and evolution (billable from day one) is almost never written into the contract. Budgets don't leak on major milestones, they leak on this blurry line, request by request, in permanent negotiation that exhausts both sides.
This article provides the defect definition to write into your contract, the third category everyone forgets (regulatory adaptation), and the mechanism that solves the problem for good: a pre-priced catalog of common requests that transforms avenant battles into transparent pricing.
Corrective, evolutive, regulatory: three budgets, three logics
The confusion starts with vocabulary. Companies talk about "maintenance," but that word actually hides three distinct services that mobilize neither the same budget nor the same decision circuit.
Corrective maintenance repairs what doesn't work as specified. An export that generates an empty file when the requirements called for a CSV with all rows, a provision calculation displaying a wrong result, a notification that never sends: these are defects. They fall under post-production warranty and must be corrected free of charge during a contractual period (typically 3 to 12 months). Budget: zero, it's included in the initial development package.
Evolutive maintenance adds what wasn't in the validated scope. Your team wants a new search filter by foreign supplier? Management wants a dashboard with quarterly tracking charts? These are enhancements. They're always billable, even on day one, because they were never part of the original contract. Budget: variable, often between $12,000 and $125,000 per year depending on platform usage intensity.
Regulatory adaptation covers modifications imposed by a change in law or standard. New monthly VAT declaration requirement, modified payroll import format for social security, adoption of a new accounting framework: nobody requested these changes, but the application must comply or become unusable. This category is neither a bug (the code does what it was asked) nor a wish (you didn't choose the new rule). Budget: negotiate case by case, some contracts provide a dedicated annual envelope.
Most contracts only mention "corrective maintenance" and "evolutive maintenance." Result: as soon as an administration publishes a new decree, the same discussion starts over. The vendor says "it's an enhancement," the client says "I didn't request it, so it's a bug," and you negotiate an ad hoc amendment that delays the work by three weeks.
The defect definition: the only paragraph that really matters
Here's the sentence missing from 80% of contracts we've audited over the past three years:
Any measurable difference between the observed behavior of the application and the behavior described in the functional specifications validated by both parties before development begins, or any technical malfunction that prevents normal use of the application, shall be deemed a defect.
This definition establishes two objective criteria. First criterion: a written trace. The expected behavior must appear in a signed document (requirements doc, validated user story, acceptance meeting minutes). If your request was never documented, it's not a bug, it's a new request. Second criterion: a measurement. The field displays "0" instead of "12,345"? Defect. The export generates 0 rows instead of 200? Defect. Response time reaches 45 seconds instead of under 3? Defect, if the contract specified a performance commitment.
In practice, this also means anything not written isn't warranted. You thought the application should sort suppliers alphabetically, but nothing says so in the specs? The vendor delivered chronological sorting (date added). That's not a bug, that's a misunderstanding. The correction will be billed.
It's harsh, but it's the only rule that stops endless debates. It forces both parties to write precisely what will be done before starting, which improves requirements quality and reduces surprises at acceptance.
The definition must also cover technical malfunctions: a page returning a 500 error, a database saturating and blocking all connections, a service crashing every morning at 9am. These cases never appear in functional specs (nobody writes "the homepage must display without error"), but they obviously fall under warranty. The contract must therefore add a catch-all clause for outages, crashes, and any unplanned downtime.
What warranty covers after production, and where it stops
Legal warranty in Morocco runs 12 months for software (Code of Obligations and Contracts, art. 555). In practice, custom development contracts often provide shorter conventional warranty (3 to 6 months) or longer (up to 24 months for critical platforms), depending on commercial leverage.
During this period, the vendor corrects all defects per the above definition free of charge. Free means: no billing of time spent, but with an intervention delay that depends on severity. Well-written contracts establish a criticality grid:
- Critical (P1): application completely unusable (general error page, database inaccessible). Intervention within 4 business hours, resolution within 24h.
- Major (P2): a key function doesn't work (impossible to create new supplier record, monthly export blocked). Intervention within 1 business day, resolution within 5 days.
- Minor (P3): an interface detail, a label typo, column alignment. Intervention within 5 days, resolution within 15 days or in next release.
Without a grid, you get "we'll look at it as soon as possible," which can mean three months for a cosmetic footer fix. With the grid, you can track contractually. If the vendor exceeds P1 deadlines three times in a quarter, it's grounds for penalty or termination.
Warranty does not cover:
- Functional enhancements requested after acceptance, even if they seem obvious to your users.
- Regulatory or technical adaptations (new browser version, server migration, new banking API imposed by your institution).
- Errors caused by improper use of the application (manual deletion of database rows, import of a file in a different format than documented).
- Training or user support requests beyond an initial quota (often 2 to 4 days of training included, then billable).
These exclusions must appear explicitly in the contract. Otherwise, the clause "all defects will be corrected free of charge" becomes elastic: the client believes every fault falls under warranty, the vendor bills everything it can. Result: negotiation on every ticket that consumes more time than the correction itself.
The maintenance subscription: what exactly are you buying for a recurring monthly amount
After warranty, most enterprises subscribe to an annual maintenance contract, typically billed 12 to 20% of initial development cost per year. For a platform delivered at $200,000, expect to pay between $24,000 and $40,000 per year. But what does this amount actually cover?
The minimum base always includes:
- Technical support: a hotline or dedicated email channel to report defects, with committed first-response time (often 4h to 48h depending on criticality).
- Residual bug fixes: any defect discovered after initial warranty ends is corrected without additional time billing, within a quota (e.g. 10 person-days per year).
- Security updates: critical patches for the framework used (Laravel, Symfony, React), updates of third-party libraries with CVE vulnerabilities.
- Hosting and monitoring: depending on contracts, may include server infrastructure, automatic backups, and 24/7 response-time surveillance.
What maintenance never includes by default:
- Functional enhancements. A new screen, a new report, a new API integration: always extra.
- Regulatory adaptations. A new tax requirement needing a new export: billed separately or via a separate envelope.
- Major technical migrations (PHP version change, cloud migration, database refactor).
The classic trap: you pay $30,000 per year for maintenance, and after six months you discover that amount only paid for support and hosting. Every enhancement request triggers additional billing, and you end up at $75,000 full year.
To avoid this drift, some contracts provide an enhancement envelope included in the annual subscription. For example: $30,000 per year including support + 5 person-days of enhancements to consume freely. Beyond 5 days, billing per day (rate often between $2,000 and $3,000/day for a senior developer). This formula gives visibility and avoids surprises, provided the counting is transparent (a tracking ticket for every consumed hour).
The pre-priced catalog of common requests, instead of ongoing negotiation
The real problem with evolutive maintenance is that every request triggers a negotiation. You want to add a search filter by region? The vendor sends you a quote: $3,750. You find that expensive for "just a dropdown menu." Exchange of three emails, phone meeting, renegotiation to $3,000. Time to get the filter: five weeks, four spent discussing price.
The solution that works in long-term relationships (multi-year subscription, living platform with 20 to 40 requests per year): a pre-priced catalog of common request types, annexed to the maintenance contract.
Example catalog for a supplier management platform:
| Request type | Effort (days) | Unit price (USD) |
|---|---|---|
| Add a text or numeric field to existing form | 0.5 days | $1,000 |
| Add a search filter (dropdown list) | 1 day | $2,000 |
| Create a new Excel export (standard columns) | 1.5 days | $3,000 |
| Add an automatic email notification | 2 days | $4,000 |
| Create a new user role with specific rights | 3 days | $6,000 |
| Third-party API integration (incoming or outgoing webhook) | Quote | Minimum $10,000 |
With this catalog, the discussion changes. You no longer negotiate the price of each request, you verify it fits a catalog box. If yes, you order, it's priced. If the request is more complex or outside the catalog, it goes to "on quote," but at least 70% of common requests are covered.
This provides budget predictability: you know a new field costs $1,000, so before requesting, you verify if it's priority. It also provides speed: no more negotiation, the vendor starts upon receipt of purchase order.
The catalog must be revised annually: rates can increase (inflation, rising required technical skills), and new categories appear with usage. After two years, you may need a rate for "add a graph to dashboard" or "modify validation workflow." Add them to the catalog during renewal.
When regulation changes during contract, who pays for adaptation
A tax decree now requires enterprises to transmit a monthly XML VAT declaration file to the SIMPL portal. Your ERP doesn't generate this format. Who pays the $15,000 development to add the export?
Legally, if the initial contract didn't provide this functionality (because the obligation didn't exist at signing date), it's an enhancement. The vendor has no obligation to deliver it free. In practice, the answer depends on the regulatory adaptation clause:
- Option 1: billable separately, at actual time. Any modification imposed by law is billed at time spent. Simple, but costly if three decrees come out the same year.
- Option 2: annual flat envelope. The maintenance contract includes $5,000 per year for regulatory adaptations. If nothing changes, you consume nothing. If a large project occurs, you have a buffer. Beyond the envelope, billing separately.
- Option 3: pass-through to end customer. Applicable in certain businesses where software is resold to end customers (SaaS publisher, integrator). The adaptation cost is amortized across the entire customer base and included in subscription. Not applicable for custom internal development.
Our recommendation: option 2 is most balanced. You provision a regulatory budget without paying the cost every year, and the vendor knows they have an envelope to consume before billing extra. However, set a clear rule to qualify a request as "regulatory": it must be caused by an external legal or regulatory obligation published in the Official Bulletin, by a banking or accounting standard update imposed by the profession, or by a third-party API evolution beyond both parties' control. A "best practice" or "auditor recommendation" doesn't qualify.
The allocation table to sign before production launch
The best way to avoid disputes is to clarify rules before final acceptance. Here's the table to annex to the contract, fill with the vendor, and have validated by your procurement or CFO before signing the production go-live PV:
| Request type | Who pays? | Intervention delay | Estimated annual budget |
|---|---|---|---|
| Blocking defect (P1) | Vendor (warranty) | 4h / resolve 24h | 0 (included) |
| Major defect (P2) | Vendor (warranty) | 1d / resolve 5d | 0 (included) |
| Minor defect (P3) | Vendor (warranty) | 5d / resolve 15d | 0 (included) |
| Functional enhancement (new field, filter) | Client (priced catalog) | Per catalog | $20,000 to $37,500 |
| Structural enhancement (new module) | Client (custom quote) | Per quote | TBD |
| Regulatory adaptation | Dedicated $7,500/yr envelope | Per criticality | $7,500 |
| User support and training | 2 days included, then $1,500/day | By appt | $6,000 to $12,000 |
| Hosting, backups, monitoring | Monthly subscription | 24/7 | $15,000 to $30,000 |
This table gives visibility to both parties. Your CIO knows they must provision between $42,500 and $87,000 per year post-production. The vendor knows they won't be solicited free for anything and everything. Procurement knows they must budget a maintenance framework contract with evolutive purchase orders.
Sign this table with the initial development contract, not six months after production launch. At that point, you're already in conflict over three tickets, and it's too late to clarify rules.
FAQ
Is a bug discovered 18 months after production launch still covered under warranty?
No, unless your contract provides multi-year warranty (rare). Legal warranty runs 12 months maximum in Morocco. After this period, even an objective defect falls under the maintenance contract: it will be corrected, but within the person-day quota included in the annual subscription, or extra if the quota is exceeded. However, if the bug existed during warranty and you reported it before period end (with written proof), the vendor must correct it free, even if the correction occurs after deadline expiration.
Can the vendor refuse to fix a bug arguing it was present during acceptance?
Yes, if you signed the acceptance PV without reservation. Signing the acceptance PV constitutes acceptance of the application in the tested state. If a malfunction was visible and you didn't report it, the vendor can consider you accepted it. That's why the acceptance phase must be exhaustive: test all critical scenarios before signing. Some contracts provide an "extended warranty" period of 30 to 60 days after acceptance, during which defects discovered in real production remain covered even if they weren't tested during formal acceptance.
How to avoid the vendor overestimating time needed for a small enhancement?
Two mechanisms: the priced catalog (discussed above) and time-tracking transparency. Contractually require detailed time tracking on each ticket (via a ticketing tool like Jira, ClickUp, or a simple shared file), with a description of tasks performed. If a request cataloged at 1 day systematically consumes 3 days, either the catalog is undervalued (to revise), or the vendor's efficiency is a problem. A technical audit by a third party (consulting firm or freelance CTO) can objectify the debate and avoid permanent suspicion.
Must we pay maintenance even if we have no enhancement requests for a year?
Yes, if you signed an annual maintenance contract. The subscription covers support, hosting, monitoring, security updates, and vendor availability to intervene in case of outage. Even without enhancements, these services have a cost. Some contracts offer an "on-demand" formula (billing per ticket), but it's always more expensive per unit ($2,500 to $3,750/day instead of $2,000 on subscription) and doesn't guarantee intervention delay. Reserve this formula for non-critical applications you only use a few months per year.
What to do if the initial vendor closed or is no longer reachable?
That's the risk of technical dependence. Your contract must provide a code escrow clause: the vendor regularly deposits (every 3 to 6 months) a copy of source code and technical documentation with a trusted third party (lawyer, approved escrow agent, escrow platform). In case of vendor default, you recover the code and can have maintenance taken over by another vendor. Without an escrow clause, you're stuck: either you pay for reverse-engineering audit (between $12,500 and $37,500 to reconstruct docs), or you redevelop everything. Some large accounts also require internal team training during the project, to reduce dependence and allow gradual takeover.
To deepen the structure of your development and maintenance contracts, consult our guides on digital transformation and software architecture consulting. If you manage multiple business applications and want an audit of your existing contracts, our team analyzes critical clauses and proposes a three-year budget optimization plan: custom business applications.
